能力矩阵与学习目标
这本书的目标不是「读完」,而是读完能做什么。下面把能力拆成 12 项,每项给出可观察的验收标准、对应章节与项目。你可以把它当作学习前的路线图,也可以当作学习后的自检表。
1. 能力矩阵
| # | 能力 | 验收标准(能做到才算) | 主章节 | 项目 |
|---|---|---|---|---|
| C1 | 命令行流利度 | 不查手册完成文件查找、文本抽取、批量改名、日志统计;能解释每条管道的退出码 | 0.2–0.6 | D2 |
| C2 | Shell 工程 | 写出 set -euo pipefail、trap 清理、参数校验、并发控制、可测试的脚本 | 0.7–0.8 | D1/D2 |
| C3 | 权限与安全 | 解释 mode/umask/ACL/capability 的判定顺序;能用最小权限运行服务 | 0.4, 2.9, 5.2 | A1 |
| C4 | 系统调用语义 | 说清 open/read/write/close 的返回值、短读、EINTR、原子性、O_CLOEXEC | 2.2–2.4 | A2/B1 |
| C5 | 进程与信号 | 画 fork/exec/wait 状态图;写出正确的信号处理与超时/取消 | 1.8, 2.7–2.11 | D1 |
| C6 | 并发 | 用互斥锁/条件变量/信号量解决生产者-消费者;解释虚假唤醒、死锁、优先级反转 | 1.12, 2.12–2.13 | A2/C1 |
| C7 | 内存与性能 | 解释虚拟地址翻译、TLB、page cache、malloc 与 mmap;用 perf 定位 cache miss | 1.5–1.6, 1.9, 2.3, 3.7–3.10 | B2 |
| C8 | 链接与二进制 | 解释符号解析、重定位、GOT/PLT、静态/动态库;能排查 undefined symbol | 1.7, 0.11 | D3 |
| C9 | 内核路径 | 沿源码走通「系统调用 → 子系统 → 驱动」;能读 task_struct、struct page、VFS 对象 | 3.1–3.15 | A1/A3 |
| C10 | 网络协议栈 | 画出收包/发包路径;解释 backlog、TIME_WAIT、epoll 回调、零拷贝 | 4.1–4.12 | C1/C2/C3 |
| C11 | 可观测性 | 用 strace/perf/bpftrace/ss/tcpdump 建立证据链,定位 CPU/内存/I/O/网络瓶颈 | 0.14, 3.15, 4.12 | A3 |
| C12 | 工程交付 | 用 Makefile/CMake、单元测试、CI、容器镜像交付一个可复现的项目 | 0.11, 6.0–6.1 | 全部 |
2. K / S / A 三层目标
K(Knowledge,知道什么)
- 掌握 Linux 的文件、进程、线程、内存、信号、IPC、socket 抽象及其边界;
- 掌握 x86-64 机器级程序的读法,能看懂编译器输出与崩溃栈;
- 掌握虚拟内存、页表、缺页、page cache、slab 的作用与相互关系;
- 掌握 TCP/IP 分层、TCP 状态机与拥塞控制、Linux 收发包路径;
- 掌握 namespace/cgroups/overlayfs 如何组成容器;
- 知道哪些内容是历史、为什么被替代。
S(Skill,会做什么)
- 写正确、可移植、可观测的 C 系统程序;
- 用
/proc、strace、perf、bpftrace、ss、tcpdump做排障; - 读内核源码的关键路径,能定位函数与数据结构;
- 实现一个能跑的项目:容器运行时、HTTP 服务器、Redis、TCP 栈、Shell、Git 对象库等;
- 做压测、分析瓶颈、写复盘。
A(Attitude,形成什么习惯)
- 证据优先:先观测,再假设,再验证;不凭印象下结论;
- 边界意识:每个 API 都问「失败时是什么语义」「并发时是否原子」;
- 最小权限:默认不用 root,能用 capability 就不用 setuid;
- 可复现:实验有脚本、有版本、有预期输出;
- 不迷信:文档、博客、甚至本书都可能错,以规范和实验为准。
3. 三种掌握程度
每个知识点按三级要求:
| 级别 | 要求 | 检验方式 |
|---|---|---|
| L1 识别 | 听到名词知道在哪、干什么 | 选择题、术语表 |
| L2 解释 | 能画出路径、说清边界、举出反例 | 简答、白板、回忆卡 |
| L3 迁移 | 能在新场景里使用、排障、改造 | 项目、压测、故障注入 |
正文的 核心 内容要求 L3;选读 要求 L2;历史 只要求 L1。
4. 章节出口检查
每章末尾有一个「出口检查」小表,形式如下:
| 检查项 | 达标线 | 没达标去哪 |
|---|---|---|
能说出 write() 返回后的三种可能状态 | 三种都说全 | 回看 2.2.4 |
能解释 O_APPEND 的原子性 | 能说出与 lseek 的区别 | 回看 2.3.1 |
能写出带 EINTR 重试的 read 循环 | 代码通过编译与测试 | 做 2.2 习题 C1 |
出口检查不是考试,而是定位器:没达标就回到指定小节,不要带着缺口往下走。
5. 项目与能力的映射
| 项目 | 主要能力 | 难度 | 预计投入 |
|---|---|---|---|
| A1 mini 容器运行时 | C3/C5/C9/C12 | ★★★★ | 30–40 h |
| A2 高性能 HTTP 服务器 | C4/C6/C7/C10/C11 | ★★★★ | 30–40 h |
| A3 eBPF 可观测性 | C9/C11 | ★★★★ | 20–30 h |
| B1 Redis 复现 | C4/C6/C10/C12 | ★★★★★ | 40–60 h |
| B2 B+ 树/WAL 引擎 | C4/C7/C12 | ★★★★★ | 40–60 h |
| C1 用户态 TCP/IP | C10/C11 | ★★★★★ | 50–70 h |
| C2 反向代理 | C6/C10/C11 | ★★★☆ | 25–35 h |
| C3 抓包分析器 | C10/C11 | ★★★ | 15–25 h |
| D1 POSIX Shell | C2/C5/C6 | ★★★★ | 30–40 h |
| D2 BusyBox 工具集 | C1/C4/C12 | ★★★ | 20–30 h |
| D3 Git 对象库 | C8/C12 | ★★★★ | 30–40 h |
不建议一次全做。按路线选 2–3 个,做完一个再开下一个;每个项目都有 Stage 验收,Stage 之间可暂停。
6. 学完后的自述
如果达到目标,你应该能用自己的话讲清下面这段,而不只是背名词:
我在终端敲下
curl,Shell 做变量与通配符展开,fork出子进程,exec加载curl;动态链接器解析libcurl.so,curl调用socket/connect,内核分配struct socket,TCP 三次握手后把请求写进发送队列;网卡驱动通过 DMA 读走sk_buff,对端回包触发中断,NAPI 轮询把包送进协议栈,tcp_v4_rcv找到 socket,唤醒epoll_wait;curl把响应写进 stdout,write进入 page cache,终端驱动把字节送到 pty。任何一步变慢,我都能用strace、perf、ss、tcpdump、/proc找到证据。
这段话就是全书的压缩版。学完后,回到这里再读一遍,看看哪些环节你还能讲得更细。
下一站:三条学习路线给出按周执行的计划。