天天看點

Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)

  大家好,我是陳哈哈,北漂五年。相信大家和我一樣,​

​都有一個大廠夢​

​,作為一名資深Java選手,深知面試重要性,接下來我準備用100天時間,基于Java崗面試中的高頻面試題,以​

​每日3題​

​的形式,帶你過一遍熱門面試題及恰如其分的解答。

  一路走來,随着問題加深,發現不會的也愈來愈多。但底氣着實足了不少,相信不少朋友和我一樣,日積月累才是最有效的學習方式!想起高中時一位女同學的座右銘:​

​隻有沉下去,才能浮上來。​

​共勉(juan)。
Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)

  LOL世界賽開始了,來一波LPL、LCK和LEC三個賽區女主持旗袍留念,穿個旗袍能讓我們有什麼壞心思呢?????????是吧鐵子們?

車票

  • ​​面試題1:什麼是線程阻塞?什麼情況會導緻線程阻塞​​
  • 追問1:線程阻塞會導緻程序阻塞麼?
  • ​​面試題2:怎麼了解阻塞和非阻塞​​
  • ​​面試題3:怎麼了解并發和并行​​
  • ​​每日小結​​

  本欄目Java開發崗高頻面試題主要出自以下各技術棧:​

​Java基礎知識​

​、​

​集合容器​

​并發程式設計​

​JVM​

​Spring全家桶​

​MyBatis等ORMapping架構​

​MySQL資料庫​

​Redis緩存​

​RabbitMQ消息隊列​

​Linux操作技巧​

​等。

面試題1:什麼是線程阻塞?什麼情況會導緻線程阻塞

  在某一時刻某一個線程在運作一段代碼的時候,這時候另一個線程也需要運作,但是在運作過程中的那個線程執行完成之前,另一個線程是​

​無法擷取到CPU執行權​

​的(調用sleep方法是進入到睡眠暫停狀态,但是CPU執行權并沒有交出去,而調用wait方法則是将CPU執行權交給另一個線程),這個時候就會造成​

​線程阻塞​

​。

java程式中出現線程阻塞的幾種情況:

Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)

1、睡眠狀态:

  ​

​Thread.sleep (long millis)​

​方法,使線程轉到阻塞狀态。millis參數設定睡眠的時間,以毫秒為機關。當睡眠結束後,就​

​轉為就緒(Runnable)狀态​

​。sleep()平台移植性好。

2、等待狀态:

  當一個線程正在運作時調用了​

​wait()​

​方法,此時該線程需要交出CPU執行權,也就是将鎖釋放出去,交給另一個線程,該線程進入等待狀态,但與睡眠狀态不一樣的是,​

​進入等待狀态的線程不需要設定睡眠時間​

​,但是需要執行​

​notify()​

​或者​

​notifyall()​

​來對其​

​喚醒​

​,自己是不會主動醒來的,等被喚醒之後,該線程也會進入就緒狀态,但是進入僅需狀态的該線程手裡是沒有執行權的,也就是沒有鎖,而睡眠狀态的線程一旦蘇醒,進入就緒狀态時是自己還拿着鎖的。

3、禮讓狀态:

​Thread.yield()​

​ 方法,暫停目前正在執行的線程對象,​

​把執行機會讓給相同或者更高優先級的線程​

​。yield() 使得線程放棄目前分得的 CPU 時間,但是不使線程阻塞,即線程仍處于可執行狀态,随時可能再次分得 CPU 時間。調用 yield() 的效果等價于排程程式認為該線程已執行了足夠的時間進而轉到另一個線程。

4、自閉狀态:

  當一個線程正在運作時,調用了一個​

​join()​

​方法,此時​

​該線程會進入阻塞狀态,另一個線程會運作,直到運作結束後,原線程才會進入就緒狀态​

​。這個比較像是”走後門“,本來該先把你的事情解決完了再解決後邊的人的事情,但是這時候有走後門的人,那就會停止給你解決,而優先把走後門的人事情解決了;

