【最新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类加载】

原创文章 80 获赞 34 访问量 17万+

猜你喜欢

转载自blog.csdn.net/u011153817/article/details/105845604