好资源和短想法
你好,我是王争。

在设计专栏内容的时候,为了兼顾不同基础的同学,我在内容上做到了难易结合,既有简单的数组、链表、栈、队列这些基础内容,也有红黑树、BM、KMP 这些难度较大的算法。但是,对于初学者来说,一下子面对这么多知识,可能还是比较懵。

我觉得,对于初学者来说,先把最简单、最基础、最重要的知识点掌握好,再去研究难度较高、更加高级的知识点,这样由易到难、循序渐进的学习路径,无疑是最合理的。

基于这个路径,我对专栏内容,重新做了一次梳理,希望给你一份具体、明确、有效的学习指导。我会写清楚每个知识点的难易程度、需要你掌握到什么程度、具体如何来学习。

如果你是数据结构和算法的初学者,或者你觉得自己的基础比较薄弱,希望这份学习指导,能够让你学起来能更加有的放矢,能把精力、时间花在刀刃上,获得更好的学习效果。

下面,我先给出一个大致的学习路线。



(建议保存后查看大图)
现在,针对每个知识点,我再给你逐一解释一下。我这里先说明一下,下面标记的难易程度、是否重点、掌握程度,都只是针对初学者来说的,如果你已经有一定基础,可以根据自己的情况,安排自己的学习。

1. 复杂度分析
尽管在专栏中,我只用了两节课的内容,来讲复杂度分析这个知识点。但是,我想说的是,它真的非常重要。你必须要牢牢掌握这两节,基本上要做到,简单代码能很快分析出时间、空间复杂度;对于复杂点的代码,比如递归代码,你也要掌握专栏中讲到的两种分析方法:递推公式和递归树。

对于初学者来说,光看入门篇的两节复杂度分析文章,可能还不足以完全掌握复杂度分析。不过,在后续讲解每种数据结构和算法的时候,我都有详细分析它们的时间、空间复杂度。所以,你可以在学习专栏中其他章节的时候,再不停地、有意识地去训练自己的复杂度分析能力。

难易程度:Medium

是否重点:10 分

掌握程度:在不看我的分析的情况下,能自行分析专栏中大部分数据结构和算法的时间、空间复杂度

2. 数组、栈、队列
这一部分内容非常简单,初学者学起来也不会很难。但是,作为基础的数据结构,数组、栈、队列,是后续很多复杂数据结构和算法的基础,所以,这些内容你一定要掌握。

难易程度:Easy

是否重点:8 分

掌握程度:能自己实现动态数组、栈、队列

3. 链表
链表非常重要!虽然理论内容不多,但链表上的操作却很复杂。所以,面试中经常会考察,你一定要掌握。而且,我这里说“掌握”不只是能看懂专栏中的内容,还能将专栏中提到的经典链表题目,比如链表反转、求中间结点等,轻松无 bug 地实现出来。

难易程度:Medium

是否重点:9 分

掌握程度:能轻松写出经典链表题目代码

4. 递归
对于初学者来说,递归代码非常难掌握,不管是读起来,还是写起来。但是,这道坎你必须要跨过,跨不过就不能算是入门数据结构和算法。我们后面讲到的很多数据结构和算法的代码实现,都要用到递归。

递归相关的理论知识也不多,所以还是要多练。你可以先在网上找些简单的题目练手,比如斐波那契数列、求阶乘等,然后再慢慢过渡到更加有难度的,比如归并排序、快速排序、二叉树的遍历、求高度,最后是回溯八皇后、背包问题等。

难易程度:Hard

是否重点:10 分

掌握程度:轻松写出二叉树遍历、八皇后、背包问题、DFS 的递归代码

5. 排序、二分查找
这一部分并不难,你只需要能看懂我专栏里的内容即可。

难易程度:Easy

是否重点:7 分

掌握程度:能自己把各种排序算法、二分查找及其变体代码写一遍就可以了

6. 跳表
对于初学者来说,并不需要非得掌握跳表,所以,如果没有精力,这一章节可以先跳过。

难易程度:Medium

是否重点:6 分

掌握程度:初学者可以先跳过。如果感兴趣,看懂专栏内容即可,不需要掌握代码实现

