多线程程序在一个核的CPU上运行
多线程程序在 多个核的CPU上运行
go可以充分发挥多核优势,高效运行
协程:用户态,轻量级线程,栈MB级别。
线程:内核态,线程跑多个协程,栈KB级别。
eg:开启协程
func hello(i int){
println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine(){
for i:=0; i < 5; i++;{
go func(j int) {
hello(j);
}(i)
}
time.Sleep(time.Second)
}
GO语言提倡通过
通信共享内存
而不是通过共享内存而实现通信
make(chan 元素类型,[缓冲大小])
eg:
A子协程发送0~9数字
B子协程计算输入数字的平方
主协程输出最后的平方数
func CalSquare() {
src := make(chan int)
dest := make(chan int, 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)
}
}
对变量执行2000次+1操作,5个协程并发执行
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)
}
计数器
开启协程+1;执行结束-1;主协程阻塞直到计数器为0.
func ManyGowait() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func() {
defer wg.Done()
hello(j)
}(i)
}
wg.Wait()
}
弊端
场景:A和B依赖于某一package的不同版本。
问题
:无法实现package的多版本控制
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个 package依赖的冲突问题。
弊端
问题
module example/project/app //依赖管理基本单元
go 1.16//原生库
require (
//单元依赖
example/lib1 v1.0.2
example/lib2 v1.0.0 // indirect
example/lib3 v0.1.0-20190725025543-5a5fe074e612
example/lib4 v0.0.0-20180306012644-bacd9c7ef1dd// indirect
example/lib5/v3 v3.0.2
example/lib6 v3.2.0+incompatible
)
依赖标识:[Module Path] [Version/Pseudo-version]
语义化版本
使用indirect标明间接依赖模块
GOPROXY="https://proxy1.cn,https://proxy2.cn,direct服务站点URL列表,“direct”表示源站
从上到下,覆盖率逐层变大,成本却逐层降低
如何衡量代码是否经过了足够的测试?
如何评价项目的测试水准?
如何评估项目是否达到了高水准测试等级?
代码覆盖率
monkey : https://github.com/bouk/monkey
快速Mock函数
结构体
var(
topicIndexMap map[int64]*Topic
postIndexMap map[int64][]*Post
)
运行测试
go run server.go