乐趣区

关于java:Java面试必考题ArrayList常见知识点

微信公众号:大黄奔跑
关注我,可理解更多乏味的面试相干问题。

写在之前

对于 ArrayList 的面试题目网上比拟多,然而大多数从 ArrayList 的数据结构登程,比方查找、批改的等效率问题剖析,本篇文章想从并发的角度动手,给大家讲讲 ArrayList 的并发问题该如何答复。

面试回顾

通常容器之类的问题因为比拟根底,个别在一面考查的比拟多,同时这也成为决定是否进入二面的关键因素。

面试官:大黄同学是吧,我看你简历下面写可能熟练掌握 Java 基础知识,平时有应用过哪些容器呢?

大黄:面试官您好,个别工作中应用的比拟多的有 ArrayList、LinkedList、HashSet、hashMap 等。

面试官:那他们都是线程平安的吗?

大黄:不是线程平安的,他们在高并发状况下都会有线程平安问题。

面试官:那你能写一个程序简略说说 ArrayList 会有哪些那问题吗?

当然这时候必定得拿出平时好好积攒的程序了。

大黄:
如下:开启 20 个线程,每个线程给生成一个随机数,并且将随机数增加到 list 容器中

public class ArrayListUnsafe {public static void main(String[] args) {List<String> lists = new ArrayList <>();
        for (int i = 0; i < 20; i++) {new Thread(()->{lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(lists);
            },String.valueOf(i)).start();}
    }
}

通常状况下,这个程序会报java.util.ConcurrentModificationException,这也是高并发状况下常见的谬误,_并发批改异样_

面试官:为什么会产生这种问题呢?

大黄:在多线程下,每次往容器中写数据时,不保障程序,谁抢占到了容器谁开始写入数据,因而可能存在笼罩状况,导致每次执行的后果都不统一。

面试官:有什么方法能够防止这种问题吗?

大黄:当初 jdk 提供了多种形式保障 List 的线程平安。

  1. 应用传统的 Vector 汇合类。然而该类在办法上加上 Synchronize 关键字,保障线程平安。然而 jdK 曾经不举荐了,因为用了重量级加锁形式,导致执行效率低。
  2. 应用工具,Collections.synchronizedList保障线程平安。比方
    List lists = Collections.synchronizedList(new ArrayList &lt;&gt;());
  3. 利用写时复制的汇合类。CopyOnWriteArrayList

可能说出写时复制,这是加分项啊,同学们!!

面试官:可能简略说说什么是 CopyOnWriteArrayList 吗?

大黄:写时复制相似于将读数据和写数据过程拆散开来。比方
A 线程和 B 线程都开始写数据,A、B 每次写数据之前,都须要拿到一个许可证(相似于锁),主内存中数据复制到工作内存中,而后再进行批改,批改结束之后将容器的援用指向新的数据集,而后再容许别的线程批改。

大黄源码小课堂

比方对于写时复制的 add() 办法,jdk源码如下:

public boolean add(E e) {
    // 先获取锁,也就是前文说的许可证
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {Object[] elements = getArray();
        int len = elements.length;
        // 将原数组复制一份
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        // 增加新值
        newElements[len] = e;
        // 将数组索引指向新数组
        setArray(newElements);
        return true;
    } finally {
        // 最初开释锁
        lock.unlock();}
}

每次增加元素的时候,先获取锁(也就是许可),之后才去更新元素。

答复到这种水平,ArrayList的问题曾经算是答复的比拟好了,如果一面每个问题都可能答复上是什么,为什么、怎么做,进入二面必然是瓜熟蒂落的事儿了。

面试官:好了,明天的面试就到这里,请问你下一场面试什么时候有工夫呢,我来安顿一下。

哈哈哈,祝贺你,到了这里面试曾经胜利拿下了,开心的筹备二面吧

大黄:我这几天都有工夫的,看你们的安顿。

总结

对于容器的问题诸多博客都有形容,对于 ArrayList 的底层数据结构,如果有同学感兴趣能够本人搜寻,这里我就不鹦鹉学舌了。本文次要从线程平安的角度剖析 ArrayList 的面试题目,个别该如何答复。

最初大黄分享多年面试心得。面试中,面对一个问题,大略依照总分的逻辑答复即可。先间接抛出论断,而后举例论证本人的论断。肯定要第一工夫抓住面试官的心里,否则容易给人抓不着重点或者不着边际的印象。

番外

另外,关注大黄奔跑公众号,第一工夫播种独家整顿的面试实战记录及面试知识点总结。

我是大黄,一个只会写 HelloWorld 的程序员,咱们下期见。

关注大黄,充当 offer 收割机

退出移动版