偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Redis面試都卷到C語(yǔ)言去了......

數(shù)據(jù)庫(kù) Redis
不同于 C 中的字符串,SDS 可以存儲(chǔ)二進(jìn)制數(shù)據(jù),因?yàn)?SDS 不再通過(guò) \0 去判斷字符串結(jié)束,因?yàn)橛幸粋€(gè) len 變量存儲(chǔ)了字符串的長(zhǎng)度。

Redis 面試都卷到 C 去了。有個(gè)小伙伴在前兩天找松哥模面的時(shí)候如是說(shuō)到。

是啊,沒(méi)辦法,自從 Java 八股文這個(gè)概念被提出來(lái)并且逐步在 Java 程序員中強(qiáng)化之后,現(xiàn)在各種各樣的八股文手冊(cè),有免費(fèi)的有付費(fèi)的,琳瑯滿目。

單純的八股文已經(jīng)區(qū)分不出 Java 猿水平的高低了,所以現(xiàn)在面試總會(huì)卷出新高度。

這次是小伙伴面試時(shí)候被問(wèn)到一個(gè) SDS 的問(wèn)題,也就是 Redis 中 String 字符串的底層實(shí)現(xiàn)原理。

我來(lái)和小伙伴們簡(jiǎn)單聊一聊這個(gè)話題。

一 String 類(lèi)型

Redis 中有一個(gè) String 類(lèi)型,使用頻率還比較高,我們?nèi)粘W鼍彺?、分布式鎖都會(huì)用到。

很多小伙伴也都知道 Redis 是用 C 寫(xiě)的,那么就有一個(gè)問(wèn)題,Redis 中的 String,底層數(shù)據(jù)結(jié)構(gòu)是什么樣的?

是不是就是 C 中的 String 呢?

二 C 中的 String

玩過(guò) C 的小伙伴應(yīng)該知道,C 語(yǔ)言本身并沒(méi)有內(nèi)置的 String 類(lèi)型,但是 C 語(yǔ)言中可以使用字符數(shù)組(char array[])或指向字符的指針(char *pointer)來(lái)表示字符串。在 C 語(yǔ)言中,字符串是以空字符 '\0' 結(jié)尾的字符序列。例如:

char *str1 = "Hello, World!";

在這個(gè)例子中,str1 是一個(gè)指向字符串字面量 "Hello, World!" 的指針。

當(dāng)我們?cè)?Redis 中使用 String 的時(shí)候,很多小伙伴可能會(huì)想這個(gè) String 可能就是 C 中的 String 吧?并不是!

為什么不直接使用 C 中的 String 呢?主要有以下幾種考慮:

  1. char* 這種方式無(wú)法直接獲取到字符串的長(zhǎng)度,只能逐個(gè)字符去遍歷,很明顯效率低。
  2. C 中的字符串使用 \0 去表示字符串結(jié)束,這就導(dǎo)致我們沒(méi)法在字符串中存儲(chǔ)二進(jìn)制數(shù)據(jù),因?yàn)槎M(jìn)制中的數(shù)據(jù)可能會(huì)和 \0 沖突。
  3. C 中字符串在創(chuàng)建的時(shí)候長(zhǎng)度和內(nèi)存大小就都確定下來(lái)了,后期如果縮容和擴(kuò)容都是創(chuàng)建新數(shù)組然后拷貝內(nèi)容,操作方式過(guò)于麻煩。

有鑒于此,Redis 自己搞了個(gè) SDS,全稱(chēng)是 Simple Dynamic String。這個(gè) SDS 和 C 中的字符串的關(guān)系,有點(diǎn)像我們 Java 中 List 和數(shù)組的關(guān)系,有點(diǎn)。

三 SDS

為了解決上述問(wèn)題,小伙伴們可以先想想,我們都需要哪些東西呢?

  • 首先得有一個(gè)存儲(chǔ)字符的 char 數(shù)組吧。
  • 數(shù)組的總長(zhǎng)度得有一個(gè)變量記錄下來(lái)吧。
  • 數(shù)組已經(jīng)使用的長(zhǎng)度得記錄下來(lái)吧。

這是三個(gè)最基本的屬性。

3.1 SDS 類(lèi)型

當(dāng)然在具體實(shí)踐中還有一個(gè) flags 屬性,這個(gè)屬性用來(lái)表示 SDS 的類(lèi)型,因?yàn)?Redis 設(shè)計(jì)了幾種不同的 SDS 類(lèi)型,這樣的設(shè)計(jì)主要是為了節(jié)省內(nèi)存。

