求求大廠給個Offer:List面試題

前言

只有光頭才能變強。

文本已收錄至個人GitHub精選文章,歡迎Starhttps://github.com/ZhongFuCheng3y/3yjava

從今天開始,我,三歪,正式開始寫面試系列。我給這個面試系列取了一個名字,叫作《求求大廠給個Offer》git

上一篇就叫作《求求大廠給個Offer:如何寫簡歷》github

因此這篇文章叫作《求求大廠給個Offer:List面試題面試

接下來就開始吧。算法

本文有配套的視頻觀看:https://www.bilibili.com/video/BV1nT4y1L71r/ 歡迎三連後端

面試現場

面試官:「你簡單自我介紹一下吧」數組

三歪:「我叫三歪,目前維護一個公衆號叫作Java3y,這幾年寫了300+原創技術文章,近1000頁的原創電子書和多個知識點的思惟導圖。個人願景是:只要關注我並三連的同窗均可以拿到大廠offer。個人....」安全

面試官:「停停停,別吹了,咱們正式開始吧。」微信

面試官:「來說講Java的List吧,你對List瞭解多少?」數據結構

三歪:「List在Java裏邊是一個接口,常見的實現類有ArrayList和LinkedList,在開發中用得最多的是ArrayList」

面試官:「你再分別來說講ArrayList和LinkedList的區別唄」

三歪:「ArrayList的底層數據結構是數組,LinkedList底層數據結構是鏈表。」

面試官:「那咱們自己就有數組了,爲何要用ArrayList呢?」

三歪:「原生的數組會有一個特色:你在使用的時候必需要爲它建立大小,而ArrayList不用」

面試官:「那你說說ArrayList是怎麼實現的吧,爲何ArrayList就不用建立大小呢?」

三歪:「實際上是這樣的,我看過源碼。當咱們new ArrayList()的時候,默認會有一個空的Object數組,大小爲0。當咱們第一次add添加數據的時候,會給這個數組初始化一個大小,這個大小默認值爲10」

面試官:「嗯」

三歪:「還有就是,數組的大小是固定的,而ArrayList的大小是可變的」

面試官:「那怎麼理解固定和可變的呢?你說說看」

三歪:「假設咱們給定數組的大小是10,要往這個數組裏邊填充元素,咱們只能添加10個元素。而ArrayList不同,ArrayList咱們在使用的時候能夠往裏邊添加20個,30個,甚至更多的元素」

三歪:「由於ArrayList是實現了動態擴容的」

面試官:「那它是怎麼實現的呢?」

三歪:「使用ArrayList在每一次add的時候,它都會先去計算這個數組夠不夠空間,若是空間是夠的,那直接追加上去就行了。若是不夠,那就得擴容」

面試官:「那怎麼擴容?一次擴多少?」

三歪:「在源碼裏邊,有個grow方法,每一次擴原來的1.5倍。好比說,初始化的值是10嘛。如今我第11個元素要進來了,發現這個數組的空間不夠了,因此會擴到15」

三歪:「空間擴完容以後,會調用arraycopy來對數組進行拷貝」

面試官:「哦,能夠的。那爲何你在前面提到,在平常開發中用得最多的是ArrayList呢?」

三歪:「是由底層的數據結構來決定的,在平常開發中,遍歷的需求比增刪要多,即使是增刪也是每每在List的尾部添加就OK了。像在尾部添加元素,ArrayList的時間複雜度也就O(1)

三歪:「另外的是,ArrayList的增刪底層調用的copyOf()被優化過,現代CPU對內存能夠塊操做,ArrayList的增刪一點兒也不會比LinkedList慢」

面試官:「Vector你瞭解嗎?」

三歪:「嗯,Vector是底層結構是數組,通常如今咱們已經不多用了。相對於ArrayList,它是線程安全的,在擴容的時候它是直接擴容兩倍的,好比如今有10個元素,要擴容的時候,就會將數組的大小增加到20」

面試官:「嗯,那若是咱們不用Vector,線程安全的List還有什麼?」

三歪:「首先,咱們也能夠用Collections來將ArrayList來包裝一下,變成線程安全。但這確定不是你想聽的,對吧。在java.util.concurrent包下還有一個類,叫作CopyOnWriteArrayList」

