Java 面试高频题:Redis 核心考点解析

Redis 作为高性能缓存和数据库系统,是 Java 后端面试的核心考点。以下是必须掌握的 10 个关键知识点,附详细解释和代码示例:


1. 数据类型与适用场景

Redis 支持 5 种核心数据结构:

  • String:缓存计数器(如$PV = \text{page_views}$)
  • Hash:存储对象属性(如用户信息)
  • List:消息队列(LPUSH/RPOP)
  • Set:去重集合(共同关注)
  • ZSet:排行榜(带权重的$score$)
// Java 操作 String 示例(Jedis)
Jedis jedis = new Jedis("localhost");
jedis.set("user:1", "Alice");
String user = jedis.get("user:1"); // 返回 "Alice"


2. 持久化机制:RDB vs AOF
  • RDB:定时快照,恢复快但可能丢数据
    $$ \text{触发条件} = \begin{cases} \text{手动 save} \ \text{自动配置(如 900 秒内 1 次修改)} \end{cases} $$
  • AOF:追加操作日志,数据更安全但文件更大
    # redis.conf 配置
    appendonly yes
    appendfsync everysec  # 每秒同步
    


3. 缓存穿透/雪崩/击穿
问题 原因 解决方案
缓存穿透 查询不存在的数据 布隆过滤器 + 空值缓存
缓存雪崩 大批 key 同时过期 随机过期时间
缓存击穿 热点 key 失效 互斥锁重建缓存

4. 事务与原子性

Redis 事务通过 MULTI/EXEC 实现,但非严格原子性(单条命令失败不影响后续执行):

Transaction tx = jedis.multi();
tx.set("balance", "100");
tx.incrBy("balance", 50);
tx.exec();  // 执行所有命令


5. 发布订阅模式

实现消息广播:

// 发布者
jedis.publish("news_channel", "Breaking News!");

// 订阅者
JedisPubSub listener = new JedisPubSub() {
    @Override
    public void onMessage(String channel, String message) {
        System.out.println("Received: " + message);
    }
};
jedis.subscribe(listener, "news_channel");


6. 内存淘汰策略

当内存不足时触发:

  • volatile-lru:淘汰最近最少使用的过期 key
  • allkeys-random:随机淘汰任意 key
  • noeviction(默认):拒绝写入新数据

7. 集群模式原理
  • 数据分片:通过槽位(slot)分配数据(共 16384 个槽)
  • 高可用:主从复制 + 故障转移(哨兵机制)
  • 扩容:使用 CLUSTER ADDSLOTS 重新分配槽位

8. Lua 脚本原子操作

解决复杂操作的原子性问题:

-- 限制接口调用频率
local count = redis.call('INCR', KEYS[1])
if count == 1 then
    redis.call('EXPIRE', KEYS[1], ARGV[1])
end
return count

Java 调用:jedis.eval(script, keyCount, "api_limit", "60")


9. 管道技术(Pipeline)

批量操作减少网络开销:

Pipeline p = jedis.pipelined();
p.set("key1", "v1");
p.get("key2");
p.sync();  // 一次性发送所有命令


10. 性能优化实践
  • 避免大 key(如 value > 10KB)
  • 使用连接池代替频繁创建连接
  • 监控慢查询:slowlog get 10
  • 合理设置超时时间:config set timeout 30

总结:掌握以上 10 个考点,能覆盖 90% 的 Redis 面试问题。重点关注数据类型、持久化、集群架构和缓存问题解决方案,结合 Java 代码实践加深理解。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