Java三十周年,Gosling深度访谈:修补C++造就Java、泛型备受诟病,劝程序员职场遇不道德要求应直接走人

360影视 国产动漫 2025-06-02 17:41 2

摘要:它曾一度被誉为“一次编写,到处运行”的典范,堪称编程语言教科书中的传奇;它也曾是企业级软件开发的绝对主角,被寄望于主导移动互联网的未来。然而,这些年随着 Python、Go、Rust 等语言不断崛起,“Java 已死”的声音不绝于耳。特别是在 AI 浪潮席卷而

编译 | 屠敏、王启隆

出品 | CSDN(ID:CSDNnews)

1995 年,一个叫 Oak 的语言悄悄登场,后来它改了个名字,叫 Java。

它曾一度被誉为“一次编写,到处运行”的典范,堪称编程语言教科书中的传奇;它也曾是企业级软件开发的绝对主角,被寄望于主导移动互联网的未来。然而,这些年随着 Python、Go、Rust 等语言不断崛起,“Java 已死”的声音不绝于耳。特别是在 AI 浪潮席卷而来的当下,这门写了三十年的语言仿佛逐渐失去了话语权,甚至被一些人认为已经“过时”。

可现实并非如此。Java 依然活跃在全球无数开发者的工作流中,支撑着大大小小的关键系统,版本号也悄悄地爬到了 24。

就在 Java 迎来 30 岁生日之际,专注于 Java 和 OpenJDK 社区技术动态的播客 FooJay 请来了 Java 的缔造者 James Gosling,主持人 Frank Delporte 与之进行了一次特别的深度对话。James Gosling 怎么看 Java 的三十年风雨历程?去年 7 月宣布退休的他,如今真的退下来了,还是“假退休,真折腾”?

这期访谈中,我们将一同探寻 Java 的起源、了解 Gosling 对编程世界革命性的影响、三十年来的持续演进,以及 Gosling 对这门语言未来走向的深刻洞见。从那个石破天惊的 Beta 版,到“一次编写,到处运行”的理念,再到驱动全球数十亿设备。这段传奇,将由 Java 之父,一切的开创者,詹姆斯·高斯林亲口讲述。

Java 的诞生:原本只是想修修 C++ 的边界问题

主持人:5 月 23 日是 Java 首个 Beta 版于 1995 年发布的三十周年纪念日,我们荣幸地推出了史上首次单嘉宾播客。而这位嘉宾,分量十足——他就是 Java 的缔造者,詹姆斯·高斯林。你近来生活如何?

詹姆斯·高斯林:其实,那更像是 35 年前的事了……

主持人:或许我们应该把时光倒回 35 年前。你当初为何以及如何开启这项事业的呢?

詹姆斯·高斯林:故事始于 90 年末、91 年初。我们一群人注意到,计算机技术正渗透到各个角落。它不再仅仅局限于数据中心、科研人员的办公桌之类的场景。我们感觉到数字系统正在扩张,当时我们对此相当敏感,但似乎整个行业,包括 Sun 公司,对此却视而不见。

于是斯科特(Sun 公司共同创办者之一)说:“好吧,你们这些爱发牢骚的家伙,去研究研究这个吧。”

我们就去了。我们做的一件事就是走访各行各业的人士,了解他们如何在自己的产品中运用计算机。从录像机制造商到电梯、火车头的工程师,我们进行了大量的实地考察。那几个月四处拜访,会见欧洲、亚洲那些正在创造事物的人们,真是一段非常有趣的时光。

期间浮现出许多问题,有些着实令人沮丧。这些人的一个共同点是,他们都在将网络融入一切,但他们却在重新发明网络。他们做的那些发明,计算机科学在几十年前就已经做过,并且深知其为何会失败。他们大量使用串行线路,却没有足够的纠错机制。那些从事工业自动化的人还在用 8 位地址。天啊,8 位地址根本无法扩展,16 位也仍然不够。

然而,在与这些人讨论需求时,我们也从他们身上学到了东西。他们从不提及安全性和可靠性。并非因为他们不在乎,而是因为安全性和可靠性是如此至关重要,以至于根本没必要列在清单上,那就像说“哦,我们要盖房子,得记得往里面放氧气”一样。这是一种不言而喻、绝无妥协余地的要求。

当时,性能是计算机设计的一切。为了提升一点性能而牺牲一点可靠性是很常见的做法。那个时代我最爱举的例子是除法的实现方式:他们用牛顿迭代法求解器,而不是你在高中学到的长除法(或者至少是其电子版)。所以他们的除法运算非常非常快,但低位精度却有些马虎。人们总是这样做。即便在 Sun 公司内部,人们也会做出一些让我们这些人感到不安的权衡。对很多用户而言,这可是人命关天。如果你在为火车头或电梯构建控制系统,一旦出错,通常就会血溅当场。第一要义,绝不能把客户给“干掉”。

主持人:这确实是条铁律。但我很惊讶你提到火车头,而如今使用 Java 的人,通常认为它是一种服务器语言,部署在大型服务器上。

