一、Java 基础
1. JDK、JRE、JVM 的区别?
-
JDK:Java 开发工具包,包含 JRE + 开发工具(javac、javadoc 等)
-
JRE:Java 运行时环境,包含 JVM + 核心类库
-
JVM:Java 虚拟机,负责字节码解释执行
2. == 和 equals() 的区别?
| 类型 | == | equals() |
|---|---|---|
| 基本类型 | 比较值 | - |
| 引用类型 | 比较内存地址 | Object 默认比较地址,String/Integer 等重写后比较内容 |
3. String、StringBuilder、StringBuffer 区别?
-
String:不可变,线程安全,每次修改创建新对象
-
StringBuilder:可变,非线程安全,单线程性能高
-
StringBuffer:可变,线程安全(synchronized),性能略低
4. HashMap 底层原理?
-
JDK 1.7:数组 + 链表,头插法,并发环境下可能死循环
-
JDK 1.8:数组 + 链表/红黑树,尾插法,链表长度≥8 转红黑树
-
默认初始容量 16,负载因子 0.75,扩容为 2 倍
5. ConcurrentHashMap 如何保证线程安全?
-
JDK 1.7:分段锁(Segment),每个 Segment 独立加锁
-
JDK 1.8:CAS + synchronized,锁粒度细化到桶(Node)
6. synchronized 和 Lock 的区别?
| 特性 | synchronized | Lock(ReentrantLock) |
|---|---|---|
| 实现 | JVM 层面 | API 层面 |
| 释放 | 自动释放 | 手动 unlock() |
| 锁类型 | 独占锁 | 可公平、可中断、可超时 |
| 条件变量 | 一个 | 多个 Condition |
7. volatile 关键字作用?
-
可见性:保证变量对所有线程可见(MESI 缓存一致性协议)
-
禁止指令重排序:插入内存屏障
⚠️ 不保证原子性,不能替代 synchronized
8. Java 内存模型(JMM)?
-
主内存:共享变量存储
-
工作内存:线程私有,操作的是主内存副本
-
三大特性:原子性、可见性、有序性
9. 线程池核心参数?
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 空闲线程存活时间
TimeUnit unit,
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
)
拒绝策略:AbortPolicy(抛异常)、CallerRunsPolicy(调用者执行)、DiscardPolicy(静默丢弃)、DiscardOldestPolicy(丢弃最老任务)
10. GC 垃圾回收算法?
| 算法 | 特点 | 应用 |
|---|---|---|
| 标记-清除 | 碎片化严重 | CMS |
| 标记-复制 | 内存减半,无碎片 | Young 区(Serial、ParNew) |
| 标记-整理 | 无碎片,停顿长 | Old 区(Serial Old、Parallel Old) |
常用收集器:G1(分区回收,可预测停顿)、ZGC(低延迟,TB 级堆)
二、MySQL
1. InnoDB vs MyISAM?
| 特性 | InnoDB | MyISAM |
|---|---|---|
| 事务 | 支持 | 不支持 |
| 锁粒度 | 行锁 | 表锁 |
| 外键 | 支持 | 不支持 |
| 崩溃恢复 | 支持 | 不支持 |
| 索引类型 | 聚簇索引 | 非聚簇索引 |
2. 索引类型?
-
B+Tree 索引:主键索引(聚簇)、二级索引(非聚簇,叶子存主键值)
-
Hash 索引:Memory 引擎,等值查询快,不支持范围
-
全文索引:MyISAM 支持,InnoDB 5.6+ 支持
-
覆盖索引:查询列全在索引中,无需回表
3. 最左前缀原则?
复合索引 (a,b,c),查询条件必须从最左列开始,中间不能断:
-
✅
where a=1 and b=2 -
✅
where a=1 -
❌
where b=2(不走索引) -
❌
where a=1 and c=3(a 走索引,c 不走)
4. 事务隔离级别及问题?
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED | ✗ | ✗ | ✗ |
| READ COMMITTED | ✓ | ✗ | ✗ |
| REPEATABLE READ(默认) | ✓ | ✓ | ✗(InnoDB 解决) |
| SERIALIZABLE | ✓ | ✓ | ✓ |
-
脏读:读到未提交数据
-
不可重复读:同一事务两次读取,数据被修改
-
幻读:同一事务两次读取,行数变化(InnoDB MVCC + 间隙锁解决)
5. MVCC 机制?
-
每行记录隐藏字段:
DB_TRX_ID(事务 ID)、DB_ROLL_PTR(回滚指针) -
ReadView:事务快照,判断数据可见性
-
实现:RC 每次查询生成新 ReadView,RR 事务开始时生成
6. SQL 优化思路?
-
避免 :
SELECT *、隐式类型转换、函数操作索引列、OR条件(可用 UNION) -
利用:覆盖索引、索引下推(ICP)、前缀索引、联合索引顺序
-
分析 :
EXPLAIN查看 type(system > const > eq_ref > ref > range > index > ALL)
7. 分库分表方案?
-
垂直分库:按业务拆分(用户库、订单库)
-
垂直分表:大字段拆分(商品基本信息 + 详情)
-
水平分表:按 ID 取模、按时间范围、Hash 取模
-
中间件:ShardingSphere、MyCat
三、Redis
1. 数据类型及应用场景?
| 类型 | 应用场景 |
|---|---|
| String | 缓存、计数器、分布式锁(SETNX) |
| Hash | 对象存储(用户信息) |
| List | 消息队列、最新 N 条(LPUSH + LRANGE) |
| Set | 去重、交集并集(共同关注) |
| ZSet | 排行榜、延迟队列(score 为时间戳) |
| Bitmap | 签到、活跃用户统计 |
| HyperLogLog | UV 统计(基数估算) |
2. 持久化机制?
-
RDB:定时快照,文件紧凑,恢复快,可能丢数据
-
AOF:日志追加,实时性高,文件大,恢复慢
-
混合模式(4.0+):RDB 全量 + AOF 增量
3. 缓存穿透、击穿、雪崩?
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 穿透 | 查询不存在数据,绕过缓存直达 DB | 布隆过滤器、缓存空值(短过期时间) |
| 击穿 | 热点 key 过期,瞬间大量请求到 DB | 互斥锁(SETNX)、逻辑过期 |
| 雪崩 | 大量 key 同时过期 | 随机过期时间、多级缓存、熔断降级 |
4. Redis 分布式锁?
// Redisson 实现
RLock lock = redisson.getLock("myLock");
try {
lock.lock(); // 看门狗自动续期
// 业务逻辑
} finally {
lock.unlock();
}
-
核心:SET key value NX EX 30(原子性加锁+过期)
-
问题:主从延迟导致锁丢失 → RedLock 算法(多主节点)
5. 过期删除策略?
-
惰性删除:访问时检查过期,省 CPU 但可能堆积
-
定期删除:随机抽查,平衡性能与内存
6. 内存淘汰策略?
-
volatile-lru:过期 key 中 LRU 淘汰(常用) -
allkeys-lru:所有 key 中 LRU 淘汰 -
volatile-ttl:快过期的优先淘汰
四、消息中间件(RocketMQ/Kafka)
1. 消息模型对比?
| 特性 | RocketMQ | Kafka |
|---|---|---|
| 架构 | NameServer + Broker + Producer + Consumer | Zookeeper/KRaft + Broker |
| 消息模型 | 发布-订阅(Tag 过滤) | 发布-订阅 |
| 延迟消息 | 支持 18 个级别 | 不支持(需外部实现) |
| 事务消息 | 支持 | 不支持 |
| 消息顺序 | 队列级别有序 | 分区级别有序 |
| 适用场景 | 金融级可靠、复杂业务 | 大数据日志、高吞吐 |
2. 如何保证消息不丢失?
-
Producer:同步发送 + 失败重试 + 事务消息
-
Broker:同步刷盘(SYNC_FLUSH)、主从复制(SYNC_MASTER)
-
Consumer:先处理业务再提交 Offset,异常时重试
3. 消息顺序消费?
-
全局有序:单队列单消费者,性能差
-
局部有序:按业务 key 取模(如订单 ID)分到同一队列
4. 消息积压处理?
-
扩容消费者(需保证无状态)
-
跳过非关键消息,后续补偿
-
临时消费到数据库,异步处理
5. Kafka 高性能原因?
-
顺序写磁盘(追加日志)
-
零拷贝(sendfile 系统调用)
-
批量压缩(Producer 端压缩,Broker 不解压)
-
分区并行消费
五、Spring Boot
1. 自动装配原理?
-
@SpringBootApplication=@Configuration+@EnableAutoConfiguration+@ComponentScan -
@EnableAutoConfiguration→spring.factories中加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports -
条件注解:
@ConditionalOnClass、@ConditionalOnProperty等控制加载
2. 常用 Starter?
| Starter | 功能 |
|---|---|
| spring-boot-starter-web | Web 开发(Tomcat + Spring MVC) |
| spring-boot-starter-data-jpa | JPA 支持 |
| spring-boot-starter-redis | Redis 集成 |
| spring-boot-starter-test | 测试支持 |
| spring-boot-starter-actuator | 监控端点 |
3. 配置文件优先级?
-
命令行参数 (
--server.port=8081) -
java:comp/envJNDI 属性 -
系统环境变量
-
application-{profile}.properties -
application.properties
4. 事务传播行为?
-
REQUIRED(默认):当前无事务则新建,有则加入 -
REQUIRES_NEW:挂起当前事务,新建独立事务 -
NESTED:嵌套事务,可独立回滚
5. 全局异常处理?
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result handleBusinessException(BusinessException e) {
return Result.fail(e.getCode(), e.getMessage());
}
}
六、Spring Cloud
1. 核心组件?
| 组件 | 功能 | 常用实现 |
|---|---|---|
| 注册中心 | 服务注册与发现 | Nacos、Eureka、Consul |
| 配置中心 | 集中配置管理 | Nacos、Spring Cloud Config |
| 网关 | 路由、限流、鉴权 | Gateway、Zuul |
| 负载均衡 | 客户端负载均衡 | Ribbon(维护模式)、LoadBalancer |
| 熔断降级 | 容错保护 | Sentinel、Hystrix(停更) |
| 链路追踪 | 请求链路监控 | SkyWalking、Sleuth+Zipkin |
2. Nacos vs Eureka?
| 特性 | Nacos | Eureka |
|---|---|---|
| 注册中心 | ✓ | ✓ |
| 配置中心 | ✓ | ✗ |
| 健康检查 | TCP/HTTP/MySQL | 客户端心跳 |
| 负载均衡 | 支持权重、同集群优先 | 简单轮询 |
| 一致性 | AP/CP 切换 | AP |
3. Gateway 工作原理?
-
基于 Spring 5 WebFlux + Reactor 异步非阻塞
-
核心概念:Route(路由)、Predicate(断言)、Filter(过滤器)
-
执行链:请求 → Predicate 匹配 → Pre Filter → 代理请求 → Post Filter → 响应
4. 熔断降级策略(Sentinel)?
-
慢调用比例:响应时间超过阈值,进入熔断
-
异常比例:异常比例超过阈值,进入熔断
-
异常数:异常数超过阈值,进入熔断
-
熔断后进入 Half-Open 状态,试探性恢复
5. 分布式事务解决方案?
| 方案 | 原理 | 适用场景 |
|---|---|---|
| Seata AT | 代理数据源,记录 UNDO_LOG,二阶段提交 | 简单业务,低并发 |
| Seata TCC | Try-Confirm-Cancel,业务实现补偿 | 复杂业务,高一致性 |
| Seata Saga | 状态机引擎,长事务编排 | 业务流程长 |
| RocketMQ 事务消息 | 半消息 + 本地事务 + 回查 | 异步场景 |
| 最大努力通知 | 本地事务 + 消息通知 + 对账 | 最终一致性 |
七、高频场景题
1. 设计一个秒杀系统?
-
前端:验证码、按钮置灰、CDN 静态化
-
Nginx:限流(漏桶/令牌桶)、负载均衡
-
网关:鉴权、防刷、请求过滤
-
Redis:预减库存(Lua 原子操作)、库存预热
-
RocketMQ:异步下单,削峰填谷
-
MySQL:乐观锁(版本号)防超卖,唯一索引防重复
2. 如何排查线上 CPU 100%?
# 1. 找到高 CPU 进程
top -Hp <pid>
# 2. 线程 ID 转 16 进制
printf "%x\n" <tid>
# 3. 打印堆栈
jstack <pid> | grep <hex_tid> -A 30
# 4. 分析代码
3. 接口慢查询优化?
-
定位 :Arthas
trace方法耗时、SkyWalking 链路追踪 -
数据库:慢 SQL 优化、索引优化、连接池调优(HikariCP)
-
缓存:Redis 缓存热点数据,本地缓存(Caffeine)二级加速
-
异步:非核心逻辑异步化(@Async + 线程池)
-
批量:N+1 问题优化(MyBatis 延迟加载或手动 Join)
建议:面试时结合项目经验回答,用"场景 + 方案 + 效果"结构,体现解决问题的能力。