🤟致敬读者
- 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉
📘博主相关
- 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息
文章目录
- Java中Redis面试题集锦(含过期策略详解)
- **一、Redis基础**
- **二、过期策略详解(重点)**
- **三、高级特性**
- **四、Java生态整合**
- **五、性能优化**
- 面试回答技巧:过期策略
📃文章前言
- 🔷文章均为学习工作中整理的笔记。
- 🔶如有错误请指正,共同学习进步。
Java中Redis面试题集锦(含过期策略详解)
一、Redis基础
-
Redis支持哪些数据类型?在Java中如何操作?
- 数据类型:String、List、Set、SortedSet、Hash、Bitmap等
- Java操作示例(Jedis):
Jedis jedis = new Jedis("localhost"); jedis.set("key", "value"); // String jedis.lpush("list", "item1", "item2"); // List jedis.hset("user:1", "name", "Alice"); // Hash
-
Redis单线程为何高性能?
- 内存操作 + IO多路复用 + 避免上下文切换
- 单线程处理命令保证原子性
二、过期策略详解(重点)
-
Redis的键过期删除策略是什么?
- 惰性删除:访问时检查过期并删除
// Jedis访问时触发惰性删除 String value = jedis.get("expired_key"); // 返回null
- 定期删除:周期性随机扫描过期键(默认10次/秒)
- 每次抽查20个键,删除过期键
- 若过期键比例>25%,重复扫描
- 惰性删除:访问时检查过期并删除
-
Java中如何设置键过期?
jedis.setex("temp_session", 300, "data"); // 300秒后过期 jedis.expire("cache_key", 60); // 60秒后过期 jedis.pexpire("key", 10000L); // 毫秒级过期
-
内存淘汰策略如何与过期键交互?
策略 是否涉及过期键 Java配置示例 volatile-lru
仅淘汰有过期时间的键 config.setMaxMemoryPolicy("volatile-lru")
volatile-ttl
优先淘汰TTL最短的键 allkeys-lru
所有键(含无过期时间) -
主从模式下过期键如何处理?
- 从节点不主动删除,依赖主节点同步DEL命令
- Java代码需确保在主节点操作过期键
三、高级特性
-
如何用Redis实现分布式锁?
// Redisson实现 RLock lock = redisson.getLock("order_lock"); lock.lock(30, TimeUnit.SECONDS); // 设置锁过期时间 try { // 业务逻辑 } finally { lock.unlock(); }
-
缓存穿透/雪崩/击穿解决方案
- 穿透:布隆过滤器 + 空值缓存
if (jedis.get(key) == null) { jedis.setex(key, 300, ""); // 缓存空值 }
- 雪崩:随机过期时间
jedis.setex(key, 60 + new Random().nextInt(30), value);
- 击穿:互斥锁
if (jedis.setnx("lock_key", "1") == 1) { jedis.expire("lock_key", 5); // 获取锁 }
- 穿透:布隆过滤器 + 空值缓存
四、Java生态整合
-
Spring Boot中如何配置Redis过期时间?
spring: redis: timeout: 5000 lettuce: pool: max-active: 8
@Bean public RedisCacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(30)); // 全局过期时间 }
-
Redis事务 vs Lua脚本
- 事务:
jedis.watch("key"); Transaction tx = jedis.multi(); tx.set("key1", "value1"); tx.expire("key1", 60); tx.exec();
- Lua脚本(原子操作):
String script = "redis.call('SET', KEYS[1], ARGV[1]); " + "redis.call('EXPIRE', KEYS[1], ARGV[2]);"; jedis.eval(script, 1, "key", "value", "60");
- 事务:
五、性能优化
-
大Key过期导致阻塞怎么办?
- 启用异步删除(Redis 6.0+):
# redis.conf lazyfree-lazy-expire yes
- Java拆分大Key:
// 将大Hash拆分为多个小Key for (int i=0; i<100; i++) { jedis.hset("user:1:part" + i, "field", "value"); }
- 启用异步删除(Redis 6.0+):
-
如何监控过期键?
// 获取过期键统计 String info = jedis.info("stats"); // expired_keys: 累计过期键数量 // evicted_keys: 内存淘汰键数量
面试回答技巧:过期策略
当被问到Redis过期策略时,按层次回答:
- 核心机制:惰性删除 + 定期删除
- 存储结构:过期字典(Expires Dictionary)
- 持久化影响:
- RDB:持久化时不保存过期键
- AOF:记录DEL命令
- 集群特性:主节点控制删除,从节点被动同步
- Java实践:
- 合理设置TTL避免堆积
- 监控
expired_keys
指标 - 大Key使用异步删除
示例回答:
“Redis采用惰性删除和定期删除组合策略。当访问键时会触发惰性删除,同时Redis每秒10次随机扫描过期键。在Java中,我们通过setex()
设置过期,结合volatile-ttl
策略优化内存。对于大Key,建议启用Redis 6.0的异步删除避免阻塞主线程。”
通过这些问题,面试官可以全面考察你对Redis在Java中的应用能力,特别是对过期机制的深入理解。
📜文末寄语
- 🟠关注我,获取更多内容。
- 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
- 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
- 🔵加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
- 🟣点击下方名片获取更多内容🍭🍭🍭👇