Gorotine
无缓冲的信道在取消息和存消息的时候都会挂起当前的 goroutine,除非另一端已经准备好。如果不用信道来阻塞主线的话,主线程就会过早跑完,其他线程都没有机会执行。 无缓冲的信道永远不会存储数据,只负责数据的流通。体现在:
- 从无缓冲信道取数据,必须要有数据流进来才可以,否则当前线阻塞
- 数据流入无缓冲信道, 如果没有其他 goroutine 来拿走这个数据,那么当前线阻塞
Channel
Actor模型和CSP模型区别
Actor 之间直接通讯,而 CSP 是通过 Channel 通讯,在耦合度上两者是有区别的,后者更加松耦合。
主要的区别在于:CSP 模型中消息的发送者和接收者之间通过 Channel 松耦合,发送者不知道自己消息被哪个接收者消费了,接收者也不知道是哪个发送者发送的消息。在 Actor 模型中,由于 Actor 可以根据自己的状态选择处理哪个传入消息,自主性可控性更好些。
在 Go 语言中为了不堵塞进程,程序员必须检查不同的传入消息,以便预见确保正确的顺序。CSP 好处是 Channel 不需要缓冲消息,而 Actor 理论上需要一个无限大小的邮箱作为消息缓冲。
CSP 模型的消息发送方只能在接收方准备好接收消息时才能发送消息。相反,Actor 模型中的消息传递是异步 的,即消息的发送和接收无需在同一时间进行,发送方可以在接收方准备好接收消息前将消息发送出去。
make(chan int) //创建一个无缓冲的Channel
make(chan int, 100) //创建一个有缓冲的Channel
Mock
通过模拟请求,减少测试环境对其他文件的依赖
package main
import (
"bou.ke/monkey"
"github.com/stretchr/testify/assert"
"testing"
)
func a() int {
return 1
}
func hello() int{
out:=a()
return out
}
func TestMock(t *testing.T) {
monkey.Patch(a,func()int{return 2}) //把a函数mock成返回值为2的函数
defer monkey.Unpatch(a)
out := hello()
assert.Equal(t,2,out)
}
终端运行指令:
go test temp_test.go -gcflags "all=-N -l"
直接点击运行的话patch不生效
基准测试
基准测试以Benchmark为前缀,需要一个testing.B类型的参数b,基准测试必须要 *执行b.N**次,这样的测试才有对照性,b.N的值是系统根据实际情况去调整的,从而保证测试的稳定性。
package main
import "math/rand"
var ServerIndex [10]int
func InitServerIndex() {
for i := 0; i < 10; i++ {
ServerIndex[i] = i + 100
}
}
func Select() int {
return ServerIndex[rand.Intn(10)]
}
func main() {
}
//test文件
package main
import (
"testing"
)
func BenchmarkSelect(b *testing.B) {
InitServerIndex()
b.ResetTimer()
for i := 0; i < b.N; i++ {
Select()
}
}
func BenchmarkSelectParallel(b *testing.B) {
InitServerIndex()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Select()
}
})
}
终端运行指令:
go test temp_test.go temp.go -bench=.* -benchmem
不加.* -benchmem不给生效,不知道什么原因
执行结果:
goos: windows
goarch: amd64
BenchmarkSelect-8 58084939 19.5 ns/op
BenchmarkSelectParallel-8 17853555 65.1 ns/op
PASS
ok command-line-arguments 2.989s
第二列很大的数字是测试的次数
第三列 19.5 ns/op表示每一个操作耗费多少时间(纳秒) (即BenchmarkSelect函数进行了58084939次,每次求和花费了19.5 ns)
可以用fastrand替换rand提高性能