这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天,今天的学习内容是Go语言进阶及工程实践。
Go的并发编程
协程 Goroutine
协程是用户态的轻量级线程。栈大小在kb级别。启动Goroutine的语法非常简单,只需要在函数前面加上go关键字就可以了。例如:go test()
通道 Channel
使用通道来让协程共享内存,是各个Goroutine通信的管道,使用通道可以防止竞态条件发生。
Channel按照有无缓冲区分为无缓冲区channel和有缓冲区channel,创建的语法分别为:
s := make(chan int) // 缓冲区
s := make(chan int,4) // 有缓冲区,缓冲区长度为4
channel的长度,取决于channel中数据剩余量。
使用channel产生死锁的情况:
- 读取空channel
- 过度写入
如果向已关闭的channel写入数据会发生panic而不是死锁
锁 Lock
Go语言并发程序中对公共资源访问的限制最常见的是互斥锁,即sync.Mutex
在需要上锁的前面使用Lock()函数进行上锁,结束的时候使用Unlock()函数解锁。
线程同步 WaitGroup
使用WaitGroup使进程进行同步,不考虑底层实现的话,一共三个函数Add(n int)使计数加n,Done()使计数减1,Wait()等待计数为0。
在使用的时候,应当合理使用,在每次启动协程之前调用Add(),在协程里面写上defer wg.Done()保证一一对应。
依赖管理
迭代历程:Gopath -> Go Vendor -> Go Module
创建项目时init创建go.mod文件。
依赖选取的时候,会选择最低兼容的版本。
使用GoLand省心省力
单元测试
回到了软件测试的课堂233
以后应该不会当测试,暂时不考虑这个。
项目实战
git到的代码和课堂展示的代码好像不太一样,git下来的是直接连的数据库,也不是很想改了,看看就得了吧。
课后实践的倒是有一些思路啥的。
- 支持发布帖子。
感觉随便写写就行了。
- 本地Id生成需要保证不重复、唯一性。
根据本地时间戳生成Id应该就可以了。
- Append文件,更新索引,注意Map的并发安全问题。
每次操作的时候上锁之类的,不是很清楚。