詹姆斯·高斯林:这正是分歧之处的全部来源。两个方向其实都对。企业市场有更多的资金,因此 Sun 公司最终将大部分投资投入到这方面。这种发展轨迹多少有点出乎意料。但尽管如此,当你回头看看人们实际用 Web 服务做的那些事——无论是航班调度、打车服务,还是城市公共交通系统的运营——我们最初想象的是像电梯这种规模的小型设备,而其他人则在构想类似伦敦地铁这样的大系统。虽然规模不同,但如果系统崩溃,后果可能是一样严重,甚至更糟。所以,一旦出现故障,代价会非常惨重。

我对 C 语言最不满意的一点,就是它太容易写出难以修复的错误,而这些错误往往会带来非常隐蔽、难以诊断的问题。边界条件实在太多了。

当我们启动这个项目时,我们首先去调研用户到底在做些什么,理解他们的工作方式。然后我们开始构建原型——因为我们是工程师,更擅长用代码说话,而不是写白皮书。原型的一个优势在于,它迫使你在脑中真正具体化问题。我们当时有几位软件工程师、几位硬件工程师,还有一位非常优秀的商业伙伴。

随着我们不断思考从用户那里收集到的需求清单,逐渐发现,软件工程中一些“标准做法”其实不断制造问题。最大的问题都集中在可靠性和安全性上。而这两个方面,在某种程度上其实是密切相关的,甚至可以说本质上是一回事。因为世界上很多安全攻击,本质上就是程序错误。当然,也有一些攻击是源于极端的愚蠢——比如把 root 密码设为空。你说这是个错误,还是彻头彻尾的无能?你自己判断吧。

我们一开始用的是 C,但很快就觉得不行……后来又尝试了 C++,但也发现问题依旧。

于是,我就成了团队里那个说“我们是不是该从方法论层面解决这些问题”的人。结果就是,一旦你开始尝试去解决这些方法论问题,很快就会被带着一步步走远。最初只是想修补 C++ 里那些讨厌的边界情况,没想到最后发展成了一件完全不同的事。

主持人:确实。如今它已经是一门完整的语言,还发展出一个庞大的社区。这真的非常了不起。数百万人正在使用你创造的 Java。你有什么感受?

詹姆斯·高斯林:真的感觉非常棒。让我最感动的是,每当有人走过来说:“谢谢你,是你让我拥有了这样一份事业。”我总是有些不知该如何回应——因为这实在太美好了。

主持人:我自己也必须对你说声谢谢,因为你对我来说就是那样的人。我从 10 岁起就开始玩 Commodore 64,我是那个时代的人。后来,我当了几年电影剪辑师,但最终重新燃起了对编程的热情——因为我需要找一种办法把视频放到网上。不知道怎么回事,最后我就选了 Java。我试过其他语言,但唯独 Java 吸引了我。

我一直无法理解 C 和 C++,它们不符合我的思维方式,我也说不清为什么。但在 Java 里,我什么都能读懂。我只需要 Java 和 JavaFX,就能做出我想要的任何东西。它真的让我找到了新的职业方向,也让我可以靠编程谋生。

詹姆斯·高斯林:看着它如此广泛地传播,有时也会带来一些负面影响。整个千年虫(Y2K)事件,现在想起来还有点心惊胆战。

因为 Y2K,许多人从 COBOL 迁移到了 Java。而我,正是 `java.lang.Date` 的作者。我大概花了一整个星期在它上面。所有新的、那些花哨的日历类都是在 2000 年之后才出现的。

但那一晚,我彻夜难眠。我关注着每一个聊天频道,想看看发生了什么,有没有出什么岔子。当然,我们之前已经进行过各种演练,把电脑的时钟拨快一个月之类的,所以我们已经经历过很多次 Y2K 了。但真正的 Y2K 是不同的。

主持人:但事后仍然有人说:“嗯,没那么糟。他们说世界会停止运转,但其实还好。”但这难道不是因为所有那些工程师们已经为可能发生的情况努力了好几年吗?

詹姆斯·高斯林:完全正确,正是如此。作为一名工程师,最麻烦的一点是,你工作的最佳状态就是无人察觉。如果真发生了什么“激动人心”的事,那很可能就是你搞砸了。如果你是那种靠着阿谀奉承和肾上腺素过活的人,或许工程领域不适合你。你必须从“桥没有塌”这件事中获得快感。

主持人:就像几年前我们遇到的 Log4j 问题一样。出现了一个漏洞,所以那个库突然成了大问题。但另一方面,人们在那个库上投入了大量精力,很多人使用它并简化了他们的工作。然后突然因为那一个问题的出现,整个系统就名誉扫地了。但这就像你说的,如果你什么都不做,就不可能做错任何事。

詹姆斯·高斯林:没错。

主持人:Java 中是否有很多类似的事情让你觉得:“我犯了个错误?”人们可能会说是空指针或空指针异常。那是个错误吗?

