每日一面系列之ArrayList奪命連環問

1.ArrayList用過嗎?知道是幹什麼的嗎?有什麼特點?

ArrayList是用來存儲數據的一個集合,當我們存儲的數據類型是基本數據類型的時候,需要存儲他們的包裝類。ArrayList底層是Object數組實現的。它的特點是查詢效率高(根據元素下表可以直接訪問),增刪效率低(增刪元素需要對其他元素位置進行移動),線程不安全,使用頻率比較高。

2.爲什麼ArrayList線程不安全還要用?

因爲在日常的開發中,我們使用集合大多數情況是去做一些查詢,不會頻繁的進行增刪操作。如果需要做一些頻繁的增刪操作可以使用LinkedList,因爲它底層是使用雙向鏈表,所以增刪效率比較高。如果需要線程安全的集合,那麼可以使用Vector,因爲它的方法基本都是用了synchronized進行加鎖。目前還不存在一個完美的集合,查詢效率高,增刪效率也高而且還線程安全,這也是數據結構的特性所致,不能做到兼顧,只能找一個相對平衡的點,沒有絕對的好壞,具體使用情況還要看需求而定。

3.ArrayList底層是數組實現的,但是數組的長度大小是固定的,如果不斷的向裏面添加元素,會有什麼問題?

ArrayList可以通過構造方法初始化底層數組的大小。

通過無參構造方法創建的ArrayList底層數組默認大小爲空,會定義一個空的數組,直到通過add()方法添加元素的時候,纔會爲數組分配默認初始容量,大小爲10(DEFAULT_CAPACITY = 10)。如果是通過有參構造創建的ArrayList,底層數組大小初始值爲指定大小。

4.數組長度的大小是固定的,而ArrayList中卻可以存放任意數量的元素,它是怎麼實現的(擴容機制)?

因爲採用無參構造方法創建的ArrayList底層數組大小默認爲10,所以這裏我們就以數組大小10爲例,當我們新增元素的時候發現數組已經滿了,此時它會重新定義一個大小爲10+10/2(增加原來的0.5倍 ),如果是使用有參構造方法創建的,擴容也會根據指定大小進行擴容,規則是一樣的。

5.說一下ArrayList在1.7版本之前和之後初始化有什麼區別?

JDK1.7之前初始化時會調用this(10),是真正的初始化爲10,從1.7版本開始首先會默認初始化一個空的數組,直到調用add()方法添加元素的時候纔會將數組初始化大小變爲10。

6.爲什麼ArrayList底層數組默認初始化大小是10?

Sun公司的開發人員通過對大量程序代碼進行調研,發現10這個長度是最常用也是最有效率的,其實8、12等都可以。10看起來可能比較舒服吧!

7.你說ArrayList新增元素比較慢,爲什麼慢?新增元素的一個具體流程是什麼樣的?

在新增元素的時候,首先會對數組長度進行校驗,看是否需要擴容。之後就是複製數組中的元素,比如現在要在下標爲5的位置添加一個元素,那麼它會將從下標爲5的元素開始對元素進行復制,整體往後移動一位,然後將新元素添加到下標5的位置。下面以圖解方式說明一下:

原數組目前是這樣的:
在這裏插入圖片描述
如果要往下標爲5的位置添加一個新的元素,是這樣的:
在這裏插入圖片描述
然後將新元素插入下標爲5的位置,是這樣的:
在這裏插入圖片描述
至於它插入爲什麼慢,試想一下如果現在有成千上萬個元素,是不是你添加元素的下標位置開始往後的元素都要進行復制、移位?如果再需要擴容的話,那效率肯定會更慢。

8.ArrayList的插入刪除一定很慢嗎?

這取決於你插入或者刪除的元素的下標距離數組末端有多遠,ArrayList拿來作爲堆棧來用還是挺合適的,push和pop操作完全不涉及數據移動操作。

9.ArrayList中的刪除操作流程是怎麼樣的?

刪除和新增其實是一樣的,只是叫法不同而已,操作流程是一樣的,都會根據操作元素的下標位置對元素進行復制。

比如現在我們要刪除下標爲5的這個元素:
在這裏插入圖片描述
它會將下標爲6開始的元素進行復制,然後往前移動,替換原來下標爲5的元素:
在這裏插入圖片描述
所謂的刪除操作,其實就是覆蓋你所需要刪除的下標位置的元素。

10.如果我不想用Vertor,又想讓線程安全,怎麼辦?

用Collections.synchronizedList把一個普通ArrayList包裝成一個線程安全版本的數組容器也可以,原理同Vector是一樣的,就是給所有的方法套上一層synchronized。

11.ArrayList適合用來做隊列嗎?

我們都知道隊列的特點就是先進先出(FIFO),如果要讓ArrayList做到這樣,那麼插入元素和刪除元素,必須一個操作從頭部開始,一個操作從尾部開始。但是ArrayList插入和刪除操作都會牽扯到數據的移動遷移,這個是非常消耗性能的,效率還很低,所以它不適合做隊列。

12.比較一下ArrayList和LinkedList的遍歷效率。

就單論遍歷效率的話,ArrayList的效率肯定是高於LinkedList的。因爲ArrayList遍歷最大的優勢就是在於內存的連續性,CPU的內部緩存結構會緩存連續的內存片段,可以大幅度降低讀取內存的性能開銷。

13.你對未來的職業規劃是什麼樣的?

往專業方向靠攏,比如未來幾年發展成技術負責人,帶團隊,多少年之後成爲架構師,比較喜歡看一些技術類書籍來提升自己的能力等等。總之要讓HR覺得你這個人很上進還很好學!

每日面試小練習,日後面試大輕鬆!

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