【Go学习】平台服务技能树 一、GoLang基础

安装与使用

go get https://github.com/choerodon/choerodon-cluster agent



 

Go和Java的区别

  1. 编译后直接生成可执行文件
    1.1 默认使用了静态编译,不依赖任何动态链接库,这样可以任意部署到各种运行环境,不用担
    心依赖库的版本问题。易于部署到任何环境。

    1.2 从1.5开始直接支持跨平台交叉编译、在Mac开发的,直接可以在windows或者linux使用。

    1.3 go不像Java那样编译生成字节码文件,然后再通过JVM来,编译成可执行文件;go可直接编译成其他平台的可执行文件;因此Go也具有跨平台的属性

CGO_ ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
  1. 没有类的概念,通过package管理
    2.1 Go中没有类的概念、所有源代码管理通过package来划分,当.go输入入同一个包时,其实和所有代码写在同一个文件中是没有区别的。所以在go中我们时长可以看到一个package下面可能只有一个.go文件。

    2.2 用标识符(包括常量、变量、类型、函数名、结构字段等等)以-个大小来表示,对包外的可见性。包中的方法的访问权限是根据名称首字母的大小写来区分的(这点跟java很不相同) ,如果首字母是小写,则表示是包内私有的(相当于java的private ) , 如果首字母是大写,其他包就可以访问( public)。

  2. 结构体类型和方法对应Java中的类
    3.1 结构体是将零个或者多个任意类型的命令变量组合在一起的聚合数据类型。

    3.2 每个变量都叫做结构体的成员、相对于Java结构体就像是类的一种简化形式

    3.3 可以通过组合替代继承

  3. 接口隐式实现,松耦合
    4.1 类型不需要显式的声明实现某个接口,只需实现该接口的所有methods

    4.2 实现某个接口的类型(除了实现接口方法外)可以有其他的方法。

    4.3 一个类型可以实现多个接口。通过接口的方式实现多态。

  4. 没有完善的错误处理机制
    5.1 没有异常的概念、将错误作为返回值

    5.2 没有finally ,使用defer

{
	//go中的error是作为返回值,返回给调用者的
	//遇到错误时,只能由调用者接收,并判断错误,然后再作相应的处理
	//go中的错误处理不像Java中一样能向上层层抛出
	//因此Go代码中有很多的if语句用来判断错误
	f, err := os. Open("filename. ext" )
	err != {
		log. Fatal(err)
	}
	defer f.Close( )  //当所有代码执行完后,执行defer的内容,像Java中的finally
}

 

数据类型

  1. 基本类型。int,float64,string,json.RawMessage,interface{}, time.Time

  2. 引用类型。
    切片,map 类型之间的转化, 断言。

  • 关于json.RawMessage类型的介绍与使用
关于json.RawMessage类型的介绍与使用
官方定义:RawMessage is a raw encoded JSON value. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.(RawMessage是一个经过编码的原始JSON值。它实现了封送处理程序和反封送处理程序,可用于延迟JSON解码或预先计算JSON编码。)
通俗定义:这是go标准库中encoding/json包下的一个数据类型 ,用于一些特殊的json使用需求,可以延迟json—>实例对象的转换
作用:在程序中使用Json时,有时某个字段其结构是根据其他字段(比如有个类型含义的字段)决定的,这个时候在解析时,需要先解析一部分,进行判断后,再解析出合适的Json结构。这时就需要用到Golang Json包的RawMessage这个对象。
应用场景:后端有Teacher、Student两个对象(或者更多),前端传来json数据,此时我们并不知道,他传的是Teacher还是Student,所以不能直接绑定到对应对象,因此需要对第一次传来的json作延迟转换,后端可根据前端的提示,来判断传来的body数据,是teacher还是student,再进行二次转换

代码如下:

//老师学生抽象成人这对象
type Person struct {
	TipId int		`json:"tip_id"`	//	1:老师,2:学生
	Body json.RawMessage	`json:"body"`//  具体实例数据
}

//学生
type Student struct {
	Id int	`json:"id"`
	StuName string		`json:"stu_name"`	//学生姓名
	StuClass string		`json:"stu_class"`	//学生班级
}

//老师
type Teacher struct {
	Id int
	TeaName string			//老师姓名
	TeaDep string			//老师部门
	TeaCourse string 		//老师教的课
}
func jsonDemo01() {

	//假设这是前端发来的json数据
	input := `
    {
        "tip_id": 2,
        "body": {
            "id":       888,
			"stu_name":  "小明",
			"stu_class": "高一一班"
        }
    } `
	var person Person
	json.Unmarshal([]byte(input), &person)	//先将json--->person (一次转换)

	fmt.Println("person type : ", person.TipId)

	switch person.TipId { //判断传来的数据是老师还是学生
	case 1 :
		var tea Teacher
		json.Unmarshal(person.Body,&tea)
		fmt.Println("This is a Teacher : ",tea)	//再将json中的body--->tea (二次转换)
	case 2 :
		var stu Student
		json.Unmarshal(person.Body, &stu)
		fmt.Println("This is a Student : ",stu) //再将json中的body--->stu
	}
}
import "testing"
//测试代码
func TestJsonDemo01(t *testing.T) {
	jsonDemo01()
}

输出如下:

关于time.Time 类型的介绍与使用
定义:该类型是time包下的,可精确到纳秒级
官方定义:时间以纳秒精度表示时间中的一个瞬间。使用时间的程序通常应该将它们作为值存储和传递,而不是指针。也就是说,时间变量和结构字段的类型应该是time。时间,而不是* time.Time。时间值可以被多个goroutines同时使用,除了GobDecode、UnmarshalBinary、UnmarshalJSON和UnmarshalText方法不是并发安全的…(此处省略一万字)
作用:可通过Time类型的各种方法对时间进行操作,eg:返回当前时间、时间的比较、时间的格式化等

代码如下:

func timeDemo() {
	t := time.Now()				  // 获取当前时间,此为time.Time类型
	year, month, day := t.Date()  //返回年月日
	fmt.Println(year, month, day) //2020 November 20

	hour, min, sec := t.Clock()	  //返回时分秒
	fmt.Println(hour, min, sec)

	day = t.Day()				  //返回日期
	fmt.Println(day)

	timeStr := t.Format(time.Kitchen)   //返回指定格式时间
	fmt.Println(timeStr)
	
	//更多的操作可参考官方文档
	https://golang.google.cn/pkg/time/#Time
}


 

流程控制

  1. if, switch,mux化
  2. goto, for, select, return, break,continue

编程方式

  1. 面向过程(函数式)
  2. 面向对象
  3. 接口化
  4. 组合

协程与并发

  1. 管道 channel
  2. 协程 go
  3. 广播,生产和消费,串行化
  4. 批量任务 waitgroup
  5. 循环任务 context

值传递与引用传递

  1. &a与a的区别与约束
  2. for range 里的v

单元测试

  1. 单次。testing.T
  2. 压测。testing.B
  3. 并发。testing.PB
  4. 无害化。可多次执行结果一致,执行后无有害数据变更
  5. CI。 go test ./…

跨平台,跨语言

  1. 交叉编译
  2. wasm
  3. cgo
二、工具基础

Git

  1. 基本概念
  2. 常用命令pull,add,commit,merge
  3. 经典场景
  4. 常见错误

IDE

  1. goland
  2. vscode

画图工具

  1. 流程图
  2. UML图
  3. 架构图
  4. 思维导图
三、Golang高级编程

错误处理

  1. 打栈
  2. 单次处理

内存调优

  1. pprof、火焰图
  2. gc优化
  3. 对象池

并发编程

  1. 并发模型GPM
  2. context与waitgroup
  3. 广播
  4. 原子操作
  5. 读写锁
  6. CAS
  7. 串行处理

序列化(文本协议)与传输协议

  1. xml, json, protobuf, toml, yaml, 自定义协议
  2. http(s),ws(s), udp, kcp, tcp

缓存

  1. 幂等
  2. 分布式锁
  3. 缓存一致性的两种策略

网络编程

  1. http
  2. websocket
  3. tcp

项目管理

  1. 代码生成
  2. 代码检测,race、codedev、fmt

容器化

  1. docker
  2. kubernate

服务器

  1. Linux常见命令
  2. 线上监控与调优
  3. supervisor、ngnix

反射

 

四、Web服务

服务框架(如Java中的Spring MVC)

Gin

  1. Http Router
  2. Json Validation

ORM框架 (如Java中的MyBatis)

  1. gorm
  2. 数据映射原理

日志框架 (如Java中的logf4j)

  1. Zap

Web调优 (如Java中的JVM调优)

  1. 线程调优
  2. 优雅启停
     
五、数据库

关系型数据库

  1. Postgres
  2. MySQL

SQL基础

  1. SQL语句:CRUD/Join/Group/Order …
  2. jsonb

索引基础

  1. 索引规则

存储引擎

  1. WAL(xLog)
  2. 物理存储
  3. 事物隔离级别/锁 MVCC

索引原理

  1. B树
  2. B+树
  3. 红黑树
  4. Explain

高可用

  1. 主从复制
  2. 水平扩展
  3. 垂直拆分
  4. 集群分布

应用拓展

  1. 分库
  2. 分表

数据同步

  1. 流复制
  2. bottledwater-pg data change delivery to mq

非关系型数据库

Redis

基础语法

  1. string / hash / list / map / zset

存储引擎

  1. 数据结构 / 内存模型
  2. 过期策略
  3. 持久化

应用场景

  1. 缓存应用
  2. 分布式锁

高可用

  1. Redis Cluster
  2. Redis Sentinel
     
六、微服务

RPC框架

GRPC

  1. protobuf
  2. 通信原理

微服务网关

Kong

  1. Auth
  2. API Manage
  3. Route
  4. Load Balancing / Rate Limiting

注册中心

Consul

ETCD

  1. keeplive
  2. Lease

配置中心

ETCD / Consul

Nacos / Apollp / 阿里云ACM

  1. 缓存机制
  2. 通信机制
  3. 服务数据高可用
  4. Raft

消息中间件

分布式调度

服务治理

链路追踪

 

七、网络安全

编码安全

行为安全

 

八、大数据

离线计算

数据仓库

实时计算

 

九、DevOPS

Linux

CD

CI

监控

 

十、Cloud Native

容器化

集群管理

Service Mesh

 

十一、技术管理

项目管理

文档管理

技术招聘

团队管理

 
 

写在最后

给自己,也给大家,路漫漫其修远兮,我将上下而求索,希望自己在Go这条路上不断前行,能点亮出一颗自己的“技能树”