詹姆斯·高斯林:很多这类事情,就像是在玩“打地鼠”游戏。你知道那种你要敲打冒出来的地鼠的游戏。工程就是这样。而且总是有权衡取舍。我们最擅长处理的是工程上的权衡,但有时社会学层面的权衡更难。

我经常被诟病的一件事是泛型。94 年的时候,关于泛型有过一场大争论。有些人坚持:“必须要有泛型。”我当时想:“好吧。”因为这些人用过泛型,他们来自 C++ 世界。“但是 C++ 的泛型糟透了。我们必须把它做对。”

然后问题就来了,什么是“对”的?我跟很多人聊过。编程语言中的泛型,在当时是一个重要的研究领域,但对于何为“良策”,众说纷纭,莫衷一是。

有一派人说:“在我们搞定泛型之前,什么都不该发布。”但很明显,这会耗费我们两三年的时间。如果我们推迟两三年,互联网正在爆发式增长,那可是爆发的极早期阶段。如果我们等上几年把它做好,我们就会错过整个浪潮。如果我随便塞进去一个东西,结果是错的——我估计有 99% 的可能性——那么撤销它将会非常困难。当时有很多面向对象的编程语言没有泛型,它们也运行得很好。

最终,几乎形成了一场关于 Java 泛型应该如何实现的全球竞赛。一个大问题是它如何与内省(introspection)交互。没有人能提出一个可行的方案。这是一个关于所谓“具体化”(reification)的争论。如果我们不惜破坏当时存在的每一个应用程序,我们本可以实现具体化。

主持人:我认为这完全违背了 Java 的哲学。

詹姆斯·高斯林:当你拥有一个庞大的用户社区时,你就肩负着重大的责任,不能把他们搞砸。直到今天,我还会从朋友那里听到:“那是个错误。”而我会说,不,那不是错误,那是一种妥协。

主持人:作为 Java 的创始人和最初的创造者,你当时的工作方式与现在 Java 通过 JEP 和六个月发布周期的演进方式之间,是否存在巨大差异?我猜存在的。

詹姆斯·高斯林:完全不同,天壤之别。在发布之前,我可以在一个下午做出翻天覆地的改动。没什么大不了的,轻而易举。而且我经常这么做。有一天我删掉了 `goto`,因为我实在受够了它的愚蠢。我默认继承了 C 和 C++ 的很多东西,以便让人们感到熟悉。但是 `goto` 是那种会导致各种奇怪边界情况的东西。一个下午,我真的就是不耐烦了,做了一些有限的研究,然后“砰”,它就消失了。那是一段极其奢侈的时光。

硅谷流行着一个令我情感极为复杂的工程原则,你经常从埃隆·马斯克和马克·扎克伯格这样的人口中听到:“快速行动,打破陈规。”当你在构建原型时,我完全赞成。但一旦有了用户,他们依赖你的产品,游戏规则就完全变了。我对“快速行动”本身没意见。

主持人:但不是破坏。

詹姆斯·高斯林:但不是破坏。而且,“快速行动”常常被曲解为随心所欲地做些蠢事,看看人们会怎么抱怨。这对用户体验来说可不妙。

Java 的“一次编写,到处运行”理念依然成立!

主持人:很多人对此感到惊讶:非常古老的 Java 应用程序仍然可以在最新的运行时上运行。这正是整个 Java 体系的强大之处。

詹姆斯·高斯林:很久以前,为了一个演示之类的,我写了一个 Swing 应用来玩纸牌。那个二进制文件我还留着。它是为 Java 6 或 7 之类的版本编写的。我现在仍然会运行它,而且频率高得有点不好意思,因为它就是纸牌游戏。

但关键是,那个二进制文件是大约 20 年前编译的,现在依然运行良好。我在我崭新的 Mac Studio 上玩过它,在程序构建时还不存在的架构和操作系统上。它运行得非常棒,惊人地好。所有的图形动画都如丝般顺滑。

主持人:这就是“一次编写,到处运行”的理念。它从一开始就存在。你认为它现在依然成立吗?

詹姆斯·高斯林:这个理念今天依然非常成立。虽然还称不上完美,但已经非常接近了。

我特别喜欢的一点是,我不需要反复编译同样的代码;也不需要为了适配市面上各种不同类型的设备,去生成二三十个不同的二进制文件。比如我那个纸牌游戏,它生成的 Linux 二进制文件,同一个文件拿到 macOS 上也能直接运行。这种感觉真的很棒。

当然,有时候还是会有些“漏风”的地方,比如你用到了 shell 脚本之类的东西,那就会比较麻烦。但从整体上来说,Java 并不比其他平台更糟糕。真正让人头疼的异类,其实是 Windows。

主持人:为什么这么说?

詹姆斯·高斯林:因为 Windows 和其他系统不太一样。除了 Windows,大多数操作系统都遵循了类似 Unix 的架构。甚至现在 Windows 自己也引入了 Linux 子系统——他们也是被迫这么做的,因为在云环境中使用 Windows 实在太贵了。

主持人:我是树莓派的忠实粉丝,背后就堆了一大堆。

詹姆斯·高斯林:我也有树莓派,如 Jetson Nano。

