Day15-技术面试问题及答案整理(Python篇)
1、深拷贝和浅拷贝
1)copy.copy 浅拷贝,只拷贝父对象,不会拷贝对象的内部的子对象。
2)copy.deepcopy 深拷贝,拷贝对象及其子对象
一个很好的例子:
import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始对象
b = a #赋值,传对象的引用
c = copy.copy(a) #对象拷贝,浅拷贝
d = copy.deepcopy(a) #对象拷贝,深拷贝
a.append(5) #修改对象a
a[4].append('c') #修改对象a中的['a', 'b']数组对象
print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d
输出结果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c = [1, 2, 3, 4, ['a', 'b', 'c']]
d = [1, 2, 3, 4, ['a', 'b']]
2、Python中的除法:
Python中除法分为3种除法:传统除法、精确除法、地板除。
1)传统除法
如果是整数除法则执行地板除,如果是浮点数除法则执行精确除法。
>>>1/2
0
>>>1.0/2.0
0.5
2)精确除法
除法总是会返回真实的商,不管操作数是整形还是浮点型。执行from __future__ import division指令就可以做到这一点。
>>>from __future__ import division
>>>1/2
0.5
>>>1.0/2.0
0.5
3)地板除
//除法不管操作数为何种数值类型,总是会舍去小数部分,返回数字序列中比真正的商小的最接近的数字。
>>>1//2
0
>>>1.0//2
0
>>>-1//2.0
-1
3、OOP(面向对象编程)三大特点:
1)封装:通过接口访问方法,通过在实例变量上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
2)继承:基于类创建新类(父类->子类,基类->派生类)
3)多态:运算符(重载)或方法可以根据对象调用不同的方法。当子类和父类都存在相同的方法时,子类的方法覆盖了父类的方法,在代码运行的时候,总是会调用子类的方法。
4、GIL线程全局锁
在进程中有一个或者多个线程。每个进程具有自己的地址空间,内存,数据栈及其它数据。线程是CPU调动的,没有自己的资源,所有线程都共享同一进程中的资源。CPU执行任务时,在线程之间是进行随机调度的,并且每个线程可能只执行n条代码后就转而执行另外一条线程。由于在一个进程中的多个线程之间是共享资源和数据的,这就容易造成资源抢夺或脏数据,于是就有了锁的概念,限制某一时刻只有一个线程能访问某个指定的数据。
为了解决不同线程同时访问统一资源时数据保护问题,而产生了GIL. Python因为GIL的问题广受诟病,因为它在解释器的层面限制了程序在同一时间只有一个线程被CPU实际执行,而不管你的程序里实际开了多少条线程。所以我们经常能发现,Python中的多线程编程有时候效率还不如单线程,就是因为这个原因。所以在Python中并不推荐多线程,而是推荐多进程。