大厂爱问的九道Java面试题

161 阅读7分钟

前言

如果你是 Java 后端方向,Java 基础的知识就必须要相当熟悉。 ​

蜗牛也做过面试官,本篇文章就从面试官的角度上,精选出 Java 基础相关的题目,我会给出参考答案,也会指明考察点,欢迎大家一起互动交流。 ​

题目

1、什么是 JDK?你常用的版本是哪个?为什么用这个版本?

【考察点】

对 Java 开发工具的理解,以及技术选型方面的思考 ​

【参考答案】

JDK 全称 Java Development ToolKit,直译一下就是 Java 语言开发工具包。

JDK 包含了 开发者工具比如 javac 用来编译 java 源码,jar 用来打包,还有一系列其他工具。此外,还包含了 JRE(Java Runtime Environment),也就是 Java 应用程序的运行环境,它除了运行程序的 java 指令外,还有类库以及执行 Java 应用程序的 JVM(Java 虚拟机)。

我常用的版本是 JDK8。一方面是这个版本已经比较稳定,另一方面,这个版本使用非常普遍,出了问题,很容易在网上找到答案。

image.png

2、一个Java程序从编码到运行,这中间发生了什么?

【考察点】

对 Java 程序运行原理的理解 ​

【参考答案】

  1. 首先编程之后得到 .java 后缀的源代码文件。
  2. 用 JDK 中的 javac 命令将 Java 源代码进行编译,生成 Java 字节码,也就是 class 文件。
  3. 用 JRE 的 java 命令执行 class 文件时,Java 字节码会被传输到 JVM(Java 虚拟机),JVM 会合并字节码以及 JRE 中的库文件一起执行,输出特定硬件平台的机器码,或者说指令集。
  4. 机器码被底层物理硬件平台执行

image.png

3、一个极简可运行的 Java 程序,它的代码有哪些要素?

【考察点】

对 Java 编码规范的理解

【参考答案】

  • 类类型
  • 类名
  • 访问修饰符
  • 成对的花括号
  • main 方法
    • 执行语句

image.png

4、Java 基本类型里的布尔类型占用多大的内存?

【考察点】

对 Java 基本数据类型的理解 ​

【参考答案】

1 字节或 4 字节。 ​

布尔类型表达是或者否,只有 trueflase 两个值,用关键字 boolean 表示,但 JVM 没有针对 boolean 的字节码指令,因此在虚拟机规范里,boolean 类型在编译后会被 int 代替,占用 4 个字节,如果是 boolean 数组,会被编译成 byte 数组类型,每个 boolean 数组元素占 1 个字节。实际情况就取决于各厂商发布的 JVM 实现了。

5、& 和 && 有什么区别?

【考察点】

对 Java 基本类型运算的理解 ​

【参考答案】

&&:逻辑与运算符。当运算符左右两边的表达式都为 true,才返回 true。同时具有短路性,如果第一个表达式为 false,则直接返回 false。 ​

&:既能当做逻辑与运算符,也能当做按位与运算符。 ​

逻辑与运算符:& 在用于逻辑与时,和 && 的区别是不具有短路性。所以通常使用逻辑与运算符都会使用 &&,而 & 更多的适用于位运算。 ​

按位与运算符:用于二进制的计算,只有对应的两个二进位均为1时,结果位才为1 ,否则为0。

6、以下代码为什么输出的不是 129?

int highIntValue = 129;
byte lowByteValue = (byte)highIntValue;

System.out.println(lowByteValue);

【考察点】

考察对计算机原码、反码和补码的理解 ​

【参考答案】

这里会输出 -127,而不是 129。 ​

在上面代码中,我们知道,int 类型数据是 32位,byte 类型数据为 8 位,Java 把 int 类型数据转成 byte 类型数据时,实质上是截取 int 后 8 位存到 byte 中。

int 类型的 129 三码(原码、反码和补码)一致,都为:0000 0000 0000 0000 0000 0000 1000 0001。计算机中存的是补码

从 int 转换 byte,截取后 8 位为:1000 0001。得到的数据为依然是补码

负数补码转原码的公式:

  • 负数原码=(补码-1)&&数值位取反

我们按照公式,会发现其原码为:补码(1000 0001)–> 反码(1000 0000)–> 原码(1111 1111)。即 1111 1111就是 (byte)highIntValue 的结果。

转换成十进制就是 lowByteValue=-(64+32+16+8+4+2+1)=-127。 ​

7、new String("xxx"); 这行代码会产生几个对象?

【考察点】

考察对 Java 字符串存储机制的理解 ​

【参考答案】

一个或两个。如果常量池中原来没有 xxx,就是两个。如果有就是一个。

String 是不可变类,Java 会分配一块常量池。通过以下代码解释下常量池的使用。 ​

String str1 = "蜗牛666";

String str2 = "蜗牛666";

String newStr1 = new String("蜗牛666");
String newStr2 = new String("蜗牛666");

str1 这个变量接收了一个常量,于是存储到常量池中,执行到 str2 的赋值语句时,发现已经有相同的常量了,于是 str2 也指向了 str1 刚才那块内存空间。

newStr1 和 newStr2 是通过 new 语法创建的对象,在创建的过程中,Java 会先去常量池中查找是否已有 蜗牛666 对象,如果没有则在常量池中创建一个 **蜗牛666 **对象,然后在堆中创建一个 蜗牛666 的拷贝对象。 ​

image.png

8、Java 的封装特性都体现在哪些地方?

【考察点】

考察对 Java 面向对象的基础知识。 ​

【参考答案】

  1. 通过包(package)的方式,把一个模块封装到一起,并由几个接口开放给使用方。使用方只能看到接口信息,而看不到接口实现。
  2. 通过访问权限控制的方式,实现信息隐藏。
  3. 通过 getter 和 setter 方法,实现了对类成员有条件的读取和修改。

9、谈谈你对双亲委派模式的理解?

【考察点】

考察对 Java 类加载机制的理解。 ​

【参考答案】

双亲委派模式要求除了顶层的引导类加载器外,其余的类加载器都应当有自己的父类加载器。 ​

双亲委派的工作原理是,如果一个类收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,一次递归,请求最终将到达顶层的引导类加载器。 ​

如果父类加载器可以完成类加载任务,就成功返回,如果父类加载器无法完成此加载任务,子加载器才会尝试自己去加载。 ​

你会发现,Java 类随着它的类加载器具备了带有优先级的层次关系,通过这种层级关系,可以避免类的重复加载,当父类已经加载了该类,就没必要子加载器再加载一次。 ​

因此像 java.lang.String 这种 Java 核心 API,即便你同名,JVM 也会优先加载 rt.jar 里的,因为引导类加载器是最顶级的加载器。这样也避免了 Java 核心 API 被随意替换,保证了安全。

image.png

后记

很多问题看似简短,背后能说道的东西其实很多,这就需要日积月累的沉淀,而非一朝一夕之功。面试题精选系列每一篇的题目不会超过 10 个,为的是读者朋友可以很好的消化内容,同时也能够深入了解相关的知识,希望对读者的面试能有帮助!