Java 基础面试题集
语言基础
-
Java 中
==
和equals()
方法有什么区别?- 【==是比较两个引用是否执行同一个对象(内存地址)
- 基本类型比较值(int char double)
- equale() 定义在Object 里面 默认实现和==一致,通常被类重写(String Integer ArrayList)用来比较内容是否相同,更适合对象见内容比较】
-
String
,StringBuilder
, 和StringBuffer
有什么区别?它们各自适用于什么场景?- 【String 不可变的字符串 每次修改都会创建新的字符串对象 不会改变原有的字符串内容 线程安全 适用场景 字符串内容不经常变化 多线程下共享使用 配置常量 参数名
- StringBuilder 可变字符串 内部使用字符串数组存储 效率高 非线程安全 适用场景 字符串频繁修改 单线程场景 生成SQL 动态HTML
- StringBuffer 可变字符串 与**
StringBuilder
**相同API 但是方法加了synchronized 性能比较低 适用场景: 多线程并发修改字符串 - 】
-
Java 中的基本数据类型有哪些?它们对应的包装类是什么?为什么需要包装类?
-
【
-
基本类型 包装类(Wrapper Class) byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean
- 集合类不能使用基本类型
- 提供了很多实用方法,包装类中提供了很多静态方法,例如字符串转数字
- 有些场景需要将基本类型作为对象传递,例如在泛型、反射、序列化、缓存等机制中。
-
】
-
-
简述 Java 中的自动装箱(Autoboxing)和自动拆箱(Unboxing),并说明可能带来的性能问题。
-
【
-
名称 含义 自动装箱 将基本类型自动转换为对应的包装类对象 自动拆箱 将包装类对象自动转换为对应的基本类型 -
频繁装箱创建大量临时对象
-
空对象拆箱导致空指针异常
-
包装类使用
==
比较容易出错 -
】
-
-
final
关键字在 Java 中可以修饰什么?分别有什么作用?-
【
-
修饰对象 含义 / 作用 变量(局部变量、成员变量、参数) 值一旦赋值后不可改变 方法 子类不能重写该方法 类 不能被继承 -
】
-
-
static
关键字在 Java 中可以修饰什么?分别有什么作用?-
【
-
可修饰的对象 作用说明 变量(字段) 所有对象共享同一个静态变量,称为静态变量(类变量) 方法 不依赖对象,可以通过类名直接调用,称为静态方法 代码块 在类加载时执行一次,称为静态代码块 内部类(嵌套类) 不依附外部类实例存在,可直接通过类名访问,称为静态内部类 -
】
-
-
解释 Java 中的访问权限修饰符:
public
,protected
,default
(包访问权限),private
。-
【
-
修饰符 当前类 同包(default) 子类(不同包) 其他包 public
✅ ✅ ✅ ✅ protected
✅ ✅ ✅ ❌ default(无修饰) ✅ ✅ ❌ ❌ private
✅ ❌ ❌ ❌ -
】
-
面向对象 (OOP)
-
面向对象的三大基本特征是什么?请简要解释每个特征。
-
【封装(Encapsulation)
将数据(属性)和操作数据的方法(行为)绑定在一起,隐藏内部实现细节,仅通过公开的方法与外部交互。这样可以保护对象的状态不被随意更改,增强程序的安全性和可维护性。继承(Inheritance)
子类可以继承父类的属性和方法,代码复用性高。Java 中使用extends
关键字实现继承,支持单继承。继承也为实现多态打下基础。多态(Polymorphism)
同一个方法调用在不同对象上可以表现出不同的行为(即“一个接口,多种实现”)。多态分为编译时多态(方法重载)和运行时多态(方法重写+动态绑定)。 -
】
-
-
什么是多态?Java 中如何实现多态?
-
【多态的定义:
指同一个方法在不同对象上表现出不同的行为。多态提高了代码的扩展性和可维护性。Java 实现多态的方式有两种:
- 编译时多态(静态多态): 方法重载(Overloading)——同一个类中方法名相同但参数不同;
- 运行时多态(动态多态): 方法重写(Overriding) + 父类引用指向子类对象。
-
】
-
-
抽象类(
abstract class
)和接口(interface
)有什么区别?在 Java 8 之后接口有什么新特性?-
【
-
特性 抽象类 ( abstract class
)接口 ( interface
)是否支持方法体 可以有抽象方法和普通方法 Java 8 之前只能有抽象方法 是否支持构造函数 ✅ 有构造器 ❌ 无构造器 是否支持成员变量 可以有成员变量(非 final
)只能有 public static final
常量多继承支持 只能继承一个类 可以实现多个接口 是否可被实例化 ❌ 不可以 ❌ 不可以 Java 8 之后接口新增特性:
- 默认方法(default method): 接口可以包含具有默认实现的方法。
- 静态方法(static method): 接口中可以定义静态工具方法。
- Java 9 起还支持私有方法(用于辅助 default 或 static 方法复用代码)。
-
】
-
-
重载(Overload)和重写(Override)的区别是什么?
-
【
比较点 方法重载(Overload) 方法重写(Override) 定义位置 同一个类中 父类和子类之间 方法名 必须相同 必须相同 参数列表 必须不同(数量或类型) 必须完全相同 返回类型 可以不同(但不能仅靠它区分) 必须相同或是父类返回类型的子类(协变返回类型) 访问修饰符限制 无限制 子类不能降低访问权限 异常抛出 可任意 子类方法不能抛出比父类方法更宽的异常 -
】
-
异常处理
-
Java 中的异常体系结构是怎样的?
Error
和Exception
有什么区别?-
【Java 异常体系结构(从
Throwable
开始):php复制编辑 Throwable / \ Error Exception / \ CheckedException RuntimeException
✅ 区别:
对比项 Error
Exception
继承自 Throwable
Throwable
是否可捕获 通常不捕获 推荐捕获处理 是否可恢复 ❌ 不可恢复,表示系统级问题 ✅ 通常是可预见、可恢复的问题 常见子类 OutOfMemoryError
、StackOverflowError
IOException
、SQLException
、NullPointerException
处理建议 交给 JVM 处理 程序员应处理(尤其是受检异常) ✅ Checked vs Unchecked 异常:
- Checked Exception(受检异常):继承自
Exception
但不是RuntimeException
,如IOException
、SQLException
,必须显式捕获或声明。 - Unchecked Exception(运行时异常):继承自
RuntimeException
,如NullPointerException
、IndexOutOfBoundsException
,可以不强制捕获。
- Checked Exception(受检异常):继承自
-
】
-
-
try-catch-finally
块的作用是什么?finally
块一定会被执行吗? -
throw
和throws
有什么区别?-
【
-
对比项 throw
throws
作用 主动抛出异常对象 声明方法可能抛出的异常 使用位置 方法体内部 方法声明处 后面跟的内容 是一个异常对象 是异常类型(类名) 数量 只能抛出一个异常对象 可声明多个异常类型,用逗号隔开 -
】
-
集合框架 (Collections Framework)
-
请简述 Java 集合框架的主要接口(如
Collection
,List
,Set
,Map
,Queue
)及其常见实现类(如ArrayList
,LinkedList
,HashSet
,TreeSet
,HashMap
,TreeMap
)。-
【✅ Java 集合体系结构:
mathematica复制编辑 ┌────────── Collection(根接口) ─────────┐ ↓ ↓ List Set ↓ ↓ ArrayList, LinkedList HashSet, TreeSet, LinkedHashSet ┌────────── Map(键值对集合) ─────────────┐ ↓ ↓ HashMap, TreeMap, LinkedHashMap ConcurrentHashMap ┌──────────── Queue(队列) ──────────────┐ ↓ ↓ LinkedList, PriorityQueue, ArrayDeque BlockingQueue 等
✅ 简要说明:
接口/类 特点 Collection
单列集合的根接口,子接口有 List
、Set
、Queue
List
有序、可重复,如: ArrayList
、LinkedList
Set
无序、不可重复,如: HashSet
、TreeSet
Map
存储键值对,如: HashMap
、TreeMap
Queue
FIFO 队列,如: LinkedList
、PriorityQueue
-
】
-
-
ArrayList
和LinkedList
有什么区别?它们各自适用于什么场景?-
【
-
对比项 ArrayList
LinkedList
底层结构 动态数组 双向链表 查找效率 高,支持索引随机访问 低,需遍历节点 插入删除效率 低,中间插入需移动元素 高,修改指针即可 内存占用 较小(仅数据) 较大(数据 + 前后指针) 适合场景 读多写少,随机访问 写多读少,频繁插入/删除 -
】
-
-
HashSet
是如何保证元素唯一性的?HashMap
的底层实现原理是什么?(涉及哈希表、哈希冲突解决)-
【
HashSet
唯一性原理: -
】
-
-
HashMap
和Hashtable
有什么区别?ConcurrentHashMap
是如何实现线程安全的? -
Comparable
和Comparator
接口有什么区别?-
【
-
对比项 Comparable
Comparator
包名 java.lang
java.util
使用方式 被比较对象实现接口 单独创建比较器 方法 int compareTo(T o)
int compare(T o1, T o2)
适合场景 自然排序(类内定义) 多种排序方式(类外定义) 是否修改类 ✅ 需要修改类 ❌ 不修改原类 示例 TreeSet
、Collections.sort()
可直接用Collections.sort(list, comparator)
-
】
-
并发编程 (Concurrency)
-
什么是线程(Thread)和进程(Process)?它们之间有什么区别?
- 【1. 什么是线程(Thread)和进程(Process)?它们之间有什么区别?
- 进程是系统资源分配的基本单位,每个进程有独立的内存空间和系统资源。
- 线程是进程中的执行单元,一个进程可以包含多个线程,共享进程内存和资源。
- 区别:
- 进程间相互独立,通信较复杂;线程共享进程资源,通信更方便但需同步。
- 进程切换开销大,线程切换开销相对较小
- 】
- 【1. 什么是线程(Thread)和进程(Process)?它们之间有什么区别?
-
创建线程有哪几种方式?推荐使用哪种方式,为什么?
- 【方式一:继承
Thread
类 - 方式二:实现
Runnable
接口 - 方式三:实现
Callable
接口 +FutureTask
- 方式四:线程池(
ExecutorService
)管理线程(推荐)
推荐使用实现
Runnable
或Callable
并结合线程池,因为:-
避免单继承限制,增强灵活性;
-
线程池能复用线程,提升性能,便于统一管理和资源控制。
-
】
- 【方式一:继承
-
简述
synchronized
关键字的用法(修饰实例方法、静态方法、代码块)及其作用原理(监视器锁/Monitor)。- 【**修饰实例方法:**锁住当前实例对象(
this
)。 - **修饰静态方法:**锁住类的
Class
对象。 - **修饰代码块:**锁住括号里的对象。
**作用原理:**基于对象监视器(Monitor),同一时刻只有一个线程持有该锁,其他线程阻塞等待。
- 】
- 【**修饰实例方法:**锁住当前实例对象(
-
volatile
关键字有什么作用?它能保证原子性吗?-
【**作用:**保证变量的可见性和防止指令重排序。
**不保证原子性:**对
volatile
变量的复合操作(如i++
)仍非原子操作。 -
】
-
-
什么是线程安全?如何保证线程安全?(列举几种方法)
- 【**线程安全:**多线程环境下,代码执行结果不受线程调度顺序影响。
- 保证方式:
- 使用
synchronized
或Lock
锁机制; - 使用原子类(
AtomicInteger
等); - 使用线程安全的集合(
ConcurrentHashMap
); - 避免共享变量(如使用局部变量);
- 不可变对象设计。
- 使用
- 】
其他
-
Java 中的
Object
类有哪些常用方法?请说明hashCode()
和equals()
方法之间的关系。-
【常用方法有:
equals()
,hashCode()
,toString()
,clone()
,finalize()
,getClass()
。关系:相等的对象必须具有相同的
hashCode()
,否则哈希集合无法正确工作。 -
】
-
-
Java 的反射(Reflection)是什么?有什么优缺点?
- 【Java 反射(Reflection)是什么?优缺点?
- **定义:**运行时动态获取类信息、创建对象、调用方法、访问字段的机制。
- **优点:**灵活,适合框架开发(如 Spring)。
- **缺点:**性能开销大,代码复杂,破坏封装。
- 】
- 【Java 反射(Reflection)是什么?优缺点?
-
String s = new String("abc");
这行代码创建了几个对象?分别是什么?- 【3.
String s = new String("abc");
创建几个对象?- 2个对象:
- 字符串常量池中的
"abc"
(已存在或新建) - 堆内存中新建的
String
对象s
- 字符串常量池中的
- 2个对象:
- 】
- 【3.
-
Java
中的IO
流分为哪两大类?请列举一些常用的流类。-
【两大类:
- 字节流(
InputStream
/OutputStream
) - 字符流(
Reader
/Writer
)
常用流:
- 字节流:
FileInputStream
,FileOutputStream
,BufferedInputStream
,BufferedOutputStream
- 字符流:
FileReader
,FileWriter
,BufferedReader
,BufferedWriter
- 字节流(
-
】
-
-
Java
中的泛型(Generics)是什么?有什么作用?-
【**定义:**Java 泛型允许定义类、接口、方法时使用类型参数,实现代码复用。
**作用:**提供类型安全,避免强制类型转换,提高代码可读性。
-
】
-
-
(设计题)如何实现一个单例(Singleton)模式?请写出一种线程安全的实现方式。
-
【
public class Singleton { private Singleton() {} private static class Holder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return Holder.INSTANCE; } }
- 利用静态内部类的延迟加载和类加载机制保证线程安全,且性能好。
】
-