国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

阿里面試這樣問:Redis 為什么把簡單的字符串設計成 SDS?

存儲 存儲軟件 Redis
redis也支持使用C語言的傳統字符串,只不過會用在一些不需要對字符串修改的地方,比如靜態的字符輸出。

本文轉載自微信公眾號「程序員內點事」,作者程序員內點事。轉載本文請聯系程序員內點事公眾號。

2021開工第一天,就有小伙伴私信我,還給我分享了一道他面阿里的redis題(這家伙絕比已經拿到年終獎了),我看了以后覺得挺有意思,題目很簡單,是那種典型的似懂非懂,常常容易被大家忽略的問題。這里整理出來分享一下,順便自己鞏固一下基礎,希望對正在面試和想要面試的兄弟有點幫助。

題目大致是這樣的

面試官:了解redis的String數據結構底層實現嘛?

鐵子:當然知道,是基于SDS實現的

面試官:redis是用C語言開發的,那為啥不直接用C的字符串,還單獨設計SDS這樣的結構呢?

鐵子:·····

 

“其實看得出面試官是想看看,鐵子是只停留在redis的使用層面,還是對底層數據結構有過更深入的研究,面試嘛都愛這樣問大家都懂得。我們知道redis是用C寫的,但它卻沒有完全直接使用C的字符串,而是自己又重新構建了一個叫簡單動態字符串SDS(simple dynamic string)的抽象類型。

redis也支持使用C語言的傳統字符串,只不過會用在一些不需要對字符串修改的地方,比如靜態的字符輸出。

而我們開發中使用redis,往往會經常性的修改字符串的值,這個時候就會用SDS來表示字符串的值了。有一點值得注意:在redis數據庫中,key-value鍵值對含有字符串值的,都是由SDS來實現的。

比如:在redis執行一個最簡單的set命令,這時redis會新建一個鍵值對。

  1. 127.0.0.1:6379> set xiaofu "程序員內點事" 

此時鍵值對的key和value都是一個字符串對象,而對象的底層實現分別是兩個保存著字符串xiaofu和程序員內點事的SDS結構。

再比如:我向一個列表中壓入數據,redis 又會新建一個鍵值對。

  1. 127.0.0.1:6379> lpush xiaofu "程序員內點事" "程序員小富" 

這時候鍵值對的鍵和上邊一樣,還是一個由SDS實現的字符串對象,鍵值對的值是一個包含兩個字符串對象的列表對象了,而這兩個對象的底層也是由SDS實現。

SDS結構

