面試官:Redis中基本的資料型別有哪些?
我:Redis的基本資料型別有:字串(string)、雜湊(hash)、列表(list)、集合(set)、有序集合(zset)。
面試官:雜湊資料型別的內部實現方式是什麼?
我還沉浸在上一個問題的沾沾自喜中,頓時表情凝固了,手心開始冒出冷汗。“這個。。沒有太深入瞭解”,我支支吾吾的說到。
面試官:回去等訊息吧。
這句話說的乾淨利落,然後就沒有然後了。失敗是成功的媽媽,我不氣餒,決定馬上惡補一下。
雜湊的編碼
雜湊的編碼有兩種,分別是壓縮列表(ziplist)和雜湊表(hashtable)。當所有鍵值對的鍵和值的長度都小於hash-max-ziplist-value
(預設為64位元組),並且鍵值對的數量小於hash-max-ziplist-entries
(預設為512個)的時候,雜湊就會使用壓縮列表作為編碼,否則使用雜湊表作為編碼。
我們來舉個例子:
127.0.0.1:6379> hset one-more-hash name "萬貓學社"
(integer) 1
127.0.0.1:6379> hset one-more-hash gender "男"
(integer) 1
127.0.0.1:6379> object encoding one-more-hash
"ziplist"
此時,所有鍵值對的鍵和值的長度和鍵值對的數量都比較小,雜湊使用壓縮列表作為編碼。我們再加入一個值比較大的鍵值對:
127.0.0.1:6379> hset one-more-hash introduce "Java領域優質創作者、CSDN部落格專家認證"
(integer) 1
127.0.0.1:6379> object encoding one-more-hash
"hashtable"
此時,雜湊的編碼由壓縮列表轉化為編碼。
當然,瞭解以上細節還沒能完全“征服”面試官,我們需要更深入一些:)
雜湊的底層實現
當壓縮列表作為雜湊的編碼時,有新的鍵值對加入到雜湊資料型別中,先把鍵的壓縮列表節點新增到壓縮列表的末尾,然後再把值的壓縮列表節點新增到壓縮列表的末尾。
所以,在雜湊資料型別的壓縮列表中,先加入的鍵值對在壓縮列表的頭部方向,後加入的鍵值對在壓縮列表的末尾方向;同一個鍵值對的兩個節點是緊挨在一起的,鍵的節點在前,值的節點在後。
壓縮列表使用更加緊湊的記憶體結構實現多個鍵值對的連續儲存,在節省記憶體方面比雜湊表表現的更加優秀。
當雜湊表作為雜湊的編碼時,每個鍵值對都使用一個字典鍵值對儲存,字典的每個鍵都是一個字串物件,物件中儲存鍵值對的鍵;字典的每個值也都是一個字串物件,物件中儲存鍵值對的值。
雜湊表雖然沒有壓縮列表節省記憶體,但是它的讀寫時間複雜度為O(1),在時間效率方面比壓縮列表表現的更加優秀。
總結
雜湊資料型別的內部實現有壓縮列表(ziplist)和雜湊表(hashtable)兩種。當雜湊資料型別的鍵和值的長度較小並且鍵值對數量較少時,使用壓縮列表作為內部實現,否則使用雜湊表作為內部實現。
最後,謝謝你這麼帥,還給我點贊和關注。
微信公眾號:萬貓學社
微信掃描二維碼
關注後回覆「電子書」
獲取12本Java必讀技術書籍