主持人:这些又便宜又神奇的小板子,是用来做 Java 实验和运行各种 Java 程序的绝佳平台。我有几个 JavaFX 应用,动画效果非常重,但在这些设备上也能跑得很顺畅。

詹姆斯·高斯林:对,这真的很棒。说实话,JavaFX 一直是我最喜欢的技术之一。那个团队干得太出色了——尤其是在 Oracle 基本放手不管之后,他们仍然坚持做出了很多令人惊叹的成果。

主持人:你认为如果 JavaFX 能得到例如 Oracle 更多的青睐,它会有更大的市场份额吗?

詹姆斯·高斯林:我当然曾抱有希望。桌面应用的世界已经变得非常碎片化。我觉得很有意思的是,对于移动设备,基本上有两个基础平台,Android 和 iPhone。它们竭尽所能地想要与众不同,非常喜欢保持各自的独特性。我完全理解这两个阵营为何要这么做。但从我作为开发者的角度来看,这简直太糟糕了。尽管 Android 最初有点像 Java 的东西,但他们完全破坏所有图形和 UI API 的方式简直是……我还是别评价 Android 了,因为它简直……

主持人:我们曾经有过 Java 手机。我想它从未真正上市,但我们是否可能拥有 Android、iOS、Java 手机并存的局面?或者 Java 手机甚至会比其他两者更好?

詹姆斯·高斯林:当然。Java 在 iPhone 上运行得很好。问题在于,从一开始,iPhone 的服务条款就不允许使用 Java 进行部署。所以那些真正想做 Java 应用的人——这也是 JavaFX 团队大显身手的地方之一——他们开发了实质上的静态交叉编译器,可以将 Java 世界的代码编译到 iPhone 的工具链中。然后你就可以发布应用,可以在 iPhone 商店发布 Java 应用,但你必须经历那个疯狂的工具链跳转过程。

主持人:这确实很疯狂。我在这方面做过太多失败的实验了。但是,我们需要做什么才能让 Java 成为移动和嵌入式开发的平台呢?

詹姆斯·高斯林:我认为作为开发者,我们无能为力。

主持人:不行吗?

詹姆斯·高斯林:这需要 Android 阵营和 iPhone 阵营开始以完全不同的方式思考这个世界。而这对我来说似乎不太可能。

主持人:他们是太大的公司在竞争。

詹姆斯·高斯林:“一次编写,到处运行”这个理念,某种程度上源于 Sun 公司。那时在计算机市场上,尤其是在早期,Sun 只是一个小角色。想让开发者为 Sun 的平台写软件非常困难,人们常常会说:“你们的市场份额才这么点儿,而那边那些公司的市场份额那么大。”

是的,为他们的平台开发软件很糟糕,但这不是工程师说了算的,而是业务部门的决策。他们会说:“没错,但如果我们能把软件卖到那个平台上,可能就能多赚五倍、甚至十倍的钱。”

Java 的意义就在于,它让你可以把所有小玩家联合起来。于是,小玩家也能和大玩家站在同一平台上。

如今我们所处的时代,硬件生态系统已经高度整合,远不如过去那样多样。如果你现在买一台笔记本电脑,基本只剩两个选择,或许勉强算上第三个,但那也只是“半个”。

像你我这样的人,会觉得 Linux 笔记本是一个可行的选项。但对 99% 的普通用户来说,根本不会考虑。

主持人:这其实挺奇怪的,因为 Linux 在那些更小、更便宜的电脑上运行得更流畅。

主持人:所以我一直不太明白,为什么学校都迷恋 Chromebook 和 Windows 电脑。明明还有更好的选择,但我觉得这完全是市场营销的力量。他们太擅长营销了。

詹姆斯·高斯林:是啊,这里面确实有市场营销的作用,也有路径依赖的成分。我一直对那些坚持什么都用 Windows 的公司感到沮丧,多半只是因为他们已经习惯了。Windows 长期以来一直存在严重的安全问题,虽然他们现在确实在努力改进,但仍然是所有平台中安全性最差的。

Linux 可能是最安全的,其次是 macOS,或者说是 iOS,在我看来这两个差不多。苹果的优势在于,一旦发现安全漏洞,他们可以在几天之内将修复推送到全球所有设备上。而 Windows 想做到这一点则要困难得多。

主持人:如果我们回到 Linux,你有没有预想到,整个云系统——在你最初设计 Java 时还根本不存在——最后会有很大一部分运行在 Java 上?把它做成一门服务器端语言,是最初的目标之一吗?

詹姆斯·高斯林:没有。你可能不信,第一个 Java 应用服务器是在 1994 年写出来的。所有后来属于 Java EE 核心的 API,实际上很多都起源于那一年。比如 Servlet 类,就是那时候写出来的。一个常被忽略的事实是,我就是写出最初那个Servlet 类的人。那时我只是随便试试,心想:“嘿,这个东西挺好用的。”

