Skip to content

Java 面试高频 100 题

按 KB Master 板块分类,每题标注考察点并链接回原理笔记 作用:原理理解后的检验手段,非学习主线


01 — Java语言基础

01.1 8种基本类型的内存占用各是多少?

考察点: 基本类型基础认知

类型位数默认值
byte80
short160
int320
long640L
float320.0f
double640.0d
char16空字符
booleanJVM 依赖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 不支持类的多继承(菱形问题),但可以通过:

  1. 接口多实现 — 一个类可实现多个接口
  2. 内部类 — 用内部类间接实现多继承效果
  3. 组合 — 优先使用组合而非继承

Java 8+ 接口可以有 default/static 方法。

→ 详阅 **抽象类与接口**

02.2 静态方法能被重写吗?

考察点: 重写 vs 隐藏

静态方法不能被重写(override),只能被隐藏(hide)。

java
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 8CAS + synchronized(锁单个桶节点)

JDK 8 改进:锁粒度更细,减少内存占用,并发度更高。

→ 详阅 **ConcurrentHashMap**

03.3 ArrayList 和 LinkedList 的区别?

考察点: 数据结构选择

操作ArrayListLinkedList
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 泛型通过类型擦除实现:编译时检查类型安全,编译后擦除类型信息。

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

java
// 不处理冲突 -> 抛 IllegalStateException
// 处理冲突:
Map<Integer, String> map = list.stream()
    .collect(Collectors.toMap(
        Item::getId,
        Item::getName,
        (oldVal, newVal) -> newVal  // 冲突时取新的
    ));

→ 详阅 **Collectors收集器**


08 — 多线程与并发

08.1 创建线程有哪几种方式?

考察点: 线程创建方式

java
1. extends Thread
2. implements Runnable
3. implements Callable + FutureTask(可返回结果)
4. ExecutorService.submit()(线程池)

推荐方式:3 和 4 — Runnable/Callable 更灵活(不占用继承位)。

→ 详阅 **线程基础与创建**

08.2 线程池的核心参数有哪些?

考察点: ThreadPoolExecutor

java
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 调整)

java
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

注解框架作用范围
@MockMockito纯 Mock,不加载 Spring 上下文
@MockBeanSpringBoot 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 包含哪些注解?

考察点: 自动配置原理

java
@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文库设计文档**
  • → 原理笔记:各板块索引页

Knowledge4J — Java 知识库