天天看点

redis 数据结构与对象 面试题

1、redis有哪几种类型对象

string(字符串)list(列表)hash(哈希)set(集合)zset(有序集合)

2、redis对象的底层结构

unsigned type对象类型,unsigned encoding 编码方式,void* ptr指向底层数据结构的指针

3、对象的编码方式有哪些

long类型的整数、embstr编码的简单动态字符串、简单动态字符串(raw)、字典、双端队列、压缩链表、整数集合、跳跃表和字典

注:每种对象至少有两种编码类型,且在数据少量的情况下会使用优化的数据结构(效率高且灵活)

4、embstr与raw的不同

embstr是保存字符串长度小于32字节的字符串编码方式。

raw编码长的字符串(>=32字节)

ematr函数创建对象分配1次内存,而raw分配两次。

embatr编码的字符串,sdshdr和redisObject是连续的,raw是分开的所以raw分配两次内存。

5、什么情况下列表对象、hash对象使用压缩列表编码

对象字符串元素长度小于64字节、元素个数小于512个

6、集合对象使用intset编码的条件

元素是整数,数量不超过512

7、什么情况下有序集合使用压缩列表编码

元素数量小于128,元素长度小于64字节

8、特定的命令只能通过特定的键执行,那么redis是如何检查命令类型是否匹配的?

通过检查redisObject的类型属性。

9、介绍下redis的内存回收机制

redis内存回收是通过引用计数机制,每个对象内部都含有一个属性记录被引用次数,创建新对象是计数值初始化为1,当次数为0时,对象所占内存会被释放。

10、对象共享机制

数据库的键的值指针指向现有对象,被共享对象引用计数值加一

( redis初始化服务器时,会初始化1万个字符串,包含了从0到9999所有整数值。)

11、sds的底层结构

记录了长度,空闲空间,字符串

12为什么使用SDS而不是c++字符串?

1、常数阶复杂度获取字符串长度(设置和更新sds的长度由sds的api在执行时自动完成)

2、杜绝缓冲区溢出(C语言字符串在拼接时可能会导致缓冲区溢出。sds会检查空间大小,自动扩容)

3、减少修改字符串时带来的内存重分配次数(通过未使用的空间,sds实现了空间预分配和惰性空间释放两种优化策略)(空间预分配。修改sds时,未使用空间分配公式:1、sds长度小于1MB时,len与free相等。2、sds的长度大于1MB,free等于1MB)(惰性空间释放,用于优化sds的字符串的缩短。当sds的字符串缩短时,程序并不立即回收多余字节,而是使用free记录这些字节。)

4、二进制安全(sds的API都会以处理二进制的方式来处理buf数组,程序不会对其中的数据做任何限制、过滤、或者假设,数据写入和读取都是一样的。C字符串不能储存音视频,因为以’\0’区分字符串末尾。)

5、兼容部分c字符串函数。