7. 散列表
尽管散列表的内容我讲了很多,有三节课。但是,总体上来讲,这块内容理解起来并不难。但是,作为一种应用非常广泛的数据结构,你还是要掌握牢固散列表。

难易程度:Medium

是否重点:8 分

掌握程度:对于初学者来说,自己能代码实现一个拉链法解决冲突的散列表即可

8. 哈希算法
这部分纯粹是为了开拓思路,初学者可以略过。

难易程度:Easy

是否重点:3 分

掌握程度:可以暂时不看

9. 二叉树
这一部分非常重要!二叉树在面试中经常会被考到,所以要重点掌握。但是我这里说的二叉树,并不包含专栏中红黑树的内容。红黑树我们待会再讲。

难易程度:Medium

是否重点:9 分

掌握程度:能代码实现二叉树的三种遍历算法、按层遍历、求高度等经典二叉树题目

10. 红黑树
对于初学者来说,这一节课完全可以不看。

难易程度:Hard

是否重点:3 分

掌握程度:初学者不用把时间浪费在上面

11. B+ 树
虽然 B+ 树也算是比较高级的一种数据结构了,但是对初学者来说,也不是重点。有时候面试的时候还是会问的,所以这一部分内容,你能看懂专栏里的讲解就可以了。

难易程度:Medium

是否重点:5 分

掌握程度:可看可不看

12. 堆与堆排序
这一部分内容不是很难,初学者也是要掌握的。

难易程度:Medium

是否重点:8 分

掌握程度:能代码实现堆、堆排序,并且掌握堆的三种应用(优先级队列、Top k、中位数)

13. 图的表示
图的内容很多,但是初学者不需要掌握那么多。一般 BAT 等大厂面试,不怎么会面试有关图的内容,因为面试官可能也对这块不会很熟悉哈:)。但是,最基本图的概念、表示方法还是要掌握的。

难易程度:Easy

是否重点:8 分

掌握程度:理解图的三种表示方法(邻接矩阵、邻接表、逆邻接表),能自己代码实现

14. 深度广度优先搜索
这算是图上最基础的遍历或者说是搜索算法了,所以还是要掌握一下。这两种算法的原理都不难哈,但是代码实现并不简单,一个用到了队列,另一个用到了递归。对于初学者来说,看懂这两个代码实现就是一个挑战!可以等到其他更重要的内容都掌握之后,再来挑战,也是可以的。

难易程度:Hard

是否重点:8 分

掌握程度:能代码实现广度优先、深度优先搜索算法

15. 拓扑排序、最短路径、A* 算法
这几个算法稍微高级点。如果你能轻松实现深度、广度优先搜索,那看懂这三个算法不成问题。不过,这三种算法不是重点。面试不会考的。

难易程度:Hard

是否重点:5 分

掌握程度:有时间再看,暂时可以不看

16. 字符串匹配(BF、RK)
BF 非常简单,RK 稍微复杂点,但都不难。这个最好还是掌握下。

难易程度:Easy

是否重点:7 分

掌握程度:能实践 BF 算法,能看懂 RK 算法

17. 字符串匹配(BM、KMP、AC 自动机)
这三个算法都挺难的,对于算法有一定基础的人来说,看懂也不容易。所以,对于初学者来说,千万别浪费时间在这上面。即便有余力,看懂就好了,不用非得能自己实现。

难易程度:Hard

是否重点:3 分

掌握程度:初学者不用把时间浪费在上面

18. 字符串匹配(Trie)
这个还是要能看懂,不过不需要能代码实现。有些面试官喜欢考这个东西,主要是结合应用场景来考察,只是看你知不知道要用 Trie 树这个东西。

难易程度:Medium

是否重点:7 分

掌握程度:能看懂,知道特点、应用场景即可,不要求代码实现

19. 位图
位图不是重点,如果有余力最好掌握一下。

难易程度:Easy

是否重点:6 分

掌握程度:看懂即可,能自己实现一个位图结构最好

20. 四种算法思想
这个是重点,也是难点。贪心、分治、回溯、动态规划,每一个都不简单,其中动态规划又是最难、最烧脑的。要应付 FLAG 这样公司的面试,必须拿下这块内容。但是呢,学习要循序渐进,这块能内容的学习可以放到最后,做个长时间的学习计划来攻克。

这块内容理论的东西不多,要想真的掌握,还是要大量刷题。

