反脆弱编程与为何AI不会取代你的工作
每当我表示不喜欢调试,并围绕避免调试来组织我的编程习惯时,总会遇到反对意见:“你肯定没用过好的调试器。”
总结我的观点是:我希望我的软件具有反脆弱性(这个概念要归功于纳西姆·塔勒布)。我在一个代码库上工作的时间越长,修复错误就应该变得越容易。
对一段代码的每次添加都可以看作是一次压力。如果什么都不做,代码会稍微变差,更难维护,更容易出现错误。值得庆幸的是,你可以避免这种结果。
这并不自然。对于大多数缺乏深厚专业知识的开发者来说,随着代码库的增长,错误会变得更难修复:你需要透过层层代码追踪症状,追查在调试器中消失的海森堡错误,或者修复一个错误却引发了另一个错误。代码越多,情况就越糟。这样的代码是脆弱的。添加一个新功能可能会破坏旧的、看似无关的部分。
在我看来,无法产出反脆弱代码解释了编程领域中极端的幂律分布:我们日常依赖的大部分代码都是由一小部分掌握了反脆弱性技巧的程序员编写的。
如何扭转这种情况?如何确保你在代码上工作的时间越长,错误就越浅显?
有一些众所周知的技术,添加大量测试和检查肯定有帮助。你可以在没有测试或调试时检查的情况下编写反脆弱代码……但你需要功能上等效的东西。
影响深远的处方(“你必须使用语言X、工具Y、方法Z”)通常是货船崇拜式的无稽之谈。复制莱纳斯·托瓦兹的工具或咒骂风格并不能保证成功。但反脆弱性不是处方,它是一个期望的结果。
防御性编程本身并无争议——然而在20世纪80年代它并不常见,今天对许多人来说仍然不是默认做法。
当然,完全的防御性方法并非总是适用或值得付出成本。
例如,如果我在快速开发一个包含过多JavaScript(多到我懒得读)的Web应用,我直接就在浏览器的调试器里运行它。它运行得很好。我不用这段代码来控制心脏起搏器,也不指望在圣诞节午夜被叫醒去修复它。
如果你的程序只有500行,并且每年只运行20次,那么追求反脆弱性就不值得。
大型语言模型可以生成防御性代码,但如果你自己从未编写过防御性代码,并且主要借助AI辅助学习编程,那么你的软件很可能仍然是脆弱的。
你可以快速添加代码,但你添加得越多,问题就越大。
这就是问题的关键。编写代码从来都不是困难的部分——我12岁时就会写代码,如今无数12岁的孩子也能编写简单的游戏和应用。同样,一个12岁的孩子可以用锤子、钉子和木头搭一个狗屋。达到80%的水平一直是很容易的。
扩展复杂度而避免一切崩溃——那才是困难的部分。