圖片圖片

從這里可以看到,一共有五種不同的 SDS 類(lèi)型,分別是:

  1. sdshdr5
  2. sdshdr8
  3. sdshdr16
  4. sdshdr32
  5. sdshdr64

從注釋中可以看到,sdshdr5 其實(shí)沒(méi)有使用,另外四個(gè)的區(qū)別主要在于數(shù)組長(zhǎng)度和分配空間長(zhǎng)度的差異。

以 sdshdr16 為例,uint16_t 表示 16 位無(wú)符號(hào) int 值,能表示的最大值是 2^16-1,所以它的 buf 數(shù)組的最大長(zhǎng)度就是 2^16。

按照這樣的設(shè)計(jì),其實(shí) Redis 的字符串能夠存儲(chǔ)超大的字符串,例如,sdshdr32 類(lèi)型意味著能夠存儲(chǔ)的字符長(zhǎng)度是 2^32,一個(gè)字符占一個(gè)字節(jié),就是 4GB。

可是實(shí)際上 Redis 的字符串存不了這么長(zhǎng)的,Redis 內(nèi)部會(huì)對(duì)字符串的長(zhǎng)度進(jìn)行限制,最大是 512MB。

當(dāng)然實(shí)際生產(chǎn)中我們不建議這么搞,一般字符串最好不要超過(guò) 1MB。

3.2 編碼格式

為了提升效率,SDS 中使用的編碼格式也會(huì)根據(jù)情況來(lái)定。

  • 如果是數(shù)字類(lèi)型,且數(shù)字長(zhǎng)度小于 20,就會(huì)使用 int 編碼。

圖片圖片

  • 長(zhǎng)度小于等于 44 字節(jié)的字符串,使用 embstr 編碼。
  • 長(zhǎng)度大于 44 字節(jié)的字符串使用 raw 編碼。

圖片圖片

3.3 其他特點(diǎn)

不同于 C 中的字符串,SDS 可以存儲(chǔ)二進(jìn)制數(shù)據(jù),因?yàn)?SDS 不再通過(guò) \0 去判斷字符串結(jié)束,因?yàn)橛幸粋€(gè) len 變量存儲(chǔ)了字符串的長(zhǎng)度。

同時(shí),SDS 在字符串?dāng)U容的時(shí)候也會(huì)進(jìn)行預(yù)分配,這些機(jī)制類(lèi)似于咱們 Java 中 ArrayList 擴(kuò)容、HashMap 擴(kuò)容,擴(kuò)容時(shí)會(huì)預(yù)留空間,避免頻繁擴(kuò)容。

同時(shí),縮容的時(shí)候并不會(huì)立馬釋放多余空間,防止后續(xù)又要擴(kuò)容。

責(zé)任編輯:武曉燕 來(lái)源: 江南一點(diǎn)雨
相關(guān)推薦

2019-12-09 10:00:46

Python語(yǔ)言Java

2023-11-10 17:04:33

2020-03-27 16:27:03

Redis數(shù)據(jù)庫(kù)

2021-07-26 14:59:23

面試Redis內(nèi)存數(shù)據(jù)庫(kù)

2010-01-21 16:08:26

C++語(yǔ)言

2019-07-03 14:47:43

程序員祼辭就業(yè)

2010-03-10 09:07:16

數(shù)據(jù)中心

2023-03-06 08:27:33

Redis數(shù)據(jù)類(lèi)型

2017-11-08 11:13:14

大數(shù)據(jù)Spark數(shù)據(jù)傾斜

2023-01-04 11:04:32

2023-09-06 07:58:45

數(shù)據(jù)緩存Redis

2020-08-03 15:20:56

Redis數(shù)據(jù)庫(kù)命令

2023-09-25 09:27:31

編程語(yǔ)言可視化

2013-05-09 10:24:28

企業(yè)軟件軟件開(kāi)發(fā)

2020-04-23 08:45:46

編程語(yǔ)言二進(jìn)制

2023-01-01 14:22:17

2009-08-27 16:03:31

從c#到c++

2019-12-06 10:59:21

編程語(yǔ)言C語(yǔ)言開(kāi) 發(fā)

2016-11-24 23:32:32

技術(shù)面試團(tuán)隊(duì)協(xié)作解決問(wèn)題

2021-11-12 10:05:19

跳表BAT面試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)