编者按:
如果你是一个 Java 开发者,那你想必读过或至少听过《Java 编程思想》(Thinking in Java)这本书。这是一本所有 Java 学习者都无法避开的经典之作,也是 Bruce Eckel 的代表作。从 1998 年第一版出版至今,《Java 编程思想》已经被翻译成十几种语言,受到全世界程序员的广泛关注。
近日,Bruce Eckel 的又一力作《On Java 中文版》在中国上市,InfoQ 借此机会专访了这位编程大师(在此由衷感谢图灵出版社的引荐)。
在交流的过程中,Bruce 给笔者的感觉有点像他写的书,友好、耐心且极具亲和力,我们提出的几乎所有问题,他都一一作了解答。
对于写技术书籍这件事,Bruce 不是在一开始就明确规划好了所谓的“职业发展路线”,最初只是喜欢写作,不断地写,然后写作这个事碰巧但又自然而然地跟他的技术背景结合到了一起。谁都没有想到他能在这条路上获得成功,包括他的父亲。在他刚刚开始写书的时候,他的父亲一度非常怀疑他是否真能以写书为生。
虽然 Bruce 累计已经出版了十余本经典计算机著作,其中不乏像《Java 编程思想》样畅销全球的书籍,但至今让他印象最深刻、最有成就感的还是他自费出版的第一本书。
对于编程语言,Bruce 涉猎颇广。除了 Java,Bruce 对 C、C++、Python 、Kotlin 、Go 等也十分擅长,他是 C++ 标准委员会的创始成员之一,大家耳熟能详的“人生苦短,用 Python!”正是出自他口,虽然他已经想不起来自己当初是怎么想到这句话的。直到现在,Bruce 还会将日常大部分时间花在学习新语言和老语言的新特性上,不过他“只在灵感出现的时候才工作”。
众多编程语言中,Bruce 最喜欢 Kotlin 和 Python。他现在仍然认为 Kotlin 很有希望成为 Java 的下一个继承者,虽然现在很多程序员还没用上 Kotlin,但“只要越来越多的人在学、在用 Kotlin,它就一定能成长为人们期待的样子。”
Bruce 爱好广泛,写书、写博客、录制播客、经营自己的 Twitter,虽年近古稀,但依然活跃在各种技术交流的峰会上。在他眼里,计算机技术和 IT 行业相对于它的发展方向来说,还非常年轻,“如果非要说编程有黄金时代,那它永远都在未来”。
在对话的最后,Bruce 还聊到了中国开发者最关心的话题 996。Bruce 强烈反对 996,他认为 12 小时工作制不适合编程这种创造性工作,“没几个人能每天编 12 个小时的程”。Bruce 认为自己的观点可能会引发争议,让我们酌情删减,但我们觉得,中国开发者应该会喜欢他的观点。
以下为访谈实录:
Bruce:其实我一直在断断续续保持写作。我的写作习惯大概是 12 岁左右养成的,但那时候只是写着玩。我有个朋友是作家,他现在在写小说。高中的时候,我们都参与过办校报之类的活动,兴趣就是这么培养起来的。所以刚上大学的时候,我选的是新闻专业,之后转修物理,但一直没丢掉写作的习惯。毕业之后几年,我找到一家自己喜欢的杂志。我参加了他们办的一场会,写了篇文章,对方觉得不错、还想要我多投几篇。事情就这么开始了,最终这些文章被汇总成一本书,我自己把它给出版了。这就是我人生中的第一本书。
反正我的写作生涯差不多就是这个样子,要说动机的话,我其实一直想成为一名顾问。我觉得写作是推销自己咨询能力的好办法,大概就是这样。当然现在我知道了,想当顾问,最好的办法是跟当过顾问的人多聊聊、向他们学习。这肯定是更简单、更直接的方式。但无论如何,我还是很喜欢写书。可能这才是最真实的答案:我就是喜欢。
Bruce:不是,刚开始是写纯新闻类的文章。我后来才开始学习技术,毕竟我的硕士学位是计算机工程嘛。但千万别误会,我并没有做过明确的规划,像是先学新闻学、再接触技术领域,最后把二者整合起来。不是那样的,我只是一直对写作感兴趣,然后不断地写,最终碰巧跟自己的技术背景呼应上了。
在写了点技术文章后,我发现这方面需求还挺大。如果写的是小说,可能永远都没有出版的机会了。我觉得把写作跟编程技术联系起来挺不错的,因为大多数人都是做技术、而不是写技术,所以这片空间里没什么竞争。
Bruce:我是高二的时候第一次接触编程的,带我入门的是位数学老师。很偶然的机会,他弄来一台电脑终端,就是那种很旧的 ASR 33 电传打字机,带推杆、打孔带和磁鼓,里面还内置了 110 波特率的调制解调器。只要接上电话线,它就能嘎嘎作响、连入网络。这就是我跟计算机的第一次接触,真的让我着迷。后来我几经波折,好不容易才又把这种感觉找回来。
在大学我学的是物理,所以当时最早接触的语言除了 BASIC,就是物理学领域常用的 APL。后来读研究生的时候,我在环境实验室工作,用的是 Apple 版的 BASIC。
事后来看,计算机工程的硕士最容易毕业,但当时我接触了各种各样的工程专业,只要有课我就去听。那时候我不想去上班,所以选择了继续上学。后来还读博了,但好在“悬崖勒马”,没有真的读下去。
虽然没读博,但我还是不想工作,每天搞东搞西的。那时候我挺浮躁的,年轻嘛。后来我做过几份工作,主要都是用的低级语言(Low-level Programming Language)。当年的编程工作都挺硬核的。
后来我在华盛顿大学海洋学院找到一份工作,带我的教授想用面向对象语言帮助其他科学家轻松进行科学编程。我们先研究了 Objective-C,后来又了解了 C++,最终决定用 C++,算是用的相当早的了。当时唯一的 C++ 工具就是 Bjarne Stroustrup 他们团队创建的,可以用来把 C++ 代码转换成 C 代码。
这时候,我的物理学背景又帮上了忙。虽然我本身的物理水平不是很高,但却在学习过程中习惯了把自己反复投入同一个问题的感觉。也可以说,我在尝试解决问题时有种韧劲。这也是物理学带给我的最大价值所在。那时候大家都不太了解 C++,但我还是义无反顾投身进去,观察输出来理解代码到底在做什么,通过这种方式慢慢理解了虚函数的运作原理。
最终,我参加了几次 C++ 会议,跟 Bjarne Stroustrup 有了近距离接触。后来我搬去东海岸,当时他们正好在为 C++ 标准委员会召开初期组织会议,我受邀加入了委员会。Stroustrup 应该是看中了我当时已经出的书,觉得我比较适合在委员会中扮演解释者的角色。
杂志封面旧照
(来自:https://www.mindviewllc.com/about/)
在加入委员会的头八年里,我一直就是个普通委员,情况到初步标准发布才有了变化。对我来说,那时候加入委员会跟读研究生没什么区别,就是每天和那些最聪明的人打交道。如果被某个难题卡住了,也可以随时找他们解决。我觉得这比研究生院还要好,毕竟没有哪个学校的学生能有这么强的整体水平。之后写的文章多了、见报的频率高了,就有人邀请我到会议上去发言,之后就慢慢变成现在这样子了。
Bruce:随着对概念的理解越来越深入,编程语言的学习难度也会下降。比如在掌握了函数式编程概念之后,所有函数式语言都会变得非常相似,理解起来也没什么障碍。这跟自然语言不一样,自然语言的发展周期漫长,往往包含大量奇奇怪怪的固定用法。但编程语言有倾向性,只要结合工作环境就应该容易理解。
很多朋友只学过一种编程语言,所以会有点畏难情绪。但稍微接触点其他语言,就会发现没那么可怕。
Bruce:我的日常安排啊?就是工作喽。只要有想法,我就会努力实现,我希望自己最终发布的都是自己最满意的成果。所以我只在灵感出现的时候才工作,昨天就啥也没干。其实这种情况挺罕见的,一般我每天都多少要做点事情。
目前我在做一个关于并发的新项目,满脑子想的都是这件事,有点无暇他顾了。比如说并发问题,就算是使用协同程序,最终也还是要由线程进行驱动,而线程又要由操作系统提供。那它们是如何工作的?执行过程中发生了什么?我没见过哪本谈计算并发的书会讲得这么细,所以我觉得不妨对具体机制做出一番推理,这就是我眼下的工作。
而且这个话题必须从头到尾讨论清楚,毕竟并发和线程理解起来不太容易,作者得真正理解其中的每个部件如何啮合、整台“机器”怎样运转。操作系统是怎么实现并发的?答案是在运行时,操作系统会提供一个线程。那如果 JVM 之类的上下文发生切换时,操作系统又是怎么意识到这种切换的?因为会有几 MB 大小的信息交换。那信息具体是怎么交换的,又被交换去了哪里?这些都是我需要回答的问题,我也不知道要花多长时间才能全部搞清楚。
但非要说日常安排,其实没有那种很明确的时间表,毕竟点子不是说有就有的。
Bruce:当然,我大部分时间都在学习新的语言和关于老语言的新特性。我一直很关注每种新兴语言,新语言总能带来一些新风格,当初的 Kotlin 就是。我会花点时间了解了解,让新语言扩展自己的思维。这样再看回原先的那些语言时,我们也能获得不同的审视角度。这就是我学习新语言的动机之一。
我们正努力在 Scala 上开发一个新的库,名叫 ZIO。ZIO 库很棒,但我还不知道该怎么准确描述。有点像函数式编程,但我暂时还说不太清楚。可能中国的朋友很难理解,我们那边每个镇子很小,大概也就一、两千人。但幸运的是,这么有限的人口基数,还是让我找到了两位伙伴,大家一起参与项目。这真的很不容易。
Bruce:我觉得不能说是必须的吧。我知道很多人在大学里学了相关专业,但从来不额外买技术书籍。他们从来不参加会议,也从来不关心行业活动。这肯定是真的,否则行业活动的规模绝对要比现在大得多。因为他们根本不参加,所以我也没法跟他们互动。但我个人觉得,想在技术领域长久发展下去,就得想尽一切办法让自己不断学习。
当然,这只能代表我自己的判断。但我实在无法想象,如果大家对技术压根就没有好奇心,那干嘛要进入这个领域。不过事实证明,大多数人确实没有好奇心,也不想学习新事物。这没问题,毕竟我不了解人家的经历、没法代表他们发言,但我个人认为社区真的很重要。我喜欢在会议上发言。只要前往参会,我大概率是要做演讲的,我也很享受这种感觉。
对我来说,无论是写作、演讲还是研讨,包括写博文或者录制播客,都是件让人快乐的事情。这些都是我好奇心的一种体现。之所以要开播客,就是为了跟人对话,通过交谈了解大家的所想所感。很多朋友发现在播客上聊天还挺舒服的,我们也一直努力让大家能够轻松享受在播客上讨论问题的乐趣。
我就是这样一个人,会从读者、听众或者参会者的角度看待自己搞的活动,希望能让大家在舒适的氛围中交流。如果单纯是为了让自己发展得更好,我可能会选择其他一些效率更高的办法。但对我来说,愉悦的过程比成功的结果更重要,这种能帮到他人的感觉激发了我努力工作的斗志。
Bruce:其实不是,那本书被翻译成多国语言,但我其实一直没怎么太留意。我脑海里一下子想到的,是我出版的第一本书(“Computer Interfacing with Pascal & C”),而且因为觉得出版社都不感兴趣,所以我是自己出版的。这本书其实是我为杂志撰写的文章集,是非常让我有成就感的一本书。毕竟这事从头到尾基本都是我自己做的,往来奔走,所以如果你问我,我出版过的哪本书最让我有成就感,我会说是这本。当然,图灵出版社是非常好的合作伙伴,能跟他们合作出版后来这些书并取得一些成就,我也特别开心。
总之,能亲手出版自己的书真的很棒。
Bruce:其实一直以来我自己都没太留意得奖这件事,《Thinking in C++》得奖了,《Thinking in Java》也得奖了。呃……要不我从后一个问题开始回答吧。
先要了解读者,之后才能写好一本书。特别是,千万别随便介绍那些前面没具体解释过的东西。所以,我在《Thinking in Java》中用了很多篇章的铺垫,才正式转入“hello world”。Java 中的“hello world”其实很有说道,要涉及类、要涉及静态,涉及不同的关键字。在看其他书时,我觉得最难受的就是很多作者太着急了,忙着切入正题。那种感觉就像“我知道你现在还看不懂,没关系。” 但问题是,原理都还不懂,切入实例有什么意义呢?早早就展示应用,只会让初学者摸不着头脑。所以我在这方面非常小心。我觉得自己最用心的地方,就是在《Thinking in C++》和《Thinking in Java》正式定稿之前,花了 5 天时间搜集研讨材料。
在研讨过程中,我会得到很多反馈,而且大家常常要求把某个概念具体解释清楚。我觉得这很重要。如果大家的反馈不好,那肯定就是我们自己的问题。所以如果书对读者有用,那就足够说明一切了;如果没什么用,那肯定是作者没做好。其实这两本书有点“名不副实”,特别是 Java 那本,并不是写给初学者看的。但多年以来,很多人都说这就是他们的第一本编程书。呃,虽然他们并不是我当初写作时的预期受众,但这样也挺好。总之,我一直小心翼翼、不敢随便抛出之前没充分讲解过的概念,可能就是这一点让大家觉得我的书适合拿来入门。
当初我在写这些书的时候,很多人提醒我市面上类似的书已经有几百本了,何必再折腾呢?但从舆论上看,我发现读者们还是在期待一本真正优秀的编程语言书籍。很遗憾,我没法一一跟他们交流,了解他们到底对之前那些书有什么不满、或者对内容有哪些新的想法。总之,哪怕有再多反对的声音,只要读者还不满意,那就值得再出一本更好的书。
Bruce:简单来讲,最大的不同应该是在函数式编程上。Java 不属于函数式编程语言,但 Java 8 新增了很多这方面的支持。当然还有其他新增特性,我这里只是以函数式编程为例,Java 8 加入了 lambdas 和 streams 等函数式编程原语。这改变了代码的编写方式,增加了可写的代码种类。而在介绍了这一变化之后,我就会在新书的后续部分用到这个特性。
当然,之后的新版本又增加了其他特性,但在重要性方面还是不如 Java 8 中的函数式编程。
Bruce:我其实尽力尝试了把例子弄得简洁一点。但读者们可能是对的,还有空间做得更简洁。不过,身为作者,我首先得保证代码例子能够正常运行,之后再想办法弄得简单些。所以当时我定的目标不高,只要示例不超过一页也就可以了。毕竟示例这东西本来读着就累,如果还要翻来翻去,那就太影响阅读感受了。
我也试过让示例再短些,但我坚持认为应该把示例的输出结果也一并写出,这样读者不用亲自尝试就能知道运行结果。这样示例看起来会更长,但我认为这一点非常重要,我自己也实际运行过,确认结果准确无误。所以对于这本书中的示例,大家看到的是包含输出结果的完整示例。
我也看过那种只列出代码片段的书,但那种书才是真的看不下去。因为只有片段,读者根本没法通过运行来验证结果。所以我有个原则:必须给出完整的示例。另外,示例开头就是下载链接,大家可以下载后自行验证。再加上输出结果,看起来示例自然就有点长。但我觉得这些都是有意义的。虽然我也会努力控制代码长度,而且肯定还有改进空间,但这是权衡后的结果。短示例有短示例的好处,比如更容易理解,这是个取向问题。
Bruce:最近我正好在做这方面工作,也对 Smalltalk 有了更深的理解,这也是对 Java 影响最大的要素。Java 最初在设计上就想基于 Smalltalk,相当于是针对 C++ 采取的行动。James Gosling 和创始团队的成员们当初是想这么干的,因为他们其实是想给电视盒开发一种简单语言。但最终,他们创造出了一种编程语言。对于电视盒子这种东西,用 C++ 做开发是最符合逻辑的,但他们不喜欢 C++,所以决定搞个新语言出来。但他们不熟悉电视盒子,所以失败了……但这种失败反而孕育出了成功的 Java。
但不管怎么样,Gosling 他们多少还是受到了 Smalltalk 的影响。因此,他们想要给 Smalltalk 设计出一种继承语言,延续 Samlltalk、一切都作为对象。但后来人们意识到,强制把一切都视为对象会产生很多不必要的麻烦,特别是大大提高了实现函数式编程的难度。但就 Java 而言,我觉得它最大的里程碑、或者说给整个编程世界带来的最大变化,在于虚拟机概念的确立。在此之前当然也有虚拟机,是由加州大学圣迭戈分校搞出来的 UCSDP 系统。
有意思的是,其实我去过那所学校。因为我有个朋友,他兄弟有门路能让我们混进去。我们可以在那边的机房里玩游戏,在那我接触到了人生中体量最大的计算机。这台机器无比强大。总之,那所高校在虚拟机和垃圾回收器方面很有经验,但当时的处理器性能还很差,没法真正实现。所以大家总觉得虚拟机和垃圾回收器永远不会有真正的意义,而 Java 向人们证明,这些可以实现而且非常有用。另外,Java 还树立了统一的概念,设计了一种统一的错误报告机制。之前 C++ 也有异常提示,但都属于可选项。Java 则强调,异常总会出现,应该把异常视为解决错误的标准方法、而非众多方法中的一种。但我不是说 C++ 就不好,毕竟它的很多问题源自必须向下兼容 C,但这也是 C++ 获得成功的前提。它的设计其实不差,只是需要戴上一副厚重的镣铐。就是为了向下兼容 C,C++ 的问题才这么多。
当然,还有操作符重载,这也是个大麻烦。C++ 之所以难用,就是因为对象可以在栈上、也可以在堆上。这就要求开发者编写重载,让对象自行分配。一旦涉及编写重载,就得同时考虑堆和栈两种情况,这很不容易。但现在有了垃圾回收器再加上引用,操作符重载就变得很简单了。Python、Kotlin 和 Scala 都有这种设计,编写操作符重载根本不是问题。其中 Scala 是个特例,因为这是一种实验性语言,所以允许开发者编写任意长度的操作符,后果大家都看到了。所以 Kotlin 又做了调整,它提供的是一组内置操作符。开发者可以随意重载这些操作符,但不能组成新的操作符,否则太难掌握了。
再下一个里程碑更具份量,那就是泛型的引入。在 Go 和 Java 的发展历程中,如果都从一开始就引入泛型,那它们的最终面貌肯定不是我们现在看到的样子。不过这一切的起点都源自 Bill Joy。我有个朋友在文章里聊过 Bill Joy,他是 Sun Microsystems(Java 最初就是在 Sun 诞生的)的创始人之一。Joy 当初就提醒过 Gosling,一定要在一开始就认真考虑引入泛型。但 Gosling 说时间太紧了,我们做不到。所以大家决定稍后再引入泛型。总有人说“要学会做减法”,但一味做减法可未必就是什么好主意。不过他们当时确实也没什么选择余地,只能暂时放弃引入泛型的想法。
在泛型之后,下一个重要里程碑就是 Java 8 支持的函数式编程了。
我不记得 Record 类型是什么时候引入的了,但我经常会演示 Record。虽然它看起来只是个帮助生成代码的编译器,但因为它允许开发者创建类型,所以重要性一下子就上去了。用不着再做什么类型检查,只要创建一个只具有其创建过程的类型,就能保证该类型为正确的值。通过这种方式,我们再也不用浪费时间考虑类型跟值到底对不对得上。所以我觉得 Record 虽然听起来没那么光鲜亮丽,但还是对编程产生了深远的影响,所以也可以算作另一个里程碑。
Bruce:其实 Java 和 C++ 有同样的问题,就是必须实现向下兼容。C++ 必须跟 C 兼容,这就限制了 C++ 的功能设计。毕竟 C++ 背负着沉重的历史包袱,所以 C++ 能做到今天这样已经很不容易了,可以随意添加新功能,只是在速度上没法跟那些新生代编程语言相比。Java 目前最重要的项目或者说最吸引我的,就是协程项目 Loom。现在很多其他语言中都出现了类似的设计,也让并发成为 Java 语言的一大优势所在。
我也不确定 Loom 最终会是什么样子,但应该跟某些协程版本大差不差。他们把 Loom 称为虚拟线程,其实就是给协程换了个称呼。不管具体为什么改名字,反正协程功能的增强对 Java 肯定是有好处的。
另外,听说 Loom 也会加入 JVM,所以后续也会给其他基于 JVM 的语言提供助力。我很高兴看到 Java 家族越来越好,毕竟相当一部分开发者已经习惯于用 Java 做开发且难以自拔,很多企业也已经无法彻底摆脱 Java 开发生态了。所以 Java 越强大,对大家就越有利。
Bruce:我的理解是,相当一部分企业其实还在往 Java 8 之类相对高级的语言迁移呢。而且在我看来,Java 18 毕竟还不是长期版本。它更多还是个实验版本,所以我也觉得大家没必要太关注中间版本,重视长期版本就可以。
像我这样的开发者可能更关注新技术,想要用到最新、最好、最先进的版本,从中学习新的功能特性。但从企业的角度来看,语言版本变更其实既困难又充满挑战,这类工作可不是说做就能做的。所以他们自然比较消极,毕竟经营企业才是第一要务。他们没有必要紧跟新的语言功能,只要原先的版本还能用就足够了。我想说的是,任何一家企业在做语言版本变更时,他们需要是真的遇到了痛点,而且他们还得证明新版本或者新语言真的就能搞定之前解决不了的问题,这样才能说服他们采取行动。
没错,有前瞻性的企业会意识到,紧跟语言、版本和时代的步伐能让自己受益。但大多数情况下,决策者并不一定是技术人员,所以他们不想没事找事。他们只想让企业平稳运营,不出事就是最好的事。虽然我个人很难理解这样的想法,但相信决策者肯定会从财务和商业的角度来做判断。无论如何,我还是认为紧跟技术前沿对企业更有好处。但这只是我的一家之言,相信很多朋友都会表示反对。
Bruce:最喜欢的啊……我最喜欢的大概有两种:Kotlin 和 Python。其中 Kotlin 可能是跟 Java 最相近的,而且它也是我见过的,功能最为完备、运行最为良好的语言。而且 Kotlin 不是真正从零开始设计出来的,它会从 C#、从 Python、从 Scala、从 Java 身上取经。与其自己发明功能,不如借用那些现有的成熟设计。所以 Kotlin 虽然也有少量创新,但大部分其实是照搬了全球程序员测试和实践过的编程语言功能。但我觉得这样挺好。这只是一种语言设计风格,而 Kotlin 的设计非常出色。
我也同样欣赏 Python 的语言设计,Guido van Rossum 很早就想明白了一切。编程应该很简单,所以他的 Python 就强调简洁、愉悦、优雅。我觉得他做到了。
我最喜欢的基本就这两种语言吧,而且也经常会用。我从 90 年代中期就开始使用 Python 了,所以还算有发言权。我真应该也给 Python 写本书,但肯定还需要深入研究一下。大概就是这样,Kotlin 和 Python,这就是我的答案。
Bruce:我认为还是一致的。当初 Scala 出来的时候,我也曾觉得它会是 Java 的继任者。但过了一段时间,我发现 Scala 社区虽然氛围很好,但却总是问题多多。Scala 更多是一种实验性语言,虽然能够带来出色的成效,但从 Java 到 Scala 其实相当困难。二者之间的很多概念差异巨大,不是很容易过渡。Scala 跟 Java 间的交互也不简单。但 Kotlin 就好多了,Kotlin 之于 Java,就像是 C++ 之于 C。
我认为,Kotlin 在设计上就充分考虑到了 Java 程序员的需求。它跟 Java 之间虽然也有差异,引入了更多函数式设计,但至少能跟 Java 无缝交互。不需要任何额外调整,它就能跟 Java 协同配合。在这一点上,Kotlin 直接就把 Scala 打爆了。所以 Kotlin 确实很有希望,虽然很多程序员还没用上它,但大家也没有升级到 Java 的最新版啊。至少我在社区中观察到的情况是,大家对 Kotlin 充满热情,这种语言在 Android 编程中也非常活跃。
谷歌自己其实就被 Java 6 卡住了,没法合法实现某些特定需求。Kotlin 则带来了新的飞跃,所以很多人已经开始把它视为准官方形式的 Android 编程语言。但 Kotlin 绝对不是 Android 专用的编程语言,而是真正的通用语言。事实上,在 Atomic Kotlin,我们是把它当成一种通用语言来教授的,绝不是那种专门面向前端、后端或者特定场景的语言。
C++ 刚刚诞生时,这个世界上还没有那么多程序员,但如今程序员的数量已经相当惊人。庞大的体量让使用者有了改变语言设计方向的能力,所以只要越来越多的人在学、在用 Kotlin,它就一定能成长为人们期待的样子。
当然了,这些都不可能一蹴而就,而且没准哪天又出现了更好的语言。在播客采访中,就有不少听众期待能有更强大的语言亮相,一举搞定那些折磨人的老问题和痛点,比如安全性、可靠性这类问题。如果真的有了更强的新语言,Kotlin 也可能会衰落,但它已经在自己的生命周期里做出了很多贡献。
而语言本身不只是在持续进化,学习编程语言时最困难的一点,就是总会出现新的重要概念。Java 就一直在努力跟上时代的脚步,实际效果也还算不错。所以未来编程语言会走向何方,目前还真的很难预测。
不过 Python 社区似乎压根不关心语言到底有多成功这个问题。铁打的 Python、流水的程序员,总有人来有人走。Python 社区也不强求大家喜欢这种语言,合适就用一用,不合适就拜拜。我们也从来没想过 Python 后来会变成现在这个样子。在经历了漫长的发展之后,Python 似乎突然就在正确的时间找到了自己的正确定位,于是变得大受欢迎。
同理,我们也不知道 Kotlin 未来会怎么样,只能说我很喜欢这种语言的设计思路,而且感觉它也很好地完成了自己的历史使命。作为 Kotlin 的开发团队,JetBrains 还开发了 IntelliJ 和 Pycharm。这些工具是为了他们自己的需求而生,解决了他们的痛点,也受到了市场的欢迎。
这种应需求而生的背景,也许正是我喜欢 Kotlin 设计的原因之一。
Bruce:这句话是怎么诞生的……这好像是我在很早之前一场 Python 会议上的演讲里说的。我倒不是想迎合观众,我确实对 Python 非常满意。因为在它之前,我只用过类型化语言,稍微用过一点 Perl。
我有过这样一段经历:有一次,我写了点 Perl 代码。隔了几周之后,我发现自己已经看不懂写的是什么了。我不想用那些我自己理解不了的代码。于是,我就找上了 Python。这就是我决定早早参与 Python 项目的原因。
那句话只是我偶然想到,并在演讲里说了出来。我也不太确定这句话是我自己原创的,还是从别人那听来的。
Bruce:Rust 真是名副其实,它会慢慢“侵蚀”程序员,像覆盖金属一样影响我们的开发习惯。Rust 让我印象最深的一点,是他们的说明文档非常出色。我从没见过这么出色的文档,Rust 的说明文档是给那些不懂 Rust 的人写的,写得很清晰。太神奇了,所以我去参观了 Rust 背后的公司——Mozilla。很多年前,我其实去过 Mozilla,我很想了解他们的组织结构。他们当时邀请我尽快写本关于 Rust 的书,但我很高兴自己没有着急行动,毕竟 Rust 的说明文档已经非常完善了,根本不需要我画蛇添足。
Rust 的神奇之处,在于 Python 或者 JVM 都有强大的运行时系统来处理垃圾回收之类的工作,但 Rust 什么都不需要。不需要单独的运行时,Rust 就能实现垃圾回收、保证运行稳定。连 Go 都有运行时,好吗?但 Rust 就不需要,这真是让我叹为观止。
我们曾经尝试编写 Python 扩展,但一直没弄明白怎么用 C 来开发。为了抢时间,我们打算用 Go,但 Go 也需要启动运行时,也不太容易。而 Rust 有一套专门用来编写扩展或者说库的系统,能轻松搞定 Python 扩展的开发,全程无缝。我虽然没认真学过或者研究过 Rust,但还是能很快体会到它的妙处。Rust 出色的内存数据移动功能甚至影响到了 C++,让 C++ 也开始效仿。我记不得具体是从哪个版本开始了,但 C++ 确实照搬了 Rust 的设计,因为效果真的太好了。
所以说 Rust 里面真的有很多超棒的设计,能为不同的群体解决各种不同的痛点。它最初可能只是为了 Mozilla 的 FireFox 而生,让 FireFox 成为更快、更高效、更可靠的浏览器,但远不止如此,现在 Rust 已经成为了解决某些特定问题的最佳方法。有它在,我基本就不用再为这些问题烦心了。
我就是会特别关注这些让自己摆脱问题的语言。如果现在让我写个 Python 扩展,那我肯定会选 Rust,因为它能解决特定的问题。如果我需要做底层开发,可能也会选 Rust,虽然现在我对底层开发已经没有兴趣了。我刚工作那几年就是做底层开发,入职第一家公司的第一项任务就是用汇编语言编写一个浮点数学(计算)库。其实我现在已经记不清了,但当时我完成了这个任务,并且对浮点数学(计算)建立起了非常深入的理解,而且据我所知,直到现在他们还在使用那个库。
我真的很期待那些越来越强大的语言。Rust 就很强大,但它也属于低级语言(Low-level Programming Language)。我大部分工作都跟低级语言开发有关,所以如果能在不需要的时候不涉及垃圾回收,那就太棒了。虽然一般来说,我也喜欢那些提供垃圾回收的语言,但有时候也需要点不一样的东西。总之,我不想直接操作内存,但如果非操作不可,那我选 Rust。
Bruce:反正如果没有可靠的内存管理,那肯定不算是优秀的编程语言。我这个人老是记不住语言的名字。总之,我们在播客采访中遇到过正在研究新语言的朋友,但他们好像是在对每部分代码进行分别设计,比如编译器啦、构建系统啦。最后得到的成果,其实就是编译器加构建系统。
可能这个方向是对的,他们的构建系统会查看代码、审查代码效果。这样只要变更的内容不会对其他代码片段产生影响,就无需重构整个系统。这就形成了一种函数属性很强的语言,变更其中的一项函数只会引发非常有限的影响,所以重构的范围也将大大缩小。
总之,就是在从高级、宏观层面审视编程工作。多年以来,我们一直在忍受很多低级特性带来的问题,而且一直得不到解决。最直观的例子,就是在变更代码时弄清可能引发什么影响、什么 bug。但如果有一种新的编程语言能从更高级别的视角出发,那它肯定就是优秀而且现代的编程语言。
Java 这边也在做类似的尝试。Java 8 已经开始重新思考要不要把一切都视为对象。这个思路是继承自 Smalltalk 的,但 Smalltalk 跟 Java 是两种完全不同的语言。Smalltalk 是动态的,整个设计理念都跟 Java 有很大区别。所以我觉得 Kotlin 做得不错,它从 Scala 和 Python 那边学到了类,而且又在类之外设置了函数的概念。比如,我发现自己在 Python 中编程时,往往会从编写函数开始,但这好像不太对。但只要再认真观察一下,我就发现这其实就是在把它设定成一个对象。没错,程序的其余部分都不需要对象,但这里又需要,于是就出现了非常拧巴的结果。总之,在函数式编程中设置对象、或者在面向对象编程中设置函数,都会让人感觉很难受。
现在有种相当强烈的声音,反对以往那种面向对象编程。我能理解,因为面向对象编程虽然带来了改进,但很多承诺解决的问题并没消失,看起来只是把问题封装了起来。
我们以 Record 类型为例。在创建 Record 时,我们实际上创造出了不可变的东西。创建 Record 对象时会进行类型检查。封装的意义,就是让我们了解里面到底有哪些变体函数。那最终得到的结果就被放在类里。而后续一旦出现问题,我们就知道这些变体函数到底在哪;把变体拿掉之后,所有检查就不再分布在整个类里。于是,我们马上就不用再管这些检查了。这是个重要的转变,彻底影响了编程、特别是大型系统的编程工作。我们做过很多测试,比如异常处理,这种方法在小型或者低级线程程序中效果不错。但如果系统变得更大、更复杂的时候,问题就会出现,因为这些设计在中大型项目中基本起不了作用。
这就是编程语言面临的实际难题,而优秀的现代编程语言当然需要尝试解决这些问题,帮助程序员们摆脱困境,最终把工作转化为纯粹的代码管理或概念管理。
我要说的大概就这么多了。我们既无法理解一切问题,也无法发现一切问题。以版本控制为例,要想彻底消除跟版本控制相关的问题,那就得在语言设计中体现,这样程序员才能用不着自己亲自费心。总之,程序员那边的麻烦够多了,语言设计者应该帮他们减轻负担、而不是增加负担。
Bruce:其实我说这话的时候,讨论的是怎么用汇编语言编写浮点数学计算库。很长一段时间里,我只要一看到浮点运算,就会想起浮点数学计算,这也是最大的瓶颈所在。
大多数情况下,我主要用 Python 解决这类问题。刚开始,我以为这种解释性语言会很慢,所以可能得把代码写得复杂一点,让速度快起来。但实际情况完全不是,我可以用最简单的办法运算,而且 Python 总能用几乎最快的方式完成任务。很明显,我对于性能的直觉出错了。其他常见的直觉判断还有架构,就是先做一点规划,再根据思路构建系统。比如这个系统未来会是什么样子,以后要满足哪些需求等等。直觉和经验还是挺重要的,毕竟开发工作中或多或少都会有一点猜测的成分。
比如后续我们可能需要添加某些类型的功能,或者需要用某种方式做出变更。参考这些要求,我们才能完成当下的架构设计。不管情不情愿,业务都有可能发生变化,突然之间提出新的功能需求。如果事先没有做好架构决策,那后续功能添加可能会非常困难。我想说的是,性能和架构往往需要一些直觉,有时候选择哪种语言也需要直觉。
我有个朋友,他们公司之前就一直在用 Java。但之后来了位新任副总裁还是 CTO 什么的,要求大家把所有代码用 Go 语言重写一遍。这时候,我朋友跟不少同事都离开了公司,根源可能就是重写代码。
所以改变企业是一码事,但这种全盘重写代码的决定没准就把公司搞倒闭了。并不是说 Go 语言有什么不好,但如果大家已经把一切都押在了 Java 身上,也已经用 Java 编写了大量代码,积累起丰富的 Java 专业知识,那轻率地决定推翻重来真的不可取。在我看来,那位副总裁根本不知道自己在干什么。他经验太浅,我都不知道他是怎么拿到这份工作的。总之,要想做出这样的决定,那就必须得有非常充分的理由。如果没有,那我就干脆辞职不干了。
Bruce:我想用我爸盖房子的故事解释这个问题。我记得刚有气动工具的时候,大家都觉得很神奇。一台压缩机,一把钉枪,问题就解决了。我爸花了不少钱购买这些工具,毕竟一看这东西就能大大提升工作效率。事实也证明,他的判断是对的。编程也差不多,有些人可能觉得自己换成 PHP 就能大大提高工作效率,或许在某些特定情况下确实如此。所以我们最好能持保留态度,毕竟我自己就花了几十年专门研究这些工具的价值。没错,我承认工具非常重要,程序员们的超高生产力也就是从这里来的。
但我有个朋友就不信这一套。我总在思考编写代码的本质是什么,是一种写作吗?还是说像是盖房子?在他看来,开发软件就像做手术,所以引入的工具是越少才越好。而真正决定这事能不能成的,永远都是人。病人当然都想请最好的专家来给自己做手术嘛。而且在他看来,软件本身也是种负担,所以拥有的软件越多、维护成本就会越高。他说的没错,所以我才觉得高级工具(编者注:此处指代高级编程语言,High-level Programing Language,下文同)非常重要。如果我们编写出来的代码更短小、更简洁,那维护负担就会轻得多。
从商业角度来看,这才是最好的结果。没人想要一大堆代码来支撑业务,软件用得越少才越好。而达成这个目标的唯一方法,就是使用更加智能的工具。我就是这么看的。有些人在企业运营中一直在用那些平庸甚至糟糕的工具,公司也不是不能运转,对他们的需求来说也够用。但我总觉得,总有一天他们会为此付出代价。
对于自己编写的软件,我们其实身负很多责任。我曾经参加过一场简短的面试,那是很久之前了,那家公司想要开发一款软件,用来控制锯片如何切割树木。锯片缓缓移动,把木料切成一块块板材那种。
这里面需要考虑的问题就多了,比如阻力、位置之类。他们已经做了一定的开发,但遇到了麻烦。整个程序是用汇编语言编写的,但程序员走了。他们迫切希望有人能接手,赶紧解决问题。但项目没有任何说明文档,也没人愿意接管这个烂摊子。而且我敢肯定,这个项目肯定会拖死整家公司。
所以,我才总在宣传高级工具。这类工具能为我们做更多的事情,生成更易于理解的代码,同时控制总代码量。对我来说,这本身就是一种商业价值。也许大家有不同的看法,但我就是这么认为的,所以会投入很多精力研究这方面问题。
Bruce:我觉得是好奇心加坚持下去的毅力。
我其实见过很多从音乐家和物理学家转行搞开发的,做得也很好。其实优秀的程序员可能来自任何地方,这跟大学学位、专业选没选计算机工程无关。除非是搞芯片或者其他非常底层的技术,否则真不一定非要科班出身。高级编程语言真的不难掌握。
我也是,虽然选修过相关课程,但从来没接受过正规的高级语言培训。说真的,很多人都完全有能力自学高级语言。而聪明的公司会愿意接纳这些充满好奇心,同时又坚忍不拔的人才。有了这两种特质,他们会成为优秀的程序员。现在世界上优秀的程序员还不够,但有了这两大特质肯定能行。
Bruce:这个不好说,毕竟时代一直在变。在上次 Python 大会上,他们就公布了 PyScript,相当于是浏览器端的 Python。它运行在 WebAssembly 之上,可能会改变大家的编程方式,让程序员们获得更强大的开发能力。它还能调用 JS 代码和 JS 库,配合 DOM 之类的。
所以说当下或者说短短一个月前,最值得掌握的语言还应该是 JavaScript。但突然之间一切都不一样了,现在出现了 Elm 这类语言,能够为前端编程提供可靠性支持。我觉得我们正在见证编程领域的一场革命。所以到底选不选 JS 反而无关紧要。如果真想了解哪种语言市场行情更好,那大家直接看企业的招聘需求就好了,哪种语言用处大就选哪一种。
但还是那句话,这一切都可能在不久的未来彻底改变。因为新技术正在提高人们的生产力,让大家能够更快开发出更加可靠的程序。这会让企业的运营成本大大降低。另外还有可维护性。总之,这一切会对企业财务产生深远影响。只要临界点一过,企业自己就会为前端和后端选择更合适的编程语言。这才是最应该关注的趋势。
Bruce:就是好奇心和毅力。没错,就这些了。优秀的开发者总在不断学习,持续学习需要的就只有好奇心加毅力,永远关注当下最需要解决的问题是什么。
但具体要如何解决,单靠不断重复过去肯定不行。毕竟老办法有时候意味着我们一直在重复浪费大量时间。优秀的开发者会思考能不能一举解决问题,让每个人都受益,也让承担成本的公司受益。另外还要考虑整体环境,公司自己也需要明白不能总是用老办法,企业得对新方式表达宽容,这样才能吸引到更出色的程序员。总之,鼓励员工们不断改进现有流程的公司,在人才市场上往往会更占优势。
Bruce:这也是个有趣的话题。我其实没认真考虑过这个问题。毕竟如果学 Java,那就需要跟之前那么多 Java 程序员直接竞争。所以在我看来,选择一门语言是因为它比较有吸引力吧。哪怕是考虑就业,既然 Java 已经那么热了,再选 Java 恐怕也没多大竞争优势。
而且最终大家应该会进入一家符合自己脾气秉性的企业。先有了兴趣,之后我们才成了 Java 程序员,应该是这样才对。而不是说之所以学 Java,是因为将来学会了更能赚钱。
和我一起写书的 Bill 之前就用 Java 编程,但他真正喜欢的其实是 Scala。所以最后,他去了做 ZIO 库的公司。他很开心,因为能在那边做自己真正喜欢的事情,就是那种“做想做的事,做喜欢的事”的感觉,这其实也是我非常向往的。有了这份热情,大家才能成为更好的程序员,报酬可能也会变得更高。虽然我们可能很难在一开始就找到这么好的工作,毕竟这样的工作机会不会很多。但只有朝这个方向努力,你才能得到一份“理想的工作”而不只是一份“工作”(编者注:Bruce 原话是“a right job rather than just a job”)。也有很多人觉得 Java 就是理想的语言,让他们用着开心。
我知道,这都是些老生常谈了,但跟随自己的内心真的很重要。总之,我认为如果做的事情没法引发自己的共鸣,那我们就不可能做得太好。只有做自己喜欢的事,才能真正做得好。所以如果非要加一点,那就是在好奇心和毅力之外,再加上做真正喜欢的事情。
但这只是理论,在实践层面很多事情没那么单纯。要具体情况具体分析,毕竟我们自己也在不断成长。
有时候,父母可能不太支持我们的选择,他们往往更希望我们能做点更稳定可靠的工作。我爸就说过类似的话,他会问我,“你要靠写书活着?你确定?”
但在我成功之后,他好像就忘了自己当初的质疑。他充满了自豪,逢人就说“你看,我儿子是写书的。”其实当时,父母真的很担心我没法养活自己,这跟他们那代人的经历有关。
我爸爸就是成长在大萧条时期的一代,所以他很看重财务稳定。如果大家的父母也有类似的经历,那观点就会跟他差不多。他们会提出建议,这很正常,毕竟在他们看来,先保证能吃饱饭最重要。
Bruce:其实我在写《Thinking in Java》的时候,就有人提醒我市面上关于 Java 的书已经太多了。就连出版商都说这类书卖得不好。
所以我觉得书跟人一样,也会经历繁荣期和萧条期。有一阵子,Java 特别流行,每个人都要出本 Java 方面的书并急于拿出来换钱。但他们显然没投入足够的时间和精力,真正把书写好。而当发现人们不想买这本书时,他们倒是表现得很惊讶。
所以这些事情不能粗暴进行联系,二者之间未必就是强相关。技术人员不买 Java 的书,并不一定代表他们就不想学 Java,没准只是看透了大部分书都写得不好。这个不能简单判断的。
至少我在写书的时候,会尽力把一切做到最好。我会花很多时间,也许算经济账的话有点亏。毕竟当初那本《Atomic Kotlin》花了我三年时间,而且我根本不知道有没有理想的回报。但我的价值判断不是那样,我觉得如果不全力以赴、那之前已经付出的任何一点努力都相当于被浪费掉了。所以我永远会尽自己所能让书更完善。
Bruce:大家觉得如果 Sun 能活到现在肯定是件很酷的事。这有点像我之前说的,希望能有一家完全专注于技术本身的研究机构。
至于“从无到有”的兴奋感越来越少嘛,我的感受正好相反。我感觉随着事物的发展,工具愈发先进,所以我更能完成从无到有的创造了。
今天是不是开发人员的黄金时代,这个我觉得言之过早。这个行业相对于它的发展方向来说,还非常年轻。只能说,如果真的出现了黄金时代,那也是事后总结出来的,身在其中未必感受得到。所以,永远力争前沿就对了。
之所以说技术行业还处于早期阶段,是因为我们还有很多基础问题没有解决。可能有些人经历过黄金时代,但又感觉好时光过去了,这是非常个人的感受。总之,我觉得目前编程语言所能带来的新概念、赋予的新能力,特别是创造力,还非常有限。所以即使是到今天,我认为一切也才刚刚开始。不知道大家有没有同感,但我总觉得现在的一切都像是正式启航前的试飞。
不管是 GitHub Copilot、Stack Overflow 还是 Google,都不能替代程序员。我们需要整理自己想做什么和想提什么问题。除非只要提出需求,整个实现过程就能自动完成,那才叫真正的成熟期。而且这也只是编程的冰山一角。未来,参与前沿研究的人们也应该能享受到技术和编程语言赋予的这种能力。大多数情况下,未来的解决方案应该消灭如今困扰我们的一切琐碎麻烦。那时候才是开发方法的标准化之日,到时候所有小问题要么全被整合进库里、要么就是有更轻松的实现方法。
比如说量子计算,这就是一种全新的问题解决方式。而要想把这种新方法推向主流,期间肯定会出现很多波折,比如大家又得适应没有垃圾回收、没有内存管理、没有可靠实现方式的工作过程。他们又得鼓捣线程,调试那些在编程黄金时代中从来没出现过的调用。
所以在我看来,编程的黄金时代可能永远是在十年之后,至少我自己完全预见不到。我只能看到自己目前手头的工作,我能把握的也只有当下的具体事物。反正就现在来说,编程工具还远称不上强大,我们仍然被困在很多非常原始的难题里苦苦挣扎。
这就是我的答案了,如果非要说编程有黄金时代的话,那它永远都在未来。
Bruce:我到过中国,待了大概十天左右,也转了很多地方,大家都非常热情好客。可能咱们的立场不太一样,所以与其对程序员说点什么,我倒更想跟管理者们说点什么。下面的话可能不太合适,所以要不要发布还请多加斟酌。
我想告诉各位管理者,编程不是那种能赶出来的工作,每个人每天就只能编几个小时的程。所以,各位管理者,最重要的是用更少的时间换更高的质量。没几个人能每天编 12 个小时的程,这是明显要收益递减的。代码写上几个小时之后,人的精力就被耗尽了,后面其实也做不了什么了。
总之,编程是种创造性的工作,你不可能每天都有那么长时间充满着创造力。一天干 12 个小时,任何人都会筋疲力尽的。我知道,我说的这些话可能不太合适,也许会引发争议之类的。但这就是我的观点。
当然,我也会说漂亮话。保持好奇心、充满毅力,这个肯定没有争议。
哈喽各位读者朋友们,InfoQ 来送福利啦!我们将通过抽奖的方式,送出 5 套 Bruce Eckel 全新力作《On Java 中文版》。
你也可以在下方留言区,分享你心目中最值得推荐的 3 本 Java 经典书籍,并说明理由。我们也会为点赞排名前三的小伙伴分别送出一套《On Java 中文版》!
如果两种方式都被选中则只送出一套书籍,中奖名额在留言的小伙伴中顺延。
开源大佬从谷歌离职:在 Go 语言项目上停滞不前,要去更小的企业寻求变革
这群 WebAssembly 大佬创业失败了:有时从 JS 迁移到 Wasm 并不值当?
没有内卷、996 和“老板”,乐视过上神仙日子?WPS 重申“删除用户本地文件”一事;小米被指违反 GPL 协议 | Q 资讯
具有易用性、扩展性、较低成本等优点的分布式数据库越来越“火”
在金融行业中,如何做好分布式数据库选型和落地?如何用好数据库?
7 月 26 日 19:00 直播间为你解答!扫码或点击【阅读原文】,立即预约直播!