Java中高级面试题,开发模拟练习

1.Redis为什么这么快?

  1. Redis是单线程的,避免了多线程的上下文切换和并发控制开销;
  2. Redis大部分操作时基于内存,读写数据不需要磁盘I/O,所以速度非常快;
  3. Redis采用了I/O多路复用机制,提高了网络I/O并发性;
  4. Redis提供高效的数据结构,如跳跃表、哈希表等;

2.Java 虚拟机架构 (JVM Architecture)

        在我看来,不管学习什么样的知识或技术,首先要做的就是从全局上去认识它,这样才能避免盲人摸象,事倍功半的情况发生。既然要学习 JVM,就要先了解它的整体架构,于是我画了个 JVM 架构图来帮助大家认识它。

Java中高级面试题,开发模拟练习_第1张图片

        对 JVM 还不太了解的同学第一次看到这张花里胡哨的图肯定会一脸懵逼,不用怕,其实我们只需要重点理解并掌握其中一部分 (同时也是面试重点) 就好了,比如运行时数据区、垃圾收集器、内存分配策略和类加载机制等,类文件结构也可以学习一下,其他的稍作了解即可。既然本篇文章是要带领大家认识 JVM 架构的,那就先把图中各个部分都介绍一下吧 (注:本文只做介绍,让各位先对 JVM 有个整体的认识,后续会做深入探讨)。

3.Class 文件 (字节码文件)

        Java 之所以号称“一次编写,处处运行”,就是得益于虚拟机和 Class 文件 (注:CLass 文件、字节码文件和类文件是一个意思) 的组合机制。程序员并不需要自己去适配不同的操作系统,大家都知道我们平时编写的 java 代码在编译成 Class 文件后才能执行,而 Class 文件可以在任何操作系统上的 JVM 上执行,这样就做到了“平台无关性”。

下面是一个最简单的 HelloWorld 程序及其对应的 Class 文件。

Java中高级面试题,开发模拟练习_第2张图片

HelloWorld 程序及其编译后的 Class 文件

        得益于 Class 文件,JVM 还可以做到“语言无关性”,也就是说不只有 Java 程序可以运行于 JVM 之上,很多其他语言例如最近在安卓开发者中大火的 Kotlin 语言,还有 Scala、Groovy 等语言也都是基于 JVM 平台的,这些语言的代码都可以编译成 Class 文件,然后在 JVM 上运行。

Java中高级面试题,开发模拟练习_第3张图片

JVM提供的平台无关性和语言无关性

4.类加载器子系统 (ClassLoader Subsystem)

        要执行 Class 文件就需要先将其加载进内存,这一工作正是由类加载器 (ClassLoader) 完成的,系统为我们提供了三种类加载器,分别是启动类加载器 (Bootstrap ClassLoader)、扩展类加载器 (Extension ClassLoader) 和应用程序类加载器 (Application ClassLoader),如果有必要,我们也可以加入自定义的类加载器。类加载过程如下:

Java中高级面试题,开发模拟练习_第4张图片

类加载过程

        类加载过程分为加载、连接和初始化三个阶段,其中的连接阶段又分为验证、准备和解析三个阶段 (详细的类加载机制在后续文章中进行介绍)。

5. Java 虚拟机运行时数据区 (JVM Runtime Data Area)

        这部分内容较多,放在本文第二部分单独进行介绍。

5.1 执行引擎 (Execution Engine)

字节码被加载进运行时数据区后,执行引擎会进行读取并执行,执行引擎主要包含以下模块:

解释器 (Interpreter):相信大家很久以前就听过“计算机只认识0和1”这句话,时至今日,计算机依然只认识0和1,所以任何编程语言的代码最终都要转化成机器码 (二进制代码)才能执行,Java 也不例外,而解释器的工作正是将编译得到的字节码再转化成机器码,然后才能执行。正因为如此,Java 才被称为解释型语言,也正是因为边解释边执行的特点,Java 程序在执行时才会慢于 C++ 之类的编译型语言。

即时编译器 ,为了弥补解释执行带来的速度劣势,JVM 引入了即时编译器,它的作用就是把热点代码,比如重复调用的方法和循环代码等,编译成机器码并存放在 code cache 中,这样之后再用到这些代码就不用重新解释执行了,可以提高程序运行效率。

垃圾收集器 (Garbage Collector):Java 程序员可以不用手动释放内存,全是垃圾收集器的功劳,这也是 JVM 中尤其重要的内容,后续会有多篇文章对其进行介绍。

5.2本地库接口 (JNI,Java Native Interface)

如果你经常看 JDK 源码的话,一定会注意到 native 这个关键词,被它修饰的方法是没有方法体的,是因为它调用了计算机本地的方法库 (通常是 C 或 C++ 代码)。JDK 源码中有很多类的方法,特别是一些需要操作计算机硬件的方法,都调用了本地方法库,毕竟与硬件打交道还是用 C 和 C++ 更方便,比如下面这些方法:

// 例一:这是 Thread 类中的 currentThread 方法,用于获取当前正在执行的线程
public static native Thread currentThread();

// 例二:这是 FileInputStream 类中 open0 方法,用于打开指定文件
private native void open0(String name) throws FileNotFoundException;

以上就是“Java中高级面试题,开发模拟练习”,你能回答上来吗?如果想要了解更多的java面试题相关内容,可以加扣扣群390144688下载更多面试题。

你可能感兴趣的:(java,开发语言)