面試官:「嗯,你繼續說」

三歪:「要講CopyOnWriteArrayList以前,我仍是想說說copy-on-write這個意思,下面我會簡稱爲cow。好比說在Linux中,咱們知道全部的進程都是init進程fork出來的,除了進程號以外,fork出來的進程,默認跟父進程如出一轍的。在fork以後exec以前,兩個進程用的是相同的內存空間的,這意味着子進程的代碼段、數據段、堆棧都是指向父進程的物理空間」

面試官:「嗯」

三歪:「當父子進程中有更改的行爲發生時,再爲子進程分配相應物理空間。這樣作的好處就是,等到真正發生修改的時候,纔去分配資源,能夠減小分配或者複製大量資源時帶來的瞬間延時。簡單來講,就能夠理解爲咱們的懶加載,或者說單例模式的懶漢式。等真正用到的時候再分配」

面試官:「嗯」

三歪:「在文件系統中,其實也有cow的機制。文件系統的cow就是在修改數據的時候,不會直接在原來的數據位置上進行操做,而是從新找個位置修改。好比說:要修改數據塊A的內容,先把A讀出來,寫到B塊裏面去。若是這時候斷電了,原來A的內容還在。這樣作的好處就是能夠保證數據的完整性,瞬間掛掉了容易恢復

三歪:「再回頭來看CopyOnWriteArrayList吧,CopyOnWriteArrayList是一個線程安全的List,底層是經過複製數組的方式來實現的。

三歪:「我來講說它 的add()方法的實現吧」

面試官:「好」

三歪:「在add()方法其實他會加lock鎖,而後會複製出一個新的數組,往新的數組裏邊add真正的元素,最後把array的指向改變爲新的數組」

三歪:「其實get()方法又或是size()方法只是獲取array所指向的數組的元素或者大小。讀不加鎖,寫加鎖」

三歪:「能夠發現的是,CopyOnWriteArrayList跟文件系統的COW機制是很像的」

面試官:「那你能說說CopyOnWriteArrayList有什麼缺點嗎?」

三歪:「很顯然,CopyOnWriteArrayList是很耗費內存的,每次set()/add()都會複製一個數組出來,另外就是CopyOnWriteArrayList只能保證數據的最終一致性,不能保證數據的實時一致性。假設兩個線程,線程A去讀取CopyOnWriteArrayList的數據,還沒讀完,如今線程B把這個List給清空了,線程A此時仍是能夠把剩餘的數據給讀出來。」

面試官:「嗯,還能夠,今天的面試就到這裏結束了,你有什麼想問個人嗎?」

三歪:「你以爲我今天的表現怎麼樣?」

面試官:「今天的表現還能夠,若是這一次你沒有100個點贊,估計HR就不會再聯繫你了。若是超過100個點贊,第二輪好好表現吧。」

面試官:「給你透露一下,Map集合能夠好好準備一下,下一輪將會考察Map的知識」

題外話

List集合整體來講不會太難,但CopyOnWriteArrayList可能不少同窗還不知道有這麼一個類。

針對此次的面試可能你想了解更多List的細節,好比說ArrayList/LinkedList/CopyOnWriteArrayList的源碼以及上面提到的COW機制,能夠在公衆號下回復「List」便可獲取我以前寫的原創文章。

須要預習或者領取電子書的同窗,在公衆號下回復「888」便可獲取。

本文有配套的視頻觀看:https://www.bilibili.com/video/BV1nT4y1L71r/ 歡迎三連

各種知識點總結

下面的文章都有對應的 原創精美PDF,在持續更新中,能夠來找我催更~

涵蓋Java後端全部知識點的開源項目(已有10K+ star):

若是你們想要實時關注我更新的文章以及分享的乾貨的話,微信搜索Java3y

PDF文檔的內容均爲手打,有任何的不懂均可以直接來問我(公衆號有個人聯繫方式)。

我是三歪,一個想要變強的男人,感謝你們的點贊收藏和轉發,下期見。給三歪點個贊,對三歪真的很是重要!

相關文章
相關標籤/搜索