面试 Redis 八股文十问十答第二期

面试 Redis 八股文十问十答第二期

作者:程序员小白条个人博客

相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!

⭐点赞⭐收藏⭐不迷路!⭐

1)redis 一般都用在什么场景?

Redis(Remote Dictionary Server)通常用于以下场景:

  • 缓存: Redis 可以作为缓存存储数据,可以帮助加速访问频繁的数据,减轻后端数据库的压力。
  • 会话缓存: 用于存储用户的会话信息,可以帮助实现分布式会话管理,提高系统的扩展性和性能。
  • 消息队列: Redis 的发布/订阅功能和列表数据类型可以用于实现简单的消息队列,用于解耦和异步处理任务。
  • 计数器: Redis 的计数器功能可以用于实现各种计数场景,如网站访问量统计、点赞数统计等。
  • 实时排行榜: Redis 的有序集合数据类型可以用于实现实时排行榜功能,如热门商品排行、热门搜索排行等。
  • 分布式锁: Redis 的分布式锁功能可以用于实现分布式系统中的并发控制,确保多个客户端对共享资源的安全访问。

2)redis 为什么这么快?

Redis 之所以快速,主要有以下几个方面的原因:

  • 内存存储: Redis 将数据存储在内存中,读写速度非常快,因为内存的访问速度比磁盘快得多。
  • 单线程模型: Redis 使用单线程模型,避免了多线程之间的线程切换开销和锁竞争,提高了处理请求的效率。
  • 非阻塞 I/O: Redis 使用了非阻塞 I/O 多路复用机制,通过一个线程来管理多个客户端连接,减少了网络 I/O 的开销。
  • 高效的数据结构: Redis 提供了丰富的数据结构,如字符串、列表、哈希表、集合、有序集合等,可以更加高效地存储和操作数据。

3)redis 为什么要设计成单线程?6.0 不是变成多线程了吗?

Redis 最初设计为单线程的主要原因是为了简化实现和提高性能。单线程模型避免了多线程之间的线程切换开销和锁竞争,同时利用了操作系统的非阻塞 I/O 多路复用机制,提高了处理请求的效率。

在 Redis 6.0 中引入了多线程支持,主要是为了充分利用多核处理器的性能。但是这并不意味着 Redis 的设计变成了多线程。多线程模型在某些场景下可能会提高并发能力,但也增加了复杂性和风险,比如线程间的同步与通信、锁竞争等问题。因此,Redis 6.0 仍然采用了单线程和多进程的混合模型,其中单线程处理网络 I/O 和协议解析,而后端任务通过多个线程执行,这样既保留了单线程模型的优势,又能充分利用多核处理器的性能。

4)redis 常见的数据类型有哪些?

Redis 支持多种数据类型,每种数据类型都有不同的特点和用途。常见的数据类型包括:

  • 字符串(String): 最基本的数据类型,可以存储字符串、整数或者浮点数。
  • 哈希表(Hash): 类似于字典,可以存储多个键值对,每个键值对都是一个字段和对应的值。
  • 列表(List): 类似于链表,可以存储多个有序的元素,支持头部和尾部的插入、删除操作。
  • 集合(Set): 类似于集合,可以存储多个不重复的元素,支持并集、交集、差集等操作。
  • 有序集合(Sorted Set): 类似于有序集合,可以存储多个元素,并为每个元素分配一个分数,元素根据分数排序。

5)详细说说 redis 跳表的实现?

Redis 中的跳表(Skip List)是一种有序数据结构,可以用来实现有序集合(Sorted Set)。跳表通过在原始链表的基础上添加多层索引,以提高查找效率。

跳表的实现主要包括以下几个步骤:

  1. 节点结构: 跳表中的每个节点包含多个指针,指向同一层中下一个节点和下一层中相同位置的节点。
  2. 头部节点: 跳表有一个头部节点,它不存储任何数据,只作为入口节点。
  3. 层级索引: 跳表中的每个节点都可能有多个层级索引,每个层级索引都是一个链表节点,它指向下一个节点。
  4. 插入操作: 在插入新元素时,需要按照一定的规则确定元素应该插入的层级,然后更新相应的索引。
  5. 删除操作: 删除元素时,需要找到对应的节点并删除,同时更新索引。
  6. 查找操作: 通过跳表的索引结构,可以快速定位到待查找元素的大致位置,然后在对应层级的链表中进行查找。

