基础_算法和数据结构

1. 二分查找法:https://blog.csdn.net/maoyuanming0806/article/details/78176957

2. 红黑树:

本质是排序平衡二叉树:二路、平衡、排序,检索效率是O(logn);

红黑树引入了“颜色”的概念。引入“颜色”的目的在于使得红黑树的平衡条件得以简化。正如著名的密码学专家Bruce Schneier所说的那样,“Being Partly balanced can be good enough”,红黑树并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能

红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。

参考:https://www.cnblogs.com/yangyquin/p/4921664.html 各种数据结构

3.B-树

本质是平衡的多路查找树:多路、平衡、排序

B树:即平衡树banlence,查询速度较高,一般用于数据库的索引,综合效率较高;

5.二叉排序树:BST

本质是非平衡的二叉排序树:非平衡、排序、二路

10. 对比:

https://blog.csdn.net/bytxl/article/details/40920165 二叉查找树,红黑树,AVL树,B~/B+树(B-tree),伸展树——优缺点及比较

3. Mysql选用B+树和MongoDB选用B-树(即B树)

题主应该知道B-树和B+树最重要的一个区别就是B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。

这就决定了B+树更适合用来存储外部数据,也就是所谓的磁盘数据。

从Mysql(Inoodb)的角度来看,B+树是用来充当索引的,一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上。那么Mysql如何衡量查询效率呢?磁盘IO次数,B-树(B类树)的特定就是每层节点数目非常多,层数很少,目的就是为了就少磁盘IO次数,当查询数据的时候,最好的情况就是很快找到目标索引,然后读取数据,使用B+树就能很好的完成这个目的,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数(磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时啊!),而

B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少。这是优点之一。另一个优点是什么,B+树所有的Data域在叶子节点,一般来说都会进行一个优化,就是将所有的叶子节点用指针串起来。这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。

至于MongoDB为什么使用B-树而不是B+树,可以从它的设计角度来考虑,它并不是传统的关系性数据库,而是以Json格式作为存储的nosql,目的就是高性能,高可用,易扩展。首先它摆脱了关系模型,上面所述的优点2需求就没那么强烈了,其次Mysql由于使用B+树,数据都在叶节点上,每次查询都需要访问到叶节点,而MongoDB使用B-树,所有节点都有Data域,只要找到指定索引就可以进行访问,无疑单次查询平均快于Mysql(但侧面来看Mysql至少平均查询耗时差不多)。

总体来说,Mysql选用B+树和MongoDB选用B-树还是以自己的需求来选择的。

https://www.jianshu.com/p/0190985635eb 一片文章搞定面试中的二叉树题目java实现 --- 好!!!

4. 阻塞队列

BlockingQueue:阻塞队列(BlockingQueue)是java.util.concurrent下的主要用来控制线程同步的工具。如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒。同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作。

阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。具体的实现类有LinkedBlockingQueue,ArrayBlockingQueued等。一般其内部的都是通过Lock和Condition(显示锁(Lock)及Condition的学习与使用)来实现阻塞和唤醒。

https://www.cnblogs.com/tjudzj/p/4454490.html BlockingQueue(阻塞队列)详解 -- 好!!

https://www.cnblogs.com/dolphin0520/p/3932906.html Java并发编程:阻塞队列 -- 好!!!

5. 在有限内存里找出两个大文件相同的记录?

https://www.cnblogs.com/aspirant/p/7154551.html --- 大数据面试题

6. 集合相关:Collection和Map

Collection接口延伸出:Set, List, Queue

Set: 无序且不可重复,HashSet优势是查找效率高;

List: 有序且可重负,实现类包括ArrayList, LinkedList等

Queue:

Map: key组合起来相当于set,value组合起来相当于list

(1) HashMap和HashTable区别:

HashMap是非线程安全的,HashTable是线程安全的。

HashMap的键和值都允许有null值存在,而HashTable则不行。

因为线程安全的问题,HashMap效率比HashTable的要高。

(1) ConcurrentHashMap和HashTable区别:

HashTable是基于synchronized机制的,锁住的是整个对象;

ConcurrentHashMap是基于Lock操作的,并发性更好;

(1)HashMap和TreeMap区别:

HashMap基于数组和链表,查询速度更快,而TreeMap基于红黑树,都是非线程安全的;

TreeMap遍历结果是默认升序排列的,HashMap遍历结果是无序的;

(2) HashMap原理:

本质是数组和链表的结合;键对象的hashcode()取模后寻找bucket位置,然后进行链表存储或查找;get()原理:HashMap会使用键对象的hashcode()找到bucket位置(槽位置,Entry数组的索引),然后遍历链表通过键对象的equals()方法找到值对象,链表存储的是键值对;put()原理:找到bucket位置后,首先遍历链表查找是否已经有key值,如果有则更新Key的value值,否则插入;

扩容时,需要新建一个长度为之前数组2倍的新的数组,然后将当前的Entry数组中的元素全部传输过去,扩容后的新数组长度为之前的2倍,所以扩容相对来说是个耗资源的操作。

哈希函数:用来确定数组的索引未知,首先算得key得hashcode值,然后跟数组的长度-1做一次“与”运算(&),取模效率低点;

数组方式存储key/value,线程非安全,允许null作为key和value,key不可以重复,value允许重复,不保证元素迭代顺序是按照插入时的顺序,key的hash值是先计算key的hashcode值,然后再进行计算,每次容量扩容会重新计算所以key的hash值,会消耗资源,要求key必须重写equals和hashcode方法;默认初始容量16,加载因子0.75,扩容为旧容量乘2,查找元素快,如果key一样则比较value,如果value不一样,则按照链表结构存储value,就是一个key后面有多个value;

详见:

https://www.cnblogs.com/s-b-b/p/6208565.html 哈希表原理

https://blog.csdn.net/abcdad/article/details/64123291 HashMap实现原理分析及简单实现一个HashMap

http://www.cnblogs.com/chengxiao/p/6059914.html HashMap实现原理及源码分析 - 好!!

(2) ConcurrentHashMap原理:

一个ConcurrentHashMap维护一个Segment数组,一个Segment维护一个HashEntry数组;

Segment继承了ReentrantLock,所以它就是一种可重入锁(ReentrantLock)。在ConcurrentHashMap,一个Segment就是一个子哈希表,Segment里维护了一个HashEntry数组,并发环境下,对于不同Segment的数据进行操作是不用考虑锁竞争的。

默认并发度是16,可在创建时指定,每个segment里面包含的HashEntry数组最小长度是2,即颗粒度最小是2;

详见:https://www.cnblogs.com/chengxiao/p/6842045.html ConcurrentHashMap实现原理及源码分析 -- 好!!!

(2)treeMap原理:

基于红黑二叉树的NavigableMap的实现,线程非安全,不允许null,key不可以重复,value允许重复,存入TreeMap的元素应当实现Comparable接口或者实现Comparator接口,会按照排序后的顺序迭代元素,两个相比较的key不得抛出classCastException。主要用于存入元素的时候对元素进行自动排序,迭代输出的时候就按排序顺序输出;

(3)为什么重写equals,需要重写HashCode?

举个例子,在hashMap的查询中,判断一个Key对象是否相等,需要首先用key的HashCode确定数组槽的位置,然后用key的equals判断对象是否相等,所以如果一个对象相等时,它的hashCode和equals返回结果必须一致;

详见:https://blog.csdn.net/u013679744/article/details/57074669 -- 详解重写equals()方法就必须重写hashCode()方法的原因

99. 参考

https://blog.csdn.net/goodlixueyong/article/details/51935526 --- 单例模式5种实现方式

https://www.cnblogs.com/hupp/p/4645346.html -- 3中常见查找算法

https://www.cnblogs.com/hupp/p/4639281.html ---7种排序算法

http://www.cnblogs.com/hupp/tag/%E5%89%91%E6%8C%87offer/ 剑指Offer -- 好!!!

https://www.cnblogs.com/qiuyong/p/6675492.html --- 二叉树遍历 java实现

猜你喜欢

转载自blog.csdn.net/zxb448126/article/details/81208609