
时间回到1995年,Java之父James Gosling和Sun公司的John Gage带着一项划时代的技术——Java,登上了TED会议的舞台。当浏览器中呈现出动态的3D分子模型时,全场震惊。这次成功的演示,让“一次编写,到处运行”的理念伴随着互联网的浪潮迅速传播开来。

Java火了,程序员们蜂拥而至。但喜悦没持续多久,一个现实问题就摆在眼前:这语言怎么连个像样的常用数据结构库都没有?写个List、Map还得自己从头实现。隔壁的C++抱着它强大的STL(标准模板库),不禁露出了“优越”的微笑。

“确实不像话。”大神Doug Lea站了出来,“让我来写一套高质量的类库。”于是,一套包含Set、List、Map等接口的Collection框架诞生了。随后,Joshua Bloch将它进一步整理、优化,并整合进了JDK 1.2。从此,Java程序员再也不用为基础数据结构发愁了。而Lea教授的目光,已经投向了更复杂的领域——并发编程。

集合框架的问题刚解决,第二个致命问题接踵而至:速度。早期的JVM采用解释执行字节码的方式,效率被调侃为“慢如蜗牛”。“这还怎么写程序?”程序员们抱怨道。直到名为HotSpot的JVM登场,情况才得以改变。它通过即时编译(JIT)技术,将热点代码编译成本地机器码,性能获得了质的飞跃。

然而,程序员们依然困惑:Java到底最擅长做什么?用它写的AWT/Swing图形界面程序可以实现跨平台,但被吐槽“丑爆了”。在桌面开发领域,Delphi、VC++各领风骚;在Web开发领域,Perl、PHP、ASP打得火热。Java似乎只是个旁观者。直到Servlet和JSP跑来请战:“老大,让我们上去干翻PHP!”Java却沉稳地说:“不急,我们正在制定一套更完善的规范。”

互联网的普及让企业应用开始Web化,它们产生了新的需求:安全、事务、分布式……程序员不想管,操作系统也管不了。这时,Java拉着WebLogic、WebSphere、JBoss等中间件登场了。“让开,这些交给我们来管!”它们提供声明式的事务管理、安全管理,并通过EJB(Enterprise JavaBeans)组件模型,让分布式部署变得简单。

J2EE(Java 2 Platform, Enterprise Edition)是一套庞大的企业级开发规范。EJB负责核心业务逻辑与分布式,JTA管理事务,JSP处理页面,JMS对接消息队列……一时间,会写EJB成了时髦的技能,“今天你J2EE了吗?”成为程序员间的问候语。

但渐渐地,大家发现J2EE,尤其是EJB,变得繁琐而笨重,开发、测试、部署都困难重重,项目延期成了常态。就在这时,救星出现了。Rod Johnson举着《J2EE Development without EJB》的大旗,搭建了Spring帐篷。“来我这里吧,”他喊道,“支持依赖注入和AOP,把业务逻辑放到简单的POJO(Plain Old Java Object)里就行!”被EJB折磨已久的程序员们纷纷涌入。

很快,Spring的营地旁又支起了两顶帐篷:负责Web层控制的Struts和负责数据持久化的Hibernate。每天清晨,程序员们走出各自的帐篷,聚集在“SSH部落”的旗帜下。这个经典组合,统治了相当长一段时间的Java 后端开发领域。

Java和J2EE阵营傻眼了,没想到开源框架如此好用且深入人心。Spring、Struts、iBatis等对EJB发起“群殴”,连收费的WebSphere和WebLogic也被“干翻”。于是,“招安”计划启动。Spring之父Rod Johnson加入了制定Java标准的组织JCP,Hibernate之父Gavin King也参与了EJB 3.0标准的制定,将开源社区的优秀思想注入官方标准。

即便如此,依然难挡J2EE(后更名为Java EE)的颓势,最终被Oracle抛弃,进入Eclipse基金会后更名为Jakarta EE。与此同时,一个强劲的挑战者出现:Ruby on Rails (RoR)。它高举“约定优于配置”和“不要重复自己”的大旗,宣称开发速度是Java的十倍,吸引了大批追求效率的程序员。

