选择无聊的技术(2015)
文章摘要
Dan McKinley 写于 2015 年 3 月的这篇文章,十一年后再次登上 HN 首页并拿到 426 分。作者说这是他从 Etsy 时期的上司 Kellan 那里学到的技术决策哲学的提炼。
拥抱无聊。 文章最著名的概念是”创新代币”(innovation tokens):假设每家公司大约有三枚创新代币,你可以随便花,但在很长一段时间里供给是固定的;达到一定的稳定度和成熟度后也许能再拿到几枚,但人们普遍高估自己钱包里的存货。选择用 NodeJS 写网站,花掉一枚;选择 MongoDB,花掉一枚;选择存在不到一年的服务发现技术,花掉一枚;选择自己写数据库——那你麻烦大了。这些选择对一家 JavaScript 咨询公司或数据库公司都可能是合理的,但你大概率不是。你多半在一家至少号称要重新思考全球商业或重新发明网络支付的公司,在那个语境下,把有限的注意力花在创新 ssh 上是失败的绝佳途径,最好的情况下也只是推迟成功。
什么算无聊? 作者强调”无聊”不等于”糟糕”——世上确实存在既无聊又糟糕的技术(他打趣说我们通常随口称之为”企业软件”,虽然这个用词可能不够精确),那些不要用。但也有大量既无聊又好用、或至少够用的选择:MySQL、Postgres、PHP、Python、Memcached、Squid、cron 都是无聊的。无聊的好处在于这些东西的能力被充分理解,但更重要的是它们的失效模式被充分理解。他借用拉姆斯菲尔德那句关于”已知的未知”和”未知的未知”的名言(同时加了一句”说清楚,去他的这家伙”):已知的未知是”我们不知道这个数据库跑到 100% CPU 会怎样”,未知的未知则是”我们压根没想到写统计数据会导致 GC 停顿”。两个集合通常都非空,即便对存在了几十年的技术也是如此,但对于闪亮的新技术,未知的未知的量级要大得多。
全局优化。 技术选择不是孤立发生的,它的作用域触及你的整个团队、组织,以及由你所有选择的总和涌现出来的系统。给公司增加技术是有成本的。作为抽象陈述这很显然:如果我们已经在用 Ruby,再加 Python 就不合理,因为由此产生的复杂度会超过 Python 的边际效用。但不知为何,当话题变成 Python 和 Scala、或 MySQL 和 Redis 时,人们就失去理智、抛弃一切约束,开始高谈”用最适合这份工作的工具”。作者的反驳很直接:“最适合工作的工具”这种思维对”最好”和”工作”两个词的理解都太短视了。你的工作是让公司活下去,见鬼。而”最好”的工具,是对尽可能多的问题占据”最不糟糕”位置的那一个。 他把这些额外负担称为”运维”,以及次一级的”认知开销”——你得监控它,得琢磨单元测试怎么写,得懂点皮毛才能改它,得写 init 脚本,这些加起来非常快。文章给出的判断是:长期保持系统可靠运行的成本,基本总是远远超过你在构建过程中遇到的任何不便;成熟且高产的开发者明白这一点。
有时也要选新技术。 把这个推理推到荒谬的极致就是只用 Java 且不用别的任何东西来实现网站,那当然很疯狂。所以你需要一套往工具箱里加东西的机制。第一步是承认这是一个过程和一场对话——新技术最终会产生全公司范围的影响,所以引入技术是需要全公司可见度的决策。他推荐的最有价值的练习是:先考虑如何在不引入任何新东西的前提下解决当下的问题。 这个提问首先能检测出”问题其实是某人特别想用某个技术”的情况——如果是这样,应当立即中止。实践中这个问题的答案几乎从来不是”我们做不到”,而通常落在”我们能做,但会太难”这个光谱的某处。如果你觉得用现有的东西达不成目标,你多半只是想得不够有创意。接着要把”当前技术栈中究竟是什么让解决这个问题贵得离谱”写下来。如果新技术与现有技术重叠或替代,就要对迁移设定清晰预期,政策通常应该是”我们承诺迁移”并附一个时间表,目的是把残骸控制在可管理的水平,避免局部最优解泛滥。作者认为这套流程并不吓人也不麻烦——几个当作作业填的问题,加上一次讨论会而已。
只管发货。 多语言编程(polyglot programming)的推销话术是:让开发者完全自由地选择自己的工具会让他们更有效地解决问题。作者认为这往好了说是对问题的天真定义,往坏了说是动机性推理——它制造的日常运维苦役的重量会把你压死。审慎的技术选择才给工程师头脑真正的自由:思考更大问题的自由。为技术而技术是蛇油。
文末的脚注里有 Etsy 的真实案例。Etsy 早年在这方面吃过大亏:招了一堆 Python 程序员,然后决定得给他们找点 Python 的活干,唯一想到的就是造一个毫无意义的中间层,后来花了好几年才切掉;与此同时搜索的 90 分位延迟大约是两分钟。Etsy 没有失败,但有好几年什么都没发出去。另一个正面案例是 Etsy 的动态信息流(activity feeds):当时团队正在努力把大部分 Etsy 收拢到 PHP、MySQL、Memcached 和 Gearman 上,用这套栈实现这个功能比用 Redis 之类复杂得多,但确实可行。结果是——他们的注意力转向别处好几年,在这期间动态信息流规模涨了 20 倍而没人盯着它,他们没有为动态信息流做过任何针对性改动,一切都平稳运行,因为用的是共享平台。作者说这就是技术选择上的克制所带来的长期收益的缩影。(他也声明这不是绝对主义立场:把动态信息流放 memcached 被判定为可行,但用原生 PHP 实现带分面的全文搜索就不可行,所以 Etsy 用了 Solr。)
HN 评论精华
-
tosh 用两个字给全帖定了调:”经受住了时间考验(aged well)。”
-
NickNaraghi 说这是他最喜欢的博客文章之一,而全文基本可以浓缩为”创新代币”这一个概念:这是他作为 PM 和工程负责人职业生涯中最有用的概念之一,不仅帮助做出正确的取舍,更帮助向各个层级的同事解释这些取舍。
-
tshaddox 提出了最有分量的修正:他喜欢这个概念,但认为把它框定为少数几枚离散代币不太对,更适合用债务和风险来看待——用”不无聊”的技术只是从余额里扣掉一些,你不希望余额太负,但背一点债有时没问题,而且有些冒险的赌注可能有巨大回报。额度显然不是离散的:把整个应用押在一个新语言运行时上可能非常冒险(潜在回报也可能巨大),但换一家邮件服务商可能就不冒险。他更大的抱怨是“无聊”这个判定本身的模糊性:”一项新技术是如何从『不无聊』过渡到『无聊』的?显然这需要很多人长期无视这篇文章的建议,直到我们集体认定那些人的结果足够好,才把那项技术算作『无聊』。”
-
sgarland(自称 DBRE)用原文自己的话回答了这个质疑:无聊技术就是那些”我没想到这也可能发生”事件发生极少的技术。但他随即指出所有数据库都打破这条规则——每一个都有多到离谱的地雷,只是相对其他选项它们已经是你能得到的最好的了。他为数据库辩护的一点是:他遇到的几乎每个地雷都是有文档的,只是文档极其密集、有时含糊。他还举了 Tailscale 发现的 SQLite WAL-Reset bug 作为”总有一些未知的未知”的完美例证。
-
帖子里最长的支线是“NodeJS 在 2026 年还算不算无聊技术”。monk_grilla 起头问,多数人(williamcotton、gherkinnn、wmf、Cthulhu_、swiftcoder)认为 Node 本身已经足够无聊、能力和失效模式都被充分理解,现在花代币的应该是 Bun 或 Deno。但 sgarland 反击说”把 JavaScript 生态里的任何东西称为『成熟』都有点勉强,这可是给我们带来 left-pad 的社区”,由此引出了一场”能不能说出一个稳定了十年的 JS 生态项目”的点名——gherkinnn 和 whstl 报出了 Express、Lodash、jQuery、require、语言本身、Vue 十年前的 API、React 类组件(Hooks 也快七八年了)。chrysoprace 给出了最精确的切分:Node 本身是无聊的,但一旦你选择 npm 这个仓库,它就不无聊了——你层叠在 Node 之上的东西才是不无聊的部分,尤其考虑到每月都有的供应链攻击。igsomething 提出了一个好的判定指标:”一个语言/框架算不算无聊,看的是把一个荒废了 9 到 12 个月的项目更新起来有多痛苦。”
-
atoav 给出了一套很实用的自查清单:这是过去十年间简单、扎实、耐操的做法吗?你和你的团队有没有用它认真做过东西并维护多年?如果产品几年无人维护会不会出大问题?造它的人离开后接手要多久?如果开发者的笔记本被卡车压了,重建构建环境是克隆一下就行,还是需要献祭和念咒?”无聊的东西就是在这些问题上轻松拿分的那个。”
-
whstl 提供了一个反直觉的现实案例,直接印证了”无聊是相对的”:他在一家老牌大公司的臭鼬工厂部门工作,最近决定未来不再用 Python——虽然 Python 是公司的官方语言。对他们团队来说 Node.js、Go、Rust、C# 都极其无聊,稳定且能在几分钟内搞定事情;而在 Python 里”像拔牙一样”,其他团队不断的 API 变更和重构让他们疲于奔命。”Python 开发者自然不同意,他们说『如果你们没法像我们一样高效地用 Python,那一定是你们团队有问题』。”
-
andai 点出了这套哲学最大的现实阻力,也是本帖最被认同的社会学观察:选择无聊技术不利于攒简历。 管理者和员工因为”热门的东西”而被奖励,而热门程度基本是新颖度的函数,所以(社会的、进而经济的)激励结构与”选择无聊技术”是负相关的。abirch 补了一个类比:”这就像人们经常因为扑灭火灾而不是预防火灾而被奖励。”andai 作为独立开发者接着说:他需要在基础设施和安全上投入大量工作,得到的回报只有”东西没炸(但愿如此)”——工作是隐形的、无法炫耀的,所以有点不值当且令人泄气。Cthulhu_ 把这条线推到了最坏的结局:”而最糟糕的部分是,因为它是隐形的,高层管理者会想『啊,我们不再需要这些人了,换成初级工程师、外包公司和/或 AI 吧』。”他还分享了自己的亲历:能源危机期间同行的服务器熔了,他所在公司的开发者做了巨大努力重写老服务;今年新一轮能源危机时服务器扛住了,公司靠着竞争对手宕机赚了很多钱——但没有英雄,没有表扬,一切被当成理所当然。
-
Cthulhu_ 还给出了一个刺眼的长期案例:十年前有人推动了热门新技术然后在东西”做完”前后跳槽或升职走人,十年后那家公司仍在苦苦维护他们的 Scala 应用,而市场上几乎没有 Scala 开发者(有的也因为是专门技能而收费更高),当初的主要作者则去了 Scala 背后的公司工作。
-
theptip 提出了在 agent 时代重读这篇文章的最佳角度:“把你所有的创新代币都押到 agent 上”大概是个好选择,这意味着你的 agent 所使用的技术都应该是无聊技术。换个说法就是”用分布内(in-distribution)的技术”——如果 agent 在 Rust 上明显强于 Zig,你大概应该用 Rust,即便 Zig”更好”,因为 Zig 好出来的那部分会被 agent 好出来的那部分淹没。
-
这条线引出了本帖后半段最热烈的讨论。epolanski 说他从 AI 那里学到的一件事是:做网站的话,即便你不太喜欢这些语言,选 PHP/Ruby/Elixir 也会好得多——流水线和部署比常见的 TypeScript monorepo 简单快速得多。被指责”为 AI 重塑社会”后他澄清了逻辑:PHP 相对 TypeScript monorepo 的运维简洁性优势在 AI 之前就存在——无聊、快、易部署、水平扩展直接、HTML 渲染出色、Laravel 开箱即用;问题一直是你得忍受 PHP 这门语言本身,”但如果 AI 写了大部分代码呢?PHP 突然就成了很多场景下的绝佳候选”。infamia 补充 Django 也是同类选择,因为大量 SWE Bench 和 Python 基准测试与 Django 相关,模型厂商极其在意这些分数,”而且 Django 文档极好,在提示里战略性地把 LLM 指向文档常有奇效”。ipsod 的一句话很传神:”Django 是我唯一 vibe-coded 出一个应用、然后回头看代码不感到惊恐的东西。”
-
michaelchisari 从另一个角度选择:”Go 在 2012 年的代码和 2026 年的代码看起来几乎一模一样,约定被遵守,
go fmt是唯一的格式化工具,『用标准库』是流行信条,代码在设计上就是可读的。如果要生成代码,我现在不会用 Go 之外的任何东西。” -
dwedge 贡献了本帖最令人怅然的一条观察:四五年前如果两个方案中有一个是 Rust 写的,那几乎可以肯定这个程序快速、可靠、作者能干;”现在它成了这个项目多半是 vibe coded 的确凿信号。不是说它不能仍然很好,我只是第一印象变了。”Animats 的回复只有一声叹息。
-
martythemaniak 指出了这套方法论的实践难点:什么技术变得无聊了,其变化速度快过人们观点更新的速度。 Kubernetes 已经很无聊了,但翻翻旧讨论帖(甚至是最近一两年的),k8s 仍被当成不该花代币的新奇玩意。asa400 则激烈反对:”在任何世界里我都不会认为 k8s 是无聊的。”他认为 k8s 之所以流行,是因为大量开发者看着 Heroku 这类平台,无法忍受自己的天才系统设计被塞进预设形状里——”某种程度上这是自尊心作祟”;此外大量工程师在硬件成本与薪酬/复杂度/组织成本之间做权衡时非常糟糕:”『Heroku 每月要花 2000 美元,自己跑 k8s 只要 400 美元。』好,但你团队的总薪酬是每年百万美元量级。”
-
insanitybit 提出了本帖最系统的反对意见:他不喜欢”创新代币”这个随意的隐喻,觉得整个概念模糊了界限、显得不够严肃。工程师应当理解需求、风险、取舍和潜在收益——新技术可能恰恰适合这些,”新”和”新颖”只是弱代理指标。”我可能觉得『新』意味着未经检验,但真是这样吗?如果一个新项目有 Jepsen 测试、模糊测试套件、大规模的 oracle 测试呢?那我应该直接说『选择经过充分测试的』而不是『选择老的』——很多老软件的测试非常糟糕。”同理,”老”也未必意味着更好的文档,很多老项目积累了多年离谱的历史包袱和无文档的边缘情况。
-
eudamoniac 把这个原则推广到个人项目上,给出了一条简洁的规则:”你可以做一个陌生的东西,或者用陌生的技术栈来做,但你不应该两者兼有。”
-
conrs 的一句感慨颇有代表性:”喜欢这篇文章。出乎意料地有争议,它没帮我交到多少工程师朋友。”
(原文抓取成功。)