[八股速成|冲击秋招SSP】JAVA集合类面经

以下是总结的高频的面经和考点:【书写不易,有用赶紧M住】

1.Java集合框架主要分为哪两大类?各自的核心接口是什么?列举常见的实现类。

1. 单列集合 (Collection):

有序、可重复

ArrayList

动态数组,支持随机访问,访问快O(1),插入删除慢O(n)

LinkedList

双向链表,增删快O(1),随机访问慢O(n)

Vector

线程安全版本的ArrayList,已较少使用

无序、不可重复

HashSet

基于哈希表实现,元素不排序,查找快O(1)

LinkedHashSet

哈希表+链表,保持插入顺序

TreeSet

基于红黑树,实现自然排序或自定义排序,操作O(logN)

队列

PriorityQueue

堆实现的优先级队列,出队元素是优先级最高的

ArrayDeque

数组实现的双端队列,可用作栈或队列,增删快速,无容量限制(补充说明)

2. 双列集合 (Map): 存储键值对 (Key-Value)

无序/有序(维护插入或访问顺序)

HashMap

基于哈希表实现,键无序,查找快O(1),存储无序

LinkedHashMap

哈希表+链表,维护插入顺序或访问顺序

有序(排序)

TreeMap

基于红黑树,键自动排序(自然顺序或自定义Comparator),操作O(logN)

线程安全

Hashtable

线程安全的哈希表,已少用(常用

ConcurrentHashMap

替代)

2. 为什么需要集合?数组/链表的局限性是什么?

核心原因:我们需要更高效、更便捷地处理特定操作

集合(如 HashSet, TreeSet)提供了一种更高层次的抽象,它封装了内部数据结构(通常基于数组、链表、树或哈希表),并专门优化了某些关键操作,特别是:

  1. 快速成员检测: 判断一个元素是否存在于集合中。
  2. 自动去重: 保证集合中不包含重复的元素。
  3. 数学集合运算: 方便地进行交集、并集、差集等操作。

数组的局限性:

  1. 固定大小(静态数组):问题: 必须预先知道或估计最大元素数量。如果实际元素数量超过初始分配大小,需要手动创建更大的新数组并复制所有元素(扩容),效率低(时间复杂度 O(n))。集合如何解决: 动态集合(如 HashSet, ArrayList 作为 List 的集合)在底层会自动处理扩容,程序员无需关心初始大小限制。
  2. 低效的查找:问题: 检查一个元素是否在数组中(contains 操作)通常需要线性搜索(遍历整个数组)。即使数组有序,可以使用二分查找(O(log n)),但插入元素时为了保持有序,插入点之后的所有元素都需要移动(O(n))。集合如何解决:HashSet 通过哈希表实现平均 O(1) 时间复杂度的 contains 和 add 操作(不考虑哈希冲突的最坏情况)。TreeSet 通过红黑树实现 O(log n) 时间复杂度的 contains, add, remove 操作,同时保持元素有序。
  3. 允许重复:问题: 数组本身不阻止重复元素。如果需要唯一性,程序员必须自己在添加元素时遍历检查是否已存在,效率很低(O(n) 每次添加)。集合如何解决:Set 的核心特性就是元素唯一性。add 操作会自动检查并拒绝重复元素,内部机制(哈希或树)使得这种检查非常高效。
  4. 插入/删除效率(特定位置):问题: 在数组中间插入或删除元素,需要移动该位置之后的所有元素以保持连续性,时间复杂度 O(n)。集合如何解决:Set 通常不关心元素的物理插入顺序(HashSet)或根据值排序(TreeSet),所以它们的 add 和 remove 操作不涉及在“中间”插入的概念,其效率由底层数据结构(哈希表 O(1) 平均 / 树 O(log n))决定,远高于在数组中间操作的 O(n)。(注:List 接口的集合如 ArrayList 也有在中间插入删除慢的问题,但 LinkedList 可以解决)。
  5. 缺乏高级抽象:问题: 数组是一个低级的、连续内存块的概念。它没有内置的方法直接支持集合运算(如并集、交集)、迭代器(虽然可以用循环)或直接提供大小信息(需要额外变量跟踪实际元素数)。集合如何解决: 集合框架(如 Java Collections Framework, C++ STL, Python Sets)提供了丰富的接口和方法(add, remove, contains, size, isEmpty, iterator, addAll (并集), retainAll (交集), removeAll (差集) 等),极大地简化了代码并提高了开发效率。

链表的局限性:

  1. 低效的查找:问题: 这是链表最大的弱点。查找特定元素(按值而非索引)必须从链表头(或尾)开始逐个遍历节点,时间复杂度 O(n)。即使是有序链表,也无法进行二分查找(因为不支持随机访问)。集合如何解决: 同数组的查找问题。HashSet 和 TreeSet 提供了远超链表的查找效率。
  2. 允许重复:问题: 链表本身也不阻止重复元素。同样需要程序员手动遍历检查去重,效率低。集合如何解决: 同数组的重复问题。Set 自动保证唯一性。
  3. 内存开销:问题: 每个链表节点除了存储数据本身,还需要额外的指针(引用)来存储前驱和后继节点的地址。在存储大量小元素时,指针的空间开销可能比数据本身还大。集合如何解决:HashSet 基于数组(桶)和链表/红黑树(解决冲突),TreeSet 基于树节点(也需要左右子节点指针)。虽然它们也有额外开销,但通常是为了换取更高效的查找和去重能力。对于纯粹需要唯一性和快速查找的场景,HashSet 的空间效率通常优于手动维护去重的链表。数组实现的集合(如 ArrayList)在空间上更紧凑。
  4. 缓存不友好:问题: 链表节点在内存中通常是分散存储的,访问时局部性差,导致 CPU 缓存命中率低,可能影响实际性能。集合如何解决:HashSet 的主要部分(桶数组)和 ArrayList 是连续内存,对缓存更友好。TreeSet 的节点也可能分散,但高效的树操作(O(log n))弥补了部分缓存劣势。

3. ArrayList 和 LinkedList 的区别? (必考!)

核心区别在底层数据结构与操作效率

非常好的 ArrayList 和 LinkedList 对比表格,信息非常全面且准确。我将其整理如下,以便更好地呈现:

特性

ArrayList

LinkedList

底层结构

动态数组

(连续内存)

双向链表

(非连续内存,节点含前后指针)

随机访问效率

O(1)

(直接下标寻址)

O(n)

(需从头/尾遍历)

头部插入/删除

O(n)

(需移动后续元素)

O(1)

(修改指针)

中间插入/删除

O(n)

(平均需移动一半元素)

O(n)

(找到位置O(n),修改指针O(1))

尾部插入/删除

O(1)

(均摊,不考虑扩容) /

O(n)

(扩容时)

O(1)

内存占用

较小 (仅存数据)

较大 (额外存储指针)

空间局部性/CPU缓存友好性

(连续内存)

(节点分散)

扩容机制

需要 (复制数据到新数组)

不需要 (动态添加节点)

主要适用场景

频繁随机访问

、尾部操作

频繁在任意位置插入/删除

、实现栈/队列

记忆口诀:“数组连续随机快,链表灵活插删妙。” 或 联想:ArrayList`像书架(取书快,塞书慢),LinkedList像珠链(加珠子快,找珠子慢)。

4. HashMap 的核心原理是什么?

基于哈希表 (数组 + 链表/红黑树),核心是哈希函数与解决冲突。

1.数据结构:数组 + 链表 + 红黑树

HashMap 采用数组 + 链表 + 红黑树的复合结构。数组作为主体存储数据,每个数组元素称为一个 “桶”;当发生哈希冲突时,冲突元素通过链表形式存储在对应桶中。当链表长度超过 8 且数组长度大于 64 时,链表会转换为红黑树,将查询时间复杂度从链表的 O (n) 优化至红黑树的 O (logn),大幅提升查询效率。

2.容量机制:初始容量与扩容

  • 初始容量:HashMap 默认初始容量为 16,若初始化时传入非 2 的幂次方值(如 17),会自动调整为大于等于该值的最小 2 的幂次方(即 32)。
  • 扩容机制:当键值对数量超过 ** 容量 × 负载因子(默认 0.75)** 时触发扩容。扩容时,创建容量为原来 2 倍的新数组,并将旧数组元素重新分配到新数组。JDK 8 采用尾插法,通过(e.hash & oldCap) == 0判断元素位置,避免重新计算哈希值,提高扩容性能。

3.put 流程

  1. 哈希寻址:通过哈希函数计算键的哈希值,并与数组长度 - 1 进行按位与运算,确定元素所在桶的索引。
  2. 判断桶状态:若桶为空,直接插入;若不为空,判断是链表还是红黑树。
  3. 处理冲突:链表结构按顺序遍历插入,红黑树按树结构插入;若键已存在,则覆盖旧值。
  4. 扩容判断:插入后检查键值对数量是否超过阈值,超过则触发扩容。

get 流程

  1. 通过哈希值定位数组索引,找到对应桶。
  2. 检查桶中第一个节点,若匹配则直接返回;否则根据节点类型遍历链表或红黑树查找,找到则返回结果,未找到返回 null。

补充:

1.如何减少哈希冲突

  • 哈希值计算:通过高位与低位异或运算,让哈希值更均匀分布。

索引计算:利用h & (n - 1)(n 为数组长度且是 2 的幂次方)按位与运算替代取模运算,提高计算效率。

2.解决哈希冲突方法

  • 拉链法:HashMap 采用的方法,用链表处理冲突,链表过长时转换为红黑树,扩容时树元素个数小于 6 则退化为链表。
  • 再哈希法:准备多套哈希算法,冲突时切换算法直至找到空槽,对算法设计要求高。
  • 开放地址法:包括线性探测(顺序查找空槽)、二次探测(按平方步长查找)、双重哈希(使用备用哈希函数)。

3.线程安全性对比

  • HashMap:线程不安全,多线程环境下可能出现数据覆盖、死循环等问题。
  • Hashtable:通过synchronized修饰方法实现线程安全,但锁粒度大,性能差。
  • ConcurrentHashMap:Java 8 后采用CAS 操作 + synchronized 锁,写操作通过 CAS 插入节点,冲突时对链表 / 红黑头结点加锁;读操作大多无锁,通过volatile保证可见性,性能更优,推荐使用。

5.HashMap 如何扩容?

触发条件: 元素数量 > 容量

1.扩容触发条件

当 HashMap 中元素个数 size 超过 阈值(threshold) 时,触发扩容:

thresh

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

剑指大厂后端SSP通关指南 文章被收录于专栏

(1)全网最精简八股整理,各个头部公司最新面经整理(2)面试时非技术问题的话术整理;价格随着内容增加而增加,早订阅早享受

全部评论
mark
点赞 回复 分享
发布于 06-09 09:38 北京
mark
点赞 回复 分享
发布于 06-09 09:03 浙江

相关推荐

作为过来人,我含泪为大家盘点这些鬼话。1. 别着急,最好的在最后说这话的人,肯定没经历过宿舍人都签了三方,我连面试都没有的恐慌。信了这句,年都过错了。秋招就好像在地铁上抢座位,犹豫一秒,好位置就没了。该下手时就要下手。2. 简历必须一页纸一页纸是形式,内容才是王道。有真材实料,一页半又何妨?真实习经历好几段,个个都有收获,一页纸写的下吗?3. 要展现真实的自己面试官问缺点,你能回答有点拖延,爱在deadline前冲刺吗?那就再也没有然后了。职场要的是职业版的你,不是那个熬夜追剧、起床困难的你。适当的演技叫专业。4. 别在乎钱,平台重要结果月薪交完房租,连奶茶自由都实现不了。薪水是对你价值最直接的认可。用爱发电,最后只能吃土。5. 多海投,总有机会你是海王公司也是。精准打击,远胜无效撒网。6. 考个证吧,简历能加分我信了,熬夜刷题考了一堆证。结果面试时,HR盯着我简历问:你这些证书,和我们岗位有什么关系?多数证书的唯一作用,就是浪费你的报名费和备考时间。 不如把精力投入到一段扎实的实习里。7. 把别人的优秀简历拿来模仿简历可以借鉴格式,但无法复制经历。没有真实经历支撑的简历,就像纸糊的墙,一捅就破。8. 面试前要把标准答案背熟你把“你的缺点是什么”的标准答案背得滚瓜烂熟。结果面试官换个问法:你同事会怎么评价你的缺点?你咋说?HR面过的候选人比你背的答案还多,真诚远比套路得人心。9. 多参加群面,积累经验我像个街溜子一样奔波于各大群面,结果除了练就一身抢话的本事,毫无长进。漫无目的地参加群面,不如认真复盘一次失败的单面。 经验在于质量,不在数量。10. 面试后一定要发感谢信一位做HR的同事说:内容千篇一律的感谢信我们不会看的,除非你能写出令人眼前一亮的内容。11. 接到Offer别马上回复,晾他们两天等HR打来电话:同学,岗位已经招满,祝您前程似锦。你就老实了,好岗位不等人,在候选人池里,你远没有自己想象中那么不可替代。总结:秋招没有标准答案。别被这些鬼话带偏,早点行动、精准投递、大胆谈薪,比什么都强。祝大家都能避开这些坑,拿到心仪offer~点点赞关注支持一下啦~
你听到的“最没用”的秋招...
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-19 17:12
长园深瑞南京分公司 嵌入式软件开发 9.8k,13薪 本科其他
点赞 评论 收藏
分享
11-13 14:19
已编辑
武汉理工大学 前端工程师
个人bg: 211本,非科班(某个计算机和管理的交叉专业),方向前端开发,一段美团的暑期实习投递:20余家约面:字节,虾皮,小米,新凯来,快手,滴滴,作业帮,深信服,科大讯飞,华为oc情况:美团(转正),虾皮,华为(审批中),新凯来(同华为)各家timeline:-美团:8.28意向 11.13开奖-字节:9.5投递9.15tiktok一面 9.17二面(挂)9.24集团信息系统一面(挂)10.17番茄小说一面(挂)-虾皮:9.9投递9.13笔试9.20一面9.25二面10.17hr面11.10无意向直接开奖-华为:9.12投递9.17笔试11.3一面 二面 三面目前审批ing,hr说大概率能开出来,就是薪资和定级还不确定-新凯来:9.9投递10.11笔试10.22一面10.25线下二面hr通知所有流程通过,目前应该也是审批中(很逆天的是给我调到嵌入式去了)-小米:9.4线上投递9.20笔试10.17线下二次投递11.3线上流程挂11.10线下简历通过初筛,约了一面(鸽了)-腾讯,京东,阿里系:秋招一个面不给。。。。。-深信服:9.5投递 简历挂。。。11.1被捞起来一面,感觉拿我当备胎,挂了我又来捞我,没诚意直接鸽了-滴滴:国庆假前几天在牛客上投的10.19一面 面完十分钟感谢信。。。(问得好简单,挂的莫名奇妙)-作业帮:9.17线下约面(直接跳过了笔试)10.25一面(挂)-快手:简历挂了一页多,10.31终于约面了,后面知道是双机位,也觉得也没什么hc了,推了-小红书:错过三次约面电话,每次都在面试,注定和🍠无缘-贝壳,网易,腾讯音乐,百度,pdd,得物,bilibili:一直卡在简历初筛,或者笔试完没动静。。。。总结:秋招奋战两个多月,收获四个offer(包含口头意向),互联网公司只有美团转正和虾皮,感觉今年秋招真的有点寒冬的味道,还在奋战秋招的牛友们不要气馁,加油,一定可以看见曙光的👍
我的秋招日记
点赞 评论 收藏
分享
评论
6
17
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务