Go语言,做为编程语言的后生,站在巨人的肩膀上,吸取了其余一些编程语言的特色。java
Go 编程语言是一个开源项目,它使程序员更具生产力。Go 语言具备很强的表达能力,它简洁、清晰而高效。得益于其并发机制, 用它编写的程序可以很是有效地利用多核与联网的计算机,其新颖的类型系统则使程序结构变得灵活而模块化。 Go 代码编译成机器码不只很是迅速,还具备方便的垃圾收集机制和强大的运行时反射机制。 它是一个快速的、静态类型的编译型语言,感受却像动态类型的解释型语言。(摘取自官网)python
Less can be morec++
大道至简,小而蕴真git
让事情变得复杂很容易,让事情变得简单才难程序员
深入的工程文化github
Go语言之因此厉害,是由于它在服务端的开发中,总能抓住程序员的痛点,以最直接、简单、高效、稳定的方式来解决问题。这里咱们并不会深刻讨论GO语言的具体语法,只会将语言中关键的、对简化编程具备重要意义的方面介绍给你们,体验Go的核心特性。golang
Go语言在并发编程方面比绝大多数语言要简洁很多,这一点是其最大亮点之一,也是其在将来进入高并发高性能场景的重要筹码。编程
不一样于传统的多进程或多线程,golang的并发执行单元是一种称为goroutine的协程。数组
因为在共享数据场景中会用到锁,再加上GC,其并发性能有时不如异步复用IO模型,所以相对于大多数语言来讲,golang的并发编程简单比并发性能更具卖点。安全
在当今这个多核时代,并发编程的意义不言而喻。固然,不少语言都支持多线程、多进程编程,但遗憾的是,实现和控制起来并非那么使人感受轻松和愉悦。Golang不一样的是,语言级别支持协程(goroutine)并发(协程又称微线程,比线程更轻量、开销更小,性能更高),操做起来很是简单,语言级别提供关键字(go)用于启动协程,而且在同一台机器上能够启动成千上万个协程。协程常常被理解为轻量级线程,一个线程能够包含多个协程,共享堆不共享栈。协程间通常由应用程序显式实现调度,上下文切换无需下到内核层,高效很多。协程间通常不作同步通信,而golang中实现协程间通信有两种:1)共享内存型,即便用全局变量+mutex锁来实现数据共享;2)消息传递型,即便用一种独有的channel机制进行异步通信。
对比JAVA的多线程和GO的协程实现,明显更直接、简单。这就是GO的魅力所在,以简单、高效的方式解决问题,关键字go,或许就是GO语言最重要的标志。
高并发是Golang语言最大的亮点
从C到C++,从程序性能的角度来考虑,这两种语言容许程序员本身管理内存,包括内存的申请和释放等。由于没有垃圾回收机制因此C/C++运行起来速度很快,可是随着而来的是程序员对内存使用上的很谨小慎微的考虑。由于哪怕一点不当心就可能会致使“内存泄露”使得资源浪费或者“野指针”使得程序崩溃等,尽管C++11后来使用了智能指针的概念,可是程序员仍然须要很当心的使用。后来为了提升程序开发的速度以及程序的健壮性,java和C#等高级语言引入了GC机制,即程序员不须要再考虑内存的回收等,而是由语言特性提供垃圾回收器来回收内存。可是随之而来的多是程序运行效率的下降。
GC过程是:先stop the world,扫描全部对象判活,把可回收对象在一段bitmap区中标记下来,接着当即start the world,恢复服务,同时起一个专门gorountine回收内存到空闲list中以备复用,不物理释放。物理释放由专门线程按期来执行。
GC瓶颈在于每次都要扫描全部对象来判活,待收集的对象数目越多,速度越慢。一个经验值是扫描10w个对象须要花费1ms,因此尽可能使用对象少的方案,好比咱们同时考虑链表、map、slice、数组来进行存储,链表和map每一个元素都是一个对象,而slice或数组是一个对象,所以slice或数组有利于GC。
GC性能可能随着版本不断更新会不断优化,这块没仔细调研,团队中有HotSpot开发者,应该会借鉴jvm gc的设计思想,好比分代回收、safepoint等。
内存自动回收,不再须要开发人员管理内存
开发人员专一业务实现,下降了心智负担
只须要new分配内存,不须要释放
初始化阶段直接分配一块大内存区域,大内存被切分红各个大小等级的块,放入不一样的空闲list中,对象分配空间时从空闲list中取出大小合适的内存块。内存回收时,会把不用的内存重放回空闲list。空闲内存会按照必定策略合并,以减小碎片。
编译涉及到两个问题:编译速度和依赖管理
目前Golang具备两种编译器,一种是创建在GCC基础上的Gccgo,另一种是分别针对64位x64和32位x86计算机的一套编译器(6g和8g)。
依赖管理方面,因为golang绝大多数第三方开源库都在github上,在代码的import中加上对应的github路径就可使用了,库会默认下载到工程的pkg目录下。
另外,编译时会默认检查代码中全部实体的使用状况,凡是没使用到的package或变量,都会编译不经过。这是golang挺严谨的一面。
因为golang诞生在互联网时代,所以它天生具有了去中心化、分布式等特性,具体表现之一就是提供了丰富便捷的网络编程接口,好比socket用net.Dial(基于tcp/udp,封装了传统的connect、listen、accept等接口)、http用http.Get/Post()、rpc用client.Call('class_name.method_name', args, &reply),等等。
高性能HTTP Server
在C,C++中,包括其余的一些高级语言是不支持多个函数返回值的。可是这项功能又确实是须要的,因此在C语言中通常经过将返回值定义成一个结构体,或者经过函数的参数引用的形式进行返回。而在Go语言中,做为一种新型的语言,目标定位为强大的语言固然不能放弃对这一需求的知足,因此支持函数多返回值是必须的。
函数定义时能够在入参后面再加(a,b,c),表示将有3个返回值a、b、c。这个特性在不少语言都有,好比python。
这个语法糖特性是有现实意义的,好比咱们常常会要求接口返回一个三元组(errno,errmsg,data),在大多数只容许一个返回值的语言中,咱们只能将三元组放入一个map或数组中返回,接收方还要写代码来检查返回值中包含了三元组,若是容许多返回值,则直接在函数定义层面上就作了强制,使代码更简洁安全。
语言交互性指的是本语言是否能和其余语言交互,好比能够调用其余语言编译的库。
在Go语言中直接重用了大部份的C模块,这里称为Cgo.Cgo容许开发者混合编写C语言代码,而后Cgo工具能够将这些混合的C代码提取并生成对于C功能的调用包装代码。开发者基本上能够彻底忽略这个Go语言和C语言的边界是如何跨越的。
golang能够和C程序交互,但不能和C++交互。能够有两种替代方案:1)先将c++编译成动态库,再由go调用一段c代码,c代码经过dlfcn库动态调用动态库(记得export LD_LIBRARY_PATH);2)使用swig(没玩过)
golang不支持try...catch这样的结构化的异常解决方式,由于以为会增长代码量,且会被滥用,无论多小的异常都抛出。golang提倡的异常处理方式是:
普通异常:被调用方返回error对象,调用方判断error对象。
严重异常:指的是中断性panic(好比除0),使用defer...recover...panic机制来捕获处理。严重异常通常由golang内部自动抛出,不须要用户主动抛出,避免传统try...catch写获得处都是的状况。固然,用户也可使用panic('xxxx')主动抛出,只是这样就使这一套机制退化成结构化异常机制了。
类型推导:类型定义:支持var abc = 10
这样的语法,让golang看上去有点像动态类型语言,但golang实际上时强类型的,前面的定义会被自动推导出是int类型。
做为强类型语言,隐式的类型转换是不被容许的,记住一条原则:让全部的东西都是显式的。
简单来讲,Go是一门写起来像动态语言,有着动态语言开发效率的静态语言。
一个类型只要实现了某个interface的全部方法,便可实现该interface,无需显式去继承。
Go编程规范推荐每一个Interface只提供一到两个的方法。这样使得每一个接口的目的很是清晰。另外Go的隐式推导也使得咱们组织程序架构的时候更加灵活。在写JAVA/C++程序的时候,咱们一开始就须要把父类/子类/接口设计好,由于一旦后面有变动,修改起来会很是痛苦。而Go不同,当你在实现的过程当中发现某些方法能够抽象成接口的时候,你直接定义好这个接口就OK了,其余代码不须要作任何修改,编译器的自动推导会帮你作好一切。
不能循环引用:即若是a.go中import了b,则b.go要是import a会报import cycle not allowed。好处是能够避免一些潜在的编程危险,好比a中的func1()调用了b中的func2(),若是func2()也能调用func1(),将会致使无限循环调用下去。
defer机制:在Go语言中,提供关键字defer,能够经过该关键字指定须要延迟执行的逻辑体,即在函数体return前或出现panic时执行。这种机制很是适合善后逻辑处理,好比能够尽早避免可能出现的资源泄漏问题。
能够说,defer是继goroutine和channel以后的另外一个很是重要、实用的语言特性,对defer的引入,在很大程度上能够简化编程,而且在语言描述上显得更为天然,极大的加强了代码的可读性。
“包”的概念:和python同样,把相同功能的代码放到一个目录,称之为包。包能够被其余包引用。main包是用来生成可执行文件,每一个程序只有一个main包。包的主要用途是提升代码的可复用性。经过package能够引入其余包。
编程规范:GO语言的编程规范强制集成在语言中,好比明确规定花括号摆放位置,强制要求一行一句,不容许导入没有使用的包,不容许定义没有使用的变量,提供gofmt工具强制格式化代码等等。奇怪的是,这些也引发了不少程序员的不满,有人发表GO语言的XX条罪状,里面就不乏对编程规范的指责。要知道,从工程管理的角度,任何一个开发团队都会对特定语言制定特定的编程规范,特别像Google这样的公司,更是如此。GO的设计者们认为,与其将规范写在文档里,还不如强制集成在语言里,这样更直接,更有利用团队协做和工程管理。
交叉编译:好比说你能够在运行 Linux 系统的计算机上开发运行 Windows 下运行的应用程序。这是第一门彻底支持 UTF-8 的编程语言,这不只体如今它能够处理使用 UTF-8 编码的字符串,就连它的源码文件格式都是使用的 UTF-8 编码。Go 语言作到了真正的国际化!
此处咱们说个小段子:
好久之前,有一个IT公司,这公司有个传统,容许员工拥有20%自由时间来开发实验性项目。在2007的某一天,公司的几个大牛,正在用c++开发一些比较繁琐可是核心的工做,主要包括庞大的分布式集群,大牛以为很闹心,后来c++委员会来他们公司演讲,说c++将要添加大概35种新特性。这几个大牛的其中一我的,名为:Rob Pike,听后心中一万个xxx飘过,“c++特性还不够多吗?简化c++应该更有成就感吧”。因而乎,Rob Pike和其余几个大牛讨论了一下,怎么解决这个问题,过了一会,Rob Pike说要不咱们本身搞个语言吧,名字叫“go”,很是简短,容易拼写。其余几位大牛就说好啊,而后他们找了块白板,在上面写下但愿能有哪些功能。接下来的时间里,大牛们开心的讨论设计这门语言的特性,通过漫长的岁月,他们决定,以c语言为原型,以及借鉴其余语言的一些特性,来解放程序员,解放本身,而后在2009年,go语言诞生。
如下就是这些大牛所罗列出的Go要有的功能:
规范的语法(不须要符号表来解析)
垃圾回收(独有)
无头文件
明确的依赖
无循环依赖
常量只能是数字
int和int32是两种类型
字母大小写设置可见性(letter case sets visibility)
任何类型(type)都有方法(不是类型)
没有子类型继承(不是子类)
包级别初始化以及明确的初始化顺序
文件被编译到一个包里
包package-level globals presented in any order
没有数值类型转换(常量起辅助做用)
接口隐式实现(没有“implement”声明)
嵌入(不会提高到超类)
方法按照函数声明(没有特别的位置要求)
方法即函数
接口只有方法(没有数据)
方法经过名字匹配(而非类型)
没有构造函数和析构函数
postincrement(如++i)是状态,不是表达式
没有preincrement(i++)和predecrement
赋值不是表达式
明确赋值和函数调用中的计算顺序(没有“sequence point”)
没有指针运算
内存一直以零值初始化
局部变量取值合法
方法中没有“this”
分段的堆栈
没有静态和其它类型的注释
没有模板
内建string、slice和map
数组边界检查
大牛真身
最大牌的当属B和C语言设计者、Unix和Plan 9创始人、1983年图灵奖得到者Ken Thompson,这份名单中还包括了Unix核心成员Rob Pike(go语言之父)、java HotSpot虚拟机和js v8引擎的开发者Robert Griesemer、Memcached做者Brad Fitzpatrick,等等。