Collection集合类

HashMap
hashmap的底层结构

数组+List(JDK1.7以及之前)
数组+List(或者红黑树JDK1.8)

JAVA 数据结构理论 面试题 java中数据结构面试题_Java面试

hashmap的put和get操作 (Array then List)

  1. hash到Array的某个节点上;
  2. 遍历节点的list;
  3. 判断是否相等,调用equals方法判断相等
  4. 判断是否需要进行扩容;
  5. 放入对象

hashmap成环的原因(JDK1.7以及之前的版本)

假设存在一个EntryList数据 A->B->NULL(后续补个图说明)

  1. 两条线程ThreadA&ThreadB进入对Map执行put方法插入数据C,发现此时map已经达到容量阈值
  2. 假设ThreadA优先执行,执行扩容,指针指向第一个元素A,准备开始采用头插法向新map迁移
  3. ThreadB开始执行,同样指针指向第一个元素A;
  4. ThreadA,开始头插法,新map中存在B->A->NULL(假设Hash结果所有数据还是路由到同一个entryList当中)
  5. ThreadB开始执行,同样持有元素A引用,往同一个新map插入,执行头插法,A->B-A(环的形成)
    并发的扩容,头插法,操作同一个新map,数据路由到新map的同一个节点上,四个条件导致了成环的问题

hashmap为什么线程不安全

hashmap没有加锁,put方法线程并发会出现数据覆盖,导致前置数据丢失;并发产生的扩容操作会导致hashmap成环,导致get方法执行时陷入死循环。

hashmap在JDK1.8之后的变化

(1)JDK1.8引入了红黑树
(2)JDK1.8将头插法换成尾插法 (解决了成环的问题
(3)JDK对hash算法做了升级,亦或操作,找位置使用的

HashSet
1 hashset底层实现

HashSet的底层实现就是HashMap,使用了虚拟的valueObject对象

TreeMap

TreeMap的底层实现原理
Tree底层采用红黑树来实现 第一:构建排序二叉树,第二:平衡二叉树

List
ArrayList

ArrayList动态数组,初始10,扩容1/2,轮流拷贝,读大于写

LinkedList

LinkedList底层是双向队列,读取效率低,适合写大于读,无初始,无扩容

CopyOnWriteArrayList

CopyOnWriteArrayList实现原理(双内存) 初始化单个容器,共享读,存在写入操作时Copy容器,写入阶段但读取数据的请求依然读取老的容器,写入完成进行引用覆盖。通过两块内存达到读写分离的效果。

ConcurrentHashMap(//todo, 待完善)


二叉查找树

左子树小于父节点,右字数大于父节点

JAVA 数据结构理论 面试题 java中数据结构面试题_List_02

平衡二叉树(AVL)

左字树和右子树高度之差<=1 B-树

JAVA 数据结构理论 面试题 java中数据结构面试题_数据_03

平衡多路查找树(B树)

不是二叉树,n阶查找树,每一个节点存储升序的真正data信息或data所在节点的地址指针(升序二分查找),键值和data一一对应

JAVA 数据结构理论 面试题 java中数据结构面试题_集合类_04

B+树

平衡多路查找树的优化,叶子节点存储data数据,非叶子节点数据所在地址key

JAVA 数据结构理论 面试题 java中数据结构面试题_Java面试_05


B+树如何实现范围查询

(1)B+树在叶子节点存储数据信息,非叶子节点存放有序的数据索引信息


(2)B+树满足左子树比当前节点小,右子树比节点大的特性


(3)找到范围查询的两个临界点的索引,索引的磁盘地址区间数据即是范围查询的结果

红黑树

JAVA 数据结构理论 面试题 java中数据结构面试题_List_06

  1. 节点是红色或者黑色
  2. 根节点是黑色
  3. 每个叶子的节点都是黑色的空节点(NULL)
  4. 每个红色节点的两个子节点都是黑色的。
  5. 从任意节点到其每个叶子的所有路径都包含相同的黑色节点。

小结
HashTable&HashMap&ConcurrentHashMap

HashMap: 线程不安全
HashTable:线程安全,采用Sychronied实现的同步操作
ConcurrentHashMap:分段可重入锁 线程安全
(1)JDK1.8引入了红黑树
(2)CAS+Sychronized换掉了可重入锁 锁细化了 Sychronized不升级成重量级别锁就不会影响效率
(3)JDK1.8将头插法换成尾插法
(4)JDK对hash算法做了升级,亦或操作,找位置使用的

ArrayList&LinkedList

  1. ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
  2. 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
  3. 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

B树&B+树

  1. 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
  2. 不可能在非叶子结点命中;
  3. 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
    B+树的优势
    B+树的磁盘读写代价更低,节点存储关键字主键更多 B+树的数据信息遍历更加方便,
    遍历叶子节点就完成全遍历 B+树的查询效率更加稳定,直达叶子节点
    B+树的缺点
    缺点: 插入时,主键不是有序递增,插入数据产生大量的数据迁移和空间碎片

平衡二叉树&红黑树

红黑树,相比于平衡二叉树场景中对插入删除不频繁,只是对查找特别有要求,AVL还是优于红黑,红黑树,约束力比较弱的微平衡二叉树。最长路径不会是最短路径的两倍