《并发哲学:从编程入道到开悟升天》5.1 你学到了什么?

你学到了什么?

现在,作为最终的收官章节,我们有必要全面总结一下本书内容。

全书内容串讲

第一章,我们从生活朴素思考——人能否同时话方圆切入,开始考虑并发的问题。在日常问题的解决中,我们往往会遇到如下的难题:

  • 如果一个实体自身无法在同一个时间点做两件事情,如何改进才可以让一个实体在同一时间点做两件事情?

从语句逻辑上来说,这本身就蕴含着矛盾:一个看起来无法完成的任务,需要我们得出解决方案。所以,我们需要以这一基本矛盾为原点,做出考虑面的延伸,以退让求解。

通过引入其他实体和自然规律,我们发现了解决这个问题的方案:

  • 借助其他实体,综合考虑整个系统的同时性,系统内部从逻辑上来说可以存在同时了!

如果我们考虑的是一根神经如何同时传导两种不同电信号,可能无法得出答案。但如果再引入两条神经,第一条神经通过切换作业的方式将任务依次传导给第二和第三条神经,从系统层面上考虑这两条链路,他们可以同时传导两种电信号。

如果我们考虑的是一个人如何在攻击的瞬间同时进行完美防御,可能无法得出较好的答案。只要开始攻击,发起攻击的瞬时恰好是防御弱点。但是依托投掷,我们把整个系统扩充到“一个攻击流程”,那么完美的攻击和完美的防御就可以做到同时发生,因为石头的自然飞行不再影响到个人的其他行为。

生物学和考古学分别支持了这两个论点。更惊奇的在于,考古学发现了人类在进化出投掷能力后,紧随着飞速发展了语言讲解和社会协调能力,这一切都为高度细化分工、社会化产生、人类的高速发展奠定了基础。

这是并发最基础的哲学起源。在现代,计算机的发展浪潮里,进入21世纪几乎每一个变革性关键潮流的到来,背后的基础能力都不再离开并发的优化。面对并不在稀缺的资源,人们却没有因为盲目追求并行处理能力而固步自封。某种程度上说,固步自封的人已经被淘汰。时代的新秀总能告诉你,如何用有限资源灵活调配,面对更大的瞬时请求然后飞速的将他们化解掉,成为一个时代的霸主。

我们看到了intel,nginx,各种因为互联网浪潮而诞生的野蛮技术霸主。

并发能力应是必知必会。

第二章,我们简要阐述了广泛流传于社会上的一些理解误区,进行了本书进一步学习在理解经验层面上的“拨乱反正”。

本身理解的方式是可以多种多样的,但是理解的关注点不同,却有可能引导我们走向不同的实践终点。本书批判了包括跑道模型在内的,仅关注并发思想一部分的理解方式。局限性,不从系统层面考虑并发的种种理解方式,无疑加重了人们的思想负担。人们会发现随着自己知识水平的扩展,原有的体系不支持延伸,只能重构。但可喜的地方在于,经过大浪淘沙优秀选择下来的理解方式阐述,我们都能从这些优秀的案例内看到最朴素关于生活日常任务安排的抽象。

于是,我们跟随正确的方向,再结合并发思想的哲学起源,构建出了我们认为无比正确和具有良好扩展性的两种理解方式:

  • 以关注人-物交互为核心的投掷者模型
  • 以关注人-人交互为核心的包工头模型

在后续的所有关于并发代码和设计模式的理解内,你都能找到我们围绕人-物和人-人为基本蓝图展开的易于理解的阐述。我们把关注点可以说第一次史无前例的加强在人类分工协调,和自然规律利用上。

从朴素哲学思想,到最终并发实践,我们通过与生活联系和日常认知紧密相关的理解方法构建桥梁,为之后的学习奠定了基础。

第三章,我们正式开始实践并发编程。通过选型,我们了解到Golang由于其良好的可读性、优秀的并发原语抽象,成为了首选的并发编程学习语言。

首先我们了解了Golang基本语法,然后我们着重关注了一下Golang关于并发的三大特性,随后我们了解了Golang在并发编程中常见的范式,以及基于基本要素和范式,如何通过融合构建可伸缩并发设计构建更加具有规模和价值的代码工程。如果你学有余力的话,不妨也看一下3.4节,学习在各大编程语言内理解通用的以内存访问同步为指导思想的具有CSP风格的并发原语,包括锁、池等多种实现。

通过第三章学习,你应该至少掌握Golang的基本语法、Golang构建并发的提及要素,并对构建良好并发程序有自己的理解。

有了编程实践的参考,思考很多其他的问题变得有特殊的意义。

随后,在第四章,我们能够以代码的案例,研究背后的奥妙。审视并发代码编写中我们需要考虑的,可能会导致灾难性结果的问题,包括数据竞争、原子性、锁。审视在系统设计中,抽象层面的关注点问题——应该以实际需求为导向决定面对实际需求编程中的关注点,这也是Golang能够爆火的一大原因。我们的止部抽象链作用于协程,获得了无比良好的基于实际世界的抽象,于是我们通过系统体系化的构建,营造了一个模拟的“李华的早晨”。

