谈谈你对 Java 平台的理解?

2024-09-03 19:48
文章标签 java 平台 理解 谈谈

本文主要是介绍谈谈你对 Java 平台的理解?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

谈谈你对 Java 平台的理解?

先谈谈我的理解:

一次编译,永久执行。依赖于jre的运行环境,jdk提供核心类库,java源代码经过javac编译为.class文件,.class文件经过JVM解析或编译运行,无需过多关心不同操作系统的差异性。

典型回答

Java 本身是一种面向对象的语言,最显著的特性有两个方面,一是所谓的“书写一次,到处运行”(Write once, run anywhere),能够非常容易地获得跨平台能力;另外就是垃圾收集(GC, Garbage Collection),Java 通过垃圾收集器(Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。

我们日常会接触到 JRE(Java Runtime Environment)或者 JDK(Java Development Kit)。 JRE,也就是 Java 运行环境,包含了 JVM 和 Java 类库,以及一些模块等。而 JDK 可以看作是 JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。

对于“Java 是解释执行”这句话,这个说法不太准确。我们开发的 Java 的源代码,首先通过 Javac 编译成为字节码(bytecode),然后,在运行时,通过 Java 虚拟机(JVM)内嵌的解释器将字节码转换成为最终的机器码。但是常见的 JVM,比如我们大多数情况使用的 Oracle JDK 提供的 Hotspot JVM,都提供了 JIT(Just-In-Time)编译器,也就是通常所说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行了。

分析

其实这个问题,问得有点笼统。题目本身是非常开放的,往往考察的是多个方面,比如,基础知识理解是否很清楚;是否掌握 Java 平台主要模块和运行原理等。很多面试者会在这种问题上吃亏,稍微紧张了一下,不知道从何说起,就给出个很简略的回答。

对于这类笼统的问题,你需要尽量表现出自己的思维深入并系统化,Java 知识理解得也比较全面,一定要避免让面试官觉得你是个“知其然不知其所以然”的人。毕竟明白基本组成和机制,是日常工作中进行问题诊断或者性能调优等很多事情的基础,相信没有招聘方会不喜欢“热爱学习和思考”的面试者。

即使感觉自己的回答不是非常完善,也不用担心。我个人觉得这种笼统的问题,有时候回答得稍微片面也很正常,大多数有经验的面试官,不会因为一道题就对面试者轻易地下结论。通常会尽量引导面试者,把他的真实水平展现出来,这种问题就是做个开场热身,面试官经常会根据你的回答扩展相关问题。

知识扩展

回归正题,对于 Java 平台的理解,可以从很多方面简明扼要地谈一下,例如:Java 语言特性,包括泛型、Lambda 等语言特性;基础类库,包括集合、IO/NIO、网络、并发、安全等基础类库。对于我们日常工作应用较多的类库,面试前可以系统化总结一下,有助于临场发挥。

或者谈谈 JVM 的一些基础概念和机制,比如 Java 的类加载机制,常用版本 JDK(如 JDK 8)内嵌的 Class-Loader,例如 Bootstrap、 Application 和 Extension Class-loader;类加载大致过程:加载、验证、链接、初始化(这里参考了周志明的《深入理解 Java 虚拟机》,非常棒的 JVM 上手书籍);自定义 Class-Loader 等。还有垃圾收集的基本原理,最常见的垃圾收集器,如 SerialGC、Parallel GC、 CMS、 G1 等,对于适用于什么样的工作负载最好也心里有数。这些都是可以扩展开的领域,我会在后面的专栏对此进行更系统的介绍。

当然还有 JDK 包含哪些工具或者 Java 领域内其他工具等,如编译器、运行时环境、安全工具、诊断和监控工具等。这些基本工具是日常工作效率的保证,对于我们工作在其他语言平台上,同样有所帮助,很多都是触类旁通的。

下图是我总结的一个相对宽泛的蓝图供你参考。
Alt test

不再扩展了,回到前面问到的解释执行编译执行的问题。有些面试官喜欢在特定问题上“刨根问底儿”,因为这是进一步了解面试者对知识掌握程度的有效方法,我稍微深入探讨一下。

众所周知,我们通常把 Java 分为编译期和运行时。这里说的 Java 的编译和 C/C++ 是有着不同的意义的,Javac 的编译,编译 Java 源码生成“.class”文件里面实际是字节码,而不是可以直接执行的机器码。Java 通过字节码和 Java 虚拟机(JVM)这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现“一次编译,到处执行”的基础

在运行时,JVM 会通过类加载器(Class-Loader)加载字节码,解释或者编译执行。就像我前面提到的,主流 Java 版本中,如 JDK 8 实际是解释和编译混合的一种模式,即所谓的混合模式(-Xmixed)。通常运行在 server 模式的 JVM,会进行上万次调用以收集足够的信息进行高效的编译,client 模式这个门限是 1500 次。Oracle Hotspot JVM 内置了两个不同的 JIT compiler,C1 对应前面说的 client 模式,适用于对于启动速度敏感的应用,比如普通 Java 桌面应用;C2 对应 server 模式,它的优化是为长时间运行的服务器端应用设计的。默认是采用所谓的分层编译(TieredCompilation)。这里不再展开更多 JIT 的细节,没必要一下子就钻进去,我会在后面介绍分层编译的内容。

Java 虚拟机启动时,可以指定不同的参数对运行模式进行选择。 比如,指定“-Xint”,就是告诉 JVM 只进行解释执行,不对代码进行编译,这种模式抛弃了 JIT 可能带来的性能优势。毕竟解释器(interpreter)是逐条读入,逐条解释运行的。与其相对应的,还有一个“-Xcomp”参数,这是告诉 JVM 关闭解释器,不要进行解释执行,或者叫作最大优化级别。那你可能会问这种模式是不是最高效啊?简单说,还真未必。“-Xcomp”会导致 JVM 启动变慢非常多,同时有些 JIT 编译器优化方式,比如分支预测,如果不进行 profiling,往往并不能进行有效优化。

除了我们日常最常见的 Java 使用模式,其实还有一种新的编译方式,即所谓的 AOT(Ahead-of-Time Compilation),直接将字节码编译成机器代码,这样就避免了 JIT 预热等各方面的开销,比如 Oracle JDK 9 就引入了实验性的 AOT 特性,并且增加了新的 jaotc 工具。利用下面的命令把某个类或者某个模块编译成为 AOT 库。

jaotc --output libHelloWorld.so HelloWorld.class
jaotc --output libjava.base.so --module java.base

然后,在启动时直接指定就可以了。

java -XX:AOTLibrary=./libHelloWorld.so,./libjava.base.so HelloWorld

而且,Oracle JDK 支持分层编译和 AOT 协作使用,这两者并不是二选一的关系。如果你有兴趣,可以参考相关文档:http://openjdk.java.net/jeps/295。AOT 也不仅仅是只有这一种方式,业界早就有第三方工具(如 GCJ、Excelsior JET)提供相关功能。

另外,JVM 作为一个强大的平台,不仅仅只有 Java 语言可以运行在 JVM 上,本质上合规的字节码都可以运行,Java 语言自身也为此提供了便利,我们可以看到类似 Clojure、Scala、Groovy、JRuby、Jython 等大量 JVM 语言,活跃在不同的场景。

今天,我简单介绍了一下 Java 平台相关的一些内容,目的是提纲挈领地构建一个整体的印象,包括 Java 语言特性、 核心类库与常用第三方类库、Java 虚拟机基本原理和相关工具,希望对你有所帮助。

posted @ 2019-03-11 16:08 南屿北岛 阅读( ...) 评论( ...) 编辑 收藏

这篇关于谈谈你对 Java 平台的理解?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133884

相关文章

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll