Go进阶
Day2 Go进阶
协程
func hello(i int) {
println("hello " + fmt.Sprint(i))
}
func Helloroutine() { //协程
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
//防止该进程跑完,协程还没有跑完
time.Sleep(time.Second)
}
channel
func ClaSquare() {
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)
}
}
Lock
var ( //该变量操作可上锁
x int64
lock sync.Mutex
)
func addwithLock() {
for i := 0; i < 2000; i++ {
lock.Lock()
x++
lock.Unlock()
}
}
func addwithoutLock() {
for i := 0; i < 2000; i++ {
x++
}
}
func main() {
x = 0
for i := 0; i < 5; i++ {
go addwithLock()
}
time.Sleep(time.Second)
println("Lock:", x)
x = 0
for i := 0; i < 5; i++ {
go addwithoutLock()
}
time.Sleep(time.Second)
println("withoutLock:", x)
}
waitgroup
func hello(i int) {
println("hello " + fmt.Sprint(i))
}
func Helloroutine() { //协程
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func(i int) {
//defer后面的函数只有在当前函数执行完毕后才能执行,通常用于释放资源。
defer wg.Done()
hello(i)
}(i)
}
wg.Wait()
}
依赖管理Go Module
1.配置文件,描述依赖 go.mod
2.中心仓库管理依赖库 Proxy
3.本地工具 go get/mod
单元测试
Mock测试
基准测试
- 优化代码,需要对当前代码分析
- 内置的测试框架提供了基准测试的能力
性能优化
- 使用 Benchmark 进行基准测试;
- 尽可能为 slice 和 map 预分配内存(通过在
make
时指定容量信息); - 注意为切片创建切片不会创建新的底层数组,这可能会导致内存泄漏发生,此时可用
copy
代替 re-slice; - 多个字符串拼接时,使用
strings.Builder
比直接使用+
或使用bytes.Buffer
更快(这和 Java 倒是十分相似,Java 也推荐使用StringBuilder
拼接多个字符串;其实他们的底层逻辑都是类似的); - 当需要占位符时,可使用空结构体(
struct{}
)代替,其不会占据镇和内存空间; - 使用
atomic
包代替锁修改变量;