58加餐:不定期福利-第二期 王争:羁绊前行的,不是肆虐的狂风,而是内心的迷茫
你好,我是王争。
专栏更新过半,我发现有些小伙伴已经掉队,虽然有人掉队也挺正常,但是我还是想尽量拉一把。于是,周末的时间,我就在想,究竟是什么原因让有些小伙伴掉队了?是内容本身太难了吗?是我讲得不够清楚吗?还是小伙伴本身基础太差、不够努力、没有掌握学习方法?
你好,我是王争。
专栏更新过半,我发现有些小伙伴已经掉队,虽然有人掉队也挺正常,但是我还是想尽量拉一把。于是,周末的时间,我就在想,究竟是什么原因让有些小伙伴掉队了?是内容本身太难了吗?是我讲得不够清楚吗?还是小伙伴本身基础太差、不够努力、没有掌握学习方法?
你好,我是王争。欢迎来到不定期更新的周末福利时间。
专栏已经上线两周了,看到这么多人在留言区写下自己的疑惑或者观点,我特别开心。在留言里,很多同学让我推荐一些学习数据结构与算法的书籍。因此我特意跟编辑商量了,给你一个周末福利。所以这一期呢,我们就来聊一聊数据结构和算法学习过程中有哪些必读书籍。
有的同学还在读大学,代码还没写过几行;有的同学已经工作数十年,这之间的差别还是挺大的。而不同基础的人,适宜看的书是完全不一样的。因此,针对不同层次、不同语言的同学,我分别推荐了不同的书。希望每个同学,都能找到适合自己的学习资料,都能在现有水平上有所提高。
短网址服务你用过吗?如果我们在微博里发布一条带网址的信息,微博会把里面的网址转化成一个更短的网址。我们只要访问这个短网址,就相当于访问原始的网址。比如下面这两个网址,尽管长度不同,但是都可以跳转到我的一个GitHub开源项目里。其中,第二个网址就是通过新浪提供的短网址服务生成的。
1 | 原始网址:https://github.com/wangzheng0822/ratelimiter4j |
从功能上讲,短网址服务其实非常简单,就是把一个长的网址转化成一个短的网址。作为一名软件工程师,你是否思考过,这样一个简单的功能,是如何实现的呢?底层都依赖了哪些数据结构和算法呢?
微服务是最近几年才兴起的概念。简单点讲,就是把复杂的大应用,解耦拆分成几个小的应用。这样做的好处有很多。比如,这样有利于团队组织架构的拆分,毕竟团队越大协作的难度越大;再比如,每个应用都可以独立运维,独立扩容,独立上线,各个应用之间互不影响。不用像原来那样,一个小功能上线,整个大应用都要重新发布。
不过,有利就有弊。大应用拆分成微服务之后,服务之间的调用关系变得更复杂,平台的整体复杂熵升高,出错的概率、debug问题的难度都高了好几个数量级。所以,为了解决这些问题,服务治理便成了微服务的一个技术重点。
所谓服务治理,简单点讲,就是管理微服务,保证平台整体正常、平稳地运行。服务治理涉及的内容比较多,比如鉴权、限流、降级、熔断、监控告警等等。这些服务治理功能的实现,底层依赖大量的数据结构和算法。今天,我就拿其中的鉴权和限流这两个功能,来带你看看,它们的实现过程中都要用到哪些数据结构和算法。
Disruptor你是否听说过呢?它是一种内存消息队列。从功能上讲,它其实有点儿类似Kafka。不过,和Kafka不同的是,Disruptor是线程之间用于消息传递的队列。它在Apache Storm、Camel、Log4j 2等很多知名项目中都有广泛应用。
之所以如此受青睐,主要还是因为它的性能表现非常优秀。它比Java中另外一个非常常用的内存消息队列ArrayBlockingQueue(ABS)的性能,要高一个数量级,可以算得上是最快的内存消息队列了。它还因此获得过Oracle官方的Duke大奖。
如此高性能的内存消息队列,在设计和实现上,必然有它独到的地方。今天,我们就来一块儿看下,Disruptor是如何做到如此高性能的?其底层依赖了哪些数据结构和算法?
像百度、Google这样的搜索引擎,在我们平时的工作、生活中,几乎天天都会用到。如果我们把搜索引擎也当作一个互联网产品的话,那它跟社交、电商这些类型的产品相比,有一个非常大的区别,那就是,它是一个技术驱动的产品。所谓技术驱动是指,搜索引擎实现起来,技术难度非常大,技术的好坏直接决定了这个产品的核心竞争力。
在搜索引擎的设计与实现中,会用到大量的算法。有很多针对特定问题的算法,也有很多我们专栏中讲到的基础算法。所以,百度、Google这样的搜索引擎公司,在面试的时候,会格外重视考察候选人的算法能力。
今天我就借助搜索引擎,这样一个非常有技术含量的产品,来给你展示一下,数据结构和算法是如何应用在其中的。
到此为止,专栏前三部分我们全部讲完了。从今天开始,我们就正式进入实战篇的部分。这部分我主要通过一些开源项目、经典系统,真枪实弹地教你,如何将数据结构和算法应用到项目中。所以这部分的内容,更多的是知识点的回顾,相对于基础篇、高级篇的内容,其实这部分会更加容易看懂。
不过,我希望你不要只是看懂就完了。你要多举一反三地思考,自己接触过的开源项目、基础框架、中间件中,都用过哪些数据结构和算法。你也可以想一想,在自己做的项目中,有哪些可以用学过的数据结构和算法进一步优化。这样的学习效果才会更好。
好了,今天我就带你一块儿看下,经典数据库Redis中的常用数据类型,底层都是用哪种数据结构实现的?
时间复杂度是衡量算法执行效率的一种标准。但是,时间复杂度并不能跟性能划等号。在真实的软件开发中,即便在不降低时间复杂度的情况下,也可以通过一些优化手段,提升代码的执行效率。毕竟,对于实际的软件开发来说,即便是像10%、20%这样微小的性能提升,也是非常可观的。
算法的目的就是为了提高代码执行的效率。那当算法无法再继续优化的情况下,我们该如何来进一步提高执行效率呢?我们今天就讲一种非常简单但又非常好用的优化方法,那就是并行计算。今天,我就通过几个例子,给你展示一下,如何借助并行计算的处理思想对算法进行改造?
在第48节中,我们讲了MySQL数据库索引的实现原理。MySQL底层依赖的是B+树这种数据结构。留言里有同学问我,那类似Redis这样的Key-Value数据库中的索引,又是怎么实现的呢?底层依赖的又是什么数据结构呢?
今天,我就来讲一下索引这种常用的技术解决思路,底层往往会依赖哪些数据结构。同时,通过索引这个应用场景,我也带你回顾一下,之前我们学过的几种支持动态集合的数据结构。
魔兽世界、仙剑奇侠传这类MMRPG游戏,不知道你有没有玩过?在这些游戏中,有一个非常重要的功能,那就是人物角色自动寻路。当人物处于游戏地图中的某个位置的时候,我们用鼠标点击另外一个相对较远的位置,人物就会自动地绕过障碍物走过去。玩过这么多游戏,不知你是否思考过,这个功能是怎么实现的呢?