惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
IT之家
IT之家
Google DeepMind News
Google DeepMind News
罗磊的独立博客
爱范儿
爱范儿
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
U
Unit 42
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
B
Blog
博客园 - 叶小钗
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

暗无天日

读:AI Agent 安全日志——从可见性与隐私的两难说起 - 暗无天日 AI写作的语言指纹——如何让文字不那么像机器 - 暗无天日 读:50 条 Claude Code 技巧——一个工程经理的六个月使用心得 读:AI 辅助开发为什么让 E2E 测试更有价值 - 暗无天日 读:在Emacs中使用Claude Code(Spacemacs适配版) - 暗无天日 Claude Code 背后的工程哲学——读 Agent Harness Engineering 读:Agent Harness Engineering——AI 智能体不只是模型,还有套件 - 暗无天日 browser-harness:让 AI 直接接管你的浏览器 - 暗无天日 读:Security-First CI/CD —— DevSecOps 自动化实践指南 TIL: 数字小键盘的小数点陷阱与行内算术求值 - 暗无天日 读:Immutability 不是万能药,它是一种权衡 - 暗无天日 Conducty:给 Claude Code 加上项目记忆和并行执行能力 - 暗无天日 读 — GitHub Trending 里的 Claude Code 技能包 读 — Prompt Caching 省钱指南 TIL: Emacs 中那些跟鼠标配合的冷门快捷键 - 暗无天日 读:Anvil——把 Emacs 变成 AI 的工具服务器 读:Emacs 代码折叠终极指南 - 暗无天日 读:Clojure 搭车客指南 - 暗无天日 git推送失败后恢复仓库损坏的完整记录 - 暗无天日 多智能体系统的两个有效模式——以及对 Claude Code 用户的启示 - 暗无天日 用 Org Babel 写 Literate 博文:扩展执行 + 定制导出 proced:Emacs 内置的进程查看器 - 暗无天日 从 proced 定制中学到的 Elisp 模式 读:让 Emacs proced 在 macOS 上显示 CPU 和内存 异步编程的函数着色税 - 暗无天日 链式调用的代价:JavaScript 和 Clojure 的共同教训 - 暗无天日 hyperfine:命令行基准测试工具 - 暗无天日 管道中的变量去哪了?——子 shell 作用域陷阱 - 暗无天日 开源包装器的信任陷阱:四个危险信号 - 暗无天日 程序员愿意为 AI 写文档,却不愿为同事写 - 暗无天日
读:20条软件工程定律 - 暗无天日
2026-05-17 · via 暗无天日

Milan 在他的newsletter里整理了 20 条软件工程定律。这些定律有些来自 1960 年代,到现在还管用。它们讲的是人在压力下一起造东西时会发生什么,不教你怎么做,只告诉你已经发生了什么、什么行不通。下面逐条解读。

Gall 定律

一个能跑的复杂系统,一定是从一个能跑的简单系统演变来的。

系统在纸面上看着没问题,真正的问题要等真实用户用起来才会暴露。所以每个能跑的复杂系统都是一步步长出来的。想一步到位造出完美系统,基本都失败了。从零重写的系统经常翻车也是这个原因:大功能倒是照搬了,但老系统在多年运行中积累的那些不起眼的小设计(比如某个特殊的缓存策略、某条异常处理路径),没人记得也没人照搬,而它们恰恰是让系统跑起来的关键。

Instagram 前身叫 Burbn,集合了签到、游戏、拍照分享。创始人砍掉所有功能只留照片分享,变成了现在的 Instagram。Google Wave 反其道行之,聊天、邮件、论坛、文档编辑一起上,没人说得清它到底是干嘛的,15 个月就死了。

KISS 原则

保持简单。超出必要的都是负担。

能 50 行脚本解决的问题,别搞 500 行的复杂方案。每多写一行代码就多一分引入 bug 的风险。简单的设计好维护:新人上手快,bug 好找,改一处不会牵动一片。别整那些花里胡哨的代码技巧,也别替未来还不存在的问题预埋复杂度。

有个创业公司需要功能开关(feature flag,不改代码就能开关某个功能的配置项),于是建了一个独立微服务:自己的数据库、缓存、管理界面、WebSocket 通知、A/B 测试支持,花了大量时间,出了问题还很难查。其实一个 JSON 配置文件就够了,一个下午搞定。

Conway 定律

组织的沟通结构会镜像到系统架构里。

你的应用架构基本等同于组织架构图。四个团队做项目,大概率产出四个模块。前端、后端、数据各干各的,做出来的东西也拼不到一块。光重写系统不调组织架构,换汤不换药。

