Sunday 的面试指南

进程、线程和协程有什么区别?CPU 密集与 I/O 密集任务怎么选?

🧑‍💻 面试官:进程、线程和协程,有什么不同?

🙋‍♂️ 我:进程主要提供资源隔离,线程是进程里的执行单元,协程可以在等待时让出执行机会。

🧑‍💻 面试官:同时创建一千个协程,是不是就能用上一千个 CPU 核?

🙋‍♂️ 我:不是。并发任务数量和同时执行计算的核心数量不同。

🧑‍💻 面试官:下载文件适合协程,那下载完以后做半分钟图片压缩,还放在同一个事件循环里吗?

先判断任务主要在「等」还是在「算」,再看执行环境能否真正并行,以及能否承受共享状态与调度成本。

面试速答(60 秒版)

进程是操作系统中的资源与隔离单位,通常有独立地址空间;同一进程里的线程共享很多资源,各自有执行状态,可以由操作系统调度。

协程则通常由语言运行时或库安排。任务在合适的位置让出执行机会,运行时再继续其他任务,因此等待网络或数据库的场景可以用较低开销管理较多并发。

但并发不等于并行。单线程上的很多协程,不能让纯计算同时跑满多个核心。CPU 密集任务需要结合多进程、可真正并行的线程、原生计算库或独立工作服务选择。

同时,要注意语言差异。例如常见带 GIL 的 CPython,纯 Python 计算使用多线程未必提速;Node.js 也不能因为使用了 async,就自动把重计算移出主线程。

资源隔离、共享执行和协程调度

知识点详解:下载和压缩,为什么不能用同一套判断?

进程首先隔开了什么?

假设咱们运行两个文件处理进程。它们通常有各自的地址空间,一个进程不能像访问本地变量一样,直接操作另一个进程的对象。

需要交换任务和结果时,可以通过管道、队列、共享内存等方式。隔离更清楚,但启动、通信和内存都可能有额外成本。操作系统的写时复制等机制也会影响具体开销,不能说每个进程都完整复制一份所有数据。

单个工作进程故障时,可以重启它,但外部文件写入和数据库副作用不会因此自动撤销。进程隔离和业务恢复仍是不同问题。

线程共享数据,为什么更容易出竞争?

同一进程的线程可以直接访问共享对象,因此传递数据比较方便。

但两个线程同时更新同一个计数器或者订单状态,就需要处理竞争。线程各自有栈和执行状态,是否能并行计算还取决于语言运行时、代码与硬件。

因此,线程不是“更轻的进程,所以总是更好”。共享内存省下了某些通信,也增加了同步和错误影响范围。

协程在等网络时,怎样让其他任务继续?

假设下载任务 A 正在等待网络返回,这段时间并没有持续做大量计算。协程可以在等待处挂起,运行时切换去推进 B 的下载。

一个线程于是能够交错管理多个等待中的任务。但它通常不是在 A 正执行任意同步代码时,随时把 A 抢占掉;协作式调度需要合适的让出点。

如果下载结束后,A 在事件循环线程上做半分钟同步压缩,其他协程就可能一起卡住。给函数加 async,并不会自动改变这段计算的执行位置。Python 的协程与任务文档解释了事件循环的协作式运行。

CPU 密集任务,怎样真正利用多个核心?

图片压缩、纯计算或大型解析,需要把计算安排到能并行执行的位置。

带 GIL 的常见 CPython 中,纯 Python 字节码计算不会因为多开线程就线性利用多个核心。可以使用进程池,或者使用会释放 GIL 的原生库。free-threaded 构建的行为又不同,所以要说明实际环境,而不是把“Python 线程不能并行”写成永久规则。Python 线程文档与多进程文档说明了这些区别。

Node.js 中,异步网络 I/O 适合事件驱动,但 JS 重计算可以考虑 Worker Threads 或独立进程。这里不展开不同运行时的内部线程数量,先把“等待不占满计算”和“计算需要执行资源”分清楚。

同一个任务可以混用:下载阶段控制异步并发,压缩阶段交给有界工作池。阶段边界要限制队列,避免下载太快,把待压缩文件堆满内存。

网络等待与CPU工作池混合

面试官继续追问

协程是不是完全不需要锁?

不是。即使同一线程中的协程,状态读写之间发生挂起,也可能与其他协程交错。

例如先读余额,等待网络,再写回余额,期间另一个任务可能已经修改。还要结合共享资源的实际操作处理并发,不能把单线程当成业务原子性。

工作池开得越大,是不是越快?

不一定。CPU 核心、内存、连接和下游容量都有上限。

过多工作者可能增加切换、争用和排队。测试时要看完成吞吐与尾部延迟,同时检查内存和失败率,而不是只统计任务创建了多少个。

怎么判断任务主要被什么拖慢?

测量计算耗时、外部等待、队列等待和资源使用。CPU 长时间满载与网络等待很长,是两种不同情况。

先定位主要瓶颈,再换并发模型。数据库已经限流时,多加线程或协程通常只会让请求排得更多。

面试速记卡

  • 进程:资源隔离,跨进程交换数据需要机制。
  • 线程:共享进程资源,需处理同步与运行时限制。
  • 协程:在等待点协作调度,适合大量可异步等待的任务。
  • 并发与并行:任务交错推进,不等于同时使用多个核心。
  • 选择依据:等待、计算、隔离、共享状态与资源上限一起判断。
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历