《吊打面試官》系列-Redis常見面試題(帶答案)
你知道的越多,你不知道的越多
點贊再看,養成習慣
GitHub上已經開源github.com/JavaFamily,有一線大廠面試點腦圖,歡迎Star和完善
前言
Redis在網際網路技術儲存方面使用如此廣泛,幾乎所有的後端技術面試官都要在Redis的使用和原理方面對小夥伴們進行360°的刁難。
作為一個在網際網路公司面一次拿一次Offer的麵霸,打敗了無數競爭對手,每次都只能看到無數落寞的身影失望的離開,略感愧疚(請允許我使用一下誇張的修辭手法)。
於是在一個寂寞難耐的夜晚,我痛定思痛,決定開始寫《吊打面試官》系列,希望能幫助各位讀者以後面試勢如破竹,對面試官進行360°的反擊,吊打問你的面試官,讓一同面試的同僚瞠目結舌,瘋狂收割大廠Offer!
絮叨
上一期因為是在雙十一一直在熬夜的大環境下完成的,所以我自己覺得質量明顯沒之前的好,我這不一睡好就加班加點準備補償大家,來點乾貨。(熬夜太容易感冒了,這次點個贊別白嫖了!)
順帶提一嘴,我把我準備寫啥畫了一個思維導圖,以後總不能每篇都放個賊大的圖吧,就開源到了我的GitHub,大家有興趣可以去完善和Star。
這篇我就先放出來大家看看,感覺還是差點意思,等大家完善了。
回望過去
上一期吊打系列我們提到了Redis相關的一些知識,還沒看的小夥伴可以回顧一下
- 《吊打面試官》系列-Redis基礎
- 《吊打面試官》系列-快取雪崩、擊穿、穿透
- 《吊打面試官》系列-Redis哨兵、持久化、主從、手撕LRU
- 《吊打面試官》系列-Redis終章-凜冬將至、FPX-新王登基
這期我就從快取到一些常見的問題講一下,有一些我是之前提到過的,不過可能大部分仔是第一次看,我就重複發一下。
快取知識點
快取有哪些型別?
快取是高併發場景下提高熱點資料訪問效能的一個有效手段,在開發專案時會經常使用到。
快取的型別分為:本地快取、分散式快取和多級快取。
本地快取:
本地快取就是在程式的記憶體中進行快取,比如我們的 JVM 堆中,可以用 LRUMap 來實現,也可以使用 Ehcache 這樣的工具來實現。
本地快取是記憶體訪問,沒有遠端互動開銷,效能最好,但是受限於單機容量,一般快取較小且無法擴充套件。
分散式快取:
分散式快取可以很好得解決這個問題。
分散式快取一般都具有良好的水平擴充套件能力,對較大資料量的場景也能應付自如。缺點就是需要進行遠端請求,效能不如本地快取。
多級快取:
為了平衡這種情況,實際業務中一般採用多級快取,本地快取只儲存訪問頻率最高的部分熱點資料,其他的熱點資料放在分散式快取中。
在目前的一線大廠中,這也是最常用的快取方案,單考單一的快取方案往往難以撐住很多高併發的場景。
淘汰策略
不管是本地快取還是分散式快取,為了保證較高效能,都是使用記憶體來儲存資料,由於成本和記憶體限制,當儲存的資料超過快取容量時,需要對快取的資料進行剔除。
一般的剔除策略有 FIFO 淘汰最早資料、LRU 剔除最近最少使用、和 LFU 剔除最近使用頻率最低的資料幾種策略。
noeviction:返回錯誤當記憶體限制達到並且客戶端嘗試執行會讓更多記憶體被使用的命令(大部分的寫入指令,但DEL和幾個例外)
allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新新增的資料有空間存放。
volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新新增的資料有空間存放。
allkeys-random: 回收隨機的鍵使得新新增的資料有空間存放。
volatile-random: 回收隨機的鍵使得新新增的資料有空間存放,但僅限於在過期集合的鍵。
-
volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新新增的資料有空間存放。
如果沒有鍵滿足回收的前提條件的話,策略volatile-lru,volatile-random以及volatile-ttl就和noeviction 差不多了。
其實在大家熟悉的LinkedHashMap中也實現了Lru演演算法的,實現如下:
當容量超過100時,開始執行LRU策略:將最近最少未使用的 TimeoutInfoHolder 物件 evict 掉。
真實面試中會讓你寫LUR演演算法,你可別搞原始的那個,那真TM多,寫不完的,你要麼懟上面這個,要麼懟下面這個,找一個資料結構實現下Java版本的LRU還是比較容易的,知道啥原理就好了。
Memcache
注意後面會把 Memcache 簡稱為 MC。
先來看看 MC 的特點:
- MC 處理請求時使用多執行緒非同步 IO 的方式,可以合理利用 CPU 多核的優勢,效能非常優秀;
- MC 功能簡單,使用記憶體儲存資料;
- MC 的記憶體結構以及鈣化問題我就不細說了,大家可以檢視官網瞭解下;
- MC 對快取的資料可以設定失效期,過期後的資料會被清除;
- 失效的策略採用延遲失效,就是當再次使用資料時檢查是否失效;
- 當容量存滿時,會對快取中的資料進行剔除,剔除時除了會對過期 key 進行清理,還會按 LRU 策略對資料進行剔除。
另外,使用 MC 有一些限制,這些限制在現在的網際網路場景下很致命,成為大家選擇Redis、MongoDB的重要原因:
- key 不能超過 250 個位元組;
- value 不能超過 1M 位元組;
- key 的最大失效時間是 30 天;
- 只支援 K-V 結構,不提供持久化和主從同步功能。
Redis
先簡單說一下 Redis 的特點,方便和 MC 比較。
- 與 MC 不同的是,Redis 採用單執行緒模式處理請求。這樣做的原因有 2 個:一個是因為採用了非阻塞的非同步事件處理機制;另一個是快取資料都是記憶體操作 IO 時間不會太長,單執行緒可以避免執行緒上下文切換產生的代價。
- Redis 支援持久化,所以 Redis 不僅僅可以用作快取,也可以用作 NoSQL 資料庫。
- 相比 MC,Redis 還有一個非常大的優勢,就是除了 K-V 之外,還支援多種資料格式,例如 list、set、sorted set、hash 等。
- Redis 提供主從同步機制,以及 Cluster 叢集部署能力,能夠提供高可用服務。
詳解 Redis
Redis 的知識點結構如下圖所示。