在并发思想指导和解决需求为最终目的的方针下,我们用别样的视角重新审视了进程、线程、协程等我们先前熟知的概念,重新审视了传统意义上的代码抽象和建模,重新审视了我们日常的生活……

把握巨人的力量

在探讨一个完整的技术case的时候,我们往往会关心是否一次技术学习涵盖了所有的技术相关点,却往往忽视了需求导向。这个很明显的表现就在于,你可以用八股文的形式把一个编程语言所有的基本语法、范式记忆下来,但是却依旧无法构建良好的代码工程。一方面是代码工程的构建本身需要良好的软件工程基础,更广泛的说,这是程序员引以为傲的工程化思维的价值;另一方面是,为了追求效率,面对全新的需求,我们提倡的做法应该是基于需求拆分case,再选型技术工具能否满足我们的需求。

我们绝对不能在解决问题的过程中,陷入无限探寻底层技术细节的怪圈。Golang就是一个很好的例子,相信如果你是能够准确把握生活中任务流转关系的人,那么一定会在解决这类需求的时候选型Golang作为编程语言。

但即便是选用Golang作为编程语言,Golang本身的知识点也数不胜数。细心或对Golang并发语言体系有事先了解的读者可能会发现,即便是在并发这个Golang语言能力的一个子集,我们在本书中试图尽力的去避开传统的锁原语,甚至没有提及context等其他书籍内认为比较重要的用于控制并发的工具。

这是为什么呢?

原因就在于,我们自始自终没有把本书作为Golang的一本技术书籍,从第一章开始我们介绍的是并发思想的起源,而不是Golang的起源,这就意味着我们将技术case的探讨严格局限在解决并发实际需求的必需上。这再一次体现了我们的需求与结果导向。

是否可以根据本书的知识点构建出优秀且正确的并发代码呢?答案是肯定的。以context知识点没有在本书中出现的解释,context本质上是一个融合了并发设计中对取消、监测、错误记录基本要素的工具,利用done通道和其他的监测手段,一样可以实现context的功能。从这个角度看,context是一种用于维护链式关系上消息记录和传送的工具,本质上并不是为了并发而生的原语——而且是否应该在并发中使用context来传递消息直到现在都还有争议。这也是golang直到很晚的时候才将context作为标准库的一个原因,而且很大程度还是受到了java等其他主流语言的影响,用context来弥补golang在链式关系上调试的一些不足。

上述的讨论,引出的问题就是我们如何把握巨人的力量。从头到尾讲述Golang基本知识的书籍,和从头到尾讲述并发基本概念的书籍,比比皆是。但是以编程语言为技术手段,将并发这一方法论说明白,并细化到具体工程实践,最终再反过来抽象思考的书籍,本书一定走在了前列。

如何算是把握住了巨人的力量,这就需要我们创造的价值进行衡量。作者我认为,能够以最高效的方式,把握一个语言关于并发的基本技术点,并切实对代码建模精确化和提速,最终能够快速、方便的写出正确的代码,提升运行效率和负载能力,这就是把握住了巨人的力量。

因而读者也能看到,即便是我们深入代码背后,我们也没有花很大的功夫在讲述线程如何调度、进程如何管理、协程上下文如何切换,毕竟在这个知识点,我们的主题就在于“止部抽象链”。延展抽象链可以带来更多的知识,止部抽象链可以带来更大的价值。

从抽象到代码实践

我们在第三章的前几节,都以近乎标准的代码,介绍了Golang关于并发的基本技术要素。但是在看起来最需要实际代码来展示“伟大工程的壮丽”的3.7,我们却放弃了代码堆砌的讲述方式,转而选择用尽可能易于理解的语言,说清楚这些优化点是为什么应该考虑,他们应该以什么机制来工作。我们将具体的编码工作无限延期,如果顺利的话,你可以看一下附录,随着时间得推移,我们相信这些较大规模的代码组织一定还有更大的优化空间,但是最底层的各种优化建议却是相对独立的,这又是一种“分离”的艺术。

和并行与并发的关注点分离一样,优秀的并发设计应该考虑优化关键点,而不是具体的代码实现。具体如何快速正确的将并发要素按照良好的并发设计组织到一起,这体现的是如何熟练的书写代码。

提升代码抽象能力是成为高阶代码工程师的必备要素,这一点也是希望读者能够通过我们书本的内容组织体会到的。

内容关系链

总的说来,我们本书关注如下的一条内容关系链,希望能够帮助你理顺并梳理出完整的学习价值:

并发思想起源->并发思想连接生活实际的理解方式->构建并发的基本要素->如何按照生活实际理解方式组织并发基本要素->按照这种方法论构建的代码一定严格贯穿并发思想->了解并发编程内屏蔽的要素和并发编程带来的附属价值

全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务