2018年6月我从工作了5年的公司离职了,离职的原因很简单:想出去看一看,看外面的公司都在做什么业务?使用什么技术?
在离职的前一周,我拿到了华为、联通和我现在所在公司的offer,之所以没去华为和联通是因为它们都不是互联网公司,我喜欢的是互联网公司那种开放的氛围,这种开放的技术氛围更能让人获得更快的成长,接触到最前沿的技术。而我最终选择的公司就是这样的一家公司,技术氛围好、业务模式新颖。
进入这家互联网公司以后,开始我接触的当然是Java的一个项目,而且是一个只有需求还没有代码的新项目。从需求分析到架构设计、模型设计、代码编写都基本是我一个人完成。差不多2个月的时间这个Java的项目就开发完成并上线,后续的工作就是一些简单的维护和一些新的需求以及一些功能的调整。
进入公司三个月的时候,我的Team Leader扔给我一个Go语言项目,当然这个项目我之前已经看到过,但是当时我并不懂Go语言,所以Team Leader并没让我做相关的开发工作。现在因为人员的变动我必须要接手这个项目,所以我开始学习Go语言,也同时开启了我的第二计算机语言之路。
初次接触Go语言的时候,我并没有一开始就去找相关的资料去学习,而是开始看TL给我的这个Go项目,让他给我讲解了这个项目的主要业务逻辑,包括入口类方法、调用链,弄清楚这些我就开始看这个项目。其实如果接触过其它计算机语言的话,阅读Go项目一点问题都没有。即使Go中的数据类型、方法入参、返回值的写法跟我们以往的语言不一样,但并不妨碍你理解这门语言的特性。尤其是接触过JavaScript语言的开发人员来说,更容易接受Go语言,因为它的方法和参数定义和JavaScript对于方法和参数的定义很像。例如:都是通过var来定义参数,方法都是以function定义,当然JavaScript是一门弱类型的语言,它没有像Go语言的int、int32、int64、string等强类型语言具有的数据类型,但是他们的某些关键字和写法与Go语言很相像,熟悉JavaScript的开发者天然的对Go语言有好感。
我用两天的时间熟悉完了这个Go项目,在熟悉项目的过程中我当然也对它的语法有了一定的了解。然后我就开始接受TL给我的新需求并开始编码工作。我“照猫画虎”式的完成了一个个的新需求,在编写代码的时候,我会去查资料,例如:Go中的strconv中的各种方法,凡是你在Java中关于String操作的方法都能在Go语言找到,如果找不到,那就再找一遍,如果还是找不到,那就自己实现一个。通过一边编写Go语言代码一边查相关资料,我很快对这门语言了解的更深入了,我知道它天生就是为分布式高并发系统设计的语言。同样的服务器配置,Go语言能轻松实现4000QPS的业务逻辑,但是用Java就不太容易,需要做各种性能用户,这都得益于Go语言的协程设计。
协程不同于线程,协程是语言本身的机制,靠语言自身的机制去做多任务的调度,而线程并不是语言的特性,它需要靠容器来调度。例如我们常见的Java中的多线程,Java中的多线程是要靠tomcat、jetty等web容器去调度,所以多线程的性能取决于容器的调度性能。而容器的调度性能我们开发者很难去优化,就如一台4G8G的服务器,tomcat跑3000的QPS都很吃力(不是简单的输出hello word),而同等配置下,Go语言跑5000的QPS都不费力!
当然Go语言有它自身的局限性,一个重要的局限性就是弱事务。我们都知道Java中的Spring框架为我们提供了事务性,我们可以保证我们一次请求的多个操作要么全部失败,然后回滚,要么全部成功,它具有很强的事务性,所以我们可以用Java语言来编写银行、支付等系统。但是Go语言并不严格强调事务性,强事务必然会带来并发性能的损失。所以,如果你的系统可以接受一定程度的数据不一致性,那就可以选择Go语言,当然这不是绝对的,因为我们也可以通过MQ等措施来解决数据的不一致性,那么GO语言的使用场景都大很多了。
学习一门编程语言最好的方式绝对不是一开始就去读它的相关技术文档,如果有机会我们能参与到实际的项目开发中,那我们应该积极的参与其中。通过在实际业务场景对该计算机语言的使用,我们可以快速的掌握这门语言的特性,这种学习方式是最快最有成效的一种学习方式。只有真正使用过它,你才能真正了解它,“纸上谈兵”永远不可能打败真正的敌人。
接触Go语言是实际需求所致,但通过使用它,我发现它真的“很香”,如果你想打造自己的高并发系统,或者想让自己目前的系统并发性能提升一个数量级,Go语言是你最好的选择。从现在起,不妨学习它并使用它,你也会觉得它”很香”。