一個SDS值的數據結構,主要由len、free、buf[]這三個屬性組成。

  1. struct sdshdr{ 
  2.  
  3.   int free; // buf[]數組未使用字節的數量 
  4.  
  5.   int len; // buf[]數組所保存的字符串的長度 
  6.  
  7.   char buf[]; // 保存字符串的數組 

其中buf[]為實際保存字符串的char類型數組;free表示buf[]數組未使用字節的數量;len表示buf[]數組所保存的字符串的長度。

 

例如上圖表示的是buf[]保存長度為6個字節的字符串,未使用的字節數free為0,但是眼尖的同學會發現這明明是7個字符,還有一個"\0"啊?

上邊提到過SDS沒有完全直接使用C的字符串,還是沿用了一些C特性的,比如遵循C的字符串以空格符結尾的規則,這樣還可以使用一部分C字符串的函數。而對于SDS來說,空字符串占用的一字節是不計算在len屬性里的,會為他分配額外的空間。

簡單了解SDS結構后,下邊我們來看看SDS相比于C字符串有哪些優點。

效率高

舉個例子:工作中使用redis,經常會通過STRLEN命令得到一個字符串的長度,在SDS結構中len屬性記錄了字符串的長度,所以我們獲取一個字符串長度直接取len的值,復雜度是O(1)。

 

而如果用C字符串,在獲取一個字符串長度時,需對整個字符串進行遍歷,直至遍歷到空格符結束(C中遇到空格符代表一個完整字符串),此時的復雜度是O(N)。

在高并發場景下頻繁遍歷字符串,獲取字符串的長度很有可能成為redis的性能瓶頸,所以SDS性能更好一些。

數據溢出

上邊提到C字符串是不記錄自身長度的,相鄰的兩個字符串存儲的方式可能如下圖,為字符串分配了合適的內存空間。

 

如果此時我想把“程序員內點事”改成“程序員內點事123”,可之前分配的內存只有6個字節,修改后的字符串需要9個字節才能放下啊,怎么搞?

 

沒辦法只能侵占相鄰字符串的空間,自身數據溢出導致其他字符串的內容被修改。

而SDS很好的規避了這點,當我們需要修改數據時,首先會檢查當前SDS空間len是否滿足,不滿足則自動擴容空間至修改所需的大小,然后再執行修改,如下圖所示。

 

不過有個特殊的地方,在把“程序員內點事”的6個字節擴容到“程序員內點事123”9個字節后,發現free屬性的值變成了擴容后字符串的總長度,這就涉及到下邊要說的內存重分配策略了。

內存重分配策略

C字符串長度是一定的,所以每次在增長或者縮短字符串時,都要做內存的重分配,而內存重分配算法通常又是一個比較耗時的操作,如果程序不經常修改字符串還是可以接受的。

但很不幸,redis作為一個數據庫,數據肯定會被頻繁修改,如果每次修改都要執行一次內存重分配,那么就會嚴重影響性能。

SDS通過兩種內存重分配策略,很好的解決了字符串在增長和縮短時的內存分配問題。

1.空間預分配

空間預分配策略用于優化SDS字符串增長操作,當修改字符串并需對SDS的空間進行擴展時,不僅會為SDS分配修改所必要的空間,還會為SDS分配額外的未使用空間free,下次再修改就先檢查未使用空間free是否滿足,滿足則不用在擴展空間。

通過空間預分配策略,redis可以有效的減少字符串連續增長操作,所產生的內存重分配次數。

 

額外分配未使用空間free的規則:

  • 如果對 SDS 字符串修改后,len 值小于 1M,那么此時額外分配未使用空間 free 的大小與len相等。
  • 如果對 SDS 字符串修改后,len 值大于等于 1M,那么此時額外分配未使用空間 free 的大小為1M。

2.惰性空間釋放

惰性空間釋放策略則用于優化SDS字符串縮短操作,當縮短SDS字符串后,并不會立即執行內存重分配來回收多余的空間,而是用free屬性將這些空間記錄下來,如果后續有增長操作,則可直接使用。

 

數據格式多樣性

C字符串中的字符必須符合某些特定的編碼格式,而且上邊我們也提到,C字符串以\0空字符結尾標識一個字符串結束,所以字符串里邊是不能包含\0的,不然就會被誤認是多個。

由于這種限制,使得C字符串只能保存文本數據,像音視頻、圖片等二進制格式的數據是無法存儲的。

redis 會以處理二進制的方式操作Buf數組中的數據,所以對存入其中的數據未做任何的限制、過濾,只要存進來什么樣,取出來還是什么樣。

總結

上邊只是 redis 數據結構的一點基礎知識,沒什么難度,但以我的面試經驗,如果被問這類問題,不要只含糊其辭的說出底層是SDS,有理有據的把為什么這樣實現也說出來。

 

一來可以顯得自己基本功扎實,如果表達的在條理清晰,是個很不錯的加分項;在一個主動打消面試官問下去的念頭,當然就怕不按套路出牌的人!

 

責任編輯:武曉燕 來源: 程序員內點事
相關推薦

2021-04-27 10:53:58

Redis數據庫SDS

2021-02-23 09:35:33

redis字符串數據庫

2019-03-07 15:43:22

Redis數據SDS

2021-02-07 21:16:04

字節跳動面試字符串

2025-12-05 09:33:40

2020-05-13 12:17:33

RedisC字符C語言

2024-02-20 20:12:09

C語言字符串Redis

2020-07-23 16:00:38

Redis字符串Java

2024-05-27 08:04:41

2023-03-21 15:27:00

RedisC語言字符串

2024-05-27 08:01:15

2023-01-03 08:07:33

Go字符串指針

2023-09-21 10:50:23

MySQL數據庫

2015-03-19 15:04:06

2023-05-29 08:03:41

代碼Go語言

2025-06-16 08:10:00

2019-02-27 09:00:13

阿里巴巴for循環Java

2019-01-29 10:30:32

阿里巴巴Java字符串

2018-05-02 08:40:36

存儲密碼字符

2021-02-02 18:03:00

字符串面試官子序列
點贊
收藏

51CTO技術棧公眾號

成人国产精品免费观看| 亚洲成人av中文字幕| xxxx视频在线| 992tv成人免费影院| www.精品| 99精品99久久久久久宅男| 国产精品毛片大码女人| 日韩福利一区| 在线免费一区| 欧美高清dvd| 国产一区日韩欧美| 日韩欧美国产片| 久久琪琪电影院| 国产精品久久久久久亚洲伦| 成人国产精品av| 国产精品久久二区| 亚洲男男gay视频| 国产人成精品一区二区三| 国产ts一区二区| 琪琪一区二区三区| 最新97超碰在线| 亚洲天堂2020| 国产一区二区三区四区| 国产偷亚洲偷欧美偷精品| 天天碰免费视频| 国产精品亚洲专一区二区三区 | 一区二区三区|亚洲午夜| 国产丶欧美丶日本不卡视频| 性综艺节目av在线播放| 色综合久久中文字幕综合网| 亚洲一区二区三区四区| 蜜桃成人在线| 亚洲午夜国产成人| 欧美国产综合视频| 亚洲自拍偷拍图区| 电影网一区二区| 色乱码一区二区三区熟女| 99久久婷婷国产| 亚洲一区二区三区香蕉| 日本午夜精品一区二区三区电影| 午夜爽爽爽男女免费观看影院| 国产精品二区影院| 久久久久久久久久久久久久一区 | 久久麻豆一区二区| 免费国产在线观看| 久久99国产精品自在自在app| 欧美69xxxxx| 国产精品美女黄网| 国产精品主播直播| 日韩一二三区在线观看| 97免费视频在线| 永久亚洲成a人片777777| 精品欧美日韩在线| 国产在线精品一区二区夜色 | 亚洲精品影片| 国产欧美在线观看| 国产精品入口| 人妻夜夜添夜夜无码av| 成人免费在线播放视频| www.av在线播放| 亚洲天堂男人天堂女人天堂| 国产在线播放精品| av色综合网| 国产98色在线|日韩| 热久久精品国产| 欧美三级午夜理伦三级中视频| 中文字幕资源网在线观看免费| 欧美一区二区三区艳史| 在线欧美一区| 成人免费视频91| 一本一道波多野结衣一区二区| 日韩免费福利视频| 91色p视频在线| 成人av在线播放网站| 欧美高清电影在线| 美女av一区二区三区| 亚洲国产免费看| 999sesese| 精品亚洲男同gayvideo网站| 成人在线国产| 国产传媒久久久| 欧美三级在线播放| 久久电影在线| 这里精品视频免费| 国内精品福利| av磁力番号网| 一区二区三区中文字幕电影| 怡红院在线播放| 羞羞色国产精品| 老妇喷水一区二区三区| 日韩毛片在线免费看| 欧美日韩国产精选| 国内精品麻豆美女在线播放视频| 秋霞久久久久久一区二区| 亚洲免费观看在线观看| aa国产成人| 国产欧美一区二区三区久久| 美腿丝袜一区二区三区| 五月伊人六月| www.久久色.com| 亚洲激情专区| 在线观看免费国产小视频| 久久精品91久久香蕉加勒比| 国产一区二区三区久久| 国产对白在线正在播放| 久久亚洲一区二区三区四区五区高| 日本va欧美va精品发布| 国产精品一二三区视频| 欧美在线性爱视频 | 一本色道久久88亚洲综合88| 亚洲国产国产亚洲一二三| av免费播放| 久久九九亚洲综合| 国产精品66部| 999福利在线视频| 免费看污久久久| 在线观看精品一区| 国产精品久久观看| 中文字幕理伦片免费看| 欧美一区二粉嫩精品国产一线天| jvid福利写真一区二区三区| 久久一卡二卡| 奇米888一区二区三区| 色综合久久综合网97色综合| 红桃成人av在线播放| 国产一区二区在线免费播放| 久久精品视频导航| 成人av在线影院| 国产精品亚洲d| 男人天堂av片| 日韩视频在线观看免费| 99久久婷婷国产综合精品 | 日韩午夜激情视频| 亚洲欧美大片| 亚洲欧美成人影院| 日韩av在线电影观看| 精品久久久久久久人人人人传媒| 久久亚洲美女| 日韩精品美女| 97超碰青青草| 久久免费在线观看| 亚洲免费资源在线播放| 国产日韩视频在线| 在线色视频网| 国产精品亚洲不卡a| 日韩一区二区三区免费看| 狂野欧美性猛交xxxx巴西| 99久久精品免费看国产小宝寻花| 特级毛片在线免费观看| 国产一区二区日韩精品欧美精品| 丁香啪啪综合成人亚洲小说| 国产精品日本一区二区三区在线| 成人久久久久久久久| 3344国产精品免费看| 亚洲国产日韩在线一区模特| 欧美色图首页| 激情网站在线| 日韩精品视频在线观看视频| 欧美精品videossex88| 亚洲一区二区三区四区五区中文 | 蜜臀久久99精品久久久久久9 | 欧美综合精品| 天天av综合网| 日韩.欧美.亚洲| 中文字幕少妇一区二区三区| 亚洲欧洲另类国产综合| 亚洲va在线| 538在线精品| 999精品视频在线| 亚洲a级在线观看| 日韩精品免费在线视频观看| 欧美极品少妇xxxxⅹ高跟鞋| 欧美精品国产一区二区| 性欧美18xxxhd| 黄色毛片av| 天堂社区 天堂综合网 天堂资源最新版| 中文字幕亚洲国产| 午夜精品久久久久久久99樱桃| 日本在线不卡一区| 免费日韩一区二区三区| 黄色片网站在线观看| 日韩视频第二页| 国产在线精品一区二区三区| 精品国产一区av| 精品久久久中文| 国产精品一区免费在线观看| 久久人体视频| 日韩三区免费| 青青草免费在线| 女性女同性aⅴ免费观女性恋| 7777精品伊久久久大香线蕉语言| 亚洲香蕉成人av网站在线观看| 亚洲永久免费av| 国产九色精品成人porny| 精品一二三区| 粉嫩一区二区| 91在线高清| 国产字幕中文| 久久久久免费看黄a片app| 国产精品区一区二区三在线播放|