面试3.2_Java_容器

本文深入解析Java中的List、Set和Map等容器的区别,探讨ArrayList与LinkedList的适用场景,对比HashMap在不同JDK版本间的实现差异,并介绍线程安全的集合类实现原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


参考链接

  1. Java集合容器面试题
  2. Java 集合高频面试题
  3. Java 基础高频面试题
  4. CopyOnWriteArrayList实现原理及源码分析

List,Set,Map区别

List:有序容器,元素可重复,可插入多个null元素,元素都有索引。

Set:无序容器,元素不可重复,只允许存一个null元素。

Map: Key无序,唯一;value 不要求有序,允许重复。在这里插入图片描述


确保集合不被修改

  1. Collections. unmodifiableCollection(Collection c)创建只读集合
List<String> list = new ArrayList<>();
list. add("x");
Collection<String> clist = Collections. unmodifiableCollection(list);
clist. add("y"); // 运行时此行报错
System. out. println(list. size());

线程安全的集合类

vector 、stack 、hashtable 、enumeration


集合、数组区别

数组集合
固定长度长度可变
基本类型,引用类型引用类型
必须同一个数据类型可以是不同数据类型。

ArrayList 、 LinkedList 区别

区别ArrayListLinkedList
数据结构动态数组双向链表
查找效率
随机插入和删除
顺序插入和删除

ArrayList 、 Vector 区别

  1. Vector:线程安全:Synchronized;
  2. ArrayList: 性能更优
  3. Vector 扩容每次增加 1 倍,而 ArrayList 只会增加 50%。

Vector实现线程安全原理

  1. 方法中都添加了synchronized关键字来保证同步
  2. 无参构造方法的默认容量为10
  3. 扩充容量的方法ensureCapacityHelper。

CopyOnWriteArrayList实现线程安全原理

  1. 适合读多写少场景
  2. 当前容器复制一份副本,在副本上执行写操作,结束后再将原容器的引用指向新容器

HashMap

1.7、1.8的区别

区别1.71.8
数据结构数组 + 链表数组+链表+红黑树
初始化单独函数集成到resize()中
hash值4次位运算 + 5次异或运算1次位运算 + 1次异或运算
插入数据头插法尾插法
扩容后存储位置的计算重新计算hash & 旧数组长度 == 0

什么时候用链表?什么时候用红黑树?

  • 节点数>8,且数组长度>=64树化
  • 节点数>8,且数组长度<64扩容
  • 节点数<6链表化

默认初始容量

大于等于该容量的最小的2的N次方

HashMap是怎么解决哈希冲突

链地址法 + 扰动函数 + 红黑树

插入流程(put)

在这里插入图片描述

扩容流程(resize)

在这里插入图片描述

为什么不直接使用hashCode()处理后的哈希值直接作为table的下标?

  1. hashCode()方法返回的是int整数类型
  2. HashMap的容量范围<=2 ^ 30
  3. 一般取不到最大值,通过hashCode()计算出的哈希值可能超出数组大小范围内

HashMap 、Hashtable 区别

区别HashMapHashtable
父类AbstractMapDictionary
初始值1611
扩容2*N2*N + 1
线程安全不安全安全,使用Synchronized
空值允许 key 和 value 为 null不允许
hash值1次位移+1次异或直接使用 hashCode

HashMap 、ConcurrentHashMap 区别

  1. ConcurrentHashMap 线程安全
  2. ConcurrentHashMap 不允许空的key与value

ConcurrentHashMap 1.7与1.8区别

区别1.71.8
线程安全Segment + HashEntry + ReentrantLockNode数组 + 链表 + 红黑树 + CAS + Synchronized
put1. 第一次key的hash定位Segment
2. 若Segment未初始化,CAS赋值
3. 第二次hash定位HashEntry,自旋获取锁后插入尾部,超过指定次数就挂起,等待唤醒
1. 若相应位置的Node未初始化,则CAS插入;
2. 若Node不为空,则加锁操作
size记录不加锁统计size2次,两次结果不一样,再加锁统计使用volatile变量baseCount记录

Comparable 、Comparator比较

ComparableComparator
排序接口,支持排序比较器,自定义比较算法
可用作类的默认排序方法用于默认排序不满足时,提供自定义排序

造相同hash的字符串进行攻击,这种情况应该怎么处理?JDK7如何处理?

  • 当客户端提交一个请求并附带参数的时候,web应用服务器会把我们的参数转化成一个HashMap存储,这个HashMap的逻辑结构为:

    key1 ——> value1;
    
  • 但是物理存储结构是不同的,key值会被转化成Hashcode,这个hashcode又会被转成数组的下标:

    0 ——> value;
    1 ——> value2;
    
  • 如果有人恶意构造请求,在请求中加入大量相同hash值的String参数名(key),那么在服务器端用于存储这些key-value对的HashMap会被强行退化成链表,如图:

    在这里插入图片描述
    如果数据量足够大,那么在查找,插入时会占用大量CPU,达到拒绝服务攻击的目的。

  • 怎么处理

    • 限制POST和GET请求的参数个数
    • 限制POST请求的请求体大小
    • Web Application FireWall(WAF)
  • JDK7如何处理

    • HashMap会动态的使用一个专门TreeMap实现来替换掉它
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值