Java併發編程之常見面試題

1. 進程和線程的異同?

相同點:生命週期相似,都包含就緒、運行、終止等狀態
不同點:
	1. 起源不同,先有進程,由於CPU的提升以及性能要求的提高,纔有了線程;
	2. 內存共享機制不同:進程與進程之間通常不能共享數據,線程與線程之間不需要任何處理就能直接共享數據;
	3. 擁有資源數量不同,線程共享的屬性:進程ID、進程公有數據等;線程私有的屬性:線程ID、線程堆棧,進程是線程的容器,一個進程至少要包含一個線程‘
	4. 開銷不同,進程的啓動和終止都遠大於線程 

2. 併發和並行的異同?

相同點:並行一定是併發
不同點:
1. 併發是利用單核CPU,多個任務在重疊的時間內運行和完成,因爲CPU運行的很快,只是看起來像同時運行,實際上是串行的;
2. 並行是利用多核CPU,多個任務在同一時刻啓動、運行和終止,是真正的同時運行。

3. 高併發是不是就意味着多線程?有什麼反例?

1. 高併發不意味着多線程,高併發是大量請求導致的狀態,多線程只是解決高併發狀態的一種解決方案
2. 反例:數據庫請求是高併發狀態時,可以加入Redis緩存層來解決高併發狀態,而Redis是單線程的
3. 反例:可以使用消息中間件來解決高併發,比如RabbitMQ

4. 多線程可以提高程序執行效率,你知不知道有哪些弊端?

1. 性能問題:上下文切換、保存CPU緩存帶來的損耗
2. 線程安全問題:數據安全(i++)、死鎖、活鎖、飢餓

5. 什麼是同步阻塞、異步非阻塞?

同步阻塞:調用者發起請求,在結果返回之前一直等待,被調用者不會主動告訴結果
異步非阻塞:調用者發起請求,在結果返回之前做別的事,被調用者主動告訴結果

6. 有多少種實現線程的方法?

1. 從代碼寫法的角度,有實現Runnable接口、繼承Thread類、線程池、FutureTask和Callable等;
2. 本質上是實現Runnable接口、繼承Thread類,其中實現Runnable接口更好,有三點優勢;
3. 看原理,實現Runnable接口、繼承Thread類本質都是一樣的,都是執行run(),一種是執行Runnable對象的run(),另一種是重寫Thread類的run()。

7. 實現Runnable接口和繼承Thread類哪種方式更好?

1. 解耦的角度,創建線程和任務內容應該解耦;
2. 新建線程的損耗,Thread類負責創建線程,實現Runnable接口的方法,我們可以反覆的用同一個線程,不用再去新建線程,比如線程池就這麼做的;
3. 擴展性,Java不支持多繼承,繼承Thread類就無法繼承其他類,限制了擴展性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章