从家里回北京的火车上,车窗外是一片点缀着零星灯光的夜色。穿过这长长的黑夜,明天便要工作了。
想到明天大概又要打开 Codex,忽然想起过去自己写代码时的种种感受。趁着还记得,索性写下来吧。怕再用 AI 编码一阵子,连那些曾经熟悉的快乐也渐渐忘记了。
我该怎么向新入行的同学形容古法编程时代的快乐呢?
那种线上出现告警后,盯着指标、翻阅日志、追踪调用链,将问题的无数种可能性逐一排除,直到混乱的现象逐渐坍缩成一条清晰的因果链时,豁然开朗的快乐。而现在,只需要给 Codex 接入 WebSSH,它自己就能把问题查出来。
那种随着项目复杂度不断上升,既有的设计逐渐失效,系统中的概念与逻辑如同无序运动的分子,彼此纠缠、碰撞;而后通过重新命名、抽象、拆分与解耦,引入分层、模块化与架构模式,让混乱的系统重新变得井然有序时,如同打扫干净屋子一般的快乐。而现在,只需要向 AI 描述概念、提供文档,代码便自行生长。对于代码的感受,渐渐只剩下 Codex 右上角的 +10000、-100 这样抽象的数字。
还有那种一行一行写下代码、亲手搭建起一个服务的充实感。清楚地知道每一行代码为什么存在,下一行代码又将如何影响整个系统,那种心里有数的踏实感,也渐渐无迹可寻。
过去我认为程序员主要具备三种能力:Root Cause Analysis、架构设计和代码编写。无论是平台化、配置化,还是设计模式、架构模式,其本质都是将易变与稳定的部分进行关注点分离,通过抽象出稳定、可复用的功能、模块与流程,构建一个有序的概念系统,去适配不断变化的现实世界。
而代码编写的核心追求,是在系统不断变"厚"的同时,尽可能保持核心代码的"薄",约束复杂度的增长,使系统始终处于人类能够理解和维护的范围之内。
可是,这些因人类记忆容量、心智负荷限制而产生的设计原则,在 AI 时代是否还同样重要?当 AI 一次生成上万行变更,人类已经很难逐行 Code Review。代码的可维护性是否还意味着必须能被人理解?如果未来的代码主要由 AI 编写、由 AI 修改,那么许多过去为人类理解代码而建立的约束,是否也需要重新审视?
遥想今年年初,我还在理直气壮地说:“AI 写的代码怎么可以不看?How dare you!”。如今再想起来,竟有一种恍如隔世的感觉。
看着 AI 在终端里飞快地编写代码,心里有时会冒出虚无感,看着那些曾经费了心力才弄懂的东西,AI 往往几句话就能讲清楚;看着 AI 轻轻松松做完自己过去费尽心思才能完成的事情;我会想:那些为了排查一个问题熬过的夜、那些为了写出更“优雅”代码而看过的书,是不是一种徒劳?要是那时就有 AI,自己是不是可以少熬几个夜,多读几本闲书?
当然我知道不能这么算。那些知识至少让我解决过一些真实的问题,也让我今天还能大致判断 AI 写得对不对。复杂度并不会因为 AI 的出现而消失。系统仍然需要可维护性、可观测性、性能、可靠性,只是这些曾经需要程序员亲手打磨的具体事物,或许正在逐渐变成向 AI 提出的抽象要求。
过去,我们通过理解系统来编写代码,一边写,一边让系统成为自己理解中的样子;如今,我们更多地通过描述需求、定义约束来生成代码,再通过测试和验证来确认它是否符合预期。最终的成果也许更好,过程却不太一样了。
过去写下的代码里,总能找到自己思考和摸索的痕迹。一个问题是如何被发现的,一段逻辑为什么要这样组织,一个模块又为什么被拆成几个部分,这些大大小小的取舍,都留在代码的字里行间。偶尔翻起刚毕业时写的代码,透过那些幼稚的命名、笨拙的抽象和丑陋的实现,仍然能看见一个稚嫩的青年。他当时想明白了什么,又在哪些地方犯了傻,过了这么多年,竟然还能从代码里看出一些端倪。
人生总得有些属于自己的东西,那些代码虽然青涩,但是我一行一行写出来的,是我写给自己的 Echo。
如今想来,就像孔乙己问孩子:“你可知道茴字有四种写法?” 我也想问问如果是今年入行的自己:“你可知道管理系统复杂度有哪几种设计模式?”
想必同样是一种来自上个时代的孤独。
不过,历史的车轮滚滚向前。若真让我回到从前,一行一行手写代码、苦苦排查问题的日子,我是半点也不愿意的。毕竟那些日子也并不全是快乐。线上故障排查不出来时的焦虑,面对一团乱麻的代码时的烦躁,还有那些莫名其妙浪费掉的周末,如今想来依然让人头疼。
只是有些遗憾,那些伴随其间的快乐,好像也一起消失了。
也许新入行的同学会拥有新的快乐,就像我们也很难理解更早一代程序员在打孔纸带上编写程序时的感受。每一代人都有自己习以为常的工具,也有自己觉得理所当然的工作方式。
我倒并不觉得过去有什么特别值得留恋的。只是那些曾经让我高兴过的事情,若是不写下来,恐怕用不了多久,自己也会觉得陌生。
车窗外依然是零零星星的灯火,列车继续向北京驶去。
明天上班,我大概还是会很愉快地打开 Codex,让它替我写下一行又一行代码。
至于过去那些亲手写代码的快乐,就留在这个夜晚吧。