软件工程的复杂性
软件开发的本质困难总结成了 4 点:复杂性、一致性、可变性和不可见性。
- 复杂性:所谓复杂性,说的是软件几乎是最复杂的人类产品。这种复杂性,在本质上无法用简单的方法化解。这一点应该是软件开发本质困难中最根本的一项。一个是业务需求本身的复杂性;另一个是技术实现的复杂性。最终软件系统的复杂性是两者的叠加。
- 一致性:所谓一致性,指的是为了使软件正常运行,开发人员必须和各种人为的不一致性做斗争。这些不一致性的产生并没有什么合理的原因,仅仅是因为不同的人、不同时间、基于不同的理解所造成的,具有任意性。同样,一致性也包含两个层面,一个是保持业务概念的一致性,另一个是技术实现的一致性。
- 可变性:所谓可变性,指的是软件常常会面临频繁的需求变化。如果一座大楼建了一半,是不可能再去改变它的朝向的。但是软件可以。需求的变化,也导致软件更加复杂。
- 不可见性:关于不可见性,我打一个比方。比如说,一块机械手表,不论多精密,都可以拆开,在显微镜下看到各个零件的构造。一座楼房不论多么高大,总可以通过建筑图纸了解内部结构。但软件不具有类似的物理上的可见性。尽管也可以通过一些技术将部分设计内容可视化,但软件内部在本质上是不可见的。也就是说,即使你把电脑拆了,也不可能看到软件的结构。
AI是银弹吗?
我们来思考一下AI 是否能消除或大幅度降低软件开发的本质困难。
- AI 可以消除软件复杂性吗? 从需求的角度,即使我们用 AI 帮助我们开发软件,也不可能降低需求本身的复杂度。随着 AI 的应用,为软件的用户提供了更多的可能性,因此业务需求反而会更加复杂。另一方面,AI 软件本身所依赖的技术,如机器学习、神经网络等,也增加了技术上的复杂性。因此,AI会增加而不是降低软件的复杂性。
- AI 能保证软件的一致性吗? 相对于单纯技术上的不一致性而言,真正难解决的是软件中包含的业务概念的不一致性。这种不一致,要么引起隐含的逻辑错误,要么导致程序复杂,难以维护。或许将来的某个时候,AI 通过学习业务文档以及代码实现,能够在一定程度上帮助我们找到软件中的概念不一致性,但目前还看不到 AI 在这方面的作用。
- AI 能阻止业务需求的变化吗?和业务复杂性同理,AI 辅助软件开发并不会减少业务需求本身的变化。
- AI 能改变软件的不可见性吗?AI 固有的问题,就是 AI 的“不可解释性”。当 AI 广泛应用于软件后,这种不可解释性会加剧软件的不可见性。
- AI 能保证产生正确的结果吗?AI 自身还有一个局限,就是 AI 产生的结果,既不能保证是正确的,也不能保证是最优的。甚至常常会“一本正经地胡说八道”,而这也是大语言模型的固有问题。
如果我们认可“没有银弹”的理论,那么至少目前的 AI 也不大可能是银弹。我们进行 AI不是银弹 的讨论,主要是思考 AI 的能力边界,也就是 AI 不能做什么。但是不是银弹,不代表 AI 没有用。事实上在很多方面能够使我们更高效地进行软件开发,可以说是一枚“铜弹”。
AI提效的方式
目前 AI 在软件开发中已经可以帮我们做不少事情了,当得起一颗“铜弹”了。我们可以想象一下,如果一个程序员善用 AI,提高了 30% 的效率,而别的程序员只提高了 10%,甚至没有提高。那么这个程序员的竞争力必然提升。推而广之,对于一个企业也是如此。
AI 可以帮我们做这几方面的事情:
- AI 能够帮助开发人员完成重复性和套路性的工作。避免重复是软件开发中一个常见的原则。但就目前的技术而言,仍然有很多重复性的工作很难避免,例如所谓“样板代码”。而 AI 可以通过模仿程序员写代码的方式,自动生成部分具有重复性的代码,从而节省了编写代码的时间。
- AI 可以帮助开发人员完成那些了解原理但忘记技术细节的代码。比如说,我已经多年没有写 JavaScript 了。虽然,原理还记得,但一些具体的语法和 API 忘记了。如果在过去,需要查书或者利用搜索引擎查找资料才能回忆起来。而 AI 可以更快地告诉我这些技术细节,甚至自动生成代码,节省我们的开发时间。
- AI 帮助开发人员提高学习新知识的速度。比如我们有某个 JavaScript 框架没有掌握,如果擅于利用 AI,那么可以比传统的方法更快地学会它。
- AI 可以帮助开发人员获取他人的经验。AI 已经学习了很多别人写的代码,因此它生成的代码中可能包含其他人的经验,甚至可能会带来我们自己没有想到的新做法或新思路。
总的来说,软件开发可以看做一个知识的加工和创造的过程。而 AI 在软件开发中的作用,就是加快了知识加工的周转率。这一点决定了 AI 确实能在软件开发中发挥不小的作用。
程序员要发展哪些能力
通过对AI能力边界的学习和分析,那些只会按照产品经理来完成业务需求的开发,自身对业务理解不透彻,并且开发的代码质量也不高(可扩展性和可维护性不好)。这样的程序员,在AI时代很容易就会被机器替代。
那么程序员要发展哪些能力,才更具有竞争力?
- 加强理解业务需求的能力。 理解业务需求本身,AI 是无法代替的 。而如果开发人员理解了需求,并以领域模型等方式表达出来,那么剩下的一些事情就可以交给 AI 处理了。
- 熟练使用 AI 工具高效工作、快速学习的能力。 基于大语言模型的 AI 有一个特点,就是只有问出好问题,才能得出好答案。我们所问的问题称为 Prompt(提示语),而如何给出好的提示语,已经形成了一个专门的技能——提示语工程。所以,如何才能更好地使用 AI,发挥 AI 的潜力,也是我们需要学习的技能。
- 评审和验证 AI 生成代码的能力。 AI 并不能保证生成的结果是最优化的,也就是说生成的可能也是“垃圾代码”。这就需要开发人员具备判断生成的代码质量的能力,以及进一步优化代码的能力。也就是掌握软件设计、整洁代码、重构等能力。
- 掌握软件开发各项技术的基本原理(而不是技术细节)的能力。 如果我已经了解 Vue.js 的基本原理,只是忘记了具体的语法细节,那么就非常适合在 AI 的辅助下开发基于 Vue.js 的程序。但是如果我一点都不了解原理,甚至 JavaScript 也不会,那么即使有 AI 的帮助,也难以达成目的。
咱们引用毛泽东思想中的一句话来总结我们对于 AI 辅助软件开发的态度:“战略上藐视敌人,战术上重视敌人”。所谓“战略上藐视”,就是不要太紧张,我们要看到 AI 的影响是渐进的,大家完全有时间,有能力掌握相关技术。所谓“战术上重视”,指的是现在就要开始行动了,主动关注相关技术的发展,最好尽快进行尝试。