1 语言优劣论

世上只有两种编程语言:一种被人骂,一种没人用。

Java已经诞生20多年了,依然是企业级开发中使用最广泛的语言,也是挨骂最多的语言。技术圈经常有“A语言比B语言更好”的争论,争论的核心有两点:语法和性能,比如“Java性能不如C#、Python语法比Java优雅”。

先谈谈语法的优劣。每个开发者都有自己偏爱的语法。你觉得很舒服的写法,就有人觉得别扭,这是个主观问题。比如Java 8 中的Lambda表达式,可以极大的优化集合操作的代码结构,但是不少人反感 () -> {} 这种符号,不愿意在项目中使用。再举个例子,Java语言定义变量的方式是数据类型前置、变量名后置,如: int maxSize = 100;而Go语言中变量名是前置的,如:var maxSize int = 100,写惯了Java的人肯定不适应变量名前置。习惯的力量太大了,许多人将自己的偏爱当成评判的标准。

再谈性能的优劣。编程语言的开发团队固然希望性能更好,但是性能优化要一步一步来。我们要用发展的眼光看待性能问题,早期的Java编译器和虚拟机性能确实堪忧,发展到如今已经改善了不少,以后也会继续提升。如果一款语言性能真的差到无法接受,绝不会用于企业开发中。每种语言的使用场景不同,C语言的性能固然高于Java或者C#,为什么没有人C开发Web项目?在需求快速迭代的项目里,开发效率更重要,性能够用就行,通俗的说就是人比机器贵。通常项目中遇到的大部分的性能瓶颈,降级需求或者优化设计方案就能解决,许多程序员的水平还没有达到可以指责语言性能的程度。

企业选择某款编程语言作为生产力工具,首先考虑的是人力招聘和培养的成本,其次才是语言特性和开发效率。这些年出现了许多新语言如Golang、Rust,也许概念更先进、性能更好,但是企业不会轻易在核心系统上采用新语言,以免出现不可预估的风险,保持系统的稳定才是最重要的。

2 Java的争议

1995 年 5 月 23 日,Java 正式发布。经过20多年的发展,Java孕育出了大量的开源组件和开发者。在它诞生的年代,相比其他语言有五个优势:

(1)简单易学:没有指针操作和手动内存分配,易学易用,程序员心智负担较小。

(2)面向对象:仅支持面向对象编程,单一的编程范式可以避免工程过度复杂。

(3)网络编程:提供了更简单的网络编程库,适合构建大型的网络分布式系统。

(4)反射机制:通过反射机制增强了语言的动态性,大部分开发框架都用到了这个特性。

(5)跨平台:通过JVM屏蔽了底层硬件的差异性,为上层应用提供统一的接口。应用程序被编译成与计算机结构无关的字节码,可以运行在不同的操作系统中。

事物总是有两面性,为了解决一个问题引入一个特性,也必然带来新的问题。我们应该如何辩证的看待Java广受诟病的几个问题呢?

  • 性能差

通常有GC语言不提供非常底层的内存操作方法,因此不可能达到无GC语言的性能,而且当虚拟机彻底回收垃圾时,应用程序会被强制停止,某些需要低延迟的场景绝不能接受这种状态。事实上,如果进行数值计算的基准测试,Java比 C++没有慢多少,企业开发中的Java项目速度慢的根本原因是框架滥用反射,加载反射代码要比普通程序慢几十倍,编译器没法优化反射代码。在资源紧张或者高性能场景下,C / C++仍然是首选,Java无法胜任。

  • 内存占用大

Java应用程序启动后包含JVM实例,一个“Hello World”都要消耗几十兆内存。每个Java的对象都要包含一个96 bits的对象头,一个32bits的integer就要占用内存96bits+32bits=128bits。向Go这种面向值的语言,每个值的存储消耗最低仅为2bits。企业级框架Spring大量采用HashMap缓存数据,也是极度消耗内存的。

  • GUI弱

