Java社招面試題

      網友投稿 780 2025-03-31

      文章目錄

      StringBuffer 和 StringBuilder 的區別

      一般的有死鎖怎么形成的,怎么解決死鎖

      HashMap,ConcurrentHashMap,LinkedHashMap的區別

      synchronized 和 ReentrantLock 的異同

      SpringMVC的運行原理

      分布式鎖怎么實現

      BIO 和 NIO區別

      new 一個對象,JVM 里面都干了啥

      volatile 關鍵字

      Synchronized 關鍵字在 1.6 做了哪些優化

      AQS和CAS

      StringBuffer 和 StringBuilder 的區別

      可變性。String 不可變,StringBuilder 與 StringBuffer 是可變的。

      String 類中使用只讀字符數組保存字符串,private?final?char?value [],所以是不可變的(Java 9 中底層把 char 數組換成了 byte 數組,占用更少的空間)。

      StringBuilder 與 StringBuffer 都繼承自 AbstractStringBuilder 類,在 AbstractStringBuilder 中也是使用字符數組保存字符串,char [] value,這兩種對象都是可變的。

      線程安全性。String 和 StringBuffer 是線程安全的,StringBuilder 是非線程安全的。

      String 線程安全是因為其對象是不可變的,StringBuffer 線程安全是因為對方法加了同步鎖或者對調用的方法加了同步鎖。

      StringBuilder并沒有對方法進行加同步鎖,所以是非線程安全的。

      性能。

      String 的性能較差,因為每次對 String 類型進行改變的時候,都會生成一個新的 String 對象,然后將指針指向新的 String 對象。

      而 StringBuffer/StringBuilder 性能更高,是因為每次都是對對象本身進行操作,而不是生成新的對象并改變對象引用。一般情況下 StringBuilder 相比 StringBuffer 可獲得 10%~15% 左右的性能提升。

      點評:

      如果要操作少量的數據用 String; 單線程操作字符串緩沖區下操作大量數據 StringBuilder; 多線程操作字符串緩沖區下操作大量數據 StringBuffer;

      一般的有死鎖怎么形成的,怎么解決死鎖

      什么是線程死鎖?

      死鎖是指兩個或兩個以上的進程(線程)在執行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處于死鎖狀態或系統產生了死鎖。

      死鎖產生的條件是什么?

      (1) 互斥條件:該資源任意一個時刻只由一個線程占用;

      (2) 請求與保持條件:一個線程 / 進程因請求資源而阻塞時,對已獲得的資源保持不放;

      (3) 不剝奪條件:線程 / 進程已獲得的資源在末使用完之前不能被其他線程 / 進程強行剝奪,只有自己使用完畢后才釋放資源;

      (4) 循環等待條件:若干線程 / 進程之間形成一種頭尾相接的循環等待資源關系。

      如何避免線程死鎖?

      針對死鎖產生的條件進行一一拆解:

      (1) 破壞互斥條件:無法破壞,因為使用鎖的本意就是想讓它們互斥的(臨界資源需要互斥訪問);

      (2) 破壞請求與保持條件:一次性申請所有的資源;

      (3) 破壞不剝奪條件:占用部分資源的線程進一步申請其他資源時,如果申請不到,可以主動釋放它占有的資源;

      (4) 破壞循環等待條件:按某一順序申請資源,釋放資源則反序釋放。破壞循環等待條件(最常用)。

      HashMap,ConcurrentHashMap,LinkedHashMap的區別

      1.HashMap 是線程不安全的,HashTable 是線程安全的。 2.HashMap 的鍵需要重新計算對象的 hash 值,而 HashTable 直接使用對象的 hashCode。 3.HashMap 的值和鍵都可以為 null,HashTable 的值和鍵都不能為 null。 4.HashMap 的數組的默認初始化大小為 16,HashTable 為 11;HashMap 擴容時會擴大兩倍,HashTable 擴大兩倍 + 1;

      1

      2

      3

      4

      LinkedHashMap維護一個雙鏈表,可以將里面的數據按寫入的順序讀出

      基礎特性不同:

      HashMap 的 key 和 value 可以為 null,ConcurrentHashMap 的 key 和 value 不能為 null。

      內部數據結構不同:

      HashMap 在 JDK1.7 中采用的數據結構是數組 + 鏈表,在 JDK1.8 中采用的數據結構是數組 + 鏈表 / 紅黑二叉樹;

      ConcurrentHashMap 在 JDK1.7 中采用的數據結構是分段的數組 + 鏈表,JDK1.8 的內部數據結構采用的數據結構是數組 + 鏈表 / 紅黑二叉樹(同 HashMap 一致)。

      線程安全不同:

      HashMap 是非線程安全的;

      ConcurrentHashMap 是線程安全的;

      ConcurrentHashMap

      JDK1.7 中,ConcurrentHashMap 采用 HashEntry+Segment的結構,ConcurrentHashMap 里一共 16個 Segment,Segment 是可重入鎖ReentrantLock的子類,每個 Segment 對應一個 HashEntry 鍵值對數組。當對 HashEntry 數組的數據進行修改時,必須首先獲得對應的 Segment 鎖,因此,多線程訪問容器里不同 Segment 的數據,就不會存在鎖競爭,從而提升并發性能。

      JDK1.8 中則摒棄了 Segment 的概念,并發控制使用 synchronized 和 CAS 來操作,雖然在 JDK1.8 中還能看到 Segment 的數據結構,但是已經簡化了屬性,只是為了兼容舊版本。來看看核心的 put 方法。

      補充

      Java社招面試題

      CAS原子語義來處理加減等操作,CAS 全稱Compare And Swap(比較與交換),通過判斷內存某個位置的值是否與預期值相等,如果相等則進行值更新。CAS 是內部是通過 Unsafe類實現,而 Unsafe 類的方法都是native的,在 JNI里是借助于一個 CPU 指令完成的,屬于原子操作。

      synchronized 和 ReentrantLock 的異同

      1. 相同點:Lock 能完成 synchronized 所實現的所有功能;

      2. 不同點:Lock 有比 synchronized 更精確的線程語義和更好的性能,而且不強制性的要求一定要獲得鎖。synchronized 會自動釋放鎖,而 Lock 則要求手工釋放。更具體地來說,有以下差異:

      (1) 含義不同

      Synchronized 是關鍵字,屬于 JVM 層面,底層是通過 monitorenter 和 monitorexit 完成,依賴于 monitor 對象來完成;

      Lock 是 java.util.concurrent.locks.lock 包下的,是 JDK1.5 以后引入的新API 層面的鎖;

      (2) 使用方法不同

      Synchronized 不需要用戶手動釋放鎖,代碼完成之后系統自動讓線程釋放鎖;ReentrantLock 需要用戶手動釋放鎖,沒有手動釋放可能導致死鎖;

      (3) 等待是否可以中斷

      Synchronized 不可中斷,除非拋出異常或者正常運行完成;

      ReentrantLock 可以中斷。

      一種是通過 tryLock(long timeout, TimeUnit unit),

      另一種是lockInterruptibly ()放代碼塊中,調用interrupt ()方法進行中斷;

      (4) 加鎖是否公平

      Synchronized 是非公平鎖;

      ReentrantLock 默認非公平鎖,

      可以在構造方法傳入 boolean 值,true 代表公平鎖,false 代表非公平鎖;

      SpringMVC的運行原理

      分布式鎖怎么實現

      CAP理論

      即滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)

      1.基于數據庫。

      基于數據庫的實現方式的核心思想是:在數據庫中創建一個表,表中包含方法名等字段,并在方法名字段上創建唯一索引,想要執行某個方法,就使用這個方法名向表中插入數據,成功插入則獲取鎖,執行完成后刪除對應的行數據釋放鎖。

      2.基于緩存環境,redis,memcache等。

      (1)獲取鎖的時候,使用setnx加鎖,并使用expire命令為鎖添加一個超時時間,超過該時間則自動釋放鎖,鎖的value值為一個隨機生成的UUID,通過此在釋放鎖的時候進行判斷。

      (2)獲取鎖的時候還設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。

      (3)釋放鎖的時候,通過UUID判斷是不是該鎖,若是該鎖,則執行delete進行鎖釋放。

      3.基于zookeeper。

      (1)創建一個目錄mylock;

      (2)線程A想獲取鎖就在mylock目錄下創建臨時順序節點;

      (3)獲取mylock目錄下所有的子節點,然后獲取比自己小的兄弟節點,如果不存在,則說明當前線程順序號最小,獲得鎖;

      (4)線程B獲取所有節點,判斷自己不是最小節點,設置監聽比自己次小的節點;

      (5)線程A處理完,刪除自己的節點,線程B監聽到變更事件,判斷自己是不是最小的節點,如果是則獲得鎖。

      BIO 和 NIO區別

      BIO(Blocking IO)阻塞IO

      NIO(Non-Blocking IO)非阻塞IO

      共同點:兩者都是同步操作。即必須先進行IO操作后才能進行下一步操作。

      不同點:

      BIO多線程對某資源進行IO操作時會出現阻塞,即一個線程進行IO操作完才會通知另外的IO操作線程,必須等待。

      NIO多線程對某資源進行IO操作時會把資源先操作至內存緩沖區。然后詢問是否IO操作就緒,是則進行IO操作,否則進行下一步操作,然后不斷的輪詢是否IO操作就緒,直到iIO操作就緒后進行相關操作。

      new 一個對象,JVM 里面都干了啥

      先是加載,驗證,準備,解析,初始化

      volatile 關鍵字

      從原子性,可見性,指令重排三個方面說了

      1.保證可見性:線程之間可見性(及時通知)

      2.不保證原子性

      3.禁止指令重排

      Synchronized 關鍵字在 1.6 做了哪些優化

      從鎖消除,鎖粗化,偏向鎖,輕量級鎖,重量級鎖解鎖了一遍。

      1.適應自旋鎖:為了減少線程狀態改變帶來的消耗 不停地執行當前線程

      2.鎖消除:不可能存在共享數據競爭的鎖進行消除

      3.鎖粗化: 將連續的加鎖 精簡到只加一次鎖

      4.輕量級鎖: 無競爭條件下 通過CAS消除同步互斥

      5.偏向鎖:無競爭條件下 消除整個同步互斥,連CAS都不操作。

      AQS和CAS

      CAS

      CAS(Compare And Swap),即比較并交換。是解決多線程并行情況下使用鎖造成性能損耗的一種機制, CAS操作包含三個操作數—— 內存位置(V)、預期原值(A)和新值(B)。 如果 內存位置的值與預期原值相匹配,那么處理器會自動將該位置值更新為新值。否則,處理器不做任何操作。 無論哪種情況,它都會在CAS指令之前返回該位置的值。CAS有效地說明了“

      我認為位置V應該包含值A;如果包含該值,則將B放到這個位置;否則,不要更改該位置,只告訴我這個位置現在的值即可。

      AQS

      AQS 的原理

      抽象隊列同步器

      AQS(AbstractQueuedSynchronizer)核心思想是,如果被請求的資源空閑,則將當前請求資源的線程設置為有效的工作線程,并且將共享資源設置為鎖定狀態;如果被請求的資源被占用,則需要一套線程阻塞等待以及喚醒分配的機制,該機制基于一個 FIFO(先進先出)的等待隊列實現。

      AQS 的應用

      作為一個用來構建鎖和同步器的框架,AQS 能簡單且高效地構造出大量同步器,事實上 java.util.concurrent.concurrent 包內許多并發類都是基于 AQS 構建。這些同步器從資源共享方式的方式來看,可以分為兩類:

      (1)Exclusive(獨占):只有一個線程能執行,如 ReentrantLock。又可分為公平鎖和非公平鎖:

      A、公平鎖:按照線程在隊列中的排隊順序,先到者先拿到鎖;

      B、非公平鎖:當線程要獲取鎖時,無視隊列順序直接去搶鎖,誰搶到就是誰的。

      (2) Share(共享):多個線程可同時執行,如 Semaphore/CountDownLatch/CyclicBarrier 等。

      此外,也可以通過 AQS 來自定義同步器,自定義同步器在實現時只需要實現共享資源 state 的獲取與釋放方式即可,至于具體線程等待隊列的維護(如獲取資源失敗入隊 / 喚醒出隊等),AQS 已經在頂層實現好了。

      Java 任務調度 容器

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel表格中怎么制作帶標記的堆積折線圖表?
      下一篇:行距在哪兒(行距指什么)
      相關文章
      亚洲综合另类小说色区| 亚洲色欲色欲www| 狠狠色香婷婷久久亚洲精品| 婷婷精品国产亚洲AV麻豆不片| 国产亚洲美日韩AV中文字幕无码成人 | 亚洲一级高清在线中文字幕| 亚洲黄色网址大全| 亚洲一级二级三级不卡| 亚洲人成依人成综合网| 亚洲成在人天堂在线| 久久精品国产精品亚洲蜜月| 亚洲AV无码一区二区三区系列| 亚洲国产精品无码成人片久久| 国产亚洲av片在线观看播放| 亚洲精品蜜桃久久久久久| 国产成人亚洲综合无码精品| 国外亚洲成AV人片在线观看| 国产亚洲精久久久久久无码77777 国产亚洲精品成人AA片新蒲金 | 亚洲av无码一区二区三区四区| 亚洲国产成人久久精品大牛影视 | 国产亚洲无线码一区二区| 亚洲精品国精品久久99热一| 亚洲AV无码成人精品区在线观看 | 亚洲AV色欲色欲WWW| 精品国产_亚洲人成在线| 天堂亚洲免费视频| 亚洲人成网站在线观看青青| 国产成人精品日本亚洲专区61 | 亚洲av日韩精品久久久久久a| 婷婷亚洲综合一区二区 | 亚洲免费黄色网址| 亚洲精品一二三区| 国产成人综合亚洲一区| 亚洲日韩国产精品乱| 亚洲欧洲自拍拍偷午夜色无码| 亚洲国产精品嫩草影院在线观看| 久久久久亚洲精品无码蜜桃| 亚洲最新在线视频| 一区二区亚洲精品精华液| 亚洲av无码无线在线观看| 亚洲A丁香五香天堂网|