核心要点
能列举典型可变/不可变类型
理解对可变对象原地修改 vs 重新绑定的区别
知道不可变才可哈希(作 dict 键)的关联
简要回答
不可变对象创建后内容不可变(int/str/tuple);可变对象可原地修改(list/dict/set)。传参时,对可变对象的原地修改会影响调用方。
标准回答
一、先给出结论和背景
- 核心回答:| 不可变 | 可变 |
|--------|------|
| int, float, str, tuple, frozenset, bytes | list, dict, set, bytearray | - 不可变:「修改」实际是创建新对象并重新绑定。如
s += "x"对 str 生成新串。
二、拆开关键步骤和判断点
- 可变:可原地改内容而不改身份。如
lst.append(1)同一id(lst)。 - 传参影响:示例代码可以这样理解:
def f(x, lst):
x += 1 # 绑定新 int,不影响外部
lst.append(1) # 原地改,影响外部
三、补上落地边界和取舍
- 哈希:不可变且实现
__hash__的类型可作 dict/set 的键;可变类型不可哈希。 - 面试陷阱:
tuple不可变,但若元素含可变 list,list 内容仍可改。
回答思路
【定义】用一句话说清「可变对象与不可变对象」
【原理】讲清关键机制或步骤(2~3 点)
【例子】举一个真实项目、论文或产品中的例子
【对比】与易混淆概念或替代方案比较(如有)
【收尾】总结适用场景 + 一个局限或风险
常见误区
⚠️ 常见踩坑
误区一:容易答偏的地方:认为 tuple 内任何情况都完全不可变;修改可变默认参数却以为每次调用独立。
追问
追问 1:字符串拼接为什么推荐 join 而非 +=?
不可变 str 每次 += 都分配新对象,循环中 O(n²)。"".join(parts) 一次分配,O(n)。大文本拼接差异显著。
追问 2:如何「复制」可变对象避免副作用?
浅拷贝:copy.copy() 或 lst[:]、dict.copy()。深拷贝嵌套结构用 copy.deepcopy()。注意深拷贝成本高。
追问 3:frozen dataclass 解决什么问题?
@dataclass(frozen=True) 生成不可变实例,可哈希、可作 dict 键,适合用作 dict 键或 set 元素的值对象(value object)。
🔗 相似问题
同一考点的不同问法,换着练更稳
没找到想看的面试题?把你想看的告诉我们 →
延伸学习
按主题分类的相关资源,便于系统复习
