golang安装,常用框架安装,记忆点

0.安装

虚拟机扩容

【Linux干货分享】LVM快速扩容虚拟机磁盘_哔哩哔哩_bilibili

newvim

安装

sudo add-apt-repository ppa:neovim-ppa/stable
sudo apt-get update
sudo apt-get install -y neovim
最强Vim新手指南,手把手教你打造只属于自己的代码编辑器!_哔哩哔哩_bilibili
linux 文本三剑客

【比刷剧还爽 】B站唯一讲的最好的Linux三剑客教程,深入理解grep、sed、awk!_哔哩哔哩_bilibili

安装go

All releases - The Go Programming Language

Download and install - The Go Programming Language

设置为GO111MODULE=on
go mod init test

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

go env

如果已经有代码,那么就用下面的,能够让go.mod根据代码自动get库

go mod tidy
安装并配置mysql,能够在bench和服务器访问

ubuntu22.04安装mysql8并授权远程登陆_哔哩哔哩_bilibili

安装配置redis
wget http://download.redis.io/releases/redis-6.2.5.tar.gz
tar -zxvf redis-6.2.5.tar.gz
cd redis-6.2.5
make
cd deps
make hiredis linenoise lua jemalloc
cd hiredis
sudo make install
cd ../lua
sudo make install
cd ../..
sudo make install
//后台运行
vi redis.conf
//修改
stop-writes-on-bgsave-error = no
daemonize yes

cd src
redis-server ../redis.conf
安装gin

有关模板和gin模板

lesson01_内容介绍_哔哩哔哩_bilibili

go get -u github.com/gin-gonic/gin

安装gorm

https://www.bilibili.com/video/BV1xg411t7RZ/?spm_id_from=333.337.search-card.all.click&vd_source=3116d28903cf9e9d76cd88eaef0fda0f

go get -u gorm.io/gorm

安装viper,用来解析配置文件yaml

go get -u github.com/spf13/viper

logrus,用来记录日志

go get -u github.com/sirupsen/logrus

swaggo,自动api文档

go get -u github.com/go-openapi/swag

govalidator,提供对文本格式校验

go get -u github.com/asaskevich/govalidator

安装protobuf和grpc

grpc官网   Quick start | Go | gRPC

使用snap安装protobuf

sudo apt install snapd

sudo snap install protobuf --classic

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

export PATH="$PATH:$(go env GOPATH)/bin"

source $HOME/.profile

网络相关:

1. GO HTTP

Golang http 标准库底层原理解析_哔哩哔哩_bilibili

2. Websocket,长轮询

websocket是什么?和HTTP是什么区别?长轮询是什么?服务器推是什么?_哔哩哔哩_bilibili

数据结构和其他

1.iota

        iota在const变量中使用,用来初始化枚举类,初始值为0

numbers := []int{1, 2, 3, 4, 5} // 创建一个长度为5的切片

const (
	
	BEIJING = iota+1
	SHANGHAI 
	SHENZHEN 
)

2.defer

        类似于c++的析构函数,会在函数结束时调用被修饰的函数,多个defer会按照栈的方式调用,即先定义的后调用。会先执行return后defer

3.slice

        切片,在函数传参时如果传入切片,那么会是引用传递

下面,数组大小为5,申请空间为10,和c++vector一样

numbers := make([]int, 5, 10) // 创建一个长度为5的切片

直接初始化:

numbers := []int{1, 2, 3, 4, 5} // 创建一个长度为5的切片
numbers = append(numbers, 4, 5) // numbers 现在是 [1, 2, 3, 4, 5]

如果,用make后再append,那么会在5后面插入,而不是10后面

删除。注意,[:]新生成的数组只是在原数组上加了两个新的范围指针,没有复制新的内存

这里把后面的数据追加到0号数据,这样会删除0号,其中。。。用来展开

numbers := []int{1, 2, 3, 4, 5}
if len(numbers) > 0 {
    numbers = append(numbers[:0], numbers[1:]...)
}
扩容,一共四种情况

