1.Redis为什么这么快?
- Redis是单线程的,避免了多线程的上下文切换和并发控制开销;
- Redis大部分操作时基于内存,读写数据不需要磁盘I/O,所以速度非常快;
- Redis采用了I/O多路复用机制,提高了网络I/O并发性;
- Redis提供高效的数据结构,如跳跃表、哈希表等;
2.Java 虚拟机架构 (JVM Architecture)
在我看来,不管学习什么样的知识或技术,首先要做的就是从全局上去认识它,这样才能避免盲人摸象,事倍功半的情况发生。既然要学习 JVM,就要先了解它的整体架构,于是我画了个 JVM 架构图来帮助大家认识它。
对 JVM 还不太了解的同学第一次看到这张花里胡哨的图肯定会一脸懵逼,不用怕,其实我们只需要重点理解并掌握其中一部分 (同时也是面试重点) 就好了,比如运行时数据区、垃圾收集器、内存分配策略和类加载机制等,类文件结构也可以学习一下,其他的稍作了解即可。既然本篇文章是要带领大家认识 JVM 架构的,那就先把图中各个部分都介绍一下吧 (注:本文只做介绍,让各位先对 JVM 有个整体的认识,后续会做深入探讨)。
3.Class 文件 (字节码文件)
Java 之所以号称“一次编写,处处运行”,就是得益于虚拟机和 Class 文件 (注:CLass 文件、字节码文件和类文件是一个意思) 的组合机制。程序员并不需要自己去适配不同的操作系统,大家都知道我们平时编写的 java 代码在编译成 Class 文件后才能执行,而 Class 文件可以在任何操作系统上的 JVM 上执行,这样就做到了“平台无关性”。
下面是一个最简单的 HelloWorld 程序及其对应的 Class 文件。
HelloWorld 程序及其编译后的 Class 文件
得益于 Class 文件,JVM 还可以做到“语言无关性”,也就是说不只有 Java 程序可以运行于 JVM 之上,很多其他语言例如最近在安卓开发者中大火的 Kotlin 语言,还有 Scala、Groovy 等语言也都是基于 JVM 平台的,这些语言的代码都可以编译成 Class 文件,然后在 JVM 上运行。
JVM提供的平台无关性和语言无关性
4.类加载器子系统 (ClassLoader Subsystem)
要执行 Class 文件就需要先将其加载进内存,这一工作正是由类加载器 (ClassLoader) 完成的,系统为我们提供了三种类加载器,分别是启动类加载器 (Bootstrap ClassLoader)、扩展类加载器 (Extension ClassLoader) 和应用程序类加载器 (Application ClassLoader),如果有必要,我们也可以加入自定义的类加载器。类加载过程如下:
类加载过程
类加载过程分为加载、连接和初始化三个阶段,其中的连接阶段又分为验证、准备和解析三个阶段 (详细的类加载机制在后续文章中进行介绍)。
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下载更多面试题。