反过来也成立:先选好想要的架构,再按架构组建团队。Amazon 在 2000 年代就把系统拆成小服务、每个服务一个小团队,系统和组织一起变了。这叫逆向 Conway 播种(Inverse Conway's Maneuver)。

三人的团队几乎总是出单体应用,因为拆分的成本比维持整体的成本还高。

Hyrum 定律

用户够多之后,你 API 的每一个可观测行为都会变成某人的依赖,不管接口文档怎么写。

接口文档写着不算数,系统实际表现出来的才算。响应时间、错误信息的文字、JSON 字段顺序、哈希的精确字节,这些你从没觉得重要的细节,总有人依赖着。

SimCity 有个 use-after-free 的 bug,在 Windows 3.x 上没事,因为内存压根不被回收。到了 Windows 95 真正回收内存了,SimCity 就崩。微软专门在 Windows 95 里加了一个特殊内存分配模式,只在 SimCity 运行时激活,让这个 bug 继续工作。

浏览器也是这么干的。Web 开发者依赖的每一个怪癖都变成了平台的一部分,浏览器改不了,改了就崩半个互联网。

CAP 定理

分布式系统只能同时保证一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的两个。

网络迟早会断。一旦两个节点联系不上(这就是分区),你要么停写保数据一致,要么继续服务但允许副本间数据不一致。每个分布式数据库都做了选择,只是多数不会主动告诉你。

MongoDB 选了 consistency:分区时某些副本拒绝写入,等整个系统恢复。Cassandra 则选了 availability:副本数据不一致时照样响应查询,之后再修。谁都没错,取舍不同罢了。

Zawinski 定律

每个程序都会膨胀到能收发邮件为止。做不到的会被能做到的替代。

这是 Netscape 早期工程师 Jamie Zawinski 在 1990 年代说的玩笑话。那个年代浏览器、编辑器、日历都在加邮件功能,好像不收发邮件就不完整。说白了就是每个程序都会无限制地膨胀,直到塞满所有能想到的功能。工具做好了、用户喜欢,产品方就想让人留在平台上,于是不断往里塞东西。时间一长,工具变得又慢又臃肿,然后新的竞争者带着精简版出现。

Netscape 从浏览器膨胀成套装(邮件、新闻、网页编辑器),Firefox 来收拾残局,精简后火了,然后又加插件和开发工具链。Slack 诞生时说要杀死邮件,现在有语音、视频、机器人、应用商店。

Brooks 定律

给延期的项目加人,只会让它更延期。

软件工作拆不了。新人进来要上手,老手得停下手头的活来带。项目已经延期了,加人只会添乱。Brooks 说得好:九个女人也不能一个月生出孩子。

有人带过一个八人团队,一直延期。第一反应是招两个人。结果招人期间走了两个,团队变成六个人,沟通反而顺畅了,产出反而更高了。

Ringelmann 效应

团队越大,人均产出越低。

很多人一起拉绳子,每个人反而不用那么大力。协作摩擦是一方面,"总觉得别人会做"是另一方面。

GitHub 做过大规模统计:2-5 人团队的工程师平均每月写 1850 行代码,10 人团队降到 1200 行,50 人以上只剩 450 行。人均掉了 75%。小团队出活快,Amazon 的"两个披萨"规则也是这个道理。

Price 定律

一半的工作是由人数的平方根完成的。

100 人的团队,大约 10 个人干了一半的重要工作。16 人的团队,4 个人承担主要产出。所有创意领域都这样。核心的人走了,团队产出能力大幅缩水。剩下的人也没闲着,干的是让团队运转起来的支撑活。

Musk 接管 Twitter 后裁员约 50%,网站照样跑。Price 定律提前预测到了。但裁掉的是那些不怎么显眼却不可或缺的能力:内容审核团队没了,SRE(站点可靠性工程)人手不够了,出了故障没人能深入排查根因,只能头疼医头。核心人员撑住了日常运转,但碰到下一个复杂问题就抓瞎了。Twitter 后来悄悄请回了一些被裁的人。

Dunning-Kruger 效应

你对一件事知道得越少,越自信。

做一件事需要的本事,和判断自己做得好不好的本事,是同一件本事。不会的人看不出自己哪做错了,觉得自己挺厉害。会的人看得到自己所有的不足,觉得自己还不够好。

新工程师被问到工期,张口就来一个精确数字。老工程师给的是范围,口头禅是"看情况"。新人不是在瞎说,他们只是还不知道自己不知道什么。

刚接触新技术的人总是特别兴奋。AI 领域正在上演这一幕:喊"AI 什么都能做"最响的,通常不是天天在用 AI 的人。

Hofstadter 定律

做事总是比你预期的久,就算你已经考虑了 Hofstadter 定律也一样。

你估 4 周,想起自己总是太乐观,翻倍到 8 周,最后花了 16 周。下次学乖了估 16 周,结果花了 32 周,因为总有你不知道的意外冒出来。

柏林勃兰登堡机场就是个典型。软件集成涉及 75000 个传感器和 50000 个灯具控制,原计划 18 个月完工,后来意识到不可能,延长到 30 个月。最终花了 7 年,造价 70 亿欧元,超支 2.5 倍,晚了 9 年。

Parkinson 定律

工作会膨胀到填满分配给它的时间。

给开发者两周做一个两天能完成的任务,他会花两周。不是说他想偷懒,而是在两周里会做计划、试方案、加没人要求的花哨细节(gold-plating)。截止日期就定一天,他大概率一天能交。

Goodhart 定律

一个指标一旦变成考核目标,就不再是好指标了。

拿 bug 数、事故数、测试覆盖率、团队速度来考核人,大家就会想办法让数字好看,而不是把事做好。数字上去了,质量没动。

2000 年代初有团队按代码行数发奖金,后来有人按 PR 数考核。结果开发者开始复制粘贴而不是提取共享逻辑,有人几乎每次提交都开一个 PR。现在流行按 AI token 消耗量(tokenmaxxing)来衡量,消耗越多越"高效"。

Gilb 定律

任何你需要量化的东西,总能找到某种方式来测量,而且比不量强。

Gilb 定律和 Goodhart 定律一体两面。Goodhart 说指标被滥用会失真,Gilb 说没指标更糟。重要的东西就该想办法去量,量不了就没法优化。DORA 指标里的部署频率和变更交付时间就是开发生产力的可用度量,不完美,但比代码行数和 token 消耗靠谱。

Knuth 的优化原则

过早优化是万恶之源。

性能优化经常做早了、做错了地方。团队优化了永远不会成为热点的代码路径,引入了用不上的复杂度,花时间解决根本不会遇到的规模问题。先写出能跑的代码,再查性能。瓶颈在哪,就改哪。没有就继续往前走。

有人在创业公司花了大量时间搭 Kubernetes,为了扛百万用户。问题是他连 10 个用户都还没有。基础设施做好了,产品功能还没做完。

Amdahl 定律

并行加速的上限取决于串行部分的比例。

10% 的工作必须串行做,那无论多少台机器,最多快 10 倍。50% 必须串行,最多快 2 倍。

人也一样。一个审批组要过问每个技术决策,不管你有多少工程师,速度都卡在审批组。加人只是让排队等着审批的队伍更长。

Web 流量水平扩展,加应用服务器就行,直到每个请求都要打同一个共享数据库或认证服务。之后再加机器没用。

AI 让编码变快了,但思考、检查、修错、协作这些步骤没法并行。所以有人效率提升 10 倍,有人只有 1.2 倍。

Murphy 定律

可能出错的事一定会出错。

空指针、竞态条件、网络断开,用户量够大的时候,一定会在最糟糕的时刻出现。所以代码要写防御性的:检查空值、处理异常、验证输入。运维那边也准备好:监控、回滚方案、应急预案,都不能少。

2024 年 7 月 19 日,CrowdStrike 改了 Falcon Sensor 的配置,850 万台 Windows 蓝屏。修复得人逐台登录,因为机器起不来,远程不了。偏偏那边是周五上午,而且IT还 不在岗。航空公司、医院、银行全中招。能出错的都出了。

Postel 定律

发送要保守,接收要宽容。

自己返回数据时,格式严格按规范来。但收别人的数据时,即使格式不标准只要能安全解读就别直接丢。

浏览器就是活例子。网上大部分 HTML 写得都不规范,但浏览器照样渲染。严格按规范来的话,半个互联网打不开。

但太宽容也有代价:所有人都容忍乱七八糟的输入,问题永远不会被修正,只会越积越多。安全敏感的代码里,容忍输入等于给攻击者开门。宽容不等于放任,得有判断。

Sturgeon 定律

90% 的东西都是垃圾。

造的大部分东西没人用,写的大部分代码质量不行,启动的大部分项目没能交付预期价值。这没什么,创造的常态就是这样。假装一切都好、给每个项目同样的资源,只会把事情搞复杂。要紧的是找到那 10%,砍掉其余的。

WordPress 插件目录大约有 57000 个插件,超过 34000 个两年没更新过,将近 19% 零安装。少数维护良好的插件撑起了公开网站 40% 以上的份额。

Cunningham 定律

在网上得到正确答案最快的方法,是贴一个错误的答案。

论坛提问经常没人理。贴一个明显错误的东西,马上就有人跳出来纠正。路过问题可能懒得停,看到错误忍不住要改。遇到难题别问"该怎么做",提一个你明知道不太行的方案,正确答案可能不请自来。

Wiki 和后来的 Wikipedia 赌的就是这个:人们改错的速度远快于从零写新文章。事实证明这个赌赌对了,Wikipedia 就是靠这个机制撑起来的。

这些定律之间的关系

20 条不用全记住,前五六条能解决大部分问题,剩下的等新问题冒出来再查。关键是要知道什么时候哪条适用。

定律之间会打架。Knuth 说别过早优化,Amdahl 说找到瓶颈修掉它。两条都对,但适用时机不同:项目早期听 Knuth,性能真出问题了听 Amdahl。

还有一点:这是作者个人的清单,他还出了本书涵盖了 56 条定律。你自己的清单会不一样。哪些定律让你吃过亏,哪些对你就是最重要的。下次遇到项目事故、团队重组、系统重写,花一分钟记下来:哪条定律帮了你?哪条给了教训?记久了,你自己的清单比谁的都好用。

框架、平台、部署模式从 Brooks 1975 年写书到现在变了很多,但这些定律没变,因为人性从不改变。