面试3.2_Java_容器
参考链接
List,Set,Map区别
List:有序容器,元素可重复,可插入多个null元素,元素都有索引。
Set:无序容器,元素不可重复,只允许存一个null元素。
Map: Key无序,唯一;value 不要求有序,允许重复。
确保集合不被修改
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 区别
| 区别 | ArrayList | LinkedList |
|---|---|---|
数据结构 | 动态数组 | 双向链表 |
| 查找效率 | 高 | 低 |
| 随机插入和删除 | 低 | 高 |
| 顺序插入和删除 | 高 | 低 |
ArrayList 、 Vector 区别
- Vector:
线程安全:Synchronized; - ArrayList:
性能更优 - Vector
扩容每次增加 1 倍,而 ArrayList 只会增加 50%。
Vector实现线程安全原理
- 方法中都添加了
synchronized关键字来保证同步 - 无参构造方法的
默认容量为10 - 扩充容量的方法ensureCapacityHelper。
CopyOnWriteArrayList实现线程安全原理
- 适合
读多写少场景 - 当前容器
复制一份副本,在副本上执行写操作,结束后再将原容器的引用指向新容器
HashMap
1.7、1.8的区别
| 区别 | 1.7 | 1.8 |
|---|---|---|
| 数据结构 | 数组 + 链表 | 数组+链表+红黑树 |
初始化 | 单独函数 | 集成到resize()中 |
hash值 | 4次位运算 + 5次异或运算 | 1次位运算 + 1次异或运算 |
| 插入数据 | 头插法 | 尾插法 |
| 扩容后存储位置的计算 | 重新计算 | hash & 旧数组长度 == 0 |
什么时候用链表?什么时候用红黑树?
- 节点数
>8,且数组长度>=64,树化 - 节点数
>8,且数组长度<64,扩容 - 节点数
<6,链表化
默认初始容量
大于等于该容量的最小的2的N次方
HashMap是怎么解决哈希冲突
链地址法 + 扰动函数 + 红黑树
插入流程(put)

扩容流程(resize)

为什么不直接使用hashCode()处理后的哈希值直接作为table的下标?
- hashCode()方法返回的是
int整数类型 - HashMap的容量范围
<=2 ^ 30 - 一般取不到最大值,通过hashCode()计算出的哈希值可能超出数组大小范围内
HashMap 、Hashtable 区别
| 区别 | HashMap | Hashtable |
|---|---|---|
父类 | AbstractMap | Dictionary |
初始值 | 16 | 11 |
扩容 | 2*N | 2*N + 1 |
线程安全 | 不安全 | 安全,使用Synchronized |
空值 | 允许 key 和 value 为 null | 不允许 |
| hash值 | 1次位移+1次异或 | 直接使用 hashCode |
HashMap 、ConcurrentHashMap 区别
- ConcurrentHashMap
线程安全 - ConcurrentHashMap
不允许空的key与value
ConcurrentHashMap 1.7与1.8区别
| 区别 | 1.7 | 1.8 |
|---|---|---|
| 线程安全 | Segment + HashEntry + ReentrantLock | Node数组 + 链表 + 红黑树 + CAS + Synchronized |
| put | 1. 第一次key的hash定位Segment; 2. 若Segment未初始化, CAS赋值; 3. 第二次hash定位HashEntry, 自旋获取锁后插入尾部,超过指定次数就挂起,等待唤醒 | 1. 若相应位置的Node未初始化,则CAS插入; 2. 若Node不为空,则加锁操作 |
| size记录 | 不加锁统计size2次,两次结果不一样,再加锁统计 | 使用volatile变量baseCount记录 |
Comparable 、Comparator比较
| Comparable | Comparator |
|---|---|
| 排序接口,支持排序 | 比较器,自定义比较算法 |
| 可用作类的默认排序方法 | 用于默认排序不满足时,提供自定义排序 |
造相同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实现来替换掉它。
- HashMap会
本文深入解析Java中的List、Set和Map等容器的区别,探讨ArrayList与LinkedList的适用场景,对比HashMap在不同JDK版本间的实现差异,并介绍线程安全的集合类实现原理。
1035

被折叠的 条评论
为什么被折叠?



