包
包的定义 => package
关键字,包名通常和目录名一致,不能包含 -
- 一个文件夹就是一个包
- 文件夹里面放的都是
.go
文件
包的导入 => import
- 包导入路径是从
$GOPATH/src/
后面的路径开始写起 - 单行导入
- 多行导入
- 给导入的包起别名
- 匿名导入 =>
sql
包导入时会提及
包中标识符(变量名\函数名\结构体名\常量…
)可见性 => 标识符首字母大写标识对外可见
init()
- 包导入的时候会自动执行
- 一个包里面只有一个
init()
函数 init()
没有参数也没有返回值,也不能直接调用- 多个包的
init
执行顺序 - 一般用于一些初始化操作…
接口
接口是一种类型,一种抽象的类型。
接口就是你要实现的方法的清单。
接口的定义
1 | type mover interface { |
接口的实现
实现了接口的所有方法就是实现了这个接口。
实现了接口就可以当成这个接口类型的变量。
接口变量
实现了一个万能的变量,可以保存所有实现了我这个接口的类型的值。
通常是作为函数的参数出现。
空接口
1 | interface{}: 空接口 |
接口中没有定义任何方法,也就是任意类型都实现空接口。任何类型都可以存放在空接口中。
用途:
- 作为函数参数。
map[string]interface{}
接口底层
动态类型
动态值
类型断言
做类型断言的前提是一定要是一个接口类型的变量。
1 | 方式一: |
1 | 方式二: |
文件操作
打开/关闭文件
小细节需要注意的地方,在打开文件时候,会返回 文件指针 和 错误信息,defer
的执行顺序很关键。一定要注意写法。
1 | file, err := os.Open("./xxx.txt") |
读文件
读取文件三种方式:
fileObj.Read()
bufio
ioutil
写文件
1 | file, err := os.openFile() |
反射
接口类型的变量底层分类两个部分:动态类型和动态值。
反射的作用: json
等数据解析\ORM等工具…
反射的两个方法
relfect.TypeOf()
relfect.ValueOf()
goroutine
- 将要并发执行的任务包装成一个函数,调用函数的时候加上
go
关键字,就能够开启一个goroutine
去执行该函数的任务。 goroutine
对应的函数执行完,该goroutine
就结束了。- 程序启动的时候会自动创建一个
goroutine
去执行main
函数。 main
函数结束了,那么程序就结束了,由该程序启动的所有其他goroutine
也都结束了。
goroutine
启动
1 |
|
goroutine
什么时间结束?
goroutine
对应的函数执行结束了,goroutine
就结束了。main
函数执行结束了,由main
函数启动的goroutine
也都结束了。
sync.WaitGroup
var wg sync.WaitGroup
wg.Add(1)
计数器 +1wg.Done()
计数器-1wg.Wait()
等待
goroutine
调度模型
goroutine
的本质: GMP
G
:goroutine
M
:P
:
goroutine
与 操作系统线程(OS线程
)的区别
goroutine
是用户态的线程,比内核态的线程更加轻量级一些,初始化时之占用2k的空间,可以轻松开启是十万个 goroutine
也不会崩内存。
M:N
: 把 m
个 goroutine
分配给 n
个操作系统线程去执行。
runtime.GOMAXPROCS
Go1.5
之后默认操作系统的逻辑核心数,默认跑满 CPU
。runtime.GOMAXPROCS(1)
: 只占用一个内核。
work pool
模式
开启一定数量的 goroutine
去干活。
math/rand
1 | func f() { |
channel
通过 channel
实现多个 goroutine
之间的通信。CSP
:通过通信来共享内存。
channel
是一种类型,一种引用类型。 make
函数初始化之后才能使用。(slice
、map
、channel
)
chan
声明与初始化
1 | var b chan int // 需要指定通道中元素的类型 |
chan
必须make
函数初始化之后才可以使用!!!1
2b = make(chan int) // 不带有缓存的通道的初始化
b = make(chan int, 3) // 带有缓存的通道的初始化
chan
的操作
箭头标识数据流动的方向。
<-
: 发送值ch1 <- 1
->
: 接收值<- ch1
close()
: 关闭
1 | for { |
单向通道
通常作为函数的参数,只读通道:<-ch
只写通道:ch<- int
。
select
同一时刻有多个通道接收数据。
使用 select
语句能提高代码的可读性。
- 可处理一个或多个
channel
的发送/接收操作。 - 如果多个
case
同时满足,select
会随机选择一个。 - 对于没有
case
的select{}
会一直等待,可用于阻塞main
函数。
package sync
包内容
互斥锁
sync.Mutex
是一个结构体,是一个值类型,给函数传参数的时候要传递指针。
两个用法
1 | var lock sync.Mutex |
为什么要加锁?
防止同一时刻多个 goroutine
操作同一个资源。
读写互斥锁
应用场景
适用于读多写少的场景下。
优点
- 读的 goroutine 来了获取的是读取锁,后续的 goroutine 能读不能写。
- 写的 goroutine 来了获取的是写锁,后续的 goroutine 不管是读写都要等待获取锁。
使用
1 | var rwLock sync.RWMutex |
等待组
sync.WaitGroup
用来等 goroutine
执行完成再继续。
同时是一个结构体,是一个值类型,给函数传参数的时候要传递指针。
使用
1 | var wg sync.WaitGroup |
sync.Once
使用场景
某些函数只需要执行一次的时候就可以使用 sync.Once
。
比如并发,博客中加载图片
1 | var once sync.Once |
sync.Map
使用场景
并发操作一个 map
的时候,内置的 map
不是并发安全的。
使用
是一个开箱即用的并发安全的 map
。
1 | var syncMap sync.Map |
原子操作
go
语言中内置了一些针对内置的基本数据类型的一些并发安全的操作。
1 | var i int64 = 10 |
网络编程
OSI
七层模型
http
: 超文本传输协议。
规定了:浏览器和服务器之间通信的规则。HTML
: 超文本标记语言
学习 HTML
就是学习标记的符号、标签。
CSS
: 层叠样式表
- 规定了
HTML
中标签的具体样式(颜色\背景\大小\位置\浮动)
JsvsScript
: 一种跑在浏览器上的编程语言。
http.Client
今日分享
注释
\ 日志
\ 单元测试