《用Go理解并发编程》0-前言

学习并发编程必要性及重要性

并发可以看作一种程序的构造方式,其思想起源于原始的人类进化,贯穿整个计算机科学飞速发展的时代。

传统的世界观看来,世界独立个体间的任务行进是并行的,但是单个个体的任务执行序列却常常是串行的,为了进一步解放和提升生产力与生产水平,解决串行作业系统与并行化作业需求这一矛盾,并发思想应运而生。

在计算机网络与多核计算机没有得到充分发展前,并发相关的思想藏掖在不起眼的角落,相比面向对象等后续影响广而深远的,放至今日依然掷地有声的思想,并发思想在初期并未得到重视。

古语有云:“当一头牛拉不动一根圆木时,不应集中精力在培育更大更壮的牛上面。”但早期的我们却在相当长的一段时间内未遵从谚语,因此受缚。著名的摩尔定律给了人们良好的预期,似乎芯片性能的增长仰仗单位面积晶体管数量的增长就可以高枕无忧。

当计算机网络步入规模化,晶体管制程规格捉襟见肘,摩尔定律逐渐失效。大数据技术大行其道,云计算的思想也陆续扎根,横向扩展变为老生常谈的可行解决方案。亡羊补牢为时未晚,相当的软件工程人员发现似乎大部分的问题都可以通过快速“拉来几头牛”(指代横向扩展的技术方案),快速的解决它。

但是,随着“牛”的增多,调配资源、在设备之间进行通信以及汇总和存储结果都成为需要解决的问题。其中最困难的,是弄清楚如何同时对代码进行建模。再复杂的说,不但要进行正确建模,还需要研究建模结果在不同设备上的适配。

这时人们才发现原来并不是简单的多拉来几头牛,就能简单地达到提升效率的结果,“牛”与“牛”之间的配合也至关重要,而研究这种配合的艺术,就是并发设计。指导并发方案设计的则是并发思想。旧时代的破局者与新时代的捍卫者,纷纷投身运用并发、优化并发的系统研究中。其实,在大部分人们恍然大悟前,聪明人们已经开始行动并有了自己的产出,诸如Intel流水线架构,nginx服务器软件等一系列载入史册的英雄。只不过此时的时代红利尚不够多,聪明人们需要学会利用并发,压缩成本,提升效能。

到互联网、移动互联网浪潮席卷而来的时候,软件层面的高并发设计大规模应用,同分布式等其他基础软件技术的成熟一道,捧起了BAT等一系列乘上了互联网浪潮的投机者,帮助他们鲸吞时代红利,奠基后人难以企及的商业帝国。

并发思想作为一种高效的方法,不但每一位当代程序员都需要持续学习并及时吸纳更优良的方法论,而且对并发思想相关编程能力的考察,也切实的出现在了大厂招聘的加分项内。

了解并发思想,掌握并发编程,势在必行。

为何选用Golang作为并发编程学习语言

实践并发编程需要一门语言作为载体。本专栏中使用Go语言(Golang)作为并发编程的学习语言。事实上,包括知乎等多渠道推荐,Golang一直被推荐作为学习并发编程、应用并发编程的首选语言。

下面从两个方面来说明,为何选用Golang作为并发编程学习语言。

从招聘供需双方来说

如果你充分的了解过各类招聘简章,往往能够发现对于编程思想及能力的考察,很少局限于某一门特定语言。根本上说,很多思想是相通的。因而选择一种合适于供需双方的语言,最好不过。

什么是合适于供需双方的语言?在笔者看来,一个是普及性,一个是代表性。

从普及性上来看,尽管Golang在TIOBE公布的2019-2021年度编程语言排行榜上,只在前十边缘徘徊,但依据Stack Overflow每年的开发者调查数据,在最想使用的编程语言榜单中,Golang的地位稳住了第三。从github相关项目的阅读数量和star数量来看,Golang的受关注程度都在稳步提升。把握趋势,也是在投资未来

从代表性上来说,作为首个发扬当代并发核心思想CSP的编程语言,Golang天生为并发而生。Golang本身就是并发编程的代表。在对并发编程有能力要求的招聘简章内,尽管最终的工作不一定是以Golang为主业,还是会在编程语言允许考察的范围内标注上Go语言的能力。

此外,下面所有的程序,均是使用Go语言进行编写,可供各位读者参考Go语言的产业价值和影响:

  • 容器和云原生:docker、k8s,两大容器化及编排的事实标准,云原生时代的程序员应该都耳熟能详。
  • 键值与时序数据库:etcd、influxdb、consul,广泛用于监控数据存储、服务发现、配置存储等领域
  • 监控和可视化:Prometheus、grafana、open-falcon,这几个都是近几年业内监控的事实标准。

毫无疑问,这些近一个时代火热的开源软件,只要企业在运用,就大概率的会保有至少一个擅长golang的团队,用于组件后续的技术支持与二次开发。

从Golang本身处理并发的优雅性来说

从先前图片里能够看到,Golang在普及性上,入流但仅属于合格行列,从这门编程语言本身的热度上,似乎远不如Python,JavaScript。

前者是大名鼎鼎的“胶水语言”,写法浪荡不羁,丰富多样,怎么简便就可以怎么来,流行自然是不必多说,python已经嵌入了主流Linux发行版的运行环境,运维、科学计算、人工智能的日常脚本内随处可见python。坏处是,往往python写出来的复杂脚本只有作者自己能够完全明白。由于python是一门解释型语言,大型业务系统内由于Python带来的运行时低效率也一直被人们所诟病。

而后者,JavaScript,作为重要的一门前端主力语言,“单线程”已经作为了该语言的一个特点,自然不能再渴求该语言在高并发的应用上有过多建树。事实上,尽管针对多核处理器优化,HTML5引入了Web Worker标准,JavaScript仅有的能够提升并发效率的场景,依然只发生在网络交互上。这一点我们后续的内容会进行少许的深入讨论。

至于C、Java这些老牌编程语言,从历史角度看,作为并发思想变革浪潮前的老油条,完全面向新的思想一定是需要伤筋动骨的。这些老牌语言经过后人的修补,具有完备的构建并发程序的能力,但必定是不够原生与优雅的。

Golang作为后来人,一款发布于2009年的编程语言,则没有这些包袱。

首先,Golang是一门编译型语言,生产环境使用的是一个编译后的二进制文件,保持着近乎C语言的高效率。

其次,我们来看看Golang如何将一段程序置入并发运行状态:

设实现程序逻辑的函数(Function)为A

go A()

Go对于并发编程的抽象到了极致,一切的标记和初始化,都浓缩到了Go语言的名称作为的关键字“go”内部。

而另外一个令人头疼的并发过程间信息同步(Java内一般强调多线程同步),如果B过程需要安全地从A过程内拿到结果产出,Golang是这么做的:

在函数A内,将结果送入一个名为res的“通道”

a=1
res <- a

在函数B内,从“通道”res内取出A送入的结果

b <- res

整个过程无需再加上其他的锁或者是同步机制。一个“<-”符号代表信息流转,形象生动且高效。

基于如此简洁和强大的抽象,我们可以将精力投入到更加高层的思考活动中,去更好的进一步思考我们程序的建模,以及如何更好的通过编程解决我们的问题。

总结

并发思想在当下是重要的,应用并发思想,对程序员来说,就需要学习并发编程。而Golang用来学习并发编程无疑是优雅、合适的。新兴项目和招聘方对Golang人才的需求有目共睹。

希望读者们能通过完整的本专栏学习,获益良多,谢谢。

全部评论

相关推荐

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