概念篇:
1、深拷贝,浅拷贝?
深拷贝是将对象本身复制给另一对象,另一对象的修改是对原对象副本的修改,不会影响原对象
浅拷贝是新增对象的引用给另一对象,另一对象的修改会影响原对象
2、三元表达式?
格式 :true的执行语句 if 条件 else flase的执行语句
3、python多线程?
python的代码执行由python虚拟机来控制,对python虚拟机的访问又由GIL(全局解释器锁)来控制,全局解释器一次只能执行单个线程。在多线程的时候,python虚拟机会先设置GIL-->切换到线程运行-->运行-->将线程设置为睡眠-->解锁,再执行另一线程。
4、内存管理机制?
引用计数:python中变量声明时会为其分配内存,并计数引用次数。当对象引用次数减至0时,该对象成为要被回收的对象。在容器对象中会产生循环引用,会使用标记清除法清除引用环,计算出对象的有效引用计数。(标记-清除算法会有两个链表,root链表和unreachable链表,容器对象会维护两个额外指针,用来将容器对象串成一个链表,根据指针前后容器对象的应用拆除引用环,放入unreachable链表中,如果被判无罪,放入root链表)
循环引用列子:a=[1,2],b=[3,4],a.append(b),b.append(a),del a,del b。a,b两对象的引用次数为2,当执行了del a,b,两对象引用次数减1,仍无法成为被回收的对象,此时标记-清除算法开始起作用,从拆除a,b的引用环,之后a,b的计数减为0,成为垃圾回收对象。
分代回收:频繁GC是相当耗资源的,故为提升GC性能,有分代回收机制。其将对象分为三代,新生对象是0代,当0代经过一次垃圾回收之后仍存活,则升级为1代青年,1代青年经垃圾回收之后存活就成为2代老年。当第0代分配的对象减去释放对象的个数差值大于threshold0,触发一次0代垃圾回收。当第0代被GC的次数大于threshold1,会触发一次第1代的GC。阈值是可以设置的。
内存池:为加速python执行效率,引用内存池管理小块内存的申请和释放。
5、对象储存机制?
数字,短小字符分配内存,相同的值只是增加引用计数,不分配新内存空间,容器对象储存其中对象的指向,不储存实际对象本身。
6、*args 和 **kwargs参数?
当未知函数需要传入多少个参数时,可使用*args,相当于列表;未知会传入多少个关键字参数时,使用**kwargs,相当于字典
7、闭包?
当外函数中定义了一个内函数,内函数中使用了外函数的变量(非全局作用域的),外函数返回内函数的函数调用,这样的结构就形成了闭包。闭包特殊在,一般函数调用结束后,函数内的变量将会被释放掉,但使用闭包,外函数发现内函数使用了自己的临时变量,将会把这个变量绑定给内部函数,然后再结束。当调用外函数,返回的是内函数的引用,一旦外函数被调用过一次,返回的就是内函数的引用;此后实际是调用内函数,使用的是外函数的临时变量,且每次使用的是同一份闭包变量。
8、装饰器?
是在不改变原函数的情况下,给函数新增功能。装饰器装饰函数,返回函数,这个函数是装饰后的函数内嵌原函数的函数。
函数执行前预备处理,函数执行后清理,函数执行时间统计等。
9、生成器,迭代器?
说到迭代器,还有一个可迭代对象的概念,我们可以使用for循环遍历的对象,都是可迭代对象,可迭代对象是指含有iter()或getitem()函数的对象,可迭代对象在迭代时是将对象一次性加载在内存中,然后调用getitem()方法根据索引遍历元素。而迭代器是含有next()方法的对象,迭代器不能使用for循环去遍历,他不会一次性将对象读到内存中,而是需要自己在next()方法中维护索引,调用next()方法实现遍历。生成器是既可以使用for循环遍历,也可以使用next(),在使用next()时他会记录最后一次被调用的位置和数据,读到最后一个后会抛出异常,但是遍历时又不会一次把对象读到内存中。含有yield()函数的对象都是生成器。
列表解析和生成器?
print sum([len(word) for word in str.split()])#列表解析,将分割出的单词长度生成列表后求和
print sum(len(word) for word in str.split())#生成器,性能更优。不会生成列表。是可迭代对象传递给sum函数
10、数组,链表,队列,堆栈?
数组,链表是描述数据的储存方式,数组是在连续空间存储数据,链表是在不连续空间存储数据
队列,堆栈是描述数据存取的方式,队列是先进先出,堆栈是后进先出。
11、is和==?
is是比较两对象的内存地址是否一致,检查是否指向同一对象;==是检查两对象的值是否相等。
12、__init__和__new__?
在实例化对象时,这两个方法都调用了。__new__是创建对象并返回实例对象,当返回对象时会调用__init__初始化;__init__是实例方法
13、上下文管理器,with语句?
一个实现了__enter__和__exit__方法的对象,就是一个上下文管理器。要使用上下文管理器需要执行with语句建立运行时上下文,负责with内语句块进入和退出操作,__enter__是语句块执行前的上下文,__exit__是退出语句块时上下文。如果有as语句,则是将__enter__返回对象赋值给as目标对象。__exit__方法只能返回布尔值,TRUE代表忽略异常,with代码块中不再抛出异常,flase表示需要抛出异常,让其在with代码块中处理异常。
class TestWith():
def __init__(self,a):
self.a=a
def __enter__(self):
print("connect....")
self.a.append("b")
self.a.append("c")
return self.a
#__exit__返回True表示异常已处理,不用再在with代码块中抛异常
#__exit__返回Flase表示异常在with代码块中处理
#无论with代码块中是否发生异常,__exit__函数都会执行
# 后面三个参数贮存发生异常时信息:<class 'ZeroDivisionError'>, division by zero, <traceback object at 0x000001FCBAE63DC8>
def __exit__(self, exc_type, exc_val, exc_tb):
print("close....")
if exc_tb:
print("异常被捕获")
print(exc_type,exc_val,exc_tb)
self.a.pop()
return True
t=TestWith(["a"])with t as tt:#执行__enter__方法,贮存在as中 print(1 / 0) print(tt)#['a', 'b', 'c']#离开with语句,执行__exit__方法print(tt)#['a', 'b']#with open("with.txt","w+") as f:# f.write("hello")#无需再调用关闭,with会在离开这个语句块后自动关闭了
网友评论