Java 并没有死!

640?wx_fmt=gif

【优快云编者按】似乎一件事存在久了,就会被唱衰。人们不相信有经久不息的实物。但是,Java似乎是一个特例。

那么,Java这朵“永生花”是怎么永葆青春的呢?一起来看本文作者API Fortress的CTO Simone Pezzano的现身说法吧。

640?wx_fmt=jpeg

作者 | Simone Pezzano,CTO@API Fortress。

译者 | 弯月

责编 | 胡巍巍

出品 | 优快云(ID:优快云news)

我是一个从事Java / Scala / Groovy工作的家伙,这不是一个秘密。有些人,特别是年轻人,在听到这话时就会冲我翻白眼。

与现代语言相比,Java老套、低效、而且已经完蛋了,基本上他们都会这样对我说。然而,实际情况确实如此吗?

 

640?wx_fmt=png

老套

 

没错,Java的基本结构和限制都比较老套,而且还依赖于20年前写代码的方式。

编程语言并不是凭空产生的,开发人员的习惯和需求是语言设计的核心,虽然语言的发明者试图将创新融入其中,但是忽略人们实际的使用方法是很愚蠢的做法。

Java史上的第一个里程碑可以追溯到1995年,虽然它的一些基础模块的设计看起来至少有10年的远见,然而很明显,24年后的今天……看起来不是那么一码事了。

但这不仅仅是时间的问题。在过去的十年中,Java发生了很多变化。其中一些变化似乎与Java本身无关,却无比重要。

例如,廉价的内存对于生产软件中大规模重新采用函数编程起着举足轻重的作用。而这又与反应式宣言(The Reactive Manifesto)息息相关。

便于访问和管理的云计算促进了微服务模型概念的发展,这种模型随着容器的出现走向了生产环境。

于是,在微服务模型的发展中,一些非常适合于某些任务,但在其他任务上表现平平的编程语言脱颖而出。

编程语言世界的变化远不止于此,大数据带来的新挑战催生了专门为处理大数据而优化过的新的数据库系统,这些数据库能够摄取大量的数据,然后对其进行分析。

实际上,这并没有催生新的语言,而是为适合于这项任务的语言找到了另一种使用方式。

更不用说人工智能又一次掀起了争先恐后的热潮。

但是,等一下......

如今,Python成为了机器学习的黄金标准,但是如果快速浏览一下它的维基百科页面,你就会发现Python的诞生早于Java,甚至可以追溯到1990年!

那么R呢?这可是数据分析常见的选择。R语言始于1993年。

那么JavaScript呢?奇怪的是,JavaScript出现于1995年,与Java同年!

Erlang呢?1986年......

为什么没人说这些语言老套,却单单说Java呢?

因为我们改变了,还有我们面临的挑战也发生了变化。

例如,Python一直是编写实用工具和数据处理程序的一种出色的脚本语言,但通常我们不认为它适合于臃肿的企业应用程序。

然而,一般来说微服务是一些小程序和数据管道,它们由明确定义的功能型小组件组成。

一直以来,JavaScript是动态网页的唯一解决方案,但随着复杂Web应用程序的激增,将JavaScript带到服务器端也算合情合理。

总而言之,我们说Java老套,只是因为它非常适合构建臃肿的单体应用,这些应用往往拥有数百万行的代码量,需要大量的规划和严格的顺序,而Java的设计目的本来就在于此。

如果试试看用JavaScript构建这样的应用,你很快就会意识到“死亡不是终点 ,而是一种转变”(摘自:梦剧院乐队的歌曲《Fatal Tragedy》)。

 

640?wx_fmt=png

低效

 

听上去确实如此。

我经常用下面的比喻来解释Java:

如果你需要做一个火柴盒,那么首先你需要10吨木材,建造一个小木屋,然后再一点点削成火柴盒。

由于Java强调用一种正式严谨的方法来鼓励开发人员创建适当的类层次结构,所以开发人员即使觉得这种做法很白痴,也不得不采用正确的方式设置所有内容,即使对于一个非常小的任务也是如此。

然而,这就是问题所在,就像我们上面所说,Java的任务都不容易。

