Go语言小细节

news2024/11/15 12:05:51

在这里插入图片描述

Go语言小细节

结构体

  • 结构体中允许存在匿名字段,即只有类型没有具体的变量名,但是一个结构体内只允许有一个相同类型的
  • 结构体中字段大写开头表示可公开访问,小写表示私有(仅在当前结构体的包中可访问)
  • 在编写结构体的 Tag 时,不要在key和value中添加空格,容错能力很差
//Student 学生
type Student struct {
	ID     int    `json:"id"` //通过指定tag实现json序列化该字段时的key
	Gender string //json序列化是默认使用字段名作为key
	name   string //私有不能被json包访问
}
  • 在结构体的方法中,如果要修改 slice、array、map 这些成员属性,要注意,因为他们的指向都是地址, GO 中函数的参数虽然是一份拷贝,但是拷贝的仍然是一份地址,如果你在方法中不进行 copy,你在外部修改源数据也会影响成员的内部

package包

一个包的初始化过程是按照代码中引入的顺序来进行的,所有在该包中声明的 init 函数将被串行调用并且仅调用一次。每一个包的初始化的时候都是先执行依赖包中的声明的 init 函数再执行当前包中的 init 函数,确保在程序 main 函数开始执行时所有的依赖包都已经初始化完成。

接口

  • 一般在接口命名时会 + er 作为单词的结尾
  • 在实现接口的过程中,如果是值接收者,接口类型的变量时可以被 结构体的实例化地址或者对象变量赋值的,但如果是指针接收者,那么不能将非 结构体的引用赋值给接口变量
  • 接口也可以和结构体一样进行组合,只要实现新结构体中的所有方法,即认为它实现了这个新的接口
  • 空接口可以不必使用 type 关键字声明,空接口可以存储任何类型的值
  • 只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。切记不要为了使用接口类型而增加不必要的抽象,导致不必要的运行时损耗。

并发

  • 串行:无法同步,只有完成了上一步才能执行下一步

  • 并行:同一时刻执行多个任务

  • 并发:同一个时间段执行多个任务

  • 进程:程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位

  • 线程:操作系统基于进程开启的轻量级进程,是操作系统调度执行的最小单元

  • 协程:非操作系统提供而是由用户自行创建和控制的用户态"线程",比线程更轻量级

并发模型

  • 线程&锁模型
  • Actor模型
  • CSP 模型
  • Fork&Join模型

go的并发主要是通过基于 CSP 的 goroutine 和 channel 来实现,当然也支持使用传统的多线程共享内存的并发方式

一个 goroutine 会以一个很小的栈开始它的生命周期,一般只需要 2kb。区别于操作系统线程由系统内核进行调度,goroutine 是由 Go运行时(runtime)负责调度。例如 Go 运行时会只能的将 M 个 goroutine 合理地分配给 N 个操作系统线程,实现类型 m:n 的调度机制,不再需要 Go 开发者自行在代码层面维护一个线程池。

goroutine 的调度是Go语言运行时(runtime)层面的实现,是完全由 Go 语言本身实现的一套调度系统——go scheduler。它的作用是按照一定的规则将所有的 goroutine 调度到操作系统线程上执行,目前 Go 采用的调度策略是 GMP 模型。

  • main goroutine如果执行完了,其他的 goroutine 没有执行完,也会被关闭,所以我们会使用 WaitGroup 等待协程的完成
  • 多个 goroutine 的调度是随机的

动态栈

操作系统的线程一般都有固定的栈内存(通常为2MB),而 Go 语言中的 goroutine 非常轻量级,一个 goroutine 的初始栈空间很小(一般为2KB),所以在 Go 语言中一次创建数万个 goroutine 也是可能的。并且 goroutine 的栈不是固定的,可以根据需要动态地增大或缩小, Go 的 runtime 会自动为 goroutine 分配合适的栈空间。

goroutine调度

单从线程调度讲,Go语言相比起其他语言的优势在于OS线程是由OS内核来调度的, goroutine 则是由Go运行时(runtime)自己的调度器调度的,完全是在用户态下完成的, 不涉及内核态与用户态之间的频繁切换,包括内存的分配与释放,都是在用户态维护着一块大的内存池, 不直接调用系统的malloc函数(除非内存池需要改变),成本比调度OS线程低很多。 另一方面充分利用了多核的硬件资源,近似的把若干goroutine均分在物理线程上, 再加上本身 goroutine 的超轻量级,以上种种特性保证了 goroutine 调度方面的性能。

