ARTICLE · 1157347
用AI做软件,人还需要懂代码吗?
这几年AI的编程能力突飞猛进,在多个编程比赛中击败人类[1],同时AI agent也能生成颇具复杂度的软件。于是,有人声称AI的编程能力已经超过了世界上最优秀的程序员,觉得以后的软件应该全部由AI来开发,人不需要看AI写的代码,只用定义需求以及做黑盒测试就可以了。甚至还有人认为以后世界上不再需要能看懂代码的程序员了,学习编程语言已经不重要了。
我觉得有过复杂工业软件开发经验的工程师都不应该相信这样的观念。我举几个例子来说明为什么这样的模式不可行。
多线程并发编程的正确性难题
编程竞赛通常以单线程的数据结构与算法实现为主,并发编程在竞赛中极其少见。然而现实世界中广泛使用的却是多线程并发程序。对并发程序来说,靠黑盒测试来检验其正确性是极其困难的任务,因为它们的运行存在着时序不确定性,对于同样的输入概率性的呈现多种结果。很多并发编程的BUG,如数据竞争、死锁等,只在极低的概率下才能被观察到。在不了解代码实现的情况下,仅靠黑盒测试来排除这类BUG是不可行的。
更糟糕的是,有些存在BUG的代码,在某次编译成二进制后,其行为居然恰好总是正确的。其中一个例子是被业界叫做“良性数据竞争”(Benign data race)的代码。这种代码到底算不算存在BUG也常常引起争议。而实际上,所谓的“良性数据竞争”仅仅只针对某一次编译后的结果而言,谁也不能保证同样的代码下次编译后行为还是正确的[2]。这也意味着,此时的测试仅对一次编译的结果有意义,并不对代码本身的正确性有意义。
有些测试方法,如TSAN,可以增大某些数据竞争问题被发现的概率,但没有任何方法能保证测出所有的数据竞争问题。还有人认为Rust语言能保证并发编程的正确性——虽然Rust语言的safe代码确实可以杜绝数据竞争(Data race),但是却无法杜绝竞态条件(Race condition)。一个例子是:用Rust的原子变量来实现无锁数据结构时,对于内存序(Memory order)的正确配置仍然只能由人来保证,编译器无法做任何检查。如果使用了错误的内存序,还是可能跑出错误的结果。
既然多线程软件的正确性难以保证,那只让AI写单线程软件行不行?——还是不行,因为
错误的代码经常跑出正确的结果
学过中学数学的都知道,要证明一个命题,必须要通过严谨的逻辑推理一步步从前提推导出结论。没有人会认为只要设计几组数据,放在命题里“测试”一下,就能证明命题的正确性。
数学界有些经典的例子[3]:“12”是一个合数(非素数),“121”也是合数,“1211”、“12111”、“121111”都是合数。你很容易会想:在“12”后面加任意多个“1”,结果是不是都是合数?你验证10个“1”,20个“1”,30个“1”……全都是合数,至此这命题看起来应该没错了。然而,当“12”后面加136个“1”的时候,这个138位数,却意外的是个素数。
计算机程序与数学命题有着高度的相似性。我经常让AI来编码解决算法问题,发现AI常常对于NP-hard问题使用贪心算法。当你用一些简单的输入测试这些程序时,大部分时候都能恰好得到预期的结果。但是如果你仔细分析代码实现,就能针对其找出反例。这说明在不了解程序实现方式时,设计测试用例的效果是受限的。
还有很多BUG并非来自于算法选择,而是来自于编程语言和数据结构的陷阱,如:
哈希数据结构没有考虑哈希冲突;
二分查找的输入数据没有严格排序;
假定不稳定排序算法(如快排)的结果是稳定的;
对两个浮点数精确比较数值是否相等;
访问已被释放的对象;
……
存在这些BUG经常不影响某次观测的结果。设想在一个有成千上万个处理步骤的复杂程序中,其中某几个步骤存在以上BUG,此时想在不了解实现的情况下靠测试暴露这种BUG,无异于大海捞针。上面这些例子还只不过是代码中最简单、最容易发现的几类错误。现实世界中软件的BUG往往由众多很难出现的状态意外交织在一起才能触发,我的另一篇文章给了一个这样的例子[4]。
更糟糕的是,存在BUG的代码,在不同运行环境下的表现还可能不一样。软件在测试环境下跑着没问题,放到用户环境下可能出问题;这次编译后跑着没问题,下次编译后可能有问题……你用测试验证的,不过是某一次编译后,在某个特定运行环境下,某一次运行产生的那个偶然结果。
软件的质量,根本上靠的是严谨的架构设计、严密的逻辑推导与一丝不苟的证明,而不是盲人摸象一般的测试。
有人觉得:这些软件的行为不是大多数时候是对的吗?又不是不能跑,出了问题再解决就行。
他们恐怕不了解工业领域的软件在干什么。外行人常常以为软件世界的全部不过是没什么性能要求的电子商务网站、界面炫酷的贪吃蛇游戏、漂在桌面上记笔记勾待办的工具……他们想不到工业软件中的一个BUG可以让发射上天的火箭爆炸,可以让高速运行的列车相撞,可以让医疗设备下的病人意外死亡。
什么样的软件工程师值钱?
我觉得这个时代里每个人都应该积极的用AI尝试编写自己想要的程序,体会一下AI那惊人的生产力。但一个疑问是:既然现在开发软件这么容易,谁还愿意为了软件付钱?
市场价格取决于供求关系,只有稀缺的东西能卖高价。AI能轻易生成那些界面漂亮、看起来能跑、逻辑未经过严格证明、有很多潜在BUG的软件,那么这样的软件必然不值钱(其实这种软件以前也不怎么值钱)。但那些高性能、高可靠、有强大质量保证的复杂工业软件,仍然会有客户愿意为其付费。要开发出这样的软件,是不能只靠AI的,高素质工程师的参与必不可少。显然,市场上什么样的软件值钱,会决定人才市场上什么样的软件工程师值钱。
有些年轻人认为AI的能力在飞速提高,AI做出的软件质量一定会超过最优秀的人类组织,所以现在学习编程语言是浪费时间。我不否认这种未来的可能性,但至少以目前的技术状况,我看不到它的实现可能。重要的是,在AI时代放弃基础知识学习的人,要明白自己赌的是什么。计算器都发明了几十年了,也没有人认为应当取消中小学的初等数学教育,现在的小学生仍然要背乘法表。这些人是基于什么逻辑,认为以后的软件开发人员可以不用学习编程语言的?
参考
https://arxiv.org/abs/2502.06807
https://hboehm.info/boehm-hotpar11.pdf
https://www.quora.com/What-is-an-example-of-a-conjecture-that-was-proven-wrong-for-very-large-numbers