面试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会