在我二十多岁时,笑容常挂在我的脸上。最初我并未察觉,但和我熟悉的人都会注意到这一点,大多数情况下,这被视为一种正面的特质。
然而,有次一位软件工程师用困惑和担忧的眼神问我:“你为什么总是这么快乐?”
这个问题让我有些意外。据我所知,我拥有一切应当让人感到快乐的条件:我刚加入了一家我非常喜欢的公司,担任的职位与我的专长高度匹配,同事们都是才华横溢且工作热情高涨的人。更重要的是,我们正在享受公司赞助的部门晚宴,这是一周紧张工作和会议后的轻松时光。在这样的环境下,谁会不快乐呢?
答案出人意料:软件工程师。
当我环顾整个房间,忽略那些热情洋溢的高级管理人员、愉悦的项目经理和乐观的用户体验设计师后,我看到了另一幅画面,一幅令人担忧的画面。
我们团队里最资深的工程师独自坐在吧台前,下巴放在手掌上,由于头部压力,肘部已泛红。他另一只手的食指在吧台上随意地划来划去,显然心情并不好。
在房间的另一个角落,四名工程师围成一个小圈子。其中一人正用手势激动地解释着某个问题,而其他人显然是在不耐烦地等待他结束,以便他们能发表自己的观点。他们的面部表情都很严肃。
后来我了解到,他们当时正在讨论一个表面上看似微不足道,但实际上非常有争议的问题:数据库中第一条记录的 ID 应该是 0 还是 1?
这让我明白了,那名先前觉得我总是快乐的软件工程师为何会有这样的疑惑。作为一名编程专家,我为何总是笑容满面呢?
如今,我 38 岁,肩负着一对婴儿双胞胎和一个三岁孩子的父亲角色。同时,我还是一家拥有 30 名员工的初创公司的创始人和 CEO。这家公司为数百家企业提供关键的身份验证服务。面对这么多身份和责任,额头上的皱纹加深、体型微胖、头发渐白,以及眼下的黑眼圈都似乎成了理所当然的事。
然而,这些身体和精神的消耗主要源于一个因素:我依然在编程。
请不要误解,我对编程依然充满热情,只是现在人们不再因为我的乐观而称赞我。
我并非孤例。Cobalt 最近发布的研究报告调查了超过 600 名网络安全和软件开发专业人士,揭示了一些令人震惊的现象:
58% 的受访者正面临职业倦怠。
53% 的受访者考虑辞职。
63% 的受访者认为工作对他们的心理健康有负面影响。
64% 的受访者认为工作对他们的身体健康有负面影响。
回头看看我以前的工程师同事,几乎所有人都已经不再进行日常的代码编写工作。事实上,许多人已经完全退出了科技行业。
一名程序员因职业倦怠而崩溃,这是他在被要求澄清一个问题时的真实回应。
“哦,这有什么大不了的?”你可能会这样想,“坐在 700 美元的椅子上,穿着睡衣,在 3000 美元的 MacBook Pro 前工作 8 小时,一周几天,有什么难受的呢?”
现在,让我来告诉你。
为什么软件工程如此困难?
根据我的经验,如果你选择软件工程仅仅是为了赚钱,你在这个领域里可能走不远。事实上,对于大多数开发者来说,有数百个其他职业路径可以提供同样或者更高的薪资、声誉和职业满足感。
我们可以从另一个角度来深入了解编程如何影响个体情感。面对各种挑战,为什么人们还是坚持下去?这些坚持的原因通常是高度个人化和深刻的,但当你与足够多的人进行交流后,你会发现一些反复出现的主题。
编程不仅是一种技术活动,更是一种高度创造性的过程,它常常触及到思想和情感的深层。有时候,人们会以一种程序员完全没法预见或者想象到的方式,来利用这些创新成果。也许,没有什么比创造出别人能够欣赏和使用的产品更能体现人类创造力的纯粹性。
在这方面,1975年软件工程经典著作《人月神话》的作者弗雷德里克·布鲁克斯是最有发言权的人。这些论文不仅历久弥新,而且具有近乎神秘的相关性。以下是我最喜欢的一段文字,摘自名为 “工艺的乐趣” 的章节。
“在如此灵活的媒介中工作,确实带来了一种独特的愉悦。程序员,有点像诗人,工作的素材几乎完全是思想。他们在虚空中构建自己的‘城堡’,这些‘城堡’是由纯粹的思想和想象力塑造的。很少有哪种创造性媒介能像编程语言那样,容许你如此自由地打磨和重塑,如此方便地实现宏伟的构想。”
布鲁克斯还描述了编程的另一面,这一点体现在名为 “工艺的困扰” 的章节中。
“为了编程的有效性,人必须追求近乎完美的准确性。在这一点上,计算机就像是传说中的魔法。如果代码中的一个字符、一个语法结构没有严格地按照规定来编写,那么整个程序就可能无法运行。人类并不特别擅长追求完美,而且很少有其他活动会对人们如此严格地要求完美。我认为,适应这种对完美的高标准,是学习编程过程中最具挑战性的一部分。”
这篇文章写于 1975 年。
延续布鲁克斯的思想,我发现编程中的乐趣与困扰往往是交织在一起的。我最自豪的编程成就往往来自那些几乎让我精疲力尽的项目。解决了长期困扰我和我的团队的 bug 会带来巨大的成就感。然而,这种成就感与陷入绝望时的沮丧是密不可分的。比如,花数小时去调试程序中一些令人困惑的行为,最后却发现问题仅仅是因为我写了 “initializer” 而非 “initialize”。这样的经历对于我们中的大多数人来说,是一种无休止的循环。难怪在社交场合中,很少有人笑得出来。
数十年来,我们经历了计算能力的指数级增长、先进开发工具的出现,以及编程语言变得更加人性化。那么,为什么布鲁克斯的观点在今天仍然有强烈的共鸣呢?
概念压缩与走向 AI 的路径
在我 11 岁时,我梦想着能制作一款属于自己的游戏。
那一年,我在公共图书馆找到了一本名为《游戏编程大师的技巧》的书。书的封面设计得非常酷,仿佛是一款类似于 DOOM 的第一人称射击游戏的包装。我心想,“这就是我要的。”我随手翻开了书的某一页,记得非常清晰,我看到了这样一个图表:
其实,当时我认识其中的一些单词而已。
我仔细翻阅了整本书,试图找到任何我能理解的、或者看起来稍微“像是游戏”的内容。结果一无所获。于是,我失望地合上了书,从此以后,我再也没有告诉任何人我曾经想成为一名游戏工程师。
然而,因为“概念压缩”的存在,下一代有志于游戏开发的年轻人会有全新的体验。
以 2015 年为例,一个名叫 Toby Fox 的 23 岁年轻人发布了一款名为 “传说之下(Undertale)” 的游戏。这款游戏完全是在他个人的家用电脑上开发完成的。尽管这款游戏是自主发布的,但它成功卖出了数百万份,并获得了业界的一致好评。许多媒体甚至将其评为“年度最佳游戏”,击败了许多拥有巨额预算的 AAA 级游戏。
“传说之下” 是在一个名为 Game Maker Studio 的可视化工具中开发的,这正是概念压缩的体现。
概念压缩 是由 David Heinemeier Hansson(DHH)首次提出的,他是 Ruby on Rails 的创始人。这个 Web 开发框架不仅对我的整个科技职业生涯有着不可或缺的影响,也对我所在的 Kolide 公司非常重要。简单来说,概念压缩描述了编程从底层的二进制语言,到更接近自然语言的 Ruby,再到如今的低代码或无代码工具,以及 LLM(Language-agnostic Low-code Model)的发展过程。
Hansson 创造这个词组的博客文章 摘录:
“在计算机科学领域,构建应用程序意味着在多层抽象的基础上进行开发。从 CPU、1 和 0,到汇编语言、C 编译器、数据库驱动、内存管理,以及其他无数关键概念,都是应用程序运行所依赖的基础。然而,随着这个行业的不断发展,越来越少的开发者需要深入了解这些底层细节。
优化‘概念压缩’算法,以便减少开发者需要关注的底层复杂性,虽然是一项巨大的挑战,但绝对值得。我们越能有效地压缩过去的复杂概念,进入这个领域的门槛就越低。如果我们希望更多的人参与应用开发,降低入门门槛是必不可少的。”
“概念压缩”不仅让 Toby Fox 能够开发出“传说之下”,还极大地推动了软件工程领域新人的增长。然而,这些新入行者同样需要面对这个行业带来的各种挑战和困扰。简而言之,在降低编程的心理和情感负担方面,让编程“更易接近”并不意味着它也“更易操作”。
在开发“传说之下”的续作过程中,Toby Fox 在多个进度报告中分享了他的经验。他谈到了更换游戏引擎所导致的时间损失、与其他工程师合作的挑战、由长时间编程引发的手腕疼痛,以及因项目周期过长(已达 8 年并仍在进行)而导致的睡眠问题。
“虽然游戏尚未完全完成,但剩余的开发工作确实在逐渐减少。这是好事,因为在游戏完成之前,我每晚都会受到噩梦的困扰。”
那么,为什么即使“概念压缩”增加了进入这个领域的人数,编程本身却并没有变得更简单呢?尤其是对于那些在新型“概念压缩”技术出现之前就已经在这个行业工作的人来说。
事实上,这里的情况相当复杂。虽然这些技术进步让编程变得更容易,但并没有从根本上降低编程所需的劳动强度。要理解这一点,我们需要讨论一个在软件开发领域长期缺失的概念——那就是“银弹”解决方案。
ChatGPT 对开发者来说是银弹吗?
Fred Brooks 在 1986 年的具有里程碑意义的论文《没有银弹——软件工程的本质与偶然》中开篇便提出了一个与本文讨论密切相关的观点:
“在各种流行的神话和传说中,狼人常常是最令人恐惧的存在,因为它们能在你最不预料的时刻从一个熟悉的形态变为可怕的怪物。为了消灭这些威胁,人们常寻找能一击致命的银弹。
在非技术经理的眼中,软件项目往往也具有类似的特性:它们看似简单、无害,但却可能突然变成一个超出预算、延误交付并且充满缺陷的问题项目。因此,人们急切地寻找那个能像计算机硬件成本一样迅速降低软件成本的‘银弹’。
然而,当我们展望未来十年,我们并没有看到这样的银弹解决方案。没有任何单一的技术或管理方法能够显著提升生产力、可靠性或简单性。”
尽管我建议你完整地阅读这篇文章,但其中一个核心观点是他对两种不同类型复杂性的讨论:偶然复杂性和本质复杂性。Brooks 强调,这些复杂性是编程工作中不可或缺的因素,因此没有所谓的银弹能完全解决这些问题。
偶然复杂性:工具导致的问题
在软件工程领域,偶然复杂性是指由我们用于完成任务的工具和抽象层带来的复杂性。这种复杂性也常被称为附加复杂性,因为它与工程师试图解决的核心问题几乎无关,主要是因为我们使用的工具局限性导致的不必要复杂性。例如,编程语言、库、框架、测试方法、Web 服务器,以及用于数据库查询的语言都是偶然复杂性的来源。
需要明确的是,“偶然”并不等于“不重要”。实际上,许多开发者经常遇到的问题往往与这种偶然复杂性有关。
编程中对人完美执行的高要求就是一个偶然复杂性的例子。与大多数偶然复杂性一样,这种复杂性可以通过改进工具和流程来减轻,甚至有可能在未来完全消除。Brooks 也没有否认这一可能性。
本质复杂性:问题固有的挑战
在软件工程领域,本质复杂性是与你所要解决的具体问题紧密相关的复杂性。以主题公园(如迪士尼乐园的 FastPass)的游乐设施预约系统为例,无论你选择何种编程语言来实现这个系统,都需要解决一系列固有的复杂问题,以确保软件的实用性。我们将在后文进一步深入探讨这个案例。
本质复杂性也是导致开发难度增加的主要因素之一。你是否曾经想过,为什么程序员需要掌握如此多看似无关紧要、但实则极其复杂的细节呢?这些都是他们在多年的职业生涯中不得不面对的本质复杂性。
以斯坦威钢琴工厂的员工为例,他们可能并不需要知道如何演奏钢琴。然而,对于那些需要为数字音频软件开发一个模拟斯坦威钢琴音效的插件的程序员来说,情况就不同了。为了精确地完成这项任务,他们不仅需要了解钢琴的基本工作原理,还需要对和声学和共振有深入的认识。甚至还需要掌握一些难以用语言描述的知识。这些知识更多地依赖于感觉和经验。
那么,斯坦威钢琴的音色为何如此引人入胜?它与其他如 Bösendorfer 或 Bechstein 钢琴有何不同?想要在数字音乐领域做出有意义的贡献,程序员必须全面了解这些因素。这也是他们常感到压力巨大的原因。在面对这些本质复杂性时,为了在这由“纯粹思想”构成的领域中脱颖而出,我们不仅需要对完美执行有高要求,还需要精细地管理和掌控这些复杂性。
几乎所有软件工程的进步都更多地减少了偶然复杂性而非本质复杂性。这甚至包括像 ChatGPT 这样的大型语言模型(LLMs)。
大型语言模型(LLMs)可以视为一种数字化的信息中心,能即时访问各种重要数据。在最理想的情况下,这些模型能够理解人类在书籍、互联网以及其他计算机相关文档中的所有有价值的信息。
经过训练后,LLMs 能根据输入的提示进行概率性的回应。对于每一个可能的回应词或“token”(可能是一个完整的词或词的一部分),模型会计算该词作为下一个词出现的概率,基于其在训练数据中观察到的模式。这个过程就像是一个基于训练数据来猜测“下一个 token 会是什么”的游戏。
令人惊讶的是,这种看似简单的方法已经是我们目前能够实现的最接近人类智能的技术。ChatGPT 的最新版本甚至能完成大多数高中、大学和研究生级别的任务。它们也能通过律师资格考试,尽管这更多地反映了我们的考试方式,而不是模型本身是否能成为优秀的律师。尽管我不希望看到一个全由 LLMs 编写的书籍世界,但我必须承认,不能忽视它们的能力和潜力。特别是,它们在减少软件工程中偶然复杂性方面表现出色。
正因为 LLMs 的高度灵活性,它们可能是迄今最有效的工具,用于减少偶然复杂性对工程师时间的影响。LLMs 不仅能将你不熟悉的编程语言翻译成你能理解的语言。它们还能教你如何高效地使用之前未接触过的工程工具,并甚至能帮助你发现编译器和 linting 工具难以识别的代码错误。
更重要的是,与以往任何工具不同,LLMs 是我第一次遇到的能够减轻本质复杂性负担的工具以我们之前提到的迪士尼乐园“快速通行证”为例,如果我们想实施一个类似系统在自己的主题公园,应从何开始?以下是我与 ChatGPT-4 在这个主题上的一次互动。