最详细的 Java 基础面试题汇总

1.面向对象和面向过程的区别

  • 面向过程 :面向过程性能比面向对象高 。因为类调用时需要实例化 , 开销比较大 , 比较消耗资源 , 所以当性能是最重要的考量因素的时候 , 比如单片机、嵌入式开发、Linux/Unix 等一般采用面向过程开发 。 但是 , 面向过程没有面向对象易维护、易复用、易扩展 。
  • 面向对象 :面向对象易维护、易复用、易扩展 。因为面向对象有封装、继承、多态性的特性 , 所以可以设计出低耦合的系统 , 使系统更加灵活、更加易于维护 。 但是 , 面向对象性能比面向过程低 。
参见 issue : 面向过程 :面向过程性能比面向对象高??

这个并不是根本原因 , 面向过程也需要分配内存 , 计算内存偏移量 , Java 性能差的主要原因并不是因为它是面向对象语言 , 而是 Java 是半编译语言 , 最终的执行代码并不是可以直接被 CPU 执行的二进制机械码 。
而面向过程语言大多都是直接编译成机械码在电脑上执行 , 并且其它一些面向过程的脚本语言性能也并不一定比 Java 好 。

2. Java 语言有哪些特点?
  1. 简单易学;
  2. 面向对象(封装 , 继承 , 多态);
  3. 平台无关性( Java 虚拟机实现平台无关性);
  4. 可靠性;
  5. 安全性;
  6. 支持多线程( C++ 语言没有内置的多线程机制 , 因此必须调用操作系统的多线程功能来进行多线程程序设计 , 而 Java 语言却提供了多线程支持);
  7. 支持网络编程并且很方便( Java 语言诞生本身就是为简化网络编程设计的 , 因此 Java 语言不仅支持网络编程而且很方便);
  8. 编译与解释并存;

修正(参见: issue#544):C++11 开始(2011 年的时候),C++就引入了多线程库 , 在 windows、linux、macos 都可以使用std::thread和std::async来创建线程 。

3. 关于 JVM JDK 和 JRE 最详细通俗的解答JVMJava 虚拟机(JVM)是运行 Java 字节码的虚拟机 。 JVM 有针对不同系统的特定实现(Windows , Linux , macOS) , 目的是使用相同的字节码 , 它们都会给出相同的结果 。
什么是字节码?采用字节码的好处是什么?

在 Java 中 , JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件) , 它不面向任何特定的处理器 , 只面向虚拟机 。 Java 语言通过字节码的方式 , 在一定程度上解决了传统解释型语言执行效率低的问题 , 同时又保留了解释型语言可移植的特点 。 所以 Java 程序运行时比较高效 , 而且 , 由于字节码并不针对一种特定的机器 , 因此 , Java 程序无须重新编译便可在多种不同操作系统的计算机上运行 。

Java 程序从源代码到运行一般有下面 3 步:
最详细的 Java 基础面试题汇总文章插图
Java程序运行过程
我们需要格外注意的是 .class->机器码 这一步 。 在这一步 JVM 类加载器首先加载字节码文件 , 然后通过解释器逐行解释执行 , 这种方式的执行速度会相对比较慢 。 而且 , 有些方法和代码块是经常需要被调用的(也就是所谓的热点代码) , 所以后面引进了 JIT 编译器 , 而 JIT 属于运行时编译 。 当 JIT 编译器完成第一次编译后 , 其会将字节码对应的机器码保存下来 , 下次可以直接使用 。 而我们知道 , 机器码的运行效率肯定是高于 Java 解释器的 。 这也解释了我们为什么经常会说 Java 是编译与解释共存的语言 。

HotSpot 采用了惰性评估(Lazy Evaluation)的做法 , 根据二八定律 , 消耗大部分系统资源的只有那一小部分的代码(热点代码) , 而这也就是 JIT 所需要编译的部分 。 JVM 会根据代码每次被执行的情况收集信息并相应地做出一些优化 , 因此执行的次数越多 , 它的速度就越快 。 JDK 9 引入了一种新的编译模式 AOT(Ahead of Time Compilation) , 它是直接将字节码编译成机器码 , 这样就避免了 JIT 预热等各方面的开销 。 JDK 支持分层编译和 AOT 协作使用 。 但是, AOT 编译器的编译质量是肯定比不上 JIT 编译器的 。