成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Redis八股文精講:字符串

存儲 Redis
Redis底層是C語言實現的。于是不少朋友想當然的以為,Redis的字符串和C語言字符串實現方式一致。

[[431323]]

寫在前面

小牛之前出了八股文背誦版系列,不少朋友問我,能不能搞個八股文精講,把面試問題講講透,于是系列就這樣誕生了。咱們第一期先聊聊Redis。

字符串

Redis底層是C語言實現的。于是不少朋友想當然的以為,Redis的字符串和C語言字符串實現方式一致。

但事實上,Redis自己定義了一套字符串的實現,名曰SDS(simple dynamic string)。

不少同學在面試時,面試官輕描淡學來一句,來講一講Redis的SDS吧。大家一臉懵逼,半天答不上來。最后搞半天,其實面試官就是問的Redis字符串呀。

首先回答一個問題:為什么Redis不采用C語言的字符串直接做具體實現?

這當然是因為這種數據結構有固有缺陷啦。主要有如下幾個

缺點1:O(n)復雜度獲取長度

我們知道,C語言如何判斷一個字符串已經結束,當然是通過標志位'\0'。

C語言Str

所以,對于我們想獲得字符串長度,我們需要從頭開始遍歷,直至遍歷到\0,時間復雜度變成了O(n)。

缺點2:沒有較好的擴容機制

對于C語言,想要搞個字符串數組,肯定需要預先確定好字符串長度。如果這個字符串經常需要修改,修改前后長度一致還好說,如果不一致,那程序層面就需要重新申請一段新內存,并把字符一個個拷貝到新的地方。

缺點3:特殊字符無法處理

引用《Redis源碼剖析與實戰》的例子 如果我們想存儲字符串"redis\0"

  1. char *a = "redis\0"

到原始C語言,它編譯器看到\0,以為還是字符結束的標志呢,如果把它打印下來,它只打出redis。所以特別是對于二進制數據,這種奇奇怪怪的case特別多,因此C語言的字符數組就處理不了這塊存儲二進制字符的需求了。

為了解決C語言字符數組的不足,redis提出了新的方法。我們先來看看3.0及之前版本的實現。

  1. struct sdshdr { 
  2.     unsigned int len; 
  3.     unsigned int free
  4.     char buf[]; 

來解釋一下這些字段吧。

len:數組字符串已使用長度

free: 數組未使用的字符串長度

buf:存儲字符串

在之后的版本,Redis對SDS進行了改進,但大體思想不變

  1. struct sdshdr { 
  2.     unsigned int len; 
  3.     unsigned int alloc; 
  4.     unsigned char flags; 
  5.     char buf[]; 

來解釋一下這些字段吧。

len:數組字符串已使用長度

alloc: 數組分配的長度

flags: 表示SDS類型

buf:存儲字符串

對于SDS類型,我也稍微多啰嗦兩句。在新版本redis中,有4種SDS類型(sdshrd5 never used)。其中 sdshrd8 sdshrd16 sdshrd32 sdshrd64 的區別僅僅就在len和alloc上有所區別。

對于sdshrd8 該定義為

  1. struct sdshdr8 { 
  2.     uint8_t len; 
  3.     uint8_t alloc; 
  4.     unsigned char flags; 
  5.     char buf[]; 

以此類推,sdshrd16就是

  1. struct sdshdr16 { 
  2.     uint16_t len; 
  3.     uint16_t alloc; 
  4.     unsigned char flags; 
  5.     char buf[]; 

那為啥新版Redis搞這么多結構體?一個結構體不是一法通萬法就夠了嘛。

當然,事實確實如此,按實現角度看。如果只采用sdshrd64,肯定也夠了。

但按摳門角度看呢?如果我們機子很菜,內存很小,想摳摳索索能省一點,是一點,這樣做就有好處辣。

好處在哪里?當然是uint8_t、uint16_t、uint32_t、uint64_t占的空間不一樣,對于小字符串,用小頭sdshdr8,這樣len 和alloc占用字段也能省一點,就是這么回事。

所以可以看到,SDS本質上是C語言的字符數組,加上了一點別的標識屬性的結構體而已。小伙伴們下次碰見面試官問SDS,就不用慌啦!

最后多啰嗦兩句SDS擴容:

  • 對于字符串增加了,如果原始的剩余空間足夠,直接返回
  • 如果空間不足夠,重新申請兩倍最小需要長度的空間,再進行挨個賦值。

最后總結一下:Redis提出動態字符串這一數據結構,改進了C語言字符數組的不足。該動態字符串有如下好處:

  1. 字符串長度獲取時間復雜度從O(n)->O(1)
  2. 減少字符串擴容引起的數據搬運次數。
  3. 可以存儲更加復雜的二進制數據

參考

《Redis源碼剖析與實戰》

https://blog.csdn.net/weixin_39744512/article/details/111170924

https://blog.csdn.net/wolf2s/article/details/107945242 

《Redis的設計與實現》

 

責任編輯:武曉燕 來源: 后端技術小牛說
相關推薦

2021-07-26 14:59:23

面試Redis內存數據庫

2021-10-26 14:40:03

MySQL SQL 語句數據庫

2021-11-04 14:32:17

Spring 面試作用域

2021-10-21 14:43:23

Java 語言 Java 基礎

2021-09-07 14:46:42

面試網絡HTTP 協議

2023-11-28 18:09:49

Java多態

2022-09-03 11:36:11

Python文件網絡

2021-08-01 22:59:43

Object八股文quals

2021-04-14 10:02:59

網絡八股文協議

2024-02-23 19:17:12

構造函數C++開發

2021-05-20 11:43:57

操作系統硬件軟件

2021-08-12 09:28:24

Java多線程變量

2024-10-12 09:26:32

線程池系統核心線程

2021-05-06 07:27:57

面試任務調度器

2021-07-05 07:55:11

String[]byte轉換

2022-01-04 08:54:32

Redis數據庫數據類型

2023-11-29 17:28:07

2022-05-27 14:43:45

JVM字節碼指令

2022-05-19 08:41:09

JVM虛擬機架構

2023-01-13 18:04:03

面試題消息中間件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国产色综合久久不卡98 | 日韩一区二区三区av | 精彩视频一区二区三区 | 伊人激情综合网 | 91pron在线| 欧美日韩在线一区 | 国产一区二区在线免费观看 | 国产中文一区二区三区 | 99热精品国产 | 成人三级视频 | 色av一区二区三区 | 亚洲精品视频免费看 | 日韩成人免费视频 | 国产一区二区三区在线免费观看 | 国产精品美女久久久久久不卡 | 一区二区三区四区视频 | 欧美精品一区二区三区在线 | 日韩成人免费中文字幕 | 亚洲欧美精品 | 日韩成人免费在线视频 | 欧美一区二区三区视频 | 国产精品一区二区福利视频 | 亚洲精品一区二区在线观看 | 国产精品久久久久久久久婷婷 | 国产高清免费视频 | 欧美男人天堂 | 波多野结衣精品在线 | av网站观看 | 91亚洲精华国产 | 亚洲国产精品一区二区久久 | 国产精品成人品 | 久99久视频 | 久久综合久 | 国产精品一区二区免费看 | 99re热精品视频国产免费 | 三级视频在线观看 | 亚洲影音 | 亚洲午夜一区二区 | 婷婷福利 | 国产91丝袜在线熟 | 欧美8一10sex性hd |