雖然已經是陽春三月,但騎著共享單車騎了這么遠,還有有點冷的,我搓了搓的被凍的麻木的手,對著前臺的小姐姐說:“您好,我是來面試的,”小姐姐問:“您好,您叫什么名字?”我回答:“我叫萬貓學社,”小姐姐笑出了聲,說到:“這名字好怪,誰給你起的啊,”我面無表情地回答:“俺爹,”小姐姐收起了笑容,說到:“跟我來吧,”我被帶到了面試間等候,片刻后一個著干凈滿臉清秀的青年走了進來,一股男士香水的淡香撲面而來,
面試官:Redis中基本的資料型別有哪些?
我:Redis的基本資料型別有:字串(string)、哈希(hash)、串列(list)、集合(set)、有序集合(zset),
面試官:集合資料型別的內部實作方式是什么?
我還沉浸在上一個問題的沾沾自喜中,頓時表情凝固了,手心開始冒出冷汗,“這個,,沒有太深入了解”,我支支吾吾的說到,
面試官:回去等訊息吧,
這句話說的干凈利落,然后就沒有然后了,失敗是成功的媽媽,我不氣餒,決定馬上惡補一下,
型別和編碼
首先,整明白什么是型別?什么是編碼?在Redis中使用物件來表示記憶體中的鍵和值,每個物件由一個叫做redisObject結構體表示,其中有三個屬性:型別(type)、編碼(encoding)、指向具體資料的指標(ptr),
我們通常說的字串、哈希、串列、集合、有序集合都是redisObject中的型別,實際上針對每一個資料結構在Redis內部都有自己底層的多種內部編碼實作,這樣是為了在合適的場景選擇合適的內部編碼,以達到記憶體空間和處理效率的平衡,這可能就是中庸之道吧,
在面試中,經常被問到的內部實作方式、內部構造、內部原理,一般指的就是redisObject中的編碼,
集合的編碼
集合的編碼有兩種,分別是:整數集合(intset)和哈希表(hashtable),
當集合中的所有元素都是整數,并且元素的個數小于set-max-intset-entries(默認為512個)時,使用整數集合作為集合的編碼,集合的所有元素都保存在整數集合里面,比如:
127.0.0.1:6379> sadd one-more-set 1 2 3 4 5
(integer) 5
127.0.0.1:6379> smembers one-more-set
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> object encoding one-more-set
"intset"
當集合中的所有元素不都是整數,或者元素的個數大于等于set-max-intset-entries(默認為512個)時,使用哈希表作為集合的編碼,哈希表的每一個鍵都是字串物件,每一個字串包含一個集合的元素,哈希表的值全部為NULL,
比如,集合中的所有元素不是整數:
127.0.0.1:6379> sadd one-more-set one more
(integer) 2
127.0.0.1:6379> smembers one-more-set
1) "more"
2) "one"
127.0.0.1:6379> object encoding one-more-set
"hashtable"
當然,了解以上細節還沒能完全“征服”面試官,我們需要更深入一些:)
集合的編碼轉換
當一個集合是以整數集合為編碼時,再向這個集合添加非整數的元素,或向這個集合添加整數的元素使元素個數過多時,就會執行集合的編碼轉換,
把原來保存在整數集合中的所有元素轉移到哈希表中,并且把集合的編碼用整數集合修改為哈希表,不過,把非整數的元素從集合中移除,或者減少整數元素的個數,以哈希表為編碼的集合也不會轉化為整數集合,
舉個例子,我們先創建一個以整數集合為編碼的集合:
127.0.0.1:6379> sadd one-more-set 1 2 3 4 5
(integer) 5
127.0.0.1:6379> smembers one-more-set
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> object encoding one-more-set
"intset"
然后,再向它添加兩個字串元素,它就是轉換為以哈希表為編碼:
127.0.0.1:6379> sadd one-more-set one more
(integer) 2
127.0.0.16379> smembers one-more-set
1) "one"
2) "5"
3) "1"
4) "2"
5) "more"
6) "4"
7) "3"
127.0.0.1:6379> object encoding one-more-set
"hashtable"
然后,再把那兩個字串元素從集合中移除,集合的編碼依然是哈希表:
127.0.0.1:6379> srem one-more-set one more
(integer) 2
127.0.0.1:6379> smembers one-more-set
1) "5"
2) "1"
3) "2"
4) "4"
5) "3"
127.0.0.1:6379> object encoding one-more-set
"hashtable"
總結
在Redis中,集合的內部實作有整數集合(intset)和哈希表(hashtable)兩種,當集合中的所有元素都是整數并元素個數較少時,使用整數集合作為內部實作,否則使用哈希表作為內部實作,當條件不滿足時,整數集合可以轉換為哈希表,但哈希表不能轉換為整數集合,
最后,謝謝你這么帥,還給我點贊和關注,
微信公眾號:萬貓學社
微信掃描二維碼
關注后回復「電子書」
獲取12本Java必讀技術書籍
作者:萬貓學社
出處:http://www.cnblogs.com/heihaozi/
著作權宣告:本文遵循 CC 4.0 BY-NC-SA 著作權協議,轉載請附上原文出處鏈接和本宣告,
微信掃描二維碼,關注萬貓學社,回復「電子書」,免費獲取12本Java必讀技術書籍,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/441919.html
標籤:其他
