面试题答案
一键面试- 内存变化分析
obj1
:- 由于直接修改了
obj1.data[1][0]
为 4,obj1.data
列表的引用不变,但是obj1.data[1]
这个子列表中索引为 0 的元素发生了改变,即内存中对应位置的值从 2 变为 4。
- 由于直接修改了
obj2
:- 因为
obj2
是obj1
的浅拷贝,obj2.data
和obj1.data
是不同的列表对象(引用不同),但是obj2.data
中的子列表obj2.data[1]
和obj1.data[1]
是同一个对象(引用相同)。所以当obj1.data[1][0]
被修改为 4 时,obj2.data[1][0]
也会变为 4 ,因为它们指向内存中的同一个子列表对象。
- 因为
obj3
:obj3
是obj1
的深拷贝,obj3.data
以及obj3.data
中的所有子对象(包括obj3.data[1]
)都是全新的对象,与obj1
及其子对象在内存中完全独立。所以修改obj1.data[1][0]
不会影响obj3.data
,obj3.data[1][0]
仍然为 2 。
- 内存占用情况
obj1
:obj1
本身占用一定内存,其data
属性是一个列表对象,列表对象本身占用一定内存,列表中的第一个元素1
占用一个整数的内存空间,第二个元素是一个子列表[2, 3]
(修改后变为[4, 3]
),子列表本身占用一定内存,子列表中的元素分别占用整数的内存空间。
obj2
:obj2
本身占用一定内存,其data
属性是一个新的列表对象,占用一定内存。列表中的第一个元素1
占用一个整数的内存空间,第二个元素与obj1.data[1]
是同一个子列表对象(修改后变为[4, 3]
),所以这部分内存占用与obj1.data[1]
共享。
obj3
:obj3
本身占用一定内存,其data
属性是一个全新的列表对象,占用一定内存。列表中的第一个元素1
占用一个整数的内存空间,第二个元素是一个全新的子列表[2, 3]
,子列表本身占用一定内存,子列表中的元素分别占用整数的内存空间,与obj1
和obj2
的内存空间完全独立。
示例代码(Python)如下:
import copy
class MyClass:
def __init__(self, data):
self.data = data
obj1 = MyClass([1, [2, 3]])
obj2 = copy.copy(obj1)
obj3 = copy.deepcopy(obj1)
obj1.data[1][0] = 4
print("obj1.data:", obj1.data)
print("obj2.data:", obj2.data)
print("obj3.data:", obj3.data)
这段代码运行后,可以直观看到 obj1
、obj2
、obj3
的 data
属性的变化。