但后来事情变得有点不堪回首了。我被告知要把这些东西扔掉,因为 Sun 有一些合作伙伴不希望看到我们在这方面形成竞争。现在回头看,我敢说那已经触犯了《谢尔曼反垄断法》。但确实就是这么回事。

主持人:我觉得没人能预料到后来会演变成今天这个样子。很多人都说:“Java 不适合跑在 Docker 容器里。”但 Docker 在你设计 Java 的时候根本还没出现。

詹姆斯·高斯林:是的,不过如今大家已经找到了很多办法,让 Java 能很好地在 Docker 容器中运行。而且也不仅仅是 Java 在容器里遇到问题——很多语言都有类似的挑战。Java 在 Docker 里的主要问题是启动时间。但其实 Docker 本身也有启动时间的问题,因为它需要先启动 Linux 系统。

他们为加快 Linux 启动所做的优化,和我们为加快 Java 启动所要做的事情几乎是一模一样的。但归根结底,这还是一个工程上的权衡问题。当年我们开始做服务器端应用时,主流的模式是:你启动一个服务器程序,然后就让它长期运行。所以我们会把所有精力集中在长期的高吞吐性能上。而很多能够实现这种性能的优化手段,其实是会牺牲启动速度的。

在很多系统中,你如果想获得更快的启动时间或更一致的响应时间,就得在某种程度上牺牲吞吐量。

就拿最基本的例子来说,比如哈希表。大家都觉得哈希表非常快——确实,在读取数据时,它真的非常快。在写入数据时,它通常也很快。但偶尔,它会变得拥堵,你就得重组哈希表,做一些调整。几乎所有的系统在底层都会有很多小聪明来追求高性能,但它们始终需要不时做一些结构维护的工作,来确保系统稳定。

如果你稍微了解一下 HotSpot,就会发现它简直是工程学上的奇迹。它所做的那些优化,令人叹为观止。即使到今天,我仍然会对它在代码生成方面的表现感到惊讶——它有时候甚至能在某些基准测试中击败 LLVM。

至于垃圾回收器,它的表现已经好得离谱。

主持人:是的,我刚加入 Azul 的时候,最让我惊讶的就是这一点。我当时接到的第一个任务,就是写一篇关于不同垃圾回收器的博客文章。虽然我已经做了十多年 Java 开发了,但从来没有为垃圾回收操过心,因为它总是能“自动”处理好。

但当我写那篇文章,开始和那些亲自实现各种垃圾回收器的人聊之后,我才意识到,这背后有多么复杂的技术体系!有那么多专业知识和工程细节,都是为了让开发者根本不需要去考虑垃圾回收本身。这才是真正了不起的地方。

詹姆斯·高斯林:没错,垃圾回收器令人惊叹的地方正在于此——它既消除了大量复杂性,又容纳了巨大的系统复杂性。

很多人都喜欢 Rust 的内存管理,我自己其实也挺喜欢的。但问题是,一旦你的数据结构变得复杂,比如有很多交叉引用、缓存层级等等,Rust 的模型就会开始变得吃力。而 Java 的垃圾回收器则能把这些复杂的数据结构处理得井井有条,而且运行效率极高。

我现在还会碰到一些人,他们说垃圾回收太慢了,一次回收得几分钟……

拜托,抱歉,几十年来,垃圾回收都不需要几分钟了。

主持人:很多批评 Java 的人,其实是很久以前用过 Java,对后来社区的贡献和这些年版本的改进完全不了解。

詹姆斯·高斯林:时下,一个中规中矩的垃圾回收器都能把最大暂停时间控制在一秒以下。而真正优秀的垃圾回收器,最大暂停时间可以压到 5 到 10 毫秒之间。

当然了,之所以存在多种不同的垃圾回收器,正是因为它们在吞吐量和延迟之间做出了不同的权衡。如果你想让系统负载更低,那就得接受响应时间可能会更不平稳。就像我们刚才说的哈希表例子一样——你想让它“超级快”,那就得接受偶尔会有性能波动。你可以通过各种算法来平滑这些波动,但无法真正消除它们。

不过也有一些回收器,能做到完全没有性能抖动,但代价就是吞吐量会被拉下来。

三十年前,如果你想获得一致的响应时间或低延迟,代价可能是 30% 的吞吐量损失。而现在,如果你要实现非常低的延迟,吞吐量的牺牲只需要 1%-2%。

垃圾回收是计算机领域里最不显眼、但也是最精彩的技术之一。当你开始读关于垃圾回收的学术论文时——我的天啊,那真是一个奇妙纷呈的世界。

主持人:而且令人惊奇的是,尽管系统变得越来越大,使用的内存越来越多,它们却改进了这么多。

詹姆斯·高斯林:另一方面,我们也有了更多的 CPU 作为底层支撑,所以所有这些东西的进化速度真是惊人。这在某种程度上也是 Java 在嵌入式系统上运行时偏离初衷的地方。在服务器世界,没有哪个系统会只有 1G 内存。如果你买一台新的树莓派,通常有 8 到 16G 内存。我面前这台新的台式电脑有 256G 内存。

