面试官:我们来聊一聊Redis吧,你了解多少就答多少

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 本文介绍Redis的相关知识。

一、前言



作为一名Java程序员,Redis底层的一些原理是我们不必学会就可以搬砖工作的一种技能点,但是小奇为什么还要讲一下呢?难道就是为了浪费大家1分钟的宝贵时间,一个人1分钟,50万人就是1年,5000万人就是100年,赚了,小奇以一己之力成功搞挂一个人(血赚)。


当然不是,并且小奇的文章也没有那么多人看,最多也就浪费个肾吧。


学习Redis底层原理是因为面试官要问啊!,所以我们就要学,什么?不实用的你不学?那邻居小奇可要使劲学啦,到时候面试官只要小奇不要你。


至于你问为什么面试官要问Redis底层原理呢,这个。。。我把这次机会留给你,下次你面试的时候面试官问:“讲一下Redis底层原理”。你:“面试官你好,请问为什么你要问Redis底层原理呢,你给我台电脑,我五分钟给你搭建好图书管理系统他不香吗,咱们键盘上见真章”。这时面试官就会告诉你答案,你就可以把答案打在评论区,让小奇以及众多小伙伴一起知道一下到底为什么要问?


二、面试



在一个晴朗的周日,我来到了一个陌生的园区(别问为什么是周日,问就是997,不过为了填饱肚子的打工人,只能明知山有虎、偏向虎山行),坐在陌生的会议室,等待HR小姐姐去叫面试官,此时我的心情和各位小伙伴一样五味杂陈,担心面试官问的会不会很难?问到我的知识盲区我该怎么办?一会自我介绍的时候要不要吹一下我和小奇的关系?


一位英俊潇洒,眼神犀利的面试官走了进来,看到他那犀利、仿佛能看穿一切的眼神 ,我在想要不然一会就不要20k了,要8k得了,这个面试官一看就不好糊弄啊,但是我想起来我来之前刚看了小奇的趣学编程系列,我已经完全学会了小奇的精髓,我顿时就来了底气,决定一会要30k,不给就学小奇赖着不走(哈哈)


面试官:小奇是吧,带简历了吗?


我:没带,现在彩印两块一张,我简历五张,每次面试都要花费十块,我朋友说了还没工作就先让你掏钱的工作不要去。


面试官:。。。那你靠什么来征服我,让我录用你


我:气质?


(此时面试官并没有叫保安,而是从门后拿出了恭候我多时的棍子,我瞬间怂了)


我只好从我的双肩包中拿出了我上午从其他公司面试官手中要回的简历,上午的情形是这样的。


上午的面试官:今天的面试就到这吧,回去等通知吧!


我:面试官你好,如果贵公司不打算录取我的话,能不能把我的纸质简历还给我,我下午还有一家面试。


上午的面试官:我说你的简历怎么皱皱巴巴,原来你一直在循环利用啊!这个症状出现多久了?


我:半拉月了。。。


(当我把皱皱巴巴的简历交给面试官后,这场面试才得以继续进行。。。)


三、Redis基本数据类型与使用场景



面试官:我看你简历上写的精通Redis?(哼,面试官轻蔑的一笑)


(看着面试官轻蔑的笑容,我忍不住拿出了我的Redis书籍推给了他)


我:这本书我倒背如流,你随便提问,答不上来算我输,答上来你就要为你的轻蔑向我道歉。


1.jpg


(此时面试官看着书若有所思,我怀疑他肯定在想他对这本书的了解程度吧)


面试官:好吧,那先简单说一下Redis有哪些数据类型吧


我:redis主要有五种数据类型,分别是String、Hash、List、Set、ZSet。


面试官:那他们都是怎么存储和读取数据的呢,有哪些使用场景呢?


1、String


单值存储:set [key] [value]


2.png


取值:get [key]


3.png


多值存储:mset [key1] [value] [key2] [value]


4.png


取值:mget [key1] [key2]


5.png


