天下無難試之多線程面試刁難大全


多線程技術在互聯網技術方面使用如此廣泛,幾乎所有的後端技術面試官都要在併發編程的使用和原理方面對小夥伴們進行各種刁難。作爲一名在互聯網技術行業打擊過成百上千名【請允許我誇張一下】的資深技術面試官,看過了無數落寞的身影失望的離開,略感愧疚,故獻上此文,希望各位讀者以後面試勢如破竹,永無失敗!

什麼是線程?

線程是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位,可以使用多線程對進行運算提速。

比如,如果一個線程完成一個任務要100毫秒,那麼用十個線程完成改任務只需10毫秒


什麼是多線程?優缺點?

什麼是多線程?

多線程:是指從軟件或者硬件上實現多個線程的併發技術。

多線程的好處:

1.使用多線程可以把程序中佔據時間長的任務放到後臺去處理,如圖片、視屏的下載

2.發揮多核處理器的優勢,併發執行讓系統運行的更快、更流暢,用戶體驗更好

多線程的缺點:

1.大量的線程降低代碼的可讀性;

2.更多的線程需要更多的內存空間

3.當多個線程對同一個資源出現爭奪時候要注意線程安全的問題。

線程的五個狀態(五種狀態,創建、就緒、運行、阻塞和死亡)?

線程通常都有五種狀態,創建、就緒、運行、阻塞和死亡。

第一是創建狀態。在生成線程對象,並沒有調用該對象的start方法,這是線程處於創建狀態。

第二是就緒狀態。當調用了線程對象的start方法之後,該線程就進入了就緒狀態,但是此時線程調度程序還沒有把該線程設置爲當前線程,此時處於就緒狀態。在線程運行之後,從等待或者睡眠中回來之後,也會處於就緒狀態。

第三是運行狀態。線程調度程序將處於就緒狀態的線程設置爲當前線程,此時線程就進入了運行狀態,開始運行run函數當中的代碼。

第四是阻塞狀態。線程正在運行的時候,被暫停,通常是爲了等待某個時間的發生(比如說某項資源就緒)之後再繼續運行。sleep,suspend,wait等方法都可以導致線程阻塞。

第五是死亡狀態。如果一個線程的run方法執行結束或者調用stop方法後,該線程就會死亡。對於已經死亡的線程,無法再使用start方法令其進入就緒

什麼是CAS?

CAScompare and swap)的縮寫,中文翻譯成比較並交換

CAS 不通過JVM,直接利用java本地方 JNI(Java Native Interface爲JAVA本地調用),直接調用CPU 的cmpxchg(是彙編指令)指令。

利用CPUCAS指令,同時藉助JNI來完成Java的非阻塞算法,實現原子操作。其它原子操作都是利用類似的特性完成的

整個java.util.concurrent都是建立在CAS之上的,因此對於synchronized阻塞算法,J.U.C在性能上有了很大的提升。

CAS是項樂觀鎖技術,當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值,而其它線程都失敗,失敗的線程並不會被掛起,而是被告知這次競爭中失敗,並可以再次嘗試。

CAS應用

CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改爲B,否則什麼都不做。

CAS優點

確保對內存的讀-改-寫操作都是原子操作執行

CAS缺點

CAS雖然很高效的解決原子操作,但是CAS仍然存在三大問題。ABA問題,循環時間長開銷大和只能保證一個共享變量的原子操作

什麼是AQS?

AbstractQueuedSynchronizer簡稱AQS,是一個用於構建鎖和同步容器的框架。事實上concurrent包內許多類都是基於AQS構建,例如ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,FutureTask等。AQS解決了在實現同步容器時設計的大量細節問題。

AQS使用一個FIFO的隊列表示排隊等待鎖的線程,隊列頭節點稱作哨兵節點或者啞節點,它不與任何線程關聯。其他的節點與等待線程關聯,每個節點維護一個等待狀態waitStatus


什麼是樂觀鎖和悲觀鎖?

悲觀鎖

Java在JDK1.5之前都是靠synchronized關鍵字保證同步的,這種通過使用一致的鎖定協議來協調對共享狀態的訪問,可以確保無論哪個線程持有共享變量的鎖,都採用獨佔的方式來訪問這些變量。獨佔鎖其實就是一種悲觀鎖,所以可以說synchronized是悲觀鎖。

樂觀鎖

樂觀鎖( Optimistic Locking)其實是一種思想。相對悲觀鎖而言,樂觀鎖假設認爲數據一般情況下不會造成衝突,所以在數據進行提交更新的時候,纔會正式對數據的衝突與否進行檢測,如果發現衝突了,則讓返回用戶錯誤的信息,讓用戶決定如何去做。

