文/一个刚从十年老项目的泥潭里爬出来的人
这周我接手了一个任务,要把一个十年前写的服务从旧架构迁移到新架构上。打开代码仓库的时候,我整个人都不好了——那些依赖包,大部分已经没人维护了,有些连官网都打不开了。当初用的那套框架,早就被社区抛弃了。代码里充斥着被标记为@Deprecated的接口,我在IDE里打开一个文件,满屏都是删除线。
我说服自己,硬着头皮把项目跑起来。你知道我怎么做的吗?先装了一个十年前版本的JDK,然后在一个旧版本的Linux容器里,用一套已经被安全社区通报过漏洞的依赖,把整个服务跑了起来。看着那一堆红色的警告和过时的日志框架输出,我自己都觉得荒谬。
这堆代码活过了十年,但它老得已经不像一个现代软件了。它像一个还住在老房子里的老人,邻居都搬走了,街道也改造了,就它还在那里。
然后我想起这个项目最初的代码里,有一个Hello World测试文件。我翻出来,那是一个独立的、三行的、不依赖任何外部库的程序。我把它复制到新环境里,用新版JDK编译它——居然一次过了,输出还是那行”Hello, World!”。
没有警告,没有过时的接口,没有被通报的漏洞。它干干净净地跑在一个十年后的环境里,就像什么都没发生一样。
我突然意识到一件事——在这个”代码烂掉”是常态的世界里,Hello World大概是唯一不会变老的程序。
所有代码都在”变质”,除了这句问候
软件行业有一个很残酷的事实:你写的代码,保质期比牛奶长不了多少。
你今年写的一个微服务,用了一套火热的技术栈,明年可能就有一半的组件出了新版本。后年那个框架可能已经进入了维护模式。大后年,当初帮你写代码的同事可能已经离职了,换了新的人来接手。再过几年,你回头看自己的代码,可能会觉得”这谁写的?写得真烂”——然后发现是你自己写的。
代码变老的速度比我们想象的快得多。依赖在变,语言在变,架构在变,技术在变,团队也在变。你昨天觉得完美的东西,今天可能已经是”技术债务”。整个行业都在持续向前,没有停下来等任何人。
但Hello World不变。
它不需要依赖包,不需要特定的框架版本,不需要维护者,不需要重构。你用C语言写的Hello World,五十年前能跑,今天也能跑(只要你有C编译器)。你用Python写的Hello World,二十年前能跑,今天也能跑。同样的字符,同样的输出,同样的行为。没有任何版本兼容问题,没有任何外部依赖,没有任何更新需求。
在软件世界”万物皆在腐烂”的大背景下,Hello World是一片”永恒”的飞地。它不跟着时间变老,它一直停在原点,保持着最初的样子。
那个”存量代码”的尴尬时刻
我去年在技术分享会上,听到一个很有感触的发言。演讲者说:”我们维护的代码库里,超过三年没动过的文件,占了一半以上。那些文件里有很多当初的’最佳实践’,今天看起来已经是’历史遗迹’了。但没人敢删,因为没人确定删了会不会出事。”
这就是存量代码的尴尬——它还在运行,但已经没人敢动了。因为一动就可能出问题,一改就可能引入新bug。最好的状态就是”保持原样”。
但Hello World没有这个尴尬。因为它从来不在”业务逻辑”里,不参与任何功能,不依赖任何外部状态。它是一个完全独立的、自包含的、可以被安全地修改和运行的最小单元。
如果你哪天需要验证一个新环境是否支持某门语言,你写一个Hello World,用那门语言的编译器/解释器去跑。你不需要考虑”这个版本支持吗?”——支持就是支持,不支持就是不支持。没有中间的”部分支持但会报某些警告”。
它简单到”支持或反对”的边界极其清晰。在这个充满了模糊地带的技术世界里,这种清晰感是稀缺的。
那个”永恒正确”的代码,成了程序的”基准面”
我后来做了一个小实验:我把那个十年前的Hello World测试文件,提交到了新架构的代码仓库里,放在一个叫reference的目录下。然后在README里写了一句话:”如果这个程序的输出跟预期不一致,说明底层环境出了基本问题,请先修复环境。”
后来新团队有人加入,第一件事就是按README说的,跑那个Hello World。看到那行字出来,才开始配置其他东西。那个文件成了所有人”确认环境正常”的起点——不管用什么语言、什么框架、什么工具,那个Hello World永远是”基线”。它不需要任何上下文,不依赖任何配置,永远只有一个判断标准:能出字就是好的。
我有时候觉得,这个文件像建筑工地上那个”基准点”——一个被固定在地面上、永远不会移动的标记。所有的测量、所有的施工、所有的标高,都以它为参照。在软件工程里,这个”基准点”往往就是那个最简单的、最不依赖任何东西的、最不可能出错的小程序。
它在整个代码库里的”地位”很低,但它的”作用”很高。因为它给你一个”绝对坐标”——你的环境到底是不是好的,你的工具链到底能不能工作,你的基本通路到底通不通。这个问题,只有Hello World能回答。
在技术不断”代谢”的世界里,一句不变的问候为何让人安心
我们这行,变是常态。语言版本每年一升,框架三个月一更新,概念每两年翻新一次。你刚学会一个东西,可能它已经在”过时”的路上了。保持”跟得上”是一件很累的事情。
在这种环境下,有一个”永远不变”的东西在你身边,就像是这个世界里的一根固定桩。它在你的代码库角落里,用同样的字、同样的格式,对你说同样的话。哪怕外面已经换了好几轮语言、框架、架构,它还是它。
这大概为什么很多人即使不再需要用Hello World来学习,也会时不时写一写它。不是为了测试环境,不是为了学习新语言,就是单纯想看一眼那个”没变过”的东西,确认”还有一个东西是稳定的”。
在一个充满变化的领域里,”稳定”本身就是一种情绪价值。
那个文件,永远不会被”优化”掉
后来公司做了一次代码清理,把大量的旧代码、测试文件、临时示例都删掉了,为的是”精简仓库””减少维护负担”。有人问我要不要删那个Hello World文件,我说不删。
“留着干嘛?又不能上线,不能帮用户解决问题。”
我沉默了一会儿,说:”留着让别人知道,不管这个项目变得多大、多老、多复杂,它最底下一直有一行能跑通的、不依赖任何东西的、永远不会报错的代码。那个代码在提醒我们——代码的世界再乱,也有一个东西是干净的。”
对方看了我一眼,没再说什么。那个文件留了下来。
现在我有时候打开那个仓库,看到那个叫HelloWorld.java的文件静静地躺在根目录里,旁边是几百个被更新过无数次的其他文件。其他文件都有修改日期、有提交记录、有版本号,只有它,从提交到今天,一行都没被改过。
它不需要被改。因为它在第一天就已经是完整的了。
在一个所有东西都需要”持续迭代”的行业里,一个不需要迭代的东西,反而成了最特别的存在。它像一个倔强的老人,蹲在路口,不管周围怎么拆、怎么建、怎么翻新,他一直在那里,用同样沙哑的嗓音,对每一个路过的人说:
“你还是可以停一下,写一行最简单的,看看它出来。没有依赖,没有配置,没有版本兼容的问题。就是一行,出来就是出来了。”
“在这个复杂得让人头疼的世界里,这份简单,从来没变过。”