分布式锁上锁:setnx [key] true

返回1代表上锁成功


6.png


返回0代表上锁失败


7.png


分布式锁释放锁:del [key]


8.png


设置超时时间:expire [key] [时间] (如果出现异常导致删除锁失败,可以设置超时时间,到达时间锁自动删除)


9.png


实现原子性分布式锁加锁并设置超时时间:set [key] true ex [时间] nx (如果上完锁在给锁设置超时时间之间出现异常,还是会导致锁无法删除,那么将上锁命令和设置超时时间命令合为一个命令)


10.png


计数器:incr [key]


11.png


获取计数器的值:get [key]


12.png


批量获取计数:incrby [key]


13.png


获取计数器的值:get [key]


14.png


2、Hash


存储数据:hset [table] [key] [value] (这里我们可以假设实现向购物车中添加商品)


向购物车添加一个苹果


15.png


向购物车添加一本书


16.png


向购物车添加一个香蕉


17.png


在原有商品上加数量:hincrby [table] [key] [数量]

再向购物车中添加一个苹果


18.png


商品种类数量:hlen [table]


19.png


获取购物车所有的商品:hgetall [table]


20.png


删除商品:hdel [table] [key]


21.png


3、List


将一个值放入列表的头部(最左边):lpush [key] [value]


22.png


移除并返回列表的头元素:lpop [key]


23.png


将一个值放入列表的尾部(最右边):rpush [key] [value]


24.png


移除并返回列表的尾元素:rpop [key]


25.png


返回列表中指定区间内的元素:lrange [key] [开始位置] [结束位置]


26.png


从列表表头弹出一个元素,若列表中没有元素,阻塞等待time秒,如果time=0,一直阻塞等待


27.png


从列表表尾弹出一个元素,若列表中没有元素,阻塞等待time秒,如果time=0,一直阻塞等待


28.png


4、Set


往集合key中存入元素,元素存在则忽略,若key不存在则新建:sadd [key] [元素] (这里我们模仿一个抽奖的业务场景,先往集合中放入要抽奖的人)


30.png


从集合key中随机选取几个元素,元素不从集合中删除:srandmember [key] [元素个数] (这里我们抽两个奖项)


31.png


获取集合key中所有元素:smembers [key]


32.png


获取集合key中元素的个数:scard [key]


33.png


判断一元素是否存在于集合中:sismember [key] [元素]


34.png


从集合中删除元素:srem [key] [元素]


35.png


从集合中随机选出几个元素,并且删除:spop [key] [元素个数] (例如我们抽奖的时候先抽了三等奖,那么抽二等奖的时候三等奖的人就没有资格了,就要将三等奖的人删除)


36.png


交集运算:sinter [key] [元素]


37.png


将交集结果存入新集合key2中:sinterstore [key2] [key] [元素]


38.png


并集运算:sunion [key] [元素]


39.png


将并集结果存入新集合key2中:sunionstore [key2] key [元素]


40.png


差集运算:sdiff [key] [运算]


41.png


将差集结果存入新集合key2中:sdiffstore [key2] [key] [元素]


42.png


5、ZSet


往有序集合key中加入带分值的元素:zadd [key] [分值] [元素] (业务中我们可以用来实现例如微博热搜排行的功能)


43.png


返回有序集合key中元素的分值:zscore [key] [元素]


44.png


返回有序集合key中元素的个数:zcard [key]


45.png


为有序集合key中元素的分值加上一个分值:zincrby [key] [分值] [元素]


50.png


正序获取有序集合key从开始下标到结束下标的元素:zrange [key] [开始] [结束]


51.png


倒叙获取有序集合key从开始下标到结束下标的元素:zrevrange [key] [开始下标] [结束下标] (这里就是例如微博热搜榜中根据热度倒叙排序获取前十个)


52.png


从有序集合key中删除元素:zrem [key] [元素]


55.png


四、Redis日常问题



面试官:嗯。你上面写了那么多我也顾不上看,简单的问你几个问题吧