5、suspend() 和 resume() :

  兩個方法配套使用,suspend()使得線程進入阻塞狀态,并且不會自動恢複,必須其對應的resume() 被調用,才能使得線程重新進入可執行狀态。

  典型地,suspend() 和 resume() 被用在等待另一個線程産生的結果的情形:測試發現結果還沒有産生後,讓線程阻塞,另一個線程産生了結果後,調用 resume() 使其恢複。Thread中​

​suspend()和resume()兩個方法在JDK1.5中已經廢除​

​,因為有死鎖傾向。

回答這個問題,我們得了解一下線程模型(下述對應關系為 ​

​線程​

​對​

​核心排程實體​

​)

  • 多對1使用者級線程模型
  • 1對1核心級線程模型
  • 多對多兩級線程模型
Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)
  • 線程的建立、排程、同步,由所屬程序的使用者空間線程庫實作。
  • 使用者态線程,對核心幾乎是透明的(許多操作不需要核心接管)
  • 但線程總要有一些操作經過核心,比如系統調用。
  • 不需要頻繁的核心态/使用者态切換,處理速度非常快。
  • 該模式下,當程序的某個線程,系統調用(比如I/O)阻塞時,該程序也會阻塞。

  該模式下,程序的所有線程,都對應一個核心排程實體(KES),多對一,并且核心不知道這個程序有哪些線程。KES無法将其他線程,排程到其他處理器上。該程序(所有的線程)被阻塞,直到本次系統調用(比如I/O)結束。

Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)
  • 每個使用者線程都對應一個的核心排程實體。
  • 核心會對每個線程進行排程,可以排程到其他處理器上。
  • 線程每次操作會在使用者态和核心态切換。
  • 線程數量過多時,對系統性能有影響。
Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)
  • 每個使用者線程擁有多個核心排程實體
  • 多個使用者線程也可以對應一個核心排程實體
  • 實作該模型非常複雜。
  1. ​線程阻塞時,在多對1使用者級線程模型下,會導緻所屬程序阻塞​

  2. ​在1對1或多對多模型下,不會導緻程序阻塞​

    ​,目前linux基本上都采用一對一模型。
Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)

課間休息,又來秀一下來自咱們群裡同學的搬磚工地,坐标:青島。

作者:​

​内蒙古上單​

面試題2:怎麼了解阻塞和非阻塞

阻塞和非阻塞關注的是程式在​

​等待調用結果​

​(消息,傳回值)時的​

​狀态​

​阻塞調用​

​:指調用結果傳回之前,目前線程會被挂起。調用線程隻有在得到結果之後才會傳回。

​非阻塞調用​

​:指在不能立刻得到結果之前,該調用不會阻塞目前線程。

  就像上司周末打電話問我能不能去公司加班,我支支吾吾半天上司沒聽懂我說的啥,如果是阻塞式調用,上司(線程)會把自己​

​挂起​

​,一直追問我直到我告訴他能不能去。

  而如果是非阻塞式調用,上司就給我發了條語音,然後讓我盡快回複他,​

​他就可以摸魚或幹别的去了​

​,但老闆會時不時看下手機有沒有回複(定時輪詢)。

Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)

​中國精神科醫學研究院主任​

面試題3:怎麼了解并發和并行

  • 你吃飯吃到一半,電話來了,你一直到吃完了以後才去接,這就說明你​

    ​不支援并發也不支援并行​

  • 你吃飯吃到一半,電話來了,你停了下來接了電話,然後一手筷子,一手電話,說一句話,咽一口飯。這說明你​

    ​支援并發​

  • 你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,咽一口飯同時說一句話,這說明你​

    ​支援并行​

    ​。但這光靠一張嘴是辦不到的,至少兩張嘴!

并發的關鍵是:你有處理多個任務的能力,不一定要同時。

并行的關鍵是:你有同時處理多個任務的能力。

是以我認為它們最關鍵的點就是:是否​

​同時​

Java崗大廠面試百日沖刺【Day45】— 實戰那些事兒 (日積月累,每日三題)

并發 - 一起執行

并行 - 同時執行

每日小結