Go语言进阶 + 依赖管理

news2024/9/21 22:56:08

依赖配置 - version开始,就开始很难听懂了,需要结合很多课后配套资料查阅很多文档和网站....然而好像没有那么多时间,一天给3小时学Go真的顶天了.....还有算法和Linux的Mysql...

这几天学Go已经把算法给挤掉了.....下步要权衡一下,好好分配下时间

目录

🐘并发编程

🍈并发与并行

🍈Goroutine -- 协程与线程

📚Git从Github拉取代码

🍉CSP

🦖Channel

🦖并发安全Lock

🦖WaitGroup

🐅依赖管理

🌼简介 + 3个阶段

🌼依赖配置

🌼依赖分发

🌼工具篇:go get/mod

🌳依赖管理三要素


🐘并发编程

主要涉及,Go并发编程的相关概念

🍈并发与并行

我们两个人在吃午饭。你在吃饭的整个过程中,吃了米饭、吃了蔬菜、吃了牛肉。吃米饭、吃蔬菜、吃牛肉这三件事其实就是并发执行的。对于你来说,整个过程中看似是同时完成的的。但其实你是在吃不同的东西之间来回切换的

还是我们两个人吃午饭。在吃饭过程中,你吃了米饭、蔬菜、牛肉。我也吃了米饭、蔬菜和牛肉。我们两个人之间的吃饭就是并行的。两个人之间可以在同一时间点一起吃牛肉,或者一个吃牛肉,一个吃蔬菜。之间是互不影响的

上图并发,下图并行

image

并发的多个任务之间是互相抢占资源的;并行的多个任务之间是不互相抢占资源的

面试必考的:并发和并行有什么区别?-腾讯云开发者社区-腾讯云 (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 main

import (
	"fmt"
	_ "fmt"
	"time"
	_ "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个goroutine
		go 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)

(1)channel是一种类型,一种引用类型,你可以把它看成一个管道

(2)一种go协程用以接收或发送消息的安全的消息队列channel就像两个go协程之间的导管,来实现各种资源的同步

第二个参数是capacity(容量) 

无缓冲通道

有缓冲通道

package main

func 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 main

import ( //引入包
	"sync"
	"time"
)

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 = 0
	for i := 0; i < 5; i++ {
		go addWithoutLock() //创建5个goroutine并发执行函数
	}
	time.Sleep(time.Second)
	println("WithoutLock:", x)
	x = 0
	for i := 0; i < 5; i++ {
		go addWithLock() //
	}
	time.Sleep(time.Second)
	println("Withlock:", x)
}
func main() {
	Add()
}
WithoutLock: 9784
Withlock: 10000

🦖WaitGroup

深入理解 go sync.Waitgroup - 掘金 (juejin.cn)

WaitGroup是Go语言里,sync包里的结构体,用来阻塞主协程,等待所有协程执行完,是较为常见的并发控制方式

计数器:开启协程,   +1;执行结束,    -1

主协程阻塞知道计数器为0

package main

import ( //引入包
	"fmt"
	"sync"
)

func hello(i int) { //定义内部函数
	println("hello goroutine : " + fmt.Sprint(i))
}

func ManyGoWait() { //并发执行多个goroutine
	var 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)

(3)Sync:包含Lock,WaitGroup等关键字,目的是实现并发安全操作,以及协程间的同步

🐅依赖管理

🌼简介 + 3个阶段

我们应该将更多精力放在应用逻辑的实现上

什么是依赖管理?

(1)依赖管理,是指在什么地方以什么形式引入外部代码

(2)没有项目任务是孤立存在的。除了第一个项目任务之外,每个任务或活动都以某种方式依赖于其他活动

项目管理软件中什么是依赖管理,具体有什么作用? (xjx100.cn)

Go的依赖管理经历了三个阶段👇

Go 依赖管理详解 - 掘金 (juejin.cn)

应用最广泛的是Go Module,依赖管理的目的是:

(1)管理不同项目依赖的版本

(2)控制依赖库的版本

环境变量Gopath

(1)项目代码直接依赖 src 下的代码

(2)go get 下载最新版本的包到 src 目录下

Go Vendor

(1)项目目录下增加vendor文件,所有依赖包,以副本形式放在 .../vendor 下

(2)依赖寻址方式:verder -> GOPATH

(3)每个项目引入一个依赖副本,解决多个项目需同一个package,的依赖冲突问题

Verdor 弊端

Vendor也只是依赖项目源码,无法具体地标识依赖了哪个版本,因此更新项目时,还是会出现依赖冲突,导致编译错误

Go module👇

(1)通过 go.mod 文件,管理依赖包版本

(2)通过 go get / go mod 指令工具,管理依赖包

最终目标:定义版本规则和管理项目依赖关系

依赖管理三要素

1,go.mod

配置文件,描述以来

2,Proxy

中心仓库管理依赖库

3,go get / go mod

本地工具

🌼依赖配置

分5个部分结合代码介绍:

go.mod -> version -> indirect -> incompatible -> 依赖图

go.mod

go.mod文件 

module example.com/project/app // 替换为你自己的域名或者其他唯一标识

go 1.16

require (
    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.0+incompatible // 替换为实际的库路径和版本号
)

version

开始一点都听不懂了,应该是有很多前置知识的,,,算了,先听一遍,适当做做笔记先

...

语义化版本  和  基于commit的伪版本

indirect

indirect关键字,A对B直接依赖,A对C间接依赖

incompatible

 

(1)对于没有go.mod文件,并且主版本2+的依赖,会+incompatible

(2)主版本2+模块会在模块路径增加  /vN  后缀

依赖图

问:X项目依赖A,B两个项目,A,B分别依赖C项目的v1.3和v1.4版本,最终编译时,所使用的C项目版本为下列的哪项(单选):

A. v1.3

B. v1.4

C. A用到C时v1.3,B用到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 + 👇

🌳依赖管理三要素

(1)go.mod  ->  配置文件,描述依赖

(2)Proxy     ->  中心仓库管理依赖库

(3)go get / go mod  ->  本地工具

总结

可算对Go Module有了个概念,但也只是概念,需要结合后续实际开发进行巩固

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

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

相关文章

C#实现数据库数据变化监测(sqlservermysql)

监测数据库表数据变化&#xff0c;可实现数据库同步&#xff08;一主一从&#xff08;双机备份&#xff09;&#xff0c;一主多从&#xff08;总部数据库&#xff0c;工厂1&#xff0c;工厂2&#xff0c;工厂数据合并到总部数据&#xff09;&#xff09; sqlserver 启用数据库…

【Linux】网络基础

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统网络编程 文章目录 一、协议初识和网络协议分层&#xff08;TCP/IP四层模型&#xff09;认识协议TCP/IP五层&#xff08;或四层&#xff09;模型 二、认识MAC地址和IP地址认识MAC地址认识IP地址认…

什么是ssm?如何使用ssm进行后端开发

目录 一、ssm概述1.1 定义1.2 持久层框架 (mybatis&&mybatisPlus)1.3 Web 层框架 springMVC1.4 spring框架 二、开发结构2.1 config介绍2.2 controller介绍2.3 dao介绍2.4 domain介绍2.5 exception介绍2.6 interceptor介绍2.7 service介绍 三、注解开发介绍3.1 常见的注…

从零开始学Flask: 3分钟用Python快速构建Web应用

文章目录 一、背景二、安装&基础使用1. 安装 Flask2. 创建 Flask 应用3. 路由解析4. 模板渲染5. 请求和响应处理 三、Demo项目实战 一、背景 什么是Flask&#xff1f;Flask 是一个轻量级的 Python Web 应用框架&#xff0c;因其简单易用、灵活性高等特点&#xff0c;可以帮…

Ribbon源码

学了feign源码之后感觉&#xff0c;这部分还是按运行流程分块学合适。核心组件什么的&#xff0c;当专业术语学妥了。序章&#xff1a;认识真正のRibbon 但只用认识一点点 之前我们学习Ribbon的简单使用时&#xff0c;都是集成了Eureka-client或者Feign等组件&#xff0c;甚至在…

better scoll右 联左

这是先拿一个数组装进我们所有 获取到的dom节点的 高度 因为算的 都是 到最上面的 高度&#xff0c;所以我们 要减去他的 高度 就得到自身的高度 然后给右边加一个滚动事件&#xff0c;得到每一次滑动的高度&#xff0c;在循环上面的数组&#xff0c;就是我们右边的 y就在算出…

如何排查 IDEA 自身报错?| 以 IntelliJ IDEA 2023.1.4 无法刷新项目 Maven 模块的问题为例

这个问题是 2023 年 7 月 26 日遇到的&#xff0c;当时还是 IDEA 2023.1.4&#xff0c;结果文章还没写完&#xff0c;7 月 27 日自动给更新了 IDEA 2023.2。问题估计解决了。 所以&#xff0c;本文就简单提一下 IDEA 自身报错的排查方法。 规避/解决方式 先说问题怎么处理&am…

重生之我要学C++第五天

这篇文章主要内容是构造函数的初始化列表以及运算符重载在顺序表中的简单应用&#xff0c;运算符重载实现自定义类型的流插入流提取。希望对大家有所帮助&#xff0c;点赞收藏评论&#xff0c;支持一下吧&#xff01; 目录 构造函数进阶理解 1.内置类型成员在参数列表中的定义 …

糟了,数据库主从延迟了!

