ArrayList知识点(面试)

2024-06-22 22:36
文章标签 知识点 arraylist 面试

本文主要是介绍ArrayList知识点(面试),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        上一篇我们说了hashmap的相关知识点,这一篇我们再说一些ArrayList的相关知识,因为ArrayList也是我们项目中比较常用的。

ArrayList(底层是数组)

底层工作原理
  • 首先,在构造ArrayList的时候会先看有没有指定容量,如果没有,则会先构造一个空数组,如果有,则会根据指定容量创建数组。

  • 在插入数据的时候,会先判断当前数组是否有足够的空间插入新数据,如果没有则会按照1.5倍的扩容标准进行扩容,同时如果容量足够,或再判断插入的位置有没有越界,以及该位置是否有元素

  • 在获取元素的时候同样也是先判断当前下标是否有越界,没有才能从数组中获取元素。

扩容机制
  1. 首先,ArrayList初始化的长度为10,如果插入的数据长度超过10则会自动触发扩容机制

  2. ArrayList会创建一个比原来数组长1.5倍的新数组,然后通过Arrays.copyof方法将原来的数组copy到新数组中

  3. 最后将新元素插入到新数组中

线程不安全是怎么解决的

先看一段代码

 @Testvoid testArrayList() {List<Integer> list = new ArrayList<>(12);list.add(1);list.add(2);list.add(3);System.out.println(list);//        遍历元素Thread t1 = new Thread(() -> {for (Integer integer : list) {System.out.println(integer);}});//              新增元素Thread t2 = new Thread(() -> {for (int i = 4; i < 8; i++) {list.add(i);}});t1.start();t2.start();}

以上代码运行后结果如下:

ArrayList在遍历的时候会去调用Collection中的next方法,然后通过checkForComodification()方法检查modCount和expectedModeCount是否相等,若不等则抛出ConcurrentModificationException,在上面的代码中我们对于list在遍历的同时也在增加数组中对的元素,modCount和expectedModeCount肯定不相等啦,所以就报错了。

modCount表示集合被修改的次数,每修改一次次数加1,而expectedModeCount是迭代器的属性,在迭代器创建时被赋予和modCount一样的值

其实在这里也是用到了fail-fast(快速失效)系统,这里简单说明一下这个是什么

fail-fast和fail-safe是什么意思?

fail-fast简单通俗的来讲就是在做系统设计的时候考虑异常情况,如果有异常情况,则抛出异常并且不会执行后面的代码

 public int divide(int dividend,int divisor){if(divisor == 0){throw new RuntimeException("divisor can't be zero");}return dividend/divisor;}

        以上的代码中,如果divisor为0,我们就会抛出一个异常并终止程序继续运行下面的代码,这样做的好处是一方面可以停止运行复杂的代码,另一方面,可以将一些异常单独进行处理。

        fail-safe就是为了避免触发fail-fast机制引发出来的异常,用java中一些带有fail-safe机制的集合类来控制。

        这样的集容器在遍历的时候会先拷贝一份出来而不是直接在原集合上进行操作,java.util.concurrent下的包都是fail-safe机制的,可以在多线程下进行并发修改(remove/add),就比如下面要说到的CopyOnWriteArrayList也是这种机制

        但是,通过这样的方式虽然是可以防止ConcurrentModificationException异常的,但是不能通过迭代器遍历元素,即元素中的元素如果发生改变,迭代器是不知道的,迭代器拿到的只是刚开始集合中的元素。

所以这个时候我们可以对其进行加锁

使用synchronized进行加锁

@Testvoid testArrayList() {List<Integer> list = new ArrayList<>(12);list.add(1);list.add(2);list.add(3);System.out.println(list);//        遍历元素Thread t1 = new Thread(() -> {synchronized (list){for (Integer integer : list) {System.out.println(integer);}}​});//              新增元素Thread t2 = new Thread(() -> {synchronized (list) {for (int i = 4; i < 8; i++) {list.add(i);}}});t1.start();t2.start();}

使用ReentrantLock进行加锁

 @Testvoid testArrayList() {List<Integer> list =new ArrayList<>(12);list.add(1);list.add(2);list.add(3);System.out.println(list);Lock lock=new ReentrantLock();// 遍历元素Thread t1 = new Thread(() -> {//            加锁lock.lock();for (Integer integer : list) {System.out.println(integer);}//                释放锁lock.unlock();});// 新增元素Thread t2 = new Thread(() -> {//            加锁lock.lock();for (int i = 4; i < 8; i++) {list.add(i);}//            释放锁lock.unlock();});t1.start();t2.start();}

        或者可以使用Collections.synchronizedxxxx来解决,把创建list的那行代码改成List<Integer> list = Collections.synchronizedList(new ArrayList<>())就行了

或者使用 CopyOnWriteArrayList来实现

  @Testvoid testArrayList() {List<Integer> list = new CopyOnWriteArrayList<>();list.add(1);list.add(2);list.add(3);System.out.println(list);// 遍历元素Thread t1 = new Thread(() -> {for (Integer integer : list) {System.out.println(integer);}});// 新增元素Thread t2 = new Thread(() -> {for (int i = 4; i < 8; i++) {list.add(i);}});t1.start();t2.start();}

这里扩展一下什么是Copy-On-Write?

        简称COW,其基本思路是一开始大家共享一个内容,后来如果有人来修改这个资源,这时就会先copy一份出来(延时懒惰策略),在这份中进行修改,修改完成后再把原来的容器指向这份新的容器。

序列化是怎么解决的

        在序列化中,如果被序列化的类中定义了readObject和writeObject方法,则虚拟机就会尝试去通过用户自定义的这两个方法进行序列化,对于自定义的序列化方法好处是可以在序列化的过程中动态修改序列化的值

        如果类中没有定义,则会用ObjectOutPutStream中默认的DefaultReadStream和DefaultWriteStream方法。

好了,现在再来说一下面试中最常被问到的内容

ArrayList和LinkList有什么区别?
  • 从地址上来说,ArrayList底层是一个数组,因此对于数组这种数据结构的话,它的地址是连续的,而对于LinkList来说,它的底层是一个循环双向链表的结构,地址就不是连续的。

  • 从操作上来讲,ArrayList在查询元素方面快于LinkList,且时间复杂度可以达到O(1),而LinkList的时间复杂度达到了O(n);但是在修改元素和增加元素上来讲,ArrayList时间复杂度达到了O(n),LinkList时间复杂度为O(1).

这篇关于ArrayList知识点(面试)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1085599

相关文章

嵌入式软件工程师应聘知识点

嵌入式软件工程师应聘 修改浏览权限 | 删除 数据结构(C语言)部分常考的知识点: 1、局部变量能、全局变量和静态变量 2、堆和栈 3、Const、volatile、define、typedef的用途 4、链表(比如链表的插入、删除和排序) 5、排序(考查冒泡法的较多) 6、可重入函数 、malloc函数 7、指针(常考函数指针,函数指针,数组指针,指针数组和

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

数据库期末复习知识点

A卷 1. 选择题(30') 2. 判断范式(10') 判断到第三范式 3. 程序填空(20') 4. 分析填空(15') 5. 写SQL(25') 5'一题 恶性 B卷 1. 单选(30') 2. 填空 (20') 3. 程序填空(20') 4. 写SQL(30') 知识点 第一章 数据库管理系统(DBMS)  主要功能 数据定义功能 (DDL, 数据定义语

C++面试八股文:std::deque用过吗?

100编程书屋_孔夫子旧书网 某日二师兄参加XXX科技公司的C++工程师开发岗位第26面: 面试官:deque用过吗? 二师兄:说实话,很少用,基本没用过。 面试官:为什么? 二师兄:因为使用它的场景很少,大部分需要性能、且需要自动扩容的时候使用vector,需要随机插入和删除的时候可以使用list。 面试官:那你知道STL中的stack是如何实现的吗? 二师兄:默认情况下,stack使

Java面试八股之JVM参数-XX:+UseCompressedOops的作用

JVM参数-XX:+UseCompressedOops的作用 JVM参数-XX:+UseCompressedOops的作用是启用对象指针压缩(Ordinary Object Pointers compression)。这一特性主要应用于64位的Java虚拟机中,目的是为了减少内存使用。在传统的64位系统中,对象引用(即指针)通常占用8字节(64位),而大部分应用程序实际上并不需要如此大的地址空间

华为某员工爆料:偷偷跑出去面试,被面试官鄙视了。第一句话就问:华为淘汰的吧,35岁了,这个年龄在华为能混得下去吗?身体没啥毛病吧

“你都35岁了,难不成是被华为淘汰的?在华为混不下去了吧?身体没啥毛病吧,我们这体检可是很严的。” 近日,一位华为员工在朋友圈爆料,自己在面试时遭到了面试官的无理取闹和人身攻击,原因仅仅是因为他35岁了,曾经在华为工作过。 这番话,充满了傲慢与偏见,让人听了义愤填膺。这位面试官的言行,不仅是对求职者的不尊重,更是对职场规则的践踏。 面试本应是双向选择的过程,企业和求职者在相互了解的基

算法与数据结构面试宝典——回溯算法详解(C#,C++)

文章目录 1. 回溯算法的定义及应用场景2. 回溯算法的基本思想3. 递推关系式与回溯算法的建立4. 状态转移方法5. 边界条件与结束条件6. 算法的具体实现过程7. 回溯算法在C#,C++中的实际应用案例C#示例C++示例 8. 总结回溯算法的主要特点与应用价值 回溯算法是一种通过尝试各种可能的组合来找到所有解的算法。这种算法通常用于解决组合问题,如排列、组合、棋盘游

【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用

【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用 1、强引用(Strong Reference)2、软引用(Soft Reference)3、弱引用(Weak Reference)4、虚引用(Phantom Reference)5、总结 💖The Begin💖点点关注,收藏不迷路💖 在Java中,除了我们常见的强引用(Strong Refer

redis 相关面试

1、Redis 使用过哪些类型?每一种类型应用场景是什么? string类型 ,基本信息存储 list 类型, 用过队列存储,每次获取前几个 hash类型, 哈希类型,主要存储对象, 如果某一个个体,有多个属性,则建议使用 redis hash类型(hset) set类型 ,无序集合,主要存储同一属性的集合 (sadd) sorted set类型, 主要用作排行榜  (之前被问过 如何实

2025秋招NLP算法面试真题(二)-史上最全Transformer面试题:灵魂20问帮你彻底搞定Transformer

简单介绍 之前的20个问题的文章在这里: https://zhuanlan.zhihu.com/p/148656446 其实这20个问题不是让大家背答案,而是为了帮助大家梳理 transformer的相关知识点,所以你注意看会发现我的问题也是有某种顺序的。 本文涉及到的代码可以在这里找到: https://github.com/DA-southampton/NLP_ability 问题