文章
努力加载图片中...
Java 面试题学习
  • 5514 字

  • 7 分钟

  • 13 次

  • 2025-09-20
标签:

又看又背了一整天才弄了这么点,看来我专注力真是不够。。。

1 概念

1.1 说一下 Java 的特点
  1. 平台无关性: java 编译器将源代码编译成字节码,可以在任何安装了 java 虚拟机的系统上运行。
  2. 面向对象: 包括类、对象、封装、继承、多态、抽象。
  3. 内存管理:java 有自己的垃圾回收机制,不需要手动管理内存。
面试说明

Java 的主要特点有三点:
第一,平台无关性,通过 JVM 实现“一次编写,到处运行”;
第二,面向对象,支持封装、继承、多态等特性;
第三,自动内存管理,通过垃圾回收机制(GC)减少内存泄漏风险。

1.2 java 的优势和劣势
  • 优势:
  1. 有 JVM ,可以跨平台运行 java 程序。
  2. 面向对象。
  3. 内存管理。
  4. 生态强大:Spring 框架、Hibenate 以及各种库和工具。
  5. 支持多线程,内置线程机制,方便并发编程。
  6. 有安全模型,例如沙箱机制。
  7. 有企业级长期稳定支持版本。
  • 劣势:
  1. 性能相比 C++ 或者 Rust 开销更多,启动时间慢。
  2. 语法繁琐,样板代码多。
  3. 内存消耗多,对资源有限的环境不友好。
面试说明

Java 的优势在于:跨平台能力强、生态系统成熟(如 Spring)、自动垃圾回收、内置多线程支持,适合企业级开发。 劣势是性能相对原生语言略低,启动较慢,内存占用较高,语法也较为冗长,样板代码多。

1.3 java 为什么是跨平台的

和 JVM 的关系比较大。 java 源码编译后生成字节码文件,而 JVM 就是将字节码文件翻译成特定平台的机器码来运行。 也就是说,只要不同平台安装了对应的 JVM 就可以运行字节码文件,运行 java 程序。

面试说明

Java 能跨平台是因为“字节码和JVM”。源代码被编译成与平台无关的 .class 文件,再由对应平台的 JVM 将字节码翻译成本地机器码执行,从而实现“一次编写,到处运行”。

1.4 JVM、JDK、JRE 的关系
  1. JVMJava Virtual Machine) 是 Java 虚拟机,是 java 程序运行的环境。 它负责将 java 字节码文件解释或者编译成机器码,并执行程序,实现一次编写,到处运行。包括:内存管理、垃圾回收、安全性、线程和同步。
  2. JDKJava Development Kit) 是 Java 开发工具包,是开发 Java 程序所需的工具包,提供了开发、编译、调试和运行 Java 程序所需的全部工具和环境。包括:JVM、编译器(javac-Java Compiler)、调试器(jdb-Java Debugger)以及一系列类库。
  3. JREJava Runtime Environment) 是 Java 运行时的环境,是 Java 程序运行所需的最小环境。包含了 JVM 和一组 java 类库,用于支持程序的执行。
面试说明

三者关系是包含关系:

  • JVM 是 Java 虚拟机,负责将字节码文件解释或者编译成机器码,并执行程序;
  • JRE 包含 JVM 和运行所需类库,用于运行 Java 程序;
  • JDK 是开发工具包,包含 JRE 和编译、调试等工具,用于开发 Java 程序。
    所以:JDK 包含 JRE,JRE 包含 JVM。
1.5 为什么 Java 解释和编译都有

java 使用的是解释器和编译器混合的模式,JVM 中的一个方法调用计数器,累计计数达到一定值的时候,就使用 JIT 进行编译生成机器码文件,否则就是用解释器进行解释执行。

面试说明

JVM 使用“解释 + 编译”混合模式:程序启动时通过解释器逐行执行字节码,对频繁执行的“热点代码”,JIT 编译器会将其编译为本地机器码,提升执行效率,兼顾了启动速度和运行性能。

1.6 JVM 是什么

JVM 是 Java 虚拟机,主要工作是解释或者编辑字节码文件,并映射到本机的 CPU 指令集和 OS 系统调用。

面试说明

JVM(Java 虚拟机)是 Java 程序运行的核心,它负责解释或编译执行字节码,并提供内存管理、垃圾回收、线程调度和安全控制等功能,实现 Java 的跨平台能力。

1.7 编译型语言和解释型语言的区别(Java 和 Python 的区别)
  1. 编译型语言:程序运行之前,会将源代码编译成机器码或者字节码,生成可执行文件,执行时运行编译后的代码,速度快,但跨平台性差。
  2. 解释型语言:程序执行时,逐行解释并执行源代码,不生成独立的可执行文件,跨平台性好,但速度较慢。
  3. Java 属于中间路线:编译为字节码,再由 JVM 解释或 JIT 编译。
