本文目录导读:

- 场景题一:设计一个短链接系统(系统设计 + 基础)
- 场景题二:OOM排查实战(JVM调优 + 性能排查)
- 场景题三:分布式锁的实现(并发 + 分布式)
- 场景题四:线程池拒绝策略导致任务丢失(并发 + 生产故障)
- 场景题五:数据库分库分表后跨库查询(架构设计)
- 附加建议
下面为你提供 5个高频Java面试场景题,涵盖设计、调优、并发、排查和架构方面,并给出解题思路和代码示例。
场景题一:设计一个短链接系统(系统设计 + 基础)
面试官问:如果让你设计一个类似 bit.ly 的短链接服务,你如何保证短链接不重复、高并发下不冲突,并且能快速跳转?
思路解析:
- 生成短码:使用
Base62(数字+大小写字母)编码自增ID;或使用MurmurHash对原URL取哈希,再截断。 - 冲突处理:自增ID天然不冲突;哈希方案需要回查数据库或用布隆过滤器预判。
- 存储:MySQL建表
(short_code, original_url, created_at),主键用short_code,并加缓存。 - 缓存:使用 Redis 做两级缓存(短码→原URL),用 Caffeine 做本地缓存,降低Redis压力。
- 跳转:302 重定向(便于统计点击量)。
代码示例(核心部分):
// Base62 编码
public class Base62Encoder {
private static final String BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static String encode(long num) {
StringBuilder sb = new StringBuilder();
while (num > 0) {
sb.append(BASE62.charAt((int) (num % 62)));
num /= 62;
}
return sb.reverse().toString();
}
public static long decode(String str) {
long num = 0;
for (char c : str.toCharArray()) {
num = num * 62 + BASE62.indexOf(c);
}
return num;
}
}
场景题二:OOM排查实战(JVM调优 + 性能排查)
面试官问:线上应用突然发生 OutOfMemoryError: Java heap space,你会怎么排查?
回答要点(逐步排查):
- 保留现场:加
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/dump.hprof参数,让JVM自动导出堆快照。 - 用MAT分析:
- 打开堆转储文件,看
Dominator Tree(支配树),找到占用最大内存的对象。 - 检查是内存泄漏(Leak Suspects)还是内存溢出(对象确实都还活着,只是太多)。
- 打开堆转储文件,看
- 区分场景:
- 泄漏:查看GC roots引用链,找到是谁强引用了这个对象(如静态集合未清理)。
- 溢出:比如一次性加载大文件到内存,或分页查询时
offset过大导致缓存穿透。
- 代码层面排查:检查是否有
ThreadLocal未remove、是否有InputStream未关闭、是否有大集合未置空。
代码示例(一个典型泄漏案例):
public class MemoryLeakDemo {
// 静态List持有对象,导致无法回收
public static List<Object> leakList = new ArrayList<>();
public void leak() {
while (true) {
Object obj = new Object();
leakList.add(obj); // 一直在增加,从不清理
}
}
}
场景题三:分布式锁的实现(并发 + 分布式)
面试官问:在分布式系统中,如何保证多个服务实例对同一个资源操作的互斥性?
回答要点:
- 基于 Redis SETNX
- 命令:
SET lock_key unique_value NX PX 30000 - 释放:用Lua脚本保证原子性(先判断value是否一致再DEL)。
- 问题:主从切换时可能丢锁;需要续期(看门狗机制)。
- 命令:
- 基于 ZooKeeper 临时有序节点
- 每个客户端创建临时有序节点,取序号最小的获得锁,后续节点监听前一个节点。
- 优点:没有锁过期时间,不会死锁;缺点:性能比Redis略差。
- 最佳实践:Java中直接用
Redisson的RLock,自带看门狗续期。
代码示例(Redisson 实现):
@Autowired
private RedissonClient redissonClient;
public void doWithLock(String key) {
RLock lock = redissonClient.getLock(key);
try {
// 尝试加锁,最多等待5秒,锁有效期30秒(看门狗会自动续期)
boolean isLocked = lock.tryLock(5, 30, TimeUnit.SECONDS);
if (!isLocked) {
throw new RuntimeException("获取锁失败");
}
// 业务逻辑...
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
场景题四:线程池拒绝策略导致任务丢失(并发 + 生产故障)
面试官问:某次线上高峰期,使用 Executors.newFixedThreadPool(10) 处理异步任务,发现大量任务被丢弃,你怎么处理?
问题分析:
- 根本原因:
newFixedThreadPool默认使用LinkedBlockingQueue(无界队列),但队列满了后会用AbortPolicy(抛异常)丢弃任务。 - 改进方案:
- 自定义线程池,使用 有界队列 + CallerRunsPolicy(让提交任务的线程自己执行),避免任务丢失与雪崩。
- 做好 拒绝监控:在拒绝时打印日志或发送告警。
代码示例(自定义线程池):
public class ThreadPoolConfig {
public static ExecutorService createPool() {
int core = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
core, // 核心线程数
core * 2, // 最大线程数
60L, TimeUnit.SECONDS, // 空闲回收时间
new ArrayBlockingQueue<>(1000), // 有界队列
new ThreadFactoryBuilder().setNameFormat("biz-pool-%d").build(),
new CallerRunsPolicy() // 拒绝策略:调用者执行
);
return executor;
}
}
场景题五:数据库分库分表后跨库查询(架构设计)
面试官问:订单表数据量达到亿级,做分库分表后(按 user_id hash),如何做订单列表查询(跨分片)和订单详情查询?
回答要点:
- 方案设计:
- 订单详情:订单ID应包含分片键信息(如
user_id + 序号),或使用 UID 生成器(如 snowflake),查详情时直接路由到对应分片。 - 订单列表:如果按 user_id 分片,那么一个用户的订单都在同一分片,直接用
WHERE user_id = ?查询即可。 - 跨分片查询:如后台运营需要查全量订单,使用 中间层聚合(如 ShardingSphere 联邦查询),或同步到 Elasticsearch 做宽表查询。
- 订单详情:订单ID应包含分片键信息(如
- 注意事项:
- 避免跨分片 JOIN:尽量把关联表也按相同维度分片。
- 使用 全局ID:雪花算法或号段模式,保证全局唯一。
代码示例(分片键路由思路):
public class OrderService {
// 根据订单ID最前面几位截取分片号,如 user_id % 16
public int getShardByUserId(Long userId) {
return (int) (userId % 16);
}
public Order getOrderById(Long orderId, Long userId) {
int shard = getShardByUserId(userId);
// 直接路由到对应分片库的表
return orderMapperShard[shard].selectByOrderId(orderId);
}
}
附加建议
面试时,场景题不要直接说“我不会”,而是按以下步骤回答:
- 澄清需求:问清是功能问题、性能问题还是稳定性问题。
- 给出方案:说一两个可行的技术方案。
- 对比利弊:分析每个方案的优劣势与适用场景。
- 落地实施:给出关键代码或伪代码。
- 验证优化:如何测试、监控、回滚。
如果你有想针对某个方向(如秒杀、消息队列、微服务链路追踪)深入了解的,可以告诉我,我可以给你更细致的场景题!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播