Java 是不是慢半拍?
坊间有很多迷思,比如“Java已经落后别的语言好多年”。我没有数据,也不知道裁量的标准,无法考证这句话的真伪。一千个人眼里,有一千个流沙河,每个人都有自己的解读吧。不过,我想聊聊每一个Java更新都需要考量的一些问题。
有没有兼容性问题?
Java语言不是一个实验性的语言,Java是一个生产性的语言。全球有450亿个运行的Java虚拟机,其中250亿个运行在云里。这么大体量的部署,每一个微小的兼容性问题都可能是灾难性的。一门语言,生产环节使用的越多,部署量越大,它的兼容性越重要。一个实验性的语言,先进是主要指标;而一个生产性语言,稳定是主要指标。这两者对兼容性的要求是有重大区别的。
在《代码精进之路》专栏里,我们聊过一个耽误了十年的安全漏洞,一直没有办法修复。阻碍修复的是C语言的read()函数的返回值定义。read()返回0表示EOF,而不是没有读取到数据。这个函数的返回值定义,不仅影响了C语言的应用程序,还影响了Java语言。虽然Java语言实际上并不存在类似于C语言的问题。事实上,它影响了所有的语言。因为兼容性问题,C语言没有办法修改返回值的定义;因为互操作性问题,所有的编程语言都没有办法修复这个安全问题。有时候,真的就存在这样的死局。
我们在聊这个漏洞时,说的是这个漏洞被耽误了十年,十年后才找到解决方案。我们没有说,这个安全漏洞十年前就被修复了,带来了十年的兼容性问题。生产性环节的语言,不能有普遍的兼容性问题。
所以,如果你熟悉OpenJDK的开发,你可能就明白,为什么每一个微不足道的小改动,都有人和兼容性较上好半天劲,甚至会完全推翻预想的设想。
保护现有的生产性部署,保护客户现有的投资,是Java语言设计的最重要考量,也是Java得以繁荣25年的背后的基本逻辑之一。某一个程序员可能会激动于新特性的酷炫;而所有的公司,都希望的是解决问题,而不是带来新问题。更重要的是,几乎所有的公司都希望他们投资研发的代码,能跑上二十五年,并且二十五年以后还能跑起来。
每一个语言都知道兼容性的重要性,但是实在做到这一点的并不多(Java几乎是独一无二的),在不断演进的同时保持良好的兼容性,实在是太难了。二十年前的代码,还能跑吗?
Java语言里,有没有类似与C语言read函数的死局?我只能说,这种死局多的很,虽然我不知道有没有比C语言read函数影响更大的死局。解这种死局,是Java研发人员最有挑战性的工作,也是创新最集中的地方之一。
严肃、认真地保持兼容性,这样的要求,是既招人恨,又招人爱。在Java 25周年票选最重要创新的活动中,就有开发者留言,他最爱的就是Java的兼容性,最恨的也是Java的兼容性。
什么样的新特性会被OpenJDK采纳?
如果你在一个领域呆的久一点,研究的深入一点,你就会发现,新技术、新标准的死亡速度几乎和诞生速度一样快。大部分新标准、新技术、新特性诞生之日,就是死亡之时。大部分新标准,诞生之前,山呼海啸,拥趸众多;诞生之后,除了标准留存、争论留存,没人用的代码留存,就再也没有半点水花。一个新技术、新标准,从一个想法到成为事实,有很长的一段路要走。其中的大部分,只能走到纸面这一步。
说一个近的例子吧。我们经常需要登录,才能使用一个互联网服务。可是,如果每次使用,都需要登录,用户可能会被烦的要死。比如,微信,你还记得你的密码吗?你还记得上次登录是一天前、一年前还是三年前?电商的网站,你每天都要输入用户名、密码登录吗?应该不是,否则,你会被烦死的。为什么关闭了微信,关闭了浏览器,下次打开还能续上上一次的登录?这背后的技术,简单地说,就是本地存储了登录的信息,下次使用时,服务可以识别这些信息,并且延续你的登录状态。遗憾的是,这些存储的信息,可能会被劫持,被冒用,从而带来严重的安全问题。
解决这个头疼的安全问题,呼声最高的就是有众多大腕加持的令牌绑定协议。其中,微软、谷歌还是标准的起草者,大批的应用协议翘首以待,希望使用令牌绑定技术,解决他们长久以来难以安枕的安全问题。2018年10月,标准通过,4年努力,3篇RFC;然后,死亡。
2018年8月,协议的倡导者和起草者谷歌,宣布将从Chrome浏览器中删除令牌绑定特性。因为,令牌绑定技术似乎不是一个好的投资,收益抵不过成本。
然后,令牌绑定技术就没有然后了,除了留存了三篇标准之外,以及偶尔的太息。直到今天,没有一个主流的浏览器支持令牌绑定技术。
对于浏览器等面向用户的最终产品,删去一个特性很容易。但是对于Java,删除一个特性是非常困难的,特别是如果还有用户使用这个特性。通常的,一个特性的删除,从提议到删除代码,短则三五年,长则十数年。中间,还要通过各种方式、各种途径,反复告知用户采用替换技术。
Java过时或者不当的特性难以删除,它的直接后果之一,就是OpenJDK的新特性难以添加、评审严格。我有一个很好的想法,我们添加一个JDK接口吧?很抱歉,大部分的想法,都只能想一想,讨论讨论,研究研究,然后就没有然后了。OpenJDK评估过的新特性请求,和能够通过的新特性请求,不在一个数量级上。
能够被OpenJDK采纳的新特性,一定是可以解决具体的、真实的问题,有可以预见的市场和用户,并且可以长久留存的技术。
所以,如果你看到一个令人激动的技术,其他语言有,而Java没有。其中一个原因,可能就是Java还没有准备好支持它。换句话说,Java还没有看到它的未来。当然, Java也会看错,怎么可能没有看错的时候呢。我自己的经验,漏掉的重要的东西,用户以后会反复地催促;不重要的东西,就再也听不到多少声音了。当有用户反复催促时,就是重新考量的时候,也是改正错误的时机。
事情的另一面,如果JDK添加了一个新特性,你可放心地使用它。因为,大概率,它会延续,有市场,可以解决真实的问题。
需要全能的OpenJDK吗?
Java或者JDK,只是Java生态系统的一个很小的部分,或者很基础的部分。你不能期待一个独立自主、自力更生的JDK。Java语言以及JDK,需要保持它的紧凑和小巧,尽管它已经不算小巧了。如果用户能够在JDK之外,在Java生态系统之中,找到有效的解决的办法,一般来说,JDK就不会再操心了。分工之下,才有效率。
Java是不是慢半拍?
我本来是想表达,Java并不慢;但是,我知道,大部分人读下来,都会觉得是慢了半拍。如果你能够读出来不一样的意思,恭喜你,你了解“因为慢,随意快”说的是什么。
后注:文章还是要一口气写完。隔了几天,再来续前,完全没有了感觉。
版权声明: 本文为 InfoQ 作者【范学雷】的原创文章。
原文链接:【http://xie.infoq.cn/article/12571be71996a053995d4420f】。未经作者许可,禁止转载。
评论 (4 条评论)