阅读须知
面试和笔试的要点其实差不多,基础知识和实战经验都是最重要的关注点(当然,面 试时的态度和眼缘也很重要)。 实际面试时,因为时间有限,不可能所有问题都问一遍,一般是根据简历上涉及的内 容,抽一部分话题来聊一聊。看看面试者的经验,态度,以及面对一层层的深入问题 时的处理思路。借此了解面试者的技术水平,对深度、广度,以及思考和解决问题的 能力。
常见的面试套路是什么呢?
- XXX是什么?
- 实现原理是什么?
- 为什么这样实现?
- 如果让你实现你会怎么做?
- 分析下你的实现有什么优缺点?有哪些需要改进的地方?
下面总结一些比较常见的面试题,供大家参考。 针对这些问题,大家可以给自己打一个分:
0分:不清楚相关知识。
30分:有一点印象,知道一些名词。
60分:知道一些概念以及含义,了解功能和常见用途。
80分:能在参考答案的基础上进行补充。
100分:发现参考答案的问题。
下面我们来看看JVM相关面试问题。
1. 什么是JVM?
- JVM全称是 Java Virtual Machine ,中文称为 Java虚拟机 。
- JVM是Java程序运行的底层平台,与Java支持库一起构成了Java程序的执行环境。
- 分为JVM规范和JVM实现两个部分。简单来说,Java虚拟机就是指能执行标准Java字节码的虚拟计算机。 (这一点我我觉得不太合理,因为JVM根本不关心运行在其内部的程序到底是使用何种编程语言编写的,它只关心“字节码”文件,所以应该叫做可以执行相关规范字节码的虚拟机)
1.1 请问JDK与JVM有什么区别?
- 现在的JDK、JRE和JVM一般是整套出现的。
- JDK = JRE + 开发调试诊断工具
- JRE = JVM + Java标准库
1.3 OracleJDK与OpenJDK有什么区别?
各种版本的JDK一般来说都会符合Java虚拟机规范。
两者的区别一般来说包括:
- 两种JDK提供的工具套件略有差别,比如jmc等有版权的工具。
- 某些协议或配置不一样,比如美国限制出口的加密算法。
- 其他细微差别,比如JRE中某些私有的API不一样。
- 在JDK11之前,OracleJDK中还会存在一些OpenJDK中没有的、闭源的功能。但在JDK11中,我们可以认为OpenJDK和OracleJDK代码实质上已经完全一致的程度。
2. 什么是Java字节码?
Java 中的字节码,是值 Java 源代码编译后的中间代码格式,一般称为字节码文件。
2.1 字节码文件中包含哪些内容?
字节码文件中,一般包含以下部分:
- 版本号信息
- 静态常量池(符号常量)
- 类相关的信息
- 字段相关的信息
- 方法相关的信息
- 调试相关的信息
可以说,大部分信息都是通过常量池中的符号常量来表述的。
2.2 什么是常量?
常量是指不变的量,字母 ‘K’ 或者数字 1024 在UTF8编码中对应到对应的二进制 格式都是不变的。同样地,字符串在Java中的二进制表示也是不变的, 比如 “KK” 。 在Java中需要注意的是, final 关键字修饰的字段和变量,表示最终变量,只能赋 值1次,不允许再次修改,由编译器和执行引擎共同保证。
2.3 你怎么理解常量池?
在Java中,常量池包括两层含义:
-
静态常量池,class文件中的一个部分,里面保存的是类相关的各种符号常量。
-
运行时常量池,是在方法区中,其内容主要由静态常量池解析得到,但也可以由程序添加。
-
他们俩的作用提高了复用性,减少了内存。
3. JVM的运行时数据区有哪些?
- 方法区
- 堆
- 程序计数器
- 本地方法栈
- 虚拟机栈
3.1 什么是堆内存?
堆内存是指由程序代码自由分配的内存,与栈内存作区分。在Java中,堆内存主要用于分配对象的存储空间,只要拿到对象引用,所有线程都可以访问堆内存。
3.2 堆内存包括哪些部分?
以Hotspot为例,堆内存(HEAP)主要由GC模块进行分配和管理, 可分为以下部分:
- 新生代
- 老年代
- 元空间
3.3 什么是非堆内存?
除堆内存之外,JVM的内存池还包括非堆(NON_HEAP),对应于JVM规范中的方法
区,常量池等部分:
-
MetaSpace 元空间
-
CodeCache
-
Compressed Class Space
4. 什么是内存溢出?
内存溢出(OOM)是指可用内存不足。
程序运行需要使用的内存超出最大可用值,如果不进行处理就会影响到其他进程,所 以现在操作系统的处理办法是:只要超出立即报错,比如抛出 内存溢出错误 。 就像杯子装不下,满了要溢出来一样,比如一个杯子只有500ml的容量,却倒进去 600ml,于是水就溢出造成破坏。
4.1 什么是内存泄漏?
内存泄漏(Memory Leak)是指本来无用的对象却继续占用内存,没有再恰当的时机 释放占用的内存。
不使用的内存,却没有被释放,称为 内存泄漏 。 也就是该释放的没释放,该回收的没回收。 (简称占着茅坑不拉屎)
比较典型的场景是: 每一个请求进来,或者每一次操作处理,都分配了内存,却有一部分不能回收(或未释放),那么随着处理的请求越来越多,内存泄漏也就越来越严重。
在Java中一般是指无用的对象却因为错误的引用关系,不能被GC回收清理。
4.2 两者有什么关系?
如果存在严重的内存泄漏问题,随着时间的推移,则必然会引起内存溢出。 内存泄漏一般是资源管理问题和程序BUG,内存溢出则是内存空间不足和内存泄漏的最终结果。