頭條終面:寫個消息中間件

每一個時代,都不會虧待會學習的人。java

你們好,我是 yes。web

這種設計類問題想必你們都不陌生,面試時或多或少都能碰到。面試

好比如何寫一個線程池?如何寫一個 HashMap ?如何寫一個 RPC 框架等等,固然這裏的寫不是真的叫你用代碼寫出來,只是說說設計理念,總體架構。算法

這個面試題來自於一個讀者的字節面試經歷,我會從面試技巧和消息中間件的設計兩個方面闡述。安全

我以爲重點在於面試技巧,由於它通用。微信

兩種極端的狀況

大多數同窗遇到這種問題會出現兩種極端的狀況:架構

  • 第一種:一臉懵逼,兩眼無神,不知從何提及,萬般思緒,都化做一聲嘆息。框架

  • 第二種:誇誇其談,像是口中架起了一把加特林,噠噠噠噠噠噠噠噠,還冒着藍火。異步

第一種不用說了,好一點的面試官可能會引導你,會問一些提示性的問題,一步一步地帶你漸入佳境,固然你要是胸中無點滴,那仍是沒救的,場面就異常地尷尬。編輯器

第二種會把面試官整蒙了,或許你真的懂不少,不少細節也都清晰,可是你不能一古腦兒的都拋出來,這會顯得你抓不住重點。

面試官也是人

這點其實很關鍵,不少把面試官當成一個莫得感情的提問機器人,以爲他無所不能能夠徹底 get 到你的點,卻不知你引覺得傲的細節回答,他可能以爲你在說蛇皮。

是人就會有感情,就須要交流,好的面試官會把控總體進度,從拉家常開始,讓場子熱起來再一步一步的深挖。

固然也有一些面試官比較弱,這時候就須要你來特地地流出一點空白,來讓面試官塗鴉,讓面試官感受你這人就很舒服,你這波就穩了。

固然即便面對着把控全場的面試官你也得主動出擊,每一個人都有本身的擅長點,你須要引導面試官來詢問你的長處。

正確的回答姿式

正確的回答姿式是 BFS(廣度優先搜索) 而不是 DFS (深度優先搜索),什麼意思呢?

就是咱們須要先從大局上講出須要設計的東西的重點,而後再等待面試官的繼續提問,深挖

咱們須要揣摩面試官的心理,從他的提問能夠看出他想要知道的重點是哪一個方向的。

好比就拿 HashMap 來講,你簡單的把獲取、寫入、衝突處理、擴容啥的都說了,而後等待面試官接下來的提問,有可能會往線程安全方面深刻,也有可能會往擴容方向再挖,好比引出 Redis 的 hash 擴容等等。

因此說給面試官留提問的機會,抓住他的喜愛或者說熟知的方向回答,這樣若是你答得好,相互之間談的來,面試官會對你高度承認。

並且在說各設計要點的時候也要注意停頓,要留機會給面試官插話,讓面試官充分參與你的設計

仍是拿 HashMap 做爲例子,好比你說了獲取、寫入、衝突以後稍做停頓,這時候大機率面試官還會問還有嗎?讓面試官有參與感,讓他感受通過他的引導這個設計才逐步地完善

固然若是不問也沒事,你停頓下繼續說就行。

讓面試成爲一場技術交流,這是面試的最高境界,相信面試完了以後雙方都會有意猶未盡的感受,惺惺相惜就是這麼來的。

可是這種場景也不是這麼容易碰到的,首先你和麪試官得有相同方向的喜愛,好比你對 JVM 有很深刻的研究,而面試官對存儲方面有很深刻的研究,JVM 懂的不深,這樣就碰不出火花了。

因此說會有不少人碰到這麼個狀況:我面這個公司一面掛,另外一家公司面面超神,這都是很正常的。

固然你要是說你全能,那當我沒說。

小結一下面試技巧

首先要正確的看待面試官,你和麪試官是同等的,不要一來就低三下四的。

其次回答問題須要抓住重點,不要一古腦兒的把你知道的都說了,要留白待面試官提問。

要把控面試的節奏,往本身熟知的方向上引。

如何寫個消息中間件

接下來我們再看看如何寫個消息中間件。

首先咱們須要明確地提出消息中間件的幾個重要角色,分別是生產者、消費者、Broker、註冊中心。

