Go 语言进阶与依赖管理

news2024/11/15 11:07:12

作者:非妃是公主
专栏:《Golang》
博客主页:https://blog.csdn.net/myf_666
个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩
在这里插入图片描述

文章目录

  • 一、语言进阶
    • 1. 并发和并行
    • 2. 协程(Goroutine)与线程
    • 3. CSP(Communicating Sequential Processes)
    • 4. Channel
    • 5. 并发安全 Lock
    • 6. WaitGroup
  • 二、依赖管理
    • 1. GOPATH
    • 2. Go Vendor
    • 3. Go Module
      • Ⅰ. 依赖表述
      • Ⅱ. 依赖管理
      • Ⅲ. 本地工具
        • ① go get
        • ② go mod

在这里插入图片描述

一、语言进阶

1. 并发和并行

Go语言是一种并发性能很好的语言,它可以多核(多核指:一个电脑包含多个CPU)优势,更加高效地运行。
在这里插入图片描述


2. 协程(Goroutine)与线程

Go语言的并发编程,主要就是通过协程(Goroutine)来实现的。协程和线程类似,但又并不同于线程,它比线程更加轻量级。
在这里插入图片描述

协程:用户态,轻量级线程,栈KB级别;
线程:内核态,线程跑多个协程,栈MB级别。


3. CSP(Communicating Sequential Processes)

协程间通信与进程通信类似,主要有2种方式:

  1. 通道
  2. 临界区

对于这两种方式,Go语言采用第一种——通道方式,进行协程间的信息传递。即,下图中左边的这种方式:
在这里插入图片描述
这样做的优点是,通过通信共享内存性能较高,不会像临界区一样,存在性能较低的问题。

4. Channel

缓冲通道:

  • 无缓冲通道 make(chan int)
  • 有缓冲通道 make(chan int,2)

它可以采用上面make的方式进行初始化,第一个参数指定类型,第二个参数指定缓冲通道的大小。

在这里插入图片描述

一个示例代码如下:

package concurrence

func CalSquare() {
	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)
	}
}

代码中关于defer主要用来进行延迟调用(程序执行完毕后,即将退出时,执行defer,详细的关于defer的介绍,请查看博客:Golang中的一些关键字),然后相当于通过src这一公共区域进行内存通信。

这个demo程序类似于生产者、消费者进程,输出结果如下:

在这里插入图片描述

5. 并发安全 Lock

锁的作用主要是用来保证在操作变量时,只有一个协程在操作,这时候另一个协程想要操作的时候,需要等待锁解除才行。这样的操作,可以保证程序执行的正确性,防止程序出错。

下面来看一个demo,这个demo的作用是执行2000次+1操作,然后采用5个协程进行。函数的定义如下。

首先,是带有锁的函数定义,在操作x的时候,锁住了lock,如下:

func addWithLock() {
	for i := 0; i < 2000; i++ {
		lock.Lock()
		x += 1
		lock.Unlock()
	}
}

不带锁的定义,如下:

func addWithoutLock() {
	for i := 0; i < 2000; i++ {
		x += 1
	}
}

5个协程,每个执行2000次+1操作,如下:

func Add() {
	x = 0
	for i := 0; i < 5; i++ {
		go addWithoutLock()
	}
	time.Sleep(time.Second)
	println("WithoutLock:", x)
	x = 0
	for i := 0; i < 5; i++ {
		go addWithLock()
	}
	time.Sleep(time.Second)
	println("WithLock:", x)
}

运行程序如下:

在这里插入图片描述

这时,很有意思的是,并没有发生错误!本来想着由于没有加锁,这样多个进程在操作数据的时候就可能在同一个时钟周期,而造成数据丢失。

于是,我分析了一下原因,现在的CPU为16核,甚至更多,5个协程可能可以在不同的不同核上并行去跑,之间并没有影响。也就是说,会不会出错误,可能和机子的性能有关。我的机子是16核的,因此,我进行了如下尝试,修改协程数为17,果然,触发了错误,没有锁的协程产生了操作丢失。

在这里插入图片描述

6. WaitGroup

相当于一个计数器,那么它的作用是什么呢?记录当前正在执行的协程数,当正在执行的线程数不为 0 的时候,就需要进行一个等待。

demo程序如下:

func ManyGoWait() {
	var wg sync.WaitGroup
	wg.Add(5)
	for i := 0; i < 5; i++ {
		go func(j int) {
			defer wg.Done()
			hello(j)
		}(i)
	}
	wg.Wait()
}

其中 wg 表示创建的一个WaitGroup,通过Add可以添加一个协程数,Add可以为负数;

然后启动协程,通过延迟调用,当协程完成后,我们执行Done函数,这会对写成书 -1 。

最后通过 Wait 函数,如果正在运行的协程不为0(存在正在运行的协程),那么就不结束主进程。

关于WaitGroup的定义,可以查看源码及注释进行了解,如下:
在这里插入图片描述

