Java面试高频问题(21-25)
二十一、分布式锁实现方案对比
核心方案对比
方案 实现原理 优点 缺点 技术选型
Redis RedLock 多节点RedLock算法 高可用,去中心化 实现复杂,时钟依赖 Redisson
ZooKeeper 临时有序节点+Watcher 强一致性,可靠性高 性能较低,依赖运维 Curator
数据库乐观锁 版本号/状态机更新 实现简单,无需依赖中间件 性能差,并发能力弱 MySQL
java
// Redisson可重入锁示例
RLock lock = redissonClient.getLock("order_lock");
try {
boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
// 执行业务逻辑
}
} finally {
lock.unlock();
}
核心挑战
1. 锁超时问题:业务未执行完导致锁自动释放(需结合业务幂等性)
2. 脑裂问题:Redis主从切换时的锁失效(RedLock算法要求多数节点可用)
3. 羊群效应:ZooKeeper大量客户端同时监听节点(需优化Watcher机制)
二十二、分库分表进阶问题:动态扩容与数据迁移
关键技术点
1. 一致性哈希算法:减少数据迁移量(节点增减仅影响相邻节点)
2. 双写中间件:ShardingSphere的Shadow算法实现数据同步
3. 灰度迁移:按用户ID分批迁移,业务无感知
数据迁移异常处理
异常类型 解决方案 技术实现
数据丢失 双写校验+日志回放 Canal监听binlog
迁移延迟 读写分离+影子库 ShardingSphere影子表
主键冲突 全局唯一ID生成器 Snowflake+分片因子
二十三、消息队列可靠性投递:exactly-once语义实现
技术实现方案
mermaid
sequenceDiagram
生产者->>MQ: 发送消息(携带唯一ID)
MQ-->>生产者: 返回ACK
生产者->>数据库: 写入业务数据+消息状态
消费者->>MQ: 消费消息(携带业务流水号)
消费者->>数据库: 更新业务状态+消息状态
数据库->>消费者: 返回结果
alt 消息重复
消费者->>数据库: 查询流水号是否存在
数据库-->>消费者: 返回已处理
消费者-->>MQ: 确认消费
end
核心保障机制
1. 生产者端:事务消息+本地表关联
2. 服务端:消息去重表+幂等性索引
3. 消费者端:状态机+唯一流水号校验
性能优化点
1. 批量确认:Kafka的acks=all机制
2. 异步刷盘:RocketMQ的同步刷盘与异步刷盘选择
3. 压缩消息:Protobuf二进制编码
二十四、分布式会话管理:多级缓存与一致性方案
会话存储架构
mermaid
graph TD
A客户端 --> BAPI网关
B --> CRedis集群
C --> D本地缓存
D --> E业务服务
E --> F数据库
核心技术方案
1. Spring Session:基于Redis的Session共享
2. JWT+服务端缓存:无状态Token+黑名单机制
3. 多级缓存:Caffeine+Redis+本地ThreadLocal
会话失效处理
场景 解决方案 技术参数
Token过期 滑动窗口续期 Redis过期时间延长
分布式时钟不一致 NTP时间同步+最大容忍时间窗口 时钟偏差<500ms
缓存雪崩 随机过期时间+二级缓存降级 Redis过期时间+30s随机
二十五、分布式一致性算法:Raft与Paxos对比
核心算法特性
特性 Raft Paxos
角色划分 Leader/Follower/Learner Proposer/Acceptor/Learner
日志复制 强一致性 最终一致性
故障恢复 自动Leader选举 多阶段提交
工程复杂度 简单(ETCD实现) 复杂(Chubby/ZAB变种)
java
// Raft日志复制伪代码
class RaftNode {
long currentTerm;
String votedFor;
List<LogEntry> log;
void appendEntries(LogEntry entry) {
if (matchTerm(entry.term) && isLeader()) {
log.add(entry);
replicateToFollowers();
}
}
}
应用场景对比
场景 推荐算法 核心优势
分布式KV存储 Raft 强一致性,易监控
元数据管理 Paxos 高容错,跨机房部署
分布式锁服务 ZAB 高性能,线性一致性