写点什么

经典 Java 面试题解析——谈谈你对 Java 平台的理解?

  • 2018-05-07
  • 本文字数:3113 字

    阅读完需:约 10 分钟

从你接触 Java 开发到现在,你对 Java 最直观的印象是什么呢?是它宣传的 “Compile once, run anywhere”,还是目前看已经有些过于形式主义的语法呢?你对于 Java 平台到底了解到什么程度?请你先停下来总结思考一下。

今天我要问你的问题是,谈谈你对 Java 平台的理解?“Java 是解释执行”,这句话正确吗?

典型回答

Java 本身是一种面向对象的语言,最显著的特性有两个方面,一是所谓的“一次编译,到处执行”(Compile 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 提供的 Hospot 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 领域内其他工具等,如编译器、运行时环境、安全工具、诊断和监控工具等。这些基本工具是日常工作效率的保证,对于我们工作在其他语言平台上,同样有所帮助,很多都是触类旁通的。

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

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

众所周知,我们通常把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 库。

复制代码
<pre spellcheck="false">
jaotc --output libHelloWorld.so HelloWorld.class
复制代码
<pre spellcheck="false">
jaotc --output libjava.base.so --module java.base

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

复制代码
<pre spellcheck="false">
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 虚拟机基本原理和相关工具,希望对你有所帮助。

想看更多 Java 经典面试题深度解析?推荐关注《Java 核心技术 36 讲》。专栏重点围绕“术”与“道”,为你讲解 Java 面试的核心知识点。就算你暂时不需要准备面试,照样可以通过这个专栏,提升 Java 技能。

现在订阅,享双重福利:

福利一:限时优惠价¥45,原价¥68(5 月 12 日恢复原价)

福利二:每邀请一位好友购买,你可获得 18 元现金返现,多邀多得,上不封顶,立即提现(提现流程:极客时间公众号 - 我的 - 现金奖励提现)

订阅方法:点击下图,微信支付,立即成功订阅。

2018-05-07 02:494104

评论

发布
暂无评论
发现更多内容

Hive SQL底层执行原理

五分钟学大数据

Hive SQL 1月月更

我相信:没有解不开的难题|ONES 人物

万事ONES

龙蜥社区一周动态 | 1.10-1.14

OpenAnolis小助手

Linux 开源 社群

知识库进化论 | 华创资本对话 ONES & 为知笔记创始人

万事ONES

CSS 自适应内容宽度的输入框

编程江湖

为什么HashMap会产生死循环?

王磊

ReactNative进阶(二十三):Javascript 严格模式详解

No Silver Bullet

React Native 1月月更

2021 OceanBase 开源半年度报告 | 不忘初心,感恩同行

OceanBase 数据库

开发者 报告 OceanBase 开源 OceanBase 社区版

虎符研究院深入解读Web3.0未来趋势 盘点代表性项目

区块链前沿News

Web Hoo虎符 虎符研究院 虎符平台 3.0

java开发之Redis的使用规范

@零度

redis JAVA开发

Android技术分享| 自定义View实现使用更方便的SeekBar

anyRTC开发者

android 音视频 移动开发 白板 SeekBar

使用php-amqplib实现RabbitMq

Owen Zhang

php RabbitMQ php-amqplib

组件通信、硬件池化,这些创新技术你get了吗?|HDC2021技术分论坛

HarmonyOS开发者

HarmonyOS

1月月更|推荐学java——Spring之AOP

逆锋起笔

spring SSM框架 spring aop 依赖注入 面向切面编程

Chrome插件:摸鱼倒计时、每日摸鱼时间统计,奋斗逼、卷王必备,用于减少摸鱼时间和频率

OBKoro1

效率 开源 效率工具 chrome扩展 高效率

GIS :元宇宙未来发展的有力技术支撑

华为云开发者联盟

AI GIS 虚拟世界 数字孪生 云宇宙

Jetpack—LiveData组件的缺陷以及应对策略

vivo互联网技术

android livedata JetPack 移动应用开发

TDSQL PG版企业级分布式数据库技术创新实践

腾讯云数据库

tdsql 国产数据库

TDSQL-C for PostgreSQL 主从架构详解

腾讯云数据库

tdsql 国产数据库

创业老兵李峻的新征程|ONES 人物

万事ONES

TDSQL | 将企业级分布式数据库做到极致

腾讯云数据库

tdsql 国产数据库

前端使用 zx 库在 Node 中编写 Shell 脚本

devpoint

node.js Shell 1月月更 zx.js

前端开发之JQuery的综合应用

@零度

jquery 前端开发

Scrum Master需要具备哪些能力和经验

华为云开发者联盟

Scrum 敏捷 团队 教练 Scrum Master

低代码实现探索(二十二)如何构建一个可以看的懂的系统

零道云-混合式低代码平台

线上流量对比应用实践

得物技术

架构 数据 流量 实践 流量回放

我以订披萨为例,给女朋友详细讲了Java设计模式的3种工厂模式

华为云开发者联盟

Java 工厂模式 工厂方法模式 简单工厂模式 抽象工厂模式

Serverless 背景下,一部分“前端工程师”会转变为“应用交付工程师”

杨成功

Serverless 架构 前端

架构实战训练营-模块7-作业

温安适

「架构实战营」

软件设计——依赖倒置

苏州程序大白

架构师

ONES CTO 冯斌|如何低成本地做出高质量决策

万事ONES

经典Java面试题解析——谈谈你对Java平台的理解?_Java_杨晓峰_InfoQ精选文章