刚开始接触golang的时候是在大学时候,当时大概是2010年左右,对这门新语言比较好奇,但是没有深入去了解,只是道听途说这门语言在并发处理上很方便,对于协程这个东西也是第一次听说。自从工作之后,就一直没有接触过这门语言,最近公司想往golang上转,开发新的项目平台,毕竟golang运行效率和开发效率都要比其他语言要简单方便很多(听说c++都快20了)。

吉祥物:(憨厚小地鼠 move~move~move~ Bui~~~~ go~go~go~ )

地鼠

(萌萌の勤劳小地鼠~)并发协作:

并发协作

语言

看七周七语言中提到的,语言各有特色,用于不同的开发场景,对应团队的工具栈;经常用自己熟悉的编程语言,思维模式也会有所不同;总的来说,支持KISS原则,方便高效开发/测试/部署/运行,并发运行解决问题,流出更多时间关注业务或者kick ass && Chew bubblegum (just a joke~)

发展历史:

发明这个语言的初衷,「不忘初心,方得始终」

特征:

  • KISS;简单朴实 (做工程的人最喜欢的就是简单实用的东西);
  • 运行占用资源低(可运行在嵌入式平台linux arm),跨平台
  • ((内存)数据结构+算法+抽象定义接口);
  • 语法简单,25个关键字;
  • c语言结构体形式模拟继承方法重写机制;
  • 基础数据结构类型:byte,string, array; slice, map,chanel 引用类型;(其他数据结构heap(优先队列),list,ring(circular list)这些在官方提供的公共库中)
  • 强类型语言,interface{} 表示通用类型(相当于stl中的模板);
  • 异常处理: defer, panic, recover 抛出一个panic的异常(异常指的是意料之外的情况,比如引用了空指针,下标越界,除数为0,不应该出现的分支,比如default),然后在defer中通过recover捕获这个异常,最后正常处理;注意如果没有recover去捕获异常,程序就会退出;
  • 错误机制: error,错误指的是意料之中的情况,比如文件可能会打开失败,网络连接可能断开导致连接失败等等,错误是业务过程的一部分,而异常不是 (业务需定义常见的错误码标识对应错误信息)
  • 变量对象内存分配通过tcmalloc来申请一块span, 分成多个page提供使用,充分利用内存空间,通过gc回收runtime对象(随着版本迭代,对gc的效率逐渐提高,有专门的runtime团队支持)
  • 并发程序通过channel共享内存(share memory by communicating);
  • 适合web后端开发(官方golang.org已提供的基础库 https://golang.org/pkg/ ,net/http(请求,响应,client,server), http/template, 数据库客户端驱动接口定义database/sql(三方根据接口标准可以自定义实现,也可以自己单独定义一套标准实现),数据加密crypto);
  • 通过goroutine(协程,用户级别轻量级线程)支持并发, 协程通过channel通信( <-chan interface{} 接收chan;chan<-interface{} 发送chan;同步通过sync机制(lock(锁接口) mutex(某个goroutine加互斥锁) rwlock(对读写操作加锁) WaitGroup(pv操作,对goroutine组) ,Cond(条件变量,信号量));
  • Golang实现了 CSP(Communicating Sequential Process http://www.usingcsp.com/cspbook.pdf )并发模型做为并发基础,底层使用goroutine做为并发实体,goroutine非常轻量级可以创建几十万个实体;实体间通过 channel 继续匿名消息传递使之解耦,在语言层面实现了自动调度,这样屏蔽了很多内部细节,对外提供简单的语法关键字(go,select,channel),大大简化了并发编程的思维转换和管理线程的复杂性;
  • SO OPEN,import 三方库源(大部分git的方式来自github/gitlib,还支持hg),源码直接可以修改编译(取之于源用之源);
  • Go 命令工具方便开发自测调试: https://golang.org/cmd/go/
    • 通过go test来单元测试,覆盖测试,性能测试(cpu,pprof),直接可以测试用例先行,
    • go tool, pprof (进行性能分析 http://cizixs.com/2017/09/11/profiling-golang-program )objdump(dump出汇编代码)
    • go get -u ~= download to go build and install , go run 单独运行
    • go fmt 代码格式化,统一编码风格,方便协同编程
    • go mod: https://github.com/golang/go/wiki/Modules 1.11新引入的功能,方便package依赖管理,类似nodejs中的npm
  • Go 2.0正待发布,10年+发展,会有一些优化和新特性 https://www.youtube.com/watch?v=RIvL2ONhFBI
  • More…..

工作上使用语言进化

coder

C/C++ -> *.so -> php/python | java -> *.jar ==» go -> *.a -import-> pkg -compile-> binary program

编写运行:复杂 -> 简单

Go 相当于兼顾了c的执行效率,python的开发效率,择中方案,适合服务端开发(业务开发,基础组件开发(网关,db,AI),自动化运维工具开发devops); 如果用go来调用.so动态链接库,需要用cgo机制

语法对比参考:http://hyperpolyglot.org/c

学习

  1. 开始入门:https://golang.org/doc/code.html
  2. golang的基本语法知识,可以通过gotour来进行简单的学习入门,godoc查看具体基础文档和get到本地的三方库接口文档, Gotour简单入门 ——> 语法快速入门
  3. 练习习题:
  1. 最佳实践:(这个会根据实践场景逐渐完善,最终可能会形成一个标准规范)
  1. 面向对象设计SOLID:
  1. 业务常用依赖阶级开发:(掌握一些三方库,方便快速集成开发)
  1. 订阅资源blog:
  1. 实践踩的坑:
  1. 应用场景:
  1. 好的开源项目:

深入理解

goroutine实现机制

  • goroutine实现机制:https://www.zhihu.com/question/20862617 (M:内核OS线程;G:goroutine用户态轻量级线程,自己的栈,正在等待的channel等;P: 调度的上下文,是调度协调的处理器,P的数量代表了真正的并发度) (tips:相对于java中并发库实现是不是要简洁高效些呢,https://golang.org/doc/faq##goroutines 这个解释了golang为什么用协成代替线程)

  • 同步机制:sync lock(锁接口) mutex(某个goroutine加互斥锁) rwlock(对读写操作加锁) WaitGroup(pv操作,对goroutine组) ,Cond(条件变量,信号量) 用法参考:https://deepzz.com/post/golang-sync-package-usage.html (其实就是OS中的同步机制实现) 锁的话是一个原子操作,要么锁住,要么不做,通过atomic操作底层的cpu指令(CHANGE*, SWAP* ….etc指令根据不同的cpu/gpu厂商定义,intel/amd)

  • 内存管理: http://legendtkl.com/2017/04/02/golang-alloc/

  • GC机制:http://legendtkl.com/2017/04/28/golang-gc/

  • 深入了解golang的执行原理,https://github.com/qyuhen/book/blob/master/Go%201.5%20%E6%BA%90%E7%A0%81%E5%89%96%E6%9E%90.pdf (底层的运行时逻辑有点像php的执行过程, php7底层运行结构也借鉴了golang的设计思想,比如内存的申请)

FAQ:

https://golang.org/doc/faq 相当有用值得一读

热更新方案: https://studygolang.com/topics/1194 (监控一个当前版本文件是否变动了,如果变动然后将老的执行文件软连指向新的执行文件(rm 软连,ln 创建新的软连,然后通过hup信号优雅的重启由endless启动的服务)

开发工具

DIY

(熟悉三方源码,基础库,自行diy服务)

  • 网关服务
  • 网关后台
  • abtest
  • abtest后台
  • 微服务
    • passport
    • activity
    • More…
  • 资源管理(K8S)
  • 监控
  • ci/cd构建发布上线
  • 队列