原文
## 概述
- 过去几年,一颗新星正冉冉升起,他就是go语言。没有比一门新语言更令开发者高潮的吧?(不接受反驳)所以呢,作者就学了4到5个月就开始要吹go了,且看他如何吹(我也是边看边敲的)。
- 本文主旨是解释当前的计算机软硬件处于哪个发展阶段,以及为啥我们需要一门向go这般的新语言。如果没有问题,也就不存在什么解决办法是不是。注意,这里不是教
hello, world!
的。
硬件限制
-
摩尔定律在凋零。2004年,Intel 推出奔腾4处理器,3.0GHz的时钟频率。现在,俺的MBP2016的时钟频率是2.9GHz。所以呢,一个十年过去(这篇文章是2017年写的),处理性能几乎没啥变化(四舍五入,忽略不计)。
- 看看上面这张图,单线程性能,时钟频率,在过去十年几乎是稳定的。如果你想多塞点晶体管进去看能不能提高性能,那你就错了。你要问我为什么,我也说不清,无非是在那个量级上,量子相关属性开始有影响(量子隧道?),再多塞点晶体管已经越来越不容易了,代价越来越大,性价比不高了。
- 当前的解决方案是:厂商给处理器多加核心,四核八核都已经很常见了;引入超线程;引入跟多的缓存增加性能。
- 每个解决方案也有自己的局限性。缓存也有它的物理限制—-越大的缓存,获取数据也越慢。多核也有代价,而且也不能无限增加啊。多核处理器可以同时跑多线程,这就带来了并发的问题了。后面再说。
- 既然不能依赖硬件的改进,剩下唯一的办法就是软件更高效。可惜,当代编程语言并不是那么有效率。
Go有goroutines!!
- 多核在不远将来的趋势是核心数的进一步增加;当今的应用也使用了很多微服务来维护数据库连接,消息队列以及缓存等。所以软件还有编程语言应该更容易支持并发,并且随着核心数的增加可扩展。
- 现在很多语言(如Java,Python等)都是从上世纪90年代单线程环境发展起来的。虽然很多支持多线程,但是真正的问题其实是并发执行,线程锁,竞争条件,死锁等。这么些个令人头疼的问题,让创建多线程的应用很麻烦,尤其在这些语言上。
- 想想吧,在Java上创建一个线程并不能有效利用内存。每个线程都要在堆上消耗大约1MB,几千个线程跑起来的话,堆的压力那是很大的,很容易内存不足。线程间的通信也挺麻烦的。
- 来来来,看看2009年发布的go。这时的多核都很常见了,Go创建时就是时时把并发问题放在心上的。它用goroutines,而不是线程。每个goroutine几乎只消耗2KB,所以百万goroutines都不在话下。
- 其他的好处还有:
- Goroutines具有可增长性的分段式栈,意味着如果需要,可以使用更多的内存。
- Goroutines具有比线程更快的启动时间。
- Goroutines具有内建的原语来进行他们之间的通信(即channels)。
- 在共享数据结构时,Goroutines可以避免使用互斥锁。
- Goroutines与OS线程并不是1:1的映射关系,一个goroutine可以再多个线程上运行。多个goroutines也可以多个OS线程上运行。
- 综上,Go既可以提供像Java,C/C++那样强大的并发处理能力,也可以让并发的执行代码像Erlang一样显得直接且漂亮。
Go直接在硬件上运行
C/C++相比于其他高级语言像Java/Python,一个显著的优势是性能。C/C++是编译型语言,而不是解释型的。
处理器只懂二进制。当你用Java或是其他基于JVM的语言时,总是会先把代码编译成JVM或是其他虚拟机可以识别的字节码,这些虚拟机时运行在OS之上的。执行时,VM解释这些字节码,转换为处理器可识别的二进制码。C/C++没有虚拟机的概念,它是直接把代码编译成二进制码,减少了执行周期,提高性能。但是释放和分配内存是个令人头疼的问题。与此同时,很多语言都通过垃圾回收器,或是引用计数算法来处理对象分配和释放的。
Go集大成。像C/C++一样稍低级的语言一样,Go是编译型语言。因此性能与C/C++相当。而且使用了垃圾回收机制来分配和释放对象。所以说,可以跟
malloc()
和free()
语句说拜拜了。你说酷不酷!!用Go写的代码容易维护
Go可没有其他语言那种疯狂的语法,紧凑、干净的语法你值得拥有。
创建这门语言时,Google的设计师们就已经心中有数了。Google拥有非常庞大的代码库,数以千计的开发者在同一个代码库上工作,因此要求代码必须容易理解,代码的副作用最小。这将使代码容易维护与修改。
Go有意抛弃了一些现代OOP语言的一些特性:
- 没有类。所有代码都只被分成packages。Go只有struct,没有class。
Go做的这些变化,使之区别于其他语言,有些特点可能不能得到码农的认可。但也不是说丢弃上述特性就写不了代码了。顶多多加几行代码而已。我们可以注意到更积极的一面,代码更干净清晰。
看上图,Go的效率接近与C/C++,语法上如Ruby,Python那样简单。对于码农与处理器来说是个双赢。
不像新晋的其他语言如Swift,Go的语法相当稳定。从2012年发布1.0版本以来都没变化过。后向兼容性尚佳。
Go有Google撑腰
这当然不算技术优势。不过Google有全球最大的云基础架构,较大规模的伸缩性。Go设计出来就是用来解决伸缩性和有效性问题的。这些都是创建自有服务时要面对的情况。
许多大公司也已经使用Go来开发商用应用了。如Adobe,BBC,IBM,Intel还有Medium。
结论
Go与其他OOP语言不同,但是其实大同小异。Go提供了类似于C/C++的高效率,类似于Java的高并发处理能力,类似于Pyhton/Perl的代码简洁性。
无论学不学习Go,硬件限制问题都一直会摆在我们面前,促使软件开发者必须编写更高效的代码。开发者需要熟悉硬件,并做相应的优化。优化的软件可以在更便宜更慢的硬件上(如IOT设备)有效运行,给终端用户带来更好的体验。
后记
这篇相当于提纲挈领,告诉俺们Go为啥时一门建议学习的语言。每一门语言的诞生都是为了解决某个现实的问题。认清这些问题比是否学习某种语言更重要。