4.interface

        类似于类中的函数,不同的interface可以相互继承,直接在interface中添加就行,用这种方式实现继承,一个struct必须要实现interface的所有方法才可以实现多态

        也可以做万能类型

5.万能指针

        类似于模板参数

    func myfunc(arg interface){
    //断言
    value,ok:=arg.(string)
if !ok{
    fmt.Println("not string")
}else{
    fmt.Println("string")
fmt.Println(value)
}
}

6.pair映射

        每个数据都用pair<type,value>

        这里,alltype万能类型会传递a的pair

var a string
a = "aasdad"
var allType interface{}
allType = a
func reflectNum(arg interface{}){
	inputType := reflect.TypeOf(arg)
	inputValue := reflect.ValueOf(arg)
	Println("type:",reflect.TypeOf(arg))
	Println("value:",reflect.ValueOf(arg))
	for i:=0;i<inputType.NumField();i++{
		field := inputType.Field(i)
		value := inputValue.Field(i).Interface()
		Printf("name:%s: %v=%v\n", field.name, field.type, value)
	}
}

7.init

每个包都会有默认的init函数,如果只想执行init,不想执行其他函数,那么用

import _ "xxx"

8.结构体标签和json

package main
import (
	"encoding/json"
	"fmt"
)
type Movie struct{
	Title string `json:"title"`
	Year int `json:"year"`
	Price int `json:"rmb"`
	Actor []string `json:"actors"`
}

func main(){
	movie := Movie{"喜剧之王", 2000, 10, []string{"xingye", "zhangbozhi"}}
	jsonStr, err:=json.Marshal(movie)
	if err!=nil{
		fmt.Println("json marshal error", err)
		return
	}
	// fmt.Printf("jsonStr = %s\n", jsonStr)

	mymovie := Movie{}
	err = json.Unmarshal(jsonStr, &mymovie)
	if err!=nil{
		fmt.Println("json unmarshal error", err)
		return
	}

	fmt.Printf("%v \n", mymovie)
}

9.GMP

解说Golang GMP 实现原理_哔哩哔哩_bilibili

一、复用线程

p为processor,为调度器。m为内核级线程,g为goroutine。

每一个p中,都有一个g0,可以称之为调度协程。而g必须要绑定p才能执行。

查找流程

每61次调度,会从全局队列调度一次。

否则,先找本地队列,调度失败则找全局队列,调度失败则找网络协程,调度失败则窃取其他p的一半goroutine(尝试4次,随机窃取,只要有一次成功窃取就停止)到本地p队列中。

即本地->全局->网络->窃取

每61次调度->全局->...

hand off机制

当用户主动让出p时,首先会把gouroutine的状态由running转换成runnable,之后goroutine和线程解绑,之后把goroutine放置到全局队列中。

gouroutine被动阻塞时,把goroutine的状态转换成waiting,之后和线程解绑。之后哪个p唤醒了gouroutine,则把它放在这个p的当前队列中。

当goroutine正常结束时,把状态换成dead,之后解绑,进行下一轮的调度。

可以看到,被动阻塞唤醒抢占成功率比主动让出唤醒抢占成功率要低。

抢占调度,当m进入阻塞时,会导致g长时间运行,而p无法自主完成解绑,需要外界调度器强制调度。当有非繁忙m时,则进行绑定,如果没有,则需要创建一个新的m

二、利用并行

三、抢占

以前的线程需要主动让出cpu,但是现在有了限制时间

四、全局G队列

当main gorotine结束时,子gorotine会立即结束

10.channel

用来协程之间的通信,本身可以让main go和子go同步,不会让main go提前结束

package main
import (
	"fmt"
)

func main(){
	c :=make(chan int)

	go func(){
		defer fmt.Println("goprotine结束")
		fmt.Println("goroutine 正在运行。。。")

		c <- 666
	}()
	num := <-c
	fmt.Println(num)
}

