收藏了一堆资料,一个都没学完。原因通常不是懒,而是那堆东西不是课程:没有单元边界、没有依赖顺序、没有反馈回路。资料解决"有什么可看",课程解决"今天坐下来做什么、做完怎么知道对了"。
先把两件事分开:路径设计回答"学什么、按什么顺序",属于地图层;课程设计回答"每次学习单元做什么",属于执行层。地图再漂亮,没有可执行单元也走不动。
1. 目标可操作化:从"掌握 X"到"能做出 Y"
"掌握 Python 异步"无法验收,因为它没有失败条件。可操作的目标必须同时包含产出物和验收条件:
| 不可操作 | 可操作改写 | 验收方式 |
|---|---|---|
| 掌握 asyncio | 能写一个并发抓取 50 个 URL、超时可取消的脚本 | 跑通 + 超时用例通过 |
| 学会 SQL 优化 | 能给一条慢查询出执行计划并说明为何换索引 | 口述 + EXPLAIN 对比 |
| 理解 RAG | 能搭一个 200 篇文档、带召回报表的检索 demo | 指标表 + 失败样例 |
| 熟悉 Docker | 能把一个服务打成镜像并在另一台机跑起来 | 从零复现一次 |
goal:
statement: "能写并发抓取 50 个 URL 的脚本"
artifact: "fetch_all.py + 运行日志"
acceptance:
- "50 个目标全部返回或明确失败"
- "单请求超时可取消,不泄漏任务"
- "失败重试不超过 3 次"
deadline: "[DATE]"
判断目标是否可操作,只问一句:能不能设计出一个"做不出来"的检验。设计不出来的目标,先别进课程。
2. 单元粒度:一次坐下能完成、有产出、可自证
单元太大,第一次卡住就会拖三天然后放弃;单元太小,学完没有成就感,也拼不成能力。可行粒度通常落在"一次 45–90 分钟、一个可见产出、一个自检动作"。
| 粒度 | 症状 | 调整方向 |
|---|---|---|
| 一章/一本书 | 三周没进展,笔记停在第一章 | 拆到"一节一个可运行片段" |
| 一个视频 | 看完感觉会了,动手全忘 | 拆到"复现视频里的最小例子" |
| 一个项目 | 前两周都在配环境 | 先做骨架,功能按单元追加 |
| 一个函数/一个报错 | 碎片化,串不起来 | 三个小单元合并成一个产出 |
单元模板固定四段,缺一段就会退化成"看资料":
## U-03 用 asyncio.gather 并发抓取
- 输入:上一单元的同步版本 fetch.py
- 动作:改成 async + gather,加超时
- 产出:fetch_async.py,日志含耗时对比
- 自检:故意让一个 URL 超时,确认不影响其余结果
"自检"这一项是分水岭。没有自检的单元,等于把验收推给"以后再说",而"以后"不会来。
3. 前置依赖:按"卡住时需要什么"排序,不按教材顺序
教材按学科逻辑排,课程按阻塞关系排。判断方法:写单元时问"这一步做不下去,最可能缺哪一项能力",缺的那项就是前置。
U1 读文件/异常处理
├─ U2 并发抓取 ── U4 超时与取消
└─ U3 解析与数据清洗 ── U5 落库与去重
└─ U6 端到端脚本 + 日志
三个实操判断:
- 能查到的不用先学:语法细节、API 参数属于查阅项,不进依赖图。
- 不常卡住的不排前:类型注解、打包发布常常被排得太靠前,实际阻塞率很低。
- 循环依赖就砍一个:A 需要 B、B 又需要 A,说明其中一项其实是查阅项,不是能力项。
依赖图不需要工具,手写六到十个节点就够;超过十五个节点,通常是目标定得太大。
4. 反馈回路:没有反馈的练习不算练习
"看懂了"和"会做"之间的差距,只能靠反馈暴露。反馈来源决定课程能否自我纠错:
| 反馈来源 | 延迟 | 可信度 | 适用 |
|---|---|---|---|
| 自动化测试 | 秒级 | 高(覆盖到就对) | 语法、边界、并发行为 |
| 运行结果对比 | 秒级 | 中(可能对而不知为何) | 数据处理、脚本 |
| 他人/评审 | 小时到天 | 高但不可扩展 | 设计取舍、代码风格 |
| 模型问答 | 秒级 | 低到中,需自己验证 | 概念澄清,不能当验收 |
| 输出物复用 | 天到周 | 高(真用得上才算会) | 项目型目标 |
最小回路是"写 → 跑 → 对比预期 → 记录差异"。缺"对比预期"这一步,跑通会被误当成学会:能跑出结果但说不出为什么,下一个同类问题仍然卡住。
反馈的设计要点是让错误可见:故意准备一个会失败的用例(超时、空输入、重复数据),比准备十个正确用例更有价值。
5. 难度曲线:先跑通还是先原理
| 目标类型 | 推荐曲线 | 失败模式 |
|---|---|---|
| 工具/框架上手 | 先跑通最小例子,再补原理 | 先读文档三章,环境还没配好 |
| 排查与调优 | 先原理(机制图),再动手 | 只会照抄参数,换个现象就失灵 |
| 面试/考试 | 先题型结构,再补知识缺口 | 按教材顺序学,考点覆盖不全 |
| 长期能力(架构、设计) | 案例先行,原理反复回补 | 只背结论,遇新场景无法迁移 |
判断依据不是"哪个更正确",而是你的失败代价在哪一侧:跑不通会立刻放弃的,先跑通;跑通了却不知道为什么、一改就坏的,先原理。
6. 重复与间隔:复习点是"重做",不是"重读"
间隔复习的原理众所周知,落地常错在形式:重读笔记带来熟悉感,但不产生提取练习。有效的复习点是不看资料重做一次,并记录卡在第几步。
REVIEW_OFFSETS = [1, 3, 7, 21] # 天,典型量级,按自己的遗忘速度调
def schedule(unit, learned_on):
return [(learned_on + d, unit) for d in REVIEW_OFFSETS]
安排规则:
- 复习点挂在单元上,不挂在"章节"上,否则一次复习量过大。
- 每次复习只做一件事:重做产出物,或口述关键决策。
- 连续两次复习都顺利,拉长间隔或移出队列;两次都卡,回退到依赖图找缺口。
- 间隔不是越密越好。每天复习同一单元,会把时间全花在已会的内容上。
7. 里程碑与验证:做出什么算过
里程碑必须是可交付物,不是"学完第 N 章"。每个里程碑配一个验收动作和一个失败处置:
| 里程碑 | 验收动作 | 不通过怎么办 |
|---|---|---|
| M1 能跑通最小例子 | 从零复现一次,不看教程 | 回退到环境单元 |
| M2 能改需求 | 给一个没做过的小改动并完成 | 回退到对应依赖单元 |
| M3 能排查故障 | 注入一个故障并定位 | 补观测/调试单元 |
| M4 能讲清取舍 | 向他人解释为何这样选 | 补原理与对比单元 |
M4 最容易被跳过,也最能区分"会用"和"掌握":讲不清取舍,说明选择是靠模仿来的。
8. 记录、放弃与 AI 辅助
学习记录只需要五列,多了就不会维护:
{"unit": "U-03", "date": "[DATE]", "minutes": 70,
"artifact": "fetch_async.py", "blocked_at": "gather 异常传播",
"next": "读 Task 异常语义,补一个失败用例"}
中途放弃的三个真实原因,以及对应的预防:
- 单元太大:一次坐下完不成,第二天不想开始 → 拆到 90 分钟内。
- 缺反馈:连续三周没有"对了"的信号 → 每个单元强制自检。
- 目标漂移:学着学着换成另一个方向 → 目标卡片写死产出物,换目标要显式作废旧卡片。
AI 辅助的风险不在"用了 AI",而在跳过动手环节:直接拿到能跑的代码,产出物有了,能力没有。可用的约束是——AI 给的代码必须先自己改一处再运行,并写下"改了什么、为什么"。改不动,说明这段代码超出当前单元范围,应当退回更小的单元。
9. 排错:课程跑不动的五个信号
| 信号 | 原因 | 处理 |
|---|---|---|
| 连续三次打开资料就关掉 | 单元没有明确产出 | 补"产出"和"自检"两行 |
| 每个单元都能看懂,合起来不会做 | 单元之间缺串联产出 | 加一个端到端小项目 |
| 复习永远在重读笔记 | 复习形式错 | 改为不看资料重做 |
| 计划表很满,实际进度为零 | 排的是"看"不是"做" | 按单元数排,不按页数排 |
| 学完立刻忘 | 无间隔、无复用 | 加 1/3/7 天复习点 + 一次真实使用 |
10. 边界:这些情况不必自设计课程
| 情况 | 判断 | 做法 |
|---|---|---|
| 有明确考试大纲 | 大纲就是课程骨架 | 按考点排单元,不自造依赖图 |
| 纯兴趣探索 | 目标是保持兴趣 | 不设里程碑,只留记录 |
| 单次时长无法保证 | 碎片到 15 分钟以下 | 先解决时间块,再谈粒度 |
| 已有成熟培训路径 | 重复设计成本更高 | 直接用,只补自检环节 |
| 目标本身模糊 | 连产出物都写不出 | 先做一次真实任务,从卡点反推目标 |
一句话判据:课程设计解决"知道该做什么但做不到",不解决"不知道该往哪走"。 后者属于目标与路径层,用单元模板硬套只会得到一张漂亮的空表。
11. 自测
- 一个目标写不出"做不出来"的检验,说明它缺了什么?
- 单元模板的四段里,哪一段缺失会让课程退化成看资料?
- 依赖图超过十五个节点,通常暴露了什么问题?
- 为什么"跑通"不能当作学会的验收标准?
- 复习点为什么应当挂在单元上而不是章节上?
- AI 辅助学习时,"先改一处再运行"约束的是什么?