最全Redis面试题大集合,帮你轻松搞定各种考点和难题
- 问答
- 2026-01-23 15:01:49
- 12
Redis到底是什么?它能做什么? 这个问题是开场白,你可以说Redis是一个基于内存的键值数据库,它读写速度特别快,所以常被用来做缓存,就是把一些经常要查的数据放里面,减轻后面像MySQL这种主要数据库的压力,除了缓存,它还能做消息队列、分布式锁、计数器等等,功能挺多的。
Redis支持哪些数据类型?别说五种,说全点。 大部分人都能说出五种基本的:String(字符串)、List(列表)、Hash(哈希)、Set(集合)、ZSet(有序集合),但这不够,你得说出更多的,才能显得你懂得多。
- String:最简单的类型,就是key-value,可以存字符串、数字甚至图片序列化后的东西,可以做计数器(incr命令)。
- List:双向链表,可以从两头插入弹出,可以用来做简单的消息队列或者最新消息列表。
- Hash:类似Java里的Map,适合存储对象,比如把一个用户的姓名、年龄、性别存成一个hash。
- Set:无序且不重复的集合,可以用来做交集、并集运算,比如共同好友推荐。
- ZSet:带分数的Set,元素按分数排序,排行榜功能最适合用它。
- Bitmaps:位图,实际上是用String类型实现的,但提供了一套位操作命令,可以用来做大量数据的布尔统计,比如用户签到记录。
- HyperLogLog:用来做基数统计的,就是估算一个集合中不重复元素的个数,统计网站UV(独立访客)很高效,占用空间极小,但有不到1%的误差。
- Geospatial:地理空间信息,可以存储地理位置(经纬度),并计算两地距离、查找附近的人等。
- Stream:这是Redis 5.0引入的,专门为消息队列设计的数据类型,功能比用List做队列要强大和完善。
为什么Redis这么快? 这是个必问题,你不能只说“因为它是内存数据库”,这太表面了,要说得有层次。
- 内存操作:数据都在内存里,读写操作直接对内存,这是速度快的根本。
- 单线程模型:Redis的网络IO和键值对读写是由一个线程完成的,这避免了多线程的上下文切换和竞争条件带来的开销,注意,Redis6.0之后的多线程只是针对网络IO部分,处理命令的核心模块还是单线程。
- 高效的数据结构:Redis自己实现了一套像简单动态字符串(SDS)、跳跃表、压缩列表等数据结构,这些结构都是为了高效操作而设计的。
- I/O多路复用:Redis使用epoll这样的机制,让单个线程能高效处理大量的连接请求。
什么是缓存穿透、缓存击穿、缓存雪崩?怎么解决? 这是考察缓存经典问题的,必须会。
- 缓存穿透:指的是查询一个根本不存在的数据,缓存和数据库都查不到,这样每次请求都会打到数据库上,就像穿透了缓存。解决办法:a) 对不存在的key也缓存一个空值(比如null),并设置一个较短的过期时间,b) 使用布隆过滤器(Bloom Filter),在查询缓存前先经过布隆过滤器拦截,如果判断不存在,就直接返回,避免查询数据库。
- 缓存击穿:指的是一个非常热点的key,在它过期的瞬间,大量请求涌来,全部穿透缓存,直接打到数据库。解决办法:a) 设置热点数据永不过期,b) 使用互斥锁(分布式锁),当第一个请求去查数据库时加锁,其他请求等待,等第一个请求重建缓存后,后面的请求就能直接从缓存拿了。
- 缓存雪崩:指的是缓存中大量的key在同一时间过期,或者Redis服务宕机,导致所有请求都落到数据库,造成数据库压力巨大甚至崩溃。解决办法:a) 给不同的key设置随机的过期时间,避免同时失效,b) 设置热点数据永不过期,c) 如果是Redis集群,搭建高可用架构(主从复制、哨兵模式、集群模式),避免单点故障,d) 服务降级和熔断机制,当发现数据库压力过大时,对部分非核心请求直接返回预设值,保护数据库。
Redis怎么保证数据不丢?持久化怎么做? Redis是内存数据库,重启或宕机数据会丢,所以需要持久化到硬盘,主要有两种方式:
- RDB(快照):在指定的时间间隔内,将内存中的数据生成一个快照文件(dump.rdb)保存到磁盘。优点:文件紧凑,恢复大数据集速度很快。缺点:可能会丢失最后一次快照之后的数据(比如5分钟持久化一次,宕机就会丢5分钟数据)。
- AOF(追加日志):记录每一次写操作命令,以日志的形式追加到一个文件里,重启时重新执行这些命令来恢复数据。优点:数据完整性高,可以配置为每秒同步一次,最多丢一秒数据。缺点:AOF文件通常比RDB文件大,恢复速度慢。 通常生产环境会两者结合使用,用AOF来保证数据不丢失,用RDB来做冷备。
Redis怎么实现分布式锁?
在分布式系统里,要控制多个服务同时操作一个资源,就需要分布式锁,Redis用SET key value NX PX milliseconds这个命令来实现。
NX表示只有当key不存在时才能设置成功。PX给key设置一个过期时间,这是为了防止加锁的服务挂了,锁永远无法释放。value最好设置一个唯一的值(比如UUID),这样在释放锁的时候可以验证是不是自己加的锁,避免误删别人的锁,释放锁时,要用Lua脚本保证判断和删除是原子操作。
Redis的内存用完了会怎样?
这涉及到内存淘汰策略,你可以通过maxmemory参数设置最大内存,当内存达到上限时,Redis会根据配置的淘汰策略来删除一些key,腾出空间,策略有:
noeviction(默认):新写入操作会报错。(一般不用)allkeys-lru:从所有key中淘汰最近最少使用的。volatile-lru:从设置了过期时间的key中淘汰最近最少使用的。allkeys-random:从所有key中随机淘汰。volatile-random:从设置了过期时间的key中随机淘汰。volatile-ttl:淘汰即将过期的key(TTL最小的)。 最常用的是allkeys-lru。
讲讲Redis的过期键删除策略? 光设置过期时间不行,还得有机制来删除它们,Redis用了两种策略结合:
- 惰性删除:当客户端访问一个key时,Redis会检查它是否过期,如果过期就删除,这样对CPU友好,但可能留下很多永不访问的过期key,浪费内存。
- 定期删除:Redis每隔一段时间(默认100ms)会随机抽取一些设置了过期时间的key,检查并删除其中已过期的,通过这种方式,减少内存浪费。 两种策略配合,保证了内存的合理使用。
如何实现一个简单的消息队列?
可以用List类型的LPUSH和BRPOP命令,生产者用LPUSH从左边插入消息,消费者用BRPOP从右边阻塞地获取消息。BRPOP是阻塞的,如果没有消息会一直等待,这样就实现了简单的点对点队列,但对于复杂的消息队列需求(如消费者组、消息回溯),建议使用Redis 5.0的Stream类型或者专业的消息队列如Kafka、RocketMQ。
什么是Redis事务?它和MySQL事务一样吗?
Redis事务是通过MULTI、EXEC、DISCARD等命令实现的,它把多个命令打包,然后按顺序一次性执行,但要注意,Redis事务不支持回滚(Rollback),如果在执行EXEC命令前有命令语法错误,整个事务都不会执行,但如果是在EXEC之后,某个命令执行出错(比如对字符串做集合操作),那么只有这条命令失败,其他命令照样执行,这和MySQL的原子性事务是完全不同的概念,所以常说Redis事务是“部分原子性”的。
这份集合涵盖了从基础概念到高级用法的核心考点,记住这些要点和解决思路,能帮助你应对大多数Redis相关的面试问题。

本文由符海莹于2026-01-23发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://ujkg.haoid.cn/wenda/84519.html
