选择无聊的技术

选择无聊的技术:工程决策中的创新 Token 理论

在技术选型的讨论中,我们常常被新技术的光环所吸引。NodeJS、MongoDB、微服务、Kubernetes......每一项新技术都承诺解决我们面临的问题。然而,经过多年的工程实践,越来越多的工程师意识到:在大多数情况下,选择"无聊"的技术才是更明智的决策。

前 Etsy 工程师 Dan McKinley 的这篇经典文章,为我们提供了一个务实的技术选型框架。这不是保守主义,而是一种深思熟虑的工程智慧。

创新 Token:有限的注意力资源

McKinley 提出了一个精妙的比喻:设想每个公司拥有大约三个"创新 token"

这是你可以用来冒险的筹码,但供应量在很长时间内是固定的。你可能在达到一定的稳定和成熟后能获得更多,但人们通常会高估自己钱包里的余额。

当你做出以下选择时,你就在消耗这些珍贵的 token:

  • 选择 NodeJS 构建网站?花掉一个 token
  • 选择 MongoDB 作为数据库?又花掉一个 token
  • 选择一个存在不到一年的服务发现技术?再花掉一个 token
  • 如果你决定自己写数据库------那你的麻烦就大了

对于 JavaScript 咨询公司或数据库公司来说,这些选择可能是合理的。但你很可能不是。你可能在为一家"重新思考全球商务"或"重新发明网络支付"的公司工作,推进着某个宏大的商业使命。

在这个背景下,把有限的注意力用在创新基础设施技术上,是一种绝佳的失败方式,或者至少会延迟你的成功。

无聊技术的真正价值

首先需要明确:"无聊"不等于"糟糕"。

世界上确实存在既无聊又糟糕的技术,你应该避免它们。但也有大量无聊且优秀(或至少足够好)的技术选择:

  • MySQL 是无聊的
  • Postgres 是无聊的
  • PHP 是无聊的
  • Python 是无聊的
  • Memcached 是无聊的
  • Squid 是无聊的
  • Cron 是无聊的

充分理解的失败模式

无聊技术的美妙之处在于:它们的能力被充分理解,更重要的是,它们的失败模式也被充分理解

在选择技术时,你面对两类不确定性:

已知的未知(Known Unknowns)

"我们不知道这个数据库达到 100% CPU 时会发生什么。"

未知的未知(Unknown Unknowns)

"天哪,我们完全没想到写入统计数据会导致 GC 暂停。"

即便是存在了几十年的技术,这两个集合通常都不是空的。但对于新兴技术,未知的未知的规模要大得多------这至关重要。

当凌晨三点系统宕机时,你会深刻理解这一点的价值。对于成熟技术,你可以在 Stack Overflow 上找到答案,可以咨询有相同经验的同行,甚至可以找到详细记录失败案例的博客文章。而对于新技术,你可能是第一个遇到这个问题的人。

追求全局最优而非局部最优

向公司添加技术是有成本的。这个道理作为抽象陈述显而易见:如果我们已经在用 Ruby,再添加 Python 似乎不太合理,因为增加的复杂性会超过 Python 带来的边际效用。

但奇怪的是,当我们讨论 Scala vs Python 或 Redis vs MySQL 时,人们往往失去理智,抛弃所有约束,开始狂热地谈论"为任务选择最佳工具"(Best Tool for the Job)。

重新定义"最佳工具"

你的工作本质上是将业务问题映射到软件解决方案的空间中。如果软件选择真的没有任何包袱,你确实可以为各种问题挑选一堆局部最优的工具。

但在现实世界------那个运维是核心关切的世界------你需要进行全局优化

"最佳工具"思维的问题在于,它对"最佳"和"任务"的理解过于狭隘:

  • 你的真正任务不是"实现一个缓存层",而是"保持公司正常运转"
  • 真正的"最佳"工具不是在某个单一维度上得分最高的,而是在尽可能多的问题上占据"最不差"位置的工具

保持系统可靠运行的长期成本,几乎总是远远超过你在构建时遇到的任何不便。成熟而富有成效的开发者理解这一点。

运维负担的复合效应