Java桌面软件的性能低、开发体验也差。最新的GUI库JavaFX比Swing、AWT进步很多,但是远远不如Qt(C++)、WinForm / WPF (C#) 等框架。从商业角度考虑,多数企业软件并不需要跨平台,运行在Winows就足够了,少量的要兼容MacOS,Java跨平台特性在这种情况下反而是鸡肋。谷歌选择Java语言开发Android应用,看重的是庞大的Java生态,而不是语言特性。

  • 代码啰嗦

Java仅支持面向对象编程范式,书写起来极为啰嗦,比如main方法不能是一个独立的函数,必须放在没有实际意义的class中。好处是风格统一,坏处就是死板和啰嗦。采用Spring框架开发的Java项目,只要遵循基本的代码规范,每个人写出来的都差不多,可读行不会太差。与之相反,C++这种多范式语言,非结构化、结构化、面向对象、宏、模板等等应有尽有,灵活性极大,要精通也很难。维护一个大型的C++项目,就像在读一本百科全书。

3 云原生的考验

云计算是一种实施模式,是指通过互联网方式交付存储、服务器、应用等等。“云”是一种管理 IT 资源的方法,能够取代本地设备和私有数据中心。在云计算模式下,用户无需购买和维护大量的计算、存储和其他 IT 基础设施,直接访问云计算提供商的计算、网络和存储资源即可。云服务提供商能够保障物理设备的正常运转、资源的按需调配等等。

云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。云原生是Cloud+Native的组合词,Cloud表示应用程序位于云中,而不是传统的数据中心;Native表示应用程序从设计之初即考虑到云的环境,原生为云计算而设计,可以充分发挥云计算平台的弹性和分布式优势。云原生架构有4个重要的实施原则:

(1)DevOps:采用自动化工具将应用快速部署到生成环境,并且让开发、运维互相协作。

(2)持续交付:支持频繁持续的发布应用,快速反馈部署故障,有效降低发布风险。

(3)微服务:将庞大复杂的单体服务拆分为更小的微服务,每个微服服可以快速、独立的部署。

(4)容器化:将应用程序及依赖项打包成镜像,以容器化的方式快速分发。

在虚拟化技术没有广泛应用的阶段,部署应用程序是个繁琐的事情。为了让程序在Linux、Windows等平台以及x86、AMD64、SPARC、MIPS、ARM等指令集架构上都能正常运行,必须先将源码编译为对应的可执行文件,或者直接分发源代码,由使用者自行构建可执行文件。Java发布时,提出了一句动人的口号:一次编写,到处运行”(Write Once, Run Anywhere),解决了应用部署的痛点。在云原生架构下,Java以及JVM的特性面临了新的挑战。

在微服务的背景下,围绕业务能力而非技术来构建应用,允许由不同的语言构建应用程序。一个大型的微服务集群,往往有成千上万个容器在运行。为了更有效率的管理容器,对微服务有几个诉求:镜像体积小、内存消耗少、启动速度快,这些却都是Java的弱项。再小的Java程序也带着完整的虚拟机和标准类库,这样会降低拉取镜像和创建容器的效率;Java的程序都会有固定的基本内存开销和启动时间,开源框架Spring等广泛采用的依赖注入也使得容器的启动时间过长。最好解决方案是,将Java源码直接编译为二进制可执行文件,再将可执行文件打包为镜像。

GraalVM是Oracle实验室推出的基于Java开发的开源高性能多语言运行时平台,它既可以在传统的 OpenJDK 上运行,也可以通过 AOT(Ahead-Of-Time)编译成可执行文件单独运行。GraalVM将源代码打包成可执行代码,运行时不包含JRE,实现秒级别的启动,占用内存更小。

知名开源框架 Spring 的研发团队也发布了 Spring Native 项目,利用 GraalVM 将 Spring 应用生成可执行的原生镜像(Native Image)。这些原生镜像的启动速度极快、内存消耗也更少,但是比JVM的构建时间更长、运行时优化也不足。目前 Spring Navtive 仍然处于孵化阶段,国内公司用于生产环境的很少。

参考

https://www.cnblogs.com/JaxYoun/p/16483067.html

https://zhuanlan.zhihu.com/p/333926379

https://zhuanlan.zhihu.com/p/150190166

https://www.codingbrick.com/archives/1130.html

老者Java,奋战一线的更多相关文章

  1. 2020阿里,字节跳动,JAVA岗(一线企业校招、社招)面试题合集

    前言 以下面试题全属于一线大厂社招以及校招的面试真题,各位在做这些题目对照自己的时候请平凡心对待,不要信心受挫.其实 做为致力于一线企业校招或者社招的你来说,能把每个知识模块的一小部分问题去深入学习和 ...

  2. 记一次MyBatis的错误

    错误信息:java.lang.StackOverflowError 关于这个错误的深度解析,大家可以参考这篇博文,比较详细:https://blog.csdn.net/zc375039901/arti ...

  3. 关于模板中的动态取值 ---反射与javascript脚本编译

    在项目中经常遇到一个问题,打印word或者打印excel的时候,我们经常使用一对一的赋值或者批量替换的方式来对模板进行修改. 但是现在遇到两种场景: 1.取值是通过自定以方法进行取值的. 如:一个销售 ...

  4. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  5. 一线互联网企业常见的14个Java面试题,Java面试题集大全等你拿,颤抖吧程序员!

    本文由尚学堂学员们根据自己参加过的面试回忆.总结而成,一线互联网企业常见的14个Java面试题,包括各大互联网企业.创业小公司,互联网企业.传统软件公司.对于刚毕业和想要跳槽的宝宝们,再适用不过啦,赶 ...

  6. 备战金三银四!一线互联网公司java岗面试题整理:Java基础+多线程+集合+JVM合集!

    前言 回首来看2020年,真的是印象中过的最快的一年了,真的是时间过的飞快,还没反应过来年就夸完了,相信大家也已经开始上班了!俗话说新年新气象,马上就要到了一年之中最重要的金三银四,之前一直有粉丝要求 ...

  7. 新知识:Java 利用itext填写pdf模板并导出(昨天奋战到深夜四点,知道今天两点终于弄懂)

    废话少说,不懂itext干啥用的直接去百度吧. ***************制作模板******************* 1.先用word做出界面 2.再转换成pdf格式 3.用Adobe Acr ...

  8. 一线互联网常见的14个Java面试题,你颤抖了吗程序员

    跳槽不算频繁,但参加过不少面试(电话面试.face to face面试),面过大/小公司.互联网/传统软件公司,面糊过(眼高手低,缺乏实战经验,挂掉),也面过人,所幸未因失败而气馁,在此过程中不断查缺 ...

  9. 一线互联网常见的 14 个 Java 面试题,你颤抖了吗程序员

    跳槽不算频繁,但参加过不少面试(电话面试.face to face 面试),面过大 / 小公司.互联网 / 传统软件公司,面糊过(眼高手低,缺乏实战经验,挂掉),也面过人,所幸未因失败而气馁,在此过程 ...

  10. 2018“金三”之一线互联网公司Java高级面试题总结

    JVM 1.请介绍一下JVM内存模型??用过什么垃圾回收器都说说呗 2.线上发送频繁full gc如何处理? CPU 使用率过高怎么办? 如何定位问题?如何解决说一下解决思路和处理方法 3.知道字节码 ...

随机推荐

  1. 【专业技能】程序员的软件工程素养之画好 UML 时序图

    目录 前言 一.认识时序图 1.1时序图元素 1.2怎么使用 二.画好时序图 2.1一般步骤 2.2举个例子 2.3推荐工具 三.其它作用 四.文章小结 前言 笔者在本科的时候上过软件工程的专业课,也 ...

  2. FastGithub.UI64位中文版V2.1.4绿色版 - 软件推荐

    推荐理由 相对于改hosts,这个更好用 FastGithub.UI64位中文版V2.1.4绿色版 https://www.cr173.com/soft/670733.html

  3. 移远4G数传模块EC800M开发总结之基本备忘

    一 前记 1 EC800M模块是移远推出的小尺寸低功耗针对可穿戴市场的数传产品.笔者在几个产品上使用过程中,遇到了一些问题. 这里做个备忘吧. 二 梳理 1 工具,这个串口的默认波特率为115200. ...

  4. python 创建文件夹并写入文件源码

    废话就不多少说了,直接上源码吧. import time import os folder = os.getcwd() folder = folder + '/test/' print(folder) ...

  5. 基于ADS1292芯片的解决方案之源码解析

    接口解析  A 该芯片和主控使用的是SPI接口通信的. SPI接口一般有四根线,确保四根线准确连接是对的. B 该芯片可以有中断模式数据触发,所以,主控mcu需要有外部中断处理流程. //DRDY中断 ...

  6. Oracle数据库中sql查询很快,但在程序中查询较慢的原因和解决方法

    代码如下 string sql = "SELECT * FROM LIS_V_LABTESTSAMPLE WHERE PATIENT_ID=:P";            HlsA ...

  7. 后端基础PHP-PHP简介及基本函数

    后端基础PHP-PHP简介及基本函数 1.PHP简单介绍 2.PHP基本语法 一.PHP简单介绍 PHP(超文本预处理器),是一种通用的开源脚本语言,标准的后端语言 比较常见的后端语言,ASP|ASP ...

  8. day01-HTML01

    day01-HTML 1.JavaWeb技术体系 2.B/S软件开发架构简述 B/S架构 B/S框架,意思是前端(Browser浏览器,小程序,APP,或者自己写的)和服务端(Server)组成的系统 ...

  9. 杂谈之WEB前端工程师身价

    了解javascript语言规范么?+1000 知道各浏览器的css差异么?+1000 javascript差异呢?+1000 知道html各标签的含义并很好地运用么?+1000 知道如何跨浏览器解决 ...

  10. MD5算法:密码学中的传奇

    MD5算法起源: MD5(Message Digest Algorithm 5)算法是由MIT的计算机科学家Ronald Rivest于1991年设计的一种消息摘要算法.MD5算法最初被用于提供数据完 ...