当然,所有这些内存都是为了施展一些能让程序运行更快的技巧。如果你想适应小内存环境,有些事情你就做不了,因为你没有足够的空间。同时,大量的内存也可以掩盖某些工程上的草率。

詹姆斯·高斯林:几年前我做的一个项目中,最让我头疼的问题是它占用了大量内存。深入调查后我们发现,虽然表面上看起来是 Java 虚拟机占了很多内存,但其实真正消耗内存的是那些引入的库。Java 生态系统的一大乐趣在于,几乎所有东西都有丰富的选择。但这也是最大的痛苦之一。

我最讨厌的东西之一是 HTTP。在我们分析的那个应用里,竟然出现了五个完整的 HTTP 栈。首先是 JVM 自带的 HTTP 栈;然后是 AWS 的库——出于我不理解的原因,他们觉得需要定制一个专用的 HTTP 栈;再是谷歌的库——只要你用到任何一个谷歌库,它就会把整个“谷歌宇宙”的依赖闭包一股脑儿地带进来,其中也包括谷歌的 HTTP 栈;另外,只要你用了任何 Apache 的库,Apache 也有自己的 HTTP 栈。对这些组织来说,自己造一个 HTTP 栈通常比去协调一个所有人都能接受的通用方案来得容易多了。虽然我们完全可以做到后者,但现实就是这样——“快速行动,打破陈规”。

主持人:但这也是开发者的责任。我参与过一些项目,里面竟然用了三个不同的 XML 库。

詹姆斯·高斯林:是的,这种情况太常见了。还有 JSON 库也是这样。幸运的是,在 JSON 的世界里,Jackson 很早就脱颖而出,而且几乎彻底占据了主导地位。当然,Jackson 其实还分两个版本:标准版和 Jackson Jr.。标准版功能更多,速度也更快,这是有原因的,但它也大得多。而 Jackson Jr. 更轻量,我更喜欢它,因为我对内存使用特别敏感,喜欢精打细算、按字节来衡量。

不过在那个充满各种 HTTP 栈的项目里,我们最后还是用了两个版本的 Jackson。因为我倾向于只用 Jackson Jr.,但其他人很喜欢完整版的功能。我其实也喜欢 Jackson 的那些强大功能,只是我在“字节计较”这件事上非常顽固。

你看着这些东西运行,尤其是像 JSON 这种场景——说到底,对于生成 JSON,你甚至连 printf 就够了。我还挺喜欢那种直接用 printf 生成 JSON 的方式,虽然我知道这会让我的不少同事感到非常不安。

谈 Java 与其他编程语言之争

主持人:你刚才简单提到了 Rust 作为 Java 的竞争对手。但我们如果把视角从语言扩展到整个 JVM 生态,你怎么看那些构建在 JVM 之上的语言?因为我们一直在讨论 Java 作为一门语言,但它其实是语言和运行时环境(JVM)的一体组合。而像 Kotlin、Scala、Clojure 这些语言,其实都是运行在同一个虚拟机上的。你如何看待这种演变?

詹姆斯·高斯林:我觉得这些语言都很酷,我也很喜欢它们。Scala 是我早期就非常欣赏的一个成功案例。但说实话,它还没吸引到我让我愿意放下手头正在做的事。我并不是那种会迅速跟风尝鲜的人。我就是个穿着 T 恤和牛仔裤干活的普通程序员。

Clojure 也很酷——如果按“酷炫指数”来说,我非常喜欢它。但 Clojure 的问题在于,它和大多数人的思维方式太不一样了。它采用 Lisp 风格的语法,而且对编程有一种非常极致的函数式理解。我自己其实是函数式编程的忠实粉丝。

不过,函数式编程风格在某些地方很适用,在另一些地方就未必了。我在写 Java 代码时也经常采用函数式的方式,这是我做的另一件会让其他工程师崩溃的事(笑)。比如,我宁愿用递归,也不愿用数组。但这只是我个人的偏好而已。

主持人:一个完全不同的话题。我在你 LinkedIn 的一条消息中看到,你也要求人们思考自己的工作及其责任。如果你在一家公司担任程序员,被要求做一些你认为邪恶的事情,比如奇怪的营销技巧之类的。作为开发者,我们对如何使用我们的工具和开发者能力负有多大责任?

詹姆斯·高斯林:我一直坚信,如果你的公司要求你做一些不道德的事,你应该直接走人。

当然,首先你也可以和他们谈一谈:“你们真的想这么做吗?你们真的理解这么做的后果吗?”有时候,你可能会让他们意识到:“哦,你说得对,我们不该这样对待客户。我们确实没考虑到长期影响。”但更多的时候,他们只会说:“哦,是的,没事的。”

你会遇到一些曾在医保公司工作过的人,听到他们讲的一些故事真的让人震惊,比如:“他们居然会那样做?”

这其实也和现实情况有关。如果是在就业机会很多的时候——软件工程师过去就经常处在这种环境下——那么说走就走也很容易。

主持人:没错,的确如此。