defer fmt.Println("goprotine结束") 永远会在num := <-c之后执行

当缓存超出,那么会阻塞,等待其他go协程取出channel元素, 然后协程才会继续进行

当缓存为空,取数据也会阻塞

往已经关闭的channel发送数据会报panic错误

从已经关闭的channel读数据,需要看缓存中是否有数据,如果没有则报错,否则读取

对于nil channel,不管读写都会报错

func main(){
	c := make(chan int, 4)

	go func(){
		for i:=0; i< 4;i++{
			c<-i
		}
		close(c)
	}()

	for{
		if data,ok<-c;ok{
			fmt.Println(data)
		}else{
			break
		}
	}
}

可以简化为

for data:= range c{
		fmt.Println(data)
	}
select

会在case中寻找满足条件,哪个先满足选哪个,如果都不满则,则会走default,如果没有default,则阻塞

func ff(c, quit chan int){
	x,y :=1,1
	for{
		select{
		case c<-x:
			x = y
			y = x + y
		case <-quit:
			fmt.Println("quit")
			return
		default:
			return
		}
	
	}
}
func main(){
	c:=make(chan int, 6)
	quit:=make(chan int)
	go func(){
		for i:=0;i<6;i++{
			fmt.Println(<-c)
		}
		quit<-0
	}()

	ff(c,quit)
}
 context

context_interface_哔哩哔哩_bilibili

数据结构

Done,可以看到,输入通道的是空结构体,所以只能用来发送信号

当context未终止时,Done()读取空channel,会阻塞。当context终止时,会关闭channel,Done()会读取到0值并终止阻塞。

用来进行传输数据,取消信号等

有context.Context 为interface,一个Context实例

context.Background() 创建一个父context,启动goroutine 

ctx.Done()   判断协程是否结束

使用withcancel创建。

可以看到,可以调用第二个返回值来取消context。

ctx,cancel := context.WithCancel(context.Context)取消一个协程 

cancel()会取消当前线程

ctx = context.WithValue(context.Context, string,string)        传入父context,值key,value,可以

在其他协程中使用。如果当前context没有找到key,则会在父context中循环查找

当有key相同时,,则会生成两个结点a,所以函数结果需要考虑当前context位置。但是不需要考虑并发写的问题,因为会生成多个结点

ctx.Value(key) 获得对应context的key的value

ctx,cancel := context.WithDeadline(context.Context,time.Now().Add(time.Second))        在一秒后自动删除协程 

ctx,cancel := context.WithTimeout(context.Context, time.Second)   在一秒后自动删除协程 

11.内存管理

页索引&heapArena_哔哩哔哩_bilibili

p为处理器,每个mcache都会有自己的一部分缓存,首先程序需要在mcache找是否有合适的缓存,这一部分没有锁。如果没有需要找mcentral,mcentral共有67个等级,每个等级的预留缓存大小也不相同,程序根据自己的大小,去mcentral寻找是否有合适的缓存,由于可能有多线程,所以需要加锁处理,但是锁粒度较小。如果没有,再去mheap找,这里锁粒度较大。如果还是没有,需要从操作系统申请更多缓存。

mcentral根据大小划分等级。

在mspan中加标签,确定哪些页被程序占用。

在 Go 语言的内存管理系统中,mspan 作为内存分配的基本单位,通常表示的是一个或多个连续的内存页(page)。然而,对于较小的内存请求,Go 语言采用了特殊的优化技术来减少内存浪费,这就是所谓的“小对象分配优化。所以可能会有内存碎片产生

nospan,写错了。

如果mspan中都是基础类型,那么最低位为0,如果只要有1个指针,那么最低位就会为1.只要最低位为1,就需要给整个mspan检查,看是否需要给指针数据释放内存

mcache内容,等级0为无内存上限,所以总共136种。

mcenctral内容。每一个mcentral对应一个mspan,同时把span分成空闲列表和满列表

在mheap中,会给所有的页加标签,如果为0则自由,如果为1则被mspan申请了。

