Java面试题 第四部分 数据结构

Collection集合类

HashMap
hashmap的底层结构

数组+List(JDK1.7以及之前)
数组+List(或者红黑树JDK1.8)
在这里插入图片描述

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, 待完善)


二叉查找树

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

平衡二叉树(AVL)

左字树和右子树高度之差<=1 B-树
在这里插入图片描述

平衡多路查找树(B树)

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

B+树

平衡多路查找树的优化,叶子节点存储data数据,非叶子节点数据所在地址key
在这里插入图片描述
B+树如何实现范围查询
(1)B+树在叶子节点存储数据信息,非叶子节点存放有序的数据索引信息
(2)B+树满足左子树比当前节点小,右子树比节点大的特性
(3)找到范围查询的两个临界点的索引,索引的磁盘地址区间数据即是范围查询的结果

红黑树
在这里插入图片描述

  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还是优于红黑,红黑树,约束力比较弱的微平衡二叉树。最长路径不会是最短路径的两倍

1.栈和队列的共同特点是(只允许在端点处插入和删除元素) 4.栈通常采用的两种存储结构是(线性存储结构和链表存储结构) 5.下列关于栈的叙述正确的是(D) A.栈是非线性结构B.栈是一种树状结构C.栈具有先进先出的特征D.栈有后进先出的特征 6.链表不具有的特点是(B)A.不必事先估计存储空间 B.可随机访问任一元素 C.插入删除不需要移动元素 D.所需空间与线性表长度成正比 7.用链表表示线性表的优点是(便于插入和删除操作) 8.在单链表中,增加头结点的目的是(方便运算的实现) 9.循环链表的主要优点是(从表中任一结点出发都能访问到整个链表) 10.线性表L=(a1,a2,a3,……ai,……an),下列说法正确的是(D) A.每个元素都有一个直接前件和直接后件 B.线性表中至少要有一个元素 C.表中诸元素的排列顺序必须是由小到大或由大到小 D.除第一个和最后一个元素外,其余每个元素都有一个且只有一个直接前件和直接后件 11.线性表若采用链式存储结构时,要求内存中可用存储单元的地址(D) A.必须是连续的 B.部分地址必须是连续的C.一定是不连续的 D.连续不连续都可以 12.线性表的顺序存储结构和线性表的链式存储结构分别是(随机存取的存储结构、顺序存取的存储结构) 13.树是结点的集合,它的根结点数目是(有且只有1) 14.在深度为5的满二叉树中,叶子结点的个数为(31) 15.具有3个结点的二叉树有(5种形态) 16.设一棵二叉树中有3个叶子结点,有8个度为1的结点,则该二叉树中总的结点数为(13) 17.已知二叉树后序遍历序列是dabec,中序遍历序列是debac,它的前序遍历序列是(cedba) 18.已知一棵二叉树前序遍历和中序遍历分别为ABDEGCFH和DBGEACHF,则该二叉树的后序遍历为(DGEBHFCA) 19.若某二叉树的前序遍历访问顺序是abdgcefh,中序遍历访问顺序是dgbaechf,则其后序遍历的结点访问顺序是(gdbehfca) 20.数据库保护分为:安全性控制、 完整性控制 、并发性控制和数据的恢复。 1. 在计算机中,算法是指(解题方案的准确而完整的描述) 2.在下列选项中,哪个不是一个算法一般应该具有的基本特征(无穷性) 说明:算法的四个基本特征是:可行性、确定性、有穷性和拥有足够的情报。 3. 算法一般都可以用哪几种控制结构组合而成(顺序、选择、循环) 4.算法的时间复杂度是指(算法执行过程中所需要的基本运算次数) 5. 算法的空间复杂度是指(执行过程中所需要的存储空间) 6. 算法分析的目的是(分析算法的效率以求改进) ............ .................
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值