为什么好软件需要时间,急不得
为什么最好的软件项目要花几年而非几个月,从开源到创业公司,聊聊工程中耐心的价值。

Flask 花了八年才发布 1.0 版本。SQLite 自 2000 年起就一直在积极开发,至今仍在持续改进。Linux 内核已有三十多年历史,可以说是越老越好。与此同时,一家获得风投支持的普通创业公司,通常被期望在 18 个月内拿出增长数据,否则就得解释原因。
好软件实际需要多久才能做出来,与我们期望的时间之间,正越来越脱节。快速交付的压力本身并没有错,但它催生了一种文化:耐心被看作缺乏野心,而那些默默把事情做对的项目,在这些年里却被贬为“慢”。
“一夜成名”的神话
几乎每一个软件领域的“一夜成名”背后,都有一段漫长的历程。React 在 Facebook 内部使用了一年多,才开源出来。Rust 在开发了七年之后才发布 1.0。PostgreSQL 1986 年作为一个研究项目启动,直到 2010 年代才成为生产环境的首选数据库,期间近三十年都在稳步改进、默默积累。
看似突然的崛起,通常是持续累积的改进跨过了可见度门槛的结果。软件一直在变好,只是大家没注意,直到它好到无法忽视。
Flask 的作者 Armin Ronacher 就直接谈过这件事。Flask 2010 年作为一个愚人节玩笑诞生,后来几乎是意外地变成了一个正经项目。多年的渐进式工作——修复边界情况、完善文档、重新思考 API 设计——让它成为最受欢迎的 Python Web 框架之一。这些年没有一年是白费的,每一年都让地基更牢固。
为什么软件有不可压缩的时间成本
有些问题无法靠加人或加班来加速。Fred Brooks 在 1975 年的《人月神话》(The Mythical Man-Month)中就指出了这一点,而其核心洞见至今没有过时:软件开发中的某些环节是顺序性的,无法并行化。
- 理解问题域。你不在某个问题空间里待上一段时间,就无法真正理解它。任何软件的第一版都会固化你最初的假设,第二版则会体现你从第一版中学到的东西。真正的理解需要反复迭代,而迭代需要时间。
- API 设计与稳定性。好的 API 是在使用中逐渐成形的。闭门造车设计不出完美的 API,你需要真实用户踩过真实的边界情况。那些急于发布 1.0 的库,往往要为早期的设计决定后悔好几年。
- 边界情况与打磨。一个功能的前 80% 只需要 20% 的时间,剩下的边界情况、错误处理和平台怪癖却要占掉另外 80%。这个比例并非偷懒,而是让软件变得可靠这件事本身的基本性质。
- 社区与生态。一个工具在拥有文档、教程、插件以及能回答问题的社区之前,并不算真正好用。这样的生态无法凭空制造,只能随时间有机生长。
人为制造紧迫感的代价
“快速行动,打破常规”对于一个想要找到产品市场契合度的社交网络来说,是个合理的口号。但对于基础设施、开发者工具、数据库,或者任何其他系统要依赖的软件来说,这是个糟糕的理念。仓促打造基础软件,破坏会层层累积。
我见过好几个前景不错的开源项目垮掉,原因都是想增长的速度超过了地基所能支撑的程度。模式几乎是可以预见的:项目变得流行,维护者迫于压力要快速发布功能,质量随之下滑,贡献者精疲力竭,用户则转投更稳定的替代品。讽刺的是,慢下来反而能走得更远。
能持续下去的项目,并不是发布速度最快的那些。它们是在早期做出了足够好的决定,因而后来不必推倒重来的项目。
技术债不只是代码乱。它也来自在时间压力下做出的决定,这些决定会限制未来的可能性。每一个为了快速交付而走的捷径,都会对之后的每一次变更征收一份“税”。有些捷径值得走,但应该是有意识地选择,而不是因为有人随手把截止日期定在了下周二。
耐心在实践中是什么样子
软件开发中的耐心并不是为慢而慢。它意味着对于要做什么足够审慎,对于事情需要多久足够诚实。以下是我见过行之有效的几种做法:
- 尽早发布,但谨慎承诺。尽快把软件交到用户手中,以便获取反馈,但对于哪些内容要作为稳定 API 来承诺,务必保守。大胆使用 0.x 版本号,并且明确告诉用户,东西可能会变。
- 对功能说不。你添加的每一个功能,都意味着要永久维护。最好的项目对自己的范围有明确的主见。SQLite 明确列出了它永远不会做的事情,正是这份自律,让它成为全球部署最广的数据库。
- 投资基础工作。文档、测试、错误信息、性能,这些都不起眼,却会复利式地累积。一个文档完善、测试套件扎实的项目,到第三年的推进速度,可能会超过文档糟糕的项目在第一年的速度。
- 保护维护者的精力。倦怠是开源项目头号杀手。可持续的节奏比冲刺速度更重要。一位维护者每周专注工作 20 小时,坚持五年,产出远超每周工作 80 小时、只干六个月然后消失的人。
创业公司的速度陷阱
创业公司面临一个真实的两难:它们需要快速行动才能活下来,但行动太快又会造出脆弱的系统,规模一大就成了负担。处理得好的公司,通常会区分两种不同的速度。
迭代速度——你能多快地验证想法、获取用户反馈并调整方向。这一点应该被最大化。短周期、快速原型、敢于推翻重来。
承诺速度——你能多快地锁定架构决定、公开 API 和数据模型。这一点应该被最小化。尽可能保持可逆性。推迟不可逆决定的时间越长,等到真正做决定时,手里的信息就越充分。
大多数创业公司犯的错误,就是把这两者混为一谈。它们对架构的承诺速度与功能迭代一样快,然后接下来两年都在为过早的决定买单。
从那些经受住时间考验的项目中学习
我们最依赖的软件项目有一个共同特点:它们在某个时候都曾被认为“慢”。PostgreSQL 曾是那个无聊的选择,而 MySQL 则是快速随性的选项。Python 曾被说“太慢”,而 Perl 才是务实的选择。Git 花了好几年才变得普通人也能用。
这些项目真正拥有的是时间,有时间犯错、从错误中学习,并打磨出扎实的东西。它们在第一年并没有试图满足所有人的所有需求,而是努力在核心目标上做到出色,并且愿意让这份出色花上它所需要的时间。
下次当你因为某个项目“进度太慢”而感到沮丧时,不妨想想:你最依赖的东西——操作系统、数据库、语言运行时、版本控制——每一样都比任何人预期的花了更长时间。而这恰恰是它们能够可靠运行的原因。
有些事情就是需要时间。最好的应对方式不是与这个现实抗争,而是去构建能够接纳它的系统、团队和预期。


