国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

面試官問你數(shù)組和ArrayList怎么答?

寵來也 / 638人閱讀

摘要:在反射方面來說,從運行時返回一個的實例時不需要經(jīng)過強制轉換然后則需要經(jīng)過轉換才能得到。如果對數(shù)據(jù)的數(shù)量大小已知,操作也非常簡單,也不需要中的大部分方法,也是可以直接使用數(shù)組的。

我在想每個人在面試的時候都會被問到集合相關的問題,有好大一部分人在回答的時候并沒有那么多的邏輯性,通常都是想到哪里說到哪里,這篇文章大概的捋一捋關于集合的相關問題。
在每種編程語言中,都會有循環(huán)、數(shù)組、流程控制語句,數(shù)組是一種線性表數(shù)據(jù)結構,內(nèi)存空間是連續(xù)的,保存的數(shù)據(jù)類型也是一致的。

正是因為這兩點,數(shù)組的隨機訪問才會非常的高效,這同時也是一把雙刃劍,使得數(shù)組的其他操作效率變得很低,比如說,增加,刪除,為了保持數(shù)組里面數(shù)據(jù)的連續(xù)性,就會做大量的消耗性能的數(shù)據(jù)遷移操作。

針對數(shù)組這種類型,java中有容器類,比如ArrayList,ArrayList是對數(shù)組的包裝,在底層就是數(shù)組實現(xiàn)的,因為數(shù)組在定義的時候必須是指定的長度,定義之后就無法再增加長度了,就是說不可能在原來的數(shù)組上接上一段,所以ArrayList就解決了這個問題,當超過數(shù)組容量的時候,ArrayList會進行擴容,擴容之后的容量是之前的1.5倍,然后再把之前數(shù)組中的數(shù)據(jù)復制過來。

接下來,我們看下ArrayList的源碼:

 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

源碼中數(shù)組最大的容量是Integer.MAX_VALUE -8,為什么要減去8 呢,這個是上面的定義上面的注釋:

 /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */

首先是一些VM在數(shù)組中保存的頭信息;嘗試著去分配更大的數(shù)組可能會導致OutOfMemoryError,請求的數(shù)組大小超過了VM的限制。

在看這句代碼的時候,腦中有沒有出現(xiàn)兩個大大的問號??
首先,有沒有想到為什么這個數(shù)組屬性需要用 transient修飾?
(想知道這個關鍵字是干什么的,可以看下我之前的一篇文章:面試問你java中的序列化怎么答?)

transient Object[] elementData; // non-private to simplify nested class access

大家可以隨便的想一下,如果是面試的時候,你會怎么回答?

由于 ArrayList 是基于動態(tài)數(shù)組實現(xiàn)的,所以并不是所有的空間都被使用。因此使用了 transient 修飾,可以防止被自動序列化。

因此 ArrayList 自定義了序列化與反序列化,具體可以看 writeObject 和 readObject 兩個方法。

需要注意的一點是,當對象中自定義了 writeObject 和 readObject 方法時,JVM 會調(diào)用這兩個自定義方法來實現(xiàn)序列化與反序列化。

第二個問題:這個屬性的類型為什么是Object而不是泛型?

這里和大家說下:

java中泛型運用的目的就是對象的重用,就是同一個方法,可以支持多種對象類型,Object和泛型在編寫的時候其實沒有太大的區(qū)別,只是JVM中沒有T這個概念,T只是存在編寫的時候,進入虛擬機運行的時候,虛擬機會對這種泛型標志進行擦除,也就是替換T到指定的類型,如果沒有指定類型,就會用Object替換,同時Object可以new Object(),就是說可以實例化,而T則不能實例化。在反射方面來說,從運行時,返回一個T的實例時,不需要經(jīng)過強制轉換,然后Object則需要經(jīng)過轉換才能得到。

當我們試圖向ArrayList中添加一個元素的時候,java會自動檢查,以確保集合中確實還有容量來添加新元素,如果沒有,就會自動擴容,下面是核心代碼,我已經(jīng)在代碼里加了注釋,幫助大家能夠更好的理解:

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

上面這段代碼中有個 變量 modCount++,看到這里的時候確實有些疑惑,我找了下,這個變量是在AbstractList中定義的protected修飾的全局變量,這個變量是記錄了結構性改變的次數(shù),結構性改變就是說修改列表大小的操作。
ArrayList是一個線程不安全的類,這個變量就是用來保證在多線程環(huán)境下使用迭代器的時候,同時又對集合進行了修改,同一時刻只能有一個線程修改集合,如果多于一個,就會拋出ConcurrentModficationException。

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //核心的擴容代碼:擴容之后的容量,
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)  //擴容之后的容量與本次操作需要的容量對比,取更大的
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0) //在與數(shù)組的最大容量對比,如果比最大的容量大,進入下一個方法
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    //接下來,是把原數(shù)組d 數(shù)據(jù)復制到新的數(shù)組里
    elementData = Arrays.copyOf(elementData, newCapacity);
}

    private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
        //當 Integer-8 依然無法滿足需求,就會取Integer的最大值
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

接下來我們看下,向指定位置添加元素是什么樣的:

