Java 核心技术面试笔记(一)

以面试题为切入点,有效提升 Java 内功

  • 应聘初级、中级 Java 工程师,通常只要求扎实的 Java 和计算机科学基础,掌握主流开源
    框架的使用。
  • Java 高级工程师或者技术专家,则往往全面考察 Java IO/NIO、并发、虚拟机等,不仅仅是了解,更要求对底层源代码层面的掌握,并对分布式、安全、性能等领域能力有进一步的要求。
  • 有些面试者确实是认真努力工作,但坦白说表现出的能力水平却不足以通过面试,通常是两方面原因:
    • 知其然不知其所以然”。
      • 做了多年技术,开发了很多业务应用,但似乎并未思考过种种技术选择背后的逻辑。
      • 团队所从事的是公司核心产品,工作于基础技术领域,我们不需要那些“差不多”或“还行”的代码,而是需要达到一定水准的高质量设计与实现。
    • 知识碎片化,不成系统。
      • 在面试中,面试者似乎无法完整、清晰地描述自己所开发的系统,或者使用的相关技术。
      • 平时可能埋头苦干,或者过于死磕某个实现细节,并没有抬头审视这些技术。
      • 比如,有的面试者,有一些并发编程经验,但对基本的并发类库掌握却并不扎实,似乎觉得在用的时候进行“面向搜索引擎的编程”就足够了。
    • 一道类加载的问题,一个类,在类加载之后,如果对类的内容进行修改,如何在不重新启动虚拟机的情况下,加载已经变化过的类。
    • 你可以创建个新的 class loader,然后用 loadClass 加载,再 newInstance;原来加载的classloader 是不能重新加载的,这算是一个典型的容器思路。

谈谈对 Java 平台的理解

典型回答

  • 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 的源代码,首先通过 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;
      • 类加载大致过程:加载、验证、链接、初始化;自定义 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)。
  • Java 虚拟机启动时,可以指定不同的参数对运行模式进行选择。
    • 比如,指定“-Xint”,就是告诉 JVM 只进行解释执行,不对代码进行编译,这种模式抛弃了 JIT 可能带来的性能优势。毕竟解释器(interpreter)是逐条读入,逐条解释运行的。
    • 与其相对应的,还有一个“-Xcomp”参数,这是告诉 JVM 关闭解释器,不要进行解释执行,或者叫作最大优化级别。
    • “-Xcomp”会导致 JVM 启动变慢非常多,同时有些 JIT 编译器优化方式,比如分支预测,如果不进行 profiling,往往并不能进行有效优化。
  • 除了我们日常最常见的 Java 使用模式,其实还有一种新的编译方式,即所谓的 AOT(Ahead-of-Time Compilation),直接将字节码编译成机器代码,这样就避免了 JIT 预热等各方面的开销,比如 Oracle JDK 9 就引入了实验性的 AOT 特性,并且增加了新的 jaotc 工具。
  • JVM 作为一个强大的平台,不仅仅只有 Java 语言可以运行在 JVM 上,本质上合规的字节码都可以运行,Java 语言自身也为此提供了便利,我们可以看到类似 Clojure、Scala、Groovy、JRuby、Jython 等大量 JVM 语言,活跃在不同的场景。

你可能感兴趣的:(Java,基础,java,面试,开发语言)