LLM 时代,
如何真正学会技术
把“得到可运行的答案”推进到“能够独立解释、实现和验证”。从一篇学习经验文章出发,建立可执行的个人技术学习流程。
分析对象:How to keep learning in the age of LLMs ↗
阅读约 15–20 分钟。01 为原文要点摘要;02–10 为本指南的分析与原创实践设计。本文不是逐段翻译,代码案例也不是原文代码。
原文观点速览
作者的经验可以归纳为五点
- 先亲自尝试:卡住时请求解释与问题提示。
- 选择性委托:把与当前目标无关的配套工作交给 LLM。
- 分阶段计划:写清目标、步骤、验收条件与易踩的坑。
- 让进展可见:用 REPL 或可视反馈维持投入。
- 持续做小步:坚持短时练习,并挑战稍难的项目。
文章从作者实现 Bitcask、继续构建 tinylsm 的经历展开。这是一份个人经验分享,不能据此推断所有人的学习效果。[1]
从观点到学习证据
在学习任务中,代码运行成功只证明产物通过了当前检查。要判断自己是否掌握技术,还需要观察:你能否解释决策,能否定位新错误,能否在条件变化后重新实现。
这个程序是否正确?
测试结果、输入输出、异常处理和性能数据回答的是系统行为。
我能否独立完成?
口头解释、闭卷重写、构造反例和迁移实现回答的是个人能力。
| 能力层次 | 可观察的行为 | 小型验证任务 |
|---|---|---|
| 理解 | 能说清设计约束与数据流 | 画出一次写入与重启恢复的过程 |
| 实现 | 能根据规格写出关键逻辑 | 关闭聊天记录,重写一段解析函数 |
| 诊断 | 能提出假设并找到反例 | 给恢复程序喂入一个不完整的文件 |
| 迁移 | 能适应不同限制与接口 | 将一次性解析改成分块输入解析 |
以上是对学习流程的实践性设计,不是经过本指南实验验证的教学效果结论。
划定人与 LLM 的边界
先写下本次要练习的能力,再决定哪些工作可以委托。相同的任务,在不同学习目标下会有不同分工。
| 当前学习目标 | 自己主导 | LLM 可辅助 |
|---|---|---|
| 文件格式与恢复 | 编码协议、边界条件、回放逻辑 | CLI 外壳、样本生成、字节展示 |
| 测试设计 | 性质、断言、故障输入与覆盖范围 | 测试框架配置、重复样本代码 |
| 性能分析 | 测量口径、变量控制、结果解释 | 采样脚本、结果表格、图表绘制 |
| 前端交互 | 状态转换、键盘操作、反馈设计 | 模拟接口、占位数据、后端骨架 |
委托前回答三个问题
- 这项工作是否直接训练我的目标能力?
- 如果让 LLM 完成,我能否独立判断结果对错?
- 它是否会把我正在学习的核心逻辑一并生成?
例如:练习崩溃恢复时,可以生成故障文件工具,但恢复规则与关键断言应由你确认。
建立导师提问协议
“不要直接给答案”还不够明确。让模型知道当前目标、你已经尝试过什么,以及每轮允许提供多少帮助。
可复制的学习提示词
你是我的技术学习导师。
目标:我想独立实现【目标能力】,不是仅拿到成品。
背景:我已掌握【基础】;当前卡在【具体问题】。
尝试:我做了【实验】,观察到【结果】。
协作规则:
1. 先让我说明预期行为与当前假设。
2. 每轮只问一个具体问题,等待我回答。
3. 默认不给完整实现,不替我修改关键逻辑。
4. 我请求提示时,先指出需要观察的变量或边界。
5. 我仍无法推进时,再给一个更小的例子。
6. 我写出修复后,要求我解释原因并构造反例。
7. 不确定的技术事实标明不确定,并给出官方来源。
现在先问我:怎样判断这个函数是正确的?
观察变量 → 构造小输入 → 解释概念 → 局部伪代码。每次升级前,先明确上一轮为什么没有解决问题。
如果最终需要看完整解法,理解之后关掉答案,换一个输入重写关键逻辑,再比较差异。
提示词是一份协作约定。模型可能偏离约定;你可以要求它撤回整段实现,改为只指出一个可验证的问题。
实战:日志解析调试
下面使用一个自定义教学格式:4 字节长度 + payload。长度以小端无符号整数存储。暂不加入校验和,只练习“完整记录边界”。这不是 LevelDB 的日志格式。
第一步:先运行有缺陷的代码
import struct
def replay_bad(data):
pos, records = 0, []
while pos < len(data):
size, = struct.unpack_from("<I", data, pos)
pos += 4
records.append(data[pos:pos + size])
pos += size
return records
# 第一条完整;第二条声明 5 字节,却只剩 2 字节。
sample = struct.pack("<I", 3) + b"abc"
sample += struct.pack("<I", 5) + b"xy"
print(replay_bad(sample)) # [b'abc', b'xy']
Python 的 struct.unpack_from 要求从指定偏移起有足够的字节;应在读取头部前检查长度。[2]
第二步:用问题定位边界
继续前先写下答案:完整头部、完整载荷分别对应哪个不等式?
第三步:完成尝试后,查看参考修复
头部检查为 pos + 4 <= len(data);载荷检查为 end <= len(data)。函数额外返回最后一条完整记录的结束位置,方便明确有效前缀。
def replay(data):
pos, records = 0, []
while pos + 4 <= len(data):
size, = struct.unpack_from("<I", data, pos)
start = pos + 4
end = start + size
if end > len(data):
break
records.append(data[start:end])
pos = end
return records, pos
assert replay(sample) == ([b"abc"], 7)
assert replay(b"\x03\x00") == ([], 0)
assert replay(struct.pack("<I", 0)) == ([b""], 4)
空 payload 在本练习中合法。完整性判断包含等号,因此恰好在文件末尾结束的记录不会丢失。
范围说明:此函数只识别长度边界,无法识别任意位翻转,也不会区分损坏的长度头与截断尾部。下一步可加入最大长度限制和校验和,但必须先制定对应错误策略。
设计一个学习项目
以一个单进程、单写入者的 tiny-log-kv 为练习对象。先通过追加日志与内存字典完成键值读写和恢复,再选择是否扩展到 LSM 相关结构。
把目标落到模块上
| 概念 | 要回答的问题 | 本项目的边界 |
|---|---|---|
| 记录格式 | 怎样区分 put 与 delete?长度如何校验? | 先使用版本固定的教学协议 |
| 持久化确认 | 在哪一步之后,允许返回“写入成功”? | 明确同步模式;单独验证失败路径 |
| 顺序回放 | 同一 key 多次更新,最终保留哪个值? | 按日志顺序应用,删除操作必须可回放 |
| LSM 扩展 | 何时生成有序表?旧值如何被覆盖? | 可选挑战,基础项目不等同于完整 LSM |
f.flush() 后再调用 os.fsync(f.fileno())。恢复承诺应围绕明确的成功确认点设计。[3]这里的崩溃练习默认指进程异常退出。断电、硬件缓存和文件系统语义需要额外验证;一次终止进程的测试不能证明所有故障条件下都不丢数据。
延伸背景:LevelDB 的实现说明描述了日志、内存表、有序表和合并的关系。可以据此理解模块职责,但不要把上面的教学布局当作 LevelDB 的精确实现。[4]
五阶段实施路线
按验收条件推进,不必按日历硬凑进度。每阶段完成一个可运行的小闭环,并留下解释与测试证据。
编解码一条记录
目标:协议清楚,完整记录能够往返转换。
步骤:写规格 → 编码 → 解析 → 构造边界样本。
验收:空值、Unicode、边界长度与半条记录行为符合规格。
易错点:把字符数当成 UTF-8 字节数;忽略长度上限。
追加日志并定义成功确认点
目标:读写接口具有明确的顺序和错误行为。
步骤:追加完整记录 → 同步模式 → 更新索引 → 返回成功。
验收:同步失败不会返回成功,也不会把失败写入暴露到内存索引。
易错点:先更新内存,再发现日志写入失败。失败后的存储实例应停止写入,恢复后再使用。
重放完整前缀
目标:重启后按顺序重建键值状态。
步骤:扫描 → 校验记录 → 更新字典 → 处理尾部。
验收:覆盖写、删除、空文件与每个字节截断测试通过。
易错点:忽略残缺尾部后直接继续追加。先按既定策略修复尾部,否则后续数据可能无法回放。
把状态与故障展示出来
目标:从输入到恢复结果形成可重复的观察链。
步骤:CLI 演示 → 固定故障点 → 状态对照 → 记录结果。
验收:另一位读者照着命令即可复现你的解释。
易错点:只观察正常运行,未检查失败后重启的行为。
尝试有序表与合并
目标:在新结构中重新验证覆盖和删除语义。
步骤:生成有序表 → 查询多个表 → 合并 → 对照结果。
验收:合并前后,同一批查询与字典参考模型一致。
易错点:过早丢弃删除标记,使旧表里的值重新出现。
此路线为本指南设计的练习顺序,不是作者 tinylsm 的完整项目计划。
每次学习如何推进
以一次 30 分钟练习为起点。时间分配可以调整,始终留下“下一步可以马上做什么”。
| 时段 | 动作 | 结束时应留下 |
|---|---|---|
| 0–4 分钟 | 先不看答案,回忆上次的约束和失败原因 | 一段自己的解释 |
| 4–19 分钟 | 围绕一个假设实现或调试;需要时请求一条提示 | 一个可运行改动或可验证假设 |
| 19–26 分钟 | 测试正常输入与反例,解释差异 | 一项结果与一个边界条件 |
| 26–30 分钟 | 记录状态,写下下次第一条命令 | 可以接续的学习记录 |
保存一份学习状态记录
# LEARNING_STATE.md · 示例
当前目标:识别完整记录前缀,正确处理尾部截断。
已完成:完整头部检查;完整 payload 检查。
验证证据:abc + 半条记录,只恢复 abc;有效偏移为 7。
我的解释:长度字段只声明大小,不能证明载荷已经存在。
未解决:加入校验和后,怎样区分尾部截断与内部损坏?
下一步:枚举 sample 的全部截断位置,检查恢复前缀。
下次第一条命令:python -m unittest -v
需要的协助:只帮我审查断言是否遗漏边界,不生成解析实现。
延后任务:图形界面;并发写入;后台合并。
反馈、度量与常见误区
展示输入与状态变化
显示写入记录、有效字节位置与回放后的键值状态。每次展示都关联一条你能解释的规则。
记录独立完成情况
记录用了几级提示、哪段可以闭卷重写、哪个反例尚未想清楚。比较同类任务中的变化。
性能练习的最小实验记录
问题:减少候选表数量,是否降低“查询不存在的 key”的耗时?
控制:数据集、查询序列、机器、缓存状态与代码版本。
采样:固定预热;重复运行;记录分布和异常值。
输出:表数量、单次访问表数、延迟中位数 / P95。
解释:收益来自哪里?是否改变了结果正确性?
边界:结论只适用于这组负载与环境。这是实验设计模板,不是已测量结果。它用于可选的多表查询阶段;基础日志项目可先测恢复时间与文件大小。
| 常见误区 | 会遗漏什么 | 修正动作 |
|---|---|---|
| “我看懂生成代码了” | 独立构造逻辑的能力 | 关掉答案,换一个输入重写 |
| “模型说这样正确” | 可检验的事实与边界 | 查官方说明,并运行最小实验 |
| “测试全绿就学会了” | 测试遗漏与解释能力 | 自己添加一个会击穿错误实现的反例 |
| “必须一直卡着才能学” | 缺少前置知识的情况 | 把任务缩小,先补概念,再回来尝试 |
| “功能越来越多就是进步” | 核心能力是否提升 | 围绕一项能力做闭卷验证,再扩大范围 |
自测与迁移练习
先写下自己的判断,再逐题展开参考答案。重点是推理与证据。
01 · 学习崩溃恢复时,能否把测试全部交给 LLM?
可委托样本生成和框架代码,但你仍要定义恢复承诺与关键断言。例如,先写明成功确认点,再规定成功确认过的写入应如何恢复;同时考虑“已落盘但还没回复”的写入可能存在。否则测试全绿只能说明实现满足了模型自己制定的条件。
02 · 为什么只检查 pos < len(data) 不够?
这个条件只保证还有至少一个字节。读取长度字段需要至少 4 字节;头部完整以后,还需要检查 payload 的结束位置不超过文件长度。两个条件分别保护两个读取阶段。
03 · 进程被终止后成功恢复,能否证明断电也安全?
不能直接得出这个结论。进程退出时,操作系统可能仍保留待写入数据;断电会改变故障范围。必须说明同步策略与故障模型,并针对目标环境设计验证。这里的练习只覆盖已声明的进程故障和文件截断行为。
04 · 未完成尾部被忽略以后,为什么不能直接追加新记录?
旧的残缺尾部仍在文件里。后续解析可能把新记录的字节当作旧记录的缺失部分,或在旧尾部再次停止。应保留有效结束偏移,先按既定恢复策略截断到有效前缀或切换到新日志,再接收写入。
05 · 如何证明自己掌握了,而不只是记住了参考代码?
把输入改成每次最多提供 2 字节的分块流。实现一个保留未完成缓冲区的解析器,并说明它何时等待更多数据、何时产出完整记录。用不同分块边界确认输出与一次性解析一致。
最后一个闭卷挑战
不用 LLM 写一个 feed(chunk) 解析器:连续接收任意大小的字节块,只在完整记录到达时输出。你需要自己决定如何处理结束信号与残缺尾部,并写出两项不变量。
完成后让 LLM 只做代码审查:要求它先提出一个能失败的输入,再解释风险,最后由你决定如何修复。
来源与阅读说明
- [1]Oğuzhan Olguncu · How to keep learning in the age of LLMs · 2026-10-04。仅用于原文观点摘要。
- [2]Python 官方文档 · struct.unpack_from · 核对二进制解析的缓冲区要求。
- [3]Python 官方文档 · os.fsync · 核对缓冲刷新与文件同步。
- [4]Google LevelDB · Implementation notes · 扩展阅读:日志、内存表、有序表与合并。
访问日期:2026-10-08。UI 按附件《html_UI设计规范.md》实现;学习模板、教学代码与阶段路线均为本指南原创延伸。