Ben Evans是 jClarity 的联合创始人。其公司致力于开发可以为开发和运维团队提供帮助的性能工具和服务。他是 LJC(伦敦 Java 用户组)的组织者之一,也是 JCP(Java 社区过程)执行委员会的成员之一,帮助定义 Java 生态系统中的一些标准。他还是“Java Champion”荣誉得主。他曾与人合著了《Java 程序员修炼之道》(The Well-Grounded Java Developer)和《Java 权威技术手册(第 6 版)》(Java in a Nutshell)。他曾就 Java 平台、性能、并发和相关主题发表过多次演讲。
问:《Java 权威技术手册》(Java in a Nutshell)是一部经典,它的上一版(第 5 版)长达 1200 页,而在十年后即将在中国出版的第 6 版却只有 400 页,这两版之间到底有什么样的变化?对于 Java 来说,这十年意味着什么?
第 1 版《Java 权威技术手册》是在 Java 刚刚变得流行之后很快出版的,那个时候人们对于 Java 充满了想象。在接下来的五个版本里,这本书越变越大,内容不断延续。所以每一本的重点都有些着眼于历史,因为几个版本之间有着演进的关系。这是由几个因素造成的结果,有一部分原因纯粹是因为这样比较好写,你只要知道这个版本和上一个版本相比增减了什么就可以了。但是更重要的是,在早些时候,在大部分企业中,Java 的生命周期很长,所以你经常可以看到很老版本的 Java。所以理解不同版本之间的区别变得很重要。所以当你在某家公司某个 Java 版本上工作时,如果你知道版本是哪个,你也就知道了能做什么不能做什么,以及这个版本与其他版本相比有什么样的改变。
这就是当我开始写新一版时,第一个想改变的事情。因为现在最新版的 Java 8(说到这里,容易让人有些混淆,《Java 权威技术手册》的第 6 版讲的是 Java 的第 8 版)的生命周期比以前短了很多。当然,这要取决于具体领域,但是了解了普遍的使用情况后,你会发现使用老版本的(比如 Java 6)只是极少数的人。当然仍然有一些疯狂的人仍然在使用 6 以前的版本,大部分的用户使用的是版本7。现在,版本 8 正在以很快的速度占领市场,仅仅在半年时间,有 15% 到 20% 的用户已经在使用 Java 8 了。所以新版《Java 权威技术手册》的关注点比以往更加开放,我们开始关注 Java 以外的世界,也会讨论现在和未来。
第二件重要的改变是长度,正如你所说,第 5 版长达 1200 页,而第六版只有它的三分之一,当我开始着手整理上一版的时候,我做的第一件事就是去掉了三分之二的内容。如果你看过第五版,你就知道除了讨论 Java 的主要内容之外,这本书的第二部分是关于索引的。当然这也是历史原因造成的,当 Java 刚出来的时候,网络的使用还不是很普遍,所以书自带一份索引是很合理的事。但是还有另外两个原因,Java 平台变得越来越大,在《Java 权威技术手册》的第一章我讨论了 Java 版本进化,指出了 Java 平台的增长速度之快。要描述 Java 5 平台的基本知识就用了 800 页,那还是 Java 5 的时候,如果用同样的方法讨论 Java 8 的话,这本书就要顶到天花板上了。可见这个方法不可行了,没有人会愿意拿着这样一本书。另外一个原因(也许这两件事是相关的)就是人们利用技术信息的方式发生了改变,因特网如今无处不在,人们不愿意携带厚重的书籍,所有的索引都可以在网上的 PDF、网站等资源中找到。所以这个时候还要在纸质书的后面加上厚重的索引就很不合理了。这就是《Java 权威技术手册》两个版本之间的重大改变。
我尝试的第三件事是捕捉 Java 的变化趋势和规律。所以很多关于过去如何使用 Java 的内容都被去掉了,我加入了更多现代的使用方法,读者们需要了解垃圾回收,内存分配,并发编程,我在这些方面讲了很多。这里面涉及了大量的工作,因为原来的版本都着力于保存原有的内容。在第五版留下的三分之一内容中,大概只有 25%-30% 留到了第六版中,这些内容也都重新编辑整理过,而剩下的 70% 左右的内容则是全新的。
因为,我们想在 Java 8 投入使用的时候就把这本书弄出来,所以 Java 8 还没有出来的时候我们就动笔了,到了后来还出现了一些一开始没有想到的工作(比如 Java 8 上隐藏的特性)。但是这次我们的经验更丰富了,所以我们希望能在 2016 年 4 月,Java 9 出来的时候完成下一个版本。事实上我已经做好具体计划了。
问:对于《Java 程序员修炼之道》(The Well-Grounded Java Developer)你有下一步的计划吗?
《Java 程序员修炼知道》这个项目很好,写作的过程也很愉快。但是在写作《Java 权威技术手册》的过程中我消耗了大量精力,我认为我可能不会再写这本书的第 2 版了。我和这本书的原出版商 Manning 谈过了,但是最新的进展我并不了解,所以很有可能这本书不会再有第 2 版了。
问:一位 Java 大牛和一位普通 Java 程序员之间的区别是什么?
我认为可以把程序员的层次看作一个金字塔,其中可以大致分成 3 个层次。在最底层的是很勤劳的程序员,但是他们可能对编程本身兴趣不大,他们也能做好工作,但是他们下班之后就不会再想关于编程的事。这是很正常的现象,软件业需要很多程序员,并且这个需求仍然在不断增长。中间层次上的程序员,想再多做一些,他们阅读科技新闻和网站上的消息,他们会跟进下一个版本的进展,他们关心自己的技能,这个层次的程序员很有趣。而最上层的程序员则是时刻对技艺以及技术的本质着迷。当你到达了这个金字塔的最顶层时,你就会开始有反馈环,你可以从自身学习,对技艺的了解也更深刻。但是我认为最难的部分就是如何从第二层突破到最顶层。如果你对你所做工作之外的知识有一丁点兴趣,你就要寻找属于自己的那个点,这个点对于每个人都不一样,一旦发现那个让你着迷的领域,你就可以随着好奇心的驱使深入学习下去。
关于开源软件有一个说法,一个好的开源开发者必须找到自己的痛点,他们不得不去解决这个困扰他们的问题。这是大多数人对开源软件感兴趣的原因,也是很多人称为 Java 开发者的原因。你找到了一个让你感兴趣的点,由于不明所以,你一直学习下去,这就是成长的秘密。
问:虽然 Lambda 加入了 Java 8,但是在开发者之间始终有关于 Java 语法过于冗长的抱怨。你认为这是很多开发者和团队不愿意使用 Java 的主要原因吗?
我不这么认为。James Gosling 有三句话可以解释 Java 的语言设计,以及为什么 Java 是现在这个样子。第一句就是英语中所说的“蓝领”语言,蓝领工人是从事第一线工作的人,而白领则代表了办公室以及经理们的工作。Java 就是一种蓝领语言,它的设计是为了让工作中的程序员解决真正的问题。Java 是实用的语言,它解决的是真实世界中的业务。
James Gosling 在 2014 年 JavaOne 大会上谈到了 Lambda 以及 Java 的早期版本中没有出现的一些设计,他说:如果我没有找到完成一件事的正确方法,那我就什么都不做。这句话表达了一种缓慢而保守的演进设计思想,要想理解 Java 是什么,就必须要明白这点。很多人觉得 Java 老了,编程语言需要改变,但是他们没有搞清楚的是,真正变化的是他们自己。他们在能力上有了发展,他们想看得更远更深,而语言反映出了这一点。并不是语言需要改变,而是提出这个观点的程序员自身发生了变化。Java 从过去到未来都是一种设计保守的语言。这也是 Java 的一大优势。
当 James 解释他设计 Java 的初衷时说:当我在设计的时候,我知道人们想要自动内存管理,人们想要強型式,但是这些功能会吓跑蓝领工人。比如说 Smalltalk,这是一门很优秀的语言,但是它太先进了,它和现实中开发者们在构建应用时的思维脱离开来。所以 Java 继承了其中的一些理念,并将其简化,把这些理念放入一种语言和格式中。这些事解释了这门语言设计的基本动机。
所以你当然可以说 Java 是一种冗长的语言,但我认为额外的内容是为了方便阅读。特别是当你还是一位初级或中级程序员的时候,那些看似多余的文字能够帮助到你。人们永远都铭记我们对于生产力的需求越来越高,但是代码仍然是写出来的。所以我不认为 Java 冗长,虽然我们可以加入一些高级功能,但是有些事永远都无法在一个语言中改变,这很遗憾。当然我们也会进步,但是就像我总说的一句话,人们总是过于关心语法,而不是能用语言来实现什么。
问:现在不少的大企业(Paypal 等)从 Java 切换到 Node.js,Java 在企业中的地位受到威胁,Java 和 Node.js 各自擅长的领域是什么?
这个问题中有一个误解,事实上并没有出现大波公司弃用 Java 转向 Node.js 的情况。Paypal 中启用 Node.js 的部分规模很小,Paypal 的大部分运行代码仍然是 Java。Node.js 参与的只是一个试点项目,这是可以理解的,Node.js 是一个有趣的环境,其中也有一些有趣的想法。Node.js 十分年轻,同时,它也有很多严重的问题,所以现在预测 Node 的未来发展还为时尚早。所以虽然各种开发者网站上有很多支持 Node 的声音,GitHub 上有很多有趣的项目(比如用它写 Ardruino,玩硬件),但是在所有生产环境下的产品中,毫无疑问,Java 拥有最多的代码行。企业在没有充分理由的情况下不会舍弃工作软件,虽然有很多使用 Node.js 的创业者,但是创业者们来得快,走得也快。
作为近些年来有趣的产品之一 Twitter,如果你观察一下他们的发展你会发现他们最开始用的是 Ruby on Rails。三四年前,他们的网站开始出现一个非常可爱的卡通形象,失败鲸。这是一件很尴尬的事,为了弄明白到底发生了什么,他们做了很多调查,在查看了 Ruby 的垃圾收集之后,他们发现自己无能为力。同时,他们的 Java 试点项目获得了成功,他们意识到 Java 能解决他们的扩展性问题。然后在接下来的 18 个月,他们使用了一些 JRuby 作为中转站,然后将整个系统改写成 Java。最终的效果也很好,他们围绕 Java 引入了新的服务,新的架构。曾几何时,Ruby 被视为企业级软件的未来,但现如今,Ruby 只是众多编程语言中的一种。现在应用最广的三种语言是 Java,JavaScript,以及C/C++,但是大部分的 JavaScript 代码都是在客户端,如果把这三种语言去掉,其他语言的市场份额都非常小。
问:直到现在,Java 应用的虚拟托管模型需要分配给整个 x86 虚拟机用来托管一个单独的 JVM 实例,相对来说实例上也托管了单独的 Java 应用。这样的方法效率很低,但是 Java 本地并不支持多租户虚拟以及云计算配置。幸运的是,在社区里可以找到一些为了解决云计算问题而产生的多租户 Java 解决方案,你认为哪个方案足够成熟可以应用到生产环境?
这里面包含了两件事,把虚拟和云以及多租户混在一起并不完全正确。比如说在 QCon 上海上有很多分享是关于 docker 的(docker 是一个并不依赖于虚拟化的平台),其中一个精彩的分享来自 Chris Swan。他展示了将 CPU 内存从虚拟环境转移到以 Docker 为基础的环境所带来的好处,虽然仍不够完善,但是它已经为 Java 带来了额外的优势,只要在 Docker 上运行 Java 你就能感受到。我们应该把云和虚拟的关系梳理清楚。另外,有很多其他你可以做的事,比如你可以建立多个 JVM 主机。
但是这个问题真正在问的是多租户。关于这个问题,有一个产品在我心中是当之无愧的冠军,那就是 Waratek。Waratek 可以把一个单独的非热点 JVM 分开,并在其中运行主机 JVM,在 JVM 里运行的是 Java 虚拟多租户 JVC,而 JVC 可以做到很轻量级。我认为 Waratek 是一个很成熟、可以投入使用的产品,德意志银行刚刚宣布把自己的第一个工作 JVM 挪到 Waratek 上,既然德意志银行已经认可了这个产品,那么这个产品应该也值得你花时间研究一下。
问:Java 经常被拿来和 Scala 做比较,这两种语言的设计目的有什么不同?在未来,这两种语言是否可能发展方向完全一致?
Java 和 Scala 是有着很大不同的语言。之前我们谈到过 Java 的设计哲学,现在我们可以来说一说 Scala 的设计思想,以及它们之间有什么不同。Scala 最初是一门来自学术界的语言,最开始 Martin Odersky 创造的语言叫做 Pizza,那时候 Java 还是版本4,这个时候 Pizza 开始逐渐加入了一些类似于 Java 范型的功能,Java 5 中也加入了一些 Pizza 的功能作为范型。
Martin 是一个很聪明的人,Scala 也有很多很棒的设计。但是同时,这个语言也有自己的问题。有时候它被称为“厨房水槽”语言,可见人们对这门语言又爱又恨。这个比喻的意思是:水槽里面装了各种各样数量过多的东西。这确实是 Scala 的一个问题,它的功能太多了。有一条语言设计的准则,同时也是 Java 设计过程中的一个重要原则——保守。具体说来,就是每当你添加一个新特性的时候(《Java 程序员修炼之道》14 页谈到了了一个具体的例子),可能你也造成了新的问题。如果你的语言有 200 种特性,而这个时候你想再加入一个,我需要检验它和所有其他特性的交互情况。对于 Scala 来说,它总是频繁地加入新的特性。要想知道这些特性之间的交互情况是很困难的。就算 Scala 有一个很灵活,能够拥抱改变的社区,语言特性的变动也是件不容易的事。所以你会发现虽然 Scala 拥有很多优秀的工作性能,但是你需要决定哪些特性是你想要的,而哪些特性是你不能碰的。当你在团队中编程的时候,这不是个问题。真正的问题在于,现代社会的软件栈从来都不是仅仅依赖于代码,问题来自于函数库。有一些 Scala 特性的动作不仅影响目标对象,还会影响其他一些东西。Scala 的特性越多,这些问题就更容易互相重叠。
另外,他们一直都纠结于二进制兼容的问题。Java、Sun 以及 Oracle 一直都认为这是对 Java 来说最重要的设计理念,所以我可以用 Java 1.0 写程序,编译一下,放到 Java 8 的虚拟机中,仍然可以运行,而且运行速度会比以前快很多倍。而 Scala 从未做出这方面的承诺,哪怕就是上一个版本也会出现问题。在函数库空间中,这个问题就更严重了,我知道很多项目都放弃了 Scala,就是因为每次只要升级函数库,整个系统就会崩溃。
所以说,这两种语言的设计思想很不相同。人们总是喜欢新鲜事物,第一个尝鲜的人也会第一个享受到很多好处,但是在更多的情况下,人们更愿意做第二个尝试的人。你可以观察第一个人犯下的错误,然后从中学习。而 Java 就是这样一个从别人的错误中学习的语言。我刚才提到过程序员的金字塔,我认为 Scala 并不适用于底层,它的作用更多在于为最顶层的程序员们激发思考。而 Java 是一种适用于整个金字塔的语言,而且它对底层和中层的程序员尤其适用。我相信在未来的很多年内都会有一个强大且健康的 Scala 社区,我也希望能和他们一起交换思想。但是我并不认为 Scala 会从一种小众语言成长成一种大众语言。现在地球上可能有上百个 Scala 程序员,但是这个数量顶多也就是 Java 程序员的百分之一,而这个比例很可能不会继续增长了。
上海 QCon 采访 Ben Evans 现场