彩票网站建设多少钱,深圳网站建设ln12345,重庆网站建设公司电话,人人商城网站开发依赖配置 - version开始#xff0c;就开始很难听懂了#xff0c;需要结合很多课后配套资料查阅很多文档和网站....然而好像没有那么多时间#xff0c;一天给3小时学Go真的顶天了.....还有算法和Linux的Mysql... 这几天学Go已经把算法给挤掉了.....下步要权衡一下#xff0c… 依赖配置 - version开始就开始很难听懂了需要结合很多课后配套资料查阅很多文档和网站....然而好像没有那么多时间一天给3小时学Go真的顶天了.....还有算法和Linux的Mysql... 这几天学Go已经把算法给挤掉了.....下步要权衡一下好好分配下时间 目录
并发编程
并发与并行
Goroutine -- 协程与线程
Git从Github拉取代码
CSP
Channel
并发安全Lock
WaitGroup
依赖管理
简介 3个阶段
依赖配置
依赖分发
工具篇go get/mod
依赖管理三要素 并发编程
主要涉及Go并发编程的相关概念
并发与并行 我们两个人在吃午饭。你在吃饭的整个过程中吃了米饭、吃了蔬菜、吃了牛肉。吃米饭、吃蔬菜、吃牛肉这三件事其实就是并发执行的。对于你来说整个过程中看似是同时完成的的。但其实你是在吃不同的东西之间来回切换的 还是我们两个人吃午饭。在吃饭过程中你吃了米饭、蔬菜、牛肉。我也吃了米饭、蔬菜和牛肉。我们两个人之间的吃饭就是并行的。两个人之间可以在同一时间点一起吃牛肉或者一个吃牛肉一个吃蔬菜。之间是互不影响的 上图并发下图并行 并发的多个任务之间是互相抢占资源的并行的多个任务之间是不互相抢占资源的
面试必考的并发和并行有什么区别-腾讯云开发者社区-腾讯云 (tencent.com) 实际开发中并行可以理解为实现并发的一种手段 而Go语言是为高并发而生的它可以发挥多核优势高效运行 Goroutine -- 协程与线程 1进程是操作系统进行资源分配的基本单位 2线程又叫做轻量级进程是进程的一个实体是处理器任务调度和执行的基本单位位。它是比进程更小的能独立运行的基本单位 3协程又称微线程是一种用户态的轻量级线程 对于操作系统来说一个任务就是一个进程Process。比如打开一个浏览器就是启动一个浏览器进程打开一个记事本就启动了一个记事本进程打开两个记事本就启动了两个记事本进程打开一个Word就启动了一个Word进程 And... 有些进程还不止同时干一件事比如Word它可以同时进行打字、拼写检查、打印等事情。在一个进程内部要同时干多件事就需要同时运行多个“子任务”进程内的这些“子任务”称为线程 And... 由于每个进程至少要干一件事所以一个进程至少有一个线程。当然像Word这种复杂的进程可以有多个线程多个线程可以同时执行多线程的执行方式和多进程是一样的也是由操作系统在多个线程之间快速切换让每个线程都短暂地交替运行看起来就像同时执行一样 协程最大的优势就是协程极高的执行效率 1因为子程序切换不是线程切换而是由程序自身控制因此没有线程切换的开销 2和线程切换相比线程数量越多协程的性能优势就越明显 3不需要多线程的锁机制因为只有一个线程 4也不存在同时写变量冲突在协程中控制共享资源不加锁只需要判断状态就好 Final... 所以协程的执行效率比多线程高很多。 此外一个线程的内存在MB级别而协程只需要KB级别 一文快速了解进程、线程与协程-腾讯云开发者社区-腾讯云 (tencent.com)
内核态与用户态 内核态运行操作系统程序操作硬件用户态运行用户程序。 1程序运行在3级特权级上时可以称之为运行在用户态 2运行在0级特权级上时称之为运行在内核态 而Go语言一次可以创建上万个协程这也是Go为什么更适合高并发场景的根源 代码Go创建多个协程
package mainimport (fmt_ fmttime_ time
)func hello(i int) {//Sprint传入参数i的字符串形式便于字符串相加println(hello goroutine : fmt.Sprint(i))
}// go创建协程, 即启用goroutine, 只需要在函数前增加 go 关键字
func HelloGoRoutine() {for i : 0; i 5; i { //创建5个goroutinego func(j int) { //匿名函数接受的参数hello(j)}(i)}//保证子协程执行完之前, 主协程不退出time.Sleep(time.Second) //使goroutine停顿1秒
}func main() {HelloGoRoutine()
}
//乱序输出因为是通过并行打印的Git从Github拉取代码 由于字节内部课每个课都需要从Github拉取课程源码怕忘了在这里总结下 使用git从github上拉取项目到本地_51CTO博客_idea从git上拉取项目 注意 1是在对应目录空白处右键点击“Open Git Bash Here” 2然后将Github复制的代码先git clone再右键粘贴Paste 3拉取前要关闭代理 CSP CSP 即 Communicating Sequential Processes “通信顺序进程” CSP是Go语言特有的并发模型 Go的CSP并发模型是通过goroutine和channel实现的 Go的CSP并发模型 - 简书 (jianshu.com) Go语言所提倡的是“不要以共享内存的方式来通信相反要通过通信来共享内存。” 普通的线程并发模型就是像Java、C、或者Python他们线程间通信都是通过共享内存的方式来进行的。非常典型的方式就是在访问共享数据例如数组、Map、或者某个结构体或对象的时候通过锁来访问 浅谈Go并发之CSP并发模型、协程并发-云社区-华为云 (huaweicloud.com) Channel Channel · Go语言中文文档 (topgoer.com) 1channel是一种类型一种引用类型你可以把它看成一个管道 2一种go协程用以接收或发送消息的安全的消息队列channel就像两个go协程之间的导管来实现各种资源的同步 第二个参数是capacity(容量) 无缓冲通道 有缓冲通道 package mainfunc CalSquare() {src : make(chan int) //无缓冲的通道dest : make(chan int, 3) //有缓冲的通道go func() {defer close(src) //人物完成时关闭通道for i : 0; i 10; i {src - i //子协程A将0-10数字发送到src通道中}}()go func() {defer close(dest)for i : range src {dest - i * i //子协程B接收数字计算平方并发送到dest通道}}()for i : range dest {//复杂操作...println(i) //主协程中依次接受通道dest中数据并打印}
}func main() {CalSquare()
}可以看到输出是有序的因为 虽然启动了多个 goroutine 并行执行但由于通道的同步机制保证了数据的有序传递 并发安全Lock 不加锁会输出预期外的结果undefined这就是并发安全问题 所以开发中要尽量避免对共享内存进行非并发安全的读写操作 换言之我们要对临界区进行权限控制 注意sync. 需要导入包而且需要Goland 1.3版本以上
package mainimport ( //引入包synctime
)var (x int64 //声明x变量作为共享资源用于计数lock sync.Mutex //声明lock变量作为互斥锁保护对x的并发访问
)func addWithLock() {for i : 0; i 2000; i {lock.Lock() //获取互斥锁x 1 //计算lock.Unlock() //释放互斥锁}
}
func addWithoutLock() { //没有互斥锁直接对x进行并发访问for i : 0; i 2000; i {x 1}
}
func Add() {x 0for i : 0; i 5; i {go addWithoutLock() //创建5个goroutine并发执行函数}time.Sleep(time.Second)println(WithoutLock:, x)x 0for i : 0; i 5; i {go addWithLock() //}time.Sleep(time.Second)println(Withlock:, x)
}
func main() {Add()
}WithoutLock: 9784
Withlock: 10000WaitGroup 深入理解 go sync.Waitgroup - 掘金 (juejin.cn) WaitGroup是Go语言里sync包里的结构体用来阻塞主协程等待所有协程执行完是较为常见的并发控制方式 计数器开启协程 1执行结束 -1 主协程阻塞知道计数器为0 package mainimport ( //引入包fmtsync
)func hello(i int) { //定义内部函数println(hello goroutine : fmt.Sprint(i))
}func ManyGoWait() { //并发执行多个goroutinevar wg sync.WaitGroup //创建sync.WaitGroup类型变量wg.Add(5) //开启5个协程for i : 0; i 5; i {go func(j int) {defer wg.Done() //子协程任务执行结束hello(j)}(i) //匿名函数, 传入索引值i}wg.Wait() //阻塞主程序等待所有goroutine完成
}func main() {ManyGoWait()
}总结 1协程Go可以通过高效调用模型来实现协程(goroutine) 2通道Go可以通过通信来共享内存利用的就是通道(channel) 3Sync包含LockWaitGroup等关键字目的是实现并发安全操作以及协程间的同步 依赖管理
简介 3个阶段 我们应该将更多精力放在应用逻辑的实现上 什么是依赖管理 1依赖管理是指在什么地方以什么形式引入外部代码 2没有项目任务是孤立存在的。除了第一个项目任务之外每个任务或活动都以某种方式依赖于其他活动 项目管理软件中什么是依赖管理具体有什么作用 (xjx100.cn) Go的依赖管理经历了三个阶段 Go 依赖管理详解 - 掘金 (juejin.cn) 应用最广泛的是Go Module依赖管理的目的是 1管理不同项目依赖的版本 2控制依赖库的版本 环境变量Gopath 1项目代码直接依赖 src 下的代码 2go get 下载最新版本的包到 src 目录下 Go Vendor 1项目目录下增加vendor文件所有依赖包以副本形式放在 .../vendor 下 2依赖寻址方式verder - GOPATH 3每个项目引入一个依赖副本解决多个项目需同一个package的依赖冲突问题 Verdor 弊端 Vendor也只是依赖项目源码无法具体地标识依赖了哪个版本因此更新项目时还是会出现依赖冲突导致编译错误 Go module 1通过 go.mod 文件管理依赖包版本 2通过 go get / go mod 指令工具管理依赖包 最终目标定义版本规则和管理项目依赖关系 依赖管理三要素 1go.mod 配置文件描述以来 2Proxy 中心仓库管理依赖库 3go get / go mod 本地工具 依赖配置 分5个部分结合代码介绍 go.mod - version - indirect - incompatible - 依赖图 go.mod go.mod文件 module example.com/project/app // 替换为你自己的域名或者其他唯一标识go 1.16require (github.com/example/lib1 v1.0.2 // 替换为实际的库路径和版本号example.com/example/lib2 v1.0.0 //indirect替换为实际的库路径和版本号github.com/example/lib3 v0.1.0-20190725025543-5a5fe074e612 // 替换为实际的库路径和版本号example.com/example/lib4 v0.0.0-20180306012644-bacd9c7ef1dd //indirect替换为实际的库路径和版本号github.com/example/lib5/v3 v3.0.2 // 替换为实际的库路径和版本号github.com/example/lib6 v3.2.0incompatible // 替换为实际的库路径和版本号
)version 开始一点都听不懂了应该是有很多前置知识的算了先听一遍适当做做笔记先 ... 语义化版本 和 基于commit的伪版本 indirect indirect关键字A对B直接依赖A对C间接依赖 incompatible 1对于没有go.mod文件并且主版本2的依赖会incompatible 2主版本2模块会在模块路径增加 /vN 后缀 依赖图 问X项目依赖AB两个项目AB分别依赖C项目的v1.3和v1.4版本最终编译时所使用的C项目版本为下列的哪项单选 A. v1.3 B. v1.4 √ C. A用到C时v1.3B用到C时v1.4 要选择最低的兼容版本v1.4且v1.3和v1.4之间肯定互相兼容的 依赖分发
回源 1通过Github这样的第三方代码托管平台go.mod中定义的依赖可以直接在对应的仓库下载来完成依赖分发。 2但是直接用版本管理仓库下载依赖存在一些问题 1当软件作者直接在代码平台修改软件版本时如果我们下次需要构建项目会发现之前所以来的版本丢失 2当软件仓库被删除依赖可用性就破坏了 3大流量场景增加负载 Proxy 1为了解决上述问题Proxy出现了 2它会缓存站中的软件内容缓存的软件版本不会改变在源站软件删除之后依然可用 3使用Go Proxy后构建时会直接从Go Proxy站点拉取依赖 变量GOPROXY 工具篇go get/mod
go get example.org/pkg example.org是一个示例域名 go get example.org/pkg比如go get github.com/username/repo 从github下载和安装一个包 go mod 依赖管理三要素 1go.mod - 配置文件描述依赖 2Proxy - 中心仓库管理依赖库 3go get / go mod - 本地工具 总结 可算对Go Module有了个概念但也只是概念需要结合后续实际开发进行巩固