前言 在实际的生产环境中&#xff0c;由单台MySQL作为独立的数据库是完全不能满足实际需求的&#xff0c;无论是在安全性&#xff0c;高可用性以及高并发等各个方面 因此&#xff0c;一般来说都是通过集群主从复制&#xff08;Master-Slave&#xff09;的方式来同步数据&…

【点云处理教程】05-Python 中的点云分割

一、说明 这是我的“点云处理”教程的第 5 篇文章。“点云处理”教程对初学者友好&#xff0c;我们将在其中简单地介绍从数据准备到数据分割和分类的点云处理管道。 在上一教程中&#xff0c;我们看到了如何过滤点云以减少噪声或其密度。在本教程中&#xff0c;我们将应用一些聚…

LeetCode_11. 盛最多水的容器

题目描述 11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/container-with-most-water/ 思路分析 这题就是典型的是一道很经典的面试题&#xff0c;最优的解法是双指针&#xff0c;但很多人在第一次看到这题的时候很难想到用双指针来…

*CTF 2023 Misc

一、 snippingTools Alice在参加某个CTF比赛&#xff0c;她成功的解出了一道题&#xff0c;拿到了flag。她很开心&#xff0c;迫不及待地想要向Bob分享她的喜悦。于是按下了快捷键ShiftWinS使用了Windows 11的截图工具&#xff0c;截取了整个屏幕&#xff0c;并且保存为文件1.p…

无涯教程-jQuery - Spinner组件函数

Widget Spinner 函数可与JqueryUI中的窗口小部件一起使用。Spinner提供了一种从一组中选择一个值的快速方法。 Spinner - 语法 $( "#menu" ).selectmenu(); Spinner - 示例 以下是显示Spinner用法的简单示例- <!doctype html> <html lang"en"…

(树) 剑指 Offer 27. 二叉树的镜像 ——【Leetcode每日一题】

❓剑指 Offer 27. 二叉树的镜像 难度&#xff1a;简单 请完成一个函数&#xff0c;输入一个二叉树&#xff0c;该函数输出它的镜像。 例如输入&#xff1a; 4/ \2 7/ \ / \1 3 6 9镜像输出&#xff1a; 4/ \7 2/ \ / \9 6 3 1示例 1&#xff1a; 输…

给你一个项目,你将如何开展性能测试工作?

一、性能三连问 1、何时进行性能测试&#xff1f; 性能测试的工作是基于系统功能已经完备或者已经趋于完备之上的&#xff0c;在功能还不够完备的情况下没有多大的意义。因为后期功能完善上会对系统的性能有影响&#xff0c;过早进入性能测试会出现测试结果不准确、浪费测试资…

We are the Lights - 思维

分析&#xff1a; 每次操作会把上一次的状态覆盖&#xff0c;但是从后往前操作可以保留最后一次覆盖&#xff0c;每一个位置最后的覆盖状态一定是最终状态&#xff0c;因此可以存下来从后往前记录第一次覆盖的状态并计数。 代码&#xff1a; #include <bits/stdc.h>usi…

玩转LaTeX(一)【源文件基本结构、中文处理方法、中英文的字体字号设置、文档基本结构】

latex源文件基本结构&#xff1a; 【在latex中一般分为两个区&#xff0c;一个是导言区&#xff0c;一个是正文区&#xff08;文稿区&#xff09;】 %导言区(主要进行全局设置)%一个latex文件&#xff0c;只能有且只有一个document环境\documentclass{article} %除article类外…

OpenHarmony开源鸿蒙学习入门 - 基于3.2Release 应用开发环境安装

OpenHarmony开源鸿蒙学习入门 - 基于3.2Release 应用开发环境安装 基于目前官方master主支&#xff0c;最新文档版本3.2Release&#xff0c;更新应用开发环境安装文档。 一、安装IDE&#xff1a; 1.IDE安装的系统要求 2.IDE下载官网链接&#xff08;IDE下载链接&#xff09; …

【论文精读】Self-Attentive Assocative Memory,2020

目录 1 引言2 Outer product attention (OPA)3 Self-attentive Associative Memory (SAM)4 SAM-based Two-Memory Model (STM)4.1 M i M^i Mi写操作4.2 M r M^r Mr读操作4.3 M i M^i Mi读操作和 M r M^r Mr写操作过程4.4 用 M r M^r Mr实现item转移4.5 模型输出 o t o_t ot​…

C语言手撕顺序表

目录 一、概念 1、静态顺序表&#xff1a;使用定长数组存储元素。 2、动态顺序表&#xff1a;使用动态开辟的数组存储 二、接口实现 1、对顺序表的初始化 2、对数据的销毁 3、对数据的打印 4、检查是否需要扩容 5、尾插 6、头插 7、尾删 8、头删 9、在pos位置插入x …