【java面试题-Redis篇-2024】

##java面试题大全

详细面试题-持续更新中-点击跳转

点赞、收藏、加关注
·
·

java基础面试题

  • ##java面试题大全
    • 1、什么是 Redis
    • 2、Redis 的数据结构类型
    • 3、Redis 为什么快
    • 4、什么是跳跃表
    • 5、什么是 I/O 多路复用
    • 6、什么是缓存击穿、缓存穿透、缓存雪崩
    • 7、什么是布隆过滤器
    • 8、热点 Key 问题
      • 1)热点 Key 怎么样会影响到 Redis 服务
      • 2)如何识别到热点 Key
      • 3)如何解决 热点 Key 问题
    • 9、Redis 过期策略和内存淘汰策略
    • 10、Redis 持久化
    • 11、实现 Redis 的高可用
      • 1)主从集群
      • 2)哨兵模式
      • 3)分片集群
    • 12、使用过 Redis 分布式锁嘛
    • 13、Redisson 原理
    • 14、什么是 Redlock 算法
    • 15、MySQL 与 Redis 如何保证双写一致性
    • 16、Redis 事务机制
    • 17、Redis 的 Hash 冲突怎么办
    • 18、Redis 底层,使用的什么协议

1、什么是 Redis

Redis,英文全称是 Remote Dictionary Server(远程字典服务),是一个开源的使用 C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。与 MySQL 数据库不同的是,Redis 的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过 10 万次读写操作。因此 Redis 被广泛应用于缓存,另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务、持久化、LUA 脚本、多种集群方案

2、Redis 的数据结构类型

** 1.String **

  • 简介:字符串。String 是 Redis 最基础的数据结构类型,它是二进制安全的,可以存储图片或者序列化的对象,值最大存储为 512M
  • 应用场景:共享 Session、分布式锁、计数器
  • 拓展:C 语言的字符串是 char[] 实现的,而 Redis 使用 SDS(simple dynamic string)封装。SDS 会保存空闲的长度、已使用的长度、实际保持的内容值。
    • 字符串长度处理:Redis 获取字符串长度,时间复杂度为 O(1),而 C 语言中,需要从头开始遍历,复杂度为 O(n)
    • 空间预分配:字符串修改越频繁的话,内存分配越频繁,就会消耗性能,而 SDS 修改和空间扩充,会额外分配未使用的空间,减少性能损耗
    • 惰性空间释放:SDS 缩短时,不是回收多余的内存空间,而是 free 记录下多余的空间,后续有变更,直接使用 free 中记录的空间,减少分配
    • 二进制安全:Redis 可以存储一些二进制数据,在C语言中字符串遇到 ‘\0’ 会结束,而 SDS 中标志字符串结束的是 len 属性

** 2.Hash **

  • 简介:哈希。哈希类型是指 v(值)本身又是一个键值对(k-v)结构
  • 应用场景:缓存用户对象信息

** 3.List **

  • 简介:列表。列表类型是用来存储多个有序的字符串
  • 应用场景:消息队列、文章列表
  • 拓展:lpush+lpop=Stack(栈);lpush+rpop=Queue(队列);lpsh+ltrim=Capped Collection(有限集合);lpush+brpop=Message Queue(消息队列)

** 4.Set **

  • 简介:集合。集合类型也是用来保存多个的字符串元素,但是不允许重复元素
  • 应用场景:用户标签、生成随机数抽奖、用户点赞
  • 拓展:smembers 和 lrange、hgetall 都属于比较重的命令,如果元素过多存在阻塞 Redis 的可能性,可以使用 sscan 来完成

** 5.ZSet **

  • 简介:有序集合。已排序的字符串集合,同时元素不能重复
  • 应用场景:排行榜

** 6.Geo **

  • 简介:地图位置。Redis3.2 推出的,地理位置定位,用于存储地理位置信息,并对存储的信息进行操作
  • 应用场景:用户定位,附近商家

** 7.Bitmaps **

  • 简介:位图。用一个比特位来映射某个元素的状态,在 Redis 中,它的底层是基于字符串类型实现的,可以把 Bitmaps 成作一个以比特位为单位的数组
  • 应用场景:签到、用户是否在线状态

