如果您是一位经验丰富的开发人员或经验丰富的计算机用户,您可能还记得 128MB RAM 曾被认为是一种奢侈品。对于那些不知道、太年轻或最近才开始使用电脑的人,让我解释一下:最初的《马克思佩恩》视频游戏只需要 128MB RAM,就像《GTA:罪恶都市》一样。这意味着计算机只需要这个内存量来运行游戏和所有其他程序。
但这不是重点。关键是,这些游戏在过去被认为是游戏界的重要里程碑。是的,他们的形象现在已经过时了。是的,它们不提供与现代游戏相同的沉浸感或丰富的游戏机制。然而,从算法的角度来看,它们与《刺客信条》或《荒野大镖客》等现代游戏并没有本质上的不同。
顺便说一句软件危机,后者需要 12GB RAM 和 120GB 存储空间。这比 Max Payne 或 GTA Vice City 的资源多 100 倍!就这么多了。
这不仅仅涉及游戏,它几乎适用于我们日常使用的所有软件。毫不奇怪,即使是最基本的应用程序(例如消息传递)也会消耗 1GB RAM。但为什么会出现这种情况呢?为什么信使需要比开放世界游戏多 10 倍的内存?
问题:软件危机
这个问题并不新鲜——它已经存在了 50 多年。事实上,维基百科上甚至有一篇专门讨论这一问题的文章:“软件危机”。想象一下,早在 20 世纪 60 年代,人们就已经在努力解决硬件能力与我们生产有效软件的能力之间的差距。这是软件开发史上的重要篇章,但令人惊讶的是它仍然没有被讨论。
为了解决这些问题,我们在1968年和1969年召开了两次北约软件工程主要会议。这些会议导致了诸如“软件工程”、“软件验收测试”等术语的正式化,这些术语后来变得普遍。后者在获得更广泛的接受之前已经广泛应用于航空航天和国防系统。
想象一下,这个问题在 UNIX 操作系统开始开发之前就很突出!
尽管此后已经编写了数十亿行代码,但我们仍然经常看到人们对某些方法、编程语言、库等不满意。“Javascript 很糟糕!”、“你不需要 Kubernetes!”和“敏捷是浪费时间!”经常听到沮丧的开发人员说。这些陈述通常伴随着一些建议和个人偏好,例如“您应该始终使用 X 而不是 Y”或“远离 X,否则您会后悔的”。
另一个流行的技巧是应用特定的设计模式和原则。他们坚信,如果您遵循他们的要求,您的代码将会更加干净,从而为其他人带来更易于维护、更易读的代码以及更稳定的版本。我同意这些说法有一定道理。尤其是设计模式,确实改进了开发人员用来相互交谈的“语言”。例如,向另一个开发人员提及“适配器”可以立即传达对其用途的共同理解。这种理解甚至可以传达给来自不同背景的开发人员。如果没有这些共享词汇,解释概念将需要更多努力。
但是,尽管有丰富的设计模式、概念、众多的架构和最佳实践,为什么我们仍然难以及时交付高质量的软件?
关于“糟糕的代码从何而来?”的思考
Casey Muratori 在他有趣的视频中声称“坏代码从何而来?”由于当今软件质量低下,仍然有很多软件需要开发。
虽然硬件开发取得了重大进展,但我们在软件实践方面却没有取得太大进展。在过去的 30 年里,我们见证了无数新的编程语言、复杂的框架、引擎、库和第三方服务的崛起。然而,对于个人开发人员来说,编程仍然像以前一样具有挑战性。开发人员需要阅读现有代码(通常是大量代码)、修改代码或编写新软件,然后执行、调试,最后交付。
虽然我们改进了执行(使用现代编程语言)和调试体验,当然也有许多工具来交付代码(感谢 CI 管道和 DevOps),但读取和编写代码的任务仍然是主要瓶颈。人脑只能处理有限的信息,这些限制是软件开发的重大障碍。
回顾凯西的视频,他将编程过程比作导航。这就像从一个已知的点出发,有某个最终目的地,但旅程本身是不确定的。你必须经历整个过程才能到达终点。你不一定知道事情会如何结束,但一旦你到达那里,你就知道了。因此,结果的质量成为您的参考点。这个过程本身很复杂,并且常常充满未知数。
我们一直在现实生活中看到这方面的证据。想想看,您有多少次读到一家公司正在开发一款软件,却在开发过程中决定用不同的语言从头开始重写所有内容。这说明,在开发过程中,团队最终可能会因挑战而迷失和不知所措,因此将所有工作放在一边并回到起点似乎是一个不错的选择。
综上所述
我同意凯西的观点,我们仍处于了解如何在受控环境中生产高质量软件的早期阶段。实现这一目标的关键是关注我们作为人类的能力;具体来说,我们如何读写软件。我们的主要重点应该是减少编程的认知负担。这意味着我们应该以与现在完全不同的方式来生产软件。我们不应该在编辑器中阅读和编写文本片段,而应该追求更高层次的抽象。我们不应该处理原始文本和附加的代码片段(如装订纸),而应该拥有某种不同的环境,让我们以可预测和可控的方式修改软件。
同时,我认为我们不应该完全拒绝对原文进行编辑;相反软件危机,我们应该在不同的抽象级别之间轻松移动。这类似于我们从打孔卡转向汇编语言和高级编程语言的方式。我们仍然可以将机器代码减少到最低级别并在该级别编写软件。在大多数情况下,这会浪费时间和精力,但能够转移到较低的抽象级别非常重要。
在某些情况下,这种能力是无价的。未来,这种能力将成为每个开发者的核心能力。