簡述下消息中間件數據流轉過程,無非就是生產者生成消息,發送至 Broker,Broker 能夠暫緩消息,而後消費者再從 Broker 獲取消息,用於消費。

而註冊中心用於服務的發現包括:Broker 的發現、生產者的發現、消費者的發現,固然還包括下線,能夠說服務的高可用離不開註冊中心。

而後開始簡述實現要點,能夠同通訊講起:各模塊的通訊能夠基於 Netty 而後自定義協議來實現,註冊中心能夠利用 zookeeper、consul、eureka、nacos 等等,也能夠像 RocketMQ 本身實現簡單的 namesrv (這一句話就都是關鍵詞)。

爲了考慮擴容和總體的性能,採用分佈式的思想,像 Kafka 同樣採起分區理念,一個 Topic 分爲多個 partition,而且爲保證數據可靠性,採起多副本存儲,即 Leader 和 follower,根據性能和數據可靠的權衡提供異步和同步的刷盤存儲。

而且利用選舉算法保證 Leader 掛了以後 follower 能夠頂上,保證消息隊列的高可用。

也一樣爲了提升消息隊列的可靠性利用本地文件系統來存儲消息,而且採用順序寫的方式來提升性能。

可根據消息隊列的特性利用內存映射、零拷貝進一步的提高性能,還可利用像 Kafka 這種批處理思想提升總體的吞吐。

至此就差很少了,該說的要點說的都差很少了,面試官內心已經想,這人好像有點東西。

以後能夠深挖的點就不少了,好比提到的 Netty,各類註冊中心就能問不少,好比各註冊中心之間的選型對比等。

你還提到了選舉算法,因此可能會問 Bully 算法、Raft 算法、ZAB 算法等等。

你還提到了分區,可能會問這個分區和 RocketMQ 的隊列有什麼不一樣啊?具體分區要怎麼實現?

而後你提到順序寫,可能會問爲何要順序寫啊?你說的內存映射和零拷貝又是什麼啊?那你知道 RocketMQ 和 Kafka 用了哪一個嗎?(這些我都分析過,能夠看 RocketMQ 和 Kafka 底層存儲之那些你不知道的事

固然還有可能問各類細節,好比消息的寫入如何存儲、消息的索引如何生成等等,來深挖看你有沒有看過消息中間件的源碼。

能夠問的還不少,這篇文章我也不可能每一個點都延伸開說,這些知識點仍是得靠你們日積月累和平日的多加思考

固然往後的文章能夠寫一寫今天提到的一些點,好比 Netty、選舉算法啊,多種註冊中心對比啊啥的。

面試官想問的是什麼

再回到這個面試題,其實面試官想問的就是大方向上的設計,包括總體的架構、數據的流轉和一些特性的把握,因此對於這個問題他想聽到的就是那些重點,而不是那些細節。

而繼續的深挖取決於你回答這個問題時提出的各個關鍵詞,對於面試官自身而言熟悉的詞一抓到,他就已經知道下一步要問你什麼了。

因此在回答面試官的時候不只要 get 到他的點,還得爲以後的回答鋪路,不會說的點不要提,擅長的點多提提。

最後

以前我已經提到了,這篇文章的重點其實不在於如何回答寫一個消息中間件,而在於面試的技巧。

由於面試題千千萬,而技巧掌握了那麼千千萬的面試題都適用。

我還想提一下關於面試的一些我的見解,我我的是面試驅動學習型選手,我學習的動力就是面試,我享受面試官問我啥我都嘴角一翹微微一笑的那種不羈。

可是我不提倡那種純粹背面試題的作法,學習是一個日積月累的過程,就像我每篇文末說的,從一點點到億點點,又像我每篇開頭都會提的,每一個時代,都不會虧待會學習的人。

個人面試驅動不只僅是說爲了面試而學習,還要以面試場景來學習,什麼意思呢?

學任何一種東西,都模擬一個面試官在你前面,讓他從各類角度向你提問,驅動你全方位的理解一個知識點,這纔是我說的面試驅動學習型選手。

因此若是你看過我以前的文章會發現我常常會提出爲何呢,而後再做答。

還有一點要注意,動手能力,這很關鍵。

Talk is cheap, show me the code。

對了,最近搞了個羣,到時候能夠搞個各大廠內推啊啥的,若是想進羣就備註下進羣,我拉你。


我是 yes,從一點點到億點點,咱們下篇見

本文分享自微信公衆號 - yes的練級攻略(yes_java)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索