今天週末,我在家坐着掐指一算,立刻又要到一年一度的金九銀十招聘季了,國內今年上半年受到 YQ 衝擊,金三銀四泡湯了,這就直接致使不少今年畢業的同窗會和明年畢業的同窗一塊兒參加今年下半年的秋招,這個競爭就比較激烈了。java
最近後臺有一些朋友給我留言,但願我能寫寫招聘相關的內容,畢竟雖說是金九銀十,可是不少大公司的校招從 7 、 8 月份就開始了。git
原本是想寫點面試技巧和簡歷技巧的,但我轉念一想,你們都是搞技術的,問題的核心仍是技術能力要過關,面試技巧這東西最多隻能用做錦上添花,而技術能力過不去,機會送到手裏都抓不住。github
再說簡歷這件事兒,說實話,這個不是短期內能進行彌補的,以前我也有文章分享過我是怎麼挑簡歷的,無外乎先看學校,再參考下實習公司,項目經驗這一欄就看心情了。面試
尤爲是校招,學校放在第一位,在金礦裏淘金子確定要比在沙堆上淘金子效率高得多,固然,若有能有大廠的實習經驗,也會成爲簡歷上的一個亮點,能去大廠實習,無論最後什麼緣由沒有留下,自己已經能夠說明不少問題了。redis
MD ,老說實話,實話這麼講下去得罪的人有點多啊。docker
固然哈,若是這兩樣都沒有出彩的地方,就只能在項目經驗上下點功夫了,在 Github 上多找找能拿來練手的項目,多動動手,動起來總比成天怨天尤人要來的強。shell
第一份工做能夠找的很差,至少先混口飯吃,在工做中再接着學習,夯實本身的基礎,作個兩三年工做仍是能夠換的嘛。數據庫
扯遠了,強行扯回來,我思來想去仍是用 Redis 開頭,就是由於這玩意使用頻率以及使用場景太多了,無論什麼語言,作什麼方向,最終都能和 Redis 扯上關係(emmm,扯不上的我也能強行扯上)。緩存
先簡單介紹下我認爲的本地最簡安裝方案,這個方案順便還實現了跨平臺(一開始我並無想到這個,直到我寫到這才突然想起來)。安全
Docker + Redis
,Docker 在各個平臺都有本身的安裝包,請各位同窗去官網自行下載安裝,我就很少介紹了, Windows 環境下官網提供了現成的 exe
程序,直接雙擊一路 next
到底就完。
Docker
安裝成功後,無論在哪一個平臺都是打開命令行模式,或者找個輸入命令的地方,Windows 平臺下可使用 CMD
、 PowerShell
或者 Windows Terminal
等工具,其餘常見平臺包括 MacOS 、 CentOS 或者 Ubuntu ,就不用我多說了吧,若是本身找不到的話,我估摸着我也找不到。
而後用下面三個命令安裝 Redis :
# 下載最新版本 Redis 鏡像
docker pull redis
# 查看當前鏡像
docker images
# 啓動命令
docker run --name redis -p 6380:6379 -d redis:latest --requirepass "02wKdSs7NvWT5TdlRyN4dxkXvIDnI1uroh5t"
# 查看運行容器
docker ps
# 進入容器
docker exec -it 013a252b24d6 redis-cli
複製代碼
稍微解釋下容器的啓動命令 --name
是對這個啓動的容器進行命名, -p
是指定映射的端口, -d
是指後臺運行容器,並返回容器的 ID , --requirepass
是指定了當前啓動的 Redis 的訪問密碼。
而後一個 Redis 就啓動好了,咱們進入容器執行幾條命令看下是否正常:
# 使用剛纔設置的密碼登陸
127.0.0.1:6379> auth 02wKdSs7NvWT5TdlRyN4dxkXvIDnI1uroh5t
OK
# 寫入一個 key-value
127.0.0.1:6379> set name geekdigging
OK
# 查詢 key
127.0.0.1:6379> get name
"geekdigging"
# 查詢全部 key
127.0.0.1:6379> keys *
1) "name"
# 刪除 key
127.0.0.1:6379> del name
(integer) 1
# 查詢全部 key
127.0.0.1:6379> keys *
(empty array)
# 退出
127.0.0.1:6379> quit
複製代碼
Redis 入門結束,看完這一段,在簡歷上寫個 Redis 達到了解級別我以爲木有任何問題。
既然是從面試出發,那麼接下來的內容將會以面試題爲導向進行解答,面試題來源於網絡或者我本身的杜撰。
如今基本上只要問到緩存,第一個問題基本上都是哪裏用了緩存?爲啥要用?不用行不行?用了之後會不會有什麼風險?
就是單純的看你背後對緩存有沒有思考,仍是說只是單純的傻乎乎的用。若是沒辦法給一個還能夠的回答,那這個映像分一下就降下來了。
首先哈,咱們在項目中使用 Redis 確定是爲了更高的性能和更好的併發。由於傳統的關係型數據庫已經沒法知足如今全部的使用場景了,最多見的秒殺場景,或者查詢時的流量洪峯等等,都很容易把傳統的 MySQL 或者是 Oracle 打崩,因此引入了緩存中間件 Redis 。
高性能:
假設一個場景,一個請求過來,開始查詢數據庫,亂七八糟一頓 SQL 操做,查了個結果,結果耗時可能有個 500ms 左右,就好比商城的首頁,各類類目的商品信息,各類推薦信息,若是走數據庫查詢,而且查完了可能接下來好幾個小時都沒什麼變化,那每次請求都走到數據庫裏,就有點不大合適了。
這時,咱們把查到的結果放到扔到緩存裏面,下次再來查詢,不走數據庫,直接走緩存查詢,算上網絡消耗可能 10ms 左右就能響應結果了,性能瞬間提高 50 倍。
這就是說,對於一些須要複雜操做耗時查出來的結果,且肯定後面不怎麼變化,可是有不少讀請求,那麼直接將查詢出來的結果放在緩存中,後面直接讀緩存就行了。
高併發:
MySQL 或者 Oracle 這種關係型數據庫壓根就不是用來玩併發的,雖然也能夠支撐必定的併發,單機 8C16G 的 MySQL 優化基本上極限能撐到 900 左右的 TPS , QPS 極限能撐到 9000 左右。別看這個數字不小,請注意是極限狀況,這個狀況下 CPU 全都已經爆表,整個服務已經處於不健康的狀態。
這時業務場景若是 1s 有 1w 的請求過來,使用一個 MySQL 單機確定直接崩掉,可是若是使用 Redis 緩存,把大量的熱點數據放在緩存,由於是走內存的操做,單機輕鬆支撐幾萬甚至於幾十萬的訪問。單機的併發承載量是 MySQL 的幾十倍。
這個問題其實是在問知識廣度,由於如今市面上比較常見的緩存有兩個,一個是 Redis 還有一個是 Memcached ,而你們如今基本上都在用 Redis 而逐漸的拋棄掉了 Memcached ,這麼作確定是由緣由的,說明 Memcached 是存在明顯的短板的。
這兩個問題我放在一塊兒,其實是一個遞進的關係。
首先明確第一點, Redis 是單線程的模型。
而單線程卻能擁有很好的性能以及支撐高併發則得益於它自身的另外一套機制「 I/O 多路複用機制」。
Redis 內部使用文件事件處理器( file event handler
) 是單線程的,因此 Redis 才叫作單線程的模型。
它採用 IO 多路複用機制同時監聽多個 socket ,將產生事件的 socket 壓入內存隊列中,事件分派器根據 socket 上的事件類型來選擇對應的事件處理器進行處理。
儘管多個文件事件操做可能會併發的出現,但 I/O 多路複用系統老是會將全部產生的套接字( Socket ) 放到一個隊列裏面,而後經過這個隊列,以有序、同步、每次一個套接字的方式向文件分派器傳送套接字。只有當上一個套接字產生的事件被處理完畢以後, I/O 多路複用系統纔會繼續向文件分派器傳送下一個套接字。
同時,單線程的模型反而帶來了另外一個好處是無需頻繁的切換上下文,預防了多線程可能產生的競爭問題。
注意: Redis 6.0 以後的版本拋棄了單線程模型這一設計,本來使用單線程運行的 Redis 也開始選擇性地使用多線程模型。
前面還在強調 Redis 單線程模型的高效性,如今爲何又要引入多線程?這其實說明 Redis 在有些方面,單線程已經不具備優點了。由於讀寫網絡的 Read/Write 系統調用在 Redis 執行期間佔用了大部分 CPU 時間,若是把網絡讀寫作成多線程的方式對性能會有很大提高。
Redis 的多線程部分只是用來處理網絡數據的讀寫和協議解析,執行命令仍然是單線程。 之因此這麼設計是不想 Redis 由於多線程而變得複雜,須要去控制 key、lua、事務、LPUSH/LPOP 等等的併發問題。
首先最基礎的五種數據結構必須爛熟於心:String 、 Hash 、 List 、 Set 、 SortedSet 。
若是連這五種基礎數據結構都記不住的話那就真的須要本身多補補課了。
那麼,是否是隻有這五種基礎數據結構,答案並非,好比在 2.8.9 版本添加的 HyperLogLog ,或者在 3.2 版本提供的 GEO ,又或者在 2.2 版本後新增的 Bitmap 以及在比較近的 5.0 版本新增的 Stream 。
上面這幾種種數據結構都不復雜,你們百度下看看文章就能和麪試官吹牛皮了。
能答出來後面這幾種數據類型,基本上面試官都會對你刮目相看,若是還能接着說出來使用場景以及具體應用,那麼這道題基本上你的發揮已經超出了面試官的預期。
這時你還能夠接着聊下去,好比你還用過一些 Redis 的第三方模塊,這個是 Redis 在 4.0 版本之後提供了插件功能,好比很是經常使用的一個插件布隆過濾器「 BloomFilter 」。
布隆過濾器主要是用來去重使用的,在空間上能夠節省 90% 以上,可是稍微有點不精確,有必定的誤判機率。能夠簡單的把布隆過濾器理解成一個不怎麼精確的 set 結構,當使用它的 contains 方案判斷某個對象是否存在時,它可能會誤判。可是布隆過濾器也不是特別不精確,只要參數設置的合理,它的精確度也能夠控制的相對足夠精確,只會有小小的誤判機率。
除了 「BloomFilter」 ,還有一些比較經常使用的,如: 「RedisSearch」 和 「rediSQL」 。
「RedisSearch」 是一個強大全文檢索插件而 「rediSQL」 則是一個使得 Redis 能使用 SQL 作查詢的插件。
Redis 數據持久化有兩種方式: RDB 和 AOF 。
append-only
的模式寫入一個日誌文件中,在 Redis 重啓的時候,能夠經過回放 AOF 日誌中的寫入指令來從新構建整個數據集。經過 RDB 或者 AOF ,均可以將 Redis 內存中的數據持久化到硬盤上面,若是有須要,還能夠將硬盤上的數據備份到其餘地方去。
若是 Redis 掛了,這時止不只 Redis 服務掛掉,內存數據丟失,同時產生硬件損壞,硬盤上的數據也丟失或者復發恢復,咱們還能夠從其餘地方將數據拷貝回來進行數據恢復。
RDB 的優缺點:
save
,另外一個是 bgsave
。 save
命令會阻塞當前的 Redis 進程,直到 RDB 文件建立完畢,在這期間,服務器不能處理任何命令請求。而 bgsave
則會派生出一個子進程,而後由子進程生成 RDB 文件,服務進程不受干擾,繼續處理命令請求。AOF 的優缺點:
append-only
模式寫入,因此沒有任何磁盤尋址的開銷,寫入性能很是高,並且文件不容易破損,即便文件尾部破損,也很容易修復。rewrite log
的時候,會對其中的指令進行壓縮,建立出一份須要恢復數據的最小日誌出來。在建立新日誌文件的時候,老的日誌文件仍是照常寫入。當新的 merge
後的日誌文件 ready
的時候,再交換新老日誌文件便可。兩種持久化方式選擇: