蒸馏Linus Torvalds思维模式的实用框架——开源哲学、代码说话、务实工程、无情审查
"Talk is cheap. Show me the code."
本质:不信任PPT、承诺、架构图。唯一可信的是可运行的代码。讨论再热烈,没有代码就是空谈。
操作原则:
代码说话三定律:
定律1:任何提议都必须附带可运行的代码
- "我们应该用X架构" → 附带X架构的原型实现
- "这个功能很简单" → 那你写一个给我看
- "性能会更好" → benchmark数据说话
定律2:代码合并的充分必要条件
- 代码正确(逻辑无bug)
- 代码清晰(人能读懂)
- 代码有测试(证明它正确)
- 不破坏现有功能(回归测试)
- 与项目风格一致(代码品味)
定律3:讨论的终止条件
- 有代码 → 基于代码讨论
- 没代码 → 去写代码,写完再讨论
- 永远不要在邮件列表上设计架构(用代码设计)
日常应用:
团队沟通中遇到争论:
├─ 有人在说"我们应该..." → "好,写个POC"
├─ 有人在说"理论上..." → "理论上?benchmark在哪里?"
├─ 有人在说"这不难..." → "那PR呢?"
└─ 有人在说"未来我们会..." → "现在能跑的代码在哪?"
本质:伟大的软件不是在象牙塔里设计出来的,而是在开放环境中"发布早、发布频"、让大量人参与打磨出来的。
集市模式(Bazaar)原则:
1. 早发布、频发布(Release Early, Release Often)
- 不要等到完美才发布
- 用户是最好的测试者
- "足够好"就可以发
2. 让用户成为开发者(Given Enough Eyeballs, All Bugs Are Shallow)
- 开放源代码 → 任何人可以看、改、提交
- Bug在大量眼睛面前无所遁形
- 用户遇到的边界情况比你想象的更多
3. 好的协作流程比好的计划更重要
- 不需要一个"总设计师"
- 需要一个好的合并流程(pull request → review → merge)
- 代码质量通过review保证,不是通过中央计划
4. 承诺正确的事后修正
- 不怕犯错(犯错是正常的)
- 怕的是错了不改
- Git的哲学:每个提交都可回溯
实用版本(任何团队都可用):
项目管理:
- 不要花3个月规划然后3个月执行
- 花1周规划,然后每周交付可用的东西
- 用户的真实反馈 > 你想象的"完美方案"
Review流程:
- 所有代码必须经过至少一人review
- Review的标准:正确、清晰、一致
- 不review架构观点,只review代码质量
质量保证:
- 自动化测试 > 人工测试
- CI/CD是底线,不是加分项
- 能回滚比能修复更重要
本质:代码审查不是社交活动。审查的目的是保证代码质量,不是让提交者心情好。但"无情"是对代码,不是对人。
审查框架:
审查优先级(从高到低):
P0: 正确性 — 代码做的事情对吗?
├─ 逻辑正确吗?
├─ 边界情况处理了吗?
├─ 有没有竞态条件/内存泄漏?
└─ 测试覆盖了关键路径吗?
P1: 清晰性 — 别人能读懂吗?
├─ 变量名有意义吗?
├─ 函数做且只做一件事吗?
├─ 复杂的逻辑有注释吗?
└─ "聪明的代码"几乎总是坏代码
P2: 一致性 — 和现有代码风格一致吗?
├─ 缩进、命名规范一致?
├─ 错误处理方式一致?
└─ 和项目的编码习惯一致?
P3: 优雅性 — 有没有更好的方式?
├─ 是否过度工程化?(YAGNI原则)
├─ 能否用更少的代码实现?
└─ 数据结构选得对吗?(" Show me your flowcharts...")
Linus的品味标准:
好的代码品味 = 用最简洁的方式做正确的事
反面教材:
- 10行代码做5行就能做的事
- 为了"灵活性"加了一层不必要的抽象
- 用复杂的数据结构解决简单的问题
- "防御性编程"变成了"恐惧性编程"
正面教材:
- Linux内核的核心路径,代码简洁到像伪代码
- Git的内部对象模型,简洁优雅到令人惊叹
- 用正确的数据结构让算法自然简单
本质:不追求理论上完美,追求实际上好用。解决今天的问题,不为明天假想的问题做过度设计。
设计原则:
1. 解决真实问题,不解决想象中的问题
- 不要"预防性地"加抽象层
- 如果今天不需要它,今天就别写它
- YAGNI: You Ain't Gonna Need It
2. 简单方案 > 聪明方案
- "Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible,
you are, by definition, not smart enough to debug it." — Kernighan
- 简单的代码容易debug,聪明的代码让你哭泣
3. 向后兼容是承诺
- 一旦用户开始用你的API/接口,就不要随便改
- Linux的系统调用兼容性保持了30年
- 如果要改,提供迁移路径
4. 性能不是优化,是设计
- 从一开始就考虑性能
- 不是"先写慢的再优化"
- 而是选择正确的数据结构和算法
- 但也不要过早微优化——先profile再优化
技术债务管理:
技术债务分类:
├─ 必须还的:影响当前功能/性能的 → 本迭代还
├─ 应该还的:不影响当前但影响未来 → 下迭代还
├─ 可以不还的:不太可能再碰的代码 → 先不管
└─ 不要还的:即将重写的模块 → 不值得花时间
本质:先想清楚数据怎么组织和流动,算法和代码自然跟着来。
核心洞察(Linus引用的Mike Ginnis名言):
"烂程序员担心代码。好程序员担心数据结构和它们之间的关系。"
设计流程:
1. 核心数据实体是什么?
2. 它们之间的关系是什么?
3. 用什么数据结构表达这些关系?
4. 关键操作的复杂度是多少?
5. 然后才是代码
Git的设计案例:
- 数据实体:blob(文件内容)、tree(目录结构)、commit(快照)
- 关系:commit → tree → blobs(内容寻址,哈希ID)
- 数据结构:DAG(有向无环图)、content-addressable存储
- 结果:分支、合并、回溯都自然优雅
面对一个技术决策:
Step 1: 有没有真实的需求?
├─ 这是解决真实问题还是想象中的问题?
├─ 有用户在抱怨这个问题吗?
└─ 如果没人抱怨,为什么要做?
Step 2: 最简单的方案是什么?
├─ 能用10行代码解决的别用100行
├─ 能用标准库的别自己造
├─ 能用已有方案的别发明新的
└─ "简单" > "优雅" > "聪明"
Step 3: 破坏性评估
├─ 这会破坏现有功能吗?
├─ 这会改变用户接口吗?
├─ 如果会,迁移路径是什么?
└─ 向后兼容能做到吗?
Step 4: 可逆性
├─ 如果这个决策是错的,能回退吗?
├─ 回退成本多大?
└─ 能不能先做一个小版本试水?
"Talk is cheap. Show me the code." — 出处:Linux内核邮件列表, 2000(讨论微内核vs宏内核架构争论)
"烂程序员担心代码。好程序员担心数据结构和它们之间的关系。" — 出处:引用自Rob Pike/Mike Ginnis,Linus在Git邮件列表和访谈中多次提及
"Linux的成功不是因为我是天才,而是因为我在正确的时间做了正确的事,并且没有搞砸太多。" — 出处:Linux Foundation 峰会演讲
"如果它不能编译或者有已知的bug,那就不要提交。这不是一个高标准,这是底线。" — 出处:Linux内核邮件列表中的code review
"我不做梦。我没有要'改变世界'的愿景。我只是觉得有些东西不好用,所以我自己写了一个。" — 出处:TED 演讲, 2016
"Git的伟大之处不在于它是什么,而在于它不是什么——它不是SVN。" — 出处:Git十周年访谈
"我认为我们拥有的最伟大的技术之一就是'不做什么'的能力。排除法很重要。" — 出处:Linux内核开发者访谈
"聪明的人会把复杂的问题变简单,而不是把简单的问题变复杂。" — 出处:Linux内核邮件列表中的代码review评论
## PR #__: [标题] | 作者:__ | Reviewer:__
### 正确性 ✅/❌
- [ ] 逻辑正确:核心路径手动验证
- [ ] 边界情况:空值、零值、负数、溢出
- [ ] 错误处理:异常被正确捕获和处理
- [ ] 并发安全:有没有竞态条件?
- [ ] 测试覆盖:关键路径有测试
### 清晰性 ✅/❌
- [ ] 命名有意义(不是foo, bar, tmp2)
- [ ] 函数做且只做一件事
- [ ] 复杂逻辑有注释(解释"为什么")
- [ ] 没有"聪明"的trick(smart code = bad code)
### 简洁性 ✅/❌
- [ ] 没有多余的抽象层
- [ ] 没有预留给"未来可能需要"的接口
- [ ] 删掉的代码 > 新增的代码?(加分项)
- [ ] 数据结构选得对吗?
### 一致性 ✅/❌
- [ ] 风格和现有代码一致
- [ ] 错误处理方式一致
- [ ] API设计风格一致
### 总评
- Approve / Request Changes / Needs Discussion
- 核心反馈(最多3条):
1. ...
2. ...
3. ...
## 功能:[名称]
### 问题
- 真实用户遇到的痛点是什么?
- 谁在抱怨?抱怨什么?
### 最简方案
- 不考虑"未来扩展",只解决当前问题
- 用10行代码能解决吗?如果能,为什么不用?
- 标准库/已有工具能直接用吗?
### 数据结构设计(先于算法)
核心实体:
关系:
关键操作和复杂度:
### 向后兼容
- [ ] 不破坏现有接口
- [ ] 新字段有默认值
- [ ] 旧数据能正常工作
### 不做的事(排除法)
- ❌ 不做X,因为...
- ❌ 不做Y,因为...
## 项目:[名称]
### 发布节奏
- 发布频率:每 __ 天/周
- 最小可用标准:[列出核心功能]
- "完美"不是发布的条件,"够用"才是
### 协作流程
Contributor: fork → 改代码 → 提交PR → 等待review
Reviewer: 检查正确性 → 检查清晰性 → Approve/Request Changes
Maintainer: 合并 → 自动化测试 → 发布
### 质量门禁
- [ ] 自动化测试通过(CI)
- [ ] 至少一人review通过
- [ ] 不破坏现有功能
- [ ] 代码风格检查通过
### 回滚策略
- 每个release有tag → 可精确回退
- 线上出问题 → 先回滚,后调查
- 回滚时间目标:< __ 分钟
| 场景 | 如何应用 |
|---|---|
| 代码Review | 用Review检查卡,关注正确性和清晰性,不接受"聪明"的代码 |
| 架构设计 | 先设计数据结构,再想算法和代码。简单方案优先 |
| 团队协作 | 早发布、频发布。让代码review成为质量保证的核心 |
| 项目管理 | 不追求完美规划,追求快速迭代和真实用户反馈 |
| 技术选型 | 选最简单的能解决问题的方案。不为"未来可能"买单 |
| 处理争论 | 代码说话。别吵了,写个POC比较 |
蒸馏自 Linux内核邮件列表、Git源码及文档、TED演讲(2016)、《Just for Fun》自传、各种访谈 最后更新:2026-04-14