Go 语言并发编程 及 进阶与依赖管理
1.0 从并发编程本质了解Go高性能的本质
1.1 Goroutine
协程可以理解为轻量级线程;
Go更适合高并发场景原因之一:Go语言一次可以创建上万协成;
“快速”:开多个协成 打印。
go func(): 在函数前加 go 代表 创建协程;
time.Sleep(): 协程阻塞,使主协程 在子协程结束前阻塞不退出;
乱序输出 说明并行;
1.2 协程通信 CSP (Communicating Sequential Processes)
通过通信共享内存:Channel通道遵循 先入先出 保证顺序
1.3Channel
Channel创建需要通过make()函数;
无缓冲通道也称 同步通道;有缓冲:缓冲满了之后要拿走才能存。
通过通信共享内存 例子:
M主函数作为消费者 实际中业务比较复杂,所以会 比 生产者AB慢;我们用 带缓冲的通道 就不会因消费者M的消费速度 影响 生产者的执行效率;
1.4 并发安全Lock
addWithLock() 通过临界区控制实现;在 每次 x+=1前后加解锁;
addWithOutLock() 没加锁; Add 测试函数;对两种实现做5个协程并发执行;
结果为:加锁时输出预期结果10000;体现不加锁的并发安全问题
1.5 WaitGroup实现并发任务的同步
计算器=0表示所有并发任务结束;
1.5.1阻塞的优化
好的,以上就是对go并发编程相关概念的介绍,这里简单做个小结
整个章节主要涉及3个方面,一个是协程,通过高效的调度模型实现高并发操作,一个是通道channel.通过通信实现共享内存;最后svnc相关关键字,实现并发安全操作和协程间的同步
2.0 依赖管理
这一章我们主要讲解go的依赖管理, 主要涉及go依赖管理的演进路线和go module实践
依赖指各种开发包
对于hello world以及类似的单体函数只需要依赖原生SDK,而实际工程会相对复杂,我们不可能基于标准库0~1编码搭建,而更多的关注业务逻辑的实现,而其他的涉及框架、日志、driver、以及collection等一系列依赖都会通过sdk的方式引入, 这样对依赖包的管理就显得尤为重要
2.1 Go依赖管理演进
2.1.1 GoPATH
GOPATH是Go语言支持的一个环境变量,value是Go项目的工作区。
目录有以下结构:
src: 存放Go项目的源码;pkg: 存放编译的中间产物,加快编译速度;
bin: 存放Go项目编译生成的二进制文件,
大家想想用gopath依赖管理有 哪些弊端呢?
弊端
如图,同一个pkg,有2个版本,A-> A0,B-> B0.
而src下只能有1个版本存在,那AB项目无法保证都能编译通过。 也就是在gopath管理模式下,如果多个项目依赖同一个库,则依赖该库是同一份代码,所以不同项目不能依赖同一个库的不同版本,这很显然不能满足我们的项目依赖需求。为了解决这问题,govender出现了
2.1.2 GoVendor
Vendor是当前项目中的一个目录,其中存放了当前项目依赖的副本,在Vendor机制下,如果当前项目存在Vendor目录,会优先使用该目录下的依赖,如果依赖不存在,会从GOPATH中寻找。 vendor无法很好解决依赖包的版本变动问题和一个项目依赖同一个包的不同版本的问题,下面我们看一个场景
如图项目A依赖pkg b和c,而B和C依赖了D的不同版本,通过vendor的管理模式我们不能很好的控制对于D的依赖版本,一旦更新项目,有可能带来依赖冲突。
归根结底vendor不能清晰的标识依赖的版本概念原因是:他还是依赖源码。
下面,go mod就应运而生了。
2.1.3 Go Module
Go Modules 是Go语言官方推出的依赖管理系统,解决了之前依赖管理系统存在的诸如无法依赖同一个库的多个版本等问题
G0 module从1.11 开始实验性引入,1.16 默认开启;我们一般都读为go mod,我们也先统一下名称
2.2 依赖管理三要素
那其实完善的依赖管理一般都需要3要素,这里我们先整体介绍下
这里熟悉java的同学,可以类比下maven
2.3.1 依赖配置-go.mod
首先模块路径(依赖管理基本单元)用来标识一个模块,从模块路径可以看出从哪里找到该模块,如果是github前缀则表示可以从Github 仓库找到该模块,依赖包的源代码由githu托管,如果项目的子包想被单独引用,则需要通过单独的go.mod文件进行管理。
下面是依赖的原生库sdk版本(go 1.16)
最下面是单元依赖(最关键的部分),每个依赖单元用模块路径(跟上面的对应)+版本来唯一标示。
2.3.2 依赖配置-version
gopath和govendor都是源码副本方式依赖,没有版本规则概念
而gmod为了方便版本管理 定义了版本规则,分为语义化版本和伪版本
其中语义化版本包括三部分,
不同的MAJOR大版本可以表示是不兼容的
所以即使是同一个库,MAJOR 版本不同也会被认为是不同的模块
MINOR版本通常是新增函数或功能,需要保持在MAJOR下做到前后兼容 patch 版本一般是修复 bug ;
基于commit的伪版本包括3部分,
版本前缀是和语义化版本一样的;
时间戳 yyyymmddhhmmss,也就是提交commit的时间,
最后是校验码(abcdefabcdef,包含 12 位的哈希前缀;每次提交commit后 Go 会默认生成一个伪版本号
2.3.3 依赖配置-非直接依赖indirect
下面我们再来看下依赖单元中的特殊标识符,首先是indirect后缀
表示go.mod对应的当前模块,没有直接导入该依赖模块的包,也就是非直接依赖,标示间接依赖,例如
2.3.4 依赖配置-incompatible
下一个常见是的是incompatible
主版本2+模块(v2以上) 会在模块路径增加/vN(v1,v2这种后缀),这让gomod按照不同的模块来处理同一个项目不同主版本的依赖(允许不同MAJOR版本间相互兼容)
由于gomod是1.11实验性引入,所以这项提出之前已经有一些仓库打上了v2或者更高版本的tag了,为了兼容这部分仓库,对于没有go.mod文件并且主版本在2或者以上的依赖,会在版本号后加上+incompatible 后缀
前面讲语义化版本提到,对于同一个库的不同的major版本,需要建立不同的pkg目录,用不同的gomod文件管理
如下面仓库为例,V1版本gomod在主目录下,而对于V2版本,则单独建立了V2目录,用另一个gomod文件管理依赖路径,来表明不同major的不兼容性。
那对于有些V2+tag版本的依赖包并未遵循这定义规则,就会打上incompatible标志,增加一个compatile的case
依赖图
答案竟然是B!
Go底层会根据自己的算法 选择最 低的兼容版本
2.3.5 依赖分发-回源
gomodule的依赖分发,也就是从哪里下载,如何下载的问题
github是比较常见给的代码托管系统平台,而Go Modules 系统中定义的依赖,最终可以对应到多版本代码管理系统中某一项目的特定提交或版本,这样的话,对于go.mod中定义的依赖,则直接可以从对应仓库中下载指定软件依赖,从而完成依赖分发。
但直接使用版本管理仓库下载依赖,存在多个问题
首先无法保证构建确定性:软件作者可以直接码平台增加/修改/删除 软件版本,导致下次构建使用另外版本的依赖,或者找不到依赖版本。
无法保证依赖可用性:依赖软件作者可以直接代码平台删除软件,导致依赖不可用;大幅增加第三方代码托管平台压力。
2.3.5 依赖分发-Proxy
而go proxy就是解决这些问题的方案,Go Proxy 是一个服务站点
它会缓存源站中的软件内容,缓存的软件版本不会改变,并且在源站软件删除之后依然可用,从而实现了供“immutability”和“available”的依赖分发;
使用 Go Proxy 之后,构建时会直接从 Go Proxy 站点拉取依赖。
类比项目中,如果下游无法满足我们上游的需求、接口,我们可以建一层适配器或Proxy解决
2.3.6 依赖分发-变量-GOPROXY
下面讲一下go proxy的使用,Go Modules通过GOPROXY环境变量控制如何使用 Go Proxy;GOPROXY是一个Proxy 站点URL列表,可以使用 “direct”表示源站 用逗号分隔。
对于示例配置,整体的依赖寻址路径,会优先从proxy1下载依赖,如果proxy1不存在,后下钻proxy2寻找,如果proxy2,中不存在则会回源到源站直接下载依赖,缓存到proxy站点中。
2.3.7 工具-go get
对go module的管理工具介绍下使用,首先是go get
2.3.8 工具-go mod
go mod,尽量提交之前执行下go tidy,减少构建时无效依赖包的拉取
非常感谢您阅读到这里,如果这篇文章对您有帮助,希望能留下您的点赞👍 关注💖 收藏 💕评论💬感谢支持!!!
相关文章:

Go 语言并发编程 及 进阶与依赖管理
1.0 从并发编程本质了解Go高性能的本质 1.1 Goroutine 协程可以理解为轻量级线程; Go更适合高并发场景原因之一:Go语言一次可以创建上万协成; “快速”:开多个协成 打印。 go func(): 在函数前加 go 代表 创建协程; time.Sleep():…...

绽放趋势:Python折线图数据可视化艺术
文章目录 一 json数据格式1.1 json数据格式认识1.2 Python数据和Json数据的相互转换 二 pyecharts模块2.1 pyecharts概述2.2 pyecharts模块安装 三 pyecharts快速入门3.1 基础折线图3.2 pyecharts配置选项3.2.1 全局配置选项 3.4 折线图相关配置3.4.1 .add_yaxis相关配置选项3.…...

BGP小综合
实验要求及拓扑 一、思路 1.使用OSPF使R2-R7之间可通。 2.各自宣告AS区域,两个区域两两之间建邻,AS2两个小区域之间建联邦(R2与R5、R4与R7)。 3.使R3、R6为路由反射器 RR反射器选取各小区域的路由器作为客户端 、非客户端 4.优…...

一起学数据结构(3)——万字解析:链表的概念及单链表的实现
上篇文章介绍了数据结构的一些基本概念,以及顺序表的概念和实现,本文来介绍链表的概念和单链表的实现,在此之前,首先来回顾以下顺序表的特点: 1.顺序表特点回顾: 1. 顺序表是一组地址连续的存储单元依次存…...

9.2.1Socket(UDP)
一.传输层: 1.UDP:无连接,不可靠,面向数据报,全双工. 2.TCP:有连接,可靠,面向字节流,全双工. 注意:这里的可不可靠是相对的,并且和安不安全无关. 二.UDP数据报套接字编程: 1.socket文件:表示网卡的这类文件. 2.DatagramPacket:表示一个UDP数据报. 三.代码实现: 1.回显服务…...

9.1网络通信基础
一.基础概念: 1)IP地址:描述网络上的一个设备所在的位置. 2)端口号(port):区分一个主机上不同的进程,和pid一样的作用,但两者不同. 3)协议:网络通信传输数据的含义,协议表示一种约定,这种约定可以是任意的.协议分层之后,上层不需要知道下层协议的细节,可以灵活地调整,替换某…...

idea添加翻译插件并配置有道翻译
1、安装Translation插件 2、 创建有道云应用 有道智云控制台 3、设置idea 4、效果(选中文本右键翻译,默认快捷键CtrlShiftY)...

激光切割机的操作中蛙跳技术是什么意思
其实,蛙跳技术就是指在激光切割机运行的过程中,机器换位置的方式。打个比方,你刚刚在这儿把孔1切好了,接下来就得跑到那儿把孔2切了。 在这个过程中,激光切割机就像是一只青蛙,要从一个位置跳到另一个位置。…...

Typescript+React入门
初识Typescript 出现背景 Typescript(以下简称TS)实际上就是JavaScriptType,用数据类型的方式来约束了JS的变量定义 在JS的基础上增加了类型支持 在JS中大多数错误都是因为数据类型造成的,所以TS为了规避这个问题加入了类型限制…...

竞赛项目 酒店评价的情感倾向分析
前言 🔥 优质竞赛项目系列,今天要分享的是 酒店评价的情感倾向分析 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/post…...

加载并绘制时间域内的心电图信号,并实施Q因子为1的陷波滤波器以去除50 Hz频率研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

瑞数信息《2023 API安全趋势报告》重磅发布: API攻击持续走高,Bots武器更聪明
如今API作为连接服务和传输数据的重要通道,已成为数字时代的新型基础设施,但随之而来的安全问题也日益凸显。为了让各个行业更好地应对API安全威胁挑战,瑞数信息作为国内首批具备“云原生API安全能力”认证的专业厂商,近年来持续输…...
HCIA静态路由与动态路由
目录 一、静态路由 定义: 适用环境 二、动态路由 定义: 特点: 动态路由协议: 三、缺点: 1)静态路由缺点: 2)动态路由的缺点: 四、静态路由与动态路由的区别 静态路由: 动态路由: 一、静态路…...

【前端 | CSS】flex布局
基本概念 Flexible模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力 我们说 flexbox 是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度上的元素布局,一行或者…...
YoloV8优化:感受野注意力卷积运算(RFAConv),效果秒杀CBAM和CA等 | 即插即用系列
💡💡💡本文改进:感受野注意力卷积运算(RFAConv),解决卷积块注意力模块(CBAM)和协调注意力模块(CA)只关注空间特征,不能完全解决卷积核参数共享的问题 RFAConv| 亲测在多个数据集能够实现大幅涨点,有的数据集达到3个点以上 💡💡💡Yolov8魔术师,独家首…...

面对AI冲击,技术人才该如何考核?
一天下午,在与知名企业的技术交流会议室里,一位兄弟企业的CTO 小力苦笑着,分享了一个技术招聘的故事: “我们有个高级工程师,为了搞定MySQL三个表Join的问题,搞了一整天都研究不出来。结果他尝试将表结构扔…...

放弃51单片机,直接学习STM32开发可能会面临的问题
学习51单片机并非仅仅是为了学习51本身,而是通过它学习一种方法,即如何仅仅依靠Datasheet和例程来学习一种新的芯片。51单片机相对较简单,是这个过程中最容易上手的选择,而AVR单片机则更为复杂。虽然您已经学习了大约十天的51单片…...

windows安装git并初始化
git官网下载地址: https://git-scm.com/downloads 安装步骤,一直点击下一步即可 git初始化 1、用户签名 git config --global user.email 2734542837qq.com#设置全局用户邮箱git config --global user.name "zoujiahao"# 设置全局用户使用人…...
SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)
SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传) 文章目录 SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)[TOC] 前…...

基于Doris实时数据开发的一些注意事项
300万字!全网最全大数据学习面试社区等你来! 最近Doris的发展大家是有目共睹的。例如冷热分离等新特性的持续增加。使得Doris在易用和成本上都有大幅提升。 基于Doris的一些存储实时数仓在越来越多的场景中开始有一些实践。大家也看到了这种方案频繁出现…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...