ArrayList 与 LinkedList 对比
面试官问:"ArrayList 和 LinkedList 有什么区别?"
候选人小任答:"ArrayList 底层是数组,LinkedList 底层是双向链表。"
面试官点点头:"那随机访问和中间插入,哪个性能更好?"
小任说:"ArrayList 随机访问快,LinkedList 中间插入快。"
面试官追问:"LinkedList 的中间插入真的快吗?"
小任说:"是啊,因为链表插入不需要移动元素..."
面试官又问:"那你估算一下,插入第 1000 个元素,ArrayList 和 LinkedList 谁更快?"
小顾答不上来了。
【面试官心理】
这道题看似简单,但 90% 的候选人不理解"链表插入快"的真实条件。能说出"需要先找到插入位置"的候选人,才能真正答对这道题。LinkedList 的 get(i) 是 O(n) 操作,插入前要先遍历到目标位置。
一、底层数据结构对比 🔴
ArrayList
优点:
- 连续的内存空间,CPU 缓存友好
- 通过下标随机访问 O(1)
缺点:
- 插入/删除需要移动元素
- 扩容时需要复制整个数组
LinkedList
优点:
- 插入/删除不需要移动元素(如果已找到位置)
- 动态分配,无需扩容
缺点:
- 每个元素需要额外存储 prev/next 引用
- 随机访问需要从头遍历 O(n)
二、性能对比表 🔴
三、LinkedList 插入的真实代价 🔴
3.1 LinkedList 中间插入的真相
结论:LinkedList 中间插入的代价 = 查找代价(O(n))+ 插入代价(O(1))= O(n)
3.2 为什么 LinkedList 查找是 O(n)
3.3 场景对比
四、内存占用对比 🔴
⚠️
LinkedList 的内存开销是 ArrayList 的 3 倍。在内存敏感场景(如 Android),这可能造成严重影响。这也是为什么阿里巴巴 Java 规约中明确"集合初始化时,指定集合初始化大小"。
五、为什么阿里规约不推荐 LinkedList 🟡
CPU 缓存的影响
六、选型总结 🔴
【面试官心理】 能说出"阿里规约不推荐 LinkedList"的候选人,说明有工程意识。能解释背后原因(CPU 缓存、内存开销)的,是 P6+ 的水准。