面对RoR的挑战,Java找来了同根同源、运行在JVM上的动态语言小弟Groovy及其Web框架Grails。同时,Java自身也在“苦练内功”,陆续引入了泛型、注解,并在JDK 8中加入了强大的函数式编程能力。大神Doug Lea更是献上了并发编程的利器。一旁的C++和Python感叹:“看来以后想嘲笑他都不容易了。”

新的挑战并未停止。JSP跑来向Java诉苦:“老大,我快失业了,写页面的活儿都被JavaScript抢了!”JavaScript可没闲着,它在家里打造了威力无比的武器——Node.js。凭借事件驱动、非阻塞I/O模型,Node.js能够用少量资源处理高并发,并且通吃前后端,带领程序员大军冲向Java的后端领地。

Spring、MyBatis等有点招架不住,赶紧向后方求援。Java的援军很快到达战场:高性能网络框架Netty、响应式编程工具包Vert.x,以及Spring家族的反应式Web框架Spring WebFlux。它们帮助Java阵营在微服务和高并发场景下稳住了局面。

微服务时代到来,Java不敢怠慢。它向Spring抱怨:“用现在的Spring MVC开发应用太复杂,配置一大堆,不符合微服务快速迭代的趋势啊!”Spring不慌不忙地推出了Spring Boot:“我开箱即用,无需繁琐配置,内嵌服务器,一个JAR文件就能运行。”

Netflix也带着它的实战成果加入了阵营:“只有Spring Boot可不够,微服务还需要服务发现、负载均衡、熔断降级等能力。”于是,Spring Cloud诞生了,它将Netflix OSS等一系列微服务治理组件无缝整合,形成了强大的微服务开发生态。

Spring Boot高兴地骑上Docker容器,在微服务的海洋中遨游。但回头一看,Go、Node.js、Ruby等语言也骑着Docker跟了上来。“你们怎么也来了?”“我们都能开发微服务,为什么不能来?我的并发能力还比你强呢!”“你们有服务发现、熔断降级吗?”“马上进入Service Mesh时代了,你说的这些都会变成云的基础设施,我们只管写业务逻辑就行!”

岸边的Java程序员忧心忡忡。Java却显得从容:“完全不用担心,我们有着庞大的生态系统,不是轻易能撼动的。况且,我们的疆域早已扩张。”它指向远方,“看,我们在移动开发(Android)和大数据(Hadoop)领域也已占据了重要地位。”

后记
所谓的“干翻一切的王者语言”现在还不存在,未来或许会是“Z语言”吧!😊
本文本想为Java立一部漫画传记,没想到仅梳理其后端开发历程就已篇幅颇长,Android与大数据领域只能略微提及。虽然Java拥有庞大的生态系统,但想要“干翻”别人也绝非易事。
这引出了一个有趣的思考:为什么一个新生的技术或语言很难撼动旧有的霸主?核心原因在于“生态位”已被占据。当一个语言或技术栈的生态系统(包括框架、工具、类库、文档、社区及现存系统)变得非常成熟时,后来者除非具备压倒性的优势,或者精准地踏中了某个技术变革的“风口”,否则很难实现替代。
Java的成功,恰恰是因为它精准地踏中了服务器端开发的风口。在上世纪90年代末至本世纪初,用C/C++进行企业级Web开发显得笨重且效率低下;而Perl、PHP等脚本语言虽灵活,但在构建大型、复杂的“正规”企业应用时,常被认为在工程化和性能上有所欠缺。Java凭借其“一次编写,到处运行”的特性、稳健的面向对象设计以及逐步完善的J2EE企业级规范,恰到好处地填补了这个市场空白,并由此蓬勃发展至今。
反观其他技术,例如.NET Core,它所要做的事情,现有的Java、Go、Node.js等生态几乎都能胜任。想让广大程序员从一个成熟、稳定的生态整体迁移到另一个生态,这其中的成本和阻力是巨大的。因此,构建和维护一个健康、活跃的开发者社区与生态,其重要性不言而喻。在云栈社区这样的平台上,技术的演进、优劣的讨论以及生态的构建,正是开发者们持续关注和参与的核心话题。