面试说明

编译型语言(如 C++)在运行前将源码直接编译为机器码,执行效率高但跨平台性差; 解释型语言(如 Python)在运行时逐行解释执行,跨平台好但速度慢; Java 是混合型:先编译为字节码,再由 JVM 解释执行或通过 JIT 编译为机器码,兼顾了性能和跨平台性。

2 数据类型

2.1 八种数据类型
  • 数值型:byte、short、int、long、float、double
  • 字符型:char
  • 布尔型:boolean
面试说明

整型byte(1)、short(2)、int(4)、long(8); 浮点型float(4)、double(8); 字符型char(2); 布尔型boolean(true/false)。

2.2 int 和 long 是多少位,多少字节的
  1. int 是 32 位,4 字节的。
  2. long 是 64 位,8 字节的。
面试说明

int 是 32 位、4 字节; long 是 64 位、8 字节, 字符型char(2); 布尔型boolean(true/false)。

2.3 long 和 int 可以互转吗

可以,但由于 long 类型的取值范围比 int 大,所以 int 转 long 是类型安全的,但 long 转 int 会出现数据丢失或者溢出。

面试说明

可以互转。intlong 是自动安全转换;但 longint 需要强制类型转换,如果 long 值超出 int 范围,会发生数据截断或溢出,导致结果错误。

2.4 数据类型转换方式有哪些
  • 自动类型转换(隐式转换):目标类型的范围大于源类型,Java 会自动将源类型转化为目标类型,例如 int 转换位 long、float 转换为 double
  • 强制类型转换(显示转换):目标类型的取值范围小于源类型,需要使用强制类型转换,语法为:目标类型 变量名 = (目标类型) 源类型
  • 字符串转换:Java 提供字符串转其他类型的方法,例如 Integer.parseInt() 方法, Double.parseDouble()
  • 数值之间转换:Java 提供了 数值类型之间转换的方法,例如正序转化为字符型,将字符型转换为整型等。
面试说明

Java 类型转换主要有四种:

  1. 自动转换:小类型转大类型,如 int 到 double
  2. 强制转换:需加 (类型),可能丢失精度;
  3. 字符串转数值:如 Integer.parseInt("123")
  4. 字符与数值互转:字符可转为 ASCII 码参与计算。
2.5 类型互转会出现什么问题
  1. 数据溢出、精度损失。
  2. 如果是对象,向下转型可能会出现对象引用转换的问题。
2.6 为什么用 bigDecimal 不用 double

double 进行的是二进制浮点运算,由于有些小数不能使用 1/(2^n) 这种形式表示,导致 Java 在浮点数运算的时候,会出现精度丢失的问题。 Decimal 进行的是精确计算,可以避免这种问题。

面试说明

double 使用二进制浮点运算,像 0.1 这样的数无法精确表示,会导致精度误差 BigDecimal 提供任意精度的十进制运算,能精确表示和计算小数

2.7 装箱和拆箱是什么
  • 装箱是指将基本数据类型转换为包装类的过程。
  • 拆箱是指将包装类转化为基本数据类型的过程。
2.8 Java 为什么要有 Integer (包装类)
  1. 将数据和数据处理的方法结合在一起,封装成对象,可以方便的处理数据。
  2. Java 中的绝大部分方法或类都是处理对象的,例如 ArrayList,用基本数据类型就没办法处理。
面试说明

Java 是面向对象语言,有些工具类,例如集合,只能存储对象,不能存基本数据类型。 此外,引入包装类,还能让基本数据类型参与泛型、反射等对象操作。

2.9 Integer 相比 int 有什么区别。
  • int 是 java 中的基本数据类型,而 Integer 是 int 的包装类,是引用类型。
  • int 可以直接赋值为0,而包装类必须通过实例化对象来赋值,不然会出现空指针异常。
  • int 存储数据时不需要分配内存,而 Integer 是引用类型,是需要分配内存的。
  • 基本数据类型的操作比相应引用类型更快。
面试说明

int 是基本类型,直接存值,效率高,不能为 nullInteger 是包装类,是对象,可为 null,可用于泛型,但有装箱拆箱开销,可能引发空指针异常。

2.10 说一下 Integer 缓存

Java 的 Integer 类内部实现了一个静态缓存池,范围是 -128 ~ 127 ,当通过 Integer.valueOf(int) 方法创建一个在范围内的对象时,会直接从缓存池中复用,不会创建新的对象实例。

面试说明

Integer 类内部缓存了 -128 到 127 的实例。当使用 Integer.valueOf(100) 时,会从缓存中获取对象,避免重复创建,提升性能。

