互联网高频面试题:Redis灵魂14问?问到你怀疑人生,面试官打压面试者

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

###3.List

常用命令: lpush,rpush,lpop,rpop,lrange等

list 就是链表,Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表, 消
息列表等功能都可以用Redis的 list 结构来实现。
Redis list 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。另
外可以通过 lrange 命令,就是从某个元素开始读取多少个元素,可以基于 list 实现分页查询,这个很棒的一个功
能,基于 redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西(一页一页的往下走),性能高。
###4.Set

常用命令: sadd,spop,smembers,sunion 等

set 对外提供的功能与list类似是一个列表的功能,特殊之处在于 set 是可以自动排重的。
当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在 一
个set集合内的重要接口,这个也是list所不能提供的。可以基于 set 轻易实现交集、并集、差集的操作。
比如:在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis可以非常 方
便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程,具体命令如下:

k e y 3
将交集存在 key1 内

###5.Sorted Set

常用命令: zadd,zrange,zrem,zcard等

和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。
举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度
的消息排行榜)等信息,适合使用 Redis 中的 SortedSet 结构进行存储。

###6.redis 设置过期时间
Redis中有个设置时间过期的功能,即对存储在 redis 数据库中的值可以设置一个过期时间。作为一个缓存数据库, 这
是非常实用的。如我们一般项目中的 token 或者一些登录信息,尤其是短信验证码都是有时间限制的,按照传统的
数据库处理方式,一般都是自己判断过期,这样无疑会严重影响项目性能。
我们 set key 的时候,都可以给一个 expire time,就是过期时间,通过过期时间我们可以指定这个 key 可以存活的
时间。
如果假设你设置了一批 key 只能存活1个小时,那么接下来1小时后,redis是怎么对这批key进行删除的? 定
期删除+惰性删除。
通过名字大概就能猜出这两个删除方式的意思了。
定期删除:redis默认是每隔 100ms 就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。
注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的
设置过期时间的 key 的话,就会给 CPU 带来很大的负载!
惰性删除 :定期删除可能会导致很多过期 key 到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期key,
靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓
的惰性删除,也是够懒的哈!
s i n t e r s t o r e k e y 1 k e y 2
k e y 3
将交集存在 key1 内
但是仅仅通过设置过期时间还是有问题的。我们想一下:如果定期删除漏掉了很多过期 key,然后你也没及时去查, 也
就没走惰性删除,此时会怎么样?如果大量过期key堆积在内存里,导致redis内存块耗尽了。怎么解决这个问题 呢?
redis 内存淘汰机制。
###7.redis 内存淘汰机制(MySQL里有2000w数据,Redis中只存
###20w的数据,如何保证Redis中的数据都是热点数据?)
redis 配置文件 redis.conf 中有相关注释,我这里就不贴了,大家可以自行查阅或者通过这个网址查看:
http://download.redis.io/redis-stable/redis.conf
redis 提供 6种数据淘汰策略:
5. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
6. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
7. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
8. allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的).
9. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
10. no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使
用吧!
###8.redis 持久化机制(怎么保证 redis 挂掉之后再重启数据可以进行恢复)
很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机
器、机器故障之后回复数据),或者是为了防止系统故障而将数据备份到一个远程位置。
Redis不同于Memcached的很重一点就是,Redis支持持久化,而且支持两种不同的持久化操作。Redis的一种持久 化
方式叫快照( snapshotting , RDB ) , 另一种方式是只追加文件( append-only fi le,AOF ).这两种方法各有千 秋,下
面我会详细这两种持久化方法是什么,怎么用,如何选择适合自己的持久化方法。
快照(snapshotting)持久化(RDB)
Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后,可以对快照进行备
份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis性 能),
还可以将快照留在原地以便重启服务器的时候使用。
快照持久化是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:
###AOF(append-only file)持久化
与快照持久化相比,AOF持久化 的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启
AOF(append only file)方式的持久化,可以通过appendonly参数开启:

开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保
存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof。
在Redis的配置文件中存在三种不同的 AOF 持久化方式,它们分别是:

为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几
乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操 作
的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。
Redis 4.0 对于持久化机制的优化
Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 开启)。
如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB
和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是
AOF 格式,可读性较差。
补充内容:AOF 重写
AOF重写可以产生一个新的AOF文件,这个新的AOF文件和原有的AOF文件所保存的数据库状态一样,但体积更小。
AOF重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有AOF文件进行任伺读 入、
分析或者写入操作。
在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新AOF文件
期间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件的工作之后,服务器会将重写缓冲区中的所有内容
追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的
AOF文件,以此来完成AOF文件重写操作。
##9.redis 事务
Redis 通过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。事务提供了一种将多个命令请求打包,然后
一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令 请
求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。在传统的关系式数据库中,常常用 ACID 性质来检验事务功能的可靠性和安全性。在 Redis 中,事务总是具有原子性
(Atomicity)、一致性(Consistency)和隔离性(Isolation),并且当 Redis 运行在某种特定的持久化模式下时,事务也
具有持久性(Durability)。
##10.Redis 常见异常及解决方案
缓存使用过程当中,我们经常遇到的一些问题总结有四点:
#####10.1 缓存穿透
一般访问缓存的流程,如果缓存中存在查询的商品数据,那么直接返回。 如果缓存中不存在商品
数据, 就要访问数据库。
由于不恰当的业务功能实现,或者外部恶意攻击不断地请求某些不存在的数据内存,由于缓存中没
有保存该数据,导致所有的请求都会落到数据库上,对数据库可能带来一定的压力,甚至崩溃。
解决方案:
针对缓存穿透的情况, 简单的对策就是将不存在的数据访问结果, 也存储到缓存中,避免缓存访
问的穿透。最终不存在商品数据的访问结果也缓存下来。有效的避免缓存穿透的风险。
######10.2 缓存雪崩
当缓存重启或者大量的缓存在某一时间段失效,这样就导致大批流量直接访问数据库,对 DB 造
成压力, 从而引起 DB 故障,系统崩溃。
举例来说, 我们在准备一项抢购的促销运营活动,活动期间将带来大量的商品信息、库存等相关
信息的查询。 为了避免商品数据库的压力,将商品数据放入缓存中存储。 不巧的是,抢购活动期
间,大量的热门商品缓存同时失效过期了,导致很大的查询流量落到了数据库之上。对于数据库来
说造成很大的压力。
解决方案:

  1. 将商品根据品类热度分类, 购买比较多的类目商品缓存周期长一些, 购买相对冷门的类目
    商品,缓存周期短一些;
  2. 在设置商品具体的缓存生效时间的时候, 加上一个随机的区间因子, 比如说 5~10 分钟
    之间来随意选择失效时间;
  3. 提前预估 DB 能力, 如果缓存挂掉,数据库仍可以在一定程度上抗住流量的压力
    这三个策略能够有效的避免短时间内,大批量的缓存失效的问题。
    #####10.3 缓存预热
    缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的
    时候,先查询数据库,然后再将数据缓存的问题。用户直接查询事先被预热的缓存数据。如图所示:

    如果不进行预热, 那么 Redis 初识状态数据为空,系统上线初期,对于高并发的流量,都会访
    问到数据库中, 对数据库造成流量的压力。
    解决方案
  4. 数据量不大的时候,工程启动的时候进行加载缓存动作;
  5. 数据量大的时候,设置一个定时任务脚本,进行缓存的刷新;
  6. 数据量太大的时候,优先保证热点数据进行提前加载到缓存。

#####10.4 缓存降级
降级的情况,就是缓存失效或者缓存服务挂掉的情况下,我们也不去访问数据库。我们直接访问内
存部分数据缓存或者直接返回默认数据。
举例来说:
对于应用的首页,一般是访问量非常大的地方,首页里面往往包含了部分推荐商品的展示信息。
这些推荐商品都会放到缓存中进行存储,同时我们为了避免缓存的异常情况,对热点商品数据也
存储到了内存中。同时内存中还保留了一些默认的商品信息。如下图所示:

