# GOLANG语言学习——day02|青训营笔记(Q&A)

222 阅读3分钟

[更新中 ...]

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] )

版本选择规则:选用最低(最新)的可兼容版本

image.png


标题:Go 语言进阶与依赖管理 - 掘金 网址:juejin.cn/c