不得不说go的市场切入点非常准确

go被设计出来的目标应用场景是服务器开发,而服务器端开发是c++和java的地盘,占了大部分份额,go的目标是从他们嘴里抢蛋糕

程序员选语言除了流行度以外,语言是否好用,写的程序是否够快这两点也是重要的参考指标。

c++的特点是足够快,却不是很好用

java的特点是足够好用,但不见得快

又快又好用,又符合大众口味, 又专注于服务器领域的语言,似乎没有

于是go诞生了

go语言在易用性方面秒杀c++这点毋庸置疑,任何有服务器开发经验的程序员都可以快速上手go语言, 门槛非常友好。而c++,即使你有十年编程经验,初玩c++ 也非被摔个七荤八素不可。

至于在性能方面是否比java强?假如写go程序和java程序的都是经验丰富的优秀程序员,那么用go写的程序不一定比用java写的程序员快。然而,如果都是初次使用这两门语言的程序员写程序,那么go程序必定比java程序快。

其中原因在于go是一门以并发编程为特色的而设计的语言,在语法层面支持协程,也就是goroutines。而java不支持协程,只支持多线程。表面上看协程和线程似乎是同一个东西,能达到的效果也相同,但是在底层的实现上却有着非常大的区别,在服务器端的绝大部分应用中,协程要比线程节省资源的多。

通俗易懂的讲,线程是操作系统的资源,当java程序创建一个线程,虚拟机会向操作系统请求创建一个线程,虚拟机本身没有能力创建线程。而线程又是昂贵的系统资源,创建、切换、停止等线程属性都是重量级的系统操作,非常消耗资源,所以在java程序中每创建一个线程都需要经过深思熟虑的思考,否则很容易把系统资源消耗殆尽。

而协程,看起来和线程差不多,但创建一个协程却不用调用操作系统的功能,编程语言自身就能完成这项操作,所以协程也被称作用户态线程。我们知道无论是java还是go程序,都拥有一个主线程,这个线程不用显示编码创建,程序启动时默认就会创建。协程是可以跑在这种线程上的,你可以创建多个协程,这些协程跑在主线程上,它们和线程的关系是一对多。如果你要创建一个线程,那么你必须进行操作系统调用,创建的线程和主线程是同一种东西。显然,协程比线程要轻量的多。

既然协程这么优秀,为什么不彻底替代线程呢?事实上协程和线程完全不是两个相同层面的东西,完全谈不上替代一说,协程可以说是一个独立于线程的功能,它是在线程的基础上,针对某些应用场景进一步发展出来的功能。我们知道,线程在多核的环境下是能做到真正意义上的并行执行的,注意,是并行,不是并发,而协程是为并发而生的。

打个简单的比方吧,射雕英雄传看过吧,周伯通教郭靖一手画圆,一手画方,两只手同时操作,左右互搏,这个就是并行。普通人肯定做不到,不信你试试。你不能并行,却可以并发,你先左手画一笔,然后右手画一笔,同一时候只有一只手在操作,来回交替,直到完成两个图案是,这就是并发,协程主要的功能。

想象一下业务场景,你需要执行两个互不依赖的sql查询,为了减少等待时间,常规的操作肯定主线程执行sqlB的同时另起一个线程执行sqlA,使两个sql并行执行。然而你会发现,执行两个sql的线程大多数时间只是在等待数据库服务器的响应,线程只是处于阻塞等待状态,而不是疯狂运转,而线程的创建、切换又很消耗系统资源,显然这很浪费。这个时候就该协程大展身手了,你可以在主线程中创建一个协程用于执行sqlB,然后再在主线程中执行sqlA,协程和线程一样,不会阻塞主线程,所以sqlB得到结果后,你可以通过语言的api去看看在协程中的sql执行完毕了没有,如果没有则等待,如果执行完毕了就拿结果,和线程操作几乎一摸一样。至于sqlA和sqlB是否真正在并行执行根本无所谓。为什么呢? 我们假设执行一个sql需要三步,提交sql、等待、获得结果 ,其中第一步和第三步极省时,只要1毫秒一步,而第二步却要1000毫秒,那么使用并行的多线程执行两个sql,你只要花掉1002毫秒,而使用并发的协程你要花掉1004毫秒,但是线程比协程多消耗一个线程的资源,请问你会为了这2毫秒而选择多线程吗,显然不可能,创建线程的开销都要大于节省下来的时间,这就是协程存在的理由。

而服务器端开发中,大多数时候都是要花大量等待时间的场景,也就是所谓的IO密集,协程极为适合这种场景,而go又主打协程,直接从语法层面支持,切中了以往开发高性能程序太过于复杂的痛点,因此广受程序员们的欢迎。java其实也可以模拟出协程的效果,比如用nio和多线程,也能假装goroutines的效果,但实际操作起来太过于麻烦,还要掌握一大堆枯涩的概念,完全没有goroutines的优雅。所以在并发性能上,go完胜java。换言之,go比java更适应高并发场景,能更优雅方便的写出高并发程序。

当然,以上只是go流行起来原因的其中之一。除此之外非常重要的原因在于,go语言有一个好爹google,以及祖师爷级别的创始人unix与C语言之父肯·汤普逊。想象一下,c语言已经如此牛逼,而还只是这位大神早年的作品,那么现在同样出于他手的go语言势必是集大成的作品,而且还有财大气粗口碑出众的google背书,简直就是含着金钥匙出生啊,不牛逼都难,不去用用简直枉为程序员。

对标一下技术上同样出众的.net core,各方面都不输于go,但就是火不起来,究其原因还是爹作的孽,微软的原罪已经成了广大互联网程序员的刻板影响,一时三刻无法逆转,即使近年来有所改善,但还是和谷歌相去甚远,这也是.net core明明足够优秀但就是没法赢得程序员们青睐的原因。

以上便是为什么go语言能虎口夺食成功的原因