Android&Java面試題大全—金九銀十面試必備【上】
喜歡或者覺得有用的小夥伴可以收藏下喲
想要更多相關資料的話可以私聊【面試】領取喲!
類載入過程
Java 中類載入分為 3 個步驟:載入、連結、初始化。
1.載入。
載入是將位元組碼資料從不同的資料來源讀取到JVM記憶體,並對映為 JVM 認可的資料結構,也就是 Class 物件的過程。資料來源可以是 Jar 檔案、Class 檔案等等。如果資料的格式並不是 ClassFile 的結構,則會報 ClassFormatError。
2.連結。
連結是類載入的核心部分,這一步分為 3 個步驟:驗證、準備、解析。
驗證。 驗證是保證JVM安全的重要步驟。JVM需要校驗位元組資訊是否符合規範,避免惡意資訊和不規範資料危害JVM執行安全。如果驗證出錯,則會報VerifyError。
準備。 這一步會建立靜態變數,併為靜態變數開闢記憶體空間。
解析。 這一步會將符號引用替換為直接引用
3.初始化。
初始化會為靜態變數賦值,並執行靜態程式碼塊中的邏輯。
雙親委派模型
類載入器大致分為3類:啟動類載入器、擴充套件類載入器、應用程式類載入器。
1.啟動類載入器主要載入 jre/lib下的jar檔案。
2.擴充套件類載入器主要載入 jre/lib/ext 下的jar檔案。
3.應用程式類載入器主要載入 classpath 下的檔案
所謂的雙親委派模型就是當載入一個類時,會優先使用父類載入器載入,當父類載入器無法載入時才會使用子類載入器去載入。這麼做的目的是為了避免類的重複載入。
Java 中的集合類
HashMap 的原理
HashMap 的內部可以看做陣列+連結串列的複合結構。陣列被分為一個個的桶(bucket)。雜湊值決定了鍵值對在陣列中的定址。具有相同雜湊值的鍵值對會組成連結串列。需要注意的是當連結串列長度超過閾值(預設是8)的時候會觸發樹化,連結串列會變成樹形結構。
把握HashMap的原理需要關注4個方法:hash、put、get、resize。
1.hash方法。
將 key 的 hashCode 值的高位資料移位到低位進行異或運算。這麼做的原因是有些 key 的 hashCode 值的差異集中在高位,而雜湊定址是忽略容量以上高位的,這種做法可以有效避免雜湊衝突。
2.put 方法。
put 方法主要有以下幾個步驟
①通過 hash 方法獲取 hash 值,根據 hash 值定址
②如果未發生碰撞,直接放到桶中。
③如果發生碰撞,則以連結串列形式放在桶後
④當連結串列長度大於閾值後會觸發樹化,將連結串列轉換為紅黑樹。
⑤如果陣列長度達到閾值,會呼叫 resize 方法擴充套件容量。
3.get方法。
get 方法主要有以下幾個步驟:
①通過 hash 方法獲取 hash 值,根據 hash 值定址。
②如果與定址到桶的 key 相等,直接返回對應的 value
③如果發生衝突,分兩種情況。如果是樹,則呼叫 getTreeNode 獲取 value;如果是連結串列則通過迴圈遍歷查詢對應的 value。
4.resize 方法。 resize 做了兩件事:
①將原陣列擴充套件為原來的 2 倍
②重新計算 index 索引值,將原節點重新放到新的陣列中。這一步可以將原先衝突的節點分散到新的桶中
sleep 和 wait 的區別
①sleep 方法是 Thread 類中的靜態方法,wait 是 Object 類中的方法
②sleep 並不會釋放同步鎖,而 wait 會釋放同步鎖
③sleep 可以在任何地方使用,而 wait 只能在同步方法或者同步程式碼塊中使用
④sleep 中必須傳入時間,而 wait 可以傳,也可以不傳,不傳時間的話只有 notify 或者 notifyAll - 才能喚醒,傳時間的話在時間之後會自動喚醒
volatile和synchronize的區別
把握HashMap的原理需要關注4個方法:hash、put、get、resize。
1.hash方法。
將 key 的 hashCode 值的高位資料移位到低位進行異或運算。這麼做的原因是有些 key 的 hashCode 值的差異集中在高位,而雜湊定址是忽略容量以上高位的,這種做法可以有效避免雜湊衝突。
2.put 方法。
put 方法主要有以下幾個步驟:
①通過 hash 方法獲取 hash 值,根據 hash 值定址。
②如果未發生碰撞,直接放到桶中。
③如果發生碰撞,則以連結串列形式放在桶後。
④當連結串列長度大於閾值後會觸發樹化,將連結串列轉換為紅黑樹。
⑤如果陣列長度達到閾值,會呼叫 resize 方法擴充套件容量
3.get方法。
get 方法主要有以下幾個步驟:
①通過 hash 方法獲取 hash 值,根據 hash 值定址。
②如果與定址到桶的 key 相等,直接返回對應的 value。
③如果發生衝突,分兩種情況。如果是樹,則呼叫 getTreeNode 獲取 value;如果是連結串列則通過迴圈遍歷查詢對應的 value。
4.resize 方法。 resize 做了兩件事:
①將原陣列擴充套件為原來的 2 倍
②重新計算 index 索引值,將原節點重新放到新的陣列中。這一步可以將原先衝突的節點分散到新的桶中。
sleep 和 wait 的區別
①sleep 方法是 Thread 類中的靜態方法,wait 是 Object 類中的方法
②sleep 並不會釋放同步鎖,而 wait 會釋放同步鎖
③sleep 可以在任何地方使用,而 wait 只能在同步方法或者同步程式碼塊中使用
④sleep 中必須傳入時間,而 wait 可以傳,也可以不傳,不傳時間的話只有 notify 或者 notifyAll - 才能喚醒,傳時間的話在時間之後會自動喚醒
volatile和synchronize的區別
final、finally、finalize區別
①final 可以修飾類、變數和方法。修飾類代表這個類不可被繼承。修飾變數代表此變數不可被改變。修飾方法表示此方法不可被重寫 (override)。
②finally 是保證重點程式碼一定會執行的一種機制。通常是使用 try-finally 或者 try-catch-finally 來進行檔案流的關閉等操作
③finalize 是 Object 類中的一個方法,它的設計目的是保證物件在垃圾收集前完成特定資源的回收。finalize 機制現在已經不推薦使用,並且在 JDK 9已經被標記為 deprecated。
文字限制問題今天先更到這裡,想獲取下篇請【關注私信】