生锈的知识,还能不能重新上场?
Posted on 二 30 6月 2026 in Tech
| Abstract | 生锈的知识,还能不能重新上场? |
|---|---|
| Authors | Walter Fan |
| Category | Tech |
| Status | v0.4 |
| Updated | 2026-06-30 |
| License | CC-BY-NC-ND 4.0 |
一个老程序员的扎心时刻
有些知识,年轻时像随身带着的瑞士军刀,掏出来就能用。过了几年再摸,刀还在,手感没了。
比如大型 C++ 和 Audio/Video 项目。以前看到音视频问题,脑子里会自然浮出采集、编码、RTP、抖动缓冲、解码、渲染那条链;看到 C++ 崩溃,也会下意识去想对象生命周期、线程同步、内存所有权、ABI、编译选项。可如果很久没碰,概念还认识,下手却会慢半拍。像多年没开的老车,钥匙插进去以后先咳嗽一下。
AI 出来以后,这种感觉更微妙。
一方面,它让你随时可以查:std::unique_ptr 怎么用、Opus packet loss concealment 是什么、WebRTC stats 里 jitter 怎么看,问一下就有答案。另一方面,它也容易让人产生错觉:既然 AI 都能讲,我是不是也还会?
我越来越觉得,AI 时代真正危险的不是知识生锈,而是你不知道它已经生锈了。
这就像《方世玉续集》里元奎饰演的李国邦。公开资料里能查到,这个角色是苗翠花的师兄、方世玉的师叔,为人胆小,口头禅是“安全第一”。影迷更津津乐道的,是他那种带着冷幽默的江湖自信:
“别以为我退隐江湖了,告诉你,我的功夫是没生锈的。”
结果呢?真到了要拼命的时候,“安全第一”没能挡住于镇海,“功夫没生锈”也救不了一个判断已经生锈的人。
程序员也一样。最怕不是不会,而是半会不会;不是忘了,而是记得一个过期版本;不是手生,而是手生还硬装手熟。
所以问题不是:长久不用的知识还能不能捡起来?
我的答案是:能。但不能靠情怀,也不能靠临时抱佛脚。要靠一套能让知识恢复战斗力的方法。
先承认一件事:知识一定会生锈
程序员最容易高估自己的“曾经会过”。
曾经写过 C++,不等于今天还能稳稳写出异常安全、生命周期清楚、并发不乱的 C++。曾经做过音视频,不等于今天还能快速判断一个卡顿问题到底是网络、编码器、jitter buffer、设备路由,还是线程调度。曾经读过一堆 RFC,也不等于今天还能在凌晨两点的线上事故里把关键字段想起来。
知识不用,会发生三种退化。
第一种是细节退化。API 名字、参数顺序、编译选项、工具命令会忘。这个问题最轻,AI 和文档都能补。
第二种是手感退化。你知道大概方向,但下手慢,调试慢,看到错误信息反应慢。像很久没打篮球,投篮姿势还在,球就是短半截。
第三种最危险,是判断退化。你以为自己知道,其实场景变了、工具变了、默认值变了、最佳实践也变了。旧经验在新环境里不是资产,可能变成负债。
比如 C++。你记得“手动管理内存很危险”,但如果只停在这句口号上,今天面对 std::shared_ptr 循环引用、lambda 捕获悬空引用、协程生命周期、跨线程回调,照样会摔跤。
再比如 Audio/Video。你记得“丢包会卡”,但现在的问题可能不是简单丢包,而是关键帧没及时到、参考帧被污染、硬件解码器输出格式变了,或者 AI 降噪把人声边缘吃掉了。旧地图有用,但不能当 GPS。
承认生锈,不丢人。假装没锈,才危险。
先放一张“锈斑检查表”。看完这张表,你大概就知道自己到底是忘了几个 API,还是判断链路已经不太稳了。
| 退化类型 | 表面现象 | C++ 里的典型表现 | Audio/Video 里的典型表现 | AI 能补什么 | 人必须练什么 |
|---|---|---|---|---|---|
| 细节退化 | 名字想不起来 | 忘了 std::move 触发条件、CMake target 写法 |
忘了 stats 字段名、RTCP feedback 类型 | 查文档、列清单、解释概念 | 快速查证和最小复现 |
| 手感退化 | 知道方向但下手慢 | 编译错误看半天,sanitizer 报告读得慢 | pcap、stats、日志串不起来 | 生成示例、辅助解读日志 | 亲手 debug、亲手跑实验 |
| 判断退化 | 旧经验误导新场景 | shared pointer 滥用、异步回调生命周期误判 | 把所有卡顿都归因于“网络不好” | 提供候选假设和检查项 | 排优先级、找证据、做取舍 |
AI 的作用:不是替你练功,而是帮你搭靶场
很多人用 AI 复习旧知识,姿势是这样的:
请给我讲讲现代 C++。
请总结一下 WebRTC 音视频技术。
请列出音视频开发面试题。
这当然有用,但只是热身。它让你觉得“我又懂了”,却未必让你真的能干活。
AI 更好的用法,不是当老师单向讲课,而是当陪练、助教、出题人、记录员。你要让它帮你搭靶场,而不是替你打靶。
我比较推荐这类问法:
我很久没写大型 C++ 项目了,想在两周内恢复到能参与代码评审和小型模块开发的状态。
请帮我设计一个训练计划:
1. 先测我哪些知识已经生锈
2. 每天安排一个 60 分钟练习
3. 每个练习必须有可运行代码或可验证输出
4. 重点覆盖所有权、并发、构建、调试和性能
5. 最后给一个小项目作为验收
再比如 Audio/Video:
我想重新熟悉实时音视频排障。
请生成 10 个故障场景,每个场景包含:
1. 用户现象
2. 可能的故障域
3. 需要采集的 stats 和日志
4. 最小复现实验
5. 不要直接给结论,先让我判断
注意这里的关键:让 AI 出题,但人必须作答;让 AI 整理,但人必须验证;让 AI 提醒,但人必须动手。
知识恢复不是看懂答案,而是重新建立“从现象到判断再到行动”的回路。
一套让知识重新可战的四层方法
我现在更愿意把知识恢复分成四层:地图、索引、演练、验收。
这四层不是线性读书流程,更像一个闭环:
+----------------------+
| v
地图 -> 索引 -> 演练 -> 验收 -> 复盘 / Runbook
^ |
| |
+---------- 新问题 / 新事故 ------+
地图让你知道自己在哪,索引让你快速找到工具,演练让知识回到手上,验收防止“我看懂了”的幻觉。最后的复盘和 Runbook,则是为了下一次别从零开始。
@startuml
skinparam backgroundColor white
skinparam shadowing false
skinparam defaultFontName "Arial"
skinparam roundcorner 12
skinparam activity {
BackgroundColor #F8FAFC
BorderColor #334155
FontColor #0F172A
DiamondBackgroundColor #E0F2FE
DiamondBorderColor #0284C7
}
title 生锈知识恢复闭环
start
:地图\n画出知识骨架;
:索引\n接到真实材料;
:演练\n用小场景恢复手感;
if (验收通过?) then (是)
:复盘 / Runbook\n沉淀可复用经验;
else (否)
:标记锈斑\n补证据和实验;
endif
:进入下一次真实问题;
repeat
:更新地图和索引;
:继续演练;
repeat while (仍有高风险锈斑?) is (是)
->否;
stop
@enduml

