天天看點

花了20天的時間給粉絲整理的一套“最全“的Java求職筆記(八)1為什麼寫這套Java求職筆記2Redis&RabbitMq技術知識大綱3一文徹底搞懂Redis RabbitMQ常見面試問題4結束語5個人說明

前言:前幾天有粉絲問我,網上java面試題總是參差不齊,希望我為他整理一套全面的java面試題,并且這套java面試題有個要求,必須能夠讓他20天就能看完這些面試題,他說現在很多面試題我看都得看3個月才能看完,然後我才能去找工作,但是自己得時間有限是以想讓我幫他總結一套萬能面試java求職筆記。接下來我将會至少分為12個章節進行闡述這套Java求職筆記,感興趣的可以堅持看完!覺得不錯的可以點個贊。

1為什麼寫這套Java求職筆記

很早的時候我就想寫一些Java求職方向的一些文章,由于很長時間耽擱了加上,有粉絲背景問我,可不可以幫他總結一些java求職筆記,他看了很多Java技術有很多技術,很迷茫不知道學哪些,我笑着說,不要着急,無論你到什麼時候你都會迷茫,因為技術一直在更新,謝謝你信任我,解救你的迷茫唯一辦法就是多看LRyab部落格,就是這樣我帶着粉絲的問題,開始編寫了這套Java求職筆記,看完這套求職筆記,我相信很多人都會找到屬于自己的心儀工作。

2Redis&RabbitMq技術知識大綱

花了20天的時間給粉絲整理的一套“最全“的Java求職筆記(八)1為什麼寫這套Java求職筆記2Redis&RabbitMq技術知識大綱3一文徹底搞懂Redis RabbitMQ常見面試問題4結束語5個人說明

3一文徹底搞懂Redis RabbitMQ常見面試問題

3.1Redis常見面試題

1、什麼是Redis?

Redis 是完全開源免費的, 遵守 BSD 協定, 是一個高性能的 key-value 資料庫。

Redis 與其他 key - value 緩存産品有以下三個特點:

Redis 支援資料的持久化,可以将記憶體中的資料儲存在磁盤中,重新開機的時候可以再次加載進行使用。

Redis 不僅僅支援簡單的 key-value 類型的資料, 同時還提供 list, set, zset, hash 等資料結構的存儲。

Redis 支援資料的備份, 即 master-slave 模式的資料備份。

2、Redis 的資料類型?

Redis 支援五種資料類型:string( 字元串),hash( 哈希), list( 清單), set(集合) 及 zsetsorted set:有序集合)。

我們實際項目中比較常用的是 string,hash 如果你是 Redis 中進階使用者,還需要加上下面幾種資料結構 HyperLogLog、Geo、Pub/Sub。

如果你說還玩過 Redis Module,像 BloomFilter,RedisSearch,Redis-ML,面試官的眼睛就開始發亮了。

3、使用Redis 有哪些好處?

3.1速度快, 因為資料存在記憶體中, 類似于 HashMap, HashMap 的優勢就是查找和操作的時間複雜度都是 O1)

3.2支援豐富資料類型, 支援 string, list, set, Zset, hash 等

3.3支援事務, 操作都是原子性, 所謂的原子性就是對資料的更改要麼全部執行, 要麼全部不執行

3.4豐富的特性:可用于緩存,消息,按 key 設定過期時間,過期後将會自動删

4、Redis 是單程序單線程的?

Redis 是單程序單線程的, redis 利用隊列技術将并發通路變為串行通路, 消除了傳統資料庫串行控制的開銷。

5、一個字元串類型的值能存儲最大容量是多少?

答:512M

6、Redis 的持久化機制是什麼?各自的優缺點?

Redis 提供兩種持久化機制 RDB 和 AOF 機制:

1、RDBRedis DataBase)持久化方式:是指用資料集快照的方式半持久化模式) 記錄 redis 資料庫的所有鍵值對,在某個時間點将資料寫入一個臨時檔案, 持久化結束後, 用這個臨時檔案替換上次持久化的檔案, 達到資料恢複。

優點:

1、隻有一個檔案 dump.rdb, 友善持久化。

2、容災性好, 一個檔案可以儲存到安全的磁盤。

3、性能最大化, fork 子程序來完成寫操作, 讓主程序繼續處理指令, 是以是 IO 最大化。使用單獨子程序來進行持久化,主程序不會進行任何 IO 操作,保證了 redis 的高性能) 4.相對于資料集大時, 比 AOF 的啟動效率更高。

缺點:

