【最新Android高級面試知識點乾貨分享(二)】

接上一篇

轉載請說明出處

四、Java集合(List、Set、Queue、Map)

Java集合體系是一個樹狀,如果按照類似OSI網絡模型來看的話,整個Java集合就是應用層,而底層的數組就是TCP/IP層。
而它也是全網各面試題中出現概率最高的。

對於集合,有幾個核心知識點是需要了解的:底層數據結構擴容機制效率線程案例等。
整個Java集合大致分爲兩類:Collection接口Map接口

下圖來源於網絡:
image

$4.1、 Collection接口:

繼承自Iteraor接口,因此其子類都擁有迭代器可以遍歷。collectin接口直接子類:List接口、Set接口、Queue接口。

List接口的子類有

  • ArrayList

      1、擴容機制:
          數組默認長度爲10,還有一個空的數組,當擴容時,如果數組長度比允許的最大長度大,則擴容至最大長度; 否則按照原數組的1.5倍擴容
    
/**    1.初始化時:默認容量爲10.
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
    //elementData爲Object[]:因此ArrayList底層是基於數組。
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

	/***
	*2. 往list中添加元素
	* 在裏面要判斷list的容量,如果不夠就做擴容處理。
	*/
	public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments 	modCount!!
        elementData[size++] = e;
        return true;
    }

/**   3. 擴容核心操作
     * 
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//舊長度
        int newCapacity = oldCapacity + (oldCapacity >> 1);//在舊長度的基礎上加上一半,即1.5倍作爲新長度
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
  • LinkedList

      爲雙鏈表集合(實現了Deque接口),
      由於ArryList是基於數組,它在內存上是一塊連續的地址,因此它查詢元素效率高。但是在刪除,插入時,得對數組進行移動,內存消耗大。而linkedList是基於雙鏈表,插入,刪除效率高。
    
  • Vector

      與ArrayList一樣,底層是數組,但Vector是線程安全的,而ArrayList是非安全的。擴容大小也有區別:vector擴容至原數組的2倍,而ArrayList爲1.5倍
    
//Vector基本與ArrayList一樣:
//1、基於Object[]數組;
//2、默認容量爲10;
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //capacityIncrement:當vector容量不夠,需要擴容時的增量值。
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);///當vector自動擴容的增量值小於或等於0時,新容量爲原容量的2倍。
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

$4.2、Queue

隊列,是接口,繼承自Collection.先進先出原則(FIFO)–一端進,另一端出,可理解爲“管道”,BlockingQueue(阻塞式隊列),實現了Queue接口。常用於生產者消費者模式,共享數據隊列

$4.3、HashMap、HashTable、ConcurrentHashmap

下面是總結的結論,最好結合源碼來看,加深印象。畢竟這種知識點就好比考試,會用,但長時間不看,具體細節就又不記得了。

  • HashMap允許存null。HashTable不允許;
  • HashMap是非線程安全,HashTable是線程安全;
  • HashMap與HashTable在計算Key的hash值獲取在數組中的位置時,HashMap採用按位與的方式,而HashTable採用取餘的方式,因此,HashMap與HashTable快。
    -concurrenthashmap採用分段鎖,內部是segment數組,而hashtable也是鎖住整個map,因此前者效率更高。

五、反射、泛型

$5.1、泛型

對於它的使用可能再熟悉不過了,需要了解一點的是它有一個“類型擦除”的動作。所謂“類型擦除”,是指JVM在編譯的過程中,針對泛型類型,會根據所設的類型邊界來生成字節碼。如下:

    //1.當未指定泛型類型邊界時,編譯器默認替換爲Object
 	private void setName(List<A> names){
                .....
     }
     //在編譯時,會進行泛型參數類型替換:
     private void setName(List<Object> names){} 

	//2.當有指定泛型類型父類時,編譯器會替換成泛型的父類
	private void setName(List<A extends User> names{}
$5.2、反射

對於Java反射原理,重點是要了解下JVM的類加載機制、以及一些重要的類,方法等。

  • 原理:簡單理解是:在JVM進行類加載時,會爲每個java文件的class生成一個Class對象,裏面包含了該類的一些基本信息(屬性,方法等),因此反射就是利用ClassLoader類加載器來提取目標Class對象,從而讀取裏面的Field屬性,Method方法。最後調用相應的API實現功能。
  • 應用:可以動態的修改,達到靈活性。
  • 爲了安全,Android9.0開始對@hide API進行一些反射的操作限制

六、final 、finaly、finalize

  • final:關鍵字,由它修飾的類或方法,或變量不可繼承、複寫、修改
  • finaly:與try catch一起用,最後執行
  • finalize:爲Object方法,由JVM在GC時最後調用。

第二節完,下一篇講分享面試知識點【Java運行時數據區】、【Java垃圾回收機制】、【Java多線程】、【JVM類加載】

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