前言

只有光头才能变强。

文本已收录至我的GitHub精选文章,欢迎Starhttps://github.com/ZhongFuCheng3y/3y

从今天开始,我,三歪,正式开始写面试系列。我给这个面试系列取了一个名字,叫做《求求大厂给个Offer》

上一篇就叫做《求求大厂给个Offer:如何写简历》

所以这篇文章叫做《求求大厂给个Offer:List面试题》

接下来就开始吧。

本文有配套的视频观看:https://www.bilibili.com/video/BV1nT4y1L71r/ 欢迎三连

面试现场

面试官:“你简单自我介绍一下吧”

三歪:“我叫三歪,目前维护一个公众号叫做Java3y,这几年写了300+原创技术文章,近1000页的原创电子书和多个知识点的思维导图。我的愿景是:只要关注我并三连的同学都可以拿到大厂offer。我的....”

面试官:“停停停,别吹了,我们正式开始吧。”

面试官:“来讲讲Java的List吧,你对List了解多少?”

三歪:“List在Java里边是一个接口,常见的实现类有ArrayList和LinkedList,在开发中用得最多的是ArrayList”

面试官:“你再分别来讲讲ArrayList和LinkedList的区别呗”

三歪:“ArrayList的底层数据结构是数组,LinkedList底层数据结构是链表。”

面试官:“那我们本身就有数组了,为什么要用ArrayList呢?”

三歪:“原生的数组会有一个特点:你在使用的时候必须要为它创建大小,而ArrayList不用”

面试官:“那你说说ArrayList是怎么实现的吧,为什么ArrayList就不用创建大小呢?”

三歪:“其实是这样的,我看过源码。当我们new ArrayList()的时候,默认会有一个空的Object数组,大小为0。当我们第一次add添加数据的时候,会给这个数组初始化一个大小,这个大小默认值为10”

面试官:“嗯”

三歪:“还有就是,数组的大小是固定的,而ArrayList的大小是可变的”

面试官:“那怎么理解固定和可变的呢?你说说看”

三歪:“假设我们给定数组的大小是10,要往这个数组里边填充元素,我们只能添加10个元素。而ArrayList不一样,ArrayList我们在使用的时候可以往里边添加20个,30个,甚至更多的元素”

三歪:“因为ArrayList是实现了动态扩容的”

面试官:“那它是怎么实现的呢?”

三歪:“使用ArrayList在每一次add的时候,它都会先去计算这个数组够不够空间,如果空间是够的,那直接追加上去就好了。如果不够,那就得扩容”

面试官:“那怎么扩容?一次扩多少?”

三歪:“在源码里边,有个grow方法,每一次扩原来的1.5倍。比如说,初始化的值是10嘛。现在我第11个元素要进来了,发现这个数组的空间不够了,所以会扩到15”

三歪:“空间扩完容之后,会调用arraycopy来对数组进行拷贝”

面试官:“哦,可以的。那为什么你在前面提到,在日常开发中用得最多的是ArrayList呢?”

三歪:“是由底层的数据结构来决定的,在日常开发中,遍历的需求比增删要多,即便是增删也是往往在List的尾部添加就OK了。像在尾部添加元素,ArrayList的时间复杂度也就O(1)

三歪:“另外的是,ArrayList的增删底层调用的copyOf()被优化过,现代CPU对内存可以块操作,ArrayList的增删一点儿也不会比LinkedList慢”

面试官:“Vector你了解吗?”

三歪:“嗯,Vector是底层结构是数组,一般现在我们已经很少用了。相对于ArrayList,它是线程安全的,在扩容的时候它是直接扩容两倍的,比如现在有10个元素,要扩容的时候,就会将数组的大小增长到20”

面试官:“嗯,那如果我们不用Vector,线程安全的List还有什么?”

三歪:“首先,我们也可以用Collections来将ArrayList来包装一下,变成线程安全。但这肯定不是你想听的,对吧。在java.util.concurrent包下还有一个类,叫做CopyOnWriteArrayList”

面试官:“嗯,你继续说”

三歪:“要讲CopyOnWriteArrayList之前,我还是想说说copy-on-write这个意思,下面我会简称为cow。比如说在Linux中,我们知道所有的进程都是init进程fork出来的,除了进程号之外,fork出来的进程,默认跟父进程一模一样的。在fork之后exec之前,两个进程用的是相同的内存空间的,这意味着子进程的代码段、数据段、堆栈都是指向父进程的物理空间”

面试官:“嗯”

三歪:“当父子进程中有更改的行为发生时,再为子进程分配相应物理空间。这样做的好处就是,等到真正发生修改的时候,才去分配资源,可以减少分配或者复制大量资源时带来的瞬间延时。简单来说,就可以理解为我们的懒加载,或者说单例模式的懒汉式。等真正用到的时候再分配”

