关于后端:Redis数据结构高频面试题及解析

7次阅读

共计 2730 个字符,预计需要花费 7 分钟才能阅读完成。

概述

Redis 是速度十分快的非关系型(NoSQL)内存键值数据库,能够存储键和五种不同类型的值之间的映射。

键的类型只能为字符串,值反对五种数据类型:字符串、列表、汇合、散列表、有序汇合。

Redis 反对很多个性,例如将内存中的数据长久化到硬盘中,应用复制来扩大读性能,应用分片来扩大写性能。

数据类型

数据类型 能够存储的值 操作
STRING 字符串、整数或者浮点数 对整个字符串或者字符串的其中一部分执行操作,对整数和浮点数执行自增或者自减操作
LIST 列表 从两端压入或者弹出元素,对单个或者多个元素进行修剪,只保留一个范畴内的元素
SET 无序汇合 增加、获取、移除单个元素,查看一个元素是否存在于汇合中,计算交加、并集、差集,从汇合外面随机获取元素
HASH 蕴含键值对的无序散列表 增加、获取、移除单个键值对,获取所有键值对,查看某个键是否存在
ZSET 有序汇合 增加、获取、删除元素,依据分值范畴或者成员来获取元素,计算一个键的排名

STRING

Redis 的 String 类型应用 SDS(简略动静字符串)作为底层的数据结构实现。SDS 与 C 字符串有所不同,它不仅能够保留文本数据,还能够保留二进制数据。这是因为 SDS 应用 len 属性的值而不是空字符来判断字符串是否完结,并且 SDS 的所有 API 都会以解决二进制的形式来解决 SDS 寄存在 buf[] 数组里的数据。因而,SDS 不仅能寄存文本数据,还能保留图片、音频、视频、压缩文件等二进制数据。

另外,Redis 的 SDS API 是平安的,拼接字符串不会造成缓冲区溢出。这是因为 SDS 在拼接字符串之前会查看 SDS 空间是否满足要求,如果空间不够会主动扩容,从而防止了缓冲区溢出的问题。

此外,获取字符串长度的工夫复杂度是 O(1),因为 SDS 构造里用 len 属性记录了字符串长度,所以获取长度的复杂度为 O(1)。相比之下,C 语言的字符串并不记录本身长度,所以获取长度的复杂度为 O(n)。这些个性使得 SDS 成为 Redis 的一个重要组成部分。

> set hello world
OK
> get hello
"world"
> del hello
(integer) 1
> get hello
(nil)

LIST

Redis 的 List 类型底层数据结构能够由双向链表或压缩列表实现。如果列表元素个数小于 512 个且每个元素的值都小于 64 字节,则 Redis 会应用压缩列表作为底层数据结构;否则,Redis 会应用双向链表作为底层数据结构。然而,在 Redis 3.2 版本之后,List 类型底层数据结构只由 quicklist 实现,代替了双向链表和压缩列表。

> rpush list-key item
(integer) 1
> rpush list-key item2
(integer) 2
> rpush list-key item
(integer) 3

> lrange list-key 0 -1
1) "item"
2) "item2"
3) "item"

> lindex list-key 1
"item2"

> lpop list-key
"item"

> lrange list-key 0 -1
1) "item2"
2) "item"

SET

Set 类型的底层数据结构能够是哈希表或整数汇合。当汇合中的元素都是整数并且元素个数小于 512 时,Redis 应用整数汇合作为 Set 类型的底层数据结构;否则,Redis 应用哈希表作为 Set 类型的底层数据结构。

> sadd set-key item
(integer) 1
> sadd set-key item2
(integer) 1
> sadd set-key item3
(integer) 1
> sadd set-key item
(integer) 0

> smembers set-key
1) "item"
2) "item2"
3) "item3"

> sismember set-key item4
(integer) 0
> sismember set-key item
(integer) 1

> srem set-key item2
(integer) 1
> srem set-key item2
(integer) 0

> smembers set-key
1) "item"
2) "item3"

HASH

Redis 中的 Hash 类型的底层数据结构能够是压缩列表或哈希表。如果元素个数小于 512 个且每个元素的值都小于 64 字节,Redis 会应用压缩列表作为底层数据结构;否则会应用哈希表。在 Redis 7.0 中,压缩列表曾经废除,改用 listpack 数据结构来实现。

> hset hash-key sub-key1 value1
(integer) 1
> hset hash-key sub-key2 value2
(integer) 1
> hset hash-key sub-key1 value1
(integer) 0

> hgetall hash-key
1) "sub-key1"
2) "value1"
3) "sub-key2"
4) "value2"

> hdel hash-key sub-key2
(integer) 1
> hdel hash-key sub-key2
(integer) 0

> hget hash-key sub-key1
"value1"

> hgetall hash-key
1) "sub-key1"
2) "value1"

ZSET

Zset 类型的底层数据结构能够是压缩列表或跳表。

如果有序汇合的元素个数小于 128 个,且每个元素的值小于 64 字节,则 Redis 会应用压缩列表作为 Zset 类型的底层数据结构。

如果有序汇合的元素个数大于等于 128 个或者每个元素的值大于等于 64 字节,则 Redis 会应用跳表作为 Zset 类型的底层数据结构。

须要留神的是,Redis 7.0 中废除了压缩列表数据结构,改用 listpack 数据结构来实现。

> zadd zset-key 728 member1
(integer) 1
> zadd zset-key 982 member0
(integer) 1
> zadd zset-key 982 member0
(integer) 0

> zrange zset-key 0 -1 withscores
1) "member1"
2) "728"
3) "member0"
4) "982"

> zrangebyscore zset-key 0 800 withscores
1) "member1"
2) "728"

> zrem zset-key member1
(integer) 1
> zrem zset-key member1
(integer) 0

> zrange zset-key 0 -1 withscores
1) "member0"
2) "982"

最初

为了不便其余设施和平台的小伙伴观看往期文章,链接奉上:

牛客 知乎 开源中国 CSDN 思否 掘金 InfoQ 简书 博客园 慕课 51CTOhelloworld 腾讯开发者社区 阿里开发者社区

看完如果感觉有帮忙,欢送 点赞、珍藏 关注

正文完
 0