1. 地图:先画出知识骨架
长久不用的领域,别一上来就钻细节。先画地图。
以 C++ 为例,我会先画这几块:
- 语言核心:对象模型、值语义、引用、移动语义、模板、异常
- 资源管理:RAII、智能指针、文件句柄、锁、线程生命周期
- 并发:
std::thread、mutex、condition variable、atomic、future、协程 - 工程化:CMake、编译链接、sanitizer、单元测试、性能分析
- 代码质量:异常安全、接口边界、依赖管理、可测试性
以 Audio/Video 为例,则可以先画这条链:
采集 -> 预处理 -> 编码 -> 打包 -> 传输 -> 抖动缓冲 -> 解码 -> 渲染
每一段下面再放关键问题:
- 采集:设备枚举、采样率、声道、权限、路由切换
- 预处理:AEC、AGC、NS、VAD、音量检测
- 编码:Opus、H.264、VP8/VP9/AV1、码率、帧率、关键帧
- 传输:RTP、RTCP、NACK、FEC、RTX、TWCC、拥塞控制
- 播放:jitter buffer、同步、渲染队列、延迟、卡顿
地图的目的不是显摆“我知道很多名词”,而是防止自己迷路。你至少要知道:我现在忘的是哪一块,不能把一个角落的熟悉,误认为整片大陆都还在掌控中。
2. 索引:把知识接到真实材料上
有地图还不够,还要有索引。
索引不是收藏夹。收藏夹最容易变成数字坟场,看着满满当当,实际没人扫墓。真正有用的索引,要能指向“我需要时立刻能用”的材料。
我会给每个领域留几类入口:
- 官方文档:标准、API reference、项目 wiki
- 经典文章:自己确认过、确实讲清楚的材料
- 代码样例:能编译、能运行、能改的最小例子
- 排障手册:常见症状、日志字段、检查顺序
- 个人笔记:踩过的坑、修过的 bug、当时的判断过程
比如 C++,你可以保留一个 cpp-lab 仓库,里面不是大而全教程,而是小而硬的练习:
cpp-lab/
ownership/
move-semantics/
concurrency/
cmake/
sanitizers/
perf/
比如音视频,你可以保留一个 av-lab:
av-lab/
opus-playground/
rtp-packet-dump/
jitter-buffer-sim/
webrtc-stats-parser/
weak-network-cases/
索引的价值在于:当你三个月、半年、一年后回来,不用从互联网的汪洋大海里重新捞针。你打开自己的 lab,就知道从哪里热身。
3. 演练:用小场景恢复手感
知识恢复最忌讳“只看不练”。
看文章会产生一种温柔的错觉:这我懂。真正一写代码,编译器立刻帮你恢复谦逊。
我会把演练分成三种。
第一种是Kata,也就是小型招式练习。比如:
- 用 RAII 封装一个文件句柄,要求异常安全
- 写一个 thread-safe queue,用 condition variable 做阻塞等待
- 用 AddressSanitizer 找出一个 use-after-free
- 写一个简单 RTP header parser
- 模拟 jitter buffer 在不同丢包率下的行为
第二种是病例复盘。找一个真实或半真实的问题,不急着看答案,先自己判断:
现象:用户说声音偶尔变成机器人音。
约束:网络 RTT 不高,但 jitter 有尖峰。
数据:audio concealment events 增加,CPU 偶尔飙高。
请判断前三个可能原因,并设计验证步骤。
第三种是小项目验收。不要大,一周能完成最好。比如:
- 写一个命令行工具,读取 pcap 或日志,统计 RTP sequence gap
- 写一个 WebRTC stats analyzer,把 jitter、RTT、packet loss 画成时间线
- 写一个 C++ 小服务,包含配置、日志、测试、CI 和性能基准
- 写一个音频小工具,读取 WAV,做音量归一化或简单频谱分析
小项目的作用不是产出伟大作品,而是逼你把散点知识重新接上线。能跑起来,能测,能解释,手感就回来了。
4. 验收:别用“我看懂了”骗自己
重新捡知识,必须有验收标准。否则很容易复习了三天,最后只获得一种“我好像又行了”的幻觉。
我给自己设的验收通常有四条。
第一,能复述模型。不用看资料,能把核心链路讲给一个聪明但不熟悉的人听。
第二,能写最小代码。不是复制,不是让 AI 一把梭,而是自己能写出核心骨架。
第三,能定位问题。给你一个症状和一组不完整日志,你能列出假设、证据、下一步实验。
第四,能审 AI 的答案。AI 给你一段 C++ 或一份音视频排障建议,你能看出哪里靠谱,哪里有风险,哪里缺证据。
最后一条尤其重要。AI 时代,很多人不需要从零写,但必须能审。审不出来,就会被漂亮答案带沟里。
两个真实感更强的工程例子
方法论说多了容易发飘,下面放两个工程里很常见、也很容易把人摔醒的例子。它们的价值不在“故事多精彩”,而在于能看出知识生锈以后,问题会怎样绕过你的自信。
例子一:C++ 异步回调里的悬空对象
很多 C++ 项目里都有这种代码味道:
class Session {
public:
void start() {
timer_.async_wait([this](const Error& err) {
if (!err) {
sendHeartbeat();
}
});
}
private:
Timer timer_;
};
这段代码第一眼看不吓人,甚至很“正常”。问题在于:回调执行时,Session 对象还活着吗?
如果对象已经被销毁,lambda 里捕获的 this 就变成了悬空指针。运气好,测试环境直接 crash;运气不好,线上偶发,堆栈还不稳定。你看日志像看悬疑小说,每个嫌疑人都有作案时间。
这种 bug 特别适合检验 C++ 手感是否生锈。
如果只是细节生锈,你会去查 lambda 捕获规则、智能指针用法,这还好补。如果是判断生锈,你可能会说“这里一直这么写,应该没事”,然后把一个生命周期问题当成偶发网络错误或线程调度问题。
比较稳的处理方式通常有几类:
- 明确取消回调:析构或 stop 阶段取消 timer,保证回调不再触达对象;
- 改用
weak_ptr:回调里先lock(),对象不在就直接返回; - 拆清所有权:让异步任务拥有必要状态,而不是偷偷依赖外部对象还活着;
- 用 sanitizer 验证:AddressSanitizer / ThreadSanitizer 比“我觉得没问题”靠谱得多。
这就是为什么我前面说,知识恢复不能只靠读。生命周期问题必须写、跑、崩、修,手才会重新记住那种边界感。
例子二:绿屏和马赛克,不一定只是“网络不好”
视频问题里,最容易误判的一句话也是:“网络不好。”
这句话不能说错,但太粗。像医生只说“你身体不舒服”,病人听了只想翻白眼。
视频绿屏和马赛克,是音视频工程里非常有画面感的事故。用户不需要懂 H.264、VP8、YUV,也不需要看 stats。他只要截一张图发过来,整个群都会安静两秒:远端人脸变成一片绿色,或者画面碎成马赛克,像压缩算法喝多了。
这类问题常见于几个场景:
- 弱网恢复后,画面没有立刻恢复正常,而是持续马赛克;
- 切换摄像头、切换分辨率、切换 simulcast 层以后,部分客户端绿屏;
- 某些 Android 机型或某些显卡上容易出现,换软解后消失;
- 共享屏幕还好,摄像头视频更容易花;
- 声音正常,视频单独坏,看起来不像整条连接断了。
第一反应当然会怀疑网络:是不是丢包太高?是不是码率估计太激进?是不是 NACK/RTX 没救回来?这些都该查,但不能只查这些。
马赛克通常和参考帧被破坏有关。视频编码不是每一帧都完整保存,大量 P/B 帧都依赖前面的参考帧。如果关键的参考帧丢了、错了,后面的帧就会“认真地错下去”。这时候 decoder 不是完全不能解,而是带着错误参考继续解,用户看到的就是一片一片的花屏。解决思路通常不是盲目加码率,而是要看:
- 丢包后有没有及时发 PLI/FIR 请求关键帧;
- 关键帧是否真的到达,还是被网络继续丢掉;
- NACK/RTX 回来的包是否已经错过播放窗口;
- 切换分辨率或 simulcast 层时,是否等到了新层的 keyframe;
- stats 里的
keyFramesDecoded、framesDropped、freezeCount有没有异常。
绿屏则常常是另一类味道:像素格式、stride、crop 或硬件解码器状态出了问题。
比如解码器输出的是 NV12,渲染侧却按 I420 去解释;或者分辨率变了,Y plane、UV plane 的 stride 没更新;或者硬解在 resolution change 之后没有正确 flush/reconfigure,上一帧的纹理状态被继续拿来画。结果就是用户看到一整块绿色、紫色,或者半边正常半边异常。
这种时候,最小验证实验很重要:
- 同一条视频流,软解是否正常、硬解是否异常;
- 同一设备上,H.264 和 VP8/VP9 表现是否不同;
- 关闭 simulcast 或固定分辨率后,问题是否消失;
- 强制请求 keyframe 后,马赛克是否恢复;
- 打印 decoded frame 的 width、height、stride、crop、format,是否和渲染侧一致。
这个例子的教训很朴素:
| 看到的现象 | 容易误判 | 真正要查的证据 |
|---|---|---|
| 弱网后持续马赛克 | 单纯网络差 | PLI/FIR、keyframe 到达时间、参考帧是否恢复 |
| 切换分辨率后绿屏 | 编码器坏了 | decoder reconfigure、SPS/PPS、frame width/height/stride/crop |
| 只在部分设备出现 | 用户设备太差 | 硬解/软解对比、像素格式、GPU texture 更新 |
| 声音正常但视频坏 | 整条连接异常 | audio/video stats 分开看,定位到视频解码或渲染链路 |
如果音视频知识生锈,很容易停在“网络不好”或“解码器有 bug”。这两句话也许都对,但都不够。工程上真正有价值的是继续往下问:是关键帧没来,还是参考帧坏了?是 codec 参数变化没处理,还是 YUV buffer 被错误解释?是媒体包问题,还是渲染层拿错了 stride?
这才是来之能战的知识。
一个两周恢复计划:以 C++ 和 Audio/Video 为例
如果要把 C++ 和 Audio/Video 重新捡起来,不追求“重回巅峰”,只追求“来之能战”,我会按两周安排。
先用一张表看全局:
| 阶段 | 时间 | 目标 | 产出物 | 验收标准 |
|---|---|---|---|---|
| 摸底 | 第 1-2 天 | 找出锈斑 | 诊断题、错题清单 | 能说清楚最弱的 3 个点 |
| 小练习 | 第 3-6 天 | 恢复手感 | RAII、queue、RTP parser、jitter 模拟 | 每个练习能运行、能解释 |
| 小项目 | 第 7-10 天 | 串起链路 | webrtc-stats-lite 或类似工具 |
有输入、输出、异常处理 |
| 病例复盘 | 第 11-14 天 | 训练判断 | 3-5 个故障病例分析 | 能列假设、证据和下一步实验 |
第 1-2 天:摸底,不急着补课
先让 AI 出一份诊断题,但自己答。
C++ 方向可以测:
unique_ptr、shared_ptr、weak_ptr的适用边界- 移动构造和拷贝构造的触发场景
- lambda 捕获引用的生命周期风险
std::atomic和 mutex 的取舍- CMake target、include path、link library 的基本组织
Audio/Video 方向可以测:
- RTP timestamp 和 sequence number 的作用
- jitter、RTT、packet loss 的区别
- NACK、FEC、RTX 的代价
- AEC、AGC、NS 的常见副作用
- 音画不同步可能从哪些层产生
摸底的目的不是考试,而是找到锈斑。
第 3-6 天:每天一个小练习
不要贪多。每天一个 60 到 90 分钟的小练习,做完要能运行。
比如:
- Day 3:写 RAII wrapper,加单元测试
- Day 4:写 thread-safe queue,用 sanitizer 跑一遍
- Day 5:解析 RTP header,输出 sequence、timestamp、payload type
- Day 6:写一个 jitter buffer 的简化模拟,观察乱序和丢包
这几天重点不是学新东西,而是让手重新相信脑子。
第 7-10 天:做一个小项目
选一个真实有用的小项目,比如 webrtc-stats-lite:
输入:浏览器导出的 WebRTC stats JSON
输出:
1. RTT / jitter / packet loss 时间线
2. 码率变化
3. 音频 concealment 指标
4. 可疑时间段标记
实现可以让 AI 辅助,但关键设计自己定:
- 数据结构怎么表示
- 指标之间怎么关联
- 哪些异常只提示,不下结论
- 输出格式如何方便人读
做完以后,你对音视频链路和工程手感都会恢复一截。
第 11-14 天:做病例分析和代码审查
最后几天别再堆知识点,改做判断训练。
让 AI 生成几个故障病例,或者拿以前的线上问题复盘。每个病例按这个模板写:
现象:
初步假设:
需要的数据:
最小实验:
可能修复:
上线风险:
回滚方案:
同时找几段 AI 写的 C++ 或音视频代码做 review,重点看:
- 生命周期有没有悬空
- 错误处理是不是只写了 happy path
- 并发有没有数据竞争
- 日志有没有泄露隐私或打爆性能
- 音视频判断有没有缺证据就下结论
到这一步,如果你能指出 AI 答案的漏洞,说明知识不只是热了,还开始恢复战斗力了。
防止再次生锈:要靠维护节奏,不靠热血
知识恢复一次不难,难的是别每次都从废墟里重建。
我现在比较相信一个很朴素的节奏。
每周:保留一块手感自留地
每周至少留一小段时间,关掉 AI 或限制 AI,只做一个很小的动手练习。
比如手写一个 parser,手调一个 sanitizer 报错,手读一段编解码代码。不是为了效率,而是为了保住那种“看到问题能下手”的肌肉记忆。
AI 可以提高产能,但不能替你保持手感。刀可以让别人磨,手不能让别人长。
每月:做一次知识巡检
每个月挑一个领域问自己三件事:
- 这个领域最近有没有重要变化?
- 我上次真正动手是什么时候?
- 如果明天有人问我一个生产问题,我能不能提出验证路径?
答不上来,就安排一次小演练。
每季度:更新一次个人 Runbook
把你踩过的坑、查过的问题、验证过的结论写进自己的 runbook。
不要写成漂亮论文,就写成能救命的格式:
症状:
优先检查:
关键指标:
常见误判:
验证命令:
修复注意:
真正有价值的知识库,不是“我收藏了什么”,而是“下次出事时我少绕多少弯路”。
每半年:做一次小型回炉
半年不用的硬技能,默认手感下降。别争,争不过人性。
给自己安排一个周末或两三个晚上,做一次小项目回炉。不要等到面试、换岗、项目救火时才想起来。那时候再练,就像比赛前夜才找球鞋,多少有点狼狈。
几个常见坑:生锈不可怕,乱磨才可怕
第一,别用“看视频”代替练习。
视频看起来很顺,因为坑都被讲课的人替你踩平了。真正恢复能力,一定要自己遇到编译错误、数据不对、图画不出来、日志看不懂。痛感是学习的一部分。
第二,别让 AI 直接给最终答案。
你可以让 AI 提示、追问、出测试、生成对比表,但不要一上来就让它总结最佳实践。最佳实践如果没有经过你的场景过滤,就只是互联网平均值。
第三,别只补新知识,不修旧误解。
很多生锈的知识不是空了,而是旧了。旧经验最麻烦,因为它有熟悉感。你要专门问:我过去的做法今天还成立吗?有什么默认条件已经变了?
第四,别一恢复就接高风险任务。
刚回炉时,适合做工具、测试、review、低风险模块;不适合直接接核心链路大改。拳头刚热,别立刻去打擂台。先打沙袋,再上实战。
总结:AI 让知识更容易捡起,也让错觉更危险
长久不用的知识,当然能重新捡起来。
但捡起来不是把概念再读一遍,也不是让 AI 给你生成一份“从入门到精通”。真正有用的方法,是把知识重新接回四个东西:地图、索引、演练、验收。
一句话:
生锈的知识不可怕,可怕的是没有打磨就上战场;AI 不会替你长功夫,但可以帮你搭一个更好的练功房。
最后给自己,也给同样有点手生的老程序员一张清单。
行动清单
- [ ] 给一个久不用但重要的领域画一张知识地图,标出最生锈的三块。
- [ ] 建一个小型
lab仓库,只放能运行、能验证、能复用的练习。 - [ ] 让 AI 出题,不让 AI 直接给结论;先自己判断,再对答案。
- [ ] 每周保留一次不用 AI 或少用 AI 的手感练习。
- [ ] 每月更新一个 runbook 条目,记录真实坑、关键指标和验证路径。
- [ ] 接高风险任务前,先用小项目或病例分析完成一次验收。
别做李国邦式的“安全第一”:嘴上说功夫没生锈,心里其实没做过验收。安全当然要第一,可前提是你真知道自己的功夫现在还剩几成。
功夫会生锈,没关系。定期擦,定期练,关键时刻还能拔得出来。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。