使用Go语言一段时间的感受
作者 openkk 2012-03-04 18:26:58
文/Windstorm
有一段时间没更新了。最近在忙一个 Server+Client 的项目,Client 是 Android 手机,大概也就是几十的规模。Server 是纯 Golang 实现,没有 apache 或者 ngix 这种 web server,也没有数据库,自己写了个文件管理 module,handle 这种小规模的服务没问题。算下来接触 Golang 也有四个多月了,断断续续写了一些东西,这里纪录一下心得吧
先大概说下为什么用 Golang。我是一个对语言有洁癖的人,曾经是一个C+Python 的坚定呐喊者,最常说的一句话就是,只要熟练这两种,什么情况都能应付,根本不用 Java 和 C++(纯指我所在的领域)。核心代码用C,速度快,需要记的语言细节少;外围用 Python glue,灵活,简洁,任何模块都容易上手,绝配。Java 的繁琐,C++ 的无数无用的特性,都让我只在不得不用的时候才去用。Objective-C 是另一个我欣赏的语言,问题是不跨平台,过于封闭。
可惜的是,在这个节奏极快的时代,不是所有情况下都适合上C。之前有一个项目也是类似的架构和规模,为了节省时间,当初几乎没有服务器平台编程经验的我,在服务器端选择用 Django+Apache+MySQL 做,成熟,社区活跃,又是 Python 作为主要开发语言,这些都是这个选择的原因。说实话,几个月过去后,回首看,这不是一个愉快的经历。Django 是一个好架构,大而全,而大而全有时也就意味着臃肿,五花八门的配置,过紧的模块耦合对引入第三方工具限制颇多,自带的 ORM 又不好用。之前从来没有搞过服务器配置的我,对 Apache 的配置和效率所带来的琐碎的东西也头疼。总的来说这个部分花了我很多时间,有新手学习服务器编程的必经过程,也有折腾 Django 和 Apache 没必要的时间浪费,很大部分上抵消了 Python 带来的快速开发的灵活性。而一旦服务器上线,动态语言带来的一些 bug 又会让人头疼。对于普通高校实验室这种没有完善的服务器调试的条件,基本就是改了就上线用,有些隐蔽 bug 到某些条件分支才会触发,一旦在运行中途出问题,改起来也麻烦。
从那时起,我就特别想,要是有一种语言能把 C 和 Python 的优点结合起来,也就是说
- 速度快,高性能
- 简洁明了,需要记的语言细节少,开发迅速(C)
- 灵活,开发快速,类 Python 的 list,map 等常用数据结构支持(Python)
- 完善的模块支持,模块也容易上手(Python)
- 对程序员友好的并行架构(Erlang)
- 安全,绝大部分问题能消灭在 compile time 中(C minus pointer)
那基本就是系统级和网络级编程最对我胃口的语言了。然后我就找到了 Go。
Golang 是一个新语言,截至目前为止,第一版正式版还没有发布。Golang 的设计者是 Robert Griesemer, Rob Pike 和 Ken Thompson,当年设计 C 和 Unix,后来的 Plan9 团队中的人 。Golang 的设计理念很明确,就是将动态类型语言的编程容易度和静态类型语言的安全效率结合起来。如果你想更深入了解 Golang 的发展历史以及完整的目标,请参考 Golang FAQ。
当然,Golang 吸引我的地方,不是因为其是 Google 出品,也不是因为其设计者皆为大牛,而是因为,Golang 真的做到了它所宣称的目标。Golang 就如同 C 和 Python 中间的完美结合,如果你是 Python 爱好者,又追求代码的速度和并行化,那么简单说,Golang 就是为你设计的。Golang 有很浓厚的C的遗风,尽量屏蔽 C++ 和 Java 的影响,比如没有独立的 OO 体系(并不是说不能 OO),一切以 struct 为中心,没有 exceptions (Oh yes!),仍然有指针,等等。但是,Golang 又吸取了很多新语言的精华,并带有自己独特的设计。比如:
1. 保留但大幅度简化指针
Golang 保留着C中值和指针的区别,但是对于指针繁琐用法进行了大量的简化,引入引用的概念。所以在 Golang 中,你几乎不用担心会因为直接操作内寸而引起各式各样的错误。
2. 多参数返回
还记得在C里面为了回馈多个参数,不得不开辟几段指针传到目标函数中让其操作么?在 Go 里面这是完全不必要的。而且多参数的支持让 Go 无需使用繁琐的 exceptions 体系,一个函数可以返回期待的返回值加上 error,调用函数后立刻处理错误信息,清晰明了。
3. Array, slice, map 等内置基本数据结构
如果你习惯了 Python 中简洁的 list 和 dict 操作,在 Golang 中,你不会感到孤单。一切都是那么熟悉,而且更加高效。如果你是 C++ 程序员,你会发现你又找到了 STL 的 vector 和 map 这对朋友。
4. Interface
Golang 最让人赞叹不易的特性,就是 interface 的设计。任何数据结构,只要实现了 interface 所定义的函数,自动就 implement 了这个 interface,没有像 Java 那样冗长的 class 申明,提供了灵活太多的设计度和 OO 抽象度,让你的代码也非常干净。千万不要以为你习惯了 Java 那种一条一条加 implements 的方式,感觉还行,等接口的设计越来越复杂的时候,无数 Bug 正在后面等着你。
同时,正因为如此,Golang 的 interface 可以用来表示任何 generic 的东西,比如一个空的 interface,可以是 string 可以是 int,可以是任何数据类型,因为这些数据类型都不需要实现任何函数,自然就满足空 interface 的定义了。加上 Golang 的 type assertion,可以提供一般动态语言才有的 duck typing 特性, 而仍然能在 compile 中捕捉明显的错误。
5. OO
Golang 本质上不是面向对象语言,它还是过程化的。但是,在 Golang 中, 你可以很轻易的做大部分你在别的 OO 语言中能做的事,用更简单清晰的逻辑。是的,在这里,不需要 class,仍然可以继承,仍然可以多态,但是速度却快得多。因为本质上,OO 在 Golang 中,就是普通的 struct 操作。
6. Goroutine
这个几乎算是 Golang 的招牌特性之一了,我也不想多提。如果你完全不了解 Goroutine,那么你只需要知道,这玩意是超级轻量级的类似线程的东西,但通过它,你不需要复杂的线程操作锁操作,不需要 care 调度,就能玩转基本的并行程序。在 Golang 里,触发一个 routine 和 erlang spawn 一样简单。基本上要掌握 Golang,以 Goroutine 和 channel 为核心的内存模型是必须要懂的。不过请放心,真的非常简单。
7. 更多现代的特性
和C比较,Golang 完全就是一门现代化语言,原生支持的 Unicode, garbage collection, Closures (是的,和 functional programming language 类似), function 是 first class object,等等等等。
看到这里,你可能会发现,我用了很多轻易,简单,快速之类的形容词来形容 Golang 的特点。我想说的是,一点都不夸张,连 Golang 的入门学习到提高,都比别的语言门槛低太多太多。在大部分人都有C的背景的时代,对于 Golang,从入门到能够上手做项目,最多不过半个月。Golang 给人的感觉就是太直接了,什么都直接,读源代码直接,写自己的代码也直接。
有朋友要抗议了,你把 Golang 吹的这么好,难道它就没有缺点?有,当然有,不过和它的优点比,我觉得很多缺点都是因为整个语言太新,不成熟,随着时间的推移都能得到解决,相比之下都能忍了。如果你希望进一步了解 Golang 的优缺点,可以参考以下 yufeng 写的这篇文章,系统编程语言明日之星—Go(http://blog.yufeng.info/Go.pdf)。
还有朋友要说,Golang 这么好,为什么没人用?我想说,眼界放开点,这个世界精彩的东西比你想象的多。Golang 被 Google 用于 Youtube 的数据库,被越来越多的国外公司(大部分创业公司)用于后端开发,甚至在天朝,也有完全用 Golang 做服务开发的云应用公司了。可以说,随着 Go 1 即将到来的正式推出,Golang 的使用范围,应该会越来越广。
好,总结时间
如果你是 Python 和动态语言狂热爱好者,Go 不一定能给你带来很大的惊喜,这纯粹取决于你的项目性质,考虑到 Python 目前在很多地方都用C做核心运算,速度在大部分情况下都不是大问题。scalability 是一个问题,但并不是人人都会遇到的。
如果你是C爱好者,强烈建议你学习和使用 Go。Go 可以调用 C/C++ 程序,又提供了太多的便利,速度上稍有牺牲,但并不大。在绝大部分场景下 Go 能给你带来媲美C的性能,而对于某些确实性能过于关键的场合,也可以通过 cgo 让 Go 和C搭配。
如果你是 Java 爱好者,除非你是做 Android 这种不得不用 Java 的平台,否则也建议你尝试学习 Go,这个开发上感觉的差异如同比较开载着 1 吨石头的拖拉机和开保时捷 911 那么明显,而 Java 能给你的,Go 能给得更好。
如果你是 C++ 爱好者,!@#$%^&*,恭喜你,至少你的智商应该是没问题的。人生苦短,赶紧脱离 C++ 这个苦海吧。你用来学 89 个 C++ 高级特性的时间,估计已经用 Go 写了 64 个开源项目了。
如果你是像我一样的 C 和 Python 的爱好者,对动态语言又没有特殊的热爱……我还需要说什么呢?
使用Go语言一段时间的感受的更多相关文章
- 这段时间对c#和java的感受
这段时间对c#和java的感受 虽然很多书上说语法相似,但实际这是一个接近于门外汉的看法 真正的不同是 c#对更贴近系统API, 而java倡导跨平台 因而c#语法关键字更多,更细, 而ja ...
- 专访黄勇:Java在未来的很长一段时间仍是主流(把老板当情人,把同事当小孩,把客户当病人)
url:http://www.csdn.net/article/2015-09-06/2825621 2015-09-06 13:18 摘要:本文采访了现任阿里巴巴公司系统架构师黄勇,从事近十年的Ja ...
- worker 启动时向 etcd 注册自己的信息,并设置一个带 TTL 的租约,每隔一段时间更新这个 TTL,如果该 worker 挂掉了,这个 TTL 就会 expire 并删除相应的 key。
1.通过etcd中的选主机制,我们实现了服务的高可用.同时利用systemd对etcd本身进行了保活,只要etcd服务所在的机器没有宕机,进程就具备了容灾性. https://mp.weixin.qq ...
- 接下来一段时间会对大家进行网络通信的魔鬼训练-理解socket
引子 下一篇标题是<深入理解MQ生产端的底层通信过程>,建议文章读完之前.或者读完之后,再读一遍我之前写的<RabbitMQ设计原理解析>,结合理解一下. 我大学时流行过一个韩 ...
- 从配置读取一段时间(TimeSpan)
C#的TimeSpan表示一段时间,DateTime表示一个时间点.TimeSpan可正可负,可与DateTime相加减,很方便,我喜欢. 代码中我们经常要表示一段时间,用一个统一的单位(时 或者 分 ...
- Win8.1开机黑屏一段时间才能登录
最近发现开机后有一段时间黑屏过后才能进人登录界面,并且时间越来越长,网上查询了很多方法都没有效果,只能自己找了. 网上有一种方法提到用msconfig诊断判断或者安全启动来查看是否有黑屏,于是试了一下 ...
- 关于ScheduledExecutorService执行一段时间之后就不执行的问题
在项目中使用java的定时任务时,有的时候执行一段时间后没任何反应了.这里有篇文章说了这个问题.猛击下面的链接. http://blog.163.com/scuqifuguang@126/blog/s ...
- C#实现每隔一段时间执行代码(多线程)
总结以下三种方法,实现c#每隔一段时间执行代码: 方法一:调用线程执行方法,在方法中实现死循环,每个循环Sleep设定时间: 方法二:使用System.Timers.Timer类: 方法三:使用Sys ...
- IIS服务器运行一段时间后卡死,且无法打开网站(IIS管理无响应,必须重启电脑)
问题描述: 公司希望使用IIS配合网站显示一些订单跟进的情况并展示出来,所以我们在一台演示的Win7 Pro电脑上安装了IIS,但使用了一段时间后发现每过几天页面就无法正常访问了,而且打开IIS管理器 ...
随机推荐
- webpack原理类型问题
1.webpack底层原理 (实现一个webpack) 步骤:1.拿到入口文件的代码并读出来转化为js对象(抽象语法术parser)2.拿到所有模块的依赖 ‘./message.js’,放进数组中 引 ...
- pandas中数据框DataFrame获取每一列最大值或最小值
1.python中数据框求每列的最大值和最小值 df.min() df.max()
- SpringBoot简要介绍
一 SpringBoot介绍 1.1 先从Spring谈起 我们知道Spring是重量级企业开发框架 Enterprise JavaBean(EJB) 的替代品,Spring为企业级Java开发提供了 ...
- js学习:基本语法结构
语句 JavaScript 程序的执行单位为行(line),也就是一行一行地执行.一般情况下,每一行就是一个语句. 语句(statement)是为了完成某种任务而进行的操作,比如下面就是一行赋值语句. ...
- git 从创建到推送到远程,到拉取,实操
https://www.liaoxuefeng.com/wiki/896043488029600/900003767775424 初始化 git init 添加所有文件到暂存区 git add . c ...
- 3_04_MSSQL课程_Ado.Net_.ExcuteReader()(SQLDataReader)
ExcuteNonQuery(); 返回影响的行数 ExcuteSacalar();返回第一行第一列 ExcuteReader(): Reader,指针,指向表的表头.只是指向,数据仍在数据库中. S ...
- [Android实例] Android网络收音机项目(内含源码)
======================帖子内容===================================最近喜欢听广播,但是搜索了一下,苦于网上没有Android的网络收音机项目的例 ...
- springmvc面试问题
1.讲下SpringMvc和Struts1,Struts2的比较的优势 性能上Struts1>SpringMvc>Struts2 开发速度上SpringMvc和Struts2差不多,比St ...
- centos7一步一步搭建docker phpmyadmin 及nginx配置phpmyadmin非根目录重点讲解
系统环境:centos7.7 镜像image 版本:phpmyadmin/phpmyadmin(截止2020.01.10最新版) 参考文章:https://blog.csdn.net/a258929 ...
- 什么是Device ID?
Android ID用于唯一识别一部设备的一次刷机行为,虽然不能完全确定该设备的唯一性(真的唯一性是用IMEI号的),但是可以很大程度上过滤重复设备.这是移动互联网广告行业的基础,尤其是CPI广告,设 ...