GOMAXPROCS

Go运行时的调度器使用GOMAXPROCS参数来确定需要使用多少个 OS 线程来同时执行 Go 代码。默认值是机器上的 CPU 核心数。例如在一个 8 核心的机器上,GOMAXPROCS 默认为 8。Go语言中可以通过runtime.GOMAXPROCS函数设置当前程序并发时占用的 CPU逻辑核心数。(Go1.5版本之前,默认使用的是单核心执行。Go1.5 版本之后,默认使用全部的CPU 逻辑核心数。)

channel

单纯地将函数并发执行是没有意义的。函数与函数间交换数据才能体现并发执行函数的意义。

虽然可以使用共享内存进行数据交换,但是共享内存在不同的 goroutine 中容易发生竞态问题。为了保证数据交换的正确性,很多并发模型中必须使用互斥量对内存进行加锁,这种做法势必造成性能问题。

Go 使用 CSP 并发模型,提倡通过通信共享内存,而不是通过共享内存实现通信

如果说 goroutine 是Go程序并发的执行体,channel就是它们之间的连接。channel是可以让一个 goroutine 发送特定值到另一个 goroutine 的通信机制。

Go 语言中的通道(channel)是一种特殊的类型。通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。每一个通道都是一个具体类型的导管,也就是声明 channel 的时候需要为其指定元素类型。

注意:一个通道值是可以被垃圾回收掉的。通道通常由发送方执行关闭操作,并且只有在接收方明确等待通道关闭的信号时才需要执行关闭操作。它和关闭文件不一样,通常在结束操作之后关闭文件是必须要做的,但关闭通道不是必须的。

关闭后的通道有以下特点:

  • 对一个关闭的通道再发送值就会导致 panic。
  • 对一个关闭的通道进行接收会一直获取值直到通道为空。
  • 对一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值。
  • 关闭一个已经关闭的通道会导致 panic。

无缓存通道

  • 它需要等待接收后才不会造成死锁,如果没有人接收就会 deadlock
  • 使用无缓冲通道进行通信将导致发送和接收的 goroutine 同步化。因此,无缓冲通道也被称为同步通道。

有缓存通道

只要通道的容量大于零,那么该通道就属于有缓冲的通道,通道的容量表示通道中最大能存放的元素数量。当通道内已有元素数达到最大容量后,再向通道执行发送操作就会阻塞,除非有从通道执行接收操作。就像你小区的快递柜只有那么个多格子,格子满了就装不下了,就阻塞了,等到别人取走一个快递员就能往里面放一个。

我们可以使用内置的len函数获取通道内元素的数量,使用cap函数获取通道的容量,虽然我们很少会这么做。

单向通道

<- chan int // 只接收通道,只能接收不能发送
chan <- int // 只发送通道,只能发送不能接收

Select多路复用

  • 可处理一个或多个 channel 的发送/接收操作。
  • 如果多个 case 同时满足,select 会随机选择一个执行。
  • 对于没有 case 的 select 会一直阻塞,可用于阻塞 main 函数,防止退出。

并发安全和锁

有时候我们的代码中可能会存在多个 goroutine 同时操作一个资源(临界区)的情况,这种情况下就会发生竞态问题(数据竞态)。这就好比现实生活中十字路口被各个方向的汽车竞争,还有火车上的卫生间被车厢里的人竞争。

互斥锁是一种常用的控制共享资源访问的方法,它能够保证同一时间只有一个 goroutine 可以访问共享资源。Go 语言中使用sync包中提供的Mutex类型来实现互斥锁。

但是一般在我们的应用中都是读多写少,我们会考虑使用读写互斥锁,当我们并发的去读取一个资源而不涉及资源修改的时候是没有必要加互斥锁的

读写锁分为两种:读锁和写锁。当一个 goroutine 获取到读锁之后,其他的 goroutine 如果是获取读锁会继续获得锁,如果是获取写锁就会等待;而当一个 goroutine 获取写锁之后,其他的 goroutine 无论是获取读锁还是写锁都会等待。

sync.WaitGroup

sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。例如当我们启动了 N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用 Done 方法将计数器减1。通过调用 Wait 来等待并发任务执行完,当计数器值为 0 时,表示所有并发任务已经完成。

sync.Once

在某些场景下我们需要确保某些操作即使在高并发的场景下也只会被执行一次,例如只加载一次配置文件等。

Go语言中的sync包中提供了一个针对只执行一次场景的解决方案——sync.Once,sync.Once只有一个Do方法,其签名如下:

sync.Map

Go 语言中内置的 map 不是并发安全的

原子操作 atomic

atomic包提供了底层的原子级内存操作,对于同步算法的实现很有用。这些函数必须谨慎地保证正确使用。除了某些特殊的底层应用,使用通道或者 sync 包的函数/类型实现同步更好。

struct转换成map时会出现数据

类型转换错误的问题

// UserInfo 用户信息
type UserInfo struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

u1 := UserInfo{Name: "q1mi", Age: 18}

这个如果 u1 转成 map 的话,先 json,然后序列化回来给 map, 这时这个 Age 就变成了 float 类型
  • 方法一:这里使用反射遍历结构体字段的方式生成map
  • 第三方库structs

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

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

相关文章

Linux之进程信号(下)

文章目录 前言信号的相关概念一、信号的保存——位图1.内核中的表示2.信号集——sigset_t3.信号集操作函数 二、信号的捕捉过程1.内核态和用户态用户代码和内核代码如何分辨是用户态还是内核态一个进程如何跑到OS中执行方法 2.信号捕捉的过程 三、核心转储1.数组越界并不一定会…

CTFHub | 远程包含

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

Flutter 库:提升开发体验——Quick

Flutter 库&#xff1a;提升开发体验——Quick 文章目录 Flutter 库&#xff1a;提升开发体验——Quick一、概述1、简介2、功能3、官方资料4、思考 二、基本使用1、安装2、基本使用3、运行结果 三、List 列表扩展示例四、Map 映射扩展示例五、其它示例 一、概述 1、简介 Quic…

打印杨辉三角

这个公式&#xff0c;不好算&#xff0c;我觉得还是杨辉三角算起来方便&#xff1a;c#代码如下&#xff1a; double 打印杨辉三角(int n)//n必须是偶数&#xff0c;展开项是n1&#xff0c;中间项是n/2,此处返回中间项的概率202306131722 { //for (int i 0…

3个月面过字节测开岗,拿个20K不过分吧?

计算机专业&#xff0c;代码能力一般&#xff0c;之前有过两段实习以及一个学校项目经历。第一份实习是大二暑期在深圳的一家互联网公司做前端开发&#xff0c;第二份实习由于大三暑假回国的时间比较短&#xff08;小于两个月&#xff09;&#xff0c;于是找的实习是在一家初创…

浅聊一下 C#程序的 内存映射文件 玩法

一&#xff1a;背景 1. 讲故事 前段时间训练营里有朋友问 内存映射文件 是怎么玩的&#xff1f;说实话这东西理论我相信很多朋友都知道&#xff0c;就是将文件映射到进程的虚拟地址&#xff0c;说起来很容易&#xff0c;那如何让大家眼见为实呢&#xff1f;可能会难倒很多人&…

耗时3个月,线下访谈30+ csdn大佬,规划出了我的云原生学习路线

前言 大家好&#xff0c;我是沐风晓月&#xff0c;最近线下拜访不少云原生方向的大佬和csdn其他方向的大佬&#xff0c;受益匪浅。 于是在 5月23日&#xff0c;我定下来自己的目标&#xff1a; 我的目标&#xff1a; 可以说&#xff0c;这个世代给予的机遇&#xff0c;让我…

WWDC苹果高管脱口秀,Mike Rockwell透露Vision Pro开发的秘密

WWDC2023之后例行的“The Talk Show”脱口秀如期展开&#xff0c;深入讨论了WWDC上的一切。本次脱口秀分别谈及Mac游戏、Vision Pro以及操作系统和AI&#xff0c;由John Gruber主持&#xff0c;嘉宾包括&#xff1a;苹果技术发展部副总裁Mike Rockwell、以及Greg Joswiak、John…

上线客流人数统计系统实现资源的最大化利用

在流量管理方面&#xff0c;智慧客流采集系统的应用可以帮助商家实现资源的最大化利用。通过对客流量数据的分析&#xff0c;商家可以准确把握客流量变化规律&#xff0c;进而制定出最优化的资源配置方案。 AI客流视觉监控 一、某汽车4S店智慧客流采集系统案例展示 以某汽车4S…

人民大学中外合作办学_人大女王金融硕士——国际顶尖的金融硕士学位等你来拿

