这套课程只默认你接触过变量、条件、循环和最简单的函数。不默认你会 Go、C、指针、并发、操作系统、编译器或 Web 部署。 如果这些词陌生,是课程需要解释,不是你应该先补完一整本教材。
目标不是让你背一套架构名词,而是走到这一步:看见 Pysolate 的一段代码,知道它的输入输出、保存了什么、依赖哪一层、失败时会发生什么。
想以代码为主线,请先进入 代码带读。 本组课程作为概念查阅,不要求先全部学完。
1. 先分清两条阅读路线
- 前置课程回答“这个概念是什么、为什么需要它”,从小例子建立直觉。
- 实现手册 回答“这个项目具体在哪个文件做了这件事”,是学完对应背景后的代码索引。
不要两边同时从头到尾硬读。每学一章,按下面的“接回代码”只打开一小段。只有你需要理解的那一层才展开。
2. 建议的学习顺序
第 1 章:工程工具与数据
读 工程入门。先认识命令、目录、输入输出、依赖、JSON 和测试。这样你运行 make demo 时,能区分“命令没找到”“文件缺失”“代码报错”和“测试不通过”。
接回代码:先看仓库 README 和 Makefile,不急着看 C。
第 2 章:Go 语言长什么样
读 Go 语言入门。弄清 package、函数、多返回值、struct、方法、接口、闭包和 defer。它们都是后续源码中的日常表达,不是为了这份项目发明的新机制。
接回代码:读 cmd/demo/main.go,能说清楚它如何准备参数、选择运行模式、打印结果。
第 3 章:Go 的值、引用关系与内存
读 Go 的值与内存。理解指针、slice、map、nil、拷贝与别名;分清自动回收内存和显式关闭资源。
接回代码:看 Runner 的字段和 callRequest,解释谁还持有同一份数据。
第 4 章:一段 Python 到底怎样运行
读 执行层次。区分源码、编译、链接、CPython、Wasm、wazero、WASI、模块和实例。
接回代码:跟 newGuest → _initialize → init → execute,暂时只关注顺序。
第 5 章:跨语言边界怎样传数据
读 内存与 ABI。从 bit/byte、地址和长度开始,再理解栈/堆、引用计数、C buffer 和 64 位返回值。
接回代码:只跟一次 alloc → Write → execute → Read → release,别一开始通读所有 C API。
第 6 章:并发、等待与取消
读 并发与任务。区分并发与并行、异步与阻塞;学会读 goroutine、channel、WaitGroup、context 和状态发布。
接回代码:读 future.go。这一轮只需要解释一个任务怎样开始、怎样完成、怎样被领取或取消。
第 7 章:PLM 为什么有时可以提前
读 PLM 的思考基础。学数据依赖、控制依赖、AST、保守优化、只读快照、幂等和回退的区别。
接回代码:运行 五个边界例子,再读 PLM 和 prefix。这是本项目的主线。
第 8 章:Web 与发布(可选旁支)
读 Web 基础。解释你正在看的页面怎样到达浏览器,以及为什么 noindex 不等于私密访问。
这章帮助理解文档站,不是理解 PLM 的前提。时间不够时可以后读。
第 9 章:Ubuntu 构建与离线演示
读 Ubuntu 上的构建与离线演示。从 WSL、SSH 和交叉编译开始,解释本机 Guest 构建链、缓存、network namespace,以及该重建和验证哪一层。准备在 Ubuntu 上现场开发时,建议在第 4 章之后提前读这一章。
接回代码:make setup-build、make guest 和 tools/offline-check.sh。
3. 同一个词,在不同层可能不是同一件事
模块
Go module 是依赖与版本管理的单位;Wasm module 是可供 runtime 加载的二进制模块。不要因为都叫 module,就以为它们是一层东西。
接口
Go 的 interface 是语言中的类型机制;Host tool 的 API 是调用约定;ABI 是更底层的参数、字节和返回方式约定。它们可以配合,但不能互换解释。
上下文
context.Context 主要传递取消、deadline 等信息;Python 的 scope 是名字到值的执行环境。这里也不是在说 LLM 的聊天上下文。
快照
Host 工具的稳定数据快照,保证本轮读到同一份业务数据。Prepared full-copy 的 Guest 内存基线,保存干净初始化状态。它们解决不同的问题,也不存放在同一个地方。
引用与关闭
“多个变量联系到同一份数据”、CPython 的引用计数、Go 的垃圾回收,是不同层的事情。Close 还可能负责文件、runtime 或任务生命周期,不能用“有 GC”一句话替代。
3.7 runtime:分别是谁的运行时?
Go runtime 提供 Go 的调度和垃圾回收等支持;wazero runtime 执行 Wasm;CPython 执行 Python。站点构建使用的 Node.js 则是在浏览器外执行 JavaScript 的环境。它们不是一个可以互换的对象。
这些短说明只是防止串层;定义和例子在对应章节展开。
4. 先认清例子的标记
- 完整程序:给出了运行需要的结构;Go 通常从
package main开始。按章节说明保存为文件,再用对应命令运行。 - 片段:只解释某个局部,需要放回原函数或项目,不能当成独立程序直接执行。
- 结构示意 / 伪代码:帮助理解关系,不是声称机器实际输出了这段文本。
- 预期输出:根据示例的逻辑应得到的结果;地址、调度顺序等若不固定,章节需要明确指出,不能要求每次逐字相同。
Python 的 tool(...) 例子属于本项目的 Guest 输入,不是系统 Python 自带了 tool。C 片段也不要求你在没有 CPython 构建依赖时直接编译。
5. 怎样判断自己读懂了一节
每节只做三件事:
- 用不依赖原句的方式解释概念。
- 对一个小输入,先预测值或错误,再运行验证。
- 在真实代码中找到它出现的位置,说清楚那里为什么需要它。
能复述“Future 是未来的结果”还不够;能指出 response 何时写、谁等 done、谁取消任务,才接到了实现。暂时做不到就回到那一层的小例子,不必把整个项目重新读一遍。
5. 这一轮刻意不扩张的内容
不要求你学完整操作系统、网络协议栈、编译器课程或算法竞赛;不补整个旧 runtime 的防御框架;不以性能测量为学习任务;Linux COW 的背景放在独立的 选读章节,不作为学习 PLM 的前提。
本课程覆盖的是当前源码、构建、测试和文档站实际需要的知识。将来面试需求引入新概念,再补对应小节。术语尽量就地解释;若某一段仍依赖没讲过的概念,它应作为课程缺口修补,而不是推给读者“自己先懂”。