面试官:“嗯”

三歪:“在文件系统中,其实也有cow的机制。文件系统的cow就是在修改数据的时候,不会直接在原来的数据位置上进行操作,而是重新找个位置修改。比如说:要修改数据块A的内容,先把A读出来,写到B块里面去。如果这时候断电了,原来A的内容还在。这样做的好处就是可以保证数据的完整性,瞬间挂掉了容易恢复

三歪:“再回头来看CopyOnWriteArrayList吧,CopyOnWriteArrayList是一个线程安全的List,底层是通过复制数组的方式来实现的。

三歪:“我来说说它 的add()方法的实现吧”

面试官:“好”

三歪:“在add()方法其实他会加lock锁,然后会复制出一个新的数组,往新的数组里边add真正的元素,最后把array的指向改变为新的数组”

三歪:“其实get()方法又或是size()方法只是获取array所指向的数组的元素或者大小。读不加锁,写加锁”

三歪:“可以发现的是,CopyOnWriteArrayList跟文件系统的COW机制是很像的”

面试官:“那你能说说CopyOnWriteArrayList有什么缺点吗?”

三歪:“很显然,CopyOnWriteArrayList是很耗费内存的,每次set()/add()都会复制一个数组出来,另外就是CopyOnWriteArrayList只能保证数据的最终一致性,不能保证数据的实时一致性。假设两个线程,线程A去读取CopyOnWriteArrayList的数据,还没读完,现在线程B把这个List给清空了,线程A此时还是可以把剩余的数据给读出来。”

面试官:“嗯,还可以,今天的面试就到这里结束了,你有什么想问我的吗?”

三歪:“你觉得我今天的表现怎么样?”

面试官:“今天的表现还可以,如果这一次你没有100个点赞,估计HR就不会再联系你了。如果超过100个点赞,第二轮好好表现吧。”

面试官:“给你透露一下,Map集合可以好好准备一下,下一轮将会考察Map的知识”

题外话

List集合总体来说不会太难,但CopyOnWriteArrayList可能很多同学还不知道有这么一个类。

针对这次的面试可能你想了解更多List的细节,比如说ArrayList/LinkedList/CopyOnWriteArrayList的源码以及上面提到的COW机制,可以在公众号下回复「List」即可获取我之前写的原创文章。

需要预习或者领取电子书的同学,在公众号下回复「888」即可获取。

本文有配套的视频观看:https://www.bilibili.com/video/BV1nT4y1L71r/ 欢迎三连

各类知识点总结

下面的文章都有对应的原创精美PDF,在持续更新中,可以来找我催更~

涵盖Java后端所有知识点的开源项目(已有10K+ star):

如果大家想要实时关注我更新的文章以及分享的干货的话,微信搜索Java3y

PDF文档的内容均为手打,有任何的不懂都可以直接来问我(公众号有我的联系方式)。

我是三歪,一个想要变强的男人,感谢大家的点赞收藏和转发,下期见。给三歪点个赞,对三歪真的非常重要!

最新文章

  1. Android_SQLite版本升级,降级 管理
  2. vmware workstation LINUX磁盘扩容
  3. struts2动态方法
  4. JDK1.7新特性
  5. 三种map的循环
  6. saltstack实战4--综合练习4
  7. mysql 跨库JOIN
  8. 一秒钟速算(WINFORM)
  9. 翻译Android USB HOST API
  10. Android清单文件AndroidMenifest.xml
  11. Semaphore (通常用于限制可以访问某些资源(物理或逻辑的)的线程数目)
  12. Oracle cloud control 12c 怎样改动sysmanpassword
  13. javascript笔记整理(概述,变量,数据类型)
  14. Following unknown configure options were used:--enable-fpm
  15. iOS开发中怎么样使用激光推送
  16. 聊聊JAVA中 String类为什么不可变
  17. 如何给filter添加自定义接口
  18. JSON.stringify()和JSON.parse()分别是什么
  19. LeetCode算法题-Search in a Binary Search Tree(Java实现)
  20. Triangle Count

热门文章

  1. 【CVPR2020】Wavelet Integrated CNNs for Noise-Robust Image Classification
  2. cli框架 获取 命令行 参数
  3. JS 原生ajax写法
  4. Android中的ANR问题
  5. 萌新学渗透系列之Hack The Box_Devel
  6. python基础day1&2
  7. Python 字典(Dictionary) copy()方法
  8. Nginx使用中遇到的问题记录
  9. markdown利器-小书匠
  10. C++ 中可调用的且有函数功能的东东