1、資料安全性低。RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發生故障, 會發生資料丢失。是以這種方式更适合資料要求不嚴謹的時候)

2、AOFAppend-only file)持久化方式:是指所有的指令行記錄以 redis 指令請求協定的格式完全持久化存儲)儲存為 aof 檔案。

優點:

1、資料安全, aof 持久化可以配置 appendfsync 屬性, 有 always, 每進行一次指令操作就記錄到 aof 檔案中一次。

2、通過 append 模式寫檔案, 即使中途伺服器當機, 可以通過 redis-check-aof 工具解決資料一緻性問題。

3、AOF 機制的 rewrite 模式。AOF 檔案沒被 rewrite 之前( 檔案過大時會對指令進行合并重寫), 可以删除其中的某些指令( 比如誤操作的 flushall))

缺點:

1、AOF 檔案比 RDB 檔案大, 且恢複速度慢。

2、資料集大着的時候, 比 rdb 啟動效率低。

7、為什麼 Redis 需要把所有資料放到記憶體中?

Redis 為了達到最快的讀寫速度将資料都讀到記憶體中,并通過異步的方式将資料寫入磁盤。是以 redis 具有快速和資料持久化的特征。如果不将資料放在記憶體中,

磁盤 I/O 速度為嚴重影響 redis 的性能。在記憶體越來越便宜的今天, redis 将會越來越受歡迎。如果設定了最大使用的記憶體, 則資料已有記錄數達到記憶體限值後不能繼續插入新值。

8、Redis 的同步機制了解麼?

Redis 可以使用主從同步,從從同步。第一次同步時,主節點做一次 bgsave, 并同時将後續修改操作記錄到記憶體 buffer, 待完成後将 rdb 檔案全量同步到複制節點,

複制節點接受完成後将 rdb 鏡像加載到記憶體。加載完成後, 再通知主節點将期間修改的操作記錄同步到複制節點進行重放就完成了同步過程。

9、是否使用過 Redis 叢集,叢集的原理是什麼?

Redis Sentinal 着眼于高可用, 在 master 當機時會自動将 slave 提升為master, 繼續提供服務。

Redis Cluster 着眼于擴充性, 在單個 redis 記憶體不足時, 使用 Cluster 進行分片存儲。

10、Redis 支援的Java 用戶端都有哪些?官方推薦用哪個?

Redisson、Jedis、lettuce 等等, 官方推薦使用 Redisson。

11、Jedis 與 Redisson 對比有什麼優缺點?

Jedis 是 Redis 的 Java 實作的用戶端, 其 API 提供了比較全面的 Redis 指令的支援;Redisson 實作了分布式和可擴充的 Java 資料結構,和 Jedis 相比,功能較為簡單, 不支援字元串操作, 不支援排序、事務、管道、分區等 Redis 特性。Redisson 的宗旨是促進使用者對 Redis 的關注分離,進而讓使用者能夠将精力更集中地放在處理業務邏輯上

12、怎麼了解 Redis 事務?

1) 事務是一個單獨的隔離操作: 事務中的所有指令都會序列化、按順序地執行。事務在執行的過程中, 不會被其他用戶端發送來的指令請求所打斷。

2) 事務是一個原子操作:事務中的指令要麼全部被執行, 要麼全部都不執行。

13、Redis 事務相關的指令有哪幾個?

MULTI、EXEC、DISCARD、WATCH

14、緩存穿透、緩存擊穿、緩存雪崩解決方案

緩存穿透

指查詢一個一定不存在的資料,如果從存儲層查不到資料則不寫入緩存,這将導緻這個不存在的資料每次請求都要到 DB 去查詢,可能導緻 DB 挂掉。

解決方案:

查詢傳回的資料為空,仍把這個空結果進行緩存,但過期時間會比較短

布隆過濾器:将所有可能存在的資料哈希到一個足夠大的 bitmap 中,一個一定不存在的資料會被這個 bitmap 攔截掉,進而避免了對 DB 的查詢。

緩存擊穿

對于設定了過期時間的 key,緩存在某個時間點過期的時候,恰好這時間點對這個 Key 有大量的并發請求過來,這些請求發現緩存過期一般都會從後端 DB 加載資料并回設到緩存,這個時候大并發的請求可能會瞬間把 DB 壓垮。

解決方案:

使用互斥鎖:當緩存失效時,不立即去 load db,先使用如 Redis 的 setnx 去設定一個互斥鎖,當操作成功傳回時再進行 load db 的操作并回設緩存,否則重試 get 緩存的方法。