Done 和 Wait,如下:

在这里插入图片描述

同时,有了 wg.Wait() ,既可以省略了之前的 time.Sleep(time.Second) 了。

二、依赖管理

随着功能的增强,同时也需要更多的依赖库,这时候,依赖管理就显得很重要了。

Golang的依赖管理按照发展历史,可分为3种,GOPATH,Go Vendor,Go Module。如下图:

在这里插入图片描述

1. GOPATH

首先,值得说明的是,不同于Java、C++、python等,在Golang中,是不存在项目(project)这一概念的,在Gopath路径下就是Golang的工作目录,存在三个文件夹,作用分别如图中标注:

在这里插入图片描述

弊端:无法实现package的多版本控制。比如,不同的程序用到了同一个package,但是又是不同版本的,这时候,Gopath这种管理方式就无法处理了。如下:

在这里插入图片描述

2. Go Vendor

由于上面的弊端,诞生了Go Vendor,相当于在每个项目下,建立了一个Vendor文件夹,里面存放项目中用到的package,当程序寻找依赖报的时候,先去Vendor中去寻找,如果找不到,再去Gopath下去寻找,这就避免了上面提到的 package版本 问题。
在这里插入图片描述

但这种方法同样存在着较大的问题,如果一个项目(A)用到的两个包(B和C),这两个包又依赖了同一个包D,但是用到的这同一个包但是版本不同且不兼容的包D,同样回出现如下 无法控制版本 的问题(即项目内出现此问题):

在这里插入图片描述

3. Go Module

Go Module解决了上面相同包,不同版本的问题。

和Mave很类似,其中包含三要素:

  1. 配置文件,描述依赖 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 go get/mod

Ⅰ. 依赖表述

在这里插入图片描述

在这里插入图片描述

通过上面这两种标识,我们就可以将不同版本的包区分开来。

Ⅱ. 依赖管理

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Ⅲ. 本地工具

① go get

在这里插入图片描述

② go mod

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/464839.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件or硬件?硬件的前途到底在哪里?

一、硬件明明比软件更难&#xff0c;国内的硬件技术也不如软件&#xff0c;为什么硬件工程师待遇还不如软件&#xff1f; 1、不需要太高层次的硬件设计&#xff0c;比如大部分小家电企业&#xff0c;简单的电子产品企业&#xff0c;单片机简单外围设计就够了&#xff0c;单片机…

java网络编程——NIO架构

目录 1.什么是NIO 2.NIO结构 3.基于NIO下的聊天系统实现 4.Netty 1.什么是NIO NIO&#xff1a;java non-blocking IO&#xff0c;同步非阻塞IO。 BIO是阻塞IO&#xff0c;即每一个事件都需要分配一个进程给他&#xff0c;如果客户端没有连接上&#xff0c;则一直阻塞等待…

Java基础--->并发部分(1)

文章目录 线程基本概念线程的创建方式线程调度-------常用的方法线程的生命周期和状态并发编程的根本原因Java内存模型(JMM)多线程核心的根本问题volatile关键字保障原子性synchronized和ReentrantLock的区别 线程基本概念 ​ 进程是程序的一次执行过程&#xff0c;是系统运行程…

【Linux】1.4 基本权限

文章目录 一、shell 命令以及运行原理二、Linux 权限的概念三、Linux 权限管理01.文件类型和访问权限&#xff08;事物属性&#xff09;02.文件访问的分类&#xff08;人&#xff09;①用户分类②角色划分 03.文件权限值的表现方法04.文件访问权限的相关设置方法&#xff08;a.…

STC8H8K64U单片机-看门狗配置与讲解

1、看门狗寄存器讲解 &#xff08;bit7&#xff09;WDT_FLAG&#xff1a;看门狗溢出标志&#xff0c;看门狗发生溢出时&#xff0c;硬件自动将此位置1&#xff0c;需要软件清零 &#xff08;bit5&#xff09;EN_WDT&#xff1a;看门狗使能位 0&#x…

被优化了怎么办?他苦学仨月拿到11koffer

网上有个段子叫做“生活就是起起落落落落落落”。人生在世&#xff0c;本就不易&#xff0c;再加上最近大环境影响&#xff0c;各行各业都在内卷&#xff0c;身为芸芸众生的一员&#xff0c;我们也难免受到影响&#xff0c;面临福利裁剪、降薪、甚至被优化的风险。 大环境我们…

面了20家大厂,发现这样介绍项目经验,显得项目很牛...

我在刚刚开始面试的时候&#xff0c;也遇到了这个问题&#xff0c;也是我第一个思考的问题&#xff0c;如何介绍自己的项目&#xff0c;既可以比较全面的让面试官了解这个项目&#xff0c;同时&#xff0c;也不会让面试官觉得废话太多。经过这么多的面试&#xff0c;我发现&…

JavaWeb+JSP+路径问题+跳转(HTML|Servlet|JSP)|这一篇就够了(超详细)

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;老茶icon &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;计…

ChatGPT真能取代程序员吗,看看它怎么解释SQL注入漏洞的问题

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;Beerus|慕课网讲师 背景 本周在《Web安全渗透测试》课程的QQ群中&#xff0c;有同学提问了一个关于网上一个关于SQL注入…

大淘宝技术斩获NTIRE 2023视频质量评价比赛冠军(内含夺冠方案)

近日&#xff0c;CVPR NTIRE 2023 Quality Assessment of Video Enhancement Challenge比赛结果公布&#xff0c;来自大淘宝音视频技术团队的同学组成「TB-VQA」队伍&#xff0c;从37支队伍中脱颖而出&#xff0c;拿下该比赛&#xff08;唯一赛道&#xff09;冠军。此次夺冠是团…

Mysql replace into与on duplicate key update区别

1、replace into REPLACE INTO 首先判断数据是否存在&#xff1b;如果不存在&#xff0c;则插入&#xff1b;如果已存在则更新&#xff08;先删除再插入 根据主键或唯一索引判断记录是否已存在&#xff0c;所以插入数据的表必须要有主键或者唯一索引&#xff01;否则的话&…

Java 实现访问Redis哨兵(六)

目录 一、哨兵和复制 1.1 哨兵(sentinal) 1.Redis哨兵主要功能 2.Redis哨兵的高可用 1.2 Redis复制(Replication) 1.数据复制原理(执行步骤) 1.3 Redis 主从复制、哨兵和集群这三个有什么区别 二、Java访问哨兵实现 一、哨兵和复制 谈到Redis服务器的高可用&#xff0c…

【笔记】I2S协议是什么?

什么是I2S协议 I2S协议的介绍I2S协议有什么 这两天在搞ESP32的btAudio库&#xff0c;接触到了I2S&#xff0c;简单做个笔记。 I2S协议的介绍 I2S(Inter—IC Sound)总线, 又称集成电路内置音频总线&#xff0c;是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标…

2.QT窗口部件

类继承关系图 &#xff08;上面为Base类&#xff0c;下面为Derived类&#xff09; 窗口与子部件 窗口&#xff1a;没有父部件的部件&#xff0c;称为顶级部件 子部件&#xff1a;非窗口部件 新建空的qmake项目mywidget1 //mywidget1.proQT core gui greaterThan(QT_MAJO…

这是一个黑科技:C++爬虫~(文末报名C/C++领域新星计划)

目录 写在前面 完整代码 这里必看&#xff01;&#xff01; 写在最后 写在前面 现在所有人都知道万能的Python可以做机器学习&#xff0c;可以做人工智能&#xff0c;可以爬取各种小网站&#xff0c;但是你不知道&#xff0c;基于C的正则表达式早就能够爬取各种网络数据啦&a…

华为OD机试——对称美学(通过率只有8.51%???)

用java写的这道题&#xff0c;两个样例都可以通过&#xff0c;但是提交之后最终的通过率只有8.51%&#xff1f;&#xff1f;&#xff1f;自己搞了半天一直都是这个通过率&#xff0c;然后用网上说的100%通过率的代码也是一样的结果&#xff0c;最后时间到了还是没有拿到满分&am…

这些vue基本语法,你掌握了吗

文章目录 一、 vue 项目重点概念介绍1. 单页面应用程序2. 单文件组件3.数据驱动视图 二、 vue 基本结构1、template2、script3、style 三、 vue 常用指令介绍1、内容渲染指令&#xff08;1&#xff09;插值表达式 {{xxx}} —常用方式&#xff08;2&#xff09;v-text&#xff0…

session和JWT的应用及区别

文章目录 登录认证(node)一、session1.下载session2.全部配置session3.存储session4.获取session5.销毁session 二、JWT (Json web token)1.JWT 的工作原理2.JWT 的组成3.下载JWT4.生成token5.解密TOken6.配置全局错误中间件 登录认证(node) 一、session 一、在node中使用sess…

还不懂Redis?看完这个故事就明白了!

还不懂Redis?看完这个故事就明白了! 我是Redis 你好,我是Redis,一个叫Antirez的男人把我带到了这个世界上。 说起我的诞生,跟关系数据库MySQL还挺有渊源的。 在我还没来到这个世界上的时候,MySQL过的很辛苦,互联网发展的越来越快,它容纳的数据也越来越多,用户请求也…

全国独家专利药品有哪些品种?全国独家药品产品汇总查阅

独家药品一般是指某一家药企拥有生产和销售某种药品的独家权利&#xff0c;细分有活性成分独家&#xff08;通用名成分独家&#xff09;、品种独家&#xff08;同成分不同剂型&#xff09;、独家品规&#xff0c;通俗可以分成药品功能独家和产品独家。独家药品经常被人认为是具…