2019 秋招提前批蘑菇街一面面經(帶答案)

今天給大家分享一下我的秋招提前批面試經歷,目前三面技術面已過,hr 面也面過了,正在等消息。由於內容太多,先分享一面的面經。

自我介紹一下吧

面試官您好,我是 xxx 大學軟件工程的一名大三學生,從大一開始學習前端,產生了對編程的興趣,大二開始接觸 Java,大二下學期學了 ssm,springboot 等框架,也做了一些項目。後來發現基礎很重要,於是從大三開始一直到現在,一直在對基礎進行學習。比如:JVM,併發,操作系統,網絡等。

看你的項目是分佈式系統,那你的上游系統調用你的系統時可能會出現超時的問題,怎麼處理

在我們的系統的話,一般有監控平臺,請求超時會拋出異常,會觸發企業微信郵件告警,開發人員知道以後去看一下對應的日誌中的異常信息。查到具體是調用哪個接口出現的問題,這個接口裏是否調用外部系統,定位問題是外部的還是內部的問題。

那如果你看到的日誌就是很多請求,你認爲這種是什麼問題,在外部系統沒有問題的情況下核心線程池被打滿了

我覺得可能是有人新改了一個功能並上線,不小心寫了死循環導致的 CPU 飄高。

PS:review code 的重要性

您說的線程池爆滿的原因是可能一個接口中存在耗時的操作,導致請求這個接口的請求一直佔用線程池,線程池被打滿,從而導致後續來的其他接口的請求也會被影響。

這種情況一般可以服務降級、限流來處理。

在外部流量沒有暴增的情況下,如果你的服務每隔半個小時會出現服務不可用的情況,這種怎麼排查

它這個是突然每隔半個小時還是其他情況?

就是這一天 11 點出現了,以後每隔半小時就會有兩分不可用,qps 都保持正常值

我猜這種情況一般出現在,定時任務同步一些數據到其他系統,由於網絡的問題,那邊服務慢的話就會導致一個超時,然後就會發生這個問題。

正常接受請求,也沒有任務跑,你會往哪個方面想

那它會不會受到部署機器其他服務的影響呢。

沒有

想了幾分鐘…..,這個目前還想不到其他的。

我可以給你個提示,往內存方面想

昂,立馬 get 到點,是可能存在內存泄露嗎?是不是由於存在內存泄露導致 full gc,gc 太頻繁導致的。

對,那這種問題怎麼排查解決

如果內存溢出的話,一般可能會有 OOM 拋出,JVM 可以設置參數在出現 OOM 時 dump 下內存的鏡像,然後你可以利用一些分析工具,分析這個 dump 文件,有的工具直接可以給你一些優化建議,或者你可以找到哪個類的內存使用情況,找到內存泄露的點,去看代碼。一般是 NIO 引起的,因爲 Java 8 開啓方法區使用的是元空間,不是永久代了。元空間是本地內存,不是堆內存,不受 JVM 管理,由操作系統管理,所以使用不當可能會出現內存泄露的問題。

好,那下一個問題,你那邊用的是 dubbo 把

是借鑑 dubbo 開發的一個 rpc 框架吧

正常 Java 用的是 dubbo,之前是 php,爲了 php 和 java 微服務之間的跨語言調用,實現了一個跨語言的 rpc,現在已經全部轉爲 Java 了,都用 dubbo 調用。而且微服務架構方面又做了改進,使用了 Service Mesh,面向雲原生。

dubbo 服務的啓動、註冊流程,說一下

首先,有個服務的提供者啓動起來後,會先向服務註冊中心註冊服務,如果是 zk 的話,它就是在某個 dubbo 的目錄下注冊上下,其他消費者想調用的話,就從 zk 上把對應的提供者的 ip 地址啥的拉下來緩存起來。然後就可以調用了。

那提供服務的提供者 ip 更改了,消費者是如何動態感知服務提供者的改變呢

一般分佈式註冊服務可以動態感知。如果是 zk 的話,服務提供者在 zk 上註冊服務時創建的是臨時節點,如果服務 ip 更改了或者服務掛了,服務的調用者通過 zk 的 watch 機制可以監聽到服務提供者目錄下的節點增加、刪除、修改事件。

你用到了很多隊列,kafka、rabbitmq 瞭解嗎

我現在這邊用的是 nsq 和 kafka,kafka 一般是大數據那邊離線處理一些東西,nsq 一般是告警信息,兩個系統之間進行解耦,進行信息交互時,發消息到 nsq。區別的話,kafka 對大數據處理能力比較好,nsq 的話一般作爲一個正常的消息隊列,同步改異步就可以用 nsq。

既然 Kafka 可以處理大數據,那爲什麼不用 kafka,而用 nsq 呢?

這個問題我之前想過,問過我的 leader。kafka 一般是大數據那邊流處理什麼的,它那邊一般都只接受 kafka 的消息,和大數據集成比較好。至於選 nsq 的話,它是結合當時的業務場景選擇的,這個也沒有選哪個好哪個壞。

那他當時選型的時候,爲什麼不用 kafka

因爲 kafka 貌似對於延時消息等支持的不太好,事務這些,它雖然對大數據的處理的好,但是它也有缺漏的地方,它有它的專攻方向,比如:吞吐量方面,但是也有它的不足之處,就好比計算機中的摩爾定律。一般業務系統常需要一些延時消息就需要用 nsq 了。

根據我的項目問的一些問題

……

有數據庫調優經驗嗎?對於數據庫有多索引匹配時,有什麼經驗嗎

這個匹配的話,比如:ABC 三個組合索引,必須要順序執行,比如 A = 2,C =2 。這個時候就不會執行,因爲它破壞了順序性。

你說這種情況是完全用不到嗎