** 8.HyperLogLog **

  • 简介:用来做基数统计算法的数据结构
  • 应用场景:统计网站的UV

3、Redis 为什么快

  • 基于内存存储实现:Redis 基于内存存储实现的数据库,相对于数据存在磁盘的 MySQL 数据库,省去磁盘 I/O 的消耗
  • 高效的数据结构:Redis 自己也封装了一些数据结构,可以有效的提高效率。如:String 的动态字符串结构、ZSet 的跳跃表
  • 合理的数据编码:Redis 每种基本类型,对应多种数据结构,使用什么样编码,是 Redis 设计者总结优化的结果,Redis 会自动的根据元素个数、元素内容大小选择合适的数据编码。如:
    • String:如果存储数字的话,是用 int 类型的编码;如果存储非数字,小于等于 39 字节的字符串,是 embstr 编码;大于 39 个字节,则是 raw 编码。
    • List:如果列表的元素个数小于 512 个,列表每个元素的值都小于 64 字节(默认),使用 ziplist 编码,否则使用 linkedlist 编码
    • Zset:当有序集合的元素个数小于 128 个,每个元素的值小于 64 字节时,使用 ziplist 编码,否则使用 skiplist(跳跃表)编码
  • 合理的线程模型:采用 I/O 多路复用。I/O 多路复用技术可以让单个线程高效的处理多个连接请求,而 Redis 使用用 epoll 作为 I/O 多路复用技术的实现。并且,Redis 自身的事件处理模型将 epoll 中的连接、读写、关闭都转换为事件,不在网络 I/O 上浪费过多的时间
  • 虚拟内存机制:Redis 直接自己构建了 VM 机制 ,不会像一般的系统会调用系统函数处理,会浪费一定的时间去移动和请求。虚拟内存机制就是暂时把不经常访问的数据(冷数据)从内存交换到磁盘中,从而腾出宝贵的内存空间用于其它需要访问的数据(热数据)。通过 VM 功能可以实现冷热数据分离,使热数据仍在内存中、冷数据保存到磁盘。这样就可以避免因为内存不足而造成访问速度下降的问题

4、什么是跳跃表

  • 跳跃表是有序集合 zset 的底层实现之一
  • 跳跃表支持平均 O(logN) 复杂度的节点查找,还可以通过顺序性操作批量处理节点
  • 跳跃表就是在链表的基础上,增加多级索引提升查找效率

5、什么是 I/O 多路复用

  • redis的网络模型是 io 多路复用+事件派发,有多个事件处理器,如连接应答处理器、[命令回复处理器]、命令请求处理器([接受请求参数、把数据转换成redis命令]、执行命令写入到缓冲队列、[由命令回复处理器进行响应给客户端结果])。[多线程的处理]
  • Redis 是基于内存的,所以它的性能瓶颈是网络 IO,IO 多路复用技术就是为了实现高效的网络请求,6 版本之后引入多线程也是为了解决这个问题
    • 阻塞 io:需要内核缓冲区等待数据,然后从内核缓冲区拷贝到用户缓冲区
    • 非阻塞 io:请求内核缓冲区的数据,没有就返回异常信息,然后再去请求,直到有数据,然后从内核缓冲区拷贝到用户缓冲区
    • io 多路复用:使用单个线程如使用 select 函数可以监听多个 socket(客户端的连接),并在某个 socket 可读可写时得到通知,避免无效的等待。使用 select 或者 poll 实现不会知道是哪个 socket 就绪的,使用 epoll 用户进程会知道就绪的 socket

6、什么是缓存击穿、缓存穿透、缓存雪崩

** 缓存击穿: **

  • 产生原因:指热点 Key 在某个时间点过期的时候,而恰好这个时间点有大量的并发请求这个热点 Key,从而大量的请求请求到数据库,导致数据库压力过大甚至宕机
  • 解决方法:
    • 使用互斥锁:缓存失效时,不是立即去加载数据库数据,而是先使用某些带成功返回的原子操作命令,如 Redis 的 setnx 去操作,成功的时候,再去加载数据库数据和设置缓存。否则就去重试获取缓存,这样就可以保证只有一个请求请求数据库
    • 设置永不过期:是指不设置过期时间

