python面试常见问题总结。
动态语言
动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明。
python中一切皆对象。
内存管理
- Python利用内存池机制用于管理小块内存的申请和释放;
- 当创建大量占用内存小的对象时,即频繁调用new/malloc,会导致大量内存碎片,致使效率降低,所以需要内存池机制。
- 内存池机制需要在内存中预先申请一定数量的、大小相同的内存块留作备用,当有新的内存需求时,先从内存池中,给这个需求分配内存,如果不够了,就在重新申请。
列表和字典的底层原理
列表
Python中的列表是由对其它对象的引用组成的连续数组。指向这个数组的指针及其长度被保存在一个列表头结构中。这意味着,每次添加或删除一个元素时,由引用组成的数组需要该标大小(重新分配)。幸运的是,Python在创建这些数组时采用了指数分配,所以并不是每次操作都需要改变数组的大小。
字典
CPython使用伪随机探测( 取随机数来作为步长 )的散列表作为字典的底层数据结构。由于这个实现细节,只有可哈希的对象才能作为字典的键。
垃圾回收机制
python利用引用计数实现跟踪和回收垃圾,并在引用计数的基础上,使用“标记-删除”解决容器内部对象的循环引用问题,利用分代回收以空间换取时间进一步提高垃圾回收的效率。
- 引用计数
当一个对象的引用被创建或者复制时,对象的引用计数+1;
当一个对象的引用被销毁时,对象的引用计数-1;
当对象的引用计数为0时,表明这个对象不会再被使用,将其内存释放掉。 - 标记-删除
寻找根对象的集合来作为垃圾检测动作的起点,根对象的集合是全局变量的引用或者函数栈的引用,这些引用所指向的对象不可能被删除;从根对象出发,沿着根对象集合的每个引用,如果某个对象能够到达,就说明这个对象是可达的,可达对象是不会被删除的,这个过程就是垃圾检测阶段;垃圾检测结束之后,所有对象被分为可达和不可达,可达对象被保留,释放所有不可达对象的内存,这就是垃圾回收阶段。 - 分代回收
将系统中所有内存快按其存活时间划分为多个集合,也就是“代”,python默认定义了三代对象集合,活得越久的对象越不可能是垃圾,应该减少对它的垃圾收集频率。
如何衡量“活得越久”:这个对象经过的垃圾收集次数。
迭代器和生成器
迭代器
- 迭代器生成,被迭代一遍之后,里面的元素就被取光了,如果想在用,还得重新生成。
- 迭代器从集合的第一个元素来开始访问,直到访问完所有的元素,只能向前,不能后退。
生成器
生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行。
生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表。一个生成器表达式的例子:
1squares = [x**2 for x in range(5)] # 列表推导式2squares = (x**2 for x in range(5)) # 生成器表达式
装饰器
装饰器是一种函数的函数,因为装饰器传入的参数就是一个函数,然后通过实现各种功能来对这个函数的功能进行增强。
装饰器最大的优势是用于解决重复性的操作,其主要使用的场景有如下几个:
- 计算函数运行时间
- 给函数打日志
- 类型检查
多线程
- GIL(Global Interpreter Lock,全局解释器锁)
待更新…