今天读到 Senko Rašić 的一篇文章,它反驳了一句在 AI 编程时代很流行的话:「代码从来不是难点,真正的难点是决定做什么。」我越来越觉得,这句话看似在强调产品判断,实际上却把软件开发拆成了一个假的二选一:仿佛只要理解了用户,剩下的实现就只是机械劳动。
理解用户当然很难。用户常常说不清自己真正需要什么,客户、使用者和付费者的目标也未必一致;一个今天正确的需求,放到组织、流程和时间里,还可能迅速发生变化。但承认这些困难,并不需要贬低写代码本身。
写代码之所以难,不是因为敲出字符很难,而是因为它要求把含混的现实压缩成精确的系统。什么状态是合法的,边界在哪里,失败之后如何恢复,权限怎样收敛,数据如何保持一致,以及一次局部修改会不会在半年后变成新的约束——这些问题最终都要落进代码,也都无法靠一句「先做出来再说」真正绕过去。
能运行的代码和好的代码之间,还隔着很远的距离。好的代码不仅要在演示时工作,还要在输入异常、依赖失败、规模增长、人员更替和需求变化时,仍然可以被理解、修改和验证。很多工程价值平时并不显眼,只有系统出错或需要继续演化时,才会突然显现出来。
AI 最容易制造的错觉,是把生成的顺畅误认为问题的简单。它可以迅速完成一个局部实现,却也会把背后的推理、取舍和风险隐藏起来。如果人没有真正理解这些代码,速度越快,积累的未知也可能越多。AI 可以替我生成代码,却不会替我承担代码上线之后的责任。
不过,我也不想走到另一个极端,把写代码神秘化成一种不可自动化的艺术。程序员一直在用新的抽象淘汰旧的手艺,AI 只是这段历史的新阶段。真正需要保留的,不是对某种写法的怀旧,而是理解系统如何工作的能力,以及面对复杂性时作出判断的能力。
因此,资深工程师需要理解用户、商业和组织,初级工程师也仍然需要学习数据结构、网络、内存、递归和系统基础。两种能力不是彼此替代的:产品判断不能替代工程判断,工程技艺也不能替代对真实需求的理解。
所以,决定做什么很难,把它正确地做出来也很难。好的软件,不是找到了其中唯一重要的那一半,而是同时尊重了这两个难题。