一葉障目,不見Offer
Redis 在當今後端技術的世界有著舉足輕重的地位。幾乎所有的後端技術面試官都會圍繞 Redis 的原理和使用對面試者進行全方位、無死角的盤問。來自Redis的盤問或許會遲到,但它絕不會缺席。看著一個個自信的小眼神被面試官折磨的黯淡無光,老衲實屬不忍。在一個月黑風高的夜晚,終於下定決心,收集整理Redis面試資料,著《面試心經》系列,望能普渡眾生。
一個穿著邋里邋遢的禿頂中年人抱著一個滿是劃痕的Mac向你走來。看你著那稀疏的頭髮,心想我艹,這至少也是個高階架構師了吧。但是看過《面試心經》的我們,依然可以氣定神閒、穩如泰山
小夥子你好,看你簡歷上寫了專案中有使用Redis,為什麼要使用 Redis ?
這時的你心裡忍不住暗罵,頭都禿成這樣了,問的問題如此平常,就這?但是你不能表現出來。
認真回答道:帥氣又迷人的面試官你好。當時是因為專案使用的人越來越多,只使用傳統的關係型資料庫(如:MySQL)已不能滿足專案的需求。出於對專案的效能和並行方面考慮,需要在專案中引入快取中介軟體。當時綜合比較了常用的快取中介軟體 Redis 和 Memcache 的優缺點之後,最終決定選擇使用Redis
這裡很可能會問你 Redis 和 Memcache 都有哪些區別,和他們各自的優缺點。感興趣的少俠可以去查閱資料瞭解下,後續我也會出文章詳細介紹對比
那你說說 Redis 都有哪些資料型別 ?
一氣呵成的回答道:redis 支援多種型別的資料結構,常用的有5種 ,分別是 strings,hashes, lists, sets,sorted sets
這五種資料結構一定要做到倒背如流、一氣呵成。知道每種資料結構的使用場景和底層實現原理更好
但是,如果你想要突出自己,還需要加上下面幾種資料結構: bitmaps, hyperloglogs, geospatial indexes ,streams
回答到這裡,基本就達到讓面試官睜眼的水平了
小夥子,那你知道 Redis String 的底層實現方式嗎 ?
這時你心想:我只是來面試個月薪 1K 的 CV 攻城獅啊,為什麼要我經歷這些。呸,真不要臉!但你依然不能表露出來,不能讓面試官的奸計得逞
略做思考,答:字串物件底層資料結構實現為 簡單動態字串(SDS) 和 直接儲存。(注:SDS是一個redis 定義的結構體)
這裡只要能夠說出 SDS,基本就可以了,如果還能夠詳細介紹 SDS 結構的內部構造更佳
Redis的持久化了解麼?請簡單介紹一下
風輕雲淡道:Redis持久化有兩種, RDB 和 AOF
RDB做全量持久化(Redis預設的持久化方式)。按照一定的時間週期策略把記憶體的資料以快照的形式儲存到硬碟的二進位制檔案。對應產生的資料檔案為dump.rdb,通過組態檔中的save引數來定義快照的週期。( 快照可以是其所表示的資料的一個副本,也可以是資料的一個複製品。)
AOF做增量持久化:Redis會將每一個收到的寫命令都通過Write函數追加到檔案最後,類似於MySQL的binlog。必要時,可以通過重新執行檔案中儲存的寫命令來在記憶體中重建整個redis資料庫。
Redis本身的機制是:當AOF持久化開啟且存在AOF檔案時,優先載入AOF檔案。當AOF持久化關閉或不存在AOF檔案時,載入RDB檔案。載入AOF/RDB檔案成功之後,Redis啟動成功。如果AOF/RDB檔案存在錯誤,則Redis啟動失敗並列印錯誤資訊
瞭解 Pipeline 嗎?請簡單介紹一下
可以將多條命令一起打包傳送至redis處理,處理完成後,將處理結果按照順序打包,一起返回。好處是可以減少I/O次數,提升redis吞吐量。不過有兩點需要注意:一個 pipeline 中的命令互相之間不能有因果關係。另外,一個 pipeline 中的命令不宜過多,不然資料量過大,增加使用者端的等待時間,還可能造成網路阻塞。可以將大量命令的拆分多個小的pipeline命令完成。
那你使用過 Redis 分散式鎖嗎?怎麼實現
先使用 setnx 爭搶鎖,搶到之後使用 expire 給鎖加一個過期時間,防止忘記釋放鎖
那如果在執行 setnx 之後,執行 expire 之前程序意外 crash 或者要重新啟動維護了,會怎麼樣?
故作驚訝的回答:如果這樣的話,這個鎖就永遠得不到釋放了!此時你可以作思考狀(思考時間別太長,可能會讓面試官誤以為你不知道怎麼處理,建議3s 左右為宜),說道: set 命令後面可以跟引數,實現加鎖和設定過期時間兩個操作,保證操作原子性。(命令:SET key value EX second NX )
面試官微微一笑,嗯,還行
使用過 redis 做非同步佇列麼?講解一下實現方式
一般使用 list 結構做佇列, lpush 生產訊息, rpop 消費訊息,當 rpop 沒有訊息的時候,適當的 sleep 一會兒再重試
面試官再問,可不可以不用 sleep 呢?
可以,使用 list 結構中的阻塞指令,如 brpop 。在列表沒有元素時,會阻塞列表直到等待超時或發現可彈出元素為止。
再再追問,如果我想生產一次,消費多次呢?
可以使用 pub/sub 釋出訂閱模式 ,實現 1:N的訊息佇列
再再再追問,pub /sub 模式有什麼缺點?
在消費者下線的情況下,生產的訊息會丟失。可以使用專業的訊息佇列保證訊息不丟失,如 rocketMQ、rabbitMQ 等
再再再再追問,Redis如何實現延時佇列?
這個時候你可能會有想叫二營長把義大利炮拉上來的衝動。但是為了面試順利,還是得強壓內心的衝動,保持微笑
緩緩答道:使用 sortedset,用時間戳作為 score,訊息內容作為 key,生產者呼叫 zadd 生產訊息,消費者用 zrangebyscore 指令獲取N秒之前的訊息,輪詢進行處理
Redis事務瞭解嗎,如果事務中有某條/某些命令執行失敗了會怎麼樣呢?
事務中的某條命令執行失敗了,事務中的其他指令依然會繼續執行。另外,Redis 事務不支援 roolback
假如Redis裡面有1億個key,其中有10w個key是以某個固定的已知的字首開頭的,如何將它們全部找出來?
使用 keys 指令可以掃出指定模式的key列表。
如果這個redis正在給線上的業務提供服務,那使用keys指令會有什麼問題?
這個時候你要回答redis關鍵的一個特性:redis是單執行緒的。 roolback keys指令會導致執行緒阻塞一段時間,線上服務會停頓,直到指令執行完畢,服務才能恢復。這個時候可以使用 scan 指令, scan 指令可以無阻塞的提取出指定模式的 key 列表,但是 key 可能會有一定的重複,在使用者端做一次去重就可以了。 scan 整體所花費的時間會比用 keys 指令長。
MySQL裡有2000w資料,redis中只能存20w的資料,如何保證redis中的資料都是熱點資料?
當用戶端往 Redis 新增了新的資料後。Redis 會檢查記憶體使用情況,如果大於 maxmemory 的限制, 則根據設定好的淘汰策略對舊資料進行回收。
使用過Redis叢集嗎,叢集的高可用怎麼保證,叢集的原理是什麼?
Redis Sentinal(哨兵)著眼於高可用,在master宕機時會自動將slave提升為master,繼續提供服務。
Redis Cluster(叢集)著眼於擴充套件性,在單個redis記憶體不足時,使用Cluster進行分片儲存。
說說 Redis 叢集的資料分片
Redis 叢集沒有使用一致性hash, 而是引入了 雜湊槽的概念。Redis 叢集有16384個雜湊槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,叢集的每個節點負責一部分hash槽。
小夥子挺不錯啊,什麼時候有時間來上班呢?要不就明天吧。
你強裝鎮定:這麼急啊,我還要租房。要不下週一吧
面試官心想,這麼NB,可不能讓他跑了,馬上叫 HR 給他加錢
不知你會不會有那樣一種感覺,很多事情看起來很簡單,覺得自己也能做,只是懶得去做而已;很多知識點看起來自己都知道,但當面試官問的時候,你卻不能邏輯清晰且完整的做出回答,事後還覺得:這些自己都會,只是發揮不好而已…
我以前也是這樣。但我現在才明白,其實不是懶,只是不想承認自己是個廢物而已。多做、多思考、多總結吧!朋友
Stay hungry, stay foolish
努力提升自己技術的看度和廣度,是通過面試的必要條件
平時多思考、多總結,才能在面試時侃侃而談
另外保持自信和從容,會讓你看起來更加靠譜,提升面試通過率
本文是根據平時面試的經歷,總結完善而成。由於篇幅原因,有一些回答或許不夠完美,我會在之後的文章中將面試時的常考點更加細緻的剖析。
最後,祝大家早日上岸。咱們的口號是: 必拿下!!!
你的 點贊 和 關注 對我非常有用