我为什么选择go语言

这里。我并不打算引起语言争论的口水仗,我并非什么大牛,对语言的造诣也不深。仅仅是想通过自己实际的经历,来说说为什么我在项目中选择go。

其它语言的经历

C++

在接触go之前,我已经有多年的c++开发经验。

主要用在游戏服务端引擎开发以及P2P上面,那可是一段痛并快乐的时期,以至于我看到不论什么的程序钉子问题都认为能够用c++这把锤子给敲定。

可是对于互联网项目开发来说。除非你的团队总体的c++技术水平nb,并且有非常强的代码规范,不然真可能是一场灾难,更别说我们现有团队差点儿没其它人会这玩意了。

本来,我打算在现有项目中的推送系统中使用c++,并用业余时间写好了一个网络底层库libtnet,但后来还是决定打住,由于没有人能够协助我开发。令我比較欣慰的是,libtnet有一个游戏公司在使用,现处于内部測试阶段。即将放出去,我倒是非常期待他们的好消息。

Lua

在做游戏的过程中。我也学会了lua这门语言,并且还有幸接触并完好了云风在Lua 不是 C++中提到的那个恐怖的lua,c++粘合层。

lua真的是一门非常好的语言,性能高,开发高速。不光游戏公司大量使用。在互联网领域,由于openresty的流行,一些公司(包含我们)也開始在web端使用lua进行开发。

(颇为自豪的是还给openresty反馈过几个bug)

可是。lua由于太短小精悍,功能库并不多。非常多须要自己去实现,并且,写出高性能。高质量lua代码也并非非常easy的事情。

另外,由于其动态语言的特性,我们也栽了不少坑,这个兴许在详说。

Python

在我来现有的团队之前。他们就已经使用python进行整个系统的开发,甚至包含clientGUI(这对client童鞋当时就是一个灾难,后来换成Qt就舒爽了)。

python的优点不必说,从数不清的公司用它进行开发就知道。库非常丰富,代码简洁,开发迅速。

可是,在项目中经过两年多python开发之后,我们渐渐出现了非常多问题:

  • 性能。python的性能是比較偏低的。对于非常多性能热点代码,通常都会採用其它的方式实现。在我们的项目中,须要对不论什么API调用进行签名认证。认证服务我们開始使用的是tornado实现,但非常不幸运的是。放到外网并没有顶住压力。所以我们引入openresty,将非常多高频操作实现放到openresty实现。最终顶住了。
  • 部署,python的库由于太丰富了。所以我们的童鞋引入了非常多的库。个人感觉我们的童鞋可没有造轮子的兴趣。有时候发版本号的时候,我们会由于忘记安装一个库导致程序无法执行。这可能跟我们团队没有成熟运维经验有关,兴许通过salt。puppet这种公布工具应该能解决。
  • 质量,通常我们都认为,由于python代码的简洁。我们非常easy的能写出高质量的代码,可是假设没有好的代码控制手段。用python也仍然能写出渣的代码,我甚至认为由于其灵活性,可能会更easy写出烂的代码。这能够说是我们团队的教训。

这里,我并没有喷python的意思,它真的是一门好语言。我能够通过它高速的构建原型,验证我的想法。并且还一直在使用。仅仅是在项目中,我们的一些疏忽,导致代码不可控了,到了不得不重构的地步了。

Why GO?

