← 返回信息流
AI 资讯Hacker News·3 天前

为不理解代码库辩护

原标题:In defense of not understanding your codebase

速览

文章为程序员无法完全理解代码库的观点进行辩护,认为在复杂系统中理解全部细节并非必要,反而可能浪费时间。作者指出,理解架构和关键部分比理解所有代码更重要。这一观点挑战了传统编程教育中‘必须理解一切’的理念。

AI 深度解读

背景

在软件工程领域,关于工程师需要多大程度理解自己的代码库,一直存在两种截然不同的文化。一种来自小规模、低人员流动率的团队(如 Redis 或《The Witness》这类游戏),他们认为“你必须完全理解代码库,否则无法做好工作”。另一种来自大规模、高人员流动率的团队(如 Google 搜索后端或 GitHub),他们认为“你显然不可能完全理解,只能在局部尽力而为”。Peter Naur 在 1985 年发表的经典论文《Programming as Theory Building》是前一种观点的有力代表,但本文作者认为,在大型系统中,部分理解不仅是可接受的,而且是唯一可行的方式。

核心内容

对“编程作为理论构建”的批判

Naur 的核心观点是:程序员工作时,代码只是副产品,真正的主产品是他们对程序的“理论”——即对程序运行方式及原因的直觉理解,这种理解只能被代码和文档部分捕捉。如果团队失去代码,可以轻松重写;但如果失去理解(例如团队全员离职),则很难弄懂代码。Naur 进一步主张,不应从代码中重建理论,而是应该彻底抛弃现有程序,让新团队从头重写,在这个过程中构建新的理论。他写道:“仅从文档中重建程序的理论是严格不可能的……因此,应该丢弃现有程序文本,让新组成的程序员团队有机会重新解决原始问题。”

作者认为,任何在大型公司有效工作的软件工程师都知道 Naur 在这点上完全错误。原因有二:

  1. 无法从头重写大型软件系统。足够大的系统(如果拥有用户)包含数千个奇怪的特例和怪癖,无法重新实现。即使熟悉该系统的团队也无法做到:要处理的东西太多。成功的重写总是从将现有代码库切分成小的孤立块开始,然后一次重写一个块。换言之,重写软件系统涉及对旧系统进行一系列修改。如果不能修改旧系统,当然也不能用新系统替换它。

  2. 被遗弃的系统经常被重新激活。在拥有数亿行代码和数千名工程师的科技公司中,代码库中没有任何人熟悉它的情况并不少见。只需要几个人在错误的时间离职,或者代码库一年无人维护。作者不仅见过其他团队这样做,自己也亲自接手过被遗弃的代码库,弄懂它,并最终能够有效地工作。这需要时间,但构建新的理论是可能的:从理解一个端到端流程开始,然后慢慢向外扩展,在过程中谨慎修改。

在足够大的代码库中,每个人都带着不正确的程序理论在工作。现代软件系统的定义性特征是它们太大,任何人都无法(甚至整个团队也无法)完全记住:没有人能理解全部。为了有效工作,你必须找到一种只使用部分正确理论的方法。这就是为什么作者反复强调“采取立场和信心”。如果对某事不确定,你不能坐等一个完全理解的人来给你答案。如果你是一个有能力的工程师,那个人就是你自己。你必须咬紧牙关,做出最合理的猜测,然后处理后果。

对 Naur 公平地说,1985 年程序的平均规模可能比今天小几个数量级。Naur 提到的“大型程序”第一个例子是一个 20 万行的工业监控程序,第二个例子是一个编译器。1987 年 GCC 第一个版本大约 10 万行代码;2015 年 GCC 超过 1400 万行。重写一二十万行代码相对简单(尤其是如果可以利用现有测试),但一两百万行就不一样了。

理论构建只是众多权衡之一

LLM 常被批评为一种工具,因为它阻碍了正常的理论构建过程。作者认为这过于简单化。像许多软件工具一样,LLM 是一把双刃剑:它们使构建详细的思维模型变得更困难,但允许你快速构建部分理论,并帮助你更有效地利用这个部分理论。这是一个复杂的权衡,作者仍在思考中。

抛开 LLM 不谈,作者确信:认为任何干扰你对软件理论理解的东西都一定是坏的,这种想法是愚蠢的。以下是一些同样会妨碍理论维护的事物:

  • 允许其他人编写你的代码库中的代码
  • 必须实现法律要求的特性(如可访问性和数据保护)
  • 允许同事离职或在团队间调动
  • 为了安全补丁升级软件版本
  • 引入库或其他依赖

像软件中的大多数事物一样,“维护代码库的理论”只是众多价值之一。有时它是最重要的价值,你为此牺牲其他价值;其他时候,你为了速度、法律合规或政治原因而牺牲它。

几乎所有工程师——尤其是“纯粹”的工程师——都更愿意维护一个准确的软件心智模型。这更有趣、压力更小,感觉更像“真正的工程”。这就是为什么许多工程师在业余时间参与开源项目,以便在小型代码库上独自工作,从而能够维护一个准确的 Naur 式理论。作者认为这没什么问题。

然而,在工作中你被付钱来做一份工作。换句话说,他们付钱给你去采用他们的工程价值观。你应该明白,无论你个人多么在意性能,有时你必须在工作中编写慢速代码(例如,为了按时完成项目,或适应某些尴尬的需求)。维护代码库的理论也是同样的事情。

关键要点

  • 完全理解代码库是一种理想,但在大型系统中不可行。 现代软件系统规模巨大,无人能完全掌握,工程师必须接受并利用部分理解。
  • Naur 的“重写理论”观点过时且错误。 大型系统无法从头重写,成功的重写依赖于对现有系统进行增量修改;被遗弃的代码库可以被重新唤醒并逐步理解。
  • 部分理解是有效工作的基础。 工程师需要采取立场、做出合理猜测,并承担后果,而不是等待完美理解。
  • 理论构建只是众多软件工程价值之一,应与其他价值(速度、合规、协作等)进行权衡。 许多常见做法(如团队协作、依赖升级、法律要求)都会干扰理论维护,但却是必要的。
  • LLM 等工具对理论构建的影响是双重的。 它们可能阻碍深度理解,但也能加速部分理论的形成并提升利用效率,需要具体评估利弊。
  • “纯粹”工程师偏好维护准确心智模型,但工作中必须适应公司需求。 业余时间可以追求完全理解,但工作中要接受工程价值观的权衡。

意义与影响

这篇文章对软件工程社区有重要的现实意义。它挑战了长期存在的“完全理解理想”,为大型系统下的工程师提供了心理和实践上的正当性。在互联网公司中,代码库规模动辄千万行,人员流动频繁,强调“必须理解一切”不仅不现实,反而可能导致工程师的挫败感或过度设计。文章指出,接受部分理解、学会在不确定性中工作,是高级工程师的关键能力。

此外,文章对 LLM 的讨论切中了当前 AI 辅助编程的热点。它提醒我们,不应简单地将 LLM 视为“坏工具”,而应看到它在降低入门门槛、加速原型开发的同时,也可能影响深度理解。这种权衡视角有助于更理性地评估 AI 在软件开发中的角色。

最后,文章通过对比两种工程文化,揭示了行业许多争论的根源——即“纯粹”的完全理解文化(常见于开源小项目或学术讨论)与“实用”的部分理解文化(常见于大型商业公司)之间的冲突。理解这一点,有助于减少不必要的争论,促进更务实的工程实践。

查看原文 →seangoedecke.com