面试题答案
一键面试引用计数工作原理
Python 中的每个对象都维护一个引用计数,记录当前指向该对象的引用(变量)的数量。当引用计数变为 0 时,对象所占用的内存就会被立即释放。这是一种实时的垃圾回收方式,优点是回收及时,不会像标记 - 清除或分代回收那样需要暂停程序运行来进行大规模垃圾回收。
引用计数增加的情况
- 变量赋值:当一个新变量被赋值为一个对象时,该对象的引用计数增加。
a = [1, 2, 3] # 列表对象 [1, 2, 3] 的引用计数增加1,因为变量a指向了它
b = a # 列表对象的引用计数又增加1,因为变量b也指向了它
- 作为函数参数传递:对象作为参数传递给函数时,函数内部对该对象的引用会使对象引用计数增加。
def func(lst):
pass
my_list = [4, 5, 6]
func(my_list) # 列表对象 [4, 5, 6] 的引用计数在函数func内增加
- 作为容器对象的元素:当对象被添加到容器(如列表、字典等)中时,该对象的引用计数增加。
d = {'key': [7, 8, 9]} # 列表对象 [7, 8, 9] 的引用计数增加,因为它成为了字典d中一个值
引用计数减少的情况
- 变量被重新赋值:如果变量被赋予新的值,那么原来指向的对象的引用计数就会减少。
c = [10, 11, 12]
c = None # 列表对象 [10, 11, 12] 的引用计数减少1,因为变量c不再指向它
- 变量离开作用域:当变量所在的作用域结束时,变量对对象的引用消失,对象的引用计数减少。
def local_scope():
local_list = [13, 14, 15]
# 函数结束时,local_list离开作用域,列表对象 [13, 14, 15] 的引用计数减少1
local_scope()
- 从容器对象中移除:当对象从容器中移除时,对象的引用计数减少。
my_dict = {'item': [16, 17, 18]}
del my_dict['item'] # 列表对象 [16, 17, 18] 的引用计数减少1,因为它从字典中被移除