当前位置: 首页 > 后端技术 > Java

面试官:Redis中集合数据类型的内部实现是怎样的?

时间:2023-04-01 18:16:04 Java

虽然阳春已经是三月了,但是骑了这么远的共享单车还是有点冷。我揉了揉麻木的手,对前台小姐姐说:“您好,我是来面试的。””女士问:“你好,请问贵姓?我回答:我叫万茂学院。少女哈哈一笑,道:“这名字好古怪,谁给你起的。”我面无表情地回答:“我父亲。”小姐收起笑容,道:“跟我来吧。”我被带到面试室等候,不一会儿,一个年轻男子走了进来,面容干净俊朗,身上散发着淡淡的男士香水味。打我脸面试官:Redis的基本数据类型有哪些?我:Redis的基本数据类型有:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)面试官:collection数据类型的内部实现是什么?我还沉浸在上一题的得意中,表情顿时一僵,手心开始冒冷汗。“这……我不‘深入了解一下’,我吞吞吐吐地说。采访者:回去等消息吧。这句话干干净净,然后就没有了。失败是成功之母,我没有气馁,并决定马上补上。类型和编码首先,什么是类型?什么是编码?对象在Redis中用来表示内存中的键和值。每个对象都由一个名为redisObject的结构体表示,它具有三个属性:类型(type)、编码(encoding)和指向特定数据的指针(ptr)。我们通常说的字符串、哈希、列表、集合、有序集合都是redisObject中的类型。实际上,对于每一种数据结构,Redis都有自己底层的多种内部编码实现。为场景选择合适的内部编码,以达到内存空间和处理效率的平衡。这可能是中庸之道。面试中经常被问到的内部实现、内部结构、内部原理,一般都是指redisObject中的编码。集合的编码集合的编码有两种,分别是:整数集合(intset)和哈希表(hashtable)。当集合中所有元素都是整数且元素个数小于set-max-intset-entries(默认为512)时,使用整数集合作为集合的编码,集合的所有元素存储在整数集合中。例如:127.0.0.1:6379>saddone-more-set12345(integer)5127.0.0.1:6379>smembersone-more-set1)"1"2)"2"3)"3"4)"4"5)"5"127.0.0.1:6379>objectencodingone-more-set"intset"当集合中所有元素都不是整数,或者元素个数大于等于set-max-intset-entries(默认为512),使用哈希表作为集合的编码,哈希表的每个键都是一个字符串对象,每个字符串包含一个集合的元素,哈希表的值都是空的。例如,集合中的所有元素都不是整数:127.0.0.1:6379>saddone-more-setonemore(integer)2127.0.0.1:6379>smembersone-more-set1)"more"2)"one"127.0。0.1:6379>objectencodingone-more-set"hashtable"当然,理解了上面的细节还没有完全“征服”面试官,还需要更深入:)Setencodingconversion当一个集合被一组整数编码时,然后向这个集合中加入非整数元素,或者向这个集合中加入整数元素使得元素个数过多,会进行集合的编码转换。将原先存放在整数集合中的所有元素转移到哈希表中,并将集合的编码从整数集合修改到哈希表中。但是,从集合中去除非整数元素,或者减少整数元素的个数,哈希表编码后的集合不会转换为整数集合。例如,让我们首先创建一个用整数集编码的集合:127.0.0.1:6379>saddone-more-set12345(integer)5127.0.0.1:6379>smembersone-more-set1)"1"2)"2"3)"3"4)"4"5)"5"127.0.0.1:6379>objectencodingone-more-set"intset"然后,再给它加上两个字符串元素,转换为哈希表编码:127.0.0.1:6379>saddone-more-setonemore(integer)2127.0.0.16379>smembersone-more-set1)"one"2)"5"3)"1"4)"2"5)"more"6)"4"7)"3"127.0.0.1:6379>objectencodingone-more-set"hashtable"然后,把那两个字符串元素从集合中去掉,集合的编码还是哈希表:127.0.0.1:6379>sremone-more-setonemore(integer)2127.0.0.1:6379>smembersone-more-set1)"5"2)"1"3)"2"4)"4"5)"3"127.0.0.1:6379>objectencodingone-more-set"hashtable"总结在Redis中,集合的内部实现包括整数集(intset)和哈希表(hashtable)两种类型.当集合中所有元素都是整数且元素个数较少时,使用整数集合作为内部实现,否则使用哈希表作为内部实现。当条件不满足时,可以将整数集转化为哈希表,但哈希表不能转化为整数集。这点我早就看出来了,你我一定是有缘,留下你的喜欢和关注,你日后必成大器。