“我不会让我的梦想成为像天上的月亮一样遥不可及的遗憾,我不希望人生有太多这样的遗憾”🌹
目录
Redis五种常见的数据类型的特点以及应用场景?
谈谈你对跳表的理解?
Redis的过期删除策略是什么?
Redis的内存淘汰策略是什么?(注意与过期删除策略进行区分)
什么是缓存雪崩、缓存击穿、缓存穿透?各自的解决方案是什么?
布隆过滤器的原理是什么?缺点与优点?
参考资料:跳表 、图解redis
Redis五种常见的数据类型的特点以及应用场景?
string:
- 介绍:常见的key-value型数据类型
- 内部实现:int和SDS(简单动态字符串,可保存文本数据和二进制数据)
- 应用场景:缓存对象、常规计数、分布式锁、共享session
list:
- 介绍:有序列表,按照插入顺序排序
- 内部实现:双向链表或压缩列表
- 应用场景:消息队列。使用LPUSH+RPOP实现消息保序;使用BRPOP实现消息的阻塞式读取(队列中有消息时并不会通知消费者,消费者会不断调用RPOP);使用BRPOPLPUSH实现了消息的可靠性(消费者在读取消息时可能会发生宕机,所以在读取时先插入另一个list作为备份)
- 缺点:无法支持多个消费者读取同一条消息
hash:
- 介绍:key-value型,但是不同于string,hash的value又分为两部分:filed和value
- 内部实现:压缩列表或哈希表
- 应用场景:缓存对象、购物车
set:
- 介绍:无序列表,不会按照插入顺序进行排序,且会对列表内重复元素进行去重
- 内部实现:哈希表或整数集合
- 应用场景:用户点赞(一个用户只能点一个赞)、共同关注(交集)、抽奖活动(一个用户只能被抽中一次)
zset:
- 介绍:有序集合,不能有重复成员
- 内部实现:压缩列表或跳表
- 应用场景:排行榜、电话或姓名排序
谈谈你对跳表的理解?
定义:跳表是一种类似于链表的数据结构,其插入、查找、删除的时间复杂度都是O(logN),实际上基于一种事件换空间的思想
特点:
- 由许多层组成
- 每一层都是一个有序的链表
- 每一个节点不仅指向同层的下一个节点,还指向下层的节点
- 最下层的链表包含了所有的元素

Redis的过期删除策略是什么?
惰性删除和定期删除
惰性删除:
- 定义:每次从数据库中访问key,才会判断这个key有没有过期;如果过期则进行删除
- 优点:在访问时才会进行删除,所以对CPU友好
- 缺点:如果某个过期key没有被访问到,那么在被访问之前会一直占用内存
定期删除:
- 定义:每次从数据库中抽取一定数量的key进行检查,并删除过期key
- 检查频率:默认每秒十次
- 执行过程:先从数据库中抽取一定数量的key进行检查,如果过期key数量与抽取数量的比值大于四分之一,那么就继续抽取;否则就等待下一轮检查
Redis的内存淘汰策略是什么?(注意与过期删除策略进行区分)
内存淘汰策略可以分为不进行数据淘汰和进行数据淘汰两种策略
不进行数据淘汰:
- noeviction,当内存已经被占满时,redis抛出OOM异常,停止工作
进行数据淘汰:又分为在已经设置过期时间的键中进行淘汰和在所有键中进行淘汰
在设置过期时间的键中进行淘汰:
- volatile-random:在已设置过期时间的键中进行淘汰
- volatile-ttl:淘汰最早过期的键值
- volatile-lru:在已设置过期时间的键中,淘汰最近最久未使用的
- volatile-lfu:在已设置过期时间的键中,淘汰最少使用的
在所有键中进行淘汰:
- allkeys-random:在所有键中随机淘汰
- allkeys-lru:在所有键中,淘汰最近最久未使用的
- allkeys-lfu:在所有键中,淘汰最少使用的
什么是缓存雪崩、缓存击穿、缓存穿透?各自的解决方案是什么?
缓存雪崩:
- 大量数据在同一时间过期或者redis发生故障宕机,此时有大量请求到达,由于无法在redis层进行处理,于是所有的请求都会到达数据库,从而导致数据库压力骤增,严重的话可能导致数据库宕机从而产生连锁反应,导致整个系统崩溃
解决方案:
- 针对数据在同一时间过期:1、均匀设置过期时间,在设置过期时间时给过期时间添加一个随机数。2、使用双key策略,双key分为主key和备key,给主key设置过期时间,但是不给备key设置过期时间,当主key过期时,直接返回备key
- 针对redis故障宕机:1、使用服务熔断机制或请求限流,当有大量请求到达redis时,redis无法处理,可以直接返回错误,使请求不再访问数据库,redis恢复正常之后,再允许业务访问;只将少部分请求进行处理,再多的请求就直接在入口处拒绝。2、构建redis集群,当主节点故障之后,使用从节点替代
缓存击穿:
- 某个热点数据过期,此时有大量请求访问该热点数据,无法从缓存中读取,所有请求就会到达数据库,导致数据库压力骤增
解决方案:
- 互斥锁:保证同一个时间只能有一个业务更新缓存
- 不给热点数据设置过期时间,如果热点数据被淘汰,使用消息队列通知后台线程
缓存穿透:
- 用户所访问的数据既不在缓存中,也不在数据库中,大量的请求出现时,会穿过缓存层去访问数据库,导致数据库被击垮
解决方案:
- 对非法请求进行限制,在API入口处判断是否有非法参数,如果有则进行拦截
- 缓存空值或默认值,如果发现缓存穿透现象,则直接在缓存层中缓存一个空值或默认值,后续请求到达时,直接返回
- 使用布隆过滤器来快速判断数据是否存在,避免请求直接查询数据库
布隆过滤器的原理是什么?缺点与优点?
布隆过滤器由初始值都为0的位图数组和N个哈希函数组成,当写入数据库时,先在布隆过滤器中做一个标记,等查询这个数据时,先到过滤器中进行查询
执行过程:
- 先由N个哈希函数对数据做哈希计算,得到N个哈希值
- 用这个N个哈希值对位图数组的长度进行取模运算,得到N个值
- 将这N个值在位图数组中对应的的位置设置为1

因为布隆过滤器使用到了哈希函数,所以存在哈希冲突;但是,使用布隆过滤器进行查找比较高效,如果布隆过滤器说数据存在,那么数据库中可能不存在这个数据;但是如果说不存在,那么数据库中就一定不存在这个数据

整理面经不易,觉得有帮助的小伙伴点个赞吧~感谢观看~