天天看點

最新Java中進階面試分享

從廣州離職回武漢面試了大大小小十幾家公司,拿到幾家offer,也選擇了一家自己覺得還不錯的公司。把面試的一些經驗記錄了下來,留給自己也分享給大家,希望能給大家帶來一定的幫助。

一、消息中間件:

消息中間件的作用:解耦、削峰、異步

常見問題:MQ服務當機怎麼處理?(配置主從、叢集)

MQ資料丢失怎麼辦?(重要資料配置事務,做持久化)

緩存擊穿等等問題。

幾種常見消息中間件的比較:

不同中間件 ActiveMQ RabbitMQ RocketMQ Kafka
單機吞吐量 萬級,比RocketMQ、Kafka低一個數量級 同ActiveMQ 10萬級,支援高吞吐 10萬級,高吞吐,一般配合大資料類的系統來進行實時資料計算、日志采集等場景
topic數量對吞吐量的影響 topic可以達到幾百/幾千的級别,吞吐量會有較小幅度的下降,這是RocketMQ的一大優勢,在同等機器下可以支撐大量的topic topic從幾十到幾百個時,吞吐量會大幅度下降,在同等機器下,kafka盡量保證topic數量不要過多,如果要支撐大規模的topic,需要增加更多的機器資源
時效性 ms級 微秒級,這是RabbitMQ的一大特性 ms級 延遲在ms級以内
可用性 高,基于主從架構實作高可用 同activeMQ 非常高,分布式架構 非常高,分布式,一個資料多個副本,少數機器當機不會丢失
消息可靠性 有較低的機率丢失資料 經過參數優化配置可做到0丢失 同RocketMQ
功能支撐 MQ領域功能及其完備 基于erlang 較完善 功能較為簡單,主要大資料領域

二、微服務:

1.springCloud和Dubbo差別

Dubbo SpringCloud
服務注冊中心 ZooKeeper SpringCloud Netfix Eureka
服務調用方式 RPC REST API
服務監控 Dubbo-monitor Springboot Admin
斷路器 不完善 SpringCloud Netfix Hystrix
服務網關 SpringCloud Netfix Zuul
分布式配置 SpringCloud Config
服務跟蹤 SpringCloud Sleuth
消息總線 SpringCloud Bus
資料流 SpringCloud Stream
批量任務 SpringCloud Task

最大差別:SpringCloud抛棄了Dubbo的RPC通信,采用的是基于HTTP的REST方式,REST相比RPC更為靈活,但也犧牲了服務調用的性能。

Dubbo和SpringCloud并不是完全的競争關系,Dubbo定位始終是一款RPC架構,SpringCloud的目的是微服務架構下的一站式解決方案。

2.分布式鎖和分布式事務:

鎖解決的是單程序中的多線程并發問題,事務解決的是一個會話中操作的資料一緻性;

分布式鎖解決的是多程序的并發問題,分布式事務解決的是組合服務的資料操作的一緻性問題。

實作分布式鎖的常見方式:

① zookeeper:每個用戶端對某個方法加鎖時,在zookeeper上的與該方法對應的指定節點的目錄下生成一個唯一的瞬時有序節點。判斷是否擷取鎖的方式很簡單,隻需要判斷有序節點中序号最少的一個,當釋放鎖的時候隻需将這個瞬時節點删除即可。同時可以避免服務當機導緻的鎖無法釋放而産生的死鎖問題。

② redis分布式鎖實作:redis函數setnx()。任務目标主鍵key存入redis,設定過期時間,每次請求先查setnx()看是否能将新資料插入redis,可以傳回true,不可以則傳回false。

①和②兩種方式:zookeeper中建立和删除節點隻能通過leader伺服器來執行,然後将資料同步到follwer上,性能上不如基于緩存的實作。

3.死鎖問題:

産生的4大必要條件:

①資源互斥/資源不共享

②占有和等待/請求并保持

③資源不可剝奪

④環路等待

避免死鎖的常見方法有:

①避免一個線程同時擷取多個鎖

②避免一個線程在鎖内同時占用多個資源,盡量保證每個鎖隻占用一個資源

③嘗試使用定時鎖,使用lock.trylock()來代替使用内置鎖

線程安全:就是多線程通路時,采用加鎖機制,當一個線程采訪該類的某個資料時,進行保護,其他線程不能進行通路。(常見問題hashMap問題等)

Dubbo:遠端服務調用的分布式架構

核心部分如下:

①叢集容錯:提供基于接口方法的透明過程調用,包括多協定支援、軟負載均衡、失敗容錯、位址路由、動态配置

②遠端通訊:提供對多種基于長連接配接的NIO架構抽象封裝

③自動發現:基于注冊中心目錄服務,使服務消費方能動态的查找服務提供方,使位址透明,使服務提供方可以平滑的增加和減少機器

zookeeper:服務注冊與發現注冊的注冊中心。zk的目标是封裝好複雜易出錯的關鍵服務,将簡單易用的接口和性能高效、功能穩定的系統提供給使用者。zk代碼版本中提供了分布式獨享鎖、選舉、隊列的接口,代碼在zookeeper-3.4.3/src/recipes下,有Java和c語音這兩個版本

三、IO和NIO的差別

IO NIO
面向流 面向緩沖
阻塞IO 非阻塞IO
選擇器
意味着每次從流中讀一個或多個位元組,直至讀取所有位元組,沒有緩存,不能前後移動流中的資料 資料讀取到一個它稍後處理的緩沖區,需要時可在緩沖區前後移動。選擇器允許一個單獨的線程來監視多個輸入通道

四、多線程問題:

常見的幾種線程池:

newSingleThreadExecutor 單線程化線程池 隻會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO,LIFO)來執行 主要問題:堆積的請求處理隊列可能會耗費非常大的記憶體,甚至OOM
newFixedThreadPool 定長線程池 可控制線程最大并發數,超出的線程會在隊列中等待 同上
newCachedThreadPool 可緩存線程池 線程池的長度超過處理需要,可靈活回收空閑線程,若無回收,則建立線程 主要問題是線程最大數是Integer Max_value,可能會建立非常多的線程,甚至OOM
newScheduledThreadPool 定長線程池,支援定時及周期性任務執行 同上

五、資料庫

資料庫常考問的幾個點:

①sql優化:mysql的my.cnf設定開啟查緩存日志,explain關鍵字,索引,or改用union all,where子句加索引,業務邏輯用Java,減少函數使用等等。

②組合索引

③資料庫分庫分表(常見的分表方法:userId,時間等)

④資料庫主從,讀寫分離,redis緩存等

⑤哨兵模式,權重等等

⑥no_sql資料庫,redis(redis的資料結構等),MongoDB,HBASE等等

六、其他問題

項目占用CPU很高,怎麼排除問題?(Linux系統)

①top指令檢視cpu占比,找出占比高的程序id

②ps -mp pid -o Thread,tid,time (pid指的是程序id,tid是線程id)

③找到cpu占用率高的tid

④轉16進制,為等會在jstack中查找做準備(網上各種工具)

⑤使用jstack,列印日志檔案 jstack pid -> log

⑥然後下載下傳日志到本地,通過16進制的tid查找,找到哪個代碼塊,完成

Windows系統直接通過任務管理器查找占cpu高的,然後通過jdk自帶的jstack工具查找

另外就是溫習下Java基礎的東西,封裝、繼承、多态等,裝箱(基本類型轉包裝類),開箱(包裝類轉基本類型),Tomcat,spring的IOC,AOP等,祝大家好運,都能找到高薪的好工作