併發編程(concurrency)並行編程(parallellism)有什麼區別?

併發(concurrency)和並行(parallellism)是:

解釋一:並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔發生。

解釋二:並行是在不同實體上的多個事件,併發是在同一實體上的多個事件。

解釋三:在一臺處理器上“同時”處理多個任務,在多臺處理器上同時處理多個任務。如hadoop分佈式集羣

所以併發編程的目標是充分的利用處理器的每一個核,以達到最高的處理性能。

想要了解更多多線程知識點的,可以加羣650385180,多線程的學習資料以及多線程面試題彙總都在羣的共享區供大家免費下載.


怎麼喚醒一個阻塞的線程?

如果線程是因爲調用了wait()、sleep()或者join()方法而導致的阻塞,可以中斷線程,並且通過拋出InterruptedException來喚醒它;如果線程遇到了IO阻塞,無能爲力,因爲IO是操作系統實現的,Java代碼並沒有辦法直接接觸到操作系統。

如何檢測死鎖?怎麼預防死鎖?

所謂死鎖:是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖

通俗地講就是兩個或多個進程被無限期地阻塞、相互等待的一種狀態

死鎖產生的原因?

1.因競爭資源發生死鎖 現象:系統中供多個進程共享的資源的數目不足以滿足全部進程的需要時,就會引起對諸資源的競爭而發生死鎖現象

2.進程推進順序不當發生死鎖

死鎖的四個必要條件:

互斥條件:進程對所分配到的資源不允許其他進程進行訪問,若其他進程訪問該資源,只能等待,直至佔有該資源的進程使用完成後釋放該資源

請求和保持條件:進程獲得一定的資源之後,又對其他資源發出請求,但是該資源可能被其他進程佔有,此事請求阻塞,但又對自己獲得的資源保持不放

不可剝奪條件:是指進程已獲得的資源,在未完成使用之前,不可被剝奪,只能在使用完後自己釋放

環路等待條件:是指進程發生死鎖後,若干進程之間形成一種頭尾相接的循環等待資源關係

這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之

一不滿足,就不會發生死鎖。

檢測死鎖

有兩個容器,一個用於保存線程正在請求的鎖,一個用於保存線程已經持有的鎖。每次加鎖之前都會做如下檢測:

檢測當前正在請求的鎖是否已經被其它線程持有,如果有,則把那些線程找出來

遍歷第一步中返回的線程,檢查自己持有的鎖是否正被其中任何一個線程請求,如果第二步返回真,表示出現了死鎖

死鎖的解除與預防:

理解了死鎖的原因,尤其是產生死鎖的四個必要條件,就可以最大可能地避免、預防和

解除死鎖。

所以,在系統設計、進程調度等方面注意如何不讓這四個必要條件成立,如何確

定資源的合理分配算法,避免進程永久佔據系統資源。

此外,也要防止進程在處於等待狀態的情況下佔用資源。因此,對資源的分配要給予合理的規劃。

想要了解更多多線程知識點的,可以加羣650385180,多線程的學習資料以及多線程面試題彙總都在羣的共享區供大家免費下載.


更多多線程面試題

1.什麼是原子操作?在Java Concurrency API中有哪些原子類(atomic classes)?

2.什麼是Executors框架?

3.什麼是阻塞隊列?如何使用阻塞隊列來實現生產者-消費者模型?

4.什麼是Callable和Future?

5.什麼是FutureTask?

6.什麼是同步容器和併發容器的實現?

7.什麼是多線程的上下文切換?

8.ThreadLocal的設計理念與作用?

9. ThreadPool(線程池)用法與優勢?

10.加羣:650385180獲取更多多線程知識點及面試題

11. Concurrent包裏的其他東西:ArrayBlockingQueue、CountDownLatch等等。

12. synchronized和ReentrantLock的區別?

13. Semaphore有什麼作用?

14. Java Concurrency API中的Lock接口(Lock interface)是什麼?對比同步它有什麼優勢?

總結

關於Java多線程面試技術點的一些總結已經寫完了,受限於我的視野,所以可能寫的不是很全面,大家要是有不同意見的,可以分享出來,一起交流,要是想深入瞭解多線程技術知識點的,可以加上面的羣,希望可以幫助在這個行業發展的朋友和童鞋們,在論壇博客等地方少花些時間找資料,把有限的時間,真正花在學習上。


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