我:好


面试官:Redis中我们怎么创建分布式锁


我:使用setnx命令


面试官:Redis中创建分布式锁后出现异常解锁失败,怎么将这个锁删掉


我:可以使用expire来给锁加一个时间,过了这个时间后Redis自动将这个锁删掉。


面试官:如果在加时间之前就出现异常了,时间没有加上怎么办?


我:可以使用原子性的命令将分布式锁和时间一同创建出来,这样就不用担心异常了,因为原子性,一个成功都成功,一个失败都失败。


面试官:Redis是单线程的吗?


我:Redis在读写操作的时候是单线程的,但是其它功能,例如持久化、异步删除、集群数据同步等是有额外的线程执行的。


面试官:Redis单线程为什么还能这么快?


我:因为Redis的数据都在内存中,而且单线程避免了多线程的切换性能损耗问题。


面试官:Redis单线程如何处理并发客户端连接?


我:Redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器中,事件分派器将事件分发给事件处理器。


面试官:我想全量查询Redis中所有key怎么查询,或者模糊查询符合规则的key怎么查询呢


我:使用 keys * 可以查询Redis中所有的key,如果要模糊查询直接加上规则即可,例如要查询前缀为小奇的key可以使用 keys 小奇* 来查询


面试官:这样查询有没有什么问题呢,有没有其他的解决方案呢?


我:使用 keys * 查询是全量查询Redis中的key值,如果key值过多的话最造成线程堵塞,因为Redis读写是单线程的,我们可以使用scan命令渐进式读取数据。


面试官:可以详细说一下scan命令吗?


我:scan命令的格式为:scan [游标] match [通配符] count [每一次查询的数量] (初始查询的时候游标为0,然后第二次查询游标为第一次查询时返回的数据,依次类推,最后游标返回0时表示查询完毕)


我现在Redis中一共有9条数据,我每次查询3条,分三次查询完毕。


56.png


面试官:scan命令有什么缺点吗,一定能够完全获取全量的数据吗?


我:不一定,如果在scan的过程中有新的数据变化,例如插入数据,删除数据等,那么新增的键可能没有遍历到,因为scan遍历过的地方就不在遍历了,你插入到遍历过的地方就不会再遍历到。


面试官:小伙子真厉害啊,我这边没有什么要问的了,你还有什么问题要问(面试官两眼放光)


我:额。。。面试官这个我的纸质简历可以给我吗,可以不往我的简历上写写画画吗,我明天的面试还要用。


面试官:还面啥别的公司啊,就来我这吧,条件随便开


我:那就100k吧(此时面试官又拿起了他准备好的棍子)


面试官:你要是不来就给我推荐一下,让别人来我这面试一下


我:你先好好学习一下Redis吧,今天幸亏只是我来了,如果是小奇的忠实读者来了,你将会被虐的很惨的。(我将我的《Redis设计与实现》留给了面试官,转身留下了帅气的背影,而面试官落寞无神的呆呆的坐在那里,仿佛一个亿离他而去。。。)


五、总结



这里关于Redis还没有整理完毕,文章后面持续更新,建议收藏。


文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。