降级一般是有损的操作,所以尽量减少降级对于业务的影响程度。
##11.分布式环境下常见的应用场景
#####11.1 分布式锁
当多个进程不在同一个系统中,用分布式锁控制多个进程对资源的操作或者访问。 与之对应有线
程锁,进程锁。
分布式锁可以避免不同进程重复相同的工作,减少资源浪费。 同时分布式锁可以避免破坏数据正
确性的发生, 例如多个进程对同一个订单操作,可能导致订单状态错误覆盖。应用场景如下。
#####11.1.1 定时任务重复执行
随着业务的发展,业务系统势必发展为集群分布式模式。如果我们需要一个定时任务来进行订单状
态的统计。比如每 15 分钟统计一下所有未支付的订单数量。那么我们启动定时任务的时候,肯
定不能同一时刻多个业务后台服务都去执行定时任务, 这样就会带来重复计算以及业务逻辑混乱
的问题。
这时候,就需要使用分布式锁,进行资源的锁定。那么在执行定时任务的函数中,首先进行分布式
锁的获取,如果可以获取的到,那么这台机器就执行正常的业务数据统计逻辑计算。如果获取不到
则证明目前已有其他的服务进程执行这个定时任务,就不用自己操作执行了,只需要返回就行了。
如下图所示:
#####11.1.2 避免用户重复下单
分布式实现方式有很多种:

  1. 数据库乐观锁方式
  2. 基于 Redis 的分布式锁
  3. 基于 ZK 的分布式锁
    咱们这篇文章主要是讲 Redis,那么我们重点介绍基于 Redis 如何实现分布式锁。
    分布式锁实现要保证几个基本点。
  4. 互斥性:任意时刻,只有一个资源能够获取到锁。
  5. 容灾性:能够在未成功释放锁的的情况下,一定时限内能够恢复锁的正常功能。
  6. 统一性:加锁和解锁保证同一资源来进行操作。
    加锁代码演示:
    解锁代码演示:
    ##11.2 分布式自增 ID
    应用场景
    随着用户以及交易量的增加, 我们可能会针对用户数据,商品数据,以及订单数据进行分库分表
    的操作。这时候由于进行了分库分表的行为,所以 MySQL 自增 ID 的形式来唯一表示一行数据
    的方案不可行了。 因此需要一个分布式 ID 生成器,来提供唯一 ID 的信息。
    实现方式
    通常对于分布式自增 ID 的实现方式有下面几种:
  7. 利用数据库自增 ID 的属性
  8. 通过 UUID 来实现唯一 ID 生成
  9. Twitter 的 SnowFlake 算法
  10. 利用 Redis 生成唯一 ID
    在这里我们自然是说 Redis 来实现唯一 ID 的形式了。使用 Redis 的 INCR 命令来实现唯一
    ID。
    Redis 是单进程单线程架构,不会因为多个取号方的 INCR 命令导致取号重复。因此,基于 Redis
    的 INCR 命令实现序列号的生成基本能满足全局唯一与单调递增的特性。
    代码相对简单, 不做详细的展示了。
    ##12.Redis 集群模式
    作为缓存数据库,肯定要考虑缓存服务稳定性相关的保障机制。
    持久化机制就是一种保障方式。持久化机制保证了 Redis 服务器重启的情况下也不会损失(或少
    量损失)数据,因为持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据。
    随着 Redis 使用场景越来越多,技术发展越来越完善,在 Redis 整体服务上的容错、扩容、稳
    定各个方面都需要不断优化。 因此在 Redis 的集群模式上也有不同的搭建方式来应对各种需求。
    总结来说,Redis 集群模式有三种:
     主从模式
     哨兵模式
     Cluster 集群模式
    ####12.1 主从模式
    为了 Redis 服务避免单点故障,通常的做法是将 Redis 数据复制多个副本以部署在不同的服务
    器上。这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。为此,Redis 提供
    了复制( replication )功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步

最后

毕竟工作也这么久了 ,除了途虎一轮,也七七八八面试了不少大厂,像阿里、饿了么、美团、滴滴这些面试过程就不一一写在这篇文章上了。我会整理一份详细的面试过程及大家想知道的一些问题细节

美团面试经验

美团面试
字节面试经验
字节面试
菜鸟面试经验
菜鸟面试
蚂蚁金服面试经验
蚂蚁金服
唯品会面试经验
唯品会

因篇幅有限,图文无法详细发出

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-AS2wyha9-1713299453411)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值