操作系统基础
基础★☆☆⏱ 75 min一句话结论
进程是资源隔离单位、线程是内核调度单位、协程是用户态调度的轻量执行单元——三者按「谁拥有资源、谁被内核调度、谁在用户态切换」分层,切换成本依次降低,隔离性依次减弱。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 概念类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
进程、线程、协程:资源边界和调度主体
操作系统面试里,进程、线程、协程不是三个孤立定义,而是三种不同层次的执行模型。核心问题是:谁拥有资源,谁被内核调度,谁在用户态切换。
| 概念 | 资源边界 | 调度者 | 切换成本 | 适合场景 | 典型风险 |
|---|---|---|---|---|---|
| 进程 | 独立虚拟地址空间、文件描述符、信号处理、资源限制 | 内核 | 最高 | 强隔离、多服务、多 worker、容器主进程 | IPC 成本高,共享状态复杂 |
| 线程 | 共享进程地址空间,独立栈和寄存器上下文 | 内核 | 中等 | CPU 并行、I/O 并发、推理 worker pool | 锁竞争、数据竞争、死锁、false sharing |
| 协程 | 运行在线程内,共享进程/线程资源 | 用户态 runtime | 最低 | 高并发 I/O、异步 RPC、事件循环 | 阻塞调用会卡住调度线程,不能自动利用多核 |
上下文切换到底切什么
| 切换类型 | 需要保存/恢复 | 代价来源 | 排查信号 |
|---|---|---|---|
| 进程切换 | 寄存器、内核栈、页表/地址空间、调度状态 | TLB 失效、cache 污染、内核调度 | pidstat -w、vmstat cs |
| 线程切换 | 寄存器、线程栈、调度状态 | 内核调度、cache 污染、锁等待 | top -H、perf sched |
| 协程切换 | 用户态栈/状态机、少量寄存器 | runtime 调度,通常无需内核态 | runtime profiler、事件循环延迟 |
回答思路:先按资源隔离、调度主体和切换成本三条线回答,再补适用场景。
进程拥有独立地址空间和资源边界,隔离性最好,适合服务拆分和容器主进程,但跨进程通信成本较高。
线程共享进程地址空间,是内核实际调度的执行实体,适合多核并行,但需要处理锁、数据竞争和死锁。
协程是用户态调度的轻量执行单元,适合 I/O 密集和高并发,但单个线程内的协程不能自动利用多核,阻塞调用会影响整个调度线程。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
死锁是一组线程互相持有对方需要的资源、谁都无法继续,需要互斥、持有并等待、不可剥夺、循环等待四个条件同时成立,破坏任意一个即可预防。工程上最实用的是破坏循环等待——所有线程按统一顺序加锁,再用锁超时兜底,比背银行家算法更落地。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 概念类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
死锁:四个必要条件
死锁是指一组进程/线程互相持有对方需要的资源,谁都无法继续。下面四个条件同时满足才会发生,破坏任意一个即可预防。
| 条件 | 含义 | 破坏方式 |
|---|---|---|
| 互斥 | 资源同一时刻只能被一个持有 | 资源可共享化(多数难破坏) |
| 持有并等待 | 持有资源的同时等待新资源 | 一次性申请全部资源 |
| 不可剥夺 | 资源不能被强行抢走 | 允许超时释放、可抢占 |
| 循环等待 | 存在环形等待链 | 按全局固定顺序加锁 |
处理策略:预防 / 避免 / 检测 / 恢复
| 策略 | 做法 | 代价 |
|---|---|---|
| 预防 | 破坏四条件之一(如固定加锁顺序) | 降低并发或资源利用率 |
| 避免 | 运行时判断是否进入不安全状态(银行家算法) | 需预知最大需求,实际少用 |
| 检测 | 构建资源分配图找环 | 检测有开销 |
| 恢复 | 杀进程、回滚、抢占资源 | 有副作用,需可重试 |
大多数业务系统采用预防 + 超时:统一加锁顺序避免大部分死锁,再用锁超时(try_lock + 超时回退)兜底,而不是上线复杂的银行家算法。
经典死锁代码(加锁顺序不一致)
// 线程 A: lock(mutex1) -> lock(mutex2)
// 线程 B: lock(mutex2) -> lock(mutex1) <-- 顺序相反,可能死锁
// 修复:所有线程统一按地址/ID 顺序加锁
std::lock(mutex1, mutex2); // C++ 一次性获取,避免顺序问题
std::lock_guard g1(mutex1, std::adopt_lock);
std::lock_guard g2(mutex2, std::adopt_lock);
死锁排查与活锁/饥饿区分
| 现象 | 特征 | 排查/区分 |
|---|---|---|
| 死锁 | 线程互相等待,CPU 不忙但卡死 | gdb / pstack 看线程栈都停在 lock;jstack(Java)能直接报 deadlock |
| 活锁 | 线程不停重试却都没进展,CPU 很忙 | 加随机退避打破对称 |
| 饥饿 | 某线程长期抢不到资源 | 用公平锁、优先级 aging |
和 AI Infra / 分布式的联系
死锁不只在单机锁里出现:① 分布式训练中,集合通信(如 NCCL all-reduce)要求所有 rank 都参与,如果某个 rank 因异常没进入通信原语,其他 rank 会一直等待,表现为整作业 hang(本质是分布式死锁/挂起);② 资源调度中,多个大作业各占一部分 GPU 又都等不到完整资源,形成资源死锁,需靠 gang scheduling(要么全给要么不给)破解;③ 数据库/分布式锁跨服务加锁顺序不一致同样会死锁。排查训练 hang 常用 py-spy dump / 看各 rank 卡在哪一步。
理论上破坏四个必要条件之一即可,但互斥和不可剥夺往往难破坏。工程上最实用的是破坏循环等待:给所有锁定义全局顺序,任何线程都按同一顺序加锁,环就不可能形成。再辅以锁超时 + 可重试兜底,以及减小锁粒度、缩短临界区、能用无锁结构就用无锁。
集合通信是同步屏障,要求所有 rank 一起到达。如果某个 rank 提前报错退出、走了不同的代码分支、或数据加载卡住没进入 all-reduce,其余 rank 会在通信原语上无限等待,整个作业 hang——这是一种分布式层面的“互相等待”。排查时用 py-spy/栈抓取看各 rank 卡在哪,常见根因是 rank 间逻辑分支不一致或某卡 OOM/异常。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
进程是资源分配单位、线程是执行调度单位、协程是用户态轻量执行流。AI Infra 里这套并发模型直接决定数据加载吞吐和推理服务并发:Python 数据预处理用多进程绕过 GIL,推理前后处理和网络收发用线程池或协程。线程过多反而会让 CPU 时间耗在上下文切换和锁竞争上。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 概念类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:进程、线程与并发模型
AI Infra 面试里,进程、线程和协程不是概念背诵题,而是资源隔离、调度成本、数据加载吞吐和推理服务并发模型的基础。
核心概念定义
| 概念 | 定义 | 面试重点 |
|---|---|---|
| 进程 | 操作系统分配资源的基本单位,有独立虚拟地址空间、文件描述符表、信号处理和权限上下文。 | 隔离性强,崩溃影响小;创建和切换成本高于线程。 |
| 线程 | 进程内的执行流,共享进程地址空间和打开文件,拥有独立栈、寄存器上下文和调度状态。 | 通信方便、切换较轻;需要处理锁竞争、数据竞争和内存安全。 |
| 协程 | 用户态轻量执行流,由语言运行时或框架调度,通常用于大量 I/O 等待型并发。 | 切换不必进入内核;阻塞系统调用会阻塞承载线程,必须配合非阻塞 I/O。 |
| IPC | 进程间通信机制,包括 pipe、socket、shared memory、message queue、signal。 | 共享内存最快但同步复杂;socket 通用但有拷贝和协议开销。 |
| 同步原语 | mutex、rwlock、semaphore、condition variable、barrier 等。 | 要能说明互斥、通知、资源计数、阶段同步分别适合什么场景。 |
需要掌握
- 进程与线程的区别:地址空间、资源隔离、崩溃影响范围、上下文切换成本。
- 用户态线程与内核态线程的区别:用户态切换快,内核态线程可被 OS 真正调度到多核。
- 多进程、多线程在 CPU 密集型和 I/O 密集型任务中的适用场景。
- 线程池为什么存在:避免频繁创建销毁线程,限制并发度,保护下游资源。
- 协程为什么适合网络服务:大量连接多数时间在等待 I/O,用少量线程承载大量逻辑执行流。
- 死锁产生条件:互斥、占有且等待、不可剥夺、循环等待。
上下文切换成本来自哪里
上下文切换要保存和恢复寄存器、程序计数器、栈指针、调度状态。进程切换还可能切换地址空间和页表,破坏 TLB;线程切换虽然共享地址空间,但仍会破坏 cache locality。大量线程竞争锁或频繁阻塞唤醒,会导致 CPU 时间消耗在调度和内核态,而不是业务计算。
AI Infra 相关关注点
- DataLoader 多进程加载数据可以绕过 Python GIL,但会引入进程间队列、pickle/IPC、shared memory 和 copy-on-write 成本。
- Python GIL 会限制纯 Python CPU 密集型多线程并行,训练框架常用多进程、C++ 后端释放 GIL、CUDA 异步执行来绕过。
- 推理服务常用线程池处理 tokenizer、detokenizer、网络收发、日志和业务逻辑;线程过多会造成 context switch 和锁竞争。
- CPU 线程数、NUMA 绑核、DataLoader worker 数量会影响 GPU feeding,CPU 准备 batch 不连续会让 GPU 周期性空转。
- 多 worker 数据预处理要关注队列深度、worker 异常退出、共享内存大小和主进程是否及时消费。
高频问题
进程是资源分配单位,线程是执行调度单位。进程有独立地址空间,隔离性强,适合强隔离、绕过 GIL、崩溃不互相影响的场景;线程共享地址空间,通信方便,适合 I/O 密集、共享状态多、延迟敏感的服务。AI Infra 中,Python 数据预处理常用多进程,推理服务前后处理和网络收发常用线程池或协程。
mutex 是互斥锁,用来保护临界区,一般强调谁加锁谁解锁;semaphore 是计数信号量,用来表示可用资源数量,可以允许多个执行流同时进入。连接池容量、GPU slot、队列容量更像 semaphore;共享 map、调度器状态更新更适合 mutex/rwlock。
CPython 有 GIL,同一时刻通常只有一个线程执行 Python bytecode,所以纯 Python CPU 密集型多线程不能真正并行利用多核。但 I/O 阻塞、C++ 扩展、CUDA kernel launch 等可能释放 GIL,因此训练框架常通过 C++/CUDA 后端、多进程 DataLoader 和异步 pipeline 提升吞吐。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
内存排查不能只看"容量够不够",要同时看四个维度:容量(系统内存/cgroup limit/GPU 显存)、带宽(HBM/内存吞吐)、延迟(page fault/swap/远端 NUMA)和局部性(CPU/GPU/NIC 是否同 NUMA 域)。系统内存、cgroup 可用内存、本地 NUMA 内存、GPU 显存是四个不同的资源池,任何一个不够都可能 OOM 或变慢。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
内存问题不是只看容量
内存排查要同时看系统内存、cgroup limit、GPU 显存、NUMA locality、page cache、swap、带宽和碎片。容量够不代表没有瓶颈。
内存问题基础模型
| 维度 | 看什么 | 典型问题 | 排查入口 |
|---|---|---|---|
| 容量 | 系统内存、cgroup、GPU 显存 | OOMKilled、CUDA OOM | free -h、memory.current、nvidia-smi |
| 带宽 | 内存/HBM 吞吐 | 容量够但吞吐低 | perf、DCGM、Nsight |
| 延迟 | page fault、swap、远端 NUMA | P99 抖动 | vmstat、numastat |
| 局部性 | CPU/GPU/NIC 是否同 NUMA 域 | 跨 socket 访问慢 | numactl -H、nvidia-smi topo -m |
OOM、CUDA OOM 和 cgroup OOM
| 类型 | 资源池 | 触发者 | 现象 |
|---|---|---|---|
| 系统 OOM | 宿主机内存 | Linux OOM killer | 进程被 kill,dmesg 有记录 |
| cgroup OOM | 容器 memory limit | cgroup memory controller | Pod OOMKilled |
| CUDA OOM | GPU 显存 | CUDA runtime / 框架 allocator | 程序抛 CUDA out of memory |
NUMA 是 Non-Uniform Memory Access。多 socket 机器上,每个 CPU socket 有本地内存控制器,访问本地内存快,访问远端内存慢。进程可能被 cpuset、membind、cgroup 或 hugepage 池限制,只能使用部分内存;即使宿主机总内存没用完,也可能因为本地 NUMA node 不足或碎片导致分配失败。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
虚拟内存让每个进程都以为独占连续地址空间,CPU 访问虚拟地址、MMU 通过页表翻译成物理地址,带来隔离、超额使用和按需分配。一句最该记的话:虚拟内存是"承诺",物理内存是"兑现",兑现发生在第一次写入触发缺页时——所以 malloc 1GB 不会立刻占物理内存。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
虚拟内存:每个进程一套“假地址”
虚拟内存让每个进程都以为自己独占一整块连续地址空间。CPU 访问的是虚拟地址,由 MMU 通过页表翻译成物理地址。这带来三个核心价值:进程间隔离、地址空间比物理内存大(靠换页)、按需分配与共享。
| 能力 | 机制 | 意义 |
|---|---|---|
| 隔离 | 每进程独立页表 | 一个进程访问不到另一个进程内存 |
| 超额使用 | page fault + swap | 虚拟空间可大于物理内存 |
| 按需/延迟 | lazy allocation、COW | malloc 不立刻占物理页,fork 不立刻拷贝 |
| 共享 | 多进程映射同一物理页 | 共享库、共享内存 |
分页与地址翻译
内存被切成固定大小的页(通常 4KB),物理内存切成同样大小的页框。页表记录“虚拟页 → 物理页框”的映射。现代 64 位系统用多级页表(如 x86-64 四级)避免单级页表过大。
缺页中断(Page Fault)三种类型
| 类型 | 触发 | 处理 | 代价 |
|---|---|---|---|
| Minor(软) | 页在内存但未建立映射(如 COW、共享页) | 内核补页表项 | 低 |
| Major(硬) | 页不在内存,需从磁盘/swap 读入 | 发起磁盘 I/O 换入 | 高(毫秒级) |
| Invalid | 访问非法地址 | 发 SIGSEGV,进程崩溃 | 段错误 |
排查信号:vmstat 的 si/so 列、/proc/<pid>/stat 的 majflt、perf stat 的 page-faults。Major fault 暴涨通常意味着内存不足开始 swap,P99 会剧烈抖动。
页面置换算法
| 算法 | 思想 | 问题 |
|---|---|---|
| FIFO | 先进先出 | 可能换出热点页,有 Belady 异常 |
| LRU | 淘汰最久未使用 | 精确实现成本高 |
| Clock / 近似 LRU | 用访问位环形扫描近似 LRU | Linux 实际采用的近似方案 |
和 AI Infra 的联系
虚拟内存机制直接影响大模型系统:① pinned memory(页锁定内存)禁止换页,才能让 GPU DMA 安全直传,是 H2D/D2H 拷贝提速的关键;② mmap 加载权重用按需缺页避免一次性读入巨大文件;③ HugePage/THP 减少 TLB miss,对大块连续访问的训练/推理负载有收益;④ 避免 swap,训练进程一旦触发 major fault 换页,吞吐会断崖式下降,所以训练节点通常关 swap。
不会。malloc 通常只是扩大虚拟地址空间(建立映射区),并不立刻分配物理页。只有当你真正写入某一页时,才触发缺页中断由内核分配物理页框(lazy allocation / demand paging)。所以 top 里 VIRT(虚拟)远大于 RES(实际驻留物理)是正常的。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
看内存别只看占用大小,要分清 VIRT 只是承诺、RES 才是真实物理占用、SHR 是共享页、page cache 看似占满但可回收。AI Infra 排查 OOM 和加载慢,关键是区分进程 RSS、page cache、cgroup limit,以及 major fault 这种要走磁盘 I/O 的缺页信号。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:内存管理
AI Infra 的内存问题往往同时涉及虚拟内存、物理内存、page cache、cgroup limit、shared memory、NUMA locality 和 GPU pinned memory。面试回答要能把 Linux 内存机制和训练/推理场景联系起来。
需要掌握
- 虚拟内存、物理内存、地址空间:进程访问虚拟地址,MMU 通过页表翻译成物理地址。
- 分页、页表、TLB、缺页中断:页表保存映射,TLB 缓存地址翻译,缺页中断负责按需分配或换入。
mmap:把文件或匿名内存映射到进程虚拟地址空间,访问时按需触发 page fault。- copy-on-write:fork 后父子进程共享物理页,写入时才复制。
- 堆、栈、内存碎片、内存泄漏:堆用于动态分配,栈用于函数调用,泄漏会让 RSS 持续增长。
malloc/free基本思路:用户态 allocator 管理空闲块,必要时通过brk或mmap向内核申请。- page cache 与 buffer cache:Linux 用空闲内存缓存文件内容,提高重复读取性能。
- swap:内存压力下把匿名页换出到磁盘,但训练/推理任务触发 swap 通常会导致吞吐断崖式下降。
- NUMA:本地内存访问快,远端内存访问延迟高、带宽低。
关键指标
| 指标 | 含义 | 排查意义 |
|---|---|---|
| VIRT / VMS | 虚拟地址空间大小 | 大不代表真实占用物理内存。 |
| RES / RSS | 实际驻留物理内存 | 判断进程真实内存压力的关键。 |
| SHR | 共享页 | 共享库、mmap 权重、shared memory 都会体现在这里。 |
| Page Cache | 文件缓存 | 看似占满内存,但通常可回收。 |
| Major Fault | 需要磁盘 I/O 的缺页 | 权重加载慢、训练抖动的重要信号。 |
| Minor Fault | 不需要磁盘 I/O 的缺页 | 匿名页分配、COW、已有页重新映射。 |
AI Infra 相关关注点
- 大模型训练中的 CPU 内存、GPU 显存、page cache 之间是联动的:CPU 数据准备慢会饿死 GPU,GPU 显存不足会 OOM,page cache 不足会让重复读数据变慢。
mmap加载大模型权重可以避免一次性读取全文件,支持多进程共享 page cache,但访问时可能触发 page fault,导致启动抖动。- fork DataLoader 时,父进程中已有的大对象初始会 COW 共享;worker 一旦写入对象,物理内存会复制,RSS 可能突然增大。
- OOM 定位要区分进程 RSS、VMS、shared memory、page cache、cgroup memory limit、宿主机 OOM 和容器 OOM。
- NUMA 绑定不合理会让 CPU worker 访问远端内存,或者跨 socket 给 GPU 准备数据,导致吞吐下降。
Linux OOM 与容器 OOM
宿主机 OOM 是整机内存压力下由内核 OOM killer 选择进程杀掉;容器 OOM 是 cgroup memory limit 被突破,内核在该 cgroup 内杀进程。容器中 page cache、shared memory、DataLoader worker、日志 buffer、主进程 RSS 都可能共同顶满 limit。
高频问题
虚拟内存提供进程隔离、连续地址空间、按需分配、换页、共享库和 mmap 能力。它让进程看到自己的虚拟地址空间,由 MMU 和页表映射到物理内存。代价是地址翻译需要 TLB/page table,缺页会进入内核,major fault 还会触发磁盘 I/O。
不一定。malloc 可能只是分配虚拟地址或复用 allocator 的空闲块,物理页通常在第一次写入时通过缺页中断分配。可以概括为:虚拟内存是承诺,物理内存是触碰页面后兑现。
Linux 会尽量用空闲内存缓存文件页,提升后续读取性能,所以 free 看到的空闲内存可能很少。但 page cache 通常是可回收的,内存压力来时可以释放。排查时要看 available、cache、cgroup limit 和真正不可回收的 RSS。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
Signal 是内核投递给进程的异步事件,最该记住的是优雅退出这条线:SIGTERM 是可捕获的"协商退出",给应用 flush 日志、保存状态、释放锁的机会;SIGKILL 不可捕获、是强制回收。K8s 删 Pod 就是先 SIGTERM、超过 grace period 再 SIGKILL。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
Signal:进程控制的异步通知机制
Signal 是内核投递给进程的异步事件,可用于终止、暂停、恢复、用户中断、非法访问、定时器和子进程状态变化。
常见 Signal
| Signal | 含义 | 是否可捕获 | 典型场景 |
|---|---|---|---|
| SIGTERM | 请求进程优雅退出 | 是 | K8s 删除 Pod、systemctl stop |
| SIGKILL | 强制杀死 | 否 | grace period 超时 |
| SIGINT | 用户中断 | 是 | Ctrl-C |
| SIGSEGV | 非法内存访问 | 可捕获但通常不恢复 | C/C++ 指针错误 |
| SIGCHLD | 子进程退出 | 是 | 父进程回收子进程 |
stdin/stdout/stderr
| 通道 | fd | 用途 | 容器/K8s 含义 |
|---|---|---|---|
| stdin | 0 | 输入 | 交互式 exec 或管道输入 |
| stdout | 1 | 正常输出 | 容器日志采集主通道 |
| stderr | 2 | 错误和 warning | 容器日志采集主通道 |
先发 SIGTERM 是为了给应用优雅退出机会:停止接新请求、处理完存量请求、flush 日志、保存状态、释放锁。超过 terminationGracePeriodSeconds 仍未退出时,再发不可捕获的 SIGKILL 强制回收资源。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
I/O 多路复用让单线程用一次系统调用同时监听海量 fd、只处理就绪的连接,解决「连接多但大部分空闲」时一连接一线程会线程爆炸的问题;epoll 把 fd 注册一次常驻内核、epoll_wait 只返回就绪 fd,在 C10K/C100K 场景远胜每次都全量拷贝+遍历的 select/poll。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
为什么需要 I/O 多路复用
核心矛盾:一个服务要同时处理成千上万条连接,但大部分连接在大部分时间是空闲的。如果“一连接一线程”,线程数会爆炸、上下文切换成本高;如果阻塞式单线程,一次只能服务一个连接。I/O 多路复用让单个线程用一次系统调用同时监听大量 fd,只在“就绪”时才去处理,是高并发服务器(Nginx、Redis、各类网关)的基石。
五种 I/O 模型(对比)
| 模型 | 阻塞点 | 特点 |
|---|---|---|
| 阻塞 I/O | read 一直等 | 最简单,一连接一线程 |
| 非阻塞 I/O | 轮询返回 EAGAIN | 忙等浪费 CPU |
| I/O 多路复用 | 阻塞在 select/poll/epoll | 一个线程管多个 fd,主流方案 |
| 信号驱动 I/O | 不阻塞,靠 SIGIO 通知 | 实际很少用 |
| 异步 I/O (AIO) | 完全不阻塞,内核完成后通知 | Linux io_uring 是现代代表 |
select / poll / epoll 对比
| 维度 | select | poll | epoll |
|---|---|---|---|
| fd 上限 | FD_SETSIZE(通常 1024) | 无硬上限 | 无硬上限 |
| 数据结构 | 位图 fd_set | pollfd 数组 | 内核红黑树 + 就绪链表 |
| 每次调用开销 | O(n) 拷贝+遍历全部 fd | O(n) 拷贝+遍历全部 fd | O(1) 注册,O(就绪数) 返回 |
| 就绪通知 | 返回后需自己遍历找就绪 | 同 select | 直接返回就绪 fd 列表 |
| 触发模式 | 仅水平触发(LT) | 仅水平触发(LT) | 支持 LT 和边缘触发(ET) |
关键区别:select/poll 每次调用都要把全部 fd 从用户态拷到内核态并线性扫描;epoll 把 fd 注册一次常驻内核红黑树,事件就绪时由回调挂到就绪链表,epoll_wait 只返回就绪的 fd,因此在海量连接、少量活跃的场景下性能远超前两者。
epoll 三个核心系统调用
| 调用 | 作用 |
|---|---|
epoll_create | 创建 epoll 实例,返回 epfd(内核里建红黑树 + 就绪链表) |
epoll_ctl | 对某个 fd 做 ADD / MOD / DEL,注册关心的事件 |
epoll_wait | 阻塞等待,返回已就绪的 fd 列表 |
水平触发 LT vs 边缘触发 ET
| 维度 | LT(水平触发) | ET(边缘触发) |
|---|---|---|
| 通知时机 | 只要缓冲区还有数据就一直通知 | 仅在状态从无到有变化时通知一次 |
| 编程难度 | 简单,可以只读一部分 | 必须循环读到 EAGAIN,否则丢事件 |
| 性能 | 可能重复唤醒 | 唤醒次数少,配非阻塞 fd 用 |
| 典型用法 | 默认、上手快 | Nginx 等高性能服务器 |
Reactor 模式与 AI Infra 关联
Reactor 是基于 I/O 多路复用的事件驱动架构:一个事件循环(event loop)用 epoll 监听所有 fd,事件就绪后分发给对应 handler。这是 Netty、Redis、Nginx、各类 RPC 框架的通用骨架。
在 AI Infra 里这套模型同样无处不在:推理服务网关、参数服务器、KV 存储、调度器的 watch 机制,本质都是“少量线程 + epoll 事件循环”处理海量并发连接。理解 epoll 是看懂这些高性能组件的前提。io_uring 则进一步把网络/磁盘 I/O 改成真正的异步提交-完成队列,减少系统调用次数,是新一代高吞吐 I/O 的方向。
三个关键:
select/poll 每次调用都要把全部 fd 集合从用户态拷到内核态;epoll 用 epoll_ctl 注册一次,fd 常驻内核红黑树。
select/poll 返回后要 O(n) 扫描所有 fd 找就绪的;epoll 用回调把就绪 fd 挂到就绪链表,epoll_wait 直接返回就绪列表,复杂度只和活跃连接数相关。
边缘触发能减少无效唤醒。
不一定。epoll 的优势来自“海量 fd 中只有少量活跃”。如果监听的 fd 很少(比如几十个),或者几乎所有 fd 每次都活跃,epoll 的红黑树维护和回调开销反而不一定占便宜,此时 select/poll 足够。选型要看连接规模和活跃比例。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
一次 read 的路径是:进入内核查 fd 和 page cache,命中就拷给用户 buffer,未命中就发起磁盘或网络存储 I/O 读入 cache 再拷贝。AI Infra 里这条路径决定训练数据加载、checkpoint 和权重加载吞吐,排障要拆到系统调用、page cache miss、磁盘/网络存储延迟、小文件 metadata 和解码这几层。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:文件系统与 I/O
文件系统与 I/O 直接影响训练数据加载、checkpoint 保存、模型权重加载和推理服务吞吐。面试中要能从文件抽象讲到内核路径,再落到性能瓶颈定位。
需要掌握
- inode、目录项、文件描述符:inode 保存文件元数据和数据块位置,目录项把文件名映射到 inode,fd 是进程打开文件后的句柄。
- buffered I/O:
read/write经过 page cache,适合复用和小块读取。 - direct I/O:绕过 page cache,适合应用自管缓存的大文件顺序读写,但要求 buffer、offset、size 对齐。
- sync/async I/O:同步 I/O 调用方等待完成,异步 I/O 提交请求后由完成事件通知。
read/write、pread/pwrite、mmap:pread/pwrite带 offset 且不改变文件偏移,适合多线程并发读写。- dirty page 与
fsync:写入先进入 page cache 形成脏页,fsync强制落盘,可能很慢。 - 顺序读写与随机读写:顺序访问利用预读和连续带宽,随机访问受寻址、队列深度和 metadata 影响。
- SSD/NVMe:延迟低、并发队列强,但小 I/O、同步刷盘、文件碎片仍可能成为瓶颈。
- I/O 多路复用:select、poll、epoll 让少量线程管理大量 fd。
- 零拷贝:sendfile、splice、DMA、mmap 等减少用户态/内核态拷贝和上下文切换。
一次 read 的典型路径
应用调用 read 进入内核;内核检查 fd、文件偏移和 page cache;如果命中,把 page cache 内容拷贝到用户 buffer;如果未命中,提交磁盘或网络存储 I/O,把数据读入 page cache,再拷贝给用户。这个路径可能慢在系统调用、page cache miss、磁盘 I/O、metadata、CPU copy、网络存储或文件格式解码。
AI Infra 相关关注点
- 训练数据读取瓶颈要拆成:磁盘/对象存储带宽、网络存储延迟、文件数量和 metadata、解码、数据增强、CPU worker、batch queue 深度。
- 小文件过多会导致
open/stat/readdirmetadata 开销高,即使总数据量不大也会拖慢 DataLoader。 - checkpoint 保存慢可能来自序列化、CPU 到磁盘写入、网络文件系统、
fsync、单文件过大、并发写冲突。 - 模型权重加载时,
mmap、顺序读、预读、page cache 预热、并行 shard 加载都会影响启动时间。 - 推理服务要把网络 I/O、请求解析、排队、batching、GPU 执行和响应写回解耦。
- 高吞吐服务常用 epoll/事件循环/异步 I/O/零拷贝降低线程数和拷贝成本。
训练时 GPU 利用率低,I/O 层怎么排查
- 看 GPU 利用率是否周期性掉到 0,如果是,常见原因是 batch feeding 不连续。
- 看 DataLoader worker CPU 是否打满,队列是否为空,是否被图像解码或数据增强拖慢。
- 用 iostat 看磁盘 util、await、吞吐;用网络监控看远端存储带宽和延迟。
- 看文件数量和单文件大小,小文件多时优先考虑打包格式或顺序读。
- 看 page cache 命中和 major fault,判断是否频繁从磁盘或网络存储重新取数据。
高频问题
inode 是文件系统中的文件元数据对象,文件名通过目录项映射到 inode。进程 open 文件后得到 fd,fd 指向内核 open file description,其中包含文件偏移和打开模式。多个 fd 可以指向同一个 inode,也可以共享或不共享文件偏移。
select/poll 每次都要传入 fd 集合并线性扫描,epoll 把关注的 fd 注册到内核对象里,就绪事件通过 ready list 返回,避免每次全量扫描,更适合大量连接但少量活跃的高并发服务。
write 返回通常只表示数据进入 page cache,不代表落盘。fsync 要等待脏页写回、文件系统 journal、设备 flush、网络存储确认和其他 I/O 排队。checkpoint 或日志频繁 fsync 会显著影响吞吐和延迟。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
CPU 调度回答的是"下一个时间片给谁"。FIFO/SJF/RR/优先级/CFS 这套单机算法,会原样迁移到 K8s、HPC 和 AI 集群里:SJF 对应短任务优先,RR 对应租户轮转,优先级对应抢占,CFS 对应公平份额。记住 CFS 靠 vruntime 选"最没跑够"的任务,目标是公平和响应而非吞吐。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 概念类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
CPU 调度算法:从单机 OS 到集群调度的共同语言
CPU 调度回答“下一个时间片给谁”。这些算法也会迁移到 K8s、HPC 和 AI 集群里:FIFO 对应队列顺序,SJF 对应短任务优先,RR 对应租户轮转,优先级对应抢占,CFS 对应公平份额。
常见调度算法对比
| 算法 | 规则 | 是否抢占 | 优点 | 缺点 | AI Infra 类比 |
|---|---|---|---|---|---|
| FIFO / FCFS | 先到先服务 | 通常非抢占 | 简单、按到达顺序公平 | 队头阻塞 | 训练队列按提交时间排队 |
| SJF | 运行时间短的先跑 | 通常非抢占 | 降低平均等待时间 | 需要预测,长任务可能饥饿 | 短实验优先、预测驱动调度 |
| SRTF | 剩余时间最短优先 | 抢占式 | 动态到达下等待时间更低 | 抢占成本高 | checkpoint-aware preemption |
| Round Robin | 按时间片轮转 | 抢占式 | 响应性好,避免独占 | 时间片难选,切换开销 | 队列/租户轮转 |
| 优先级调度 | 高优先级先运行 | 可抢占或非抢占 | 表达业务重要性 | 低优任务可能饥饿 | PriorityClass、队列优先级 |
| CFS | 按虚拟运行时间公平分配 CPU | 抢占式 | 兼顾公平和交互响应 | 不是硬实时 | 公平份额、quota、dominant share |
抢占式调度 vs 非抢占式调度
| 维度 | 抢占式 | 非抢占式 |
|---|---|---|
| 定义 | 调度器可以打断正在运行的任务 | 任务主动阻塞、退出或让出 CPU 才切换 |
| 响应性 | 高,适合交互和高优任务 | 低,可能被长任务卡住 |
| 开销 | 上下文切换更频繁 | 切换少,实现简单 |
| 集群类比 | 抢占低优训练任务,可能回滚 checkpoint | 不抢占更稳定,但高优任务等待更久 |
CFS 深挖:vruntime、权重和 runqueue
CFS(Completely Fair Scheduler)的核心思想是:不要只按固定时间片轮转,而是持续维护每个 runnable task 已经获得的“公平份额”。它用 vruntime 表示加权后的虚拟运行时间,倾向于选择 vruntime 最小的任务运行。
| 概念 | 含义 | 面试解释 |
|---|---|---|
vruntime | 加权虚拟运行时间 | 越小表示相对越“没跑够”,越应该获得 CPU |
| nice / weight | 优先级权重 | 权重越高,同样真实运行时间带来的 vruntime 增长越慢 |
| runqueue | 可运行任务队列 | 每个 CPU 有自己的可运行任务集合,CFS 按 vruntime 组织任务 |
| 抢占 | 打断当前任务 | 新唤醒任务或更小 vruntime 任务可能触发重新调度 |
| 上下文切换 | 保存/恢复执行状态 | 线程过多、频繁阻塞唤醒会让 CPU 时间浪费在切换上 |
CFS 的目标是公平和响应性,而不是让某一个任务吞吐最大。这个点和 GPU 的 warp/block 调度形成鲜明对比:GPU kernel 内部通常不追求每个 CUDA thread 的公平时间片,而是追求 SM 吞吐、occupancy 和隐藏内存延迟。
和 CUDA 调度的层次区别
Linux CFS 调度的是 OS task;CUDA Stream/Event 管的是 GPU 任务队列和依赖;CUDA block/warp 调度管的是 kernel 内部如何映射到 SM。这三层经常被混淆。
直觉:短任务放前面,只会让长任务多等一个短任务时间;长任务放前面,会让所有短任务都等一个长任务时间。因此短任务优先能降低平均等待。
SJF 需要知道或预测运行时间,并且会让长任务饥饿。工程上通常用 aging、配额保障或最大等待时间兜底。
CFS 是 CPU 上的操作系统调度器,调度对象是进程或线程,目标是公平性、响应性和 CPU 时间共享;CUDA thread block 调度是 GPU kernel 内部的硬件执行机制,调度对象是 grid 中的 block/CTA,目标是把 block 分配到 SM、让 warp scheduler 用 ready warp 隐藏访存延迟。CFS 通过 vruntime、权重、抢占和上下文切换决定哪个 task 运行;CUDA block 一旦驻留 SM 通常运行到完成,SM 内部以 warp 为单位发射指令,更强调吞吐而不是公平时间片。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
load average 高不等于 CPU 忙,因为 load 同时统计 runnable 和 D 状态不可中断睡眠任务,大量任务卡在磁盘或网络 I/O 也会推高 load。判断 CPU 瓶颈要同时看 load、utilization、run queue、iowait 和 context switch。AI Infra 里数据预处理、tokenizer、序列化和容器 CFS throttling 都可能让 CPU 成瓶颈、拖垮 GPU 喂数据。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 排障诊断类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:CPU 调度与性能分析
AI Infra 里 CPU 不是“辅助资源”。数据预处理、tokenizer、detokenizer、请求调度、网络协议栈、NCCL 辅助线程、checkpoint 序列化都可能让 CPU 成为瓶颈。
需要掌握
- 进程调度基本原理:内核从 runnable 队列中选择下一个任务运行。
- 时间片、优先级、抢占、上下文切换:调度器在公平性、响应时间和吞吐之间取舍。
- CPU load average 与 CPU utilization:load 包含 runnable 和不可中断睡眠任务;utilization 表示 CPU 实际忙碌比例。
- user、system、iowait、steal:分别代表用户态执行、内核态执行、等待 I/O、虚拟化环境被宿主抢占。
- cache locality、CPU cache、false sharing:线程迁移和共享 cache line 会影响吞吐。
- 软中断、硬中断:硬中断来自设备,软中断常用于网络包处理等延后工作。
- perf、top、htop、pidstat、vmstat、sar 等工具的基本使用。
AI Infra 相关关注点
- GPU 训练时 CPU 数据准备不足会让 GPU 空转。
- 高 QPS 推理服务中,CPU 前处理、tokenizer、JSON 序列化、日志和网络协议栈可能成为瓶颈。
- 多线程服务中锁竞争、上下文切换过高、cache miss 过高会导致吞吐下降和 p99 抖动。
- 容器环境下 CPU quota、cpuset、CFS throttling 会让服务“看起来还有 CPU”,但实际被限流。
load high 不等于 CPU busy
Linux load average 会统计 runnable 任务和 D 状态不可中断睡眠任务。大量任务卡在磁盘或网络 I/O,也会推高 load,但 CPU utilization 可能不高。因此判断 CPU 瓶颈要同时看 load、utilization、run queue、iowait、context switch 和线程栈。
高频问题
不一定。load 包含 runnable 和不可中断睡眠任务。I/O 卡住、网络存储慢、D 状态进程多都可能让 load 很高。要结合 CPU utilization、iowait、run queue 和 D 状态进程判断。
iowait 表示 CPU 空闲但系统中有任务在等 I/O。它提示 I/O 可能拖慢任务,但还要结合 iostat 的 await、util、吞吐和应用访问模式判断。训练中 iowait 高常见于数据集读取、checkpoint 或网络存储。
先用 perf top -p <pid> 在线看热点,再用 perf record -g -p <pid> -- sleep 30 采样调用栈,最后用 perf report 或火焰图分析热点是在业务函数、系统调用、锁、内核网络栈、内存拷贝还是调度函数。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
网络基础要能从 socket API 讲到 TCP 状态机,再落到连接池、超时、反压和 RDMA/NCCL 为什么存在。三次握手确认双方收发能力和初始序列号,TIME_WAIT 保证可靠关闭。AI Infra 里分布式训练通信慢要分应用、GPU 拓扑、网络和系统四层排查;RDMA/InfiniBand/NCCL 的存在就是为了绕过传统 TCP/IP 的内核协议栈、CPU copy 和延迟瓶颈。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 概念类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:网络基础与系统调用
网络基础连接分布式训练、推理服务、RPC、存储访问和控制面组件。面试回答要能从 socket API 讲到 TCP 状态,再扩展到连接池、超时、重试、反压和 RDMA/NCCL 为什么存在。
需要掌握
- TCP/IP 基础:三次握手、四次挥手、拥塞控制、流量控制。
- socket 编程流程:socket、bind、listen、accept、connect、read/write、close。
- listen backlog、SYN queue、accept queue:半连接和全连接队列过小会导致连接失败或延迟升高。
- TIME_WAIT、CLOSE_WAIT:TIME_WAIT 用于可靠关闭和旧报文消散;CLOSE_WAIT 常说明应用未 close。
- TCP keepalive、Nagle、reuseaddr/reuseport:分别影响连接保活、小包聚合和端口复用。
- 网络收发包路径:网卡、DMA、硬中断/软中断、协议栈、socket buffer、用户态。
- epoll 在网络服务中的使用。
AI Infra 相关关注点
- 分布式训练通信瓶颈可能来自带宽、延迟、拥塞、丢包、网卡队列、PCIe/NUMA 拓扑、NCCL 算法选择。
- RDMA、InfiniBand、RoCE、NCCL 解决的是传统 TCP/IP 在内核协议栈、CPU copy、延迟和吞吐上的瓶颈。
- 推理服务要关注连接数、长连接、连接池、超时、重试、限流和熔断。
- 大模型服务中的流式输出需要处理慢客户端、发送缓冲区、反压和请求取消。
高频问题
三次握手是客户端 SYN、服务端 SYN+ACK、客户端 ACK,用于确认双方收发能力和初始序列号。四次挥手是主动关闭方 FIN、被动方 ACK,被动方处理完剩余数据后 FIN,主动方 ACK 并进入 TIME_WAIT。
TIME_WAIT 用于确保最后一个 ACK 能被对端收到,并让旧连接残留报文自然消失。过多时先判断是否短连接过多,可通过连接池、长连接、HTTP keepalive、端口范围调整和合理复用缓解,不能简单粗暴关闭安全机制。
LT 是水平触发,只要 fd 仍然可读/可写就会反复通知;ET 是边缘触发,只在状态变化时通知,要求非阻塞 fd 并一次读到 EAGAIN,否则可能遗漏事件。ET 通知少但编程要求更高。
从应用看 batch、梯度大小、通信算法、NCCL 日志;从 GPU 拓扑看 NVLink/PCIe、跨 NUMA、GPU affinity;从网络看带宽、丢包、拥塞、RoCE PFC/ECN、网卡错误;从系统看 CPU 辅助线程、软中断、IRQ 亲和和容器资源限制。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
namespace 管"看见什么"(PID、网络栈、挂载点、IPC),cgroup 管"能用多少"(CPU、内存、I/O、设备),容器隔离就是 namespace + cgroup + rootfs + capability/seccomp 组合出来的。AI Infra 几乎都跑在容器和 K8s 上,所以要能把 OS 知识映射到容器 OOM(exit 137)、CFS throttling、cgroup memory limit 和 /dev/shm 不足这些实际故障。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 机制类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:容器、cgroup 与 Linux 隔离机制
AI Infra 基本运行在容器和 Kubernetes 之上,因此操作系统知识必须能映射到 namespace、cgroup、device plugin、资源限制和容器内外观测差异。
需要掌握
- namespace:pid、net、mnt、uts、ipc、user,负责隔离“看到什么”。
- cgroup:CPU、memory、blkio/io、device、pids,负责限制和统计“能用多少”。
- 容器与虚拟机:容器共享宿主机内核,虚拟机有独立 guest kernel。
- Docker 镜像层与 overlayfs:镜像是只读层叠加,可写层记录容器修改。
- 容器内看到的资源与宿主机资源关系:工具显示可能来自宿主机视角,但实际受 cgroup 限制。
- OOM、CPU throttling、文件描述符限制在容器中的表现。
AI Infra 相关关注点
- Kubernetes 训练任务的 CPU、内存、GPU 资源隔离由 request/limit、cgroup、device plugin 和调度器共同实现。
- 容器 OOM 与宿主机 OOM 不同:容器达到 memory limit 会在 cgroup 内 kill。
- cgroup memory limit 会影响匿名内存、page cache、shared memory,可能出现 page cache 把容器 limit 顶满。
- 多卡训练容器通过 NVIDIA device plugin 暴露 GPU device、驱动库和
CUDA_VISIBLE_DEVICES。 /dev/shm太小会导致 PyTorch DataLoader、共享内存队列或分布式训练异常。
namespace 和 cgroup 的区别
namespace 解决“看见什么”:PID、网络栈、挂载点、主机名、IPC 对象。cgroup 解决“能用多少”:CPU、内存、I/O、进程数和设备。容器隔离通常是 namespace + cgroup + rootfs + capability/seccomp 组合出来的。
高频问题
Docker 主要利用 Linux namespace 隔离进程视图、网络、挂载、IPC、用户等;利用 cgroup 限制和统计 CPU、内存、I/O、设备等资源;利用 overlayfs 提供镜像层和可写层;再配合 capability、seccomp、AppArmor/SELinux 限制权限和系统调用。
先看 Pod 状态、exit code 137、events;再看 cgroup memory.current/memory.max、容器日志和 dmesg;区分主进程 RSS、DataLoader worker、/dev/shm、page cache、shared memory、内存泄漏和 batch size 是否异常。
/dev/shm 是 tmpfs 共享内存。PyTorch DataLoader 多进程、共享内存队列、Ray、某些分布式通信都可能依赖它。空间不足会出现 bus error、worker 异常退出、进程 hang 或吞吐下降。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
GPU 利用率低不能只看一个数:要分层判断到底卡在哪。先看 SM utilization 判断计算单元是否真在工作(显存高只代表被占不代表在算),再看 PCIe/NVLink 吞吐排查 H2D/D2H 或通信瓶颈,再看 CPU worker 和 DataLoader queue 是否供给不足,最后看 NCCL 日志和网络指标。这正是区分 AI Infra 候选人和普通后端的关键。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 概念类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:GPU 训练/推理相关系统层知识
这部分是区分普通后端候选人和 AI Infra 候选人的关键。面试官通常关心你是否理解 CPU、内存、PCIe、GPU、驱动和 CUDA runtime 之间的数据路径,以及系统瓶颈如何影响 GPU 利用率。
需要掌握
- CPU、内存、PCIe、GPU 之间的数据路径:数据通常从磁盘/网络进入 CPU 内存,再通过 PCIe/NVLink 进入 GPU HBM。
- DMA:设备绕过 CPU 指令拷贝,直接在设备和内存之间传输数据。
- pinned memory/page-locked memory:锁定物理页,避免换页,使 DMA 可以稳定访问。
- CPU 到 GPU 数据拷贝瓶颈:可能来自 CPU 解码、内存带宽、PCIe 带宽、pageable memory staging、NUMA 跨 socket。
- NUMA、PCIe topology、GPU affinity:GPU 挂在哪个 CPU socket/PCIe switch 下会影响数据路径。
- GPU 进程、驱动、CUDA runtime:应用通过 CUDA runtime/driver 提交 kernel、内存分配和拷贝。
- 多进程使用 GPU 的资源竞争:显存、SM、显存带宽、copy engine、上下文和 MPS/MIG 隔离。
AI Infra 相关关注点
- DataLoader 中
pin_memory=True可以把 batch 放入 pinned memory,使 H2D 拷贝更高效,尤其配合 non_blocking copy 和 CUDA stream。 - GPU 利用率低要判断是计算、通信、I/O、CPU 预处理、H2D 拷贝还是调度排队瓶颈。
- 多卡训练中 PCIe/NVLink 拓扑决定 GPU 间通信路径,跨 NUMA 或跨 PCIe switch 可能降低 all-reduce 性能。
- 推理服务中 batch、队列、CPU 前处理、GPU 执行、后处理、网络写回需要流水线化。
GPU 利用率低的分层判断
- 看 SM utilization / GPU-Util:低说明计算单元没持续工作。
- 看显存占用:高只代表资源被占,不代表计算忙。
- 看 PCIe/NVLink 吞吐:高可能是 H2D/D2H 或通信瓶颈。
- 看 CPU worker 和 DataLoader queue:CPU 供给不足会导致 GPU 等 batch。
- 看 NCCL 日志和网络指标:分布式训练可能卡在通信。
高频问题
普通 pageable memory 可能被 OS 换页,GPU DMA 不能直接安全访问,驱动通常需要先拷到 pinned staging buffer 再 DMA 到 GPU。pinned memory 锁定物理页,避免换页,使 DMA 可以直接传输,减少额外拷贝并支持异步 H2D。
显存高可能只是模型权重、optimizer state、KV cache 或缓存 allocator 常驻,并不代表 GPU 正在计算。利用率低可能是 DataLoader 慢、CPU 前处理慢、H2D 拷贝没重叠、网络通信等待、batch 太小、请求不足或 kernel launch 间隙大。
GPU 之间可能通过 NVLink、NVSwitch、同一 PCIe switch、跨 PCIe root complex 或跨 NUMA socket 通信,路径不同带宽和延迟差异很大。rank 放置不匹配拓扑时,all-reduce 可能跨慢链路;NIC 和 GPU 不在同一 locality 时,RDMA/GPUDirect 效果也会变差。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
排障要体现分层思维:先界定现象(影响范围、开始时间、是否稳定复现、是 p99 还是吞吐还是 GPU 利用率变坏),再按链路分层拆(应用队列、CPU、内存、I/O、网络、GPU、容器限制、下游依赖),用指标和工具逐层验证假设,最后给优化方案。指标发现异常、日志解释语义、trace 串联请求链路,这套方法对 GPU 空转、p99 抖动、OOM 都通用。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 排障诊断类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
AI Infra 面试模块:系统可观测性与故障排查
AI Infra 面试经常问“线上问题怎么定位”。回答这类问题要体现分层思维:先界定现象,再看资源指标,再抓进程、系统调用、日志和 trace,最后形成假设并验证。
需要掌握
- 常用系统指标:CPU、内存、磁盘、网络、FD、线程数、上下文切换、系统调用耗时。
- 常用命令:top、htop、ps、free、vmstat、iostat、pidstat、sar、ss、lsof、strace、perf、dmesg。
- 日志、指标、trace 的定位思路:指标发现异常,日志解释语义,trace 串联请求链路。
- 系统调用耗时分析:strace 可以看到进程卡在 futex、read、write、poll、connect、fsync 等调用上。
- core dump、gdb 基础:进程崩溃或卡死时查看调用栈、线程状态和锁等待。
AI Infra 相关关注点
- 训练任务卡住:看 GPU、CPU、DataLoader、NCCL 日志、网络、磁盘和进程栈。
- 吞吐下降:看 batch 时间拆分、CPU feeding、H2D、GPU compute、通信、checkpoint 和日志写入。
- GPU 空转:看 DataLoader queue、CPU worker、I/O、网络存储、tokenizer、请求流量。
- OOM:区分 CPU OOM、GPU OOM、容器 OOM、/dev/shm 不足和 allocator fragmentation。
- checkpoint 慢:看序列化、磁盘吞吐、网络存储、fsync、并发写和 dirty page writeback。
- 推理 p99 抖动:拆成排队、batching、CPU 前后处理、GPU 执行、网络、锁竞争、GC、下游依赖。
训练任务 GPU 利用率突然下降如何排查
- 先确认影响范围:单卡、单机、多机,还是所有卡同时下降。
- 看 GPU 指标:SM utilization、显存、PCIe/NVLink、power、temperature、ECC。
- 看 CPU 和 DataLoader:worker 是否打满,队列是否为空,上下文切换是否高。
- 看 I/O:iostat、网络存储、数据集小文件、page fault、解码耗时。
- 看通信:NCCL 日志、网络丢包/拥塞、rank 是否 hang。
- 看应用日志和 trace:是否 checkpoint、eval、日志上报、数据增强异常。
高频问题
先按请求链路拆分:入口排队、网络、鉴权/路由、tokenize、batch scheduler、GPU prefill/decode、detokenize、响应写回。再看资源:CPU、GPU、显存、队列长度、batch size、KV cache、网络连接、锁等待和 GC。最后用 trace 对比 p50/p99 请求,定位是哪一段变长。
先用 ps/top 看进程状态,是 R、S、D 还是 zombie;用 strace -p 看是否卡在 futex、read、poll、connect、fsync;用 pstack/gdb 看线程栈;用 lsof/ss 看 fd 和网络连接;用 dmesg 看 OOM、磁盘、驱动错误。
CPU 瓶颈通常表现为 CPU util 高、run queue 长、perf 热点明显;I/O 瓶颈表现为 iowait、磁盘 await/util 高、read/write 慢、major fault 多;网络瓶颈表现为吞吐接近上限、丢包/重传、RTT 增大、socket buffer 堆积。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。
一句话结论
这页是 OS 模块的收束:准备分三层——概念准确(每个机制能说清解决什么问题、原理、性能代价、在训练/推理里怎么体现)、能结合场景分析(GPU 利用率低、DataLoader 慢、OOM、p99 抖动、通信慢怎么排查)、熟悉 top/iostat/perf/nvidia-smi 等工具链。系统排查题用固定模板回答:先界定现象,再分层拆链路,用指标验证假设,最后给优化方案。
复习定位
| 维度 | 内容 |
|---|---|
| 所属模块 | 操作系统基础 |
| 章节类型 | 面试收束类 |
| 解决问题 | 围绕进程线程、调度、虚拟内存、IO、多路复用、死锁、观测和 AI Infra OS 问题建立系统基础答案。 |
| 面试抓手 | 先讲定义,再讲链路,最后讲 AI Infra 中如何使用或排障。 |
准备方式与最小复习清单
这一页用于最后收束:怎样从概念走到场景分析,面试前最小需要覆盖哪些问题,以及常用工具链。
推荐准备方式
第一层:概念准确
每个模块至少能解释:这个机制解决什么问题;核心原理是什么;有什么性能代价;它在 AI 训练或推理场景中如何体现。
第二层:能结合场景分析
- GPU 利用率低如何排查。
- DataLoader 很慢如何优化。
- 训练任务 OOM 如何定位。
- 推理服务 p99 延迟升高如何分析。
- 分布式训练通信慢如何定位。
- checkpoint 保存很慢如何优化。
- 容器内任务被 OOM kill 如何排查。
第三层:熟悉工具链
top / htop
ps
free
vmstat
iostat
pidstat
sar
ss
lsof
strace
perf
dmesg
nvidia-smi
如果面试偏 Infra 或性能优化,建议进一步了解:
numactl
numastat
ethtool
tcpdump
bcc / bpftrace
nsenter
cgget / systemd-cgtop
最小复习清单
- 进程、线程、协程的区别。
- 线程同步、死锁、锁竞争。
- 虚拟内存、分页、缺页中断、TLB。
- mmap、page cache、copy-on-write。
- Linux OOM 与容器 OOM。
- read/write、mmap、direct I/O 的区别。
- epoll 原理与使用场景。
- CPU load、utilization、iowait、context switch 的含义。
- TCP 三次握手、四次挥手、TIME_WAIT。
- namespace、cgroup、容器资源限制。
- pinned memory、NUMA、PCIe topology 对训练性能的影响。
- GPU 利用率低、服务延迟高、训练 OOM 的排查路径。
系统排查题回答模板
- 先界定现象:影响范围、开始时间、是否稳定复现、p50/p99/吞吐/GPU 利用率哪个变坏。
- 再分层拆链路:应用队列、CPU、内存、I/O、网络、GPU、容器限制、下游依赖。
- 用指标验证假设:用 top、pidstat、iostat、ss、strace、perf、nvidia-smi、日志和 trace 逐层收敛。
- 最后给优化方案:调参数、改并发模型、减少拷贝、增加缓存、调整 NUMA/绑核、优化 I/O 格式、扩容或限流。
关联模块
GPU 硬件与资源共享:提供硬件、显存、互联和利用率诊断基础。LLM 推理系统 / 分布式训练:提供大模型系统中的实际落点。Kubernetes / 调度与集群:提供平台、资源和多租户治理语境。专题综合题 / 论文工作:把基础知识组织成可复述的方案和项目叙事。