面试 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)。跳表通过在原始链表的基础上添加多层索引,以提高查找效率。
跳表的实现主要包括以下几个步骤:
- 节点结构: 跳表中的每个节点包含多个指针,指向同一层中下一个节点和下一层中相同位置的节点。
- 头部节点: 跳表有一个头部节点,它不存储任何数据,只作为入口节点。
- 层级索引: 跳表中的每个节点都可能有多个层级索引,每个层级索引都是一个链表节点,它指向下一个节点。
- 插入操作: 在插入新元素时,需要按照一定的规则确定元素应该插入的层级,然后更新相应的索引。
- 删除操作: 删除元素时,需要找到对应的节点并删除,同时更新索引。
- 查找操作: 通过跳表的索引结构,可以快速定位到待查找元素的大致位置,然后在对应层级的链表中进行查找。
跳表的时间复杂度为 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+ 访问!
⭐点赞⭐收藏⭐不迷路!⭐