Redis數(shù)據(jù)結(jié)構(gòu)面試高頻問題解析
概述
Redis 是速度非??斓姆顷P(guān)系型(NoSQL)內(nèi)存鍵值數(shù)據(jù)庫,可以存儲(chǔ)鍵和五種不同類型的值之間的映射。
鍵的類型只能為字符串,值支持五種數(shù)據(jù)類型:字符串、列表、集合、散列表、有序集合。
Redis 支持很多特性,例如將內(nèi)存中的數(shù)據(jù)持久化到硬盤中,使用復(fù)制來擴(kuò)展讀性能,使用分片來擴(kuò)展寫性能。
數(shù)據(jù)類型
數(shù)據(jù)類型 | 可以存儲(chǔ)的值 | 操作 |
---|---|---|
STRING | 字符串、整數(shù)或者浮點(diǎn)數(shù) | 對(duì)整個(gè)字符串或者字符串的其中一部分執(zhí)行操作,對(duì)整數(shù)和浮點(diǎn)數(shù)執(zhí)行自增或者自減操作 |
LIST | 列表 | 從兩端壓入或者彈出元素,對(duì)單個(gè)或者多個(gè)元素進(jìn)行修剪,只保留一個(gè)范圍內(nèi)的元素 |
SET | 無序集合 | 添加、獲取、移除單個(gè)元素,檢查一個(gè)元素是否存在于集合中,計(jì)算交集、并集、差集,從集合里面隨機(jī)獲取元素 |
HASH | 包含鍵值對(duì)的無序散列表 | 添加、獲取、移除單個(gè)鍵值對(duì),獲取所有鍵值對(duì),檢查某個(gè)鍵是否存在 |
ZSET | 有序集合 | 添加、獲取、刪除元素,根據(jù)分值范圍或者成員來獲取元素,計(jì)算一個(gè)鍵的排名 |
STRING
Redis 的 String 類型使用 SDS(簡(jiǎn)單動(dòng)態(tài)字符串)作為底層的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)。SDS 與 C 字符串有所不同,它不僅可以保存文本數(shù)據(jù),還可以保存二進(jìn)制數(shù)據(jù)。這是因?yàn)?SDS 使用 len 屬性的值而不是空字符來判斷字符串是否結(jié)束,并且 SDS 的所有 API 都會(huì)以處理二進(jìn)制的方式來處理 SDS 存放在 buf[] 數(shù)組里的數(shù)據(jù)。因此,SDS 不僅能存放文本數(shù)據(jù),還能保存圖片、音頻、視頻、壓縮文件等二進(jìn)制數(shù)據(jù)。
另外,Redis 的 SDS API 是安全的,拼接字符串不會(huì)造成緩沖區(qū)溢出。這是因?yàn)?SDS 在拼接字符串之前會(huì)檢查 SDS 空間是否滿足要求,如果空間不夠會(huì)自動(dòng)擴(kuò)容,從而避免了緩沖區(qū)溢出的問題。
此外,獲取字符串長(zhǎng)度的時(shí)間復(fù)雜度是 O(1),因?yàn)?SDS 結(jié)構(gòu)里用 len 屬性記錄了字符串長(zhǎng)度,所以獲取長(zhǎng)度的復(fù)雜度為 O(1)。相比之下,C 語言的字符串并不記錄自身長(zhǎng)度,所以獲取長(zhǎng)度的復(fù)雜度為 O(n)。這些特性使得 SDS 成為 Redis 的一個(gè)重要組成部分。
> set hello world OK > get hello "world" > del hello (integer) 1 > get hello (nil)
LIST
Redis 的 List 類型底層數(shù)據(jù)結(jié)構(gòu)可以由雙向鏈表或壓縮列表實(shí)現(xiàn)。如果列表元素個(gè)數(shù)小于 512 個(gè)且每個(gè)元素的值都小于 64 字節(jié),則 Redis 會(huì)使用壓縮列表作為底層數(shù)據(jù)結(jié)構(gòu);否則,Redis 會(huì)使用雙向鏈表作為底層數(shù)據(jù)結(jié)構(gòu)。然而,在 Redis 3.2 版本之后,List 類型底層數(shù)據(jù)結(jié)構(gòu)只由 quicklist 實(shí)現(xiàn),代替了雙向鏈表和壓縮列表。
> 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 類型的底層數(shù)據(jù)結(jié)構(gòu)可以是哈希表或整數(shù)集合。當(dāng)集合中的元素都是整數(shù)并且元素個(gè)數(shù)小于512時(shí),Redis使用整數(shù)集合作為Set類型的底層數(shù)據(jù)結(jié)構(gòu);否則,Redis使用哈希表作為Set類型的底層數(shù)據(jù)結(jié)構(gòu)。
> 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 類型的底層數(shù)據(jù)結(jié)構(gòu)可以是壓縮列表或哈希表。如果元素個(gè)數(shù)小于 512 個(gè)且每個(gè)元素的值都小于 64 字節(jié),Redis 會(huì)使用壓縮列表作為底層數(shù)據(jù)結(jié)構(gòu);否則會(huì)使用哈希表。在 Redis 7.0 中,壓縮列表已經(jīng)廢棄,改用 listpack 數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)。
> 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 類型的底層數(shù)據(jù)結(jié)構(gòu)可以是壓縮列表或跳表。
如果有序集合的元素個(gè)數(shù)小于 128 個(gè),且每個(gè)元素的值小于 64 字節(jié),則 Redis 會(huì)使用壓縮列表作為 Zset 類型的底層數(shù)據(jù)結(jié)構(gòu)。
如果有序集合的元素個(gè)數(shù)大于等于 128 個(gè)或者每個(gè)元素的值大于等于 64 字節(jié),則 Redis 會(huì)使用跳表作為 Zset 類型的底層數(shù)據(jù)結(jié)構(gòu)。
需要注意的是,Redis 7.0 中廢棄了壓縮列表數(shù)據(jù)結(jié)構(gòu),改用 listpack 數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)。
> 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"
以上就是Redis數(shù)據(jù)結(jié)構(gòu)高頻面試問題解析的詳細(xì)內(nèi)容,更多關(guān)于Redis數(shù)據(jù)結(jié)構(gòu)高頻面試的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- redis底層數(shù)據(jù)結(jié)構(gòu)之ziplist實(shí)現(xiàn)詳解
- Redis數(shù)據(jù)結(jié)構(gòu)之intset整數(shù)集合使用學(xué)習(xí)
- Redis數(shù)據(jù)結(jié)構(gòu)之跳躍表使用學(xué)習(xí)
- Redis數(shù)據(jù)結(jié)構(gòu)之listpack和quicklist使用學(xué)習(xí)
- Redis數(shù)據(jù)結(jié)構(gòu)類型示例解析
- Redis數(shù)據(jù)結(jié)構(gòu)原理淺析
- redis底層數(shù)據(jù)結(jié)構(gòu)之skiplist實(shí)現(xiàn)示例
相關(guān)文章
React?Native實(shí)現(xiàn)Toast輕提示和loading效果
這篇文章主要介紹了React Native實(shí)現(xiàn)Toast輕提示和loading效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09從零搭建react+ts組件庫(封裝antd)的詳細(xì)過程
這篇文章主要介紹了從零搭建react+ts組件庫(封裝antd),實(shí)際上,代碼開發(fā)過程中,還有很多可以輔助開發(fā)的模塊、流程,本文所搭建的整個(gè)項(xiàng)目,我都按照文章一步一步進(jìn)行了git提交,開發(fā)小伙伴可以邊閱讀文章邊對(duì)照git提交一步一步來看2022-05-05解決React報(bào)錯(cuò)React.Children.only expected to rece
這篇文章主要為大家介紹了React報(bào)錯(cuò)React.Children.only expected to receive single React element child分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01