多線程和併發問題已成爲各類 Java 面試中必不可少的一部分。若是你準備參加投行的 Java 開發崗位面試,好比巴克萊銀行(Barclays)、花旗銀行(Citibank)、摩根史坦利投資公司(Morgan Stanley),你會遇到不少有關多線程的面試題。多線程和併發是投行面試的熱門知識點,尤爲是在面試有關電子交易開發工做時,他們喜歡用棘手的 Java 線程面試題轟炸面試者。他們但願確保面試者對 Java 多線程和併發有紮實的知識基礎,由於他們大多數關注高性能帶來的競爭優點。php
舉個例子,直接市場準入模式(Direct to Market,DMA)使用高容量低延遲的電子交易系統,一般來講是併發的。大多數時間他們致力於微秒級的延遲,因此掌握如何有效地下降延遲、提升吞吐量很是重要。html
有一些 Java 線程面試題是我特別中意的。我並不會直接給你答案,而是儘量給你指點。我會以後補充上詳細答案,正如我在其餘文章中那樣。java
JDK 1.5 中引入併發包以後,併發工具和併發集合備受歡迎,好比 ThreadLocal、 BlockingQueue、Counting Semaphore 和 ConcurrentHashMap,與這些工具相關的面試題也愈來愈多。面試
Java 8 和 Java 9 也是這種狀況。圍繞 lambda 表達式、並行流(parallel streams)、新的 Fork/Join 線程池、CompletableFuture 的問題在 2018 年不斷涌現,2019 年還將持續。從此你也應該對這些知識點有所準備。編程
總之不要考慮那麼多,下面是各類投行,好比巴克萊銀行(Barclays)、花旗銀行(Citibank)、摩根史坦利投資公司(Morgan Stanley)等等,面試 Java 開發者時常問的 Java 多線程和併發問題。緩存
這個線程面試題一般在第一輪面試或電話面試時被問到,這道多線程問題爲了測試面試者是否熟悉 join
方法的概念。答案也很是簡單——能夠用 Thread 類的 join
方法實現這一效果。數據結構
多線程和併發編程中使用 lock 接口的最大優點是它爲讀和寫提供兩個單獨的鎖,可讓你構建高性能數據結構,好比 ConcurrentHashMap
和條件阻塞。
這道 Java 線程面試題愈來愈多見,並且隨後的面試題都基於面試者對這道題的回答。
我強烈建議在任何 Java 多線程面試前都要多看看有關鎖的知識,由於現在電子交易系統的客戶端和數據交互中,鎖被頻繁使用來構建緩存。多線程
wait
和 sleep
方法有什麼區別?咱們來看看另外一個常常被問到的線程面試題。這道題常出如今電話面試中。二者主要的區別就是等待釋放鎖和監視器。sleep
方法在等待時不會釋聽任何鎖或監視器。wait
方法多用於線程間通訊,而 sleep
只是在執行時暫停。能夠看我另外一篇有關Java 中 wait 和 sleep的文章。併發
這是一道相對困難的 Java 多線程面試題,考察點不少。它考察了面試者是否真正寫過 Java 多線程代碼,考察了面試者對併發場景的理解。而且能夠根據面試者的代碼問不少後續問題,若是他用 wait()
和 notify()
方法成功實現了阻塞隊列,可讓他用 Java 5 的併發類從新實現一次。工具
和上面有關線程的問題類似,這個問題在工做中很典型,但有時面試官會問這類問題,好比「在 Java 中如何解決生產者消費者問題?」其實,有不少解決方式。我分享過用 Java 中 BlockingQueue 的解決方案。有時他們甚至會讓你給出哲學家進餐問題的解決方案。
這是我最喜歡的 Java 多線程面試題,由於即便死鎖在多線程併發編程中十分常見,許多面試者仍然抓耳撓腮,不能寫出無死鎖的代碼。
只須要問他們若是有 N 個資源和 N 個線程去執行某個操做,而後請求全部資源。
這裏的 N 能夠是 2 做爲最簡單的狀況,也能夠是個很大的數字讓問題變複雜。有關死鎖的更多信息能夠看這篇文章Java 中如何避免死鎖。
這是個簡單的 Java 線程面試題。另外一個緊隨其後的問題將是:你須要同步原子操做嗎?你能夠看這篇文章瞭解更多Java 同步。
volatile
關鍵字是什麼?你如何使用它?它和 Java 中的同步方法有什麼區別?自從 Java 5 中調整 volatile
關鍵字和 Java 內存模型後,有關 volatile
關鍵字的線程問題愈來愈常見。掌握 volatile
變量在併發環境中如何確保可見性、有序性和一致性很是重要。
這個 Java 多線程問題通常出如今高級面試。多數面試官會問你最近一次遇到的競態條件,如何解決的,有時他們也會寫點簡單代碼讓你發現競態條件。能夠看看個人這篇文章Java 中的競態條件。我認爲,這是最棒的 Java 線程面試問題之一,並且能夠測試出面試者解決競態條件的經驗,或是編寫無數據競爭、無其競態條件的代碼經驗。
在 UNIX 中,你可使用 kill -3
而後線程轉儲日誌會打印在屏幕上,可使用 CTRL+Break
查看。這只是一個較簡單的線程面試題,狡猾一點的話他們會問你如何分析轉儲日誌。線程轉儲日誌對於分析死鎖狀況很是有用。
start()
方法會調用 run()
方法,爲何咱們調用 start()
方法,而不直接調用 run()
方法?這是一個基本的 Java 多線程面試題。最初,我剛開始多線程編程時對此還有些困惑。現在我通常在 Java 中級面試的電話面試或一輪面試中遇到。
這道問題的答案是這樣的。當你調用 start()
方法時,它會新建一個線程而後執行 run()
方法中的代碼。若是直接調用 run()
方法,並不會建立新線程,方法中的代碼會在當前調用者的線程中執行。能夠看這篇文章瞭解更多線程中 Start 和 Run 方法的區別。
這是有關線程的一個很狡猾的問題。有不少緣由會致使阻塞,若是是 IO 阻塞,我認爲沒有方式能夠中斷線程(若是有的話請告訴我)。另外一方面,若是線程阻塞是因爲調用了 wait()
,sleep()
或 join()
方法,你能夠中斷線程,經過拋出 InterruptedException
異常來喚醒該線程。能夠看這篇文章瞭解有關處理阻塞線程的知識Java 中如何處理阻塞方法。
CyclicBarriar
和 CountdownLatch
有什麼區別?最近的 Java 線程面試題多數在測試你對 JDK 5 併發包的掌握程度。二者區別之一就是 CyclicBarrier
在屏障打開以後(全部線程到達屏障點),能夠重複使用。而 CountDownLatch
不行。想了解更多能夠參與課程Java 中的多線程和並行計算。
儘管這道面試題和線程沒有直接關係,但間接影響也很大。若是面試官隨後讓你寫一個不可變類,或問你爲何 Java 中的 String 是不可變的,會讓面試題變得更加複雜。
內存干擾、競態條件、死鎖、活鎖、線程飢餓是多線程和併發編程中比較有表明性的問題。這類問題無休無止,並且難於定位和調試。
這是基於經驗給出的 Java 面試題。你能夠看看Java 併發實戰課程來了解現實生活中高性能多線程應用所面臨的問題。
上面所說的是我喜歡的,也是投行最常問的 Java 線程面試題。這個清單並不完整,因此能夠在下方評論出你在面試中遇到的有意思的 Java 線程題目。這篇文章收集並分享與多線程概念有關的面試題,不只僅有助於面試,還爲你們打開多線程概念的大門。
原文連接: https://dzone.com/articles/top-15-java-multithreading-concurrency-interview-q
翻譯: ImportNew.com - 一杯哈希不加鹽
譯文連接: http://www.importnew.com/29562.html