** 缓存穿透: **

  • 产生原因:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而导致数据库压力过大甚至宕机
  • 解决方法:
    • 校验非法请求:在 API 入口,对参数进行校验,过滤非法值
    • 缓存空值:如果查询数据库为空,可以给缓存设置个空值,或者默认值
    • 使用布隆过滤器:使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查,可能存在误判,key 如果不存在那一定不存在,如果判断 key 存在,也有可能是不存在的

** 缓存雪崩: **

  • 产生原因:指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,导致数据库压力过大甚至宕机
  • 解决方法:
    • 过期时间分散:缓存雪奔一般是由于大量数据同时过期造成的,对于这个原因,可通过均匀设置过期时间解决,比如添加随机数
    • 构建高可用集群:Redis 故障宕机也可能引起缓存雪奔,这就需要构造Redis高可用集群了

7、什么是布隆过滤器

  • 布隆过滤器是一种占用空间很小的数据结构,它由一个很长的二进制向量和一组Hash映射函数组成,它用于检索一个元素是否在一个集合中,空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难
  • 布隆过滤器原理:假设我们有个集合 A,A 中有 n 个元素。利用 k 个哈希散列函数,将 A 中的每个元素映射到一个长度为 a 位的数组 B 中的不同位置上,这些位置上的二进制数均设置为 1。如果待检查的元素,经过这 k 个哈希散列函数的映射后,发现其 k 个位置上的二进制数全部为 1,这个元素很可能属于集合 A,反之,一定不属于集合 A
  • 如何降低误判率:搞多几个哈希函数映射,降低哈希碰撞的概率;增加 B 数组的 bit 长度

8、热点 Key 问题

在 Redis 中,把访问频率高的 Key,称为热点 Key。如果某一热点 Key 的请求到服务器主机时,由于请求量特别大,可能会导致主机资源不足,甚至宕机,从而影响正常的服务

1)热点 Key 怎么样会影响到 Redis 服务

  • 用户消费的数据远大于生产的数据,如秒杀、热点新闻等读多写少的场景
  • 请求分片集中,超过单 Redis 服务器的性能,比如固定名称 Key,Hash 值落入同一台服务器,瞬间访问量极大,超过机器瓶颈,产生热点 Key 问题

2)如何识别到热点 Key

  • 凭经验判断哪些是热Key;
  • 客户端统计上报;
  • 服务代理层上报

3)如何解决 热点 Key 问题

  • Redis 集群扩容,增加分片副本,均衡读流量
  • 将热点 Key 分散到不同的服务器中
  • 使用二级缓存,即 JVM 本地缓存,减少 Redis 的读请求

9、Redis 过期策略和内存淘汰策略

** 过期策略:**

  • 定时过期:每个设置过期时间的 Key 都需要创建一个定时器,到过期时间就会立即对 Key 进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的 CPU 资源去处理过期的数据,从而影响缓存的响应时间和吞吐量
  • 惰性过期:只有当访问一个 Key 时,才会判断该 Key 是否已过期,过期则清除。该策略可以最大化地节省 CPU 资源,却对内存非常不友好。极端情况可能出现大量的过期 Key 没有再次被访问,从而不会被清除,占用大量内存
  • 定期过期:每隔一定的时间,会扫描一定数量的数据库的字典中一定数量的 Key,并清除其中已过期的 Key。该策略是前两者的一个折中方案。一般同时使用了惰性过期和定期过期两种策略

** 淘汰策略:**

  • volatile-lru:当内存不足以容纳新写入数据时,从设置了过期时间的 Key 中使用 LRU(最近最少使用) 算法进行淘汰
  • allkeys-lru:当内存不足以容纳新写入数据时,从所有 Key 中使用 LRU 算法进行淘汰
  • volatile-lfu:4.0 版本新增,当内存不足以容纳新写入数据时,在过期的 Key 中,使用 LFU(使用频率最少) 算法进行删除 Key
  • allkeys-lfu:4.0 版本新增,当内存不足以容纳新写入数据时,从所有 Key 中使用 LFU 算法进行淘汰
  • volatile-random:当内存不足以容纳新写入数据时,从设置了过期时间的 Key 中,随机淘汰数据
  • allkeys-random:当内存不足以容纳新写入数据时,从所有 Key 中随机淘汰数据
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的 Key 中,根据过期时间进行淘汰,越早过期的优先被淘汰
  • noeviction:默认策略,当内存不足以容纳新写入数据时,新写入操作会报错