3 面向对象

3.1 怎么理解面向对象

面向对象是一种编程范式,它将现实世界中的事物抽象为对象具有属性和行为。通过对象之间的交互完成程序的功能,具有灵活性和可拓展性。

3.2 简单说说封装、继承和多态
  1. 封装是指将对象的属性和行为结合在一起,对外隐藏内部细节,只提供接口与外界交互的机制。目的是简化编程、使对象更加独立安全。
  2. 继承是可以让子类拥有父类的属性和行为的机制。目的是代码复用,使类与类之间的结构更加清晰。
  3. 多态是允许不同类对同一消息做出不同的响应的机制。可以让程序具有良好的灵活性和可扩展性。
3.3 多态体现在哪几个方面
  1. 方法重载
  2. 方法重写
  3. 接口与实现
3.4 多态解决了什么问题

解决了“如何在不修改现有代码的前提下,让系统支持新类型”的问题,从而提升了代码的灵活性、可扩展性和可维护性。

3.5 面向对象的设计原则有哪些
  1. 单一职责原则
  2. 开放封闭原则
  3. 里氏替换原则
  4. 接口隔离原则
  5. 依赖倒置原则
  6. 最少支持原则
3.6 重载和重写有什么区别
  1. 重载是在同一个类中,可以有多个同名方法,它们具有不同的参数列表(类型、顺序、个数不同)。
  2. 重写是子类可以重新定义父类中的方法,但方法名、参数列表和返回类型必须与父类中的一致。
3.7 抽象类和普通类的区别
  1. 普通类可以之间实例化对象,抽象类不能被实例化,只能被继承。
  2. 普通类方法可以有具体实现,而抽象类方法可以有具体实现,也可以没有具体实现。
3.8 抽象类和接口的区别
  1. 一个类只能使用 extends 继承一个抽象类,但可以使用 implements 实现多个接口。所以接口支持‘多实现’,并且接口还可以多重继承。
  2. 抽象类中可以有构造方法、成员变量、普通方法和抽象方法;而接口在 Java 8 之前只能有抽象方法,但从 Java 8 开始支持 default 方法和 static 方法,允许有默认实现。
3.9 抽象类能加 final 修饰吗

不能,Java 中的抽象类是用来被继承的,而被 final 修饰的类是被禁止继承的,因此抽象类和 final 是互斥的,不能同时使用。

3.10 解释一下静态变量和静态方法
  1. 静态变量是在类中使用 static 声明的变量。

    • 所有该类的实例共享一个静态变量。
    • 静态变量在类被加载时初始化,并且只会分配一次内存。
    • 静态变量可以通过实例访问,也可以之间通过类名访问。
  2. 静态方法是在类中使用 static 声明的方法。

    • 静态方法可以在没有创建类实例的情况下调用。
    • 静态方法可以直接调用其他静态变量和静态方法,但不能访问非静态成员。
    • 静态方法不支持重写。

4 关键字

4.1 final 的作用

final 关键字主要用于修饰类、方法和变量。

  1. 修饰类时,表示该类不能被继承。
  2. 修饰方法时,表示该方法不能在子类中被重写。
  3. 修饰基本数据类型时,变量一旦被赋值,就不能再修改。
  4. 修饰应用数据类型时,表示这个引用变量不能再指向其他对象,但对象本身的内容是可以变的。
4.2 static 的作用

static 关键字主要用于修饰类的成员和内部类,作用是将修饰内容和类本身关联。

  1. 修饰变量的时候,表示变量属于类本身,所有对象共享一份静态变量,内存中只存在一份。
  2. 修饰方法时,表示方法属于类,不需要创建类实例也能调用。
  3. 修饰内部类的时候,表示内部类不依赖于外部类的实例,可以独立存在。

5 深拷贝和浅拷贝

5.1 深拷贝和浅拷贝的区别

浅拷贝和深拷贝的区别主要在于对对象中引用类型字段的处理方式。

浅拷贝只是复制对象本身,如果对象里还引用了其他对象,它不会去复制那个对象,而是让新对象指向原来的那个引用对象。这就意味着,修改其中一个对象的引用内容,另一个也会受影响。

深拷贝会把对象内部的所有引用对象也递归地复制一份,生成一个完全独立的新对象,两个对象之间互不影响。

5.2 实现深拷贝的三种方法
  1. 实现 Cloneable 接口并重写 clone() 方法。
  2. 使用序列化和反序列化。
  3. 手动递归复制。

6. 泛型

6.1 什么是泛型

泛型(Generic)是 Java 的一种语法特性,它允许你在定义类、接口或方法时,使用“类型参数”,例如<T>,代替具体的类型,等到使用时再指定实际类型。可以提高代码的类型安全性和代码复用性。

7 对象

