python高级编程面试题
1. 什么是 GIL?对多线程/多进程意味着什么?
GIL(全局解释器锁)使得同一进程内同一时间只有一个线程在执行 Python 字节码。I/O 密集可用 threading/asyncio;CPU 密集应改用 multiprocessing、C 扩展或 NumPy/Numba/Cython 等释放 GIL。
2. 迭代器 / 可迭代对象 / 生成器的区别?
可迭代对象实现 iter 返回迭代器;迭代器实现 next。生成器是带 yield 的函数,自动实现迭代器协议,支持 send/throw/close。
3. 如何自定义上下文管理器?
实现 enter/exit 或用 contextlib.contextmanager。
from contextlib import contextmanager
@contextmanager
def timer():import time; t=time.time()try: yieldfinally: print(f"{time.time()-t:.3f}s")
- new 与 init 有何不同?
new 负责“创建”实例并返回对象;init 负责“初始化”已创建的实例。不可变类型(如 tuple) 常重载 new。 - super() 的工作原理与 MRO?
super() 按 C3 线性化的 MRO 顺序在继承链上传递调用,避免菱形继承重复初始化。查看顺序:Cls.mro。 - 描述符(descriptor)与 @property 的关系?
描述符实现 get/set/delete 控制属性访问;property 是数据描述符的语法糖。ORM 字段、验证都常用描述符。 - 可变默认参数陷阱与正确写法?
默认参数只在函数定义时求值:
def f(x, acc=None):acc = [] if acc is None else acc
- 浅拷贝/深拷贝的差异?
浅拷贝复制最外层容器引用;深拷贝递归复制。用 copy.copy/copy.deepcopy,注意自定义对象的 deepcopy。 - 装饰器如何保留函数签名与元数据?
用 functools.wraps。
from functools import wraps
def log(fn):@wraps(fn)def wrapper(*a, **k): return fn(*a, **k)return wrapper
- typing 中 Protocol 有什么价值?
定义“结构化子类型”(鸭子类型),避免强耦合到具体类,让库对外露出行为契约,便于测试与替换实现。 - 协变/逆变与常见类型选择?
Sequence[T] 协变、list[T] 不协变;函数参数位置常逆变、返回值常协变。接口设计上多用抽象 Sequence/Mapping 而不是具体容器。 - TypedDict 与 dataclass 何时选用?
TypedDict 适合给“字典结构”加类型,零运行时开销;dataclass 适合需要方法、默认值、排序等“对象语义”的数据模型。 - pyproject.toml 有什么作用?
统一项目元数据与构建后端(PEP 517/518),替代 setup.py;配合 build/pip 打包,便于现代依赖与工具链整合。 - 日志最佳实践?
使用标准库 logging,按模块记录器、设置结构化字段、配置不同 handler/level,避免 print;为异步/多进程准备无阻塞处理(如队列)。 - 如何定位内存泄漏?
用 tracemalloc 对比快照;检查长生命周期全局缓存、闭包引用、循环引用(尤其含 del),以及 C 扩展未释放资源。 - 性能优化常用策略?
剖析→定位热点;向量化(NumPy)、JIT(Numba)、Cython/pybind11;I/O 批处理;数据结构选择;避免 Python 层热循环。 - NumPy 广播规则简述并举例。
自尾维度对齐,尺寸为 1 的维度可扩展。
import numpy as np
a=np.ones((3,1)); b=np.arange(4) # (4,)
c=a+b # 形状变为 (3,4)
- Pandas “链式索引”与 SettingWithCopy 如何避免?
不要 df[df.a>0].b=…;改用 .loc:df.loc[df.a>0, ‘b’]=…,或显式 .copy()。 - asyncio 基本概念:Task、协程、事件循环?
协程是可 await 的对象;Task 是调度中的协程;事件循环负责调度 I/O 与回调。避免在协程内执行阻塞操作。 - 如何在 asyncio 中跑 CPU 密集任务?
用 loop.run_in_executor 或 asyncio.to_thread/ProcessPoolExecutor,避免阻塞事件循环。 - aiohttp/httpx 连接复用与超时配置要点?
复用 ClientSession/AsyncClient;设置连接/读取/总超时;合理的并发窗口与连接池上限,失败重试配合指数退避。 - 多进程与 CUDA 有什么坑?
CUDA 上下文不可安全 fork,应使用 spawn;PyTorch DataLoader 在非 Linux/MPS 下注意 num_workers 与固定种子。 - PyTorch Autograd 工作方式?
构建反向图,记录张量算子;requires_grad 控制跟踪;with torch.no_grad() 关闭记录;inference_mode 更轻量的只读推理。 - DDP vs DataParallel?
DataParallel 单进程多线程,GIL/串行开销大;DDP 多进程多卡、NCCL 通信,边反向边 AllReduce,更高吞吐与稳定性。 - AMP(自动混合精度)如何使用?
autocast() + GradScaler()(FP16),或 BF16 直接 autocast;注意算子稳定性、loss scale、溢出与层归一化精度。 - 模型序列化:state_dict、TorchScript、ONNX 的取舍?
state_dict 通用可复现训练;TorchScript 便于 C++/移动端;ONNX 便于跨框架与推理引擎。动态轴/不支持算子需特别处理。 - 常见量化方式与使用场景?
动态/静态 PTQ、QAT;8bit/4bit(如 bitsandbytes/GPTQ)侧重吞吐与显存;评估精度回退与延迟收益。 - Tokenizer 不匹配会导致什么问题?
分词不一致会造成输入 token 不同、位置编码错配,结果漂移;必须用与训练时一致的分词器与规范化流程。 - FastAPI 如何实现 SSE 流式输出?
StreamingResponse 返回生成器/异步生成器,设置 media_type=“text/event-stream”,按 event:/data: 规范写入,客户端增量渲染。 - Gunicorn/Uvicorn 配置关键点?
选择 --workers(CPU 核心数×2±1 经验值)与 --worker-class uvicorn.workers.UvicornWorker,合理 --timeout/–graceful-timeout,配合反向代理 keep-alive。 - 如何实现动态批处理提升推理吞吐?
网关聚合请求到队列,按时间/数量阈值组批,填充到最大 batch,推理后再分发结果;需考虑超时、QoS 与公平性。 - 如何保证训练/推理可复现?
固定 torch/random/numpy 种子,cudnn.deterministic=True,关闭 benchmark;记录版本、超参、数据快照。 - RAG 典型坑点与缓解?
切片粒度与重叠、索引质量、过长上下文、召回→重排(cross-encoder)、去重、答案引用;预算内做 token 规划与缓存。 - 序列化安全与性能:pickle 与替代方案?
pickle 不安全(可执行代码),仅信任环境使用;跨进程/网络传输用 json/MessagePack/orjson/ormsgpack 等。 - memoryview/零拷贝的使用价值?
通过 memoryview 在不复制的前提下对二进制缓冲区切片;在高吞吐 I/O、编解码场景降低内存与 CPU 消耗。 - 文件映射 mmap 的适用场景?
大文件随机读取、只读模型参数映射;减少峰值内存,利用操作系统页缓存。 - subprocess 与 multiprocessing 选型?
调用外部可执行程序用 subprocess;并行 Python 任务用 multiprocessing。注意超时、管道阻塞与输出回收。 - 重试与幂等设计?
对可重入操作使用幂等键(如请求哈希)、乐观锁或去重缓存;重试采用指数退避 + 抖动,区分可重试与不可重试错误。 - pytest 高级用法?
fixture 作用域、parametrize 参数化、monkeypatch/tmp_path、自定义标记与 -k 选择、xfail/flaky 管理不稳定测试。 - 静态检查与格式化链路推荐?
ruff(lint+fmt)、black(格式化)、mypy/pyright(类型)、pre-commit 挂钩、pip/uv/poetry 锁定依赖版本。 - C 扩展/FFI 的方式?
ctypes/cffi 动态调用;pybind11/Cython 写高性能扩展,暴露 Python API;注意 GIL 管理与异常翻译。 - 在异步服务中限制并发与背压?
asyncio.Semaphore 限制外部并发;内部队列设置最大长度并在满时 await;为下游设置超时与取消,避免雪崩。 - 缓存策略与“缓存击穿/雪崩/穿透”治理?
增加随机过期、互斥锁/单飞、二级缓存、布隆过滤器、防穿透;观察命中率与延迟,冷热分层。 - 导入系统与懒加载?
sys.path、包初始化 init.py、相对导入、importlib 懒加载大型依赖以缩短冷启动;使用 all 控制导出。 - 时区与时间处理的坑?
区分 naive/aware datetime;用 zoneinfo 或 pendulum;序列化统一 UTC,界面显示本地化。 - YAML/模板注入风险?
禁用 yaml.load,改用 safe_load;模板引擎开启 auto-escape;所有外部输入都做白名单/正则限制。 - Token 预算与流式分块输出实现?
在服务端对 prompt 与上下文做截断策略(优先保留高权重内容);输出采用 SSE/WS 增量发送,客户端按段渲染,支持取消。 - Pydantic v1 vs v2 关键差异?
v2 基于 pydantic-core 更快;校验器 API 与 model_validate/field_validator 变化;与 dataclass 集成更一致。 - 多进程的内存模型与“写时复制”(CoW)?
Linux fork 初始共享父进程物理页,写入时复制;Mac/Windows 默认 spawn 不共享内存。共享大对象可用 SharedMemory/mmap/零拷贝。 - 优雅停机与取消(FastAPI/asyncio)?
处理 SIGTERM/SIGINT,在 lifespan/shutdown_event 中关闭连接池、队列与后台任务;对进行中的 SSE/WS 发送终止事件并取消任务。