是的,因爲它不滿足索引的最左匹配原則。

那比如說,我數據庫有多個索引,A,B,BC,一個查詢條件 A,B,C 都有,那一般怎麼查看呢

這個一般的話是用 explain 去分析一下 sql 的執行計劃,它會輸出可能走的索引,真正走的索引,掃描的行數,額外的消耗(extra),用沒用臨時表等。

那它分析出來的索引就是數據庫一定會用的索引嗎

explain 分析出來的嗎

或者說,你覺得它 explain 分析出來的就是最佳的索引嗎

一般情況下最佳的,數據庫會根據你的 sql,通過解析器生成對應的語法分析樹,它對這個樹進行一些規則的優化後,會生成一些查詢計劃,通過基於時間成本的分析算法選出一個儘可能是最佳的查詢計劃。這個具體合不合適很難說。

你沒有遇到建的索引不好,導致走的索引是最差的情況嗎

這個一般的話,可能是你對索引一無所知,導致一些索引的規則不去遵守,而且數據庫索引的匹配規則很多,很容易走坑。如果你的業務一定要走你設置的那個索引,mysql 也可以通過設置強制走你設置的某個索引。

你對 Java8 瞭解嗎

瞭解,因爲我現在參與的項目就大量用了 Java8 的特性。比如:stream,lambda 表達式,時間 API 等。具體應用場景的話,比如你一個接口要返回 VO List 集合,而你數據庫查出來的是 DO List 集合,這個時候你就可以用集合的 stream 去做這個轉換。相比於傳統的寫法,代碼會變的很簡單和清爽。

流式編寫代碼的好處和壞處可以說一下嘛

好處的話,寫代碼的效率快了,看和很舒服。

壞處的話,流式性能不怎麼好,併發情況很多的情況下才體現出好。

我覺得最主要的是,之前你自己寫的話,就面向過程化了。流式的話,Java8 提倡的是面向函數式編程嘛。編程模型之前最開始是面向過程,然後面向對象,面向元編程,面向切面編程,面向函數式編程,以後 java9 的面向模塊化編程。而且把過程封裝在函數中,通過函數去轉換數據的狀態對於線程安全方面也有很大的好處。

如果數據庫對一些記錄存在熱點更新操作,有大量的更新,怎麼解決呢

一般可以利用多級緩存去解決。如果數據量太猛增的話,你用 redis 客戶端訪問 redis 服務端都訪問不到,因爲帶寬被打滿了嘛。這種情況可以提前去探測某個 key 是不是熱點,然後在本地緩存操作。

你怎麼即時同步數據給其他人呢

它會有一個算法提前探測某個 key 是否是熱點,然後框架會幫你進行本地緩存的管理。

數據庫有單熱點,那你怎麼解決

這種一般先做一個緩存,然後可以用消息隊列削峯填谷。

操作緩存可能會超時,你怎麼保證這個數據的正確性呢?因爲你加了緩存呀

對對,這個數據庫和緩存保持一致性比較難保證。而且大量數據訪問更新,也不能加鎖,因爲數據庫通過行鎖保證線程併發安全問題。

我要你解決的就是行鎖等待導致的性能被拉低的問題,用緩存也是可以的,但是不能保證 100% 的數據一致性,那我的業務場景就是想要 100% 的數據一致性,你現在有大概的解決思路嗎

這個可以用多套數據庫主從集羣來解決嗎?通過這種方式來提升數據庫的寫性能。讓多個集羣去抗。數據庫中間件可以把流量分散到各個主從集羣中的主庫上。

可以,這算是一種解決方案,那還有其他辦法嗎

你打破這個行鎖就行了

…… 我再想想。這個 ……

主要是單條記錄引起的,它就是頻繁更新引起的。

昂,這個是不是可以……… 我看 JDK 源碼,頻繁更新它一般是: HashMap 是非線程安全的,後來出現了線程安全版的 HashTable,但是它性能比較差,因爲它直接就對整個 hash 表進行了加鎖。後來出現了 CurrentHashMap,出現了分段鎖,降低了鎖的粒度,其實就是一種思想,你對一個熱點數據的訪問的話,就是分而治之,多去搞幾個,均攤一下。難道是利用 hash 一致性算法把這些寫請求,多分幾張表。

差不多吧,思想就是分而治之,只要把單點數據拆分掉,讓它變成多條數據,然後去更新多條數據,最後再合成一條。

嗯嗯。現在大數據一般也這樣,大的搞不動就拆分。

從和你的對話來看,我覺得你基礎也不錯,基礎我就不問了,我這邊沒有什麼問題了,我看你這邊,實習經歷豐富,offer 收的也挺多。你有什麼想問的

貴公司的技術棧,還有如果我進去以後所在的產品線。

面試官講述了他們公司的技術棧和一些業務

面試官對我的一些職業規劃的建議

多鍛鍊自己的技術思維 + 業務思維,可以往業務中臺方向走。更好的支持別人的業務,技術主要服務於技術,要培養業務架構思維。

總結

我覺得面試過程中要避免自己一直在說,可以多和面試官去互動,去問面試官是不是這樣子,這樣可以避免你理解錯面試官的問題。我們的項目可能大部分是 CRUD,但是我們的思維不可以停留在 CRUD,多去結合業務,也就是結合場景去思考你項目,這可能是一個很大的優勢。畢竟技術是用於服務業務,去解決業務需求。

**整理面經不易,花了我週末大部分的時間,如果覺得寫的好話,歡迎關注公衆號、轉發,你們的支持是我繼續寫後續面經的動力。**

file

搜索微信公衆號:Java知其所以然,可免費領取某課、Java 後端面經等資源,還有統一環境(教你怎麼配置一套開發環境)視頻領取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章