永遠不過期:實體不過期,但邏輯過期(背景異步線程去重新整理)。

緩存雪崩

設定緩存時采用了相同的過期時間,導緻緩存在某一時刻同時失效,請求全部轉發到 DB, DB 瞬時壓力過重雪崩。與緩存擊穿的差別:雪崩是很多 key,擊穿是某一個key 緩存。

解決方案:

将緩存失效時間分散開,比如可以在原有的失效時間基礎上增加一個随機值,比如 1-5 分鐘随機,這樣每一個緩存的過期時間的重複率就會降低,就很難引發集體失效的事件。

15、 Redis 的叢集模式

(1)主從複制

當從資料庫啟動時,會向主資料庫發送sync指令,主資料庫接收到sync後開始在背景儲存快照rdb,在儲存快照期間收到的指令緩存起來,當快照完成時,主資料庫會将快照和緩存的指令一塊發送給從**。複制初始化結束。 之後,主每收到1個指令就同步發送給從。 當出現斷開重連後,2.8之後的版本會将斷線期間的指令傳給重資料庫。增量複制

主從複制是樂觀複制,當用戶端發送寫執行給主,主執行完立即将結果傳回用戶端,并異步的把指令發送給從,進而不影響性能。也可以設定至少同步給多少個從主才可寫。 無硬碟複制:如果硬碟效率低将會影響複制性能,2.8之後可以設定無硬碟複制,repl-diskless-sync yes

(2)哨兵模式

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-Hzcc1bJo-1613794914158)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3e8c3ce5-a43d-45f0-a384-90ecc42dbaff/Untitled.png)]

哨兵的作用:

1、監控redis主、從資料庫是否正常運作

2、主出現故障自動将從資料庫轉換為主資料庫。

哨兵的核心知識

1、哨兵至少需要 3 個執行個體,來保證自己的健壯性。

2、哨兵 + redis 主從的部署架構,是不保證資料零丢失的,隻能保證 redis 叢集的高可用性。

3、對于哨兵 + redis 主從這種複雜的部署架構,盡量在測試環境和生産環境,都進行充足的測試和演練。

4、配置哨兵監控一個系統時,隻需要配置其監控主資料庫即可,哨兵會自動發現所有複制該主資料庫的從資料庫。

16、記憶體淘汰機制

redis 記憶體淘汰機制有以下幾個:

noeviction: 當記憶體不足以容納新寫入資料時,新寫入操作會報錯,這個一般沒人用吧,實在是太惡心了。

allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的 key(這個是最常用的)。

allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,随機移除某個 key,這個一般沒人用吧,為啥要随機,肯定是把最近最少使用的 key 給幹掉啊。

volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的 key(這個一般不太合适)。

volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,随機移除某個 key。

volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的 key 優先移除。

17、Redis 和 Mysql 的資料不一緻怎麼辦

定時任務更新

通過定時任務,按照一定時間間隔更新緩存。

優點:不影響正常業務,在特殊場景應用廣泛。

缺點:不保證明時一緻性,且需要為每個任務寫一個排程代碼。

适用環境:适用于需要複雜資料統計的緩存更新,比如展示高速車流量,五分鐘一次的統計不會影響業務使用。

18、為什麼Redis要使用緩存?

Redis使用緩存是為了實作高性能和高并發。

Redis操作緩存就是直接操作記憶體,速度相當快,使用者下一次再通路這些資料時可以直接從緩存中擷取,以達到高性能的目的。

緩存能夠承受的請求數量是遠遠大于直接通路資料庫的,資料庫中的部分資料轉移到緩存中去,這樣使用者的一部分請求會直接到緩存而不用經過資料庫,以達到高并發的目的。

19、談談你對Redis的了解?

Redis是一種基于鍵值對的記憶體資料庫,是以讀寫速度非常快,是以 Redis 被廣泛應用于緩存方向。

提供了多種功能應用

資料緩存功能,減少對資料庫的通路壓力,比如優化網站性能和一些不經常變動的資料

消息隊列功能: Redis提供了釋出訂閱功能和阻塞隊列功能

計數器-應用儲存使用者憑證比如計算浏覽數,如果每次操作都要做資料庫的對應更新操作,那将會給資料庫的性能帶來極大的挑戰

redis的應用場景場景有:

緩存資料伺服器比如SSO單點登入

應對高速讀寫的場景比如秒殺高可用

分布式鎖比如秒殺資料一緻性

資料共享比如庫存資料

20、Redis為什麼不适應多線程?