10、Redis 持久化

RDB 持久化:

  • Redis Database Backup file(Redis数据备份文件)
  • 每隔一段时间会将数据保存到磁盘中的备份文件中,在 redis.conf 配置文件中配置
  • 执行条件:执行 save 命令,会阻塞;执行 bgsave 命令,异步执行;Redis 停机时;触发 RDB 条件时,在 redis.conf 配置文件中配置,如:save 90 1:90秒内,如果至少有1个 key 被修改,则执行 bgsave
  • 优缺点: 适合大规模的数据恢复场景,如备份,全量复制等。没办法做到实时持久化/秒级持久化;新老版本存在 RDB 格式兼容问题

AOF 持久化:

  • Append Only File(追加文件)
  • 每一个写命令都会记录在 AOF 文件,默认关闭,修改 redis.conf 配置文件来开启。AOF 每次写命令都会记录(频率一般设置为每秒),所以文件会记录一些没用的数据,而且占用会很大,所以需要文件重写来压缩持久化文件,auto-aof-rewrite-percentage 100 AOF 文件比上次文件增长超过 100% 则触发重写,auto-aof-rewrite-min-size 64mb AOF 文件体积 64M 以上触发重写
  • 优缺点: 数据的一致性和完整性更高。AOF 记录的内容越多,文件越大,数据恢复变慢

11、实现 Redis 的高可用

1)主从集群

搭建:
在多个服务器上启动多个 Redis 实例,要想让 B、C 实例成为 A 实例的从节点,需要在 B、C 实例的配置文件或者命令行中使用命令 slaveof <masterip> <masterport> ,A 就成为了主节点,可读可写,B、C 就成为了从节点,只可读;它们的数据会自动同步

全量同步:

  1. slave 节点请求增量同步,将自己的 Replication Id(是数据集的标记,id一致则说明是同一数据集。每一个 master 都有唯一的 replid,slave 则会继承 master 节点的 replid) 和 offset(偏移量,随着记录在 repl_baklog 中的数据增多而逐渐增大。slave 完成同步时也会记录当前同步的 offset。如果 slave 的 offset 小于 master 的 offset,说明 slave 数据落后于 master,需要更新) 发送过去
  2. master 节点判断 replid,发现不一致,拒绝增量同步,确定了是第一次请求
  3. master 将完整内存数据生成 RDB,发送 RDB 到 slave
  4. slave 清空本地数据,加载 master 的 RDB,并将继承 master 节点的 replid
  5. master 将 RDB 期间的命令记录在 repl_baklog,并持续将 log 中的命令发送给 slave
  6. slave 执行接收到的命令,保持与 master 之间的同步

增量同步:

  1. master 判断 slave 发送过来的 replid 与自己一致,然后就发送 repl_baklog 中两者的 offset 相差值的内容来进行增量同步
  2. repl_baklog 相当于是一个环形数组,当 slave 出现问题,导致两者的 offset 相差值大于了整个数组的长度,就必须进行全量同步了

优化主从集群:

  • 在 master 中配置 repl-diskless-sync yes 启用无磁盘复制,避免全量同步时的磁盘 IO,但要求是网络带宽大,否则可能出现阻塞
  • Redis 单节点上的内存占用不要太大,减少 RDB 导致的过多磁盘 IO
  • 适当提高 repl_baklog 的大小,发现 slave 宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个 master 上的 slave 节点数量,如果实在是太多 slave,则可以采用主-从-从链式结构,减少 master 压力

2)哨兵模式

作用:

  • 监控:Sentinel 会不断检查您的 master 和 slave 是否按预期工作,每秒 ping 一下,未在规定时间内响应,则认为该实例主观下线,若超过指定数量(quorum)的 Sentinel 都认为该实例主观下线,则该实例客观下线
  • 自动故障恢复:如果 master 故障(客观下线),Sentinel 会将一个 slave 选举为 master。当故障实例恢复后也以新的 master 为主。选举前先排除与 master 节点断开超过指定时间的 slave 节点,主要根据 offset 值,越大说明数据越新,优先级越高
  • 通知:Sentinel 充当 Redis 客户端,当集群发生故障转移时,会将最新信息推送给 Redis 的客户端。Sentinel 给选中的 slave 节点发送 slaveof no one 命令,让该节点成为 master,然后给所有其它slave发送slaveof <新 master ip> <新 master port> 命令,让这些 slave 成为新 master 的从节点,最后,Sentinel 将故障节点标记为 slave,当故障节点恢复后会自动成为新的 master 的 slave 节点

搭建哨兵集群:

  1. 创建多个哨兵实例
  2. 为每个实例编写配置文件,指定监控的 master 节点的 ip、port、quorum
  3. 启动每一个实例,redis-sentinel 配置文件路径

RedisTemplate 使用哨兵集群:
1.引入 spring-boot-starter-data-redis 依赖
2.配置 Redis 地址:spring:redis:sentinel:nodes: List<每个哨兵的ip地址:端口号>
3.配置读写分离:

@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){//REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取masterreturn clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

3)分片集群

主从和哨兵可以解决高可用、高并发读的问题,分片集群进一步解决海量数据存储问题和高并发写的问题

搭建:
1.创建多个 Redis 实例
2.为每一个实例创建配置文件
3.启动每一个实例
4.使用命令创建集群:redis-cli --cluster create --cluster-replicas 1(每一个主节点的从节点数量) 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003(根据计算,前三个会成为主节点,后三个会成为从节点)

散列插槽:
Redis 会把每一个 master 节点映射到 0~16383 共 16384 个插槽(hash slot)上。数据 key 是与插槽绑定的。Redis 会根据 key 的有效部分进行 Hash 取余计算插槽值来决定数据存放在哪个 master 上,有效部分是:key 中包含 “{}”,且 “{}” 中至少包含 1 个字符,“{}” 中的部分是有效部分;key 中不包含 “{}”,整个 key 都是有效部分。可以设置 {} 前缀来将一类数据保存到同一 master 上

集群伸缩:
1.启动一个 Redis 实例
2.添加实例到集群:redis-cli --cluster add-node 192.168.150.101:7004(自己的实例) 192.168.150.101:7001(通知给集群中的一个实例)
3.转移插槽,刚添加的实例是没有插槽的,redis-cli --cluster reshard 192.168.150.101:7004(自己的实例),然后根据选项输入指定实例 id 来转移指定数量的插槽

故障转移:

  • 自动故障转移:当 一个master 宕机后,集群会自动选一个它的子节点来成为 master 节点
  • 手动故障转移:利用 cluster failover 命令可以手动让集群中这个 slave 节点成为 master 节点,实现无感知的数据迁移

RedisTemplate 使用分片集群:

  1. 引入 spring-boot-starter-data-redis 依赖
  2. 配置 Redis 地址:spring:redis:cluster:nodes: List<每个哨兵的ip地址:端口号>
  3. 配置读写分离:
@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){//REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取masterreturn clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}

12、使用过 Redis 分布式锁嘛

数据库实现:
乐观锁,多个线程去插入数据,谁插入成功谁就获取到锁

zookeeper 实现:

zookeeper 的结构类似的文件目录,多线程向 zookeeper 创建一个子目录(节点)只会有一个创建成功,利用此特点可以实现分布式锁,谁创建该结点成功谁就获得锁

Redis 实现:

  • set key value NX EX 失效时间 命令实现,setIfAbsent(key,value) 方法,只有当键不存在的时候才能设置成功。需要结合 Lua 脚本解决原子性问题。而且过期时间设置不好确定
  • Redisson 实现,使用看门狗线程给使用中的锁续期,保证原子性,实现了 Lock 接口,List 接口

13、Redisson 原理

Redisson 使用:

  1. 引入 redisson-spring-boot-starter 依赖
  2. 在 yml 配置文件中配置 redisson 配置文件位置,然后引入配置文件
  3. 使用 RedissonClient 对象,getLock 方法设置锁获得 Lock 锁对象,然后锁对象进行上锁 lock(),释放锁 unlock

Redisson 原理:
只要线程加锁成功,就会启动一个 watch dog 看门狗,它是一个后台线程,会每隔 10 秒检查一下,如果线程还持有锁,那么就会不断的延长锁 key 的生存时间。因此,Redisson 就是解决了锁过期释放,业务没执行完问题

14、什么是 Redlock 算法

Redlock 算法解决的问题:
Redis 一般都是集群部署的,假设数据在主从同步过程,主节点挂了,如果线程一在 Redis 的 master 节点上拿到了锁,但是加锁的 key 还没同步到 slave 节点。恰好这时,master 节点发生故障,一个 slave 节点就会升级为 master 节点。线程二就可以获取同个 key 的锁,但线程一也已经拿到锁了,锁的安全性就得不到保障了,Redlock 算法就是解决这个问题的

Redlock 算法核心思想:
搞多个 Redis master 部署,以保证它们不会同时宕掉。并且这些 master 节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个 master 实例上,是与在 Redis 单实例,使用相同方法来获取和释放锁

Redlock 算法核心步骤:

  • 按顺序向多个 master 节点请求加锁
  • 根据设置的超时时间来判断,是不是要跳过该 master 节点
  • 如果大于一半的节点加锁成功,并且使用的时间小于锁的有效期,即可认定加锁成功
  • 如果获取锁失败,解锁

15、MySQL 与 Redis 如何保证双写一致性

  • 延时双删:强一致性。先删缓存,再修改数据库,因为有数据库的主从复制,所以延时一会在删除缓存。但是延时的时间不好控制,还是有脏数据风险
  • 分布式锁:强一致性。使用加锁来防止意外情况,然后就可以正常同步数据。使用读写锁提高性能,代码中使用 redissonClient.getReadWriteLock 方法实现
  • MQ 异步通知:最终一致性。依赖 MQ 的可靠性
  • Canal 异步通知:最终一致性。伪装成从节点监听 binlog 日志

16、Redis 事务机制

Redis 通过 multi、exec、watch 等一组命令集合,来实现事务机制。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。简言之,Redis事务就是顺序性、一次性、排他性的执行一个队列中的一系列命令。执行事务的流程:开始事务(MULTI)、命令入队、执行事务(EXEC)、撤销事务(DISCARD )

17、Redis 的 Hash 冲突怎么办

  • Redis 作为一个 K-V 的内存数据库,它使用用一张全局的哈希来保存所有的键值对。这张哈希表,有多个哈希桶组成,哈希桶中有 entry 元素,每一个 entry 元素保存了 key 和 value 指针,其中 *key 指向了实际的键,*value 指向了实际的值
  • Redis 为了解决哈希冲突,采用了链式哈希。链式哈希是指同一个哈希桶中,多个元素用一个链表来保存,它们之间依次用指针连接。哈希冲突链上的元素只能通过指针逐一查找再操作
  • 当往哈希表插入数据很多,冲突也会越多,冲突链表就会越长,那查询效率就会降低了。为了保持高效,Redis 会对哈希表做 rehash 操作,也就是增加哈希桶,减少冲突。为了 rehash 更高效,Redis 还默认使用了两个全局哈希表,一个用于当前使用,称为主哈希表,一个用于扩容,称为备用哈希表
    在这里插入图片描述

18、Redis 底层,使用的什么协议

  • RESP,英文全称是 Redis Serialization Protocol,它是专门为 Redis 设计的一套序列化协议。这个协议其实在 Redis 1.2 版本时就已经出现了,但是到了 Redis 2.0 才最终成为 Redis 通讯协议的标准
  • RESP 主要有实现简单、解析速度快、可读性好等优点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/600507.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VSCode输入花括号{}}会多一个解决方案

打开设置 搜索Closing Brackets 选择BeforeWhitespace 选完后重启下VSCode即可

中颖51芯片学习3. 定时器

