#美团#Java面试题:集合高频要点问题你能答上来吗?


#美团#Java面试题:集合高频要点问题你能答上来吗?
文章图片
#美团#Java面试题:集合高频要点问题你能答上来吗?
Java是世界最流行的编程语言 , 也是国内大多数IT公司的主流语言 。
招聘网站上Java岗位众多 , Java工程师似乎不愁找工作 。 但仔细一看就会发现 , Java岗位的招聘薪酬天差地别 , 人才要求也是五花八门 。 而在Java工程师求职过程中 , 也是冷暖自知 。
List
1. 为什么 arraylist 不安全?
我们查看源码发现 arraylist 的 CRUD 操作 , 并没有涉及到锁之类的东西 。 底层是数组 , 初始大小为 10 。 插入时会判断数组容量是否足够 , 不够的话会进行扩容 。 所谓扩容就是新建一个新的数组 , 然后将老的数据里面的元素复制到新的数组里面(所以增加较慢) 。
2. CopyOnWriteArrayList 有什么特点?
它是 List 接口的一个实现类 , 在 java.util.concurrent(简称 JUC , 后面我全部成 juc , 大家注意下) 。
内部持有一个 ReentrantLock lock = new ReentrantLock(); 对于增删改操作都是先加锁再释放锁 , 线程安全 。 并且锁只有一把 , 而读操作不需要获得锁 , 支持并发 。
读写分离 , 写时复制出一个新的数组 , 完成插入、修改或者移除操作后将新数组赋值给 array 。
3. CopyOnWriteArrayList 与 Vector 的选择?
Vector 是增删改查方法都加了 synchronized , 保证同步 , 但是每个方法执行的时候都要去获得锁 , 性能就会大大下降 , 而 CopyOnWriteArrayList 只是在增删改上加锁 , 但是读不加锁 , 在读方面的性能就好于 Vector , CopyOnWriteArrayList 支持读多写少的并发情况 。
Vector 和 CopyOnWriteArrayList 都是 List 接口的一个实现类 。
4. CopyOnWriteArrayList 适用于什么情况?
我们看源码不难发现每次增加一个元素都要进行一次拷贝 , 此时严重影响了增删改的性能 , 其中和 arraylist 差了好几百倍 。
所以对于读多写少的操作 CopyOnWriteArrayList 更加适合 , 而且线程安全 。
DriverManager 这个类就使用到了CopyOnWriteArrayList 。
5. LinkedList 和 ArrayList 对比?
LinkedList<Integer> lists = new LinkedList<>();
lists.addFirst(1);
lists.push(2);
lists.addLast(3);
lists.add(4);
lists.addFirst(5);
lists.forEach(System.out::println);
// 5 2 1 3 4
addFirst 和 addLast 方法很清楚 。 push 方法默认是 addFirst 实现 。 add 方法默认是 addLast 实现 。 所以总结一下就是 add 和 last , push 和 first 。
其实我们要明白一下 , 链表相对于数组来说 , 链表的添加和删除速度很快 , 是顺序添加删除很快 , 因为一个 linkedList 会保存第一个节点和最后一个节点 , 时间复杂度为O(1) , 但是你要指定位置添加 add(int index E element), 那么此时他会先遍历 , 然后找到改位置的节点 , 将你的节点添加到他前面 , 此时时间复杂度最大值为 O(n) 。
数组呢?我们知道 ArrayList 底层实现就是数组 , 数组优点就是由于内存地址是顺序的 , 属于一块整的 , 此时遍历起来很快 , 添加删除的话 , 他会复制数组 , 当数组度特别大时所消耗的时间会很长 。 这是一张图 , 大家可以看一下:
6. Arrays.asList() 方法返回的数组是不可变的吗?
List<Integer> integers = Arrays.asList(1 2 3 4 5);
integers.set(2 5); // 这个操作可以
//integers.add(6); 这个会抛出异常


推荐阅读