單線程程式設計容易并且更容易維護;

Redis的性能瓶頸不在CPU上,主要在記憶體和網絡;

多線程就會存在死鎖、線程上下文切換等問題,甚至會影響性能。

Redis在6.0之後引入了多線程

21、Redis回收程序如何工作的?

一個用戶端運作了新的指令,添加了新的資料。

Redis檢查記憶體使用情況,如果大于最大記憶體的限制, 則根據設定好的政策進行回收。

一個新的指令被執行,不斷地穿越記憶體限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。

如果一個指令的結果導緻大量記憶體被使用,不用多久記憶體限制就會被這個記憶體使用量超越。

22、Redis叢集會有寫操作丢失嗎?為什麼?

Redis 并不能保證資料的強一緻性,這意味這在實際中叢集在特定的條件下可能會丢失寫操作。

23、Redis的記憶體用完了會發生什麼?

如果達到設定的上限,Redis的寫指令會傳回錯誤資訊,但是讀指令還可以正常傳回。可以将Redis當緩存來使用配置淘汰機制,當記憶體達到上限時會沖刷掉舊的内容。

24、Redis有哪些應用場景?

最簡單的就是緩存、使用者登陸和校驗碼

Redis提供的有序集合資料能構造排行榜功能,比如文章通路排行榜,月度銷售排行榜等。

Redis提供的incr指令可以用來實作計數器功能,比如視訊的播放量,文章的浏覽量等。

Redis提供的釋出/訂閱和阻塞隊列功能可以實作一個簡單的聊天室。

3.2RabbitMQ常見面試題

1、什麼是rabbitmq?

采用AMQP進階消息隊列協定的一種消息隊列技術,最大的特點就是消費并不需要確定提供方存在,實作了服務之間的高度解耦。

2、為什麼要使用rabbitmq?

(1)在分布式系統下具備異步,削峰,負載均衡等一系列進階功能;

(2)擁有持久化的機制,程序消息,隊列中的資訊也可以儲存下來。

(3)實作消費者和生産者之間的解耦。

(4)對于高并發場景下,利用消息隊列可以使得同步通路變為串行通路達到一定量的限流,利于資料庫的操作。

(5)可以使用消息隊列達到異步下單的效果,排隊中,背景進行邏輯下單。

3、使用rabbitmq的場景。

服務間異步通信、順序消費、定時任務、請求削峰

4、使用RabbitMQ有什麼好處?

(1)服務間高度解耦

(2)異步通信性能高

(3)流量削峰

5、mq的缺點

系統可用性降低

系統引入的外部依賴越多,越容易挂掉,本來你就是A系統調用BCD三個系統的接口就好了,人 ABCD四個系統好好的,沒啥問題,你偏加個MQ進來,萬一MQ挂了咋整?MQ挂了,整套系統崩潰了,你不就完了麼。

系統複雜性提高硬生生加個MQ進來,你怎麼保證消息沒有重複消費?怎麼處理消息丢失的情況?怎麼保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已。

一緻性問題

A系統處理完了直接傳回成功了,人都以為你這個請求就成功了;但是問題是,要是BCD三個系統那裡,BD兩個系統寫庫成功了,結果C系統寫庫失敗了,咋整?你這資料就不一緻了。

是以消息隊列實際是一種非常複雜的架構,你引入它有很多好處,但是也得針對它帶來的壞處做各種額外的技術方案和架構來規避掉,最好之後,你會發現,媽呀,系統複雜度提升了一個數量級,也許是複雜了10倍。但是關鍵時刻,用,還是得用的。

6、MQ的優點。

異步處理 - 相比于傳統的串行、并行方式,提高了系統吞吐量。

應用解耦 - 系統間通過消息通信,不用關心其他系統的處理。

流量削鋒 - 可以通過消息隊列長度控制請求量;可以緩解短時間内的高并發請求。

日志處理 - 解決大量日志傳輸。

消息通訊 - 消息隊列一般都内置了高效的通信機制,是以也可以用在純的消息通訊。比如實作點對點消息隊列,或者聊天室等。

7、解耦、異步、削峰是什麼?

解耦:A系統發送資料到BCD三個系統,通過接口調用發送。如果E系統也要這個資料呢?那如果C系統現在不需要了呢?A系統負責人幾乎崩潰A 系統跟其它各種亂七八糟的系統嚴重耦合,A系統産生一條比較關鍵的資料,很多系統都需要A系統将這個資料發送過來。如果使用MQ,A系統産生一條資料,發送到MQ裡面去,哪個系統需要資料自己去MQ裡面消費。如果新系統需要資料,直接從MQ裡消費即可;如果某個系統不需要這條資料了,就取消對MQ消息的消費即可。這樣下來,A系統壓根兒不需要去考慮要給誰發送資料,不需要維護這個代碼,也不需要考慮人家是否調用成功、失敗逾時等情況。