由于在mheap中可能有很多内存,找出连续未使用的内存,使用基数树

有一个64位的pallocsum,首位不用,剩下的分为3个部分,分别是start,max和end,表示首次出现空闲页的mspan序号,连续空闲空间最大的mspan序号,以及最后出现空闲mspan的序号。图画错了,不是连续大小。和span分配位图取与来获得对应的数据

同时,给pallocsum进行分级,把位逐渐的细粒度化,最后一级的单位为512个页

P申请内存过程。P在小于16B为微对象,16B到32KB为小对象,大于32KB为大对象,对应mspan的0号等级,即直接在mheap找。

mcache的tiny allocator,以2B的倍数为单位

12.垃圾回收

并发三色标记_哔哩哔哩_bilibili

三色标记法

把自身存活并且所指向的结点也被标记的结点,变成黑色结点

把自身存活,但是指向结点没有被标记的结点,变成灰色结点

把未扫描的结点,加上白色结点

采用dijkstra算法

第一步,把根节点(包括全局变量,栈上局部变量)变黑,根节点指向的结点变灰,并从灰色结点逐步扫描

第二步,从灰色结点扫描,并把周围所有可以置成灰色的结点变灰

第三步,如果所有结点都变灰,那么结点变黑,如果有结点是白色,则对白色结点的引用

第四步,从第二步循环

第五步,如果有结点依旧是白色,则垃圾回收

并发三色标记法

在并发下,可能出现漏标的问题

也有可能出现多标的问题

混合写屏障机制

可以看出,漏标的原因有两点,一是黑色结点指向了白色结点,二是灰色对象删除了对白色对象的引用,导致白色结点不会被扫描,由此可以引出强弱三色不变式

强三色不变式:插入写屏障 

白色不能被黑色对象引用

做法为,如果黑色对象引用了一个白色对象,那么就把黑色对象变灰

弱三色不变式:删除写屏障

不会删除对白色对象的引用

做法为,如果一个白色对象被引用,那么就把白色对象变灰,并不会删除对这个对象的引用

为什么需要混合两者:

如果频繁的使用屏障调用函数,那么开销很大,因此屏障只会作用于非栈对象

那么,看看能否解决漏标和多标的问题:

13.map

map不能够并行的读写,或并行写,只能并行读

map采用桶数组。每一个桶有8个key-value pair。

可以说,map解决hash冲突的方式是拉链法和开放寻址法的结合。

对比:c++ map的扩容条件是hash因子达到0.75

map的数据结构:

包括两个map。其中,溢出桶用来存放hash桶溢出的数据,避免桶因扩容导致的频繁的再hash

14.sync.map

作为map的可并行版本,下面是数据结构

可以看到,相对于map,多了一个dirty map和锁,misses。

dirty map用来把读操作和写错做分开,从而减少因并行导致的加锁行为。

删除数据时,当删除read map数据,则把数据指针变成nil,称之为软删除态。当删除dirty 数据,则物理删除,为硬删除态。

在读数据时,如果在read map中读不到数据,则进入dirty map中读取,并且misses++,当misses达到阈值时,则把dirty map作为新read map,新dirty map暂时为空。

在写数据时,需要先查看read map是否有数据,因为可能是修改操作。当dirty map为nil时,且需要写入到dirty map,需要把read map复制dirty map,同时遍历read map,把非删除态数据复制,软删除态数据进行物理删除。

可以看到,如果频繁的把数据从dirty map复制到read map,那么sync.map效率不会很高。

具体来说,可以看到,当misses频繁增加,则会有很大性能影响。所以当有频繁读取新加数据时,会造成sync.map性能不如直接加锁的性能好。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

亚马逊旺季爆品攻略:如何利用旺季打造爆品?

随着假日季的脚步日益临近&#xff0c;亚马逊卖家们正摩拳擦掌&#xff0c;准备迎接这一年度的销售高峰。本文将为您揭示如何在旺季中抓住机遇&#xff0c;通过精心策划和执行一系列策略&#xff0c;让您的产品在众多竞争对手中脱颖而出&#xff0c;成为真正的爆品&#xff01;…