难易程度:Hard

是否重点:10 分

掌握程度:可以放到最后,但是一定要掌握!做到能实现 Leetcode 上 Medium 难度的题目
Netty的学习过程:
1. Hello World案例
2. 点对点通信
3. 聊天室
4. 加入心跳检测机制
5. 整合Protobuf技术
6. .....
7. Netty的案例库

如何进一步:
1. 搭建微服务
2. 在微服务整合的过程中持续增加特性,例如消息队列,缓存,分布式事务
The Go Programming Language Specification,这是Go语言的,作用同上: https://jiajunhuang.com/sharing#415
The Python Language Reference,Python语言的说明书,基本上读完以后,每一行Python代码背后会发生什么,心里都有个底: https://jiajunhuang.com/sharing#414
1. Dubbo的扩展机制
在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性。 如同罗马不是一天建成的,任何系统都一定是从小系统不断发展成为大系统的,想要从一开始就把系统设计的足够完善是不可能的,相反的,我们应该关注当下的需求,然后再不断地对系统进行迭代。在代码层面,要求我们适当的对关注点进行抽象和隔离,在软件不断添加功能和特性时,依然能保持良好的结构和可维护性,同时允许第三方开发者对其功能进行扩展。在某些时候,软件设计者对扩展性的追求甚至超过了性能。

在谈到软件设计时,可扩展性一直被谈起,那到底什么才是可扩展性,什么样的框架才算有良好的可扩展性呢?它必须要做到以下两点:

作为框架的维护者,在添加一个新功能时,只需要添加一些新代码,而不用大量的修改现有的代码,即符合开闭原则。
作为框架的使用者,在添加一个新功能时,不需要去修改框架的源码,在自己的工程中添加代码即可。
Dubbo很好的做到了上面两点。这要得益于Dubbo的微内核+插件的机制。接下来的章节中我们会慢慢揭开Dubbo扩展机制的神秘面纱。

2. 可扩展的几种解决方案
通常可扩展的实现有下面几种:

Factory模式
IoC容器
OSGI容器
Dubbo作为一个框架,不希望强依赖其他的IoC容器,比如Spring,Guice。OSGI也是一个很重的实现,不适合Dubbo。最终Dubbo的实现参考了Java原生的SPI机制,但对其进行了一些扩展,以满足Dubbo的需求。
对一天中做的每件事问个为什么。
深思身边至少3个人的思维策略的不同。
写篇有自己想法的博客。
读一个优秀开源库的源代码。
写一个小工具代码,把它优化到极致。
写个main测下你正在用的某个库的性能。
事太多,处理不完?生活/工作?
保持节奏感,踩在点上办事。
做好计划,控制风险。
管理好自己的时间,保持大块时间。
主动办要事,而不要被动办急事。
角色平衡。
什么样的人能更快晋升?
做好自己,技术实力强,有深度,也有宽度。
对事专注,持之以恒,将事情做到极致,发挥自己的长处,成为专家。
传道授业,对内对外分享,帮助手边的人成长,影响力大。
主动性强,不只做好手上的事,还能推动事情的发展,独挡一面。
有高度,能先人一步思考,找到方向,找到落地点。
爱问为什么
为什么要Action -> Service -> Dao?为什么要服务化?
为什么要在范儿图片推荐第三行插入话题推荐,而不是第一行?
为什么他会这么思考问题,而我不会?
爱总结
书上那些原则,那些理论体系怎么来的?不就是作者总结的?为什么不自己总结?
自己总结,自己发明理论。不会,多写就会。
爱质疑
从小教科书就把各种知识全当真理教给了我。我智商低,别骗我。
喜欢有“此理论未被证明”或”与实验结论不符”或“下一章推翻上一章”的书。
看到开源软件自吹性能多牛,一定要自己动手去测一测。(一个main函数+多个线程就够了,别被搭性能环境吓着)
梁飞的看书方式:
爱看书
爱看写作者思想的书,不爱看工具用法的书。
爱看只讲一个观点的书,不爱看堆彻作者所有知识的书。
喜欢把书中引用的书,接龙看下去。
爱看源码
看Linux,JDK,Spring等开源代码。
看不懂就自己写一个或一部分。
看自己写的代码。