詹姆斯·高斯林:现在就不一样了。现在的就业市场非常非常艰难,尤其是在美国。美国现在简直就是一团糟。

我在 LinkedIn 上写的那篇文章,谈的是“叫板的底气钱”(fuck you money)这个概念——这个词其实已经存在几个世纪了。意思是说:你是否有足够的积蓄,能在必要的时候对雇主说“去你的”,然后直接走人?如果你没有这份底气钱,你在某种程度上就成了奴隶。

而“奴役”也可以以别的形式存在。比如说,如果你是一个家长,孩子又有严重的健康问题,那么考虑到美国医疗体系的运作方式,一旦你离职,可能就会影响到孩子的治疗和健康。从雇主的角度看,这反倒成了美国糟糕医疗体系的一种“优势”——它让员工在某种程度上被绑定在公司里。这也许在技术上算不上真正的奴役,但感觉真的非常接近了。

主持人:随着人工智能带来的全面竞争,选择会不会变得更加艰难?对于很多总监、工程师、很多老板来说,他们认为他们不再需要软件开发者了。

詹姆斯·高斯林:我认为他们是在自欺欺人。而且我觉得,有些情况简直近乎滑稽。一些人工智能领域的人,比如 OpenAI 这样的公司一直在说:“啊,你不需要文案撰稿人了,你不需要这个那个了,因为人工智能可以做所有事情。”但现实是,AI 目前能做的事情非常有限,效果也往往不如人意。

比如有家律所尝试用 AI 来撰写法律文书,结果文书看起来像那么回事,但内容完全是胡扯,最后还因此受到了处罚。这类例子比比皆是。

但软件工程又不太一样。它有一个独特的特性,就是我们有“库”这个概念。如果某件事你做过一次,下次你很可能就会把它封装成一个库,以后复用。很多人用的东西还会变成开源库。换句话说,开发者并不总是在重复造轮子,除非你还在学习阶段。

AI 工具,尤其是像 ChatGPT 这样的生成式系统,本质上是基于大量已有代码训练的,它们在“插值”方面表现不错——也就是在已有知识的基础上做填充和改写。但这并不是软件开发的难点。

真正有挑战的是“外推”——也就是解决那些没人遇到过的新问题。软件工程的乐趣正是你经常在做全新的东西,而不是一遍遍复制已有的方案。

我喜欢拿土木工程打比方:你建一座桥要花很多精力,但建下一座桥、再下一座桥,成本都很高。而在软件工程里,一旦你写好了一个模块,复制它几乎是免费的。这种“从零到一”的创造,是 AI 目前很难替代的。

我看到的像 ChatGPT 这样的工具的用途,主要是在学习方面。我发现自己把它当作一种自动化的帮助系统。就像,“我该如何写一段代码来连接这个和那个?”它有一定的准确率。

主持人:你对初级程序员有什么建议吗?如果他们遇到糟糕的经理,如果他们必须选择一门语言。你对新手有什么好的建议吗?

詹姆斯·高斯林:当你乐在其中时,事情总是更容易。我一直发现,如果我从事的是我真正着迷的项目,我会做得更好。

软件工程的一个好处是,软件是一种工具,它被用于许多不同的行业。所以我更倾向于根据项目所处的环境来选择工作。

我有点像个太空迷,我非常喜欢航海、船只之类的东西,而且我有幸从事过一些让我能接触到很多这些事物的工作。当我有幸能够真正选择工作时——我的数学还没好到能成为一名物理学家,但我可以为物理学家工作,并且过得很开心。如果你足够幸运,并且能找到适合你的那种环境。当就业市场像现在这样紧张时,就有点像“乞丐没得挑”。然后通常就只能忍气吞声,做你需要做的事情,然后等待更好的时机。

主持人:如果回顾你开始 Java 的这 30 年,你能指出几个重要的时刻吗?可能有很多,但你能挑几个吗?

詹姆斯·高斯林:有几个“显而易见”的关键时刻。比如 Java 的正式发布,再比如我们当时跟网景(Netscape)那种疯狂的合作关系,还有与整个行业中其他势力之间的一些微妙互动。

我们也因为没有更早地开源而受到不少批评。其实从一开始我们就提供了源代码,但用的不是开源社区真正推崇的那种许可证。这里面牵涉很多复杂的问题,但从我们的角度来说,最大的担忧是:当时有好几家非常强劲的竞争对手,他们几乎是铁了心要“干掉我们”。如果我们早早使用一个完全开放的许可证,那无异于把武器递到对手手里,简直像是发了一张“开火许可证”。

我们当时预估,大概有五六家公司在盯着我们,只等我们一开放代码,就要把我们碾碎。所以我们处在一个非常矛盾的局面里:理智上知道开源可能对发展更有利,但情势又逼着我们不得不防守。这不是个容易做的决定。

主持人:听起来那时候也有很多“戏剧性”的瞬间?

詹姆斯·高斯林:有的,甚至可以说比电视里的剧情还精彩。比如,有一次我们正与 ECMA(欧洲计算机制造商协会)谈判,想把 Java 纳入为他们的一个标准。当时的气氛看起来很顺利,大家在技术细节上已经基本达成一致。

