Skip to content

Python 面试 · 并发与性能 ​


高频问法 ​

  1. GIL 是什么?对你选并发模型有什么影响?
  2. 多线程、多进程、asyncio 怎么选?
  3. CPU 密集任务怎么办?
  4. IO 密集(调很多 API)怎么办?
  5. 为什么说「别在异步里写阻塞代码」?

口述参考 ​

1)GIL ​

CPython 有全局解释器锁,同一进程里同一时刻大致只有一个线程执行 Python 字节码。
所以:纯 Python 计算靠多线程加速有限;等 IO 时线程切换仍能提高吞吐。

2)怎么选 ​

场景更合适
等网络/磁盘多线程或 asyncio
算得凶(图片/加密/大循环)multiprocessing / 进程池,或换 Java/原生扩展
大量并发连接asyncio 常见
要共享复杂可变状态小心锁;进程间用队列更清晰

3)CPU 密集 ​

  • 进程池拆任务
  • 关键路径用更合适的语言/服务
  • 向量化(NumPy)等减少纯 Python 循环

别回答「开 100 个线程就快了」。

4)IO 密集(调模型 API、爬数据) ​

  • concurrent.futures.ThreadPoolExecutor 简单够用
  • 或 asyncio + httpx/aiohttp
  • 一定要:超时、限流、重试退避,否则把对方接口打挂或自己卡死

5)异步里的阻塞 ​

async def 里若调用同步 requests.get 或长时间 time.sleep,会堵住事件循环,其它协程也停。
阻塞调用要放进线程池,或换异步库。


和 Java 对比(加分) ​

  • Java:线程是一等公民,业务服务常用线程池。
  • Python 脚本:快速 IO 并发很香;长期高并发业务服务我仍倾向 Java 生态。

体现你是选型而不是站队。


追问预备 ​

  • 「协程和线程差别?」→ 协程协作式调度、更轻;线程抢占、由系统调度。
  • 「死锁?」→ 多把锁顺序不一致;脚本里尽量少锁,用队列传递数据。