【Python 面试突击 · 04】大厂高频面试题:从标准库到多线程陷阱
目录
5、简述 Python 在异常处理中,else 和 finally 的作用分别是什么?
9、Python 中使用多线程可以达到多核 CPU 一起使用吗?
一、基础语法与内置模块篇📚
1、常用的 Python 标准库都有哪些?
🗣️ 推荐话术:
“Python 被称为‘电池 included’语言,其标准库非常强大。我日常开发中常用的是以下几类:
- 系统操作:
os(文件/目录操作)、sys(解释器交互)、pathlib(现代路径操作) - 数据处理:
json(JSON 编解码)、csv、pickle(对象序列化) - 网络通信:
socket、http.client、urllib - 并发编程:
threading、multiprocessing、asyncio - 日期时间:
datetime、time - 正则表达式:
re - 日志记录:
logging - 单元测试:
unittest、doctest - 数学计算:
math、random、statistics
💡 加分项:提到
collections(如Counter,defaultdict,deque)和itertools(高效迭代工具),体现对高级用法的掌握。
2、range 和 xrange 的区别?
🗣️ 推荐话术:
“这个问题要注意 Python 版本差异:
- Python 2:
range()→ 返回一个列表,立即生成所有元素,占用内存大。xrange()→ 返回一个生成器对象,按需生成,节省内存。
- Python 3:
range()→ 行为等同于 Python 2 的xrange(),返回惰性序列对象。xrange()→ 已被移除。
✅ 所以在 Python 3 中,我们统一使用 range(),它既高效又省内存。”
📝 代码对比(Python 2 风格示意):
# Python 2
r = range(1000000) # 立即创建百万元素列表 → 内存爆炸
xr = xrange(1000000) # 只保存起始/结束/步长 → 极简内存
# Python 3
r = range(1000000) # 等价于 Python 2 的 xrange → 安全高效
二、面向对象与函数特性篇🧩
3、Python 中类方法、类实例方法、静态方法有何区别?
🗣️ 推荐话术:
“这三种方法的核心区别在于第一个参数和调用方式:
| 类型 | 装饰器 | 第一个参数 | 调用方式 | 用途 |
|---|---|---|---|---|
| 实例方法 | 无 | self |
obj.method() |
操作实例属性 |
| 类方法 | @classmethod |
cls |
Class.method() |
操作类属性或工厂模式 |
| 静态方法 | @staticmethod |
无特殊参数 | Class.method() 或 obj.method() |
工具函数,不依赖类或实例 |
📝 代码示例:
class MyClass:
count = 0
def instance_method(self):
print(f"实例方法,count={self.count}")
@classmethod
def class_method(cls):
print(f"类方法,count={cls.count}")
cls.count += 1
@staticmethod
def static_method():
print("静态方法,不访问任何类或实例属性")
MyClass.class_method() # 输出: 类方法,count=0
MyClass.static_method() # 输出: 静态方法...
💡 面试加分:提到“类方法常用于替代构造函数(如
from_json()),静态方法用于命名空间分组”。
4、Python 函数调用时参数是值传递还是引用传递?
🗣️ 推荐话术:
“这是一个经典误区题。准确地说,Python 是 ‘对象引用传递’(Pass by Object Reference),既不是纯值传递也不是纯引用传递。
- 对于不可变对象(如 int, str, tuple):行为像“值传递”,函数内修改不影响外部。
- 对于可变对象(如 list, dict, set):行为像“引用传递”,函数内修改会影响外部。
📝 代码验证:
def modify(a, b):
a = 100 # 不可变,局部重绑定
b.append(4) # 可变,原地修改
x = 5
y = [1, 2, 3]
modify(x, y)
print(x) # 5 → 未变
print(y) # [1, 2, 3, 4] → 被修改了!
⚠️ 避坑提醒:不要说“Python 是引用传递”,容易误导;要说“传递的是对象的引用,但赋值行为取决于对象是否可变”。
5、简述 Python 在异常处理中,else 和 finally 的作用分别是什么?
🗣️ 推荐话术:
“在 try-except-else-finally 结构中:
else:当try块没有抛出任何异常时执行。常用于将可能出错的代码与后续逻辑分离。finally:无论是否发生异常都会执行,通常用于资源清理(如关闭文件、释放锁)。
📝 代码示例:
try:
result = 10 / 2
except ZeroDivisionError:
print("除零错误")
else:
print("计算成功:", result) # 只有没异常才执行
finally:
print("无论如何都执行") # 总是执行
💡 最佳实践:
finally是确保资源释放的黄金搭档,比如配合with语句或直接关闭文件句柄。
6、什么是 lambda 函数?有什么好处?
🗣️ 推荐话术:
“lambda 是 Python 中的匿名函数,语法简洁,适合定义简单的一次性函数。
- 语法:
lambda 参数: 表达式 - 好处:
- 简洁:无需
def定义命名函数。 - 适合作为高阶函数的参数(如
sorted,map,filter)。 - 避免污染命名空间。
- 简洁:无需
📝 代码示例:
# 普通函数
def add(x, y): return x + y
# lambda 等价写法
add_lambda = lambda x, y: x + y
# 实际应用:排序
students = [('Alice', 88), ('Bob', 92), ('Charlie', 75)]
sorted_students = sorted(students, key=lambda s: s[1], reverse=True)
⚠️ 注意:
lambda只能包含一个表达式,不能写复杂逻辑或多行语句。复杂功能仍需用def。
三、并发与底层机制篇⚙️
7、Python 中的进程与线程的使用场景?
🗣️ 推荐话术:
“选择进程还是线程,关键看任务类型:
-
多线程(
threading):- 适用于 I/O 密集型 任务(如网络请求、文件读写、数据库查询)。
- 优点:轻量级,共享内存方便。
- 缺点:受 GIL 限制,无法真正并行利用多核 CPU。
-
多进程(
multiprocessing):- 适用于 CPU 密集型 任务(如图像处理、科学计算、加密解密)。
- 优点:绕过 GIL,可充分利用多核 CPU。
- 缺点:进程间通信成本高,内存开销大。
💡 进阶建议:对于高并发 I/O 场景,推荐使用
asyncio协程,性能优于传统多线程。
8、python 中的 pass 有什么作用?
🗣️ 推荐话术:
“pass 是一个空语句,什么都不做,仅作为语法占位符。
- 主要用途:
- 定义空函数/类/条件分支,避免语法错误。
- 作为开发过程中的临时占位,后续再填充逻辑。
- 在继承中表示“暂不重写父类方法”。
📝 代码示例:
class MyBase:
def do_something(self):
pass # 子类必须重写
class MyChild(MyBase):
def do_something(self):
print("实现了具体逻辑")
if True:
pass # 暂时不写逻辑,避免缩进报错
💡 面试加分:提到“
pass不影响程序运行,但能提高代码可读性和结构完整性”。
9、Python 中使用多线程可以达到多核 CPU 一起使用吗?
🗣️ 推荐话术:
“不可以。由于 Python 的 GIL(全局解释器锁) 机制,同一时刻只有一个线程能执行字节码,即使有多核 CPU,多线程也无法实现真正的并行计算。
- 原因:GIL 是为了保护 Python 对象的内存管理而设计的全局锁。
- 影响:CPU 密集型任务中,多线程甚至可能比单线程更慢(因为线程切换开销)。
- 解决方案:
- 使用
multiprocessing多进程绕过 GIL。 - 使用 C 扩展或 Cython 编写关键部分。
- 使用 Jython 或 IronPython(无 GIL,但生态弱)。
- 使用
💡 深度理解:GIL 在 I/O 操作中会释放,所以多线程在 I/O 密集场景依然有效。
10、Python 新式类和经典类的区别?
🗣️ 推荐话术:
“这是 Python 2 到 Python 3 的重要演进:
-
经典类(Classic Class):
- Python 2 默认类,不显式继承
object。 - MRO(方法解析顺序)采用深度优先搜索。
- 不支持
super()的正确多继承调用。
- Python 2 默认类,不显式继承
-
新式类(New-style Class):
- Python 2 中需显式继承
object,Python 3 所有类默认都是新式类。 - MRO 采用 C3 线性化算法,保证单调性和一致性。
- 支持
super()正确调用父类方法,支持描述符、__slots__等高级特性。
- Python 2 中需显式继承
📝 代码对比:
# Python 2 经典类
class OldClass:
pass
# Python 2/3 新式类
class NewClass(object): # Python 3 可省略 (object)
pass
# 查看 MRO
print(NewClass.__mro__) # 显示 C3 线性化结果
💡 结论:Python 3 中无需关心此问题,所有类都是新式类;但在维护旧项目时需留意。
🎯 结语
本系列持续更新中,本期聚焦 Python 核心机制与并发模型,帮助你在面试中不仅“答对”,更能“答深”、“答透”。
✅ 复习重点:
- 参数传递机制 ≠ 值/引用传递
- GIL 是多线程的天花板
- 新式类是 Python 3 的基石
else/finally是异常处理的黄金组合
更多推荐


所有评论(0)