7.1 java 创建对象有哪些方式
  1. 使用 new 关键字。
  2. 使用 Class 类的 newInstance() 方法。
  3. 使用 Constructor 类的 newInstance() 方法。
  4. 使用 close() 方法
  5. 使用反序列化
  6. 使用工厂模式封装 new 方法
7.2 创建对象除了 new 还有什么别的方法
  1. 通过反射创建对象。
  2. 通过反序列化创建对象。
  3. 通过 clone 创建对象。
7.3 new 出的对象什么时候回收

通过 new 创建的对象,当它不再被任何引用变量指向,也就是变成‘不可达’时,就会在下一次垃圾回收时被自动回收。具体时间由 JVM 的垃圾回收器决定,开发者不能控制。

7.4 如何获取私有对象
  1. 通过公共访问器方法(getter)。
  2. 通过反射机制。

8 反射

8.1 什么是反射

反射是允许程序在运行时动态地获取类的信息,比如类的属性、方法、构造器等,并可以动态地创建对象、调用方法、访问和修改成员变量的一种机制。

9 注解

9.1 注解的原理

Java 注解的原理主要分为三个阶段:定义、存储和读取。

首先,注解是用 @interface 定义的特殊接口,继承自 Annotation 这个接口,配合元注解,例如 @Retention@Target 来控制它的行为。

其次,编译后,注解信息会写入 .class 文件。保留策略决定了它能存在多久:SOURCE(仅源码)、CLASS(字节码)、RUNTIME(运行时)。

最后,在运行时,框架通过反射(如 getAnnotation())读取这些注解,并根据标记执行相应的逻辑,比如注册 Bean、映射请求等。

9.2 注解的作用域
  1. 类级。
  2. 方法级。
  3. 字段级。

10 异常

10.1 介绍一下异常

异常主要基于两大类:Throwable 及其子类。Throwable 有两个重要的子类: Error 和 Exception。

  1. Error (错误)表示运行时环境错误,是程序无法处理的严重错误,例如系统崩溃、虚拟机错误等等。
  2. Exception(异常)表示程序本身可以处理的异常。异常分为两大类:
    • 非运行时异常,在编译时就被捕获或者声明抛出。
    • 运行时异常,运行时异常由程序错误导致的。
10.2 Java 的异常处理有哪些
  1. try-catch 语句块,用于捕获并处理可能抛出的异常。
  2. throw 语句,用于手动抛出异常。
  3. throws 关键字,用于在方法中声明可能抛出的异常类型。
  4. finally 块,无论是否发生异常都会执行的代码块。

11 object

11.1 == 与 equals 有什么区别
  1. == 是一个运算符,对于基本数据类型,比较的是值是否相等,语句引用类型,比较的是两个引用是否指向同一个内存地址。
  2. equals 是 Object 类的一个方法,默认实现和 == 一样,但很多类重写了该方法,用来比较对象内容是否相等。
11.2 String、StringBuffer、StringBuilder的区别和联系
  1. String 是不可变的,一旦创建,内容就不可修改,每次就改都会创建一个新的对象。而 StringBuffer 和 StringBuilder 是可变的,对字符串内容进行修改不会创建新的对象。
  2. String 因为不可变,天然线程安全;StringBuilder 不是线程安全的,适用于单线程环境;StringBuffer 是线程安全的,通过 synchronized 实现了同步,适用于多线程。
  3. String 性能较低,StringBuilder 的性能最高。
  4. 使用环境不同。

12. Java 新特性

12.1 Lambda 表达式是什么

Lambda 表达式是一种简洁的写法, 用于创建匿名函数,简化函数式编程的写法,特别是替代匿名内部类。它适用于只有一个方法的接口,也就是函数式接口中。

12.2 介绍一下 Stream API

Stream 是 Java 8 引入的一个函数式编程工具,用于高效、简洁地处理集合数据,主要分为创建流、中间操作,终止操作几个流程。

  • 中间操作主要有 filter、map、sorted等,它们返回新的 Stream,支持链式调用。
  • 终止操作有 forEach、collect、count等,真正触发执行,并返回结果。

13 其他

13.1 BIO、NIO、AIO 是什么
  1. BIO是同步阻塞模型,每个连接需要一个线程,线程在读写时会阻塞。
  2. NIO是同步非阻塞模型,多个连接复用一个线程,通过“轮询”检查是否有数据。
  3. AIO是异步非阻塞模型,发起 I/O 操作后立即返回,系统在操作完成时通过回调通知。

来源:Java基础面试题 | 小林coding | Java面试学习

作者: Xigrut发布时间: 2025-09-20 21:13:02上次编辑时间: 2026-06-18 19:26:30 许可协议: CC BY-NC-SA 4.0
留言区