【大厂秘籍】系列 - Redis基础篇

创作不易,你的关注分享就是博主更新的最大动力, 每周持续更新

微信搜索【 企鹅君】关注还能领取学习资料喔,第一时间阅读(比博客早两到三篇)

求关注❤️ 求点赞❤️ 求分享❤️ 对博主真的非常重要

企鹅君原创|GitHub开源项目github.com/JavaDance 欢迎Star和完善

面试开始

激动的心,颤抖的手, 你打开了面试官发过来的远程面试链接

对面是一位身穿格子衬衫的有点中年发福的男子,

看着屏幕上面试官反光的头顶,一寸亮,一寸强!啧啧,你瞬间就感受面试官的实力恐怖如斯~~

但是你也不慌,因为你早已看了多遍《大厂秘籍》,再见面试官都是小场面

面试官从你的项目聊到了Java知识、数据库, 然后就到了面试基本必问的Redis

你心想这不踢到钢板了吗, 公司同事都尊称你是「Redis小王子

但你还是忍住了心中的沸腾,面色平静、假装着小白等着面试官提问

面试官: 小伙汁, 你能告诉我Redis支持哪些数据结构吗?

Redis 5 种基本数据类型对应以及对应的底层数据结构分别是

数据类型底层数据结构应用场景
String简单动态字符串(SDS)常规热点数据,分布式锁
Hash哈希表、压缩列表结构化数据、对象存储
List双向链表(LinkedList)、压缩列表(ZipList)评论、商品等列表数据
Set整数数组、哈希表适合交集、并集、查集操作, 如朋友圈共同好友
Sort Set(Zset)跳表(SkipList)、压缩列表排行榜

Redis 还支持 3 种特殊的数据类型:

数据类型应用场景
Bitmap(位图)用二进制记录状态
HyperLogLog(基数统计)访问 ip 数统计, 网站UV统计
GEO(地理位置)存储地理位置信息

面试官接着就问到:那你讲下这几种底层数据结构吧

简单动态字符串(SDS)

Redis 是用 C 语言写的, 没有直接用C的字符串, 而是自己构造了

简单动态字符串(simple dynamic string,SDS)类型

struct sdshdr{ 
  int len;//记录buf数组中已使用字节的数量 
  int free; //记录 buf 数组中未使用字节的数量 
  char buf[];//字符数组,用于保存字符串
}

好处是获取字符串长度复杂度为 O(1)(C 字符串为 O(N)), 通过len属性校验杜绝了缓存区的溢出

跳跃表(SkipList)

将有序链表中的部分节点分层,每一层都是一个有序链表。

​ 1、可以快速查找到需要的节点 O(logn) ,额外存储了一倍的空间

​ 2、可以在O(1)的时间复杂度下,快速获得跳跃表的头节点、尾结点、长度和高度。

压缩表(Ziplist)

压缩列表并不是对数据利用某种算法进行压缩,而是将数据按照一定规则编码在一块连续的内存区域,目的是节省内存。

Pipeline有什么好处,为什么要用pipeline?

Redis的pipeline功能的原理是 客户端通过一次性将多条redis命令发往Redis 服务端,减少了每条命令分别传输的IO开销。同时减少了系统调用的次数,因此提升了系统的吞吐能力。

(答得这么好,都有点佩服自己了)

面试官心想,小伙汁不错嘛,答得这么流畅,看来是没少看《大厂秘籍》,接着就问到:那你是怎么实现分布式锁的

通过Redis命令

SET key value[EX seconds][PX milliseconds][NX]
  • EX seconds: 设定过期时间,单位为秒
  • PX milliseconds: 设定过期时间,单位为毫秒
  • NX: 仅当key不存在时设置值

争取锁的时候,执行这条命令

返回ok 代表抢到了锁可以继续执行 (Redis里key不存在)

否则就终止用户操作

如何解决数据一致性问题

可以监听mysql binlog消息,对于mysql的update、insert、delate变更数据。

利用消息队列, 推送刷新redis缓存数据。

如何解决热Key问题

  1. 本地缓存是最常用的解决方案, 例如guavaCache, 命中本地缓存服务端直接返回, 降低redis集群压力

  2. 数据分片, 通过将热点数据分散存储在多个Redis节点上,避免单个节点负载过高,也是解决热点Key问题常用的策略。

  3. 限流, 防止系统过载

  4. 预热,提前将热key加载到缓存中

面试官心想:这小伙汁看来是有备而来,得放个大招让他看看。那你说一说缓存穿透、缓存击穿、缓存雪崩的理解

缓存穿透

​ 缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案:

​ 1)接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;

​ 3)采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。

缓存击穿

​ 缓存击穿是指当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。

解决方案:

​ 1)设置热点数据永远不过期,异步线程处理。

​ 2)使用分布式锁,保证同一时刻只能有一个查询请求重新加载热点数据到缓存中,这样,其他的线程只需等待该线程运行完毕,即可重新从Redis中获取数据。

缓存雪崩

​ 缓存雪崩是指当缓存中有大量的key在同一时刻过期,或者Redis直接宕机了,导致大量的查询请求全部到达数据库,造成数据库查询压力骤增,甚至直接挂掉。

解决方案:

针对第一种大量key同时过期的情况,解决起来比较简单,只需要将每个key的过期时间打散即可,使它们的失效点尽可能均匀分布。或者设置key永不过期等

针对第二种redis发生故障的情况,部署redis时可以使用redis的高可用方案部署主从+哨兵,Redis cluster,避免全盘崩溃

(大家可以先关注企鹅君公众号哦,我会继续更新Redis高可用篇详解这个问题哦~)

面试结束

小伙汁你针不戳,给你发Offer了,能不能早点来公司上班呀

你心想自己手里还有几个其他大厂的Offer呢,还得问下网友考虑选哪个好呢

你当然没把心里话说出来,假装镇定回复合适的话,争取早点来公司。

好的。面试官 心想这小伙汁有点东西,必须把他招进公司,赶紧联系hr给他工资加满。

你感叹《大厂秘籍》果然有用,再也不用担心没有Offer了

赶紧让你的小伙伴也分享点赞收藏!!!

总结

技术面试其实并不难,但是也没有什么捷径,(当然博主希望《大厂秘籍》可以帮助读者少走弯路)平时多看多总结。在面试的时候,可以试着通过自己的项目引导面试官向你熟悉的领域提问,比如你的简历项目里写到了使用Redis解决了XX问题,这时候面试官基本都会问你更细节的东西,这样在你提前准备下逻辑清晰, 有理有据的讲出如何解决问题会在面试官心里加不少分, 那一个个Offer还不到手就来

创作不易,你的关注分享就是博主更新的最大动力, 每周持续更新

微信搜索【 企鹅君 】第一时间阅读(比博客早一到两篇), 关注还能领取资料

求关注❤️ 求点赞❤️ 求分享❤️ 对博主真的非常重要

企鹅君原创|GitHub开源项目github.com/JavaDance 欢迎Star和完善

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值