进入金融圈后&#xff0c;你会发现学历是筛选手段之一&#xff0c;之后的晋升更是看重学历。一个金融学士学位可以让你跨过门槛进入到金融行业&#xff0c;想要得到更好的发展&#xff0c;就需要从知识和证书等多方面进行提升了。辞职去攻读硕士学位不太现实&#xff0c;幸好遇…

vsftpd安装配置,Linux系统配置FTP服务器教程(CentOS 7)

vsftpd&#xff08;very secure FTP daemon&#xff09;是Linux下的一款小巧轻快、安全易用的FTP服务器软件。今天飞飞将和你分享Linux系统安装并配置vsftpd&#xff0c;搭建FTP环境。 先让我们来认识下FTP&#xff01; FTP&#xff08;File Transfer Protocol&#xff09;是一…

C语言-运算符

1 运算符的概念以及分类 运算符的概念 用运算符将运算对象(也称操作数&#xff09;连接起来的、符合&#xff23;语法规则的式子&#xff0c;称为&#xff23;表达式运算对象包括常量、变量、函数等 运算符的分类 1、双目运算符&#xff1a;即参加运算的操作数有两个 例&…

系统移植 网络环境配置和TFTP服务器搭建

目录 网络环境配置 1. 配置windows环境下协议 2. 配置linux环境下的网络 3. 开发板 4. Ping 不通解决办法 搭建TFTP服务器环境搭建 》1.验证tftp服务器环境是否搭建 》2.若是未安装&#xff0c;执行下面命令 》3.修改tftp服务器配置文件 》4.在ubuntu下创建工作目录并…

华为OD机试真题 JavaScript 实现【日志采集系统】【2023Q1 100分】

一、题目描述 日志采集是运维系统的的核心组件。日志是按行生成&#xff0c;每行记做一条&#xff0c;由采集系统分批上报。 如果上报太频繁&#xff0c;会对服务端造成压力&#xff1b;如果上报太晚&#xff0c;会降低用户的体验&#xff1b;如果一次上报的条数太多&#xf…

ffplay播放http-mp4视频提示 “stream 1, offset 0x1f85: partial file“错误

解决办法就是将非交织视频 重新 remux. ffmpeg -i a.mp4 -c copy -movflags faststart a1.mp4 -movflags faststart : 这个是将moov移动到 mp4头部,和remux没有关系. 这样处理也是通过HTTP 流式播放必须要做的一步.

Linux防火墙学习笔记11

iptables扩展动作&#xff1a;TARGET EXTENSION: filter&#xff1a; -j ACCEPT -j DROP -j REJECT -j LOG nat: -j SNAT: 源地址转换 -j MASQUERADE: 转换源地址&#xff08;伪装&#xff09; -j DNAT: 目的地址转换及端口 -j REDIRECT: 转换目标端口 本机端…

Java后端入职第六天,Nginx搭建负载均衡+反向代理

一:需求背景 Nginx相信大家应该不陌生吧!是一个高性能web服务器,可以做负载均衡或者是反向代理,比如,把静态页面直接部署到到html,实现动静分离,一个服务器部署多个服务,缓解服务压力,等等,都可以利用Nginx实现。 1.负载均衡 这个理解比较简单,其实就是压力分摊,…

Aspose.Pdf使用教程:获取PDF文档中的所有注释

Aspose.PDF 是一款高级PDF处理API&#xff0c;可以在跨平台应用程序中轻松生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现&#xff0c;保护和打印文档。无需使用Adobe Acrobat。此外&#xff0c;API提供压缩选项&#xff0c;表创建和处理&#xff0c;图形和图像功能&am…

小马赠书【第7期】清华出版社 IT BOOK 多得活动(送书5本)

本期 敬 之 共精心挑选了 15 本 IT 相关书籍&#xff0c;包含 前端、后端、数据分析、人工智能、python、低代码 等各个领域。关于如何参与等具体活动信息请看活动详情页&#xff0c;以下是 15 本 IT 书籍介绍&#xff1a; 活动详情页&#xff1a;小马赠书【第7期】 1. C《C 高…

Django高级扩展之静态文件和ajax使用

目录 使用静态文件 创建静态文件目录 Settings.py配置 创建css文件 路由与视图 设置路由 视图 模板使用静态文件 调用css 调用js 调用图片 优化路径 加载标签 修改文件路径 修改图片路径 修改js路径 修改css路径 使用Ajax 应用场景 示例 路由 视图 模板…