协程、线程,
协程:用户态,轻量级 KB级别
线程,线程跑多个协程 MB级别
“快速”打印:
想要快速打印就要开启多个协程
开启一个协程的方法:调用函数时加上关键字“go“即
func hello(i int){
}
go func(j,int){
hello(j)//调用前加go
}
CSP
协程之间的通信:通过通信来共享内存 "chinnal通道"
通过共享内存实现通信需要通过一个互斥量来对内存进行加速
也就是获得一个临界区权限,但这么做可能会影响程序的性能
channal
make(chan元素类型,[缓冲大小])
无缓冲通道 make(chan int)
有缓冲通道 make(chan int,2)(容量为2)
channal的具体使用
func CAL(){
src:=make(chan int)//无缓冲通道
dest := make(chan int,3)//有缓冲通道容量3
go func(){//开启一个协程
defer close(src)
for i:=0;i<10;i++{
src <- i
}
}()
go func(){//开启一个协程
defer close(dest)
for i:= range src{
dest <- i*i
}
}
for i :=range dest{
//复杂操作
println(i)
}
}
A 子协程发送0-9数字
B 子协程计算输入数字的平方主协程输出最后的平方数
通过range遍历
此程序通过通信实现共享内存
并发安全Lock
//对变量进行2000次+1操作,预期结果10000
//通过临界区进行的实现
var(
x int64
lock sync.Mutex
)
func addWithLock(){
for i:=0;i<2000;i++{
lock.Lock()
x+=1
lock.Unlock()
}
}
func addWithoutLock(){//没有对临界区形成保护,无加锁
for i:=0;i<2000;i++{
x+=1
}
}
func Add{
x=0
for i:=0;i<5;i++{
go addWithoutLock()
}
time ,Sleep(time.Second)
Println("WithoutLock:",x)
x=0
for i:=0;i<5;i++{
go addWithLock()
}
time .Sleep(time.Second)
println("WithLock:",x)
}
加锁值和不加锁值进行对比
结果加锁10000
不加锁5565
可见加锁是对高并发进行保护,这就反应了并发安全区问题
waitGroup 可以实现并发同步在Sync包下
Add(delta int ) 计数器+delta
Done() 计数器减一
Wait() 阻塞直到计数器为0)
当计数器为0就表示所有并发任务已完成
高并发编程的三个概念
Goroutine
Channal
Sync
依赖管理(各种开发包,开发组件工具提升开发效率)
GOPATH
配置go语言支持的环境变量,是go项目的工作区
bin 项目二进制文件
pkg 项目编译的中间变量,加速编译
src 项目源码
工程在src下
AB不同时工作
GO VENDOR
vendor存放项目依赖的一个库本
AB比兼容
GO Module
1.配置文件,描述依赖 go.mod
2.中心仓库管理依赖库 Proxy
3.本地工具 go get/mod
依赖配置
version
indirect
incompatible
依赖分发-回源
依赖分发——变量GOPROXY
工具-go mod/get
单元测试
输入——>测试单元——>输出——>校对
规则:
所有测试文件以_test.go结尾
func TestXxx(*testing,T)
初始化逻辑放到TestMain中
单元测试——assert
单元测试——覆盖率
一般 50%-60%较高80%+
单元测试-Mock(开源测试包)
分层结构
数据层:数据Model,外部数据的增删改查
逻辑层:业务 Entity ,处理核心业务逻辑输出
视图层:试图view,处理和外部的交互逻辑
GIn高性能 go web框架
元数据 索引
数据行——>内存Map
例如:
var(
topicIndexMap map[int64]*Topic
postIndexMap map[int64][ ]*Post
)
Service
实体
type PageInfo struct{
Topic *respository.Topic
PostList [ ]*repository.Post
}
流程:参数校验——>准备数据——>组装实体
Controller
构建View对象
业务错误码
Router
初始化数据索引
初始化引擎配置
构建路由
启动服务
运行测试
go run server.go