考虑以下场景:

  • 你的团队使用 5 种不同的编程语言
  • 3 种不同的数据库系统
  • 4 种不同的消息队列
  • 每种技术都有自己的监控工具、日志格式、部署流程

当系统出现问题时,工程师需要在这些技术栈之间跳转。新员工的学习曲线变得陡峭。招聘变得困难,因为你需要找到精通这个独特技术组合的人。

复杂性不是线性增长的,而是组合爆炸式增长的。

何时以及如何选择新技术

把这种推理推向极端------比如只选 Java 并试图仅用它实现整个网站------显然是疯狂的。你需要某种向工具箱添加新东西的机制。

关键的第一步是承认:这是一个过程,也是一场对话。新技术最终会产生公司层面的影响,因此添加技术是一个需要全公司可见度的决策。

评估新技术的实践框架

第一步:如何用现有工具解决问题?

这是最重要的问题,能有效检测出"问题"是否只是某人想尝试新技术的借口。如果是这样,应该立即否决。

你会惊讶地发现,有限的技术选择集合能走多远。实践中,答案几乎从来不是"我们做不到",通常只是某种程度的"我们可以做到,但会比较困难"。

如果你认为现有工具无法实现目标,你可能只是思考得不够有创造力。

这不是说要强行使用不合适的工具。而是说,在引入新的复杂性之前,确保你已经充分探索了现有工具的可能性。

第二步:明确记录现有方案的困难

写下用当前技术解决问题的具体困难和成本:

  • 开发时间会增加多少?
  • 性能会差到什么程度?
  • 维护成本如何?
  • 是否存在根本性的技术限制?

这个过程有两个好处:

  1. 迫使你量化"困难",而不是停留在模糊的感觉上
  2. 为未来的决策提供了可对比的基准
第三步:设定迁移预期

新技术选择可能是纯增量式的(比如"我们还没有缓存,所以添加 Memcached")。但如果它与现有工具重叠或替代现有功能,你应该为迁移设定明确的期望。

策略通常应该是"我们承诺迁移"并附带建议的时间线。

这一步的目的是:

  • 将技术债务保持在可控水平
  • 避免局部最优解的泛滥
  • 防止系统变成"技术动物园"

决策流程不应繁琐

这个过程并不需要繁文缛节------只是几个填空题作为作业,然后开会讨论:

  1. 我们试图解决什么问题?
  2. 用现有技术解决有什么困难? (具体量化)
  3. 新技术如何解决这些困难?
  4. 引入新技术的成本是什么? (学习曲线、运维负担、招聘难度)
  5. 如果新技术与现有工具重叠,迁移计划是什么?

如果一项新技术能通过这些挑战,那么引入它是合理的。

多语言编程的陷阱

多语言编程(Polyglot Programming)常被包装成一个诱人的承诺:让开发者完全自由地选择工具,会使他们更有效地解决问题。

这种说法往好了说是天真,往坏了说是自我欺骗。

理想与现实的差距

理想情况:每个团队选择最适合他们问题域的语言和工具,各自高效地交付价值。

现实情况:

  • 跨团队协作变得困难:A 团队的 Go 服务需要调用 B 团队的 Scala 服务,双方对错误处理和超时的理解完全不同
  • 共享库和工具无法复用:每种语言都需要自己的日志库、配置管理、服务发现客户端
  • 运维团队被压垮:需要维护多套部署流程、监控系统、日志收集管道
  • 人员流动成本高昂:工程师在团队间转岗需要重新学习整套技术栈

这种方式产生的日常运维负担会把你压垮。

真正的工程自由

有意识地选择技术给了工程师真正的自由:思考更大问题的自由。

当你不需要花时间:

  • 为第五种编程语言配置 CI/CD 流程
  • 调试不同技术栈之间的互操作问题
  • 学习又一个新框架的特殊语法

你就有更多时间:

  • 理解业务需求
  • 设计更好的架构
  • 优化用户体验
  • 解决真正有价值的技术挑战

为技术而技术只是万金油,解决不了真正的业务挑战。

案例:Etsy 的技术栈演进

McKinley 在 Etsy 的经历是这个理念的最佳注脚。

Etsy 在很长一段时间内主要使用:

  • PHP 作为主要的 Web 开发语言
  • MySQL 作为主要数据库
  • Memcached 作为缓存
  • Gearman 作为任务队列

