[更新中 ...]
golang打卡第二天,上午听完了课,下午将第一堂课的笔记整理了一下并记录成了QA的形式,回答一些问题时添加上了我类比java的一些理解,欢迎同学们阅读,一起解决我们今天上课遇到的难题呀~(不亏是字节跳动,货很干也很难,课程很跳学不动哈哈哈哈);
如果理解有误也欢迎同学们指出不断完善我们的golang基础知识;
如果你有一些好的理解,或者珍贵的Q&A也欢迎在评论区留下你宝贵的见解呀~。
golang语言进阶及依赖管理
1、语言进阶 2、依赖管理 3、测试 4、项目实战
go.mod工具如何使用
【更新中 ...】
前提:golang版本在1.14及以上
以下是cmd命令
go version
go version go1.20.4 windows/amd64
go evn -w GO111MODULE=auto //开启module功能 go evn -w GOPROXY=goproxy.cn,direct //配置国内镜像云仓库,这里使用的是七牛云
这个更改国内镜像云仓库我感觉应该放在第一节课的,否则从国外网站调用资源速率会很慢还有可能失败,我就是开始时vs-code上一些go的插件下载不了降低了许多编程效率
在后期工程中go mod 的使用方式按照如下流程 创建damo文件夹作为工程名 ==> 终端中输入 go mod init dome (生成go.mod文件) ==> 编写main.go主文件 ==> main.go中使用的包使用go mod tidy 加载依赖 ==> 最后使用go mod vendor 将使用的依赖复制到vendor文件夹下
后期开始做项目也会不断更新的
语言进阶——并发编程
Q. go语言如何实现高性能并发编程?
A. Go可以充分发挥多核优势,高效运行 (多线程程序的线程在单核cpu上是抢占式运行,每个线程都有可能被调用即为并发,而在多核cpu下可以减缓抢占频率进而提高程序运行效率,当cpu核数等于线程数时即为并行)
Q. go语言如何充分发挥多核优势,提高运行效率呢
A. go语言在处理大并发时使用协程,而java在处理大并发时使用的是线程,协程相较于线程更加轻量(栈KB级别),因此运行效率更高(一个线程也可以拥有多个协程)
Q. 如何开启一个协程?
A.
package main
import (
"fmt"
"time"
)
// 无返回值,实参类型为int的函数
func hello(i int){
println("hello goroutine: ",Sprint(i))
}
func main() {
for i := 0 ; i < 5 ; i++ {
//开启协程
go func(j int){
hello(j)
}(i)
}
//协程休眠
time.Sleep(time.Sceond)
}
Q. 什么是通过通信共享内存,如何实现?[协程之间的通信问题]
A.
Q. 如何创建无缓冲通道(channel)与有缓冲通道及双方的区别?
A.
作用:将上一层的协程结果获取,并发送一个特定的值到下一个协程
创建通道
//通式:make(chan 元素类型,[缓冲大小])
make(chan int) //创建一个类型为int的无缓冲通道
make(chan int,2) //创建一个类型为int有两个缓冲的通道
使用过程:使用在协程通信的过程中
两种通道的区别:
无缓冲通道:导致发射的协程与接收的协程同步
有缓冲通道:解决协程同步问题(我的理解是:将发射协程的发送值先存放至缓冲通道内,由于通道数目有限,所以当通道被占满后,会阻塞发射协程的运行)
Q. 如何使用锁(类似于java中的同步锁)
A. lock sync.Mutex //声明锁
锁定涵义:临界区的并发控制
锁的作用:为了避免多个线程同时对公共资源进行操作,以课上的例子为例进行说明的:假如有一个公共的变量资源i,现在i的值为3,如果说5个线程中的3个线程同时对i进行操作[同时取到3,同时加1],导致实际应该为i=6变成了i=4,上锁即使避免此类情况发生(不上锁跑10000应该单核吧哈哈哈)
练习
package main
import (
"time"
"sync"
)
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 main() {
x = 0
for i := 0;i < 5;i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("addWithLock result: ",x)
x = 0
for i := 0;i < 5;i++ {
go addWithoutLock()
}
time.Sleep(time.Second)
println("addWithOutLock result: ",x)
}
Q. 如何美化高并发协程任务
[原]
package main
import (
"fmt"
"time"
)
// 无返回值,实参类型为int的函数
func hello(i int){
println("hello goroutine: ",Sprint(i))
}
func main() {
for i := 0 ; i < 5 ; i++ {
//开启协程
go func(j int){
hello(j)
}(i)
}
//协程休眠
time.Sleep(time.Sceond)
}
[改]
import "sync"
func main() {
var wg sync.WaitGroup //声明一个变量
wg.Add(5)
for i:=0 ;i < 5; i++ {
go func(j int){
defer wg.Done() // 减少协程数量
hello(j)
}() //带有参数的函数开启协程方式
}
wg.Wait() //阻塞关闭协程
}
依赖管理
使用SDK引入依赖(java中的jar包)
Go PATH(Deprecated): 类似于java中自带的lib,无法进行版本锁定
Go Vendor:类似于java工程下设置lib依赖文件加,(是否像java工程中的lib一样需要手动下载导入?),同时也是无法锁定依赖版本,比较麻烦
Go mod:类似于Java中的Maven仓(Maven中的pom.xml 等同于 go.mod)
go.mod的 配置
go mod init xxx 后自动生成,并可通过go mod的一些方法改变
module [你的依赖管理基本单元路径]
go 1,20 //你实际安装的golang版本:可在cmd中输入go version查看
require( //配置你的单元依赖 //例: example/lib1 v1.0.2(版本号)[对于主版本较大的依赖,会+incompatible] )
版本选择规则:选用最低(最新)的可兼容版本
标题:Go 语言进阶与依赖管理 - 掘金 网址:juejin.cn/c