但我们不知道的是,有三家大型公司(我就不点名了,你大概也能猜到是哪几家)一直在暗中跟 ECMA 协调。等我们准备好召开一次会议、敲定标准时,ECMA 的代表突然变脸——就在前一天晚上我们还一起吃饭、意见完全一致——却在会上宣布:新计划是把 Java 分成三部分,语言、虚拟机和标准库,每一部分由那三家公司中的一家负责,而 Sun 公司将不再在标准制定中拥有任何正式地位。

换句话说,那三家公司将分别掌控 Java 的三大核心组成,而我们这个发明者彻底被排除在外。这对我们来说简直是晴天霹雳。

更关键的是,Java 是一个生态系统,不是几段独立的代码拼凑起来的东西。每一个部分都会影响其他所有部分。很多年里,人们都在问我一个问题:“为什么你不做 Java 的终身‘仁慈独裁者’(benevolent dictator for life)呢?”

说实话,我很清楚那种角色会让我这辈子做不了别的事情。而对我而言,真正重要的是,那些每天用 Java 写代码的人也有他们自己的关切和声音。我一直希望他们的声音能被听见,因为只有真正理解开发者的需求,才能设计出他们愿意用的工具。这也是为什么后来我们创建了“Java 社区流程”(JCP)。

它当然不完美,有时候你得在会议室里跟一群人拉锯、辩论,过程挺烦的。但这比独裁式的决策强太多了。就像那句老话说的:“民主是最糟糕的制度——除了所有其他制度之外。”这话也同样适用于 Java 社区的发展。

主持人:Java 目前的运作机制是否良好?它现在的发布节奏靠谱吗?你觉得它未来 30 年会朝着正确方向发展吗?

詹姆斯·高斯林:我其实一直对它运转得这么好感到有些惊讶。

主持人:你是指六个月发布一次的节奏运作得不错?

詹姆斯·高斯林:其实我并不觉得六个月的发布周期带来了什么本质变化。在这之前,Java 是三年左右发布一个大版本,但在这三年之间,也会不断推出构建版本(builds),很多人,包括我自己,其实都在使用这些中间版本。而这些构建版本通常也都非常稳定。

主持人:像现在我们在两个长期支持版本(LTS)之间,也会用 23、24 这样的常规版本。

詹姆斯·高斯林:对,是这样。现在是每六个月发布一次版本,而 LTS 版本是每两年发布一次,对吧?

主持人:对的,是每两年一个 LTS。

詹姆斯·高斯林:这的确让整个节奏更具可预测性了。

不过我对现在的机制还是有些小抱怨,比如现在引入了很多“预览功能”(preview features)。有些功能一预览就是好几年,始终没有变成正式特性。以前在三年一个大版本的节奏里,大家会在周期一开始提出复杂的新功能,然后经历一系列小版本试验,等最终发布大版本时,这些功能要么就成熟了,要么就被砍了。预览状态不会持续太久。

但现在我发现自己经常在用那些仍处于预览状态的功能。一方面,这挺好,因为很多有趣的特性现在都以预览方式提供;但另一方面也挺烦,因为你永远不知道它们什么时候会变成正式的,甚至会不会被彻底放弃。而且现在,即便是 LTS 版本,也可能带着未成熟的预览功能发布,这让我有点不太舒服。

虽然大多数预览功能最终都会稳定下来,但也有些特性到最后被直接推翻了。比如有一个叫“dot double quote”的语法(点双引号),我当时特别喜欢,还用得挺多,但后来它被彻底移除了。我当时一想,天哪……这下完了。我现在想用最新版的 JVM 都不行,除非重写那部分代码,改动还挺大。

当然啦,布莱恩·戈茨(Brian Goetz)说这东西不该保留,他通常都是对的(笑)。

主持人:你现在还参与讨论吗?

詹姆斯·高斯林:有时候会。

主持人:你正式退休了吗?

詹姆斯·高斯林:我现在正式退休了,无业游民一个。除了我妻子,谁的话我都不用听。

主持人:那么 Java 对你来说,如今还占据多大的分量呢?

詹姆斯·高斯林:其实不多了。我离开 Java 组织已经 15 年了。现在照管它的人们,我非常尊敬他们,他们非常出色。而且社区也在约束着他们,这很棒。我通常不是那种喜欢到处对人大喊大叫的人。

主持人:在结束这次访谈之前,你对 Java 社区有什么最后的话想说吗?

詹姆斯·高斯林:保持开心!继续创造!

原播客链接:https://www.youtube.com/watch?v=6iP376VwcjY

📢 2025 全球产品经理大会

2025 年 8 月 15–16 日

北京·威斯汀酒店

2025 全球产品经理大会将汇聚互联网大厂、AI 创业公司、ToB/ToC 实战一线的产品人,围绕产品设计、用户体验、增长运营、智能落地等核心议题,展开 12 大专题分享,洞察趋势、拆解路径、对话未来。

来源:CSDN一点号

相关推荐