当前位置: 首页 > 科技观察

Java面试遇到这样的面试题是最惨的!

时间:2023-03-12 16:59:08 科技观察

从接触Java开发到现在,你对Java最直观的印象是什么?是它标榜的“一次编译,到处运行”,还是现在有点形式化的语法?你对Java平台了解多少?请先停下来想一想。今天想问大家的问题是,谈谈你对Java平台的理解?“Javaisinterpretedandexecute”,这句话对吗?典型答案Java本身就是一种面向对象的语言。最显着的特点有两个方面:一是所谓的“一次编译,随处运行”(Compileonce,runanywhere),可以轻松获得跨平台能力;就是垃圾回收(GC,GarbageCollection)。Java通过垃圾收集器(GarbageCollector)回收和分配内存。在大多数情况下,程序员不需要担心内存分配和回收。我们每天都会接触到JRE(JavaRuntimeEnvironment)或者JDK(JavaDevelopmentKit)。JRE,即Java运行环境,包括JVM和Java类库,以及一些模块。JDK可以看作是JRE的超集,提供了更多的工具,比如编译器、各种诊断工具等。对于“Java是解释执行的”这句话,这个说法是不太准确的。我们开发的Java源代码首先通过Javac编译成字节码,然后在运行时通过嵌入在Java虚拟机(JVM)中的解释器将字节码转换成最终的机器码。但是常见的JVM,比如我们大多数情况下使用的OracleJDK提供的HospotJVM,都提供了JIT(Just-In-Time)编译器,也就是通常所说的动态编译器。代码被编译成机器代码。在这种情况下,一些热点代码被编译执行,而不是被解释执行。考点分析其实这道题有点笼统。题目本身就很开放,往往考察多个方面,比如对基础知识的理解是否清晰;是否掌握了Java平台的主要模块和运行原理等,很多面试官都会被这类问题困扰。他们有些紧张,不知道从何说起,所以给出了一个非常简短的回答。对于这种笼统的问题,你需要尽量表现出你的思考是有深度和系统性的,你的Java知识比较全面。一定要避免让面试官觉得你是一个“知其然不知其所以然”的人。毕竟了解基本的组成和机制是日常工作中很多事情的基础,比如问题诊断或者性能调优。相信没有哪个招聘人员会不喜欢“爱学习、爱思考”的面试官。即使您觉得自己的答案并不完美,也不要担心。我个人认为,回答这种笼统的问题,有时略带片面的回答是正常的。大多数有经验的面试官不会因为一个问题就轻易对面试官下结论。通常,您会尽力引导面试官并展示他的真实水平。这种题就是做开场热身。面试官往往会根据你的回答展开相关问题。知识拓展回到正题。对Java平台的理解可以从很多方面来简单说说,比如:Java语言特性,包括泛型、Lambda等语言特性;基础类库,包括集合、IO/NIO、网络、并发、安全等基础类库。对于我们在日常工作中使用较多的类库,可以在面试前系统地总结一下,有助于临场发挥。或者说说JVM的一些基本概念和机制,比如Java的类加载机制,常用的JDK版本(比如JDK8)中嵌入的Class-Loader,比如Bootstrap、Application和ExtensionClass-loader;类加载的大致流程:loading,Verification,linking,initialization(参考周志明的《深入理解 Java虚拟机》,一本JVM入门的好书);自定义Class-Loader等。还有垃圾回收的基本原理。最常见的垃圾收集器,如SerialGC、ParallelGC、CMS、G1等,很清楚什么样的工作负载适合它们。这些都是可以拓展的地方,我会在后面的专栏中更加系统的介绍。当然JDK或者Java领域的其他工具包括什么工具,比如编译器、运行环境、安全工具、诊断和监控工具等等,这些基础工具是日常工作效率的保障,也是有助于我们在其他语言平台上工作,其中许多都是类似的。下图是我总结的一个比较宽泛的蓝图,供大家参考。不展开了,我们回到前面问的解释执行和编译执行的问题。有的面试官喜欢在具体问题上“挖个底”,因为这是进一步了解面试官知识水平的有效途径,所以我会稍微深挖一下。众所周知,我们通常将Java分为编译时和运行时。这里说的Java编译和C/C++是不同的意思。Javac编译,编译Java源代码生成“.class”文件,实际上包含的是字节码,不是可以直接执行的机器码。Java通过字节码和Java虚拟机(JVM)的跨平台抽象,屏蔽了操作系统和硬件的细节,这也是实现“一次编译,到处执行”的基础。在运行时,JVM会通过类加载器(Class-Loader)加载字节码,解释或编译并执行。前面说过,主流的Java版本,比如JDK8,其实是一种解释和编译混合的模式,即所谓的混合模式(-Xmixed)。通常,以服务器模式运行的JVM会进行数万次调用,以收集足够的信息以进行高效编译。客户端模式的阈值是1500次。OracleHotspotJVM有两个不同的内置JIT编译器。C1对应上面提到的客户端模式,适用于对启动速度比较敏感的应用,比如普通的Java桌面应用;C2对应服务器模式,针对长时间运行的服务器端应用设计进行了优化。默认是使用所谓的分层编译(TieredCompilation)。关于JIT的更多细节这里就不用展开了,也不用一口气说完,后面会介绍分层编译的内容。Java虚拟机启动时,可以指定不同的参数来选择运行模式。例如,指定“-Xint”告诉JVM只解释和执行代码而不编译代码。这种模式舍弃了JIT可能带来的性能优势。毕竟解释器是一个一个读进去,一个一个解释运行的。相应的,还有一个“-Xcomp”参数,它告诉JVM关闭解释器,不进行解释执行,或者称为最高优化级别。那么你可能会问这种模式是否有效?简单地说,不是真的。“-Xcomp”会导致JVM启动速度变慢很多。同时,一些JIT编译器的优化方法,比如分支预测,在没有profiling的情况下往往无法得到有效的优化。除了我们最常见的日常Java使用模式外,其实还有一种新的编译方式,即所谓的AOT(Ahead-of-TimeCompilation),直接将字节码编译成机器码,从而避免了JIT预热等。各方面的开销,比如OracleJDK9引入了实验性的AOT特性,并添加了一个新的jaotc工具。使用以下命令将类或模块编译成AOT库。jaotc--outputlibHelloWorld.soHelloWorld.classjaotc--outputlibjava.base.so--modulejava.base然后在启动时直接指定即可。java-XX:AOTLibrary=./libHelloWorld.so,./libjava.base.soHelloWorld而且OracleJDK支持分层编译和AOT协同使用,不是替代关系。有兴趣的可以参考相关文档:http://openjdk.java.net/jeps/29***OT不是唯一途径,业界早就有第三方工具(如GCJ、ExcelsiorJET)提供相关功能。另外,JVM是一个强大的平台,不仅Java语言可以在JVM上运行,本质上兼容的字节码也可以运行,而Java语言本身为此提供了便利。我们可以看到,Clojure、Scala、Groovy、JRuby、Jython等众多JVM语言活跃在不同的场景中。今天简单介绍一下Java平台相关的一些内容。目的是概述和建立一个整体印象,包括Java语言特性、核心类库和常用的第三方类库、Java虚拟机的基本原理和相关工具。你帮忙。