这些都是"无聊"的技术。但 Etsy 用它们支撑了一个处理数十亿美元交易的全球电商平台。

当 Etsy 确实引入新技术时(比如引入 Scala 用于搜索和推荐系统),这是经过深思熟虑的决策,针对的是现有技术栈确实难以解决的问题。

给技术领导者的建议

建立技术决策文化

  1. 使新技术引入成为可见的过程:不要让个别团队或开发者悄悄引入新技术
  2. 要求写下决策理由:强制进行上面提到的三步评估
  3. 定期审查技术栈:识别并清理没有充分使用的技术
  4. 设定迁移预期:新技术不应该只是"添加",还应该"替代"

培养工程师的判断力

年轻工程师往往被新技术吸引,这是自然的。但优秀的技术领导者应该帮助他们理解:

  • 技术选择的长期影响:今天引入的技术,可能需要维护十年
  • 全局优化的重要性:个人生产力 vs 团队生产力 vs 组织生产力
  • 失败模式的价值:知道什么时候会出问题,比永远不出问题更重要

知道何时打破规则

这个框架不是教条。有时引入新技术是正确的选择:

  • 现有技术确实存在根本性限制:比如需要实时数据处理,而批处理系统无法满足
  • 新技术已经足够成熟:虽然对你的组织是新的,但在行业中已经被广泛验证
  • 你有能力承担成本:团队有足够的资源学习和维护新技术
  • 这是你的核心竞争力:如果你是一家搜索公司,投资最前沿的搜索技术是合理的

关键是:这应该是有意识的决策,而不是因为"这个技术很酷"或"我想在简历上写这个"。

结语:成熟不是保守

选择无聊的技术不是反对创新,而是关于智慧地分配有限的注意力资源

在一个充满不确定性的世界中,减少不必要的复杂性是一种竞争优势。当你把创新 token 用在真正重要的地方------那些直接推动业务使命的创新上,而不是分散在基础设施的各个角落时,你的团队才能走得更远。

正如 McKinley 总结的:

"保持系统可靠运行的长期成本,几乎总是远远超过你在构建时遇到的任何不便。成熟而富有成效的开发者理解这一点。"

这不是保守主义,而是工程成熟度的标志。

当你的公司在凌晨三点没有宕机,当新员工能在一周内上手,当你的团队可以专注于解决业务问题而不是基础设施问题------你会感激当初选择了那些"无聊"的技术。


原文 :Dan McKinley, "Choose Boring Technology", 2015

链接mcfunley.com/choose-bori...

延伸阅读

  • "The Grug Brained Developer" - 另一篇关于简单性的经典文章
  • "Stevey's Google Platforms Rant" - 关于平台思维的思考
  • "Boring Technology Club" - 一个收集成熟技术栈的社区项目
相关推荐
大鹅同志3 小时前
Agent Runtime Evaluation Platform — AI Agent 运行时全维度质量评估平台
ai·langchain·agent·rag·langgraph·vibecoding·llm-as-judge
我才是银古19 小时前
OpenCode × DeepSeek 配置方案再进化:审查体系、深度工作流与持续精进
deepseek·vibecoding·opencode
ClouGence1 天前
为什么很多团队的自动化测试很难真正落地?
测试·vibecoding
卡卡罗特AI1 天前
卡兹克大佬网站被攻击?新手Vibe Coding上线安全指南!保姆级教程
ai编程·vibecoding
我才是银古1 天前
OpenCode × DeepSeek 配置方案继续迭代:从能用到好用
编程开发·deepseek·ai平台·vibecoding·opencode
8Qi83 天前
HelloAgents:RAG——让 Agent 学会检索知识
人工智能·llm·agent·ai编程·vibecoding
8Qi83 天前
hello-agents学习笔记--Memory让Agent拥有记忆
人工智能·python·llm·agent·ai编程·vibecoding
utmhikari4 天前
【日常随笔】深入回答纯Vibe Coding写后端项目的几个问题
后端·ai编程·vibecoding
子兮曰5 天前
Agency-Agents 深度解析:400+ AI 专家的"梦之队"如何重塑开发工作流
前端·后端·vibecoding