中颖51芯片学习3. 定时器 一、SH79F9476定时器简介1. 简介2. 定时器运行模式 二、定时器21. 说明&#xff08;1&#xff09;时钟&#xff08;2&#xff09;工作模式 2. 寄存器&#xff08;1&#xff09;控制寄存器 T2CON&#xff08;2&#xff09;定时器2模式控制寄存器 T2MOD …

Netty学习——源码篇13 命中缓存的分配 备份

上一篇分析了DirectArena内存分配大小的大概流程(Netty池化内存管理机制),知道了其先命中缓冲&#xff0c;如果没有命中&#xff0c;再去分配一款连续内存。现在分析命中缓存的相关逻辑。前面说到PoolThreadCache中维护了三个缓存数组(实际上是6个&#xff0c;这里仅以Direct为…

【微服务-链路跟踪】Spring Cloud Sleuth核心技术(上)

在前面几篇文章中&#xff0c;我们主要介绍了基于 Sentinel 如何对微服务架构提供限流、熔断保护。从本篇开始&#xff0c;我们继续完善微服务架构&#xff0c;通过介绍链路跟踪原理和基于SpringCloud Sleuth实现链路跟踪。 一、微服务链路跟踪原理 我们先看一个图&#xff0…

基于RTThread的学习(三):正点原子潘多拉 QSPI 通信 W25Q128 实验

1、基于芯片创建工程 2、QSPI配置 2.1、RTThing_setting 设置组件 2.2、配置board.h 文件 2.3、cubemx生成QSPI的硬件初始化代码&#xff1b;HAL_QSPI_MapInit; 这里注意&#xff1a;你所买的开发板对应的qspi 连接的是否是cubemx 上边显示的&#xff0c;如果不是你需要将引脚…

计算机服务器中了rmallox勒索病毒怎么办?Rmallox勒索病毒解密流程步骤

网络为企业的生产运营提供便利的同时&#xff0c;也为企业的数据安全带来严重威胁。随着互联网技术的不断应用与发展&#xff0c;企业的生产运营离不开网络&#xff0c;利用网络可以开展各项工作业务&#xff0c;极大地方便了企业生产运营&#xff0c;大大提升了企业生产效率&a…

MySQL学习笔记------事务

事务 事务是一组操作的集合&#xff0c;他是一个不可分割的单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败 事务操作 create table account(id int comment ID,name varchar(10) …

前端| 富文本显示不全的解决方法

背景 前置条件&#xff1a;编辑器wangEditor vue项目 在pc端进行了富文本操作&#xff0c; 将word内容复制到编辑器中&#xff0c; 进行发布&#xff0c; pc端正常&#xff0c; 在手机端展示的时候 显示不全 分析 根据h5端编辑器内容的数据展示&#xff0c; 看到有一些样式造…

基于RKNN的YOLOv5安卓Demo

1.简介 基于RKNPU2 SDK 1.6.0版的安卓YOLOv5演示应用程序&#xff0c;选择图片进行对象检测并显示识别结果。 GitHub源码地址&#xff1a;https://github.com/shiyinghan/rknn-android-yolov5 2.实现过程 参考RKNN官方库RKNN Model Zoo提供的YOLOv5对象检测demo&#xff0c…

【Web】CTFSHOW-2023CISCN国赛初赛刷题记录(全)

目录 Unzip BackendService go_session deserbug 主打一个精简 Unzip 进来先是一个文件上传界面 右键查看源码&#xff0c;actionupload.php 直接访问/upload.php&#xff0c;看到后端的源码 就是上传一个压缩包&#xff0c;对其进行解包处理 因为其是在/tmp下执行…

C++ | Leetcode C++题解之第16题最接近的三数之和

题目&#xff1a; 题解&#xff1a; class Solution { public:int threeSumClosest(vector<int>& nums, int target) {sort(nums.begin(), nums.end());int n nums.size();int best 1e7;// 根据差值的绝对值来更新答案auto update [&](int cur) {if (abs(cur…

Qt 中的项目文件解析和命名规范

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、Qt项目文件解析 1、.pro 文件解析 2、widget.h 文件解析 3、main.cpp 文件解析 4、widget.cpp…