Java常見面試真題之中級進階(List篇)

码路编程發表於2024-10-28

前言

本來想著給自己放鬆一下,刷刷部落格,突然被幾道面試題難倒!獲取一個類Class物件的方式有哪些?ArrayList 和 LinkedList 的區別有哪些?用過 ArrayList 嗎?說一下它有什麼特點?有陣列了為什麼還要搞個 ArrayList 呢?說說什麼是 fail-fast?似乎有點模糊了,那就大概看一下Java基礎面試題吧。好記性不如爛鍵盤

*** 12萬字的java面試題整理 ***

獲取一個類Class物件的方式有哪些

搞清楚類物件和例項物件,但都是物件。
第一種:透過類物件的 getClass() 方法獲取,細心點的都知道,這個 getClass 是 Object 類裡面的方法。

User user=new User();
//clazz就是一個User的類物件
Class<?> clazz=user.getClass();

第二種:透過類的靜態成員表示,每個類都有隱含的靜態成員 class。

//clazz就是一個User的類物件
Class<?> clazz=User.class;

第三種:透過 Class 類的靜態方法 forName() 方法獲取。

Class<?> clazz = Class.forName("com.tian.User");

ArrayList 和 LinkedList 的區別有哪些?

ArrayList

  • 優點:ArrayList 是實現了基於動態陣列的資料結構,因為地址連續,一旦資料儲存好了,查詢操作效率會比較高(在記憶體裡是連著放的)。
  • 缺點:因為地址連續,ArrayList 要移動資料,所以插入和刪除操作效率比較低。

LinkedList

  • 優點:LinkedList 基於連結串列的資料結構,地址是任意的,所以在開闢記憶體空間的時候不需要等一個連續的地址。對於新增和刪除操作,LinkedList 比較佔優勢。LinkedList 適用於要頭尾操作或插入指定位置的場景。
  • 缺點:因為 LinkedList 要移動指標,所以查詢操作效能比較低。

適用場景分析

  • 當需要對資料進行對隨機訪問的時候,選用 ArrayList。
  • 當需要對資料進行多次增加刪除修改時,採用 LinkedList。

如果容量固定,並且只會新增到尾部,不會引起擴容,優先採用 ArrayList。
當然,絕大數業務的場景下,使用 ArrayList 就夠了,但需要注意避免 ArrayList 的擴容,以及非順序的插入。

用過 ArrayList 嗎?說一下它有什麼特點?

只要是搞 Java 的肯定都會回答“用過”。所以,回答題目的後半部分——ArrayList 的特點。可以從這幾個方面去回答:

Java 集合框架中的一種存放相同型別的元素資料,是一種變長的集合類,基於定長陣列實現,當加入資料達到一定程度後,會實行自動擴容,即擴大陣列大小。

底層是使用陣列實現,新增元素。

  • 如果 add(o),新增到的是陣列的尾部,如果要增加的資料量很大,應該使用 ensureCapacity()方法,該方法的作用是預先設定 ArrayList 的大小,這樣可以大大提高初始化速度。
  • 如果使用 add(int,o),新增到某個位置,那麼可能會挪動大量的陣列元素,並且可能會觸發擴容機制。

高併發的情況下,執行緒不安全。多個執行緒同時操作 ArrayList,會引發不可預知的異常或錯誤。
ArrayList 實現了 Cloneable 介面,標識著它可以被複制。注意:ArrayList 裡面的 clone() 複製其實是淺複製。

有陣列了為什麼還要搞個 ArrayList 呢?

通常我們在使用的時候,如果在不明確要插入多少資料的情況下,普通陣列就很尷尬了,因為你不知道需要初始化陣列大小為多少,而 ArrayList 可以使用預設的大小,當元素個數到達一定程度後,會自動擴容。
可以這麼來理解:我們常說的陣列是定死的陣列,ArrayList 卻是動態陣列。

說說什麼是 fail-fast?

ail-fast 機制是 Java 集合(Collection)中的一種錯誤機制。當多個執行緒對同一個集合的內容進行操作時,就可能會產生 fail-fast 事件。

例如:當某一個執行緒 A 透過 iterator 去遍歷某集合的過程中,若該集合的內容被其他執行緒所改變了,那麼執行緒 A 訪問集合時,就會丟擲 ConcurrentModificationException 異常,產生 fail-fast 事件。這裡的操作主要是指 add、remove 和 clear,對集合元素個數進行修改。
解決辦法:建議使用“java.util.concurrent 包下的類”去取代“java.util 包下的類”。
可以這麼理解:在遍歷之前,把 modCount 記下來expectModCount,後面 expectModCount 去和 modCount 進行比較,如果不相等了,證明已併發了,被修改了,於是丟擲ConcurrentModificationException 異常。

相關文章