Java 面试高频 100 题
按 KB Master 板块分类,每题标注考察点并链接回原理笔记 作用:原理理解后的检验手段,非学习主线
01 — Java语言基础
01.1 8种基本类型的内存占用各是多少?
考察点: 基本类型基础认知
| 类型 | 位数 | 默认值 |
|---|---|---|
| byte | 8 | 0 |
| short | 16 | 0 |
| int | 32 | 0 |
| long | 64 | 0L |
| float | 32 | 0.0f |
| double | 64 | 0.0d |
| char | 16 | 空字符 |
| boolean | JVM 依赖 | false |
→ 详阅 **数据类型与运算符**
01.2 String 为什么是不可变的?
考察点: 不可变性的设计动机
原因:
1. 线程安全 — 无需同步即可在多线程共享
2. 常量池复用 — 不可变保证了引用安全
3. 哈希值缓存 — String 是 HashMap 最常用的 key
4. 安全性 — 反射/类加载路径等场景不会被篡改→ 详阅 **String深度解析**
01.3 String s = new String("a") 创建了几个对象?
考察点: 常量池与堆内存
如果常量池中没有 "a":创建 2 个对象(常量池 1 个 + 堆 1 个) 如果常量池中已有 "a":创建 1 个对象(堆)
→ 详阅 **String深度解析**
01.4 equals() 和 == 有什么区别?
考察点: 引用比较 vs 值比较
==:比较基本类型的值,或引用类型的内存地址equals():默认同==,但可重写为内容比较- String、Integer 等包装类已重写 equals() 为值比较
→ 详阅 **Object类与通用方法**
01.5 重写 equals 为什么必须重写 hashCode?
考察点: hash 集合的正确性
hashCode 契约:
- equals 相等 → hashCode 必须相等
- hashCode 相等 → equals 不一定相等(哈希冲突)
HashMap/Set 的查找逻辑:先 hashCode 定位桶 -> 再 equals 比较
所以只重写 equals 不重写 hashCode -> 相同对象可能在不同桶 -> 找不到!→ 详阅 **Object类与通用方法**
02 — 面向对象核心
02.1 Java 支持多继承吗?怎么实现类似效果?
考察点: 多继承冲突 & 接口默认方法
Java 不支持类的多继承(菱形问题),但可以通过:
- 接口多实现 — 一个类可实现多个接口
- 内部类 — 用内部类间接实现多继承效果
- 组合 — 优先使用组合而非继承
Java 8+ 接口可以有 default/static 方法。
→ 详阅 **抽象类与接口**
02.2 静态方法能被重写吗?
考察点: 重写 vs 隐藏
静态方法不能被重写(override),只能被隐藏(hide)。
class Parent { static void foo() {} }
class Child extends Parent { static void foo() {} } // 隐藏,不是重写
Parent p = new Child();
p.foo(); // 调用 Parent.foo(),不是 Child.foo()→ 详阅 **三大特性(封装继承多态)**
02.3 抽象类和接口有什么区别?如何选择?
考察点: 设计动机差异
| 维度 | 抽象类 | 接口 |
|---|---|---|
| 核心语义 | "是什么" (is-a) | "能做什么" (can-do) |
| 构造方法 | 可以有 | 不能有 |
| 状态字段 | 可以有 | 不能有 (JDK8+) |
| 多重继承 | 单继承 | 多实现 |
| 演进 | 修改需谨慎 | JDK8+ default 方法兼容 |
→ 详阅 **抽象类与接口**
03 — 集合框架
03.1 HashMap 的 put 流程是怎样的?
考察点: 哈希表核心机制
put(key, value)
1. hash(key) — 扰动函数(高16位 ^ 低16位)
2. (n-1) & hash — 计算桶索引
3. 桶为空 -> 直接放入
4. 桶不为空 -> 遍历链表/红黑树
- key 已存在 -> 替换 value
- key 不存在 -> 插入末尾
5. 链表长度 > 8 -> 树化为红黑树
6. 元素数 > threshold(cap*0.75) -> 扩容为 2 倍→ 详阅 **HashMap核心原理**
03.2 ConcurrentHashMap 如何保证线程安全?
考察点: 并发集合的设计演进
| 版本 | 实现方式 |
|---|---|
| JDK 7 | 分段锁 (Segment 数组,每段一个锁) |
| JDK 8 | CAS + synchronized(锁单个桶节点) |
JDK 8 改进:锁粒度更细,减少内存占用,并发度更高。
→ 详阅 **ConcurrentHashMap**
03.3 ArrayList 和 LinkedList 的区别?
考察点: 数据结构选择
| 操作 | ArrayList | LinkedList |
|---|---|---|
| get(i) | O(1) | O(n) |
| add(E) 尾部 | O(1) 均摊 | O(1) |
| add(i, E) 中间 | O(n) 移动元素 | O(1) 改指针 |
| 内存 | 连续数组 | 节点+前后指针 |
→ 详阅 **List体系**
04 — 泛型与注解
04.1 Java 的泛型是怎么实现的?
考察点: 类型擦除
Java 泛型通过类型擦除实现:编译时检查类型安全,编译后擦除类型信息。
// 编译前
List<String> list = new ArrayList<>();
// 编译后(擦除)
List list = new ArrayList();优点:兼容旧版本(无泛型的集合代码) 缺点:运行时不能获取类型参数、不能 new T()、不能 new T[]
→ 详阅 **泛型原理与类型擦除**
04.2 ? extends T 和 ? super T 的区别?
考察点: PECS 原则
Producer Extends, Consumer Super
? extends T: 只读(生产者)— 可以 get,不能 add(除了 null)
? super T: 只写(消费者)— 可以 add,get 只能读到 Object
例:List<? extends Number> -> 可以 get Number,不能 add Integer
List<? super Integer> -> 可以 add Integer,get 只能得到 Object→ 详阅 **通配符与边界**
05 — 异常与日志
05.1 Checked Exception 和 Runtime Exception 的区别?
考察点: 异常设计哲学
Checked Exception (如 IOException):
- 编译期强制处理(try-catch 或 throws)
- 调用方可以合理恢复的场景
Runtime Exception (如 NullPointerException):
- 编译期不强制处理
- 程序 bug(可避免),不应该 try-catch→ 详阅 **异常体系结构**
06 — IO与NIO
06.1 BIO、NIO、AIO 的区别?
考察点: IO 模型演进
| 模型 | 特点 | 适用场景 |
|---|---|---|
| BIO | 阻塞,一连接一线程 | 连接数少且固定 |
| NIO | 非阻塞,Selector 多路复用 | 连接数多,连接短 |
| AIO | 异步,回调通知 | 连接数多,连接长 |
→ 详阅 **NIO核心**
07 — Lambda与Stream
07.1 Stream 的中间操作和终端操作有什么区别?
考察点: 惰性求值
中间操作 (filter/map/sorted): 惰性,构建操作流水线,不触发执行
终端操作 (collect/forEach/count): 触发实际执行,执行后 Stream 不可用
关键:没有终端操作,中间操作不会执行!→ 详阅 **Stream流水线**
07.2 toMap 时 key 冲突怎么处理?
考察点: Collectors.toMap
// 不处理冲突 -> 抛 IllegalStateException
// 处理冲突:
Map<Integer, String> map = list.stream()
.collect(Collectors.toMap(
Item::getId,
Item::getName,
(oldVal, newVal) -> newVal // 冲突时取新的
));→ 详阅 **Collectors收集器**
08 — 多线程与并发
08.1 创建线程有哪几种方式?
考察点: 线程创建方式
1. extends Thread
2. implements Runnable
3. implements Callable + FutureTask(可返回结果)
4. ExecutorService.submit()(线程池)推荐方式:3 和 4 — Runnable/Callable 更灵活(不占用继承位)。
→ 详阅 **线程基础与创建**
08.2 线程池的核心参数有哪些?
考察点: ThreadPoolExecutor
ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 空闲线程存活时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 工作队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
);执行流程:core -> 队列 -> max -> 拒绝策略
→ 详阅 **Executor与线程池**
08.3 volatile 能保证原子性吗?
考察点: volatile 语义
volatile 保证:
- 可见性 — 写操作立即刷新到主存
- 有序性 — 禁止指令重排序
volatile 不保证:
- 原子性 — i++ 不是原子操作(读-改-写三步)→ 底层原理:**volatile的内存语义**
09 — 包装类与时间API
09.1 Integer 的缓存范围是多少?
考察点: 包装类缓存
Integer 缓存池范围:-128 ~ 127 (可通过 -XX:AutoBoxCacheMax 调整)
Integer a = 127; // 缓存
Integer b = 127; // 缓存
a == b; // true
Integer c = 128; // 新对象
Integer d = 128; // 新对象
c == d; // false — 用 equals() 比较!→ 详阅 **包装类详解**
10 — 单元测试
10.1 @Mock 和 @MockBean 有什么区别?
考察点: Mockito vs SpringBoot Test
| 注解 | 框架 | 作用范围 |
|---|---|---|
| @Mock | Mockito | 纯 Mock,不加载 Spring 上下文 |
| @MockBean | SpringBoot Test | 替换 Spring 容器中的 Bean |
→ 详阅 **Mockito**
11 — MyBatis
11.1 #{} 和 ${} 有什么区别?
考察点: SQL 注入防范
#{}: 预编译(PreparedStatement),防 SQL 注入
${}: 字符串拼接,有 SQL 注入风险
能用 #{} 的地方不用 ${}
${} 仅用于表名/列名等动态 SQL 元数据→ 详阅 **Mapper映射原理**
11.2 MyBatis 一级缓存和二级缓存?
考察点: 缓存机制
一级缓存(SqlSession 级别):
- 默认开启,同一 SqlSession 中共享
- 执行 update/delete/insert 或 close() 后清除
二级缓存(SqlSessionFactory 级别):
- 需手动开启(cache 标签)
- 跨 SqlSession 共享
- 注意:分布式环境下需考虑一致性问题→ 详阅 **缓存机制**
12 — SpringBoot
12.1 @SpringBootApplication 包含哪些注解?
考察点: 自动配置原理
@SpringBootApplication =
@Configuration // Java Config
+ @EnableAutoConfiguration // 自动配置
+ @ComponentScan // 组件扫描
自动配置原理:spring.factories -> 条件装配 @ConditionalOnClass/OnBean/OnProperty→ 详阅 **注解体系速查**
12.2 @Transactional 失效场景有哪些?
考察点: 事务代理机制
事务失效常见场景:
1. 非 public 方法
2. 同类中方法调用(this.method() — 不走代理)
3. 异常被 try-catch 捕获未抛出
4. 传播行为设置不当
5. 数据库引擎不支持事务(MyISAM)→ 详阅 **数据访问与事务**
13 — Redis
13.1 Redis 为什么快?
考察点: 高性能设计
1. 纯内存操作,无磁盘 IO 瓶颈
2. 单线程模型,无上下文切换和锁竞争
3. IO 多路复用(epoll)
4. 数据结构简单高效(SDS、跳表等)→ 详阅 **数据结构**
13.2 缓存穿透、击穿、雪崩的区别?
考察点: 缓存三大问题
| 问题 | 现象 | 解决 |
|---|---|---|
| 穿透 | 查不存在的数据,直接查 DB | 布隆过滤器 / 缓存空值 |
| 击穿 | 热点 key 过期,大量请求同时查 DB | 互斥锁 / 逻辑过期 |
| 雪崩 | 大量 key 同时过期或 Redis 宕机 | 随机过期时间 / 多级缓存 |
→ 详阅 **Java集成与场景**
📚 相关链接
- ← 返回 **Java文库设计文档**
- → 原理笔记:各板块索引页