就是一個系統或者一個子產品,調用了多個系統或者子產品,互相之間的調用很複雜,維護起來很麻煩。但是其 實這個調用是不需要直接同步調用接口的,如果用MQ給它異步化解耦。

異步:A系統接收一個請求,需要在自己本地寫庫,還需要在BCD三個系統寫庫,自己本地寫庫要3ms,BCD三個系統分别寫庫要 300ms、450ms、200ms。最終請求總延時是3+300+450+200=953ms,接近1s,使用者感覺搞個什麼東西,慢死了慢死了。使用者通過浏覽器發起請求。

如果使用MQ,那麼A系統連續發送3條消息到MQ隊列中,假如耗時5ms,A系統從接受一個請求到傳回響應給使用者,總時長是3+5=8ms。

削峰:減少高峰時期對伺服器壓力。

8、你們公司生産環境用的是什麼消息中間件?

這個首先你可以說下你們公司選用的是什麼消息中間件,比如用的是RabbitMQ,然後可以初步給一些你對不同MQ中間件技術的選型分析。

舉個例子:比如說ActiveMQ是老牌的消息中間件,國内很多公司過去運用的還是非常廣泛的,功能很強大。

但是問題在于沒法确認ActiveMQ可以支撐網際網路公司的高并發、高負載以及高吞吐的複雜場景,在國内網際網路公司落地較少。而且使用較多的是一些傳統企業,用ActiveMQ做異步調用和系統解耦。

然後你可以說說RabbitMQ,他的好處在于可以支撐高并發、高吞吐、性能很高,同時有非常完善便捷的背景管理界面可以使用。

另外,他還支援叢集化、高可用部署架構、消息高可靠支援,功能較為完善。

而且經過調研,國内各大網際網路公司落地大規模RabbitMQ叢集支撐自身業務的case較多,國内各種中小型網際網路公司使用RabbitMQ的實踐也比較多。

除此之外,RabbitMQ的開源社群很活躍,較高頻率的疊代版本,來修複發現的bug以及進行各種優化,是以綜合考慮過後,公司采取了RabbitMQ。

但是RabbitMQ也有一點缺陷,就是他自身是基于erlang語言開發的,是以導緻較為難以分析裡面的源碼,也較難進行深層次的源碼定制和改造,畢竟需要較為紮實的erlang語言功底才可以。

然後可以聊聊RocketMQ,是阿裡開源的,經過阿裡的生産環境的超高并發、高吞吐的考驗,性能卓越,同時還支援分布式事務等特殊場景。

而且RocketMQ是基于Java語言開發的,适合深入閱讀源碼,有需要可以站在源碼層面解決線上生産問題,包括源碼的二次開發和改造。

另外就是Kafka。Kafka提供的消息中間件的功能明顯較少一些,相對上述幾款MQ中間件要少很多。

但是Kafka的優勢在于專為超高吞吐量的實時日志采集、實時資料同步、實時資料計算等場景來設計。

是以Kafka在大資料領域中配合實時計算技術(比如Spark Streaming、Storm、Flink)使用的較多。但是在傳統的MQ中間件使用場景中較少采用。

9、RabbitMQ的工作模式

simple模式(即最簡單的收發模式)

work工作模式(資源的競争)

publish/subscribe釋出訂閱(共享資源)

routing路由模式

10、RabbitMQ叢集架構模式

主備模式

遠端模式

鏡像模式

多活模式

4結束語

2019年7月開始勵志打造最強java面試體系、項目實戰體系、java技術體系建立屬于自己的知識棧。目前java電商項目實戰、項目技術指導體系、工作技術應用場景體系、職業目标規劃定位體系、就業面試體系基本更新完畢。2021年勵志完成知識付費項目實戰體系開發。完善更強大的技術知識體系,打造LRyab部落格最強java技術知識棧。

5個人說明

我是LRyab部落格,專注電商項目實戰開發,擅長網站搭建與技術問題指導,經驗是由一點一點積累的,思維也是由一天一天訓練出來的。謝謝大家的閱讀,原創不易,如果你認為文章對你有所幫助,就點個贊感謝大家支援,你的點贊是我持續寫作的動力!