前面说了我的语言经历,以及项目到了重构地步的原因,可是为什么会是go呢?我们能够有非常多其它的选择,譬如java,erlang,或者仍然採用python。我认为有非常多因素考量:

  • 静态,go是一门静态语言。有着强类型约束。所以我们不太可能出如今python中变量在执行时类型不匹配(譬如int + string)这种runtime error。 在编译阶段就能够帮我们发现非常多问题。不用等到执行时。(当然。这个静态语言都能做到)

  • 代码规范。非常多人都比較反感go强制的编码规范。譬如花括号的位置。

    但我认为,就由于强制约定,所以大家写出来的go代码样子都几乎相同,不用费心再去深究代码样式问题。

    并且我发现,由于规范统一。我非常easy就能理解别人写的代码。

  • 库支持,go的库非常丰富,并且能通过go get非常方便的获取github,google code上面的第三方库(质量你自己得担着了)。再不行,用go自己造轮子也是非常方便的,并且造的轮子通常都比較稳定。

  • 开发迅速,不得不说。当你习惯用go开发之后。用go开发功能非常的快。相对于静态语言c++,开发的效率快的没话说,我认为比python都不差。并且质量有保证。我们花了不到一个星期进行推送服务核心功能开发,到如今都没怎么变动,稳定执行。

  • 部署方便,由于是静态的。仅仅须要build成一个可执行程序就能够了。部署的时候直接扔一个文件过去,不须要像python那样安装太多的依赖库。

GO特性

go如今的这个样子,有些人喜欢。有些人不喜欢,我无法知道为啥google那帮人把go设计成这样,可是我认为,既然存在,就有道理,我仅仅须要知道什么该用,什么不该用就能够了。

gc

GO提供了gc,这对于c++的童鞋来说,极大的降低了在内存上面犯错的机会,仅仅是go的gc这个效率还真的不好恭维。比起java来说。还有非常大的提升空间。

所以有时候写代码,我们还得依据tuning来提升gc的效率,譬如採用内存池的方式来管理大块的slice分配,採用no copy的方式来进行string,slice的互转。

只是go1.3貌似gc性能有了非常大的改善,这点让我比較期待。

defer

go的defer事实上是一个让人又爱又恨的东西,对于防止资源泄露,defer可是一个非常不错的东西,可是滥用defer可是会让你面临非常严重的内存问题,尤其是像以下的代码:

for {
    defer func(){
        //do somthing
    }
}

别以为go会在调用完毕defer之后就好好的进行gc回收defer里面的东西,在我们进行内存profile的时候,发现大量的内存占用都是defer引起的。所以使用起来须要特别慎重。

但我认为,这个go应该会略微改善,在go1.3里面。也有了对defer的优化。

error

或许error是一个让人争议非常大的东西。现代方式的exception那里去呢?可是我认为error能够非常明白的告诉使用者该函数会有错误返回,假设使用exception,除非文档足够具体。我还真不知道哪里就会蹦出一个异常了。

仅仅是,go又提供了相似exception的defer,panic,recover,这是要闹哪出。

事实上这篇文章我认为已经解释的非常好了,go程序的惯例是对外的API使用error,而内部错误处理能够用defer,recover和panic来简化流程。

事实上这倒跟我一贯的编程准则相应。在团队在用python进行开发的时候。我们都明白要求库对外提供的API须要使用返回值来表示错误,而在内部能够使用try,catch异常机制。

interface

go提供了interface来进行抽象编程。何谓接口。最通常的样例就是鸭子的故事,“当看到一仅仅鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这仅仅鸟就能够被称为鸭子“。

在go里面。interface就是一堆方法的集合,假设某个对象实现了这些方法,那么该对象能够就算是该interface。

使用interface,我们能够非常方便的实现非侵入式编程,进行模块功能的替换。

对于长时间沉浸c++和python的童鞋来说,一下子要用interface来解决抽象问题,可能会非常不适应。但当习惯之后,你会发现,事实上interface非常的灵活方便。

写到后面

在使用的时候。我们须要知道go究竟适用在什么地方,譬如我们如今也就将API服务使用go重构。我们可没傻到用go去替换openresty。

总之,go是一门非常新的语言。国内也已经有非常多公司開始吃这个螃蟹,也有成功的样例了,而我们也正開始了这段旅程。

最后在附上曾经给公司同事写的一个ppt:https://qing.wps.cn/l/b76667b40bdb4b7c91f2b3920a7f4780

猜你喜欢

转载自www.cnblogs.com/mqxnongmin/p/10660942.html