public void add(int index, E element) {
    rangeCheckForAdd(index);
    //擴容校驗
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

可以看到,當一個集合足夠大的時候,add操作向數(shù)組的尾部添加元素效率還是非常高的,但是當向指定的位置添加元素的時候,也是需要大量的移動復制操作:System.arraycopy()。

到這里,ArrayList最大的優(yōu)勢是什么呢?我們在平時的開發(fā)中涉及到容器的時候為什么會選擇List家族的成員,而不直接選擇數(shù)組呢?大家回想一下自己之前敲代碼的經(jīng)歷,答案也就出來了:

ArrayList封裝了大部分數(shù)組的操作方法,比如插入、刪除、搬移數(shù)據(jù)等等,都在集合內(nèi)部幫你做好了,還有就是支持動態(tài)擴容,這點是數(shù)組不能比擬的。

這里需要注意一點,當我們在開始定義集合的時候,如果知道我們需要多大的集合,就應該在一開始就指定集合的大小,因為在集合的內(nèi)部來進行數(shù)據(jù)的搬移,復制也是非常耗時的。

那么數(shù)組在什么時候會用到呢?
1、java ArrayList無法存儲基本類型,int,long,如果保存的話,就需要封裝為Integer、Long,而自動的拆裝箱,也有性能的消耗,所以總結下這點就是說如果要保存基本類型,同時還特別關注性能,就可以使用數(shù)組。
2、如果對數(shù)據(jù)的數(shù)量大小已知,操作也非常簡單,也不需要ArrayList中的大部分方法,也是可以直接使用數(shù)組的。

如果對本文有任何異議,可以加我好友(有沒有問題都歡迎大家加我好友),也可以在下面留言區(qū)留言,我會及時修改。希望這篇文章能幫助大家在面試路上乘風破浪。

這樣的分享我會一直持續(xù),你的關注、轉發(fā)和好看是對我最大的支持,感謝。關注我,我們一起成長。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74151.html

相關文章

  • 前端秋招面試總結

    摘要:前言秋招宣告結束,面試了接近家公司,有幸拿到,感謝這段時間一起找工作面試的朋友和陪伴我的人。一定要提前準備好,不然面試官叫你說遇到的難點,或者直接問問題時可能會懵逼。 前言 秋招宣告結束,面試了接近20家公司,有幸拿到offer,感謝這段時間一起找工作面試的朋友和陪伴我的人。這是一段難忘的經(jīng)歷,相信不亞于當年的高考吧,也許現(xiàn)在想起來高考不算什么,也許只有經(jīng)歷過秋招的人才懂得找工作的艱辛...

    Gu_Yan 評論0 收藏0
  • 前端秋招面試總結

    摘要:前言秋招宣告結束,面試了接近家公司,有幸拿到,感謝這段時間一起找工作面試的朋友和陪伴我的人。一定要提前準備好,不然面試官叫你說遇到的難點,或者直接問問題時可能會懵逼。 前言 秋招宣告結束,面試了接近20家公司,有幸拿到offer,感謝這段時間一起找工作面試的朋友和陪伴我的人。這是一段難忘的經(jīng)歷,相信不亞于當年的高考吧,也許現(xiàn)在想起來高考不算什么,也許只有經(jīng)歷過秋招的人才懂得找工作的艱辛...

    Scholer 評論0 收藏0
  • 面試問你如何進行性能優(yōu)化時,你該這么回(一)

    摘要:背景在開發(fā)好頁面后,如何讓頁面更快更好的運行,是區(qū)分一個程序猿技術水平和視野的一個重要指標。在對這些環(huán)節(jié)進行優(yōu)化之前,我們需要知道如何監(jiān)控這些環(huán)節(jié)花費了多少時間。為了優(yōu)化鏈接的環(huán)節(jié),前端這里還需要對資源使用,雪碧圖,代碼合并等手段。 背景 在開發(fā)好頁面后,如何讓頁面更快更好的運行,是區(qū)分一個程序猿技術水平和視野的一個重要指標。所以面試時,面試官總會問你一個問題,如何進行性能優(yōu)化呢? 如...

    elisa.yang 評論0 收藏0
  • 簡歷上的項目經(jīng)歷怎么寫 ?這 3 條原則不可忽視 !

    摘要:正因為如此,現(xiàn)在很多簡歷上的項目經(jīng)歷的質量都是參差不齊,同時有的項目經(jīng)歷又非常相似,面試官一眼就能知道你的項目到底是真是假。雖然以上三點原則不能包治百病,但是對很多同學來說應該是蠻有益處的。閱讀本文大概需要 5 分鐘。作者:黃小斜showImg(https://user-gold-cdn.xitu.io/2019/3/30/169cdb4bd2cac24c);?作為一個程序員,想必大家曾經(jīng)都...

    fobnn 評論0 收藏0
  • 一個 16年畢業(yè)生所經(jīng)歷的 PHP 面試

    摘要:正確做法是給加索引,還有聯(lián)合索引,并不能避免全表掃描。 前言:有收獲的話請加顆小星星,沒有收獲的話可以 反對 沒有幫助 舉報三連 有心的同學應該會看到我這個noteBook下面的其它知識,希望對你們有些許幫助。 本文地址 時間點:2017-11 一個16年畢業(yè)生所經(jīng)歷的php面試 一、什么是面試 二、面試準備 1. 問:什么時候開始準備? 2. 問:怎么準備? 三、面試...

    dabai 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<