go语言


基础篇视频:https://www.bilibili.com/video/BV1hv411x7we?p=7

go圣经:http://books.studygolang.com/

gin框架篇:https://www.topgoer.com/gin%E6%A1%86%E6%9E%B6/ 

mac下go语言环境的搭建:https://www.jianshu.com/p/29124e2f656e

Golang基础(变量[普通变量、数组、切片、map、list、ring]声明及赋值):https://blog.csdn.net/qq_31387691 

shell下运行go:https://blog.csdn.net/lovechris00/article/details/71178881

go语言语法的踩坑总结:https://blog.csdn.net/kongkongkkk/article/details/78675095

注意:1.在GO语言中int、int32、int64被认为是不同的类型。 

var value1 int32 = 22 

value2 := 22 

fmt.Println(value1 == value2)  valid operation

2.变量冲突;变量声明使用 := 方式时,左值必须是未声明的,否则会出现编译错

var a int

a := 23

https://blog.csdn.net/c315838651/article/details/105007931

3.变量声明了,就必须要使用,否则会出现编译错误: b declared and not used

4.++自增和- -自减运算符类比C语言,相当于前置的自增和自减,而且go语言中不区分前置或后置

 不能使用++自增或- -自减运算符初始化变量和对变量赋值:syntax error: unexpected ++ at end of statement

5.if…else 语句中的 else 必须和 if 的 ’ } ’ 在同一行,否则编译错误 :unexpected else, expecting }

6.switch 中的 case和default分支不用添加break;switch 中的 case和default分支不用添加break;switch的case分支的常量表达式可以同时测试多个值;switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型

注:行长规定:字符串拼接用"","",""换行形式拼接成。 

switch和select相关:https://blog.51cto.com/qingkechina/1685383

for循环:

package main
import "fmt"
func main() {
    var number = [5]int{1, 2, 3, 4, 5}
    for i, x := range number {
        fmt.Println(i, x)
    }
}

 常用api:https://studygolang.com/pkgdoc

defer函数:

  • defer 主要用于简化编程(以及实现 panic/recover ,后面会专门写一篇相关文章来介绍)

  • defer 实现了函数的延迟调用;

  • defer 使用要点:延迟调用,即时求值和反序调用

  • go 语言的 return 会被编译器翻译成多条指令,其中包括保存返回值,调用defer注册的函数以及实现函数返回

log.print和panic函数:https://blog.csdn.net/whatday/article/details

总结起来log.Fatal函数完成:(和os.Exit()相比多了第一步!)

  1. 打印输出内容
  2. 退出应用程序
  3. defer函数不会执行

总结panic函数:

  1. 函数立刻停止执行 (注意是函数本身,不是应用程序停止)
  2. defer函数被执行
  3. 返回给调用者(caller)
  4. 调用者函数假装也收到了一个panic函数,从而
    4.1 立即停止执行当前函数
    4.2 它defer函数被执行
    4.3 返回给它的调用者(caller)
  5. ...(递归重复上述步骤,直到最上层函数)
    应用程序停止。
  6. panic的行为

简单的总结panic()就有点类似java语言的exception的处理,因而panic的行为和java的exception处理行为就非常类似,行为结合catch,和final语句块的处理流程。

Todo:panic和recover详解(包含源码,难!!!)https://segmentfault.com/a/1190000023910280

copy和sort接口:https://blog.csdn.net/qq_31387691/article/details

copy数组的复制,切片应用广泛;sort排序,如:sort.Ints(a) 升序排列a数组;

os.Stdin指向标准输入文件/dev/stdin,即os.Stdin是标准输入文件/dev/stdin的指针 .

go的并发:https://blog.csdn.net/jiese1990/article/details/21752159 

goroutine:使用者分配足够多的任务,系统能自动帮助使用者把任务分配到 CPU 上,让这些任务尽量并发运作。这种机制在 Go语言中被称为 goroutine

goroutine是Go并行设计的核心。goroutine说到底其实就是协程,但是它比线程更小,十几个goroutine可能体现在底层就是五六个线程,Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine比thread更易用、更高效、更轻便。

goroutine的简单用法:https://blog.csdn.net/tennysonsky/article/details/79062451;

创建goroutine:只需在函数调?语句前添加 go 关键字,就可创建并发执?单元。开发?员无需了解任何执?细节,调度器会自动将其安排到合适的系统线程上执行。

runtime包:

1.runtime.Gosched() 用于让出CPU时间片,让出当前goroutine的执行权限,调度器安排其他等待的任务运行,并在下次某个时候从该位置恢复执行。

2.调用 runtime.Goexit() 将立即终止当前 goroutine 执?,调度器确保所有已注册 defer 延迟调用被执行。

Channel原理(难+详细!):https://blog.csdn.net/u010853261/article/details/85231944

channel主要是为了实现go的并发特性,用于并发通信的,也就是在不同的协程单元goroutine之间同步通信。

创建channel时候有两种,一种是带缓冲的channel一种是不带缓冲的channel。创建方式分别如下:

// buffered
ch := make(chan Task, 3)
// unbuffered
ch := make(chan int)

当我们新建channel的时候,hchan是在heap里面分配的。当我们使用make去创建一个channel的时候,实际上返回的是一个指向channel的pointer,所以我们能够在不同的function之间直接传递channel对象,而不用通过指向channel的指针。

 channel主要特性:

(1)goroutine-safe
hchan mutex

(2)store values, pass in FIFO.
copying into and out of hchan buffer

(3)can cause goroutines to pause and resume.
a)hchan sudog queues
b)calls into the runtime scheduler (gopark, goready)

(4)channel的高性能所在:
a)调用runtime scheduler实现,OS thread不需要阻塞;
b)跨goroutine栈可以直接进行读写;

channel的数据结构相对比较简单,主要是两个结构:
1)一个数组实现的环形队列,数组有两个下标索引分别表示读写的索引,用于保存channel缓冲区数据。
2)channel的send和recv队列,队列里面都是持有goroutine的sudog元素,队列都是双链表实现的。
3)channel的全局锁。

Go语言特性:

1.垃圾回收
a.内存自动回收,再也不需要开发人员管理内存
b.开发人员专注业务实现,降低了心智负担
c.只需要new分配内存,不需要释放
2.天然并发
a.从语言层面支持并发,非常简单
b.goroute,轻量级线程,创建成千上万个goroute成为可能
c.基于CSP(Commnuncating Sequential Process)模型并发

func main() {
go fmt.Println(“hello")
}

3.channel:简单例子理解channel并发
a.管道,类似unix/linux中的pipe
b.多个goroute之间通过channel进行通信
c.支持任何类型;channel的通信以及具体的读写操作

func test_pipe() {
pipe := make(chan int, 3)
pipe <- 1
pipe <- 2
pipe <- 3

sum := <-pipe
// pipe <- 4

fmt.Println("sum=", sum)
fmt.Println(len(pipe))
}

结果:

sum= 1
2

客户端与服务端的响应 grpchttps://blog.51cto.com/u_15127505/4339920

官方的介绍是:gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

从定义上可以看到这个主要是给移动应用做通信用的,其次他支持双向的通信,因此可以说GRPC是一个RPC框架没错,但是

gRPC主要有4种请求/响应模式,分别是:

(1) 简单模式(Simple RPC)

客户端发起一次请求,服务端响应一个数据,即标准RPC通信。

ClientRequest:1,ServerResponse:1

(2) 服务端数据流模式(Server-side streaming RPC)

这种模式是客户端发起一次请求,服务端返回一段连续的数据流。典型的例子是客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端。

ClientRequest:1,ServerResponse:N

(3) 客户端数据流模式(Client-side streaming RPC)

与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。典型的例子是物联网终端向服务器报送数据。

ClientRequest:N,ServerResponse:1

(4) 双向数据流模式(Bidirectional streaming RPC)

这是客户端和服务端都可以向对方发送数据流,这个时候双方的数据可以同时互相发送,也就是可以实现实时交互。比如聊天应用。

ClientRequest:N,ServerResponse:N

grpc客户端服务度简单通信(包含proto相关):https://blog.51cto.com/u_9291927/2332271

proto相关:https://www.jianshu.com/p/c81eca3fd603

 go语言的http server实现:https://mp.weixin.qq.com/s?__biz=MzU4MTE2NDEyMQ==&mid=2247493895&idx=1&sn=c7295372b2792651ca0d12bfcc6abee6&scene=21#wechat_redirect

先编译再运行:编译go build a.go生成a.exe文件,再执行exe 文件

Go编译运行:go run a.go

 (六种方式)结论:fasthttp > FunTester > http    https://blog.51cto.com/FunTester/4848002

基本图:

 go语言的优势:https://www.techug.com/post/bad-and-good-of-golang.html

性能、并发、生态、grpc、

go语言入门相关:https://blog.csdn.net/weixin_36338224/article/details/116189718

 用go做简单测试:https://go.dev/doc/tutorial/add-a-test

 备注:某大佬git地址:https://gitee.com/zhangyafeii//(主要包含go语言项目,py+flask项目)