相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
NoSQL Redis Sentinel
【怒怼大厂面试官】听说你精通Redis?说说Redis哨兵
面试官:Redis哨兵知道吧?知道的,Sentinel哨兵本质是一个运行在特殊模式下的Redis服务器。面试官:嗯然后呢?它的主要作用是通过检测Redis主从服务器的下线状态,选举出新Redis主服务器,也就是故障转移,来保证Redis的高可用性。
79 4
【怒怼大厂面试官】听说你精通Redis?说说Redis哨兵
|
15天前
|
NoSQL MongoDB Redis
Python与NoSQL数据库(MongoDB、Redis等)面试问答
【4月更文挑战第16天】本文探讨了Python与NoSQL数据库(如MongoDB、Redis)在面试中的常见问题,包括连接与操作数据库、错误处理、高级特性和缓存策略。重点介绍了使用`pymongo`和`redis`库进行CRUD操作、异常捕获以及数据一致性管理。通过理解这些问题、易错点及避免策略,并结合代码示例,开发者能在面试中展现其技术实力和实践经验。
144 8
Python与NoSQL数据库(MongoDB、Redis等)面试问答
|
25天前
|
缓存 NoSQL Java
面试官:Redis如何实现延迟任务?
延迟任务是计划任务,用于在未来特定时间执行。常见应用场景包括定时通知、异步处理、缓存管理、计划任务、订单处理、重试机制、提醒和数据采集。Redis虽无内置延迟任务功能,但可通过过期键通知、ZSet或Redisson实现。然而,这种方法精度有限,稳定性较差,适合轻量级需求。Redisson的RDelayedQueue提供更简单的延迟队列实现。
341 9
|
26天前
|
缓存 NoSQL 定位技术
深入探索Redis:面试中必须掌握的关键知识点
深入探索Redis:面试中必须掌握的关键知识点
|
1月前
|
NoSQL Java 测试技术
面试官:如何搭建Redis集群?
**Redis Cluster** 是从 Redis 3.0 开始引入的集群解决方案,它分散数据以减少对单个主节点的依赖,提升读写性能。16384 个槽位分配给节点,客户端通过槽位信息直接路由请求。集群是无代理、去中心化的,多数命令直接由节点处理,保持高性能。通过 `create-cluster` 工具快速搭建集群,但适用于测试环境。在生产环境,需手动配置文件,启动节点,然后使用 `redis-cli --cluster create` 分配槽位和从节点。集群动态添加删除节点、数据重新分片及故障转移涉及复杂操作,包括主从切换和槽位迁移。
34 0
面试官:如何搭建Redis集群?
|
2月前
|
运维 负载均衡 NoSQL
【大厂面试官】知道Redis集群和Redis主从有什么区别吗
集群节点之间的故障检测和Redis主从中的哨兵检测很类似,都是通过PING消息来检测的。。。面试官抓抓脑袋,继续看你的简历…得想想考点你不懂的😰。
67 1
|
2月前
|
NoSQL Redis
【怒怼大厂面试官】听说你精通Redis?Redis数据同步懂吗
面试官:不用慌尽管说,错了也没关系。。。来说说Redis数据同步。是这样的,Redis有一个叫命令传播的概念,如果像面试官说的这种场景,再使用上面我提到的AOF缓冲区就有点浪费内存空间了。所以Redis会将主服务器的这条Del删除命令
63 2
【怒怼大厂面试官】听说你精通Redis?Redis数据同步懂吗
|
2月前
|
NoSQL Redis 数据库
【怒怼大厂面试官】听说你精通Redis?说说Redis持久化
咳咳咳,看你简历写了精通Redis,那我就随便问问。主要有RDB持久化、AOF持久化。是这样,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。
55 1
【怒怼大厂面试官】听说你精通Redis?说说Redis持久化
|
24天前
|
存储 NoSQL 算法
09- Redis分片集群中数据是怎么存储和读取的 ?
Redis分片集群使用哈希槽分区算法,包含16384个槽(0-16383)。数据存储时,通过CRC16算法对key计算并模16383,确定槽位,进而分配至对应节点。读取时,根据槽位找到相应节点直接操作。
54 12
|
1天前
|
NoSQL Redis
透视Redis集群:心跳检测如何维护高可用性
Redis心跳检测保障集群可靠性,通过PING命令检测主从连接状态,预防数据丢失。当连接异常时,自动触发主从切换。此外,心跳检测辅助实现`min-slaves-to-write`和`min-slaves-max-lag`策略,避免不安全写操作。还有重传机制,确保命令无丢失,维持数据一致性。合理配置心跳检测,能有效防止数据问题,提升Redis集群的高可用性。关注“软件求生”获取更多Redis知识!
23 10
透视Redis集群:心跳检测如何维护高可用性