Software Friction

Hillel Wayne

软件摩擦

原文由 Hillel Wayne 发布,订阅该博客

在他的著作《战争论》中,克劳塞维茨将摩擦定义为军事理论与现实之间的差距:

因此,在战略中一切都很简单,但也正因如此,一切都不那么容易。战争中的一切都很简单,但最简单的事却很困难。这些困难累积起来,便产生了一种摩擦,没有亲历过战争的人是无法准确想象的。

以天气为例来说明摩擦。在这里,浓雾使敌人无法被及时发现,使炮兵无法在恰当的时机开火,使报告无法送达将军;在那里,大雨使一个营无法赶到,使另一个营无法按时到达,因为原本三小时的行程,也许不得不走上八小时;使骑兵无法有效冲锋,因为它深陷于泥泞之中。

自从读到这段话后,我发现“摩擦”在软件开发中无处不在:

  • 第三方厂商的 API 表现和你预想的不太一样,或者一开始是一样的,后来他们又改了。
  • Bug。安全告警。升级某个依赖导致出问题。
  • 有人生病了。有人孩子生病了。有人离职了。有人去参加火人节了。
  • 需求不明确,或者客户在开发过程中改变主意。客户在开发完成后改变主意。
  • 笔记本电脑坏了或被偷了。Slack 宕机一整天。
  • 工具链出故障。Word 把所有字体都变成了 Wingdings。(这事真的会发生

这份清单远非穷尽,也不可能把所有摩擦的来源都一一列出。

摩擦的一些特性

摩擦在时间跨度越长、范围越大的项目中影响越大,原因很简单:可能出问题的地方更多。

摩擦会自我叠加:两次挫折带来的影响远不止一次挫折的两倍。这是因为大多数系统至少具备一定的韧性,能够围绕某个问题进行自我调整,但这也会让下一个问题更难应对。

(这也是颇具争议的“周五不发布”这一说法背后的一个因素。部署时出错、或是需要回滚所带来的摩擦,会因为周末大家都不在线而被大大放大。争议的一方说“别这么干”,另一方则主张进行系统性的流程改进。无论如何,目标都是确保摩擦不会引发问题,争论的只是具体该怎么做。)

应对摩擦本身也可能制造新的摩擦来源,比如你为了修复安全告警而升级依赖,但新版本却存在微妙的不向后兼容的问题。而这时如果你还要和一个身处不同时区的同事一起修复它……

应对摩擦

摩擦不可避免,也不可能完全消除。我认为甚至连完全预见它都不可能。但我们可以采取一些措施来减轻它,也可以让计划对它更具韧性。我不了解军事规划者是如何减少摩擦的。以下是我在软件领域见过的一些做法:

更小的范围与更短的迭代
这正是“敏捷”优于“瀑布”的依据。时间线越短,摩擦叠加的空间就越小。你要做的事越多、时间线越长,不确定性就越高,可能出问题的地方也就越多。不过,如果你接连不断地进行大量短冲刺,摩擦依然有滋生的空间。那样的话,你只不过是在跑一场低效的马拉松。
更高的自主权
摩擦是模型与现实之间的差距,而在高层你只能看到模型。如果人们拥有足够的自主权去做出局部明智的决策,就能更容易地从摩擦中恢复。但如果自主权过大以至于各自为政,反而会让情况变得更糟。我就曾见过一位拥有高度自主权的工程师把一个“太慢”的数据库给删了。
冗余
这可以是库存中的备用设备、更高的巴士因子,也可以在排期中留出缓冲。这样一来,如果出了问题,你就能更快地修复,为下一个问题叠加留下更小的空间。但这会以正常情况下的效率为代价,这也是项目会自然地向减少冗余的方向漂移的原因。
更完善的规划
好的规划无法识别所有摩擦的来源,但能识别出更多的来源,这本身就是巨大的收益。例如,编写形式化规约可以暴露设计中的问题,或将未知的未知变为已知的未知(之后你就可以对其进行更深入的研究)。这可能就是被 5 件事打个措手不及和被 15 件事打个措手不及之间的区别。这也是我如此看好形式化方法的原因。
自动化
这是一把双刃剑。一方面,流程自动化减少了人为出错的空间。另一方面,自动化流程本身也可能有 bug,从而制造新的摩擦来源。而且,如果自动化运行得足够久,人们会忘记它是如何工作的、或是它所覆盖的完整范围,导致一旦它出故障,所有人都毫无准备。自动化可能会以经验为代价。
经验
你遇到的问题越多,就越能预见问题的到来,也就越有经验去从问题中恢复。不幸的是,这大多只能靠吃亏来学。但有一个捷径是……
推演

关于这一点,一本有意思的书是美国海军战争学院的《战争推演基础》。书中认为,兵棋推演有两个目的:收集关于局势如何发展的情报,以及在安全的环境中让指挥官获得(一定的)经验。如果学员在推演中就学到“天气会打乱你的计划”,就不需要用真实的人命去学。同样,我宁愿在不需要拼命恢复误删数据表的时候,就练习如何取回数据库备份。据我所知,安全团队和运维团队正是出于这个原因而使用推演。

(与此同时,人们必须投入时间来组织和参与推演,这和增加冗余一样,是一种低效。)

检查清单与运行手册

将应对特定问题的隐性知识形式化的方法。

关于摩擦,我的一些疑问

将摩擦的来源细分是否有用?把工具链问题称为“技术”摩擦而非“社会”摩擦,对我们真的有帮助吗?

其他领域是如何应对摩擦的?我问过一些建筑行业的人关于摩擦的问题,他们认同这个概念,但没有专门的词来形容它。那活动策划、护士、军官们呢?

我们如何在“做 X 能减轻摩擦的影响”和“不做 X 眼下更高效”之间找到恰当的平衡?

摩擦对个人重要吗?即使团队中没有其他人考虑摩擦,我在项目中思考它是否依然能让我受益?

感谢Jimmy Koppel 提供的反馈。如果你喜欢这篇文章,欢迎订阅我的 Newsletter!我每周都会在上面发布新的文章。

我为企业提供形式化方法培训,帮助软件开发变得更快、更便宜、更安全。在这里了解更多。


更新 2024-05-30

我把收到的关于本文的一些评论收集在了这里

本文章由 muse-spark-1.2-contributor 进行翻译

评论