跳表的时间复杂度为 O(log n),与平衡二叉树的性能相当,但实现起来比较简单,并且不需要像平衡二叉树那样复杂的平衡操作。

6)redis 的 hash 可以详细讲讲吗?

Redis 的哈希表(Hash)是一种类似于字典的数据结构,可以存储多个键值对,每个键值对都是一个字段和对应的值。Redis 的哈希表支持以下操作:

  • 添加字段(HSET): 将指定字段的值设置为指定的值。
  • 获取字段值(HGET): 获取指定字段的值。
  • 删除字段(HDEL): 删除指定字段。
  • 判断字段是否存在(HEXISTS): 判断指定字段是否存在。
  • 获取所有字段(HKEYS): 获取哈希表中的所有字段。
  • 获取所有值(HVALS): 获取哈希表中的所有值。

哈希表在 Redis 中的内部实现使用了类似于字典的结构,具体来说,它使用了哈希表和链表相结合的方式来实现,其中哈希表用于快速查找字段,链表用于解决哈希冲突。在 Redis 中,哈希表的扩容操作采用了渐进式 rehash 策略,即在扩容过程中仍然可以对哈希表进行读写操作,减少了扩容过程的阻塞时间。

7)redis 和 memcached 有什么区别?

  • 数据类型支持: Redis支持更丰富的数据类型,如字符串、哈希、列表、集合、有序集合等,而Memcached只支持简单的键值对存储。
  • 持久化: Redis支持持久化,可以将数据保存到磁盘上,而Memcached不支持持久化。
  • 数据复杂度: Redis对于更复杂的数据处理(如排序、范围查找等)更友好,而Memcached更适合简单的键值缓存。
  • 内存管理: Redis采用多种内存管理技术,可以更灵活地控制内存的使用,而Memcached的内存管理相对简单。

8)redis 可以实现事务吗?

是的,Redis 支持事务。Redis 的事务通过 MULTI、EXEC、WATCH、DISCARD 等命令实现。在事务中,客户端可以将多个命令组合在一起,然后一次性发送给 Redis 服务器执行。Redis 在执行事务期间会将命令序列化,保证事务的原子性。如果在 EXEC 执行之前,有被 WATCH 监控的键发生了变化,那么事务将被打断。

9)redis 的过期策略可以说说吗?

Redis 的过期策略主要有两种:

  • 定时删除: Redis 使用一个定时器(每秒执行10次)来检查键是否过期,过期的键会被定期删除。
  • 惰性删除: 当访问一个键时,Redis 会先检查该键是否过期,如果过期则删除。这种策略可以节省内存,但会增加访问时的延迟。

10)redis 的内存淘汰策略有哪些?

当内存不足时,Redis 可以通过一些策略来淘汰部分数据以释放内存,常见的内存淘汰策略包括:

  • LRU(Least Recently Used): 淘汰最近最少使用的键。
  • LFU(Least Frequently Used): 淘汰最不经常使用的键。
  • TTL(Time To Live): 淘汰具有过期时间的键。
  • 随机淘汰: 随机选择一些键进行淘汰。

开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system

前后端总计已经 1300+ Star,2W+ 访问!

⭐点赞⭐收藏⭐不迷路!⭐

相关推荐
mubeibeinv1 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
青莳吖2 分钟前
Java通过Map实现与SQL中的group by相同的逻辑
java·开发语言·sql
张声录15 分钟前
【ETCD】【实操篇(三)】【ETCDCTL】如何向集群中写入数据
数据库·chrome·etcd
Buleall9 分钟前
期末考学C
java·开发语言
无为之士11 分钟前
Linux自动备份Mysql数据库
linux·数据库·mysql
重生之绝世牛码11 分钟前
Java设计模式 —— 【结构型模式】外观模式详解
java·大数据·开发语言·设计模式·设计原则·外观模式
小蜗牛慢慢爬行18 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
小汤猿人类24 分钟前
open Feign 连接池(性能提升)
数据库
新手小袁_J42 分钟前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
呆呆小雅43 分钟前
C#关键字volatile
java·redis·c#