别卷Transformer了!时序卷积这么做,一样发顶会!

Transformer爆火之后&#xff0c;时间序列领域基本上算是被占领了&#xff0c;围绕此类相关的研究也是非常之卷。这种情况下&#xff0c;我们不妨了解一下时序卷积。 在大规模时间序列数据处理任务中&#xff0c;时序卷积是一种非常重要的方法&#xff0c;它结合了传统CNN的特…

【C++】STL中的list容器详解及常用函数用法

个人主页: 起名字真南的CSDN博客 个人专栏: 【数据结构初阶】 &#x1f4d8; 基础数据结构【C语言】 &#x1f4bb; C语言编程技巧【C】 &#x1f680; 进阶C【OJ题解】 &#x1f4dd; 题解精讲 目录 &#x1f4cc; 1 引言&#x1f4cc;2 list容器✨2.1 list容器简介✨2.2 li…

使用kalibr_calibration标定相机(realsense)和imu(h7min)

vslam-evaluation/VINS/Installation documentation/4.IMU和相机联合标定kalibr_calibration.md at master DroidAITech/vslam-evaluation GitHub 目录 1.kalibr安装 1.1安装依赖项 1.2创建工作空间 1.3下载kalibr并编译 1.4设置环境变量 2.准备标定板 3.配置驱动和打…

论文阅读:基于语义分割的非结构化田间道路场景识别

论文地址&#xff1a;DOI: 10.11975/j.issn.1002-6819.2021.22.017 概要 环境信息感知是智能农业装备系统自主导航作业的关键技术之一。农业田间道路复杂多变&#xff0c;快速准确地识别可通行区域&#xff0c;辨析障碍物类别&#xff0c;可为农业装备系统高效安全地进行路径规…

能识别黑烟的摄像头

能识别黑烟的摄像头主要应用于监测车辆尾气排放情况&#xff0c;特别是针对排放黑烟的车辆进行抓拍和识别。以下是朗观视觉对这类摄像头的详细介绍&#xff1a; 一、主要特点 智能识别&#xff1a;摄像头内置视频识别功能&#xff0c;能够实时分析视频中的车辆尾气排放情况&am…

Docker镜像分成

1. 镜像分层原理 1.1 镜像分层的定义与结构 Docker 镜像的分层存储机制是其核心特性之一&#xff0c;它允许 Docker 镜像由多个只读层组成&#xff0c;这些层叠加在一起形成一个完整的文件系统。每个层代表 Dockerfile 中的一个指令&#xff0c;并且每一层都是不可变的&#…

2020年美国总统大选数据分析与模型预测

数据集取自&#xff1a;2020年&#x1f1fa;&#x1f1f8;&#x1f1fa;&#x1f1f8;美国大选数据集 - Heywhale.com 前言 对2020年美国总统大选数据的深入分析&#xff0c;提供各州和县层面的投票情况及选民行为的可视化展示。数据预处理阶段将涉及对异常值的处理&#xff0…

微服务系列五:避免雪崩问题的限流、隔离、熔断措施

目录 实验环境说明 前言 一、一片小雪花引起的雪崩&#xff01; 1.1 雪崩问题&#xff08;级联失败问题&#xff09;示意图 1.2 雪崩问题的产生原因与解决策略 二、雪崩问题的具体解决策略 2.1 请求限流 2.2 线程隔离 2.3 服务熔断 2.4 总结——具体解决策略 三、微…

聊一聊:ChatGPT搜索引擎会取代谷歌和百度吗?

当地时间 10 月 31 日&#xff0c;OpenAI 正式推出了 ChatGPT 搜索功能&#xff0c;能实时、快速获取附带相关网页来源链接的答案。这一重大升级标志着其正式向谷歌的搜索引擎霸主地位发起挑战。 本周五我们聊一聊&#xff1a; 欢迎在评论区畅所欲言&#xff0c;分享你的观点~ …