请注意,我所说的“不容易”指的是不容易实现,但在架构方面却很容易。

编写错综复杂的算法是一项艰巨的任务,而且我发现用Python来写更容易。

对于这一点,很明显我们一直在反复讨论同一个概念:选择正确的工具。

一直以来,Java都是一种非常通用的编程语言,而且被用于解决各种情况下各种类型的问题,但随着时间的推移和挑战的变化,似乎越来越明显Java也并非无所不能——这并不是因为它已经演变成了一种专门的语言,而是因为其他语言更加擅长处理特定的任务。

如果你想构建一个大型企业平台,其中包含大量的内部构造,巨大的代码库,疯狂的并行性等等。

那么Java仍然很给力。等一下,真的是这样吗……?

 

640?wx_fmt=png

Java已经完蛋了

 

也许有点阴暗,但是有一句话说的好:“不要害怕未来,你也活不了那么长。” 你是不是感觉想笑……

Java就像一名开发人员一样,随着时间流逝一天天老去,你不再像10年前那样拥有清醒的头脑,但是你会变得更聪明、稳定和可靠。

当然,你仍然可以学习Rust,但你永远无法像比你年轻10岁的人那样,你总觉得哪里不对劲。

同样,Java也在现代化的竞争中不断落后,当新功能出现时,你总感觉在经历了诸多波折后,它们终于成为了现实。

例如,当他们第一次引入lambdas时,你的反应不是:“哇!欢呼吧!”,而更像是:“天啊,为什么到现在才出来啊?”

另一方面,人们没有意识到Java的最大成就不在于语言本身。

 

640?wx_fmt=png

良好的生态系统

 

在规划大型软件时,让我想起Java的另一个因素就是Java的生态系统。无论是何种互联网上你梦寐以求的东西,Java都可以为你提供卓越高品质的库。

想想Spring、Akka、Tomcat等等(我可以说出来几百个),这些都不是业余项目,而是非凡的成就。

我并不是说其他语言做不到,但是在大企业的推动下,Java创造了这种软件生存的先决条件。

此外,一个良好的生态系统需要花费数年才能培养起来,时间因素也非常重要,对于Java生态系统成熟来说,20年可以说是很长的时间了。

当然,你也可以找到适用于多种语言的特殊库,但是很快你就会意识到这些库的存亡,在很大程度上取决于大公司是否认可这些项目。

例如,为Python找到好的机器学习库非常容易,但你不能否认Google在其中发挥的作用。在Facebook的支持下,你才有了React.js(Javascript)开发出色的Web应用程序。

 

640?wx_fmt=png

Java最大的成就是JVM

 

除了我们之前提到的庞大生态系统之外,Java最大的成就是JVM。虽然语言可能因年龄的增长而面临重重困难,但至少在我看来JVM很健康。

如今,有人可能会说容器化已经削弱了对JVM的需求,从某种意义上说,此言非虚。

JVM最初的需求是允许程序在所有操作系统上执行,但容器改变了一切,因为在容器的帮助下,我们可以假定操作系统可以在任何地方运行,甚至是纸上。

然而,JVM的作用远不止于此。内存管理和垃圾收集、安全性、基本编程库以及调试和检查功能,JVM承担起了所有的这些工作,为我们提供了一个安全舒适的环境。

人们常常反驳我说:“但是JVM非常臃肿,非常慢!”虽然从内存的占用和引导时间来看,这话没错,然而从性能的角度来看,过去的20年中发生了很多变化。

我们经常会通过常用的算法,进行下述的比较:

  • Python 3 Vs. Java 

  • Node js Vs. Java

  • Go Vs. Java 

  • Erlang HiPE Vs. Java

虽然这种比较对一些语言不太公平,因为算法只是性能因素的一部分,但从中可以看出JVM绝非病入膏肓。

 

640?wx_fmt=png

然而…...

 

从某种程度上,我同意虽然JVM状况良好,但Java却在努力保住自己的地位。

Oracle明白这种形式,而且他们正在努力再次将Java推向巅峰,虽然这种做法会产生一些意想不到的后果,但没人能够阻止老化的过程。

然而,这也未必是一件坏事。

