一、背景:
我们经常会在网上看到一些面试题,比如HashMap数据结构、Handler实现原理、binder进程通信等等。但是很多文章都是深入分析,缺少对每个环节问题点提问,比如这块为什么要这么设计。面试官也不会问完一个问题就结束,也会逮着追问,直到问到你不会。特别是大厂都喜欢一步步深入提问,来考察你对知识点掌握的深度。
本文计划从ArrayList切入,尽可能覆盖面试过程中涉及ArrayList的所有问题点。问题和解答尽量精简易懂,每个人视角不一样,如果大家有遇到文章中没有提到的问题点,可以留言或私信指出。
今年大环境整体不好,大家一起努力~
二、ArrayList常见问题脑图
三、面试问题点及解答
问题一:ArrayList是线程安全的吗
答:是线程安全,add添加元素的时候会存在线程安全问题,线程安全可以使用CopyOnWriteArrayList或Collections.synchronizedList
进一步追问:CopyOnWriteArrayList为什么能保证线程安全
答:COW采用自旋锁(jdk1.6升级为synchronize)对写加锁,读不加锁,数组变量有使用volatile保证可见性,增删创建一新数组,读取的是原数据,适合读多写少场景。
备注:后续会针对COW问题单独来一篇
问题二:ArrayList操作时间复杂度是多少
答:基于数组数据结构,查询快、删除慢。查询时间复杂度O(1),增删O(n)
进一步追问:ArrayList扩容机制是什么样的
答:jdk1.7 懒汉方式,默认10,1.5倍扩容;jdk1.8 饿汉方式,默认0,新增元素时创建长度10数组
进一步追问:详细说下如何实现扩容的
答:通过grow扩容函数,确定新数组长度后,调用Arrays.copyOf复制原数组,背后调用的是System.arraycopy() native方法;
进一步追问:除了Array.CopyOf,Java还有其他拷贝方式吗
答:有四种拷贝方式:
拷贝方式 数值类型 引用类型
for循环 深拷贝 浅拷贝
System.CopyOf 深拷贝 浅拷贝
Arrays.CopyOf 深拷贝 浅拷贝
clone 深拷贝 浅拷贝
其中Arrays.copyOf底层调用的是System.arraycopy,速度更快
System.arraycopy(original, start, result, 0, copyLength);
进一步追问:System.arraycopy为什么会更快?
答:它是native实现,jvm固有方法,会对其做一些增强处理,比如手动编写汇编实现该方法,在jvm内部实现,跟jdk库中native方法实现不同,不走常规的jni lookup,可以节省开销
下面是查阅到的资料,如有侵权请联系删除
问题三:ArrayList可以存放null吗
答:ArrayList存放的是object,是可以存储多个null的