国标GB28181公网直播EasyGBS国标GB28181软件管理解决方案

随着信息技术的飞速发展&#xff0c;视频监控技术已经成为维护公共安全、提升管理效率的重要手段。在这一背景下&#xff0c;国标GB28181软件EasyGBS作为一款自主研发的安防视频管理软件&#xff0c;致力于为用户提供全面、高效且可靠的视频监控管理体验。其强大的功能和灵活的…

《Practical Deep Raw Image Denoising on Mobile Devices》论文详解

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 论文&#xff1a;Practical Deep Raw Image Denoising on Mobile Devices 引言 在数字摄影领域&#xff0c;噪声是影响图像质量的主要因素之一&#xff0c;特别是在弱光条件下拍摄时更为明显。移…

戴尔电脑 Bios 如何进入?Dell Bios 进入 Bios 快捷键是什么?

BIOS&#xff08;基本输入输出系统&#xff09;是计算机启动时运行的第一个程序&#xff0c;它负责初始化硬件并加载操作系统。对于戴尔电脑用户来说&#xff0c;有时可能需要进入 BIOS 进行一些特定的设置调整&#xff0c;比如更改启动顺序、调整性能选项或解决硬件兼容性问题…

【AD】3-2 原理图绘制格点的调整与推荐设置

1.点击工具&#xff0c;选择原理图优先项&#xff0c;如图设置 2.画原理图之前&#xff0c;选中原理图&#xff0c;也可以快捷键vgs&#xff0c;设置栅格为100mil&#xff0c;并画原理图是元器件管脚放置在格点上 3.通过改选项设置格点显示与不显示

I.MX6U 裸机开发2. 芯片简介、汇编基础及GPIO操作准备工作

I.MX6U 裸机开发2. 芯片简介、汇编基础及GPIO操作准备工作 一、I.MX6U 芯片介绍1. 基本介绍2. 架构图如下&#xff1a;3. I.MX6U 管脚定义规则 &#xff1a; 二、GPIO资源介绍1. 原理图2. 寄存器控制(1) 使能时钟&#xff0c;CCGR0~CCGR7(2) 设置引脚复用(3) 设置电气属性(4) 配…

DNS配置

1.搭建dns服务器能够对自定义的正向或者反向域完成数据解析查询。 2.配置从DNS服务器&#xff0c;对主dns服务器进行数据备份。 options {listen-on port 53 { 192.168.111.130; };directory "/var/named";allow-query { any;};zone "openlab.com&qu…

day-81 打家劫舍 II

思路 与LCR 089. 打家劫舍相比&#xff0c;本题所有房屋围成了一圈&#xff0c;那么第一间房子和最后一间房子不能同时打劫&#xff0c;那么就可以分为两种情况&#xff1a;1.选第一间房打劫&#xff1b;2.选最后一间房打劫 解题过程 然后依次计算出以上两种情况的最大金额&am…

什么是进销存?进销存系统都有哪些类型?

进销存管理和企业运营之间的利害关系大家应该都已经听的不少了。上次给大家说明白了进销存系统是什么&#xff0c;但是进销存系统到底有哪几种&#xff1f;把今天这篇文章耐心读完你就懂了&#xff01; 随着市场竞争的加剧和消费者需求的多样化&#xff0c;企业亟需灵活高效的…

spark的学习-03

RDD的创建的两种方式&#xff1a; 方式一&#xff1a;并行化一个已存在的集合 方法&#xff1a;parallelize 并行的意思 将一个集合转换为RDD 方式二&#xff1a;读取外部共享存储系统 方法&#xff1a;textFile、wholeTextFile、newAPIHadoopRDD等 读取外部存储系统的数…

Python练习10

Python日常练习 题目&#xff1a; 编写程序&#xff0c;输出如下所示图案。 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 要求&#xff1a; 使用for循环的方式完成 --------------------------------------------------------- 注意&#xff1a; …