JVM充当了创建效率更高的现代化语言的平台。虽然不是很多,但凭良心说,有一些还是非常成功的。

这就是关键所在。Java这个霸主并没有死,虽然有些咳嗽。然而,它的后代将继续传承它的遗产。

  • Scala。我的第二个心中所爱。这是一种非常强大的语言,它是静态类型、面向对象的函数式编程语言。虽然仍未被广泛采用,但目前它是最值得投资掌握的技术之一。Scala是Play Framework的实现语言,它还经常和Akka的actor模型搭配使用。

  • Clojure。一种被广泛接受的类似于Lisp的语言,以其在并发计算方面的强大功能而闻名,它经常用于处理庞大的数据集。

  • Groovy。动态编程的脚本语言,我常常觉得它与Java非常类似。Groovy广泛用于脚本编写,也是支持Grails框架的语言。

  • Kotlin。虽然最后一个出场,但并不是说这种语言不重要,它是JetBrains的静态类型面向对象的函数式编程语言,如今是Google Android开发的首选工具。

上述我们讨论的不是Java的扩展。这些是全新的编程语言,但它们都借鉴了Java,最重要的是它们充分利用了JVM和Java生态系统。

 

640?wx_fmt=png

但实际上......

 

Java编程语言不会在近期内走向消亡。

不仅因为大量的软件都是用Java编写的,而且无论你同意与否,它虽然有缺陷,但仍然是一种久经考验非常适合于新项目的编程语言。

当然,Java承担的角色会发生变化。从前“你唯一需要的只有Java”,而如今只能在部分领域发挥作用,但它仍然是坚实可靠的一部分。

虽然我对Scala非常感兴趣,但是我也必须说Oracle和社区在改进Java方面做出了很大贡献,我们都享受着这些改进带来的优势。

虽然新功能的到来比我们预想得晚,但在质量上却没得说。

毕竟,编程语言发展缓慢可能意味着被弃用,也可能是成功的标志。

既然人们如此大规模地使用你的编程语言,那么你就不得不认真地对待所有的重大改变。

你所做的每一步都需要考虑影响的程度,以及向后兼容性的方式。任何问题都不能掉以轻心。

 

640?wx_fmt=png

总结

 

我在这个领域已经很长时间了,所以我有理由相信我对Java这门编程语言的某些特质有了一定的了解。

在过去10年中,这个领域的发展加快了速度,但是这些发展主要集中在某些领域。

出现这样的情况时,你可能会感觉一切都将发生变化。这些发展让部分人过于激动和兴奋,所以他们四处喧嚷。

但是,当喧嚣过后,你就可以清楚地看到这些发展的真实本质,并尽力利用好这些发展。

正如我上述所说,Java依然是Java,但是坦白地说,多年来Java努力达成的所有辉煌还无人能及。

我想对你们所有人说——无论是年轻人还是老年人,无论你喜欢还是讨厌Java:享受这个美妙的科技时代带来的多样性!

原文:https://dzone.com/articles/java-is-not-dying-yet

本文由优快云翻译,转载请注明来源出处。

【End】

长三角开发者联盟

代码就是力量,长三角的开发者联合起来!

加入「长三角开发者联盟」将获得以下权益

长三角地区明星企业内推岗位
优快云独家技术与行业报告
优快云线下活动优先参与权
优快云线上分享活动优先参与权

 

扫码添加联盟小助手,回复关键词“长三角1”,加入「长三角开发者联盟」。

640?wx_fmt=jpeg

全面学python的时代,作为程序员你怎么看?

https://edu.youkuaiyun.com/topic/python115?utm_source=csdn_bw

 热 文 推 荐 

☞ 华为效仿苹果卖高价手机?滴滴顺风车开放灰度测试;苹果官微被投诉“攻陷”| 极客头条

☞ Python 爬取吴亦凡的 10 万转发数据,扒一扒流量的真假!

☞ 优秀的程序员是如何诞生的?

 杨镭访谈:UCloud 的技术价值观

☞ 普通人也能用AI拍出3D大片?这位清华博士后这么做

☞ 码二代的出路是什么?

☞ 小程序的侵权“生死局”

☞ 19岁当老板, 20岁ICO失败, 21岁将项目挂到了eBay, 为何初创公司如此艰难?

☞ 她说:为啥程序员都特想要机械键盘?这答案我服!

 

 

System.out.println("点个在看吧!");
console.log("点个在看吧!");
print("点个在看吧!");
printf("点个在看吧!\n");
cout << "点个在看吧!" << endl;
Console.WriteLine("点个在看吧!");
Response.Write("点个在看吧!");
alert("点个在看吧!")
echo "点个在看吧!"

640?wx_fmt=gif点击阅读原文,输入关键词,即可搜索您想要的 优快云 文章。

640?wx_fmt=png你点的每个“在看”,我都认真当成了喜欢

<think>首先,用户的问题是基于引用的内容:“我想查找Java应用假的原因和解决方案 请问Java应用假的原因及解决办法”。用户提供了几个参考资料,我需要参考这些引用来回答。 引用内容总结: - 引用[1]: 强调确定假现象。 - 引用[2]: 列出常见原因:资源耗尽(内存不足、CPU使用率高)、锁、无限循环、外部依赖问题。 - 引用[3]: 描述了一个具体案例,涉及定时服务和多线程问题。 - 引用[4]: 提到应用假排查过程,涉及OutOfMemory问题,优化byte[]和增加堆大小。 用户的问题是:“Java应用假的原因及解决办法”。所以,我需要给出原因和解决方法。 我的回答必须遵循系统级指令: - 所有行内数学表达式用$...$格式。但在这个主题中,可能没有数学表达式,所以可能不需要。 - 独立公式用$$...$$,单独成段。同样,可能不适用。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题:结束时,添加相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。我需要基于提供的引用进行引用。 回答结构应该清晰,帮助用户逐步解决问题。确保回答真实可靠。 结构化回答: 1. **介绍**:简要解释Java应用假的概念。 2. **原因**:列出常见原因,基于引用[2]和其他引用。 3. **解决方法**:针对每个原因提供解决方案。 4. **排查步骤**:提供通用的排查方法,参考引用[1]和[4]。 5. **总结**。 6. **相关问题**:结束时生成相关问题。 引用标识: - 当引用具体内容时,在末尾添加[^n],n对应引用编号。 - 例如,提到资源耗尽时,引用引用[2]。 确保使用中文。 生成相关问题: - 在结束时,添加“§§相关问题§§”部分,列出2-3个相关问题。 详细内容: - **原因**: - 资源耗尽:CPU使用率过高或内存不足[^2]。 - 锁:线程互相等待资源[^2]。 - 无限循环:消耗CPU资源[^2]。 - 外部依赖问题:如数据库连接失败[^2]。 - 其他:如引用[4]提到的OutOfMemory问题。 - **解决方法**: - 资源耗尽:监控资源使用;优化代码;增加资源(如堆大小)[^4]。 - 锁:使用工具(如jstack)检测锁;避免嵌套锁;使用超时机制。 - 无限循环:代码审查;日志调试;CPU分析。 - 外部依赖:添加超时;重试机制;隔离故障。 - 通用:使用JVM工具(如jstat, jmap, jstack)排查。 - **排查步骤**: - 确定现象:检查日志、监控指标[^1]。 - 分析线程:使用jstack dump线程堆栈,查找锁或卡住线程[^3]。 - 内存分析:使用jmap dump堆内存,检查内存泄漏[^4]。 - CPU分析:使用top或jstack查找高CPU线程。 相关问题: 1. 如何使用jstack工具排查Java线程问题? 2. Java内存泄漏的常见原因和检测方法? 3. 如何监控Java应用的资源使用以防止假? 确保回答清晰、步骤化。 </think>### Java应用假的原因及解决方法 Java应用假是指应用程序表面上无响应,但仍在运行的状态,这会导致性能下降和用户请求超时。基于提供的引用,我将系统地分析原因提供解决方案。排查过程应遵循“观察→分析→修复”的步骤。以下是详细解析。 #### 原因分析 Java应用假的常见原因主要包括资源耗尽、线程问题、代码缺陷和外部依赖故障等。以下是基于引用总结的核心原因: 1. **资源耗尽**:最常见的原因,包括: - **内存不足**:堆内存或直接内存耗尽,导致频繁GC(垃圾回收)或OutOfMemory错误,应用无法分配新对象[^2][^4]。 - **CPU使用率过高**:CPU资源被过度占用,导致线程调度延迟,应用无法处理新请求[^2]。例如,引用中提到“无限循环消耗大量CPU资源”[^2],或“业务量增加导致byte[]占用过高内存”[^4]。 - 引用数据显示,这是约50%假案例的直接根源[^2][^4]。 2. **线程问题**: - **锁**:多个线程互相等待资源释放,导致所有相关线程卡(如引用[2]所述“[锁:多个线程互相等待对方释放资源]”)[^2]。 - **线程阻塞**:线程在I/O操作、锁竞争或外部调用中无限期等待(如引用[3]的定时服务案例,“所有线程执行完成则当次任务执行完成”时卡)[^3]。 - 引用表明,锁在发应用中占比高达30%的假问题[^2][^3]。 3. **代码缺陷**: - **无限循环或递归**:算法逻辑错误导致循环(如引用[2]提到的“无限循环,消耗大量CPU资源”)[^2]。 - **内存泄漏**:对象未被GC回收,内存占用持续增长,最终引发OOM(OutOfMemory)(如引用[4]的“byte[]占用问题”)[^4]。 4. **外部依赖故障**: - 数据库、API或网络服务不可用,导致线程在等待响应时卡住(引用[2]描述“[外部依赖问题:服务依赖的外部系统出现问题]”)[^2]。例如,连接池耗尽或超时设置不当。 #### 解决方法 针对上述原因,提供分层解决方案。推荐结合JVM工具(如jstack、jmap)排查。 1. **通用排查步骤**(参考引用[1]和[4]): - **步骤1: 确定现象**:监控应用日志、系统资源(CPU、内存使用率)。使用命令如`top -H`(Linux)或任务管理器(Windows)查看资源瓶颈。确认是否为假而非完全崩溃[^1]。 - **步骤2: 线程分析**:运行`jstack <pid>`导出线程堆栈。检查线程状态(如“BLOCKED”或“WAITING”),识别锁或阻塞点。引用[3]案例表明,定时任务卡往往源于线程锁[^3]。 - **步骤3: 内存分析**:使用`jmap -dump:live,format=b,file=heapdump.hprof <pid>`导出堆内存快照。工具如Eclipse MAT分析内存泄漏(如byte[]过大问题[^4])。 - **步骤4: CPU分析**:结合`jstack`和`top`,找出高CPU线程,检查代码逻辑(如无限循环)。 2. **针对性修复**: - **资源耗尽**: - 优化内存:增加JVM堆大小(如`-Xmx4g`),修复内存泄漏(避免静态集合持有对象)。引用[4]通过“优化byte[]和增加堆大小”解决OOM[^4]。 - 降低CPU:使用异步处理或限流机制;监控工具如Prometheus预警。 - **线程问题**: - 避免锁:使用锁超时(如`ReentrantLock.tryLock(timeout)`);代码审查避免嵌套锁。 - 线程管理:设置线程池超时(如`ThreadPoolExecutor`的`keepAliveTime`);引用[3]的多线程任务需添加超时控制[^3]。 - **代码缺陷**: - 修复无限循环:添加循环退出条件;使用静态分析工具(如SonarQube)。 - 预防OOM:优化数据结构大小;定期GC调优(如`-XX:+UseG1GC`)。 - **外部依赖故障**: - 添加超时和重试:例如,在HTTP调用中使用`HttpClient`设置超时参数;隔离故障服务(Hystrix模式)。 3. **预防措施**: - 监控:集成APM工具(如SkyWalking或Prometheus),实时报警资源阈值。 - 测试:压力测试模拟高发;锁检测工具(如VisualVM)。 - 最佳实践:遵循线程安全编程;定期代码审查。 #### 总结 Java应用假通常由资源耗尽或线程问题引发。排查时,优先使用`jstack`和`jmap`定位根源,然后针对性优化代码或配置。引用案例显示,80%的问题可通过资源监控和线程分析解决[^2][^4]。如果假频发,建议结合日志和工具深入诊断。
评论 16
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值