对于数据结构和算法、计算机操作系统等底层的知识,首先想说一句话,代的账迟早是要还的【除非自己不想往更高的方向走】。对于为什么要学习数据结构和算法,自己觉得还是走了很多的弯路。怎样建立自己的知识体系【自己】,现在对于工作年限的增加,行业对于人才需求是什么【环境】,总不是随着年限的增加仅仅是写不完的项目经验,永远停留在基础的重复的劳动(无脑)上。如果用武功来形容整个知识体系的话,上层的体现就是招式并且招式变化特别快【如果mq,前几年流行rabbitmq现在流行kafka并且层出不穷;比如数据库持久化框架ORM,前几年流行Hibernate、jpa可能现在流行Mybatis】,而底层的内功比如计算机操作系统、网络知识、以及最底层的数据结构和算法【特别是数据结构和算法本身可能几十年了就没有什么变化,并且都是前人总结的经验和经过时间考验的结晶】。
刚入行时总是在不断的追求招式,并且学的是皮毛的皮毛,比如数据库根本没有深入的学,然后又去学Spring,刚开始工作肯定是需要快速建立自己的广度的,但是如果工作多年后还是没有在某些领域有自己的深度,那么将是非常可怕的事情。近年最深的感触就是当每学一个东西深入之后就一直往下钻,最后发现像建楼房一样,高度越高则要求地基更深。比如并发编程,最终就会回到计算机Cpu高速缓存、底层指令、内存屏障等;学Mysql为什么使用B+数,那么多读写时间复杂度是OlogN的数据结构(红黑树、跳表、散列表)为什么不选,深入学习Mysql之后会涉及:B+树,快排、操作系统的数据缓存页、变种的LRU淘汰数据缓存页的数据结构和算法【将其分成young区和old区】等;Redis深入学习之后发现其不仅仅是将数据存储到内存中,同样用到了LRU,为什么使用单线程处理任务、底层使用了(散列表、压缩列表、跳表、整数数组、双向链表)的数据结构,NIO或者说epoll处理请求、操作系统层面父子进程fork操作、Raft分布式算法、一致性hash算法等。所有优秀的产品都是深刻理解其特性之后,对底层权衡之后的结果。而整体知识体系就像是一个倒三角形,上层就是不断变化的武功招式,底层就是内功,自己最好是能自上而下融会贯通不要出现断层。其中底层的底层就是数据结构和算法,如果代的账迟早是要还的,并且走再多的弯路最后都会回到底层,那么就从现在开始吧。
数据结构和算法一般会涉及到论证过程,而很多论证过程是非常复杂的。自己也买过算法导论之类的书,然后就慢慢淹没在看不懂的求证、分析中,就没有然后了。所以,最好是带着疑问带着好奇心去慢慢的深入,当然了这也是很多面试的必须课。什么是数据结构和算法?数据结构就是组织一组数据的存储结构,是【静态】的;算法是操作数据的一组方法,是作用在某种特定的数据结构之上的【是动态的】。所以,算法脱离了数据结构是没有任何意义的,比如二分查找一定在操作在有序的数组上的,需要利用下标随机访问的特定,而链表就无法发挥O(logN)的查询效率了。数据结构本身是静止的状态,没有算法动态处理,也就没有任何的意义了(比如:对数据进行排序,将用户想要的订单时间倒序展示,实现数据的价值)。
常用的数据结构:
数组、链表、栈、队列、散列表【hash表】、跳表、树【平衡二叉搜索树、堆、Trie树、红黑树、B+树】、图
那么怎么理解这些数据结构呢,他们之间有什么联系?进行分组。
1)、线性表
数组、链表、栈、队列都是线性表(其他的称为非线性表)。数组就是在内存中一次性申请开辟连续的空间,链表由多个节点内部使用前驱和后继指针指向其他节点,栈是先进后出、队列是一头进一头出(dqueue除外)。可以理解栈和队列是受限的数组或链表。
2)、树
单链表只有后驱指针指向下一个节点的内存地址,那么每个节点是否可以有两个或者多个后驱指针呢?那么树就出现了。当然双链表也是可以的,即树也可以在子节点中,存储指向父节点的指针。其形状就像是一颗倒立的树。常用的树有:二叉树(即父节点可以有两个子节点),而红黑树、堆、B+树都是特殊的树,或者是受限的树。
3)、图
树特别的形象,但是只有父子关系指向。那么可不可以有一个节点,允许一个子节点,指向其父辈的其他节点(叔叔)、或者其他旁系分支呢?那么就会有环存在,图就出现了。常用的图有:有限状态转换器(FST)、有向无环图等应用。
4)、数据结构组合
散列表:数组和链表(红黑树等)数据结构的结合【开放寻址法只有数组】,并且用到了hash函数或者hash算法;
跳表:数组和链表的结合
B+树:严格的说,B+树算是树和链表的结合
常用的算法:
排序、递归、二分查找、Hash算法、一致性Hash算法、动态规划、回溯算法、贪心算法、归并算法【或思想】、动态规划、字符串匹配算法、搜索
常用的排序算法:
O(N²)的【冒泡排序、插入排序、选择排序】、O(N*logN)的【归并排序、快速排序、堆排序、二分插入排序、希尔排序】、O(n)的【桶排序、计数排序、基数排序】