AI / Data Infra 知识地图
一份面向系统工程师的学习指南:每章带介绍、该回答的问题,以及用来学的概念、Lab、资料、工具。
语言 · C++ / Rust / Go
C++ 是几乎所有基础设施(数据库、浏览器、游戏引擎、推理运行时)的实现语言,Rust 正在数据库、浏览器、操作系统等领域接替它的位置,Go 则主导了云原生、RPC 和 CLI 工具链。这个模块不求三语样样精通,而是把三者的心智模型放在一起看:内存和生命周期怎么管、并发和异步怎么调度、哪套工具链能真正把你的代码送到 CPU 上。
学完后你应该能回答
C++
- RAII 到底解决了什么问题?为什么说它比 try/finally 或 defer 更彻底?
- unique_ptr / shared_ptr / weak_ptr 各自适用场景?shared_ptr 的引用计数是线程安全的,那它指向的对象呢?
- 移动语义相比拷贝能带来什么?什么情况下一个看起来该 move 的对象其实发生了拷贝?NRVO / RVO 又什么时候能完全消掉拷贝?
- 列举 3 个常见 UB(有符号溢出、越界、严格别名),编译器为什么可以因此删代码?
- memory_order_relaxed / acquire / release / seq_cst 区别是什么?什么时候可以放心用 relaxed?
- 异常 vs 错误码的工程权衡?为什么 Google、LLVM 和很多嵌入式项目都禁用异常?
- 虚函数的 vtable 实现是什么样的?final / override 对编译器去虚化(devirtualization)的实际帮助在哪?
- 两个线程分别写各自的计数器还会互相拖慢吗?怎么用 perf c2c 或 cache-miss 事件确认 false sharing?
- 模板实例化和 concept(C++20)有什么取舍?为什么很多库开始用 concept 替换 enable_if?
- C++20 coroutine 底层长什么样?promise_type、suspend point、coroutine_handle 各做什么?
- constexpr / consteval / if consteval 分别在编译期和运行期起什么作用?
- pimpl 惯用法解决了 ABI 稳定和编译隔离的哪些问题?代价又是什么?
Rust
- ownership + borrow checker 禁止了 C++ 能做的哪些操作?为什么能在编译期消掉 use-after-free?
- Lifetime 标注的作用是什么?什么时候要求你显式写 'a,什么时候会按 elision 规则自动推导?
- 为什么 Rust 不需要 garbage collector?RAII 和 ownership 如何一起保证资源释放?
- Send 和 Sync trait 分别说明了什么?为什么 Rc<T> 不是 Sync 但 Arc<T> 是?
- async/await + Future 的核心是什么?为什么 Rust async 是 zero-cost 但又需要 executor?Pin 又解决了什么?
- Unsafe Rust 开了哪些特权?什么时候不得不用 unsafe?Miri 能帮你发现哪些违规?
- Interior mutability(Cell / RefCell / Mutex)背后的类型系统契约是什么?
- trait object 的 fat pointer 长什么样?为什么不是所有 trait 都能 dyn(object safety 是什么)?
- declarative macro 和 procedural macro 分别适合什么场景?为什么 serde / tokio 离不开 proc-macro?
- 为什么错误是 Result<T, E> 而不是异常?? 操作符等价于什么代码,它和 Try trait 的关系?
Go
- Goroutine 比 OS 线程轻到什么程度?GMP 调度器怎么决定一次抢占?基于信号的异步抢占(1.14+)解决了什么?
- channel 的底层数据结构(hchan)是什么?buffered / unbuffered 在唤醒语义上有什么不同?
- GC 是 concurrent mark-and-sweep,write barrier 解决了什么问题?当前 STW 的典型耗时是多少?
- error 约定为什么不用异常?errors.Is / errors.As / wrap 机制为什么到 1.13 才引入?
- memory model 的 happens-before 是怎么定义的?channel send / receive 的同步语义保证了什么?
- context.Context 的正确用法?cancel 信号怎么穿透到底层 syscall?
- interface 的 itab 是什么?一次 interface 方法调用比普通函数调用贵多少?
- generics(1.18+)是如何实现的?为什么选 GC shape stenciling 而不是每类型一份特化?
- sync.Pool 解决了什么问题?它在 GC 时的行为是什么?
- sync.Map 和 map + Mutex 什么时候各自更快?为什么一般代码不该默认用 sync.Map?
跨语言对比
- 三种错误处理模型(C++ 异常 / Rust Result / Go error)对 API 设计和 ABI 稳定性各有什么影响?
- Rust async、C++ coroutine、Go goroutine 的运行时开销和心智模型差在哪?为什么 Rust / C++ 选 stackless、而 Go 选 stackful?
- C++ RAII、Rust ownership、Go defer 三种资源管理思路的异同?各自能 / 不能处理哪些场景?
- C++ template、Rust generics + trait、Go generics + type constraint 三套泛型机制的编译产物和错误提示差在哪?
- 三种语言的构建系统(CMake / Bazel、cargo、go build)在增量编译、依赖管理、可复现性上的工程取舍?
C++
核心概念
-
用对象生命周期绑定资源释放,是 C++ 资源管理的底层范式。理解它才能看懂智能指针、锁守卫、文件句柄的设计。
-
unique_ptr / shared_ptr / weak_ptr 把裸指针的所有权显式化。正确使用能消掉绝大部分 leak 和 double-free。
-
让昂贵的资源转移而不是深拷贝。读现代 C++ 代码必须理解右值引用、std::move 和返回值优化。
-
const 是类型系统层面的只读契约,不只是注释。接口设计时 const 放的位置直接决定调用方能做什么。
-
模板是 C++ 泛型和零开销抽象的基础,STL 容器 / 算法是你读任何 C++ 项目都会碰到的词汇。
-
搞清楚预处理、编译、汇编、链接四阶段各做什么。链接错误、ODR 违反、符号可见性问题都绕不开这层理解。
-
未定义行为不是 bug 而是编译器可以假设它不发生。知道常见坑(越界、未初始化、别名)才能避开。
-
C++11 起有了正式的内存模型,决定了原子操作的可见性顺序。写任何 lock-free 代码前必须先理解它。
-
CPU 与内存之间的最小传输单位,通常 64 字节。数据结构对齐、padding、热字段聚簇都从这里出发。
-
多个线程改同一 cache line 里的不同字段,会触发 cache line ping-pong。是并发代码里最隐蔽的性能杀手之一。
-
现代 CPU 靠猜下一条指令维持流水线。写 hot path 时尽量让 if 结果可预测,或者改写成无分支。
-
一条指令同时处理多个数据,是向量化的根基。理解它才能读懂 ClickHouse、numpy、ffmpeg 的内循环。
-
多路服务器上,本地节点内存快、远端慢。数据库、JVM、推理引擎都要调 NUMA binding。
-
很多号称 CPU-bound 的任务其实卡在 DRAM 带宽。先用 stream benchmark 和 roofline 画清楚上限。
-
乱序执行、超标量、退休这些概念是理解 IPC、stall、port 竞争的前提。
Lab
- 写一个小型 allocator
手写 bump / freelist / slab 分配器。逼你直面对齐、内存碎片和 placement new 这些平时被库挡住的东西。
- 实现 hash map
不用 std::unordered_map,自己写一个开地址哈希。做完会对缓存局部性、rehash 策略、负载因子有肌肉记忆。
- LRU 缓存
hash map + 双向链表的经典组合,面试常考,也是做内存 / 磁盘缓存的最小原型。
- 最小 shell
fork / exec / wait / pipe / dup2 一次性过一遍。做完你再看 bash 或 systemd 源码就不会陌生。
-
从零用 C 写一个带 GC 的字节码解释器。写完会懂语言运行时、栈帧、垃圾回收是怎么回事。
-
从零实现数据库、Redis、Git 的开源教程集合。工程级 Lab 的好来源。
-
工业级性能工程训练,从 bit hacks 到 cache-aware 算法一路走到底。
-
经典 warm-up:从 naive 三重循环优化到接近 BLAS 的 10-100x。一次把分块、向量化、多线程全摸一遍。
-
挑一个算子(dot product、memcpy、argmax 之类)写 AVX2 / AVX-512 版本,再和编译器输出对比。
资料
-
Scott Meyers 讲 C++11 / 14 的 42 个条款。从老式 C++ 切换到现代 C++ 的最快路径。
-
Bjarne 和 Herb Sutter 主持的官方风格 / 实践清单。遇到设计分歧时能当仲裁者。
-
数据表示、汇编、处理器、内存层级。让你在 C++ 层面看到的问题在机器层面能画得出来。
-
C++ 标准的工作参考手册,比 ISO 文档可读得多。写代码时一直开着就对了。
-
大型 C++ 代码库里怎么写才不会互相伤害的实战指南。不一定全盘接受,但值得读一遍理解为什么这么定。
-
x86 微架构级别的圣经,包含每代 CPU 的指令延迟表和优化建议。
-
Ulrich Drepper 的经典长文,讲 CPU cache、NUMA、prefetch 的内在原理。
-
Intel 官方优化手册。遇到具体微架构问题时的权威查阅处。
-
MIT Leiserson 开的性能工程课,讲义和录像全部开放。
工具
-
Linux 下的标准调试器。看栈、设断点、读寄存器、分析 core dump,基础功每个系统方向的人都要有。
-
LLVM 系调试器,macOS 默认的就是它。和 gdb 命令不完全一样,习惯 Clang 的人值得掌握。
-
编译期插桩的动态检查器,分别抓内存错误、未定义行为、数据竞争。CI 跑一遍能省下无数个调试夜晚。
-
Linux 上采样式性能分析,火焰图把 CPU 热点可视化。性能调优第一站。
-
通过动态二进制翻译检查内存错误,比 ASan 慢但不用重编译。适合分析已发布二进制。
-
基于 Clang AST 的静态检查和自动修复工具。能按 Core Guidelines 或 Google Style 批量扫代码。
-
GCC / Clang 的警告开关,把编译器变成免费的静态分析器。配合 -Werror 是进 CI 的基本礼仪。
Rust
核心概念
-
一个值只能有一个 owner;可以同时有多个 &T 共享引用或一个 &mut T 独占引用,两者不并存。C++ 里所有 lifetime bug 的源头这里被直接禁掉。
-
编译器需要知道引用活多久才能防悬垂。大多数情况推断,剩下要你显式写 'a。
-
类似 Haskell type class + C++ concept。零成本抽象和 trait bound 都走它。
-
没有异常,错误走类型系统。? 操作符让错误传播零样板。
-
marker trait 告诉编译器哪些类型可跨线程、可跨共享引用。数据竞争被编译期消灭。
-
Future 是惰性状态机,tokio / async-std 是轮询它的 executor。zero-cost 但需要运行时。
-
一块 unsafe 换来写 raw pointer、FFI、底层数据结构的能力。大部分标准库背后都有它。
-
Cell / RefCell / Mutex / RwLock 把「外表不可变内部可改」塞进类型系统。
-
match + tagged union 让「不可能的状态」不可表达。
-
宏系统是 serde、tokio、sqlx 生态的基石,也是编译期元编程的官方机制。
Lab
-
官方交互式练习。几小时把 ownership / lifetimes / traits 的肌肉记忆建起来。
-
书里的 grep 克隆、多线程 web server 等练手项目。官方书 + 动手的组合。
-
从零在 x86 上写内核,no_std / unsafe 的实战场景。
-
不用 std::collections,自己实现开地址哈希。把 Rust 泛型和 cache locality 一起摸透。
-
手写一个 tokio 上的 echo / HTTP server,亲历 async 心智模型。
-
官方配套代码样例站,查单点用法特别快。
资料
-
官方书,入门读这一本就够。
-
Jon Gjengset 的进阶书,覆盖 trait 对象、unsafe、async 实战。
-
Blandy / Orendorff / Tindall 的大部头系统入门。
-
官方讲 unsafe Rust 的「黑书」,写 FFI / 底层代码必看。
-
官方 async book,讲清 Future / Pin / executor 为什么长这样。
-
深度直播编程,讲 async runtime、trait 对象等进阶话题。
-
社区周报,追生态和 nightly 特性。
工具
-
包管理 + 构建 + 测试 + benchmark 的统一入口。
-
官方 lint,抓无效模式和风格问题。
-
官方格式化工具。Rust 社区对代码风格争论极少。
-
LSP 服务器,提供 IDE 智能提示 / 补全 / 跳转。
-
MIR 解释器,抓 unsafe 代码里的 UB(越界、未初始化、数据竞争)。
-
展开宏成普通 Rust 代码,调试 proc-macro 必备。
-
一条命令生成火焰图,定位热点。
Go
核心概念
-
M 个 OS thread 上多路复用 G 个 goroutine,内置 work-stealing。
-
goroutine 间通信原语,底层 hchan = ringbuf + 等待队列 + 锁。
-
多路 channel 选择 + 跨层级传递的取消 / 超时信号。
-
隐式鸭子类型,运行时 itab 做方法分派。interface{} / any 是类型擦除。
-
并发三色标记 + write barrier,STW 目标 < 1ms,代价是内存开销和 CPU 占用。
-
退栈时执行 + 异常机制的有限替代,慎用 panic。
-
Mutex / RWMutex / WaitGroup / Once / atomic,标准锁语义。
-
类型参数 + type constraint,迟到但核心。
-
错误是值,errors.Is / errors.As / fmt.Errorf 的 %w 动词做错误链。
-
happens-before 规范,channel / mutex / atomic 的同步保证。
Lab
-
官方交互式教程,2 小时过一遍语法和并发。
-
主题化代码样例站,查 snippet 最快。
-
在 net/http 之上加路由、中间件、context 穿透,能力边界看得清。
-
用 protoc-gen-go 出 stub,实现服务端 + 客户端 + 拦截器,顺带练 proto3。
-
channel + sync 组合的经典练习。
-
Thorsten Ball 的书,从零写 Monkey 解释器,顺带吃透 Go。
资料
-
Donovan / Kernighan 的官方级入门书。
-
官方风格和惯用法指南。
-
进阶细节集合,覆盖大量边角语义。
-
设计决策、新版本分析的第一手来源。
-
工程实践讲义,Go 代码组织和测试的正道。
-
Go 团队 lead 的深度分析,语言和工具链决策都有。
-
happens-before 规范原文,写并发代码前看一遍不亏。
工具
-
一体化工具链,零配置上手。
-
官方静态检查,抓 printf 参数不对等常见错误。
-
格式化 + import 排序。Go 不讨论风格。
-
社区 lint 合集,CI 标配。
-
Go 专用 debugger,看 goroutine、channel 状态必备。
-
集成 profiler,CPU / heap / block / mutex 一把全能抓。
-
加 -race 编译就能跑数据竞争检测,测试里常开。
操作系统
操作系统是所有基础设施坐落的地板:进程怎么调度、内存怎么映射、I/O 怎么多路复用,直接决定了你写的服务的上限。这个模块的目标不是背概念,而是通过 xv6 这种能编译跑起来的教学内核把抽象拆开看一遍,之后再看 Linux 的行为就有参照物。
学完后你应该能回答
进程 / 虚拟内存 / fork
- 进程和线程共享什么、不共享什么?fork 之后的写时复制是怎么实现的?
- 页表多级结构解决了什么问题?一次 TLB miss 的代价大概多大,TLB shootdown 是怎么回事?
- 缺页中断(page fault)的处理流程是什么?major fault 和 minor fault 的区别?
- 从用户态系统调用到内核态执行,中间走过哪些步骤(陷入、上下文切换、返回)?
- Copy-on-write 在 fork 之后的具体时机是什么?一个大内存进程 fork + exec 的代价为什么还相对小?
- huge page / transparent huge page 解决的是什么问题?数据库为什么常常建议关 THP?
- 进程状态 R / S / D / Z 各意味着什么?D 状态为什么连 SIGKILL 都杀不掉?
- ASLR / NX / KASLR 分别在哪一层工作?它们各防哪类攻击?
文件系统 / I/O / 多路复用
- mmap 和 read/write 在性能上的区别是什么?什么场景下应该用 mmap,什么场景下反而更慢?
- epoll 相比 select/poll 的优势在哪?边缘触发(ET)和水平触发(LT)怎么选?
- io_uring 和 epoll 的核心区别是什么?它解决了哪些 epoll 解决不了的问题?
- 零拷贝系统调用(sendfile、splice、tee、MSG_ZEROCOPY)各自适合什么场景?
- 写入磁盘链路 write → page cache → writeback → device queue,fsync / fdatasync 分别等到哪一步?
- ext4、XFS、Btrfs 在日志方式、元数据并发、snapshot 上的主要差异?数据库选型时怎么考虑?
- direct I/O(O_DIRECT)绕开 page cache 的代价和收益?为什么 PostgreSQL 不用它而 MySQL/InnoDB 用?
调度 / cgroup / 容器
- Linux 的 CFS 和 EEVDF 调度器是怎么分配 CPU 时间的?nice 值和 cgroup cpu.weight 的关系是什么?
- cgroup v1 和 v2 的核心差异?容器里的 CPU / 内存限制底层走的是哪些 controller?
- OOM killer 怎么打分(oom_score / oom_score_adj)?为什么内存最多的进程不一定先被杀?
- futex 和用户态 mutex 的关系?无竞争时为什么几乎不走系统调用?
- 容器隔离涉及哪些 namespace(pid / net / mnt / uts / ipc / user)?user namespace 为什么是安全的关键?
- seccomp / capabilities / AppArmor / SELinux 分别在哪一层限制进程?runc 默认拒绝哪些 syscall?
- CFS 的 cpu.cfs_period_us / cpu.cfs_quota_us 组合会产生什么 throttle 现象?在线上延迟敏感服务上为什么常常要关 CPU limit?
性能 & 观测
- 如何用 strace 定位一个卡住的进程?perf 采样和 bpftrace 追踪各适合什么问题?
- USE 方法(Utilization / Saturation / Errors)在排查机器卡顿时具体怎么逐项看?
- perf record 采样栈为什么需要 frame pointer / libunwind / DWARF 三选一?它们各自的 overhead 和准确度差在哪?
- eBPF 为什么被称为"内核里安全跑程序"?verifier 拦住了哪些类型的坑?
- Top-down 方法学四象限(Frontend / Bad Speculation / Backend / Retiring)怎么判断一个热点循环到底卡在哪?
核心概念
-
内核调度的两类基本单位,分别承担隔离和共享的角色。搞清楚它们的地址空间、文件描述符、信号是怎么分的。
-
每个进程看到自己独占的连续地址空间,靠页表和 MMU 映射到物理内存。是理解 fork、mmap、OOM 的前置。
-
inode、目录、日志、页缓存这一套。看懂后你能解释为什么 fsync 贵、为什么小文件多会慢。
-
锁、条件变量、信号量、无锁数据结构。写多线程代码绕不过去,也是 xv6 lock lab 的直接目标。
-
Linux 的高效 I/O 多路复用机制,Nginx / Redis 的事件循环底座。理解 LT / ET 模式是基本要求。
-
Linux 新一代异步 I/O 接口,用共享环形队列把系统调用批处理化。高吞吐存储 / 网络栈正在往这里迁。
-
把文件或匿名内存映射进进程地址空间,共享内存和大文件随机访问的常用手段。用错会带来 SIGBUS 和诡异的页回写。
-
内核把运行时状态暴露成虚拟文件系统。线上排查时 /proc/<pid>/maps、status、stack 是你最常打开的文件。
-
Brendan Gregg 的系统性排查框架:对每个资源看 Utilization / Saturation / Errors。机器卡住时按这三维扫一遍。
-
Intel 的 Frontend / Bad Speculation / Backend / Retiring 四象限分析法。用来判断热点循环到底卡在 CPU 的哪一环。
Lab
-
教学级 Unix-like 内核的实验套件。一套做下来,syscall、页表、锁、文件系统从概念变成你自己改过的代码。
-
用 xv6 的系统调用写小工具(xargs、find 等)。入门热身,熟悉 xv6 工作流。
-
往内核里加一个新系统调用。走完 trap 表、参数传递、返回值的全流程。
-
亲手动 RISC-V 的三级页表。做完你对虚拟地址翻译的理解会从 PPT 级别变成能画寄存器的级别。
-
重构内核里粗粒度锁,优化并发性能。直面锁争用和锁拆分的取舍。
-
在 xv6 里实现 mmap / munmap。懂了之后你再看 Linux mmap 的行为会觉得自然。
资料
-
三段式(虚拟化、并发、持久化)讲 OS,免费在线,语言直白。最适合当主线教材。
-
MIT 操作系统课主页,讲义 / 视频 / lab 全开放。和 OSTEP 搭配食用效果最佳。
-
逐行讲 xv6 源码的配套小册子。做 lab 时的最高频参考。
-
Linux 内核社区的权威新闻站。想追踪调度器、内存、io_uring 等主线演进,这里是唯一选择。
-
Michael Kerrisk 的 Linux 系统编程百科全书。Linux 系统调用行为有疑问时翻它一般都有答案。
-
Linux 系统性能的大百科。CPU / memory / disk / network 四大块按 USE 方法展开。
工具
-
追踪进程发出的系统调用和信号。卡住的进程、文件没打开、网络连不上,先 strace 一把基本不亏。
-
strace 的库调用版,看 libc / 动态库函数调用。排查 glibc 层面的奇怪行为有用。
-
Linux 原生的性能分析工具,采样 CPU、硬件事件、调度延迟。做 profile 的主力。
-
基于 eBPF 的高级追踪语言,一行脚本就能观测内核事件。比 strace 轻,比 perf 灵活。
-
在内核里安全跑沙盒程序的基础设施,bcc 是它的 Python 工具集。现代 Linux 可观测性的事实标准。
-
开源机器模拟器,xv6 就跑在它上面。想 debug 内核或玩其他架构(RISC-V、ARM)都离不开它。
-
内核函数追踪框架。排查系统调用、调度、IO 栈问题的主力,bpftrace 之外的经典路线。
-
把采样栈折叠成可视化图。perf record 之后第一件事就是 flame graph。
网络与 RPC
网络是后端工程师每天都在用、却很少真正读过 RFC 的一层。这个模块的目标不是把你训练成协议专家,而是让你能看懂抓包、能解释一次 HTTPS 请求发生了什么、能判断一个性能问题是出在握手、拥塞控制还是应用层。
学完后你应该能回答
TCP / 传输层
- 为什么三次握手够了、两次不行?四次挥手中的 TIME_WAIT 存在的意义是什么?
- 一条新建的 TCP 连接从慢启动进入拥塞避免的临界点是什么?丢包时 Reno 和 CUBIC 的反应有何不同?
- BBR 和 CUBIC 的核心差异?为什么 BBR 更适合长肥管道,却在短连接主导的场景可能更差?
- Nagle 算法与 delayed ACK 组合会导致什么延迟 anti-pattern?TCP_NODELAY 什么时候该开、什么时候别开?
- MSS / MTU / Path MTU Discovery 的关系?MTU 1500 的链路叠加 VPN 后为什么会卡在 1400 多?
- 在 Wireshark 里如何一眼识别重传、乱序、零窗口这三种常见的 TCP 异常?
- Linux 的 tcp_wmem / tcp_rmem / tcp_mem 三层缓冲区怎么协作?高 BDP 链路上如何调?
HTTP / QUIC
- HTTP/2 的多路复用解决了 HTTP/1.1 的什么问题?为什么它仍然受 TCP 队头阻塞影响,而 HTTP/3 不会?
- QUIC 为什么建在 UDP 上而不是新建一个传输层协议?它如何实现连接迁移?
- 一次 `curl https://example.com` 从 DNS 查询到收到首字节,依次经过哪些系统调用和网络往返?
- HTTP/1.1 的 chunked、keep-alive、pipelining 分别解决什么问题?pipelining 为什么没有流行?
- HTTP/3 的 0-RTT resumption 和 TLS 1.3 0-RTT 有什么关系?应用层要怎么防 replay?
TLS / 加密
- TLS 1.3 相比 1.2 少了哪一轮 RTT?0-RTT 的安全代价是什么?
- mTLS 相比单向 TLS 多做了什么?service mesh 里 sidecar 自动注入 mTLS 的典型流程是什么?
- TLS 握手里 ECDHE、certificate、Finished 分别在做什么?PFS(前向安全)具体由哪一步保证?
- 证书吊销的 CRL / OCSP / OCSP stapling 路径分别有什么延迟 / 可用性问题?
RPC / 应用层
- gRPC 是如何利用 HTTP/2 的 stream 和 trailer 实现双向流和状态码的?
- HTTP retry 的幂等性:哪些方法天然幂等?为什么客户端无脑重试可能引发雪崩?
- gRPC 的 deadline 怎么穿透到所有下游?metadata / header / context 的传播机制是什么?
- 客户端负载均衡(lookaside / proxyless xDS)和经典 L4/L7 代理相比各有什么取舍?
内核网络 / 负载均衡
- Proxy protocol 解决的是什么问题?L4 负载均衡下真实客户端 IP 如何穿透到后端?
- ip_conntrack 表项打满的典型症状?什么场景适合干脆关掉 conntrack?
- Cilium / eBPF 替代 kube-proxy 相比 iptables / IPVS 在性能和可观测性上优势在哪?
- SO_REUSEPORT 和传统 bind 的区别?多进程监听同一端口时内核按什么策略分发?
- Linux 网卡的 RSS / RPS / RFS / XPS 分别在哪一层做流量分发?高 pps 场景怎么调?
- DPDK / XDP / AF_XDP 三条用户态收包路径的性能和编程模型差在哪?
核心概念
-
RFC 9293 是 2022 年合订版的 TCP 规范。读它是为了搞清楚 SYN / ACK / FIN 的状态机,而不是背题。
-
慢启动、拥塞避免、快速重传、快速恢复四件套。所有性能诡异现象几乎都能回到这张状态图上。
-
至今仍是最多服务端实际处理的协议。理解 keep-alive、chunked、管线化的坑是底线。
-
引入了二进制帧、多路复用和 HPACK。了解它才能读懂 gRPC、才知道为什么一个 TCP 卡住会拖垮所有 stream。
-
HTTP 语义跑在 QUIC 上的版本。重点是它如何绕开 TCP 队头阻塞并支持连接迁移。
-
在 UDP 上重建了可靠传输 + 加密 + 多路复用。是理解现代网络栈的新地基。
-
砍掉了一轮 RTT、淘汰了一堆不安全算法。知道它和 1.2 握手差异能帮你看懂几乎所有抓包。
-
请求链路里第一个可能失败的地方。理解递归解析、TTL、缓存是排障的前提。
-
官方文档,一页讲清楚 gRPC 如何编码到 HTTP/2 帧上。比读源码快得多。
Lab
-
用 socket API 实现一个 echo server / client。第一次知道 listen、accept、read、write 的真实形状。
-
从解析请求行开始手写一个能响应 GET 的服务器。会让你对框架的黑盒祛魅。
-
各种从零实现项目的索引。网络相关的几个都值得选一个做完。
-
半小时跑通一个 gRPC 服务,然后去抓包看它到底在 HTTP/2 上发了什么。
-
用官方样本包练习识别握手、重传、TLS ClientHello。看得多了才能在生产抓包里找到线索。
-
分阶段关卡式实现 HTTP,包括持久连接和 gzip。比自己随便写更有约束力。
资料
-
Stevens 的经典。当工具书查,不用通读。
-
Ilya Grigorik 的免费在线书,从物理层一直讲到 HTTP/2。性能视角最清晰的一本。
-
百度开源 RPC 框架的中文设计文档。工业级 RPC 考虑的问题都能在这里找到对应章节。
-
官方博客里有不少关于 retry、xDS、流控的深度文章,比文档更接近工程实践。
-
一线落地者写的 QUIC / HTTP3 调优与踩坑记录。是理解真实部署挑战的最佳素材。
-
socket 编程入门天花板。写得像散文,又把每个 API 讲透了。
分布式系统
分布式系统是讨论「当机器、网络、时钟都可能骗你时,还能得到什么保证」的学问。这个模块的目标是建立词汇表:一致性模型、共识、复制、故障模型,让你在读论文、设计存储或排查线上诡异故障时有共同语言。
学完后你应该能回答
一致性模型 & 理论
- 为什么 CAP 的 C 和 ACID 的 C 不是同一个 C?分区发生时实际工程里如何权衡 A 与 C?
- FLP 不可能性说的是"异步系统无法共识",Raft 为什么又能工作?它到底绕过了哪个假设?
- 线性一致性、顺序一致性、因果一致性、最终一致性,请给出四个能区分它们的具体反例。
- BFT vs CFT 的阈值差异(n ≥ 3f+1 vs n ≥ 2f+1)?区块链之外还有哪些场景必须上 BFT?
- PACELC 相比 CAP 多补了什么维度?它更贴近实际系统选型的哪一面?
共识 & 复制
- Raft 选举时为什么要求候选人日志"至少和大多数一样新"?否则会出什么问题?
- 一个 5 节点集群能容忍几台故障?把集群扩到 7 台能获得什么、失去什么?
- 2PC 的阻塞问题具体是什么场景?Paxos / Raft 如何避免这种阻塞?
- Raft 的 read index 和 lease read 分别怎么实现线性一致读?代价各是多少?
- Joint consensus(共同一致)是什么?为什么 Raft 用它做配置变更而不直接切换?
- Raft snapshot + log compaction 解决了什么问题?follower 落后太多时 install snapshot 的流程是什么?
- Multi-Paxos、EPaxos、Raft 三者在跨地域部署时延迟模型有什么差别?
事务 & MVCC
- 事务隔离级别(RC / RR / SI / SSI / Serializable)各自允许哪些异象?为什么 Snapshot Isolation 不是可串行的?
- Percolator / Omid 等跨分片事务模型的核心思路是什么?和 2PC 有什么差异?
- MVCC 下一次事务看到的快照是怎么确定的?vacuum / GC 为什么是 MVCC 系统逃不开的代价?
- 悲观锁 vs 乐观锁在跨分片事务里的 tail latency 差异?OCCC 在冲突率高的工作负载下为什么会崩?
- Deterministic database(Calvin / FaunaDB)相比两阶段提交减少了什么?代价是什么?
时钟 & 时序
- Spanner 的 TrueTime 给出什么保证?没有 GPS+原子钟的团队该怎么近似实现外部一致性?
- Lamport 时钟、向量时钟、HLC 各自能给出什么保证?HLC 在 CockroachDB 里起什么作用?
- 在最终一致的系统里,如何用版本向量或 CRDT 合并并发写,而不靠时钟?
- NTP 偏移 50ms 会让典型分布式 DB 出什么问题?leader lease 最小能设多短?
工程实践 & 故障
- 一致性哈希 vs range 分片的取舍?虚拟节点(vnode)解决了什么问题?
- Split brain 发生的条件?lease + fencing token 如何组合防止"两个 leader"同时写?
- Jepsen 报告里最常见的五类一致性 bug 是什么?为什么早期 MongoDB 屡屡中招?
- Gray failure(半死节点)相比 crash failure 为什么更难处理?哪些系统有针对性设计?
- Chaos engineering 在生产做成常态化有哪些前置条件?和 Jepsen-style 模型检查的互补点?
核心概念
-
分区发生时,一致性和可用性二选一。被滥用最严重的概念之一,搞清楚它说了什么、没说什么很重要。
-
异步网络 + 一个可能崩溃的节点,就没有确定性共识算法。知道它才理解为什么 Raft 要引入超时。
-
最强的单对象一致性模型:每个操作看起来都在某个瞬间原子生效。etcd、ZooKeeper 提供的就是这个。
-
Dynamo、Cassandra 代表的弱一致性模型。Jepsen 的模型图是这个领域最清晰的一张参考图。
-
绝大多数共识和复制协议的第一步。弄清楚「谁说了算」是所有一致性讨论的起点。
-
把操作变成可回放的日志、复制到多数派、再应用到状态机。现代存储系统的底层模式。
-
R + W > N 这类算术约束。理解它才能推导出一个系统在某种配置下的一致性强度。
-
跨资源事务的经典做法,也是阻塞 / 协调者单点问题的经典反面教材。
Lab
-
在 Go 里从零实现 Raft。做完这个才真正理解选举、日志匹配、安全性这些概念。
-
在 Lab 2 的 Raft 上搭一个线性一致 KV。学会幂等和客户端会话怎么处理重复请求。
-
多 Raft 组 + 分片迁移。接近真实分布式 KV(TiKV、CockroachDB)的架构。
-
PingCAP 设计的分布式系统训练课,偏工程向。是 MIT 课之外的一条实战补充路径。
-
生产级 Go 版 Multi-Raft 库的示例项目。对比自己的 Lab 2 能学到很多工程细节。
-
把一个分布式数据库塞进浏览器跑确定性仿真的案例。看懂它你就懂了现代故障注入测试的上限。
资料
-
Google 文件系统原论文。HDFS 和一大批分布式存储都是它的后代,范式意义大于细节。
-
开启了大数据时代的模型。今天你未必用 MR 了,但它对失败处理、重试的思路影响了一整代系统。
-
刻意为可理解性设计的共识算法。读完加一遍 Lab 2 基本就吃透共识了。
-
Lamport 自己写的「简化版」。虽然仍然烧脑,但是理解 Raft 为什么长那样的必读。
-
全球分布式强一致数据库,TrueTime 是关键创新。现在所有强一致云数据库都在追它。
-
最终一致 KV 的范式。NWR、vector clock、gossip、一致性哈希几个概念集中展示。
-
Kleppmann 的《数据密集型应用系统设计》。这个模块唯一推荐通读一遍的书。
-
DDIA 作者的博客。对一致性模型、时钟、流处理的思考比书里更新、更犀利。
工具
-
Kyle Kingsbury 的分布式系统故障测试框架和博客。写分布式存储的人最该定期读的报告。
-
生产级 Raft 实现,Kubernetes 的底层存储。阅读它的源码比读论文更贴近工程。
-
老牌的协调服务,基于 ZAB 协议。大量老系统的一致性原语(锁、选主)都跑在它上面。
-
Lamport 的形式化规约语言。用来在代码之前把协议模型写出来、让模型检查器帮你找 bug。
-
Kubernetes 上的混沌工程平台。注入网络分区、节点宕机、延迟,用来验证系统真的能挺住。
-
轻量级网络故障注入代理。在集成测试里模拟分区和延迟非常顺手。
Data Infra
数据基础设施关注数据从写入到查询全链路的工程问题:存储引擎如何权衡读写放大,列式格式如何让分析查询更快,流处理如何在乱序和故障下给出正确答案,湖仓表格式如何在对象存储上提供事务语义。掌握这一层,才能读懂现代 OLAP、实时数仓和 Lakehouse 的设计取舍。
学完后你应该能回答
存储引擎(LSM / B+ Tree)
- LSM-Tree 为什么写入快但读可能变慢?compaction 究竟在解决什么问题,它又引入了什么新的放大?
- 同样是索引结构,B+ Tree 和 LSM-Tree 在写放大、读放大、空间放大上各自的典型表现是什么?什么场景该选哪个?
- RocksDB 的 leveled / universal / FIFO compaction 各适合什么写入模式?三种放大怎么权衡?
- LSM 默认会配 bloom filter 的理由?什么情况下 bloom filter 反而拖慢读?
- RocksDB 的 LSM compaction 会放大写入,为什么它还能在 SSD 上跑得比 B-Tree 快?compaction_job.cc 里哪一段最能说明问题?
- Redis 为什么选择单线程 + IO 多路复用而不是多线程?ae.c 和 networking.c 里怎么做延迟 / 吞吐权衡?
- Redis cluster 的 hash slot 和一致性哈希相比,为什么选了定长 16384 slots?
- 近年出现的 FoundationDB / TigerBeetle 这类"确定性仿真"数据库,它们的存储引擎和 RocksDB 有何根本不同?
列存 & 查询执行
- Parquet 为什么要按 row group + column chunk + page 三级切分?Dictionary encoding 和 RLE 分别在什么数据分布下有效?
- Dremel 的 repetition level 和 definition level 解决了嵌套结构列存中的什么问题?为什么不能直接展开成扁平列?
- 向量化执行相比火山模型快在哪里?为什么 ClickHouse 能比 Spark SQL 快一个数量级?
- ORC 和 Parquet 在 footer / stripe / bloom filter 上的差异?为什么 Hive 倾向 ORC 而 Spark 生态倾向 Parquet?
- Arrow 作为内存列存,零拷贝传递相比 Parquet 解决了什么问题?Flight 协议在其中起什么作用?
- ClickHouse 的 MergeTree 是什么层次的"LSM"?primary index、skip index、part 三级结构各自的角色?
流处理(Kafka / Flink)
- Kafka 的 exactly-once 是怎么实现的?idempotent producer、事务、consumer 的 read_committed 各自负责哪一环?
- Flink Watermark 本质是什么?late event 出现时 window 的行为取决于哪几个旋钮(allowedLateness / sideOutput / trigger)?
- Kafka 的 ISR、leader 选举、unclean leader election 对一致性分别意味着什么?
- Kafka tiered storage 把冷数据放到 S3 之后,新的元数据和延迟问题怎么解?
- Flink aligned checkpoint vs unaligned checkpoint 分别解决什么问题?代价是什么?
- event time 和 processing time 混用会产生什么坑?迟到数据和补发如何设计?
- Flink 的 state backend(memory / rocksdb)在 checkpoint 大小和 recovery 时间上的权衡?
Lakehouse / 事务
- Iceberg 和 Delta Lake 是怎么在 S3 这种只有 PUT 的对象存储上做出事务的?snapshot、manifest、commit conflict 解决分别是怎么做的?
- 湖仓在 S3 上的"事务"到底是什么?Iceberg / Delta / Hudi 解决 commit 冲突的机制差别?
- Iceberg 的 metadata JSON + manifest list + manifest 三层结构怎么支持 time travel 和 partition evolution?
- Hudi 的 CoW vs MoR 表各适合什么读写比?和 Iceberg 的 MoR 在 merge 策略上有什么不同?
MVCC / Schema 演进 / CDC
- MVCC 下一次事务看到的快照是怎么确定的?vacuum / GC 为什么是 MVCC 系统逃不开的代价?
- CDC(Debezium 等)为什么要解 binlog / WAL?上游 schema 变更时下游怎么不崩?
- Avro / Protobuf / JSON 在 schema evolution(加字段、删字段、改类型)上的兼容性规则?
- Debezium 的 snapshot + incremental 模式和 "log-only" 模式各适合什么场景?
- dbt 这类"SQL 做 ETL"工具的核心价值在哪?和传统 Airflow + 手写 SQL 相比测试和 lineage 怎么做?
核心概念
-
为写优化的分层存储结构,原始论文。理解 memtable / SSTable / compaction 的分层思路是所有现代 KV(RocksDB、Cassandra、ScyllaDB)的共同前提。
-
传统关系数据库的默认索引结构。和 LSM 对比着读,才能理解为什么 OLTP 和 KV 系统做了不同的工程取舍。
-
分析场景的事实标准列式文件格式。读懂它的 row group / page / encoding,才能理解为什么 OLAP 扫描能比行存快一个数量级。
-
Parquet / BigQuery 嵌套列存的思想源头。repetition / definition level 是处理 JSON-like 嵌套结构的关键。
-
Postgres、MySQL InnoDB、几乎所有现代 OLTP 都靠它实现读写不阻塞。理解快照和可见性规则是读源码的基础。
-
append-only log + segment + index 的经典实现。是流处理、CDC、事件溯源架构的共同底座。
-
流处理中处理乱序事件的核心机制。不理解 watermark 就没法谈 event time 窗口和 late data。
-
分布式流处理最被误解的概念之一。读完这篇能把 idempotent producer、transaction、consumer isolation 串起来。
-
开放 Lakehouse 的事实标准之一。snapshot / manifest / metadata 的设计决定了它怎么在对象存储上做 schema evolution 和 time travel。
-
Databricks 推的另一套 Lakehouse 协议。和 Iceberg 对比读,会看到事务日志设计的不同取舍。
Lab
-
从 buffer pool 写到 B+ Tree 再到事务,是系统性入门数据库内核最好的开源课。
-
用 Rust 一步步实现 memtable、SSTable、compaction。比读论文更能让你摸清 LSM 的细节。
-
几十行代码但在 LSM、数据库、缓存中无处不在。亲手写一遍能理解哈希函数数量和误判率的关系。
-
官方 quickstart 跑一遍,把 topic / partition / offset 的心智模型建立起来,再谈流处理才不虚。
-
最小可跑的 DataStream 例子。用它体会 keyBy、window、watermark 的基本 API。
-
嵌入式 OLAP,本机就能对 Parquet 做向量化查询。拿真实数据集跑 EXPLAIN 看执行计划特别直观。
-
从 ae.c、networking.c、t_string.c 入手,体会单线程事件循环和 SDS / ziplist 的内存打包技巧。
-
LSM-tree 的工业参考实现。先读 LevelDB 把脉络摸清,再跳到 RocksDB 看 compaction、prefix bloom 这些真实场景扩展。
-
列存 + SIMD + 向量化执行引擎的教科书。看 AggregatingTransform 和 ColumnVector 的内循环。
资料
-
嵌套列存和交互式 SQL 引擎的鼻祖论文,BigQuery 的底层思想。
-
HTAP 列存的一次重要尝试,讲清了为什么 OLAP 列存很难同时支持低延迟随机写。
-
列存 OLAP 的开山论文,Vertica 的前身。projection、压缩、排序列的思路至今仍在用。
-
2011 年的原始设计论文。短小但把 log-centric 架构的取舍讲得很清楚。
-
TrueTime + 全球一致性事务的标杆。理解它对后续 CockroachDB、YugabyteDB 的设计有直接帮助。
-
Kleppmann 的《Designing Data-Intensive Applications》,数据系统领域最被推荐的一本综述书。
工具
-
单机向量化 OLAP 引擎。本地分析 Parquet / CSV 非常顺手,也是研究列存执行的好靶子。
-
生产级列存 OLAP 数据库,查询速度是业界标杆。读它的 MergeTree 源码能学到大量工程技巧。
-
工业界最广泛使用的 LSM KV 引擎,被 MySQL、TiDB、CockroachDB、Kafka Streams 等内嵌。
-
kafka-console-producer / consumer / topics 这些命令行工具是排查消息系统的第一手武器。
-
批处理事实标准,也是 Lakehouse 生态的主要计算引擎。理解 Catalyst / Tungsten 能让你懂现代 SQL 优化器。
-
流处理事实标准,state、checkpoint、exactly-once 的工业实现参考。
AI Infra
AI 基础设施关心的是模型怎么真正跑在硬件上:训练怎么把参数、梯度、优化器状态切到多卡多机,推理怎么在 GPU 上把 KV Cache 和调度做得尽量高效,编译器怎么把算子图映射到 CUDA / Tensor Core。掌握这层,才能解释为什么同一个模型跑在不同框架上延迟差几倍,以及成本优化从哪里下手。
学完后你应该能回答
GPU 基础 & CUDA
- CUDA 的 thread / warp / block / grid 是怎么映射到 SM 上的?为什么 block size 一般选 128 或 256 的倍数?
- 什么是 memory coalescing?一次 warp 访存不 coalesce 会导致几倍的带宽浪费?
- HBM / L2 / SMEM / register 各自的带宽和延迟差多少?常见"算子慢"究竟卡在哪一级?
- Roofline 模型里算子是 compute-bound 还是 memory-bound,对 kernel 的优化方向意味着什么?
训练并行
- Data / Tensor / Pipeline 三种并行各自切的是什么?训练 70B 模型时为什么必须组合使用而不能只用 DP?
- ZeRO 1/2/3 分别把什么切开了?它和 FSDP 的关系是什么?通信量相比普通 DP 增加了多少?
- Pipeline parallel 的 bubble 怎么来?1F1B、interleaved 1F1B、zero-bubble 分别怎么压缩 bubble?
- Sequence parallel / context parallel 解决了什么 TP 覆盖不到的问题?
- overlap compute 和 comm 是怎么做的?NCCL 的 stream 和 buffer 配合起来,哪个算子最常挡在关键路径上?
- Gradient checkpointing 用什么换什么?激活重算节省的显存和额外 compute 的比例大概是多少?
推理优化
- KV Cache 占显存的公式是什么?为什么长 context 推理时它比参数本身还大?
- PagedAttention 解决的是 KV Cache 的什么问题?为什么说它把显存利用率从 20-40% 提升到 90%+?
- Continuous batching 和传统 static batching 的区别?为什么它对 LLM 推理吞吐的提升特别大?
- FlashAttention 快在哪里?它本质是算法优化还是访存优化?为什么说它不改变 attention 的数学结果?
- Prefill 和 decode 阶段的计算模式差别在哪?PD 分离部署能带来多大吞吐提升?
- Speculative decoding 的 Medusa / EAGLE / Lookahead 各自怎么生成 draft?加速比受什么限制?
- Prefix cache 在多轮对话和 system prompt 共享时能省多少 KV?和 SGLang 的 radix tree 有什么关系?
精度 & 量化
- 混合精度训练(fp16 / bf16 / fp8)的数值范围差异?为什么 fp16 需要 loss scaling 而 bf16 通常不用?
- INT8 / INT4 / AWQ / GPTQ 几种量化方案的区别?哪些场景精度损失会变得不可接受?
- fp8 训练(Hopper E4M3 / E5M2)相比 bf16 省了多少?收敛风险在哪?
- KV cache 量化到 INT8 / INT4 对长 context 推理延迟的影响?哪些模型架构更容易掉点?
模型架构 (MoE / GQA)
- LoRA / QLoRA 相比全参微调,显存和质量如何权衡?哪些层放 LoRA 性价比最高?
- MoE 的 expert parallel 实现里最难的三个问题是什么(routing、all-to-all、load imbalance)?
- GQA / MQA 相对 MHA 省了什么?为什么几乎所有新模型都选 GQA?
- DeepSeek MoE 的 fine-grained expert + shared expert 相比 Mixtral 的 Top-2 路由有哪些工程差异?
- MLA(multi-head latent attention)在 KV cache 压缩上相对 GQA 多走了什么?
指标 & 评估
- MFU 和 HFU 的区别?工业级训练的典型水平是多少?
- vLLM 的 PagedAttention 为什么能把 KV cache 的显存碎片消掉?它借鉴了操作系统的哪个机制?
- 推理 SLO 该怎么分解:TTFT、TPOT、e2e latency 三者在请求分布不均时会矛盾吗?
核心概念
-
GPU 编程模型的最基础抽象。不理解它就没法谈 kernel 性能调优和 occupancy。
-
warp 是 GPU 调度和执行的最小单位;shared memory 是 block 内线程通信的高速通道,是写高性能 kernel 的核心工具。
-
让一个 warp 的 32 个线程合并成一次访存事务,是 GPU 带宽打满的前置条件。
-
Megatron-LM 系统论文,把三种并行组合使用的工程方案讲得最清楚。训练大模型绕不开。
-
把优化器状态、梯度、参数分片到数据并行组内,是现代大模型训练(DeepSpeed、FSDP)的理论基础。
-
自回归生成必备的中间状态缓存。它决定了 LLM 推理显存的下限和调度的上限。
-
vLLM 的核心贡献,把虚拟内存分页思想用到 KV Cache 上,显著减少碎片。
-
按 token 粒度动态拼 batch,而不是按 request 等齐。对 LLM 推理吞吐的提升通常 2-10 倍。
-
小模型先起草、大模型批量验证,在不改模型质量的前提下降低 latency 的主流手段。
-
通过 tiling 和 recomputation 把 attention 的 HBM 访问降到最低。是过去几年最重要的 kernel 级优化之一。
Lab
-
陈天奇团队的深度学习系统课,从 autograd 一路实现到 CUDA kernel,系统性地过一遍 DL 框架。
-
并行计算经典课,ISPC、CUDA、MPI 都有作业。打底 GPU 编程心智模型的最佳选择。
-
Karpathy 用纯 C / CUDA 实现 GPT 训练。读完对训练 loop、算子实现会有从 PyTorch 黑盒到透明盒的转变。
-
Andrew Chan 的纯 C++/CUDA 单卡推理实现,零外部依赖。Mistral-7B 上 63.8 tok/s,和 llama.cpp 打平甚至更快。llm.c 管训练,yalm 管推理,是同一维度上的互补项目。
-
Sasha Rush 的 14 道交互式小题,专治 warp / shared memory / reduce 这些易错点。几小时能建立 GPU 直觉。
-
一百多行 Python 实现反向传播。理解它之后,PyTorch 的 computation graph 就不再神秘。
-
OpenAI 的 GPU DSL,门槛比 CUDA 低很多。FlashAttention、fused 算子的主流实现语言。
-
PagedAttention、continuous batching 的开源实现。推理性能优化的第一手材料。
资料
-
Vaswani 等人 2017 年的原始 Transformer 论文。所有 LLM 基础设施的共同地基,self-attention、multi-head、positional encoding 都出自这里。
-
NVIDIA 2017 年的 fp16 训练奠基作。loss scaling、master weights 这一整套现代训练默认配置都源自它。
-
Google 的 pipeline parallelism 开山之作,把模型按层切段、micro-batch 流水填充 bubble。今天的 1F1B、interleaved 1F1B、zero-bubble 都是它的迭代。
-
NVIDIA 的大模型训练系统论文。Tensor Parallel 的权威出处。
-
Megatron 团队在 SC'21 的续作,把 data / tensor / pipeline 三维并行在上千块 A100 上跑通。现代大模型训练系统的事实参考架构,几乎所有 LLM 训练团队都以此为起点。
-
DeepSpeed 团队的分片优化器论文。FSDP 和现代大模型训练的理论基础。
-
Google 把 MoE 推到万亿参数规模。Top-1 routing、load balancing loss、expert capacity 的工程选择深远影响了 Mixtral、DeepSeek MoE 等一整代模型。
-
IO-aware 算子设计的教科书案例。读完能理解 HBM vs SRAM 带宽对 kernel 设计的决定性影响。
-
Tri Dao 的 v2:重分配 thread block、压缩非 matmul 指令,A100 上 attention kernel 再快 2x。今天几乎所有推理框架的默认 attention 实现。
-
Hopper 专版:利用 wgmma、TMA 异步、warp specialization,在 H100 上做到接近硬件 SOL 的 fp16/fp8 attention。
-
Continuous batching + iteration-level scheduling 的奠基论文。vLLM、TensorRT-LLM、SGLang 背后所有调度器的思想源头。
-
系统视角看 LLM 推理的里程碑论文。把调度和显存管理问题正式化。
-
Prefill / decode 分离部署的代表作。在延迟和吞吐之间用 PD 解耦做出新的 Pareto 前沿,当前推理栈最重要的架构趋势之一。
-
Leviathan 等人 2022 年的原始论文。小模型起草 + 大模型并行验证的范式,Medusa、EAGLE、Lookahead 都是它的后代。
-
一次前向就能做 INT4 post-training 量化,几乎无精度损失。llama.cpp / HuggingFace 生态里绝大多数 INT4 权重都走这条路。
-
Activation-aware weight quantization:按激活分布挑出"重要 channel"保留高精度。和 GPTQ 各占半壁江山,是当前生产级 INT4 的两大主线。
-
LLVM 团队面向 AI / 异构编译的新 IR 基础设施。理解它有助于看懂现代编译栈的分层。
-
深度学习编译器的代表作,schedule / compute 分离的思想深远影响了 Triton、Halide 社区。
-
yalm 作者 Andrew Chan 的配套长文。从 naive 实现逐层推到工业水平:OpenMP + AVX、warp reduction、kernel fusion、attention kernel、KV cache 量化、手动 unroll 和 prefetch。近几年讲推理优化最清楚的一篇单机视角长文。
工具
-
事实标准的深度学习框架。几乎所有开源模型以 PyTorch checkpoint 为主要发行形式。torch.compile / FSDP2 / DTensor 是当前生态的核心新能力。
-
Google 推的函数式深度学习框架,基于 XLA 编译。在 TPU 和大规模训练(Gemini、Mixtral 等)上优势明显。
-
NVIDIA 的开源大模型训练框架。tensor / pipeline / sequence 并行的参考实现,GPT-3 规模以上训练的共同起点。
-
PyTorch 团队 2024 年推的 native 4D 并行训练库。不依赖 Megatron,直接用 DTensor / FSDP2,是 PyTorch 自己的训练参考实现。
-
微软的训练优化库,ZeRO 的主要实现。训练大模型的常见选型之一。
-
NVIDIA 的 fp8 训练 / 推理 kernel 库,Hopper / Blackwell 上跑 fp8 模型的事实标准。和 Megatron-LM 深度集成。
-
HuggingFace 的多卡 / 混合精度 / FSDP 封装层,适合从单卡到多卡快速过渡。
-
FlashAttention 论文的官方实现(含 v1 / v2 / v3)。PyTorch 2.2+ 的 SDPA 直接集成了它。
-
Meta 开源的高效 Transformer 算子库,memory-efficient attention、SwiGLU、ALiBi 等算子都在里面。
-
写 GPU kernel 比 CUDA 容易一个数量级。生产级 fused attention、量化 kernel 的主要实现语言。
-
当前事实上的 LLM 推理引擎。PagedAttention + continuous batching 的工业实现。
-
NVIDIA 旗舰 LLM 推理引擎。高并发下相比 vLLM 还能再快 30-50%,代价是编译步骤复杂、模型覆盖窄一些。大厂生产推理几乎都在用。
-
后起之秀。RadixAttention 让 prefix cache 命中率极高;在 DeepSeek-V3 等新架构上常跑赢 vLLM。结构化生成 / 多轮对话场景的首选。
-
纯 C/C++ 的本地推理引擎,Mac Metal / CPU / CUDA / Vulkan 通吃。GGUF 格式 + INT4 量化是消费级本地 LLM 的事实标准。
-
HuggingFace 的推理服务,早期最受欢迎的生产方案。官方已转入维护模式、推荐切 vLLM / SGLang,但存量部署仍然巨大。
-
int8 / nf4 量化的事实标准运行时。QLoRA、HuggingFace Transformers 的 load_in_8bit / load_in_4bit 背后都是它。
-
针对 LoRA / QLoRA 的定制 Triton kernel,相比原生 HuggingFace 快 2x、显存少 50%+。消费级 GPU 微调的首选。
-
分布式 Python 计算框架,Ray Train / Ray Serve / Ray Data 一整套 ML 基础设施。vLLM、SGLang 的多机部署都走它。
-
分析训练 / 推理性能的第一道工具,能看到算子级 CPU / GPU 时间和 memory 分配。
-
NVIDIA 官方 GPU profiler。kernel 级性能分析、SM 占用率、访存瓶颈都靠它。
CUDA / GPU 编程
GPU 不是「多核 CPU」,它是为吞吐量设计的大规模并行机器:一个 SM 上几千个寄存器、上百 KB shared memory、上万线程同时在飞。这个模块从硬件视角把 CUDA 的执行模型、内存层级、同步原语拆明白,让你能自己写 kernel、读懂 CUTLASS / FlashAttention 的内循环、从 Nsight Compute 的 metric 就能判断该去哪里优化。
学完后你应该能回答
执行模型 & warp
- kernel launch 从 host 发起到 GPU 开始执行,中间经过哪些层(driver、runtime、queue、command processor、SM)?一次 launch 的固定开销大概是多少?
- SM 里的 warp scheduler 每 cycle 发射几条指令?occupancy 100% 就一定最快吗?为什么 Volta 之后 occupancy 的重要性被削弱了?
- Warp divergence 是什么?同一 warp 里 16 个线程走 if、16 个走 else,硬件怎么执行?开销大致是多少?
- Cooperative Groups / grid.sync 适合什么场景?它和 persistent kernel 的组合能消掉什么 launch 开销?
- CUDA Graph 相比 per-launch 的收益主要来自哪?什么情况下它没有明显收益?
内存层级 & 访存
- Shared memory 的 bank conflict 是怎么产生的?一个 warp 里 32 个线程访问同一 bank 不同地址,会被串行成几次事务?
- Register / Shared / L1 / L2 / HBM 的延迟和带宽大致分别是多少?给一个数据重用模式,你会把它放在哪一级?
- SM 上 shared memory 和 L1 合计 ~192 KB,kernel 配置怎么避免 register spill 落到 local memory?
- 向量化加载(float4、ldmatrix)能带来多大带宽提升?为什么写 GEMM 几乎必用?
- Unified memory(cudaMallocManaged)的 page migration 代价是什么?哪些场景应退回显式 cudaMemcpy?
- async copy(cp.async)相比传统 global→shared 走 register 的路径省了什么?Ampere 和 Hopper 的差别?
Tensor Core / MMA
- Tensor Core 和普通 CUDA Core 的区别?wmma API 和直接写 mma PTX 指令各自的适用场景是什么?
- CUTLASS 3.x 的 CuTe 布局抽象相较 2.x 的 tile iterator 有哪些质的区别?
- wgmma(Hopper)相对 mma(Ampere)在执行粒度和异步性上的根本区别?
- FlashAttention-3 在 Hopper 上为什么又能快 1.5-2x?用到了 warp specialization 和 wgmma 的哪些特性?
多卡通信
- cudaStream 之间的并发是怎么实现的?event / graph / barrier 三种同步方式各自的代价?
- NCCL 的 ring all-reduce 为什么在 NVLink 集群上能接近硬件带宽?到 64 卡规模时 tree 算法会不会更优?
- NVSwitch、NVLink、PCIe、InfiniBand 四种互联带宽/延迟量级大致是多少?训练集群怎么组拓扑?
- SHARP(NVIDIA in-network reduction)相比传统 ring all-reduce 能省多少?部署约束是什么?
新硬件 (Hopper / Blackwell)
- Hopper 引入的 thread block cluster、distributed shared memory 提供了以前做不到的什么能力?
- TMA 的 swizzling 有哪几种?为什么配合 wgmma 时必须选对?
- fp8 tensor core(Hopper FP8 / Blackwell FP4)在训练 / 推理里有什么额外精度约束?
- Blackwell 的 2nd-gen Transformer Engine 和 FP4 tensor core 相比 Hopper 升级了什么?
- MPS (Multi-Process Service) 解决什么问题?和 MIG 在用法和隔离性上怎么取舍?
调优工具
- Nsight Compute 里 SOL(Speed of Light)指标怎么解读?long scoreboard / short scoreboard / barrier 各对应什么根因?
- Nsight Systems 的 timeline 上怎么看出 CPU 发射不够快 vs GPU 真正闲着?
- nvcc 的 --ptxas-options=-v 输出里哪些字段最能指导你调 occupancy 和寄存器预算?
核心概念
-
一个 SM 上的执行单元、寄存器文件、L1 / shared memory 布局直接决定 kernel 设计。搞清楚 SM 数量、warp 宽度、寄存器预算是所有调优的起点。
-
一个 block 在哪个 SM 上跑、一个 warp 怎么被调度,决定了 occupancy 和 latency hiding。不仅是概念,更要看它如何映射到硬件。
-
Register / Shared / L1 / L2 / Global / HBM 的带宽和延迟差两三个数量级。90% 的 GPU 性能优化都在回答「这块数据放哪一级」。
-
让一个 warp 的 32 个线程合并成一次 global memory 事务,是 HBM 带宽打满的前置条件。
-
shared memory 被划分成 32 个 bank,同一 bank 的不同 word 会串行。padding 和 swizzle 是消冲突的两种标准手段。
-
shfl_sync / ballot_sync / reduce_sync 等 warp 内同步指令。写高性能 reduce、scan、transpose 都离不开。
-
C++ API 层把 thread / warp / block / grid 级别的同步统一抽象起来。跨 block 协作(grid.sync)是写 persistent kernel 的基础。
-
stream 是 GPU 上的 work queue,不同 stream 之间可以并发。把 compute、H2D、D2H 三条 stream 重叠是训练 / 推理的性能基本功。
-
Volta 引入的矩阵乘加单元。wmma 是 C++ 层 API,mma PTX 指令是更底层的调用。cuBLAS、CUTLASS、FlashAttention 的性能都靠它。
-
Ampere 的 cp.async 让 global → shared 绕过寄存器,Hopper 的 TMA 再把拷贝批量化。现代高性能 kernel 默认都会用。
-
PTX 是 NVIDIA 的虚拟 ISA,SASS 才是实际机器码。性能 debug 到最后一步经常要读 PTX 或反汇编。
Lab
-
官方样例覆盖从 vectorAdd 到 cooperative groups、CUDA Graph 的几十个示例。读 + 改 + 测,是最快的上手路径。
-
Simon Boehm 用 10 步把 naive matmul 优化到接近 cuBLAS 性能的经典文章。照着做一遍,shared memory tiling、register blocking、double buffering 会彻底内化。
-
Mark Harris 的经典 7 版优化。从朴素两两相加到 warp shuffle,每一步都对应一个硬件约束的揭示。
-
社区维护的 GPU 编程讲座资料集,话题从 warp 原语到 FlashAttention、Triton 全覆盖。
-
从 vector add 一路写到 fused attention。写 CUDA 之外,Triton 是做生产级 kernel 的现代起点。
-
读官方实现 + 自己写一版 tiled attention,做完会对 IO-aware 算子设计有直接感觉。
-
纯 C++/CUDA 的 LLM 推理实现,重点看 matmul warp reduction、kernel fusion、attention kernel、手动 unroll / prefetch。读完对 Nsight metric 到 kernel 改写的闭环会有很具体的感觉。
资料
-
官方权威参考。programming model、hardware implementation、performance guidelines 三章是高频回看内容。
-
Andrew Chan 的 yalm 配套长文,讲 CUDA 推理优化最清楚的一篇:warp reduction、kernel fusion、KV cache 量化、手写 unroll 和 prefetch 为什么比 compiler 出的版本快。
-
把性能工作拆成 APOD 流程(Assess / Parallelize / Optimize / Deploy)。写新 kernel 前扫一遍能避开大量经典坑。
-
Hwu / Kirk 的 GPU 编程教科书。从并行思维到 stencil、reduce、scan、GEMM 的典型 pattern 一次过完。
-
写 inline PTX、手写 mma 指令、读反汇编时的必备文档。
-
NVIDIA 开源的 GEMM 模板库。读它的 tile iterator、pipeline、shape 模板,基本等于跟着 NVIDIA 工程师学现代 GEMM。
-
当前网上讲 CUDA matmul 优化最清楚的一篇,把每一步的 metric 和 trade-off 画得很明白。
工具
-
CUDA 编译器驱动。-arch / -code、--ptxas-options=-v(打印寄存器 / 占用率)是调优第一步。
-
kernel 级 profiler,给出 roofline、warp stall 原因、memory chart。写完 kernel 第一件事就是它。
-
系统级 timeline profiler,看 CPU / GPU / CUDA stream / NCCL 的时序对齐。定位 stream 依赖和空转的主力。
-
GPU 上的 ASan 等价物,能抓越界、race、未初始化内存。CI 里定期跑一把能省下很多炸显存的夜晚。
-
GPU 上的 gdb,可以在 kernel 内设断点、看 warp 状态。诊断 illegal memory access 的最终武器。
-
看 SM 利用率、显存、温度、功耗的基础命令。DCGM 是集群版,直接暴露 Prometheus metric。
-
多卡 / 多机集体通信带宽的官方基准。排查训练通信瓶颈时先跑一把 all_reduce_perf。
工程与可观测
写完代码只是上半场,让它在生产环境稳定跑才是下半场:容器、K8s、Prometheus、OpenTelemetry、SLO。这个模块的目标是让你能独立把一个服务部署到集群、能定义合理的 SLI / SLO、能在凌晨三点根据四个黄金信号和调用链定位到出问题的那一行代码。
学完后你应该能回答
容器 / K8s 基础
- 镜像里的一层和容器运行时的可写层分别存在哪里?为什么 `docker commit` 出的镜像通常比 Dockerfile 构建的大?
- Pod 的 requests 和 limits 分别影响调度器的什么决策?设 limit 不设 request 会怎样?反过来呢?
- 同一个 Service 后面 10 个 Pod,kube-proxy iptables 模式和 IPVS 模式在连接分布上有什么区别?
- Deployment 的滚动更新在什么情况下会卡住?kubectl rollout status 看到 stuck,你会依次检查哪些资源?
- Helm values 覆盖优先级是怎样的?chart 里 `{{- if .Values.x -}}` 的 `-` 去掉会怎样?
- Init container、sidecar、ephemeral container 各适合什么场景?在 Pod 生命周期里分别什么时候起来?
K8s 高级模式
- kube-scheduler 的 plugin 化架构(filter / score)怎么扩展?自定义调度器的典型落地路径是什么?
- Pod 的 priority / preemption 机制怎么工作?大规模集群里经常踩什么坑?
- StatefulSet 和 Deployment 的核心差异在哪?为什么有状态服务一般还要配套 Operator?
- Operator 模式的 reconcile loop 怎么写才幂等?level-triggered vs edge-triggered 的取舍?
- CRD + admission webhook 的典型扩展路径?mutating 和 validating 两类 webhook 各在哪个阶段介入?
发布 & GitOps
- GitOps(ArgoCD / Flux)怎么处理"集群和 Git 发散"?auto-sync 和 manual sync 分别适合什么团队?
- 金丝雀、蓝绿、滚动发布的差异?Istio 做流量切分相比 Service + Deployment 多出什么能力?
- Progressive delivery(Flagger / Argo Rollouts)里 metric-driven rollback 的闭环是怎么跑的?
- 多集群、多区域部署时 ArgoCD ApplicationSet 和 Flux Kustomization 各自的工程模型差异?
SLO / 错误预算
- 你要给一个延迟敏感的 API 定义 SLO,选 p99 还是 p999?错误预算(error budget)用完后团队应该做什么?
- 四个黄金信号(latency / traffic / errors / saturation)对应到 Prometheus,你会用哪些 metric 类型(counter / gauge / histogram)去表达?
- Multi-window multi-burn-rate SLO 告警是怎么组合的?为什么单 burn rate 会出现假警报?
- Error budget 用完后"冻结功能开发"在工程文化上怎么落地?什么情况下可以例外?
- histogram_quantile 在 Prometheus 里什么时候会骗你?和 summary 各适合什么场景?
Observability / Tracing
- OpenTelemetry 里 trace、metric、log 的 context 是怎么关联的?看到一条错误日志,如何跳到对应的 trace?
- OpenTelemetry Collector 的 receiver / processor / exporter 管道,典型生产部署长什么样?
- 分布式追踪的采样策略(head-based vs tail-based)如何选?尾采样的工程复杂度主要在哪?
- 日志走 Loki、追踪走 Tempo、指标走 Prometheus,在"一个 trace id 跳到日志和指标"时用的是哪些 label / attribute 约定?
- Continuous profiling(pprof / Parca / Pyroscope)作为第四根支柱,和传统 metric/log/trace 互补在哪?
核心概念
-
基于 namespace + cgroup 的进程隔离,镜像是只读层的堆叠。先搞清楚容器不是虚拟机。
-
scheduler 根据 node 资源、亲和性、taint / toleration 把 Pod 绑到 Node。面试和排障绕不开。
-
requests 决定调度和 QoS 级别,limits 决定 cgroup 上限。OOMKilled 多半是这里配错。
-
Service 提供集群内稳定 VIP 和负载均衡,Ingress 处理 L7 入口。理解 kube-proxy 才能排网络问题。
-
可观测性三支柱。Metric 回答「有没有事」,Log 回答「是什么事」,Trace 回答「在哪一环出的事」。
-
指标、目标、合约三层。错误预算是工程和产品平衡速度与稳定性的共同语言。
-
Deployment 提供滚动更新和回滚。配合 readinessProbe、PDB 才是真·安全发布。
-
Latency / Traffic / Errors / Saturation。任何服务的监控面板都该从这四个开始。
Lab
-
从零写 Deployment + Service + Ingress,本地用 kind 或 minikube 跑通。
-
给玩具服务加 /metrics,写第一个 PromQL 告警规则,做一个 latency + QPS 的 Grafana 面板。
-
在服务里埋点 trace 和 metric,用 OTLP 导到 collector。体会 propagation 和 context 传递。
-
把手写 yaml 改成 Helm chart,理解 values、template、release 三层模型。
-
部署一个多服务 demo,在 Jaeger UI 里看到跨服务的 trace tree,学会定位慢 span。
资料
-
把 K8s 里反复出现的设计抽成模式,例如 Sidecar、Ambassador、Init Container。
-
Google SRE 的方法论底座。SLO、错误预算、on-call、post-mortem 都出自这里。
-
质量相当高的官方文档。Concepts 章节至少通读一遍。
-
数据模型、PromQL、recording rule、alertmanager。做监控前先把这套模型吃透。
-
trace / metric / log 的统一标准。API、SDK、Collector 分层要分清楚。
工具
-
K8s 的瑞士军刀。describe、logs、exec、port-forward、debug 是每天都要用的五个子命令。
-
K8s 的包管理器。生产里极少有人手写裸 yaml 部署。
-
事实标准的指标系统。Pull 模型 + 标签 + PromQL 的组合是整个云原生监控的地基。
-
仪表盘和告警前端。不只用于 Prometheus,还能聚合 Loki、Tempo、各种 DB。
-
厂商中立的观测数据标准。SDK 埋点 + Collector 转发是目前最推荐的埋点方式。
-
开源分布式追踪后端。看 trace tree 定位跨服务慢调用的主力工具。