zoukankan      html  css  js  c++  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收割机
    关注大黄,充当offer收割机
  • 相关阅读:
    RNN 一对一
    js只保留整数,向上取整,四舍五入,向下取整等函数
    oracle中的decode的使用
    ORACLE里锁有以下几种模式,v$locked_object,locked_mode
    时间序列/信号处理开源数据集-转
    ORACLE常用数值函数、转换函数、字符串函数
    Oracle to_date()函数的用法
    java使double保留两位小数的多方法 java保留两位小数
    Oracle修改字段类型方法总结
    POI对Excel自定义日期格式的读取
  • 原文地址:https://www.cnblogs.com/xiaxj/p/14245047.html
Copyright © 2011-2022 走看看