GO语言核心30讲 进阶技术 (第一部分)
原站地址:Go语言核心36讲_Golang_Go语言-极客时间
一、数组和切片
1. 两者最大的不同:数组的长度是固定的,而切片的长度是可变的。
2. 可以把切片看成是对数组的一层封装,因为每个切片的底层数据结构中,一定会包含一个数组。 切片也可以被看作是对底层数组的某个连续片段的引用(窗口)。
3. go语言不存在传值或传引用两种区分。 只要传递的是引用类型的,就是“传引用”。如果传递的是值类型的,就是“传值”。 切片属于引用类型,数组属于值类型。
4. 内建函数 len()计算长度,cap()计算容量。
例子: s1是切片,底层数组是8个元素。 s2 := s1[3:6]
len(s2) = 6-3, 即 结束索引 减去 起始索引
cap(s2) = 8-3,即 底层数组长度 减去 起始索引 , 从起始索引位置向右扩展到最末端
5. 切片容量的增长逻辑:
(1) 一般情况下,新切片的容量将会是原切片容量的 2 倍。
(2) 如果新长度比原容量的 2 倍还要大,那么新容量就会以新长度为基准。
(3) 如果原长度大于等于1024,会以原容量的1.25倍作为基准,一直扩展到满足扩容需求。
6. 切片的底层数组在扩容时不会被替换。 扩容时是使用了新的切片和新的底层数组。 旧切片不变。
二、container包中的容器:List 和 Ring
1. List 容器,是一个双向链表,所以它支持下面的方法:
(1) 把内部元素移动到链表头部或尾部,或移动到另一个元素的前面或后面
(2) 插入新元素到链表头部或尾部,或一个元素的前面或后面
(3) 如果自己生成元素,直接传给链表的方法做 移动操作,链表不会接受。因为可以根据前后元素的指针数据做合法性判定。
2. List 支持开箱即用。经过声明的List变量 是一个长度为0的链表,是一个空壳,但可以直接使用。 使用之后再做初始化。这种延迟初始化可以分散初始化带来的计算量压力。
3. List内部就是一个循环链表。它的根元素不持有实际的元素值,但连接了这个循环链表的首尾两端。
4. List 和 Ring 的区别
(1) List 和 Ring 都是循环链表
(2) List 可以添加和删除元素, Ring不可以。Ring要添加元素,需要重建一个新的Ring.
(3) Ring的数据结构仅由它自身即可代表,而List则需要由它以及Element类型联合表示。
三、字典的操作和约束
1. 哈希表查找某个 键值对应的元素值 的过程:
(1) 用哈希函数把键值转换为哈希值。 哈希值是一个无符号的整数
(2) 哈希表持有一定数量的桶(bucket),这些哈希桶储存其所属的一定数量 键-元素对。
(3) 哈希表用这个键的哈希值去定位一个哈希桶,然后在这个哈希桶中查找这个键-元素对。
2. Map的键类型必须支持操作符 == 和 != 。 函数、字典和切片类型的值并不支持判等操作,所以他们不能作为键。
如果键的类型是接口类型,而且实际类型也是上述三种类型,在程序运行过程中会引发 panic。
如果键的类型是自定义结构体,而且包含上述三种类型,也是会panic
3. 键的数据类型,优先选用数值和指针类型。
求哈希和判等操作的速度越快,对应的类型就越适合作为键类型。
宽度越小、长度越短,求哈希值的速度越快。
4. 在值为nil的字典上执行读和写操作会成功吗?
(1) 仅声明而不初始化 字典变量,它的值会是nil。
(2) 往nil字段添加删除元素值,会panic
(3) 其他nil字典上的任何操作,包括获取元素值,都不会panic
四、通道的基本操作
1. 通道相当于一个先进先出队列,先被发送到通道的元素值,一定会先被接收。
2. 声明并初始化通道: ch1 := make(chan int, 3) 元素类型为int、容量为3
往通道发送数据: ch1 <- 1
从通道接收数据: data := <- ch1
3. 通道的三个特性:
(1) 发送操作之间,接收操作之间是互斥的。即多个goroutine要同时发通道发送数据时,只有一个能起作用。 对于同一个数据而言, 发送和接收两个操作也是互斥的。
(2) 发送和接收时,对数据的处理是不可分割的。即 只会是没发送或发送完,不会是发送了一半。
在通道中的数据,是被复制的一个副本。
(3) 发送和接收操作在完成之前, goroutine会被阻塞。包含复制、放置、删除三个步骤。如此阻塞是为了保证数据的安全和完整性。
4. 发送和接收是,触发阻塞状态的几种情况:
(1) 非缓冲通道,一执行就会阻塞
(2) 带缓冲的通道,缓冲区满了时发送操作会阻塞,缓冲区空了是接收操作会阻塞。
(3) 值为nil的通道,执行操作时会立刻阻塞。 不要忘记初始化通道。
5. 会引发panic的情况
(1) 向已经关闭的通道发送数据会panic。 但是接收数据的话不会。
(2) 试图关闭一个已经关闭的通道,会panic
6. 关闭通道,要交给发送方来做。
因为即使通道已经关闭,接收方也能成功完成接收操作 (第二个结果值是true)。如果根据这个结果值来判断是否要做关闭操作的话,会引发重复关闭通道,导致panic。 所以应该让发送方根据发送逻辑来判定是否要关闭通道。
五、通道的高级玩法
1. 创建一个通道: ch := make(chan int, 1)
创建单向只发通道: ch := make(chan <- int, 1)
创建单向只收通道: ch := make( <- chan int, 1)
2. 单向通道的用途是约束局部代码的行为。某部分代码值能发送,某部分代码值能接收。
3. 只发通道应用: 只发通道作为参数传入
func SendInt(ch chan<- int) {ch <- rand.Intn(1000)
}
外部函数向上面这个函数传参时,可以传入一个双向通道,GO语言会自动把双向通道转换为单向通道。
4. 只收通道应用: 只收通道作为结果返回
func getIntChan() <-chan int {num := 5ch := make(chan int, num)for i := 0; i < num; i++ {ch <- i}close(ch)return ch
}
注意,这里函数内部已经把通道给关闭了
5. 用 for range 接收通道数据
intChan2 := getIntChan()
for elem := range intChan2 {fmt.Printf("The element in intChan2: %v\n", elem)
}
for 循环会一直从通道接收数据。 接收完之后,如果通道没关闭就会阻塞,如果关闭了就会直接执行退出for循环。
6. select语句与通道联用
// 准备好几个通道。
intChannels := [2]chan int{make(chan int, 1),make(chan int, 1),
}
// 随机选择一个通道,并向它发送元素值。
index := rand.Intn(2)
fmt.Printf("The index: %d\n", index)
intChannels[index] <- index
// 哪一个通道中有可取的元素值,哪个对应的分支就会被执行。
select {
case <-intChannels[0]:fmt.Println("The first candidate case is selected.")
case <-intChannels[1]:fmt.Println("The second candidate case is selected.")
default:fmt.Println("No candidate case is selected!")
}
(1) select语句只能与通道联用
(2) 加入了 default 分支后,当其他分支都出现阻塞,select语句就会进入default分支。
(3) 没有加入default 分支的话,其他分支都出现阻塞,select语句就会阻塞。
(4) select只会对分支的通道求值操作一次,如果要反复操作通道的话,需要加for循环。但要注意,default里的代码执行break,只会结束掉select语句,不会结束掉for语句。
7. select 的分支选择规则都有哪些?
(1) case 右边的表达式,可以是通道接收操作,也可以是发送操作。
(2) case 右边的表达式,可以有多个接收操作。
(3) select语句的执行是先全部分支case求值,完毕后再选择其中一个分支。
(4) case 求值顺序是从上至下,从左至右。
(5) 多个case满足条件的话,select语句会随机选择一个分支去执行。
(6) default 分支只有在无候选分支可选时才会被执行,与default分支是位置无关
六、使用函数的正确姿势
1. 什么是高阶函数? (函数式编程的重要概念) 满足以下两条件之一:
(1) 接受其他函数作为参数输入
(2) 把其他函数作为结果返回
2. 如何实现高阶函数? 下面以 函数作为参数输入 做例子。
(1) 声明一个名叫operate的函数类型
type operate func(x, y int) int
(2) 实现这个函数(低阶),签名与上面声明的一样。并赋值给函数变量 op
op := func(x, y int) int {return x + y
}
(3) 实现高阶函数,把低阶函数 operate 作为参数输入。 并调用执行这个函数,op()
func calculate(x int, y int, op operate) (int, error) {res := op(x, y)return res , nil
}
这个 calculate 就是高阶函数,提供给外部调用。
3. 那如何把 函数作为结果返回?
func genCalculator() calculateFunc {f := func(x int, y int) (int, error) {return x + y}return f, nil
}
genCalculator 内部实现了一个匿名函数,作为结果值返回
4. 什么是自由变量?作用是什么?
自由变量 是一个低阶函数,这个低阶函数是从外部传入的,如何实现由外部决定。
作用是 动态地生成部分程序逻辑, 再根据需要生成功能不同的函数。
5. 传入函数的那些参数值,被修改后,原值会发生变化吗?
值类型比如数组的话,不会。
引用类型比如切片、字典、通道的话,会。
七、结构体及其方法的使用法门
1. 什么叫嵌入字段?
// Category 代表动物分类学中的基本分类法。
type Category struct {family string // 科。species string // 种。
}func (ac Category) String() string {return fmt.Sprintf("%s%s", ac.family, ac.species)
}type Animal struct {name string // 名字。Category // 分类。
}
上面结构体 Animal 的 Category 字段就是嵌入字段,也叫匿名字段,没有声明名称,它既是类型也是名称。
2. 怎样调用嵌入字段的方法?
通过类型变量的名称 Category 后跟 “.”, 这样:
animal := Animal{name: "Shorthair",
}
animal.Category.String()
3. 嵌入字段的方法 会被无条件地 合并进 被嵌入类型的方法集合中.
比如上面 Animal类型变量animal可以直接使用Category变量的方法: animal.String()
4. 如果 嵌入结构体(Category) 和 被嵌入结构体(Animal) 存在相同的方法名字,那么 嵌入结构体(Category) 的方法会被屏蔽。 即外层优先。
5. GO语言没有继承,但是用 嵌入的方式实现了类型之间的组合。(但和继承有差别,且更优)
6. GO的组合,和继承的区别:
(1) 组合 不需要 显式地声明某个类型继承了另一个类型,只需要把类型当做字段嵌入进来。
(2) 组合 可以通过嵌入多个字段来实现功能强大的类型,却不会有多重继承那样复杂的层次结构。
7. 接口类型之间也可以组合,而且更加常见
8. 什么叫 接受者类型 和 接受者名称 ? 如下代码
func (cat *Cat) SetName(name string) {cat.name = name
}
*Cat 叫 接收者类型, cat 叫 接收者名称
9. 什么叫指针方法? 就是 接收者类型是指针类型的方法。 不是指针类型的话,叫做 值方法。
10. 值方法和指针方法的不同点:
(1) 值方法的修改 不会修改 接受者的原值; 但是指针方法的修改 会改变原值。
(2) 值方法集合 和 指针方法集合 两者是不同的。但指针方法集合 包含了 值方法集合
(3) 严格来讲,基本类型的值上只能调用它的值方法。但是,Go 语言会自动转译,使得值上也能调用到指针方法。
(4) 如果基本类型和指针类型的方法集合不同,那么它们实现的接口类型的数量也会有差异。
相关文章:

GO语言核心30讲 进阶技术 (第一部分)
原站地址:Go语言核心36讲_Golang_Go语言-极客时间 一、数组和切片 1. 两者最大的不同:数组的长度是固定的,而切片的长度是可变的。 2. 可以把切片看成是对数组的一层封装,因为每个切片的底层数据结构中,一定会包含一…...

[力扣题解]225. 用队列实现栈
题目:225. 用队列实现栈 思路 用一个队列模拟栈; 假设有数字:1,2,3; pop 队列里是这样的存的:3,2,1; 作为一个栈,应该弹出最后进来的那一个3&…...

Leetcode—2105. 给植物浇水 II【中等】
2024每日刷题(131) Leetcode—2105. 给植物浇水 II 实现代码 class Solution { public:int minimumRefill(vector<int>& plants, int capacityA, int capacityB) {int size plants.size();int i 0;int j size - 1;int capA capacityA;in…...

wordpress外贸建站公司歪建站新版网站上线
wordpress外贸建站公司 歪猫建站 歪猫WordPress外贸建站,专业从事WordPress多语言外贸小语种网站建设与外贸网站海个推广、Google SEO搜索引擎优化等服务。 https://www.waimaoyes.com/dongguan...

关于二手车系统学习--登录模块
1.样式1-17行 <div class="cheader"><div style="width: 80%;margin: 0 auto;line-height: 50px;padding-top: 10px"><el-row><el-col:span="5"style="font-size: 20px;cursor: pointer;color: #00ae66;font-weight: …...

若依生成代码的步骤
1.创建表,要有注释 2.导入表 3.创建主菜单 4.修改表 5.生成代码 6.把代码复制到自己的程序中:复制表、后端、前端 7.重启后端,如果有问题则clean 8.回到浏览器可以看到正常显示了生成的页面...

深度学习论文: LightGlue: Local Feature Matching at Light Speed
深度学习论文: LightGlue: Local Feature Matching at Light Speed LightGlue: Local Feature Matching at Light Speed PDF: https://arxiv.org/pdf/2306.13643 PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://github.com/shanglianlm0525/…...

全面解析C++11与C++20线程(含内容)
昨晚跟一些小伙伴做了第一次直播尝试,一起探讨了C11 thread与 C20的jthread,于此同时给大家出了几个问题,在直播之外不会公布答案,所以以后直播还是得跟着走起。 总共有22人参加直播,氛围相当不错,没有录播…...

【八股】消息中间件
通用MQ问题 使用场景 异步发送(验证码、短信、邮件)MYSQL和Redis,ES之间的数据同步分布式事务削峰填谷消息的重复消费问题 👉定义:消费者已经消费了消息,但是可能由于网络抖动或者消费者挂了导致ack回执没有发送给MQ 👉解决方案 为每条消息设置一个唯一的标识id,在…...

【17-Ⅰ】Head First Java 学习笔记
HeadFirst Java 本人有C语言基础,通过阅读Java廖雪峰网站,简单速成了java,但对其中一些入门概念有所疏漏,阅读本书以弥补。 第一章 Java入门 第二章 面向对象 第三章 变量 第四章 方法操作实例变量 第五章 程序实战 第六章 Java…...

weblogic 反序列化 [CVE-2017-10271]
一、漏洞描述 这个漏洞是wls-wsat这个接口出了问题,Weblogic的WLS Security组件对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令。攻击者发送精心构造的…...

CoPilot 产品体验:提升 OpenNJet 的控制管理和服务提供能力
文章目录 前言系统架构介绍CoPilot 配置CoPilot 插件规范 体验 CoPilot 实例CoPilot: Broker 实例CoPilot: Ctrl 实例 开发其他语言编写的 CoPilot目标主要思路具体实现执行 go 程序代码 功能扩展总结 前言 CoPilot 是 OpenNJet 的一个重要组成部分,它在 Master-Wo…...

Leetcode 第396场周赛 问题和解法
问题 有效单词 有效单词需要满足以下几个条件: 至少包含3个字符。 由数字0-9和英文大小写字母组成。(不必包含所有这类字符。) 至少包含一个元音字母。 至少包含一个辅音字母。 给你一个字符串word。如果word是一个有效单词,则…...

OC foudation框架(上)学习
foundation框架 文章目录 foundation框架字符串(NSString && NSMutableString)NSString的其他功能NSMutableString 日期与时间 (NSDate)2.1 日期与时间(NSDate)2.2日期格式器日历与日期组件定时器&…...

【机器学习300问】83、深度学习模型在进行学习时梯度下降算法会面临哪些局部最优问题?
梯度下降算法是一种常用的优化方法,用于最小化损失函数以训练模型。然而,在使用梯度下降算法时,可能会面临以下局部最优问题。 (一)非凸函数的局部极小值 问题描述:在复杂的损失函数中,如果目…...

基于springboot的校园管理系统源码数据库
基于springboot的校园管理系统源码数据库 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,校园管理系统当然也不能排除在外。校园管理系统是以实际运用为开发背景,…...

图形网络的自适应扩散 笔记
1 Title Adaptive Diffusion in Graph Neural Networks(Jialin Zhao、Yuxiao Dong、Ming Ding、Evgeny Kharlamov、Jie Tang)【NIPS 2021】 2 Conclusion The neighborhood size in GDC is manually tuned for each graph by conductin…...

vue基础配置
vite.config.ts import { defineConfig } from vite import vue from vitejs/plugin-vue import path from "path"; //引入svg需要用到的插件 import { createSvgIconsPlugin } from vite-plugin-svg-icons //mock插件提供方法 import { viteMockServe } from vite-…...

C++基础中的存储类别
存储的类别是变量的属性之一,C语言定义了4种变量的存储类别,分别是auto变量、static变量、register变量和extern变量。以下重点介绍这几种类型。 一、auto变量 auto变量是C默认的存储类型。函数内未加存储类型说明的变量均被称为自动变量,即…...

【NPM】Nginx Proxy Manager 一键申请 SSL 证书,自动续期,解决阿里云SSL免费证书每3个月失效问题
文章目录 1、NPM 简介2、实战Step 1:环境搭建 也可以看作者安装笔记 Step 2:创建容器 2.1 在系统任意位置创建一个文件夹,此文档以~/nginx-proxy-manager为例。2.2 创建docker-compose.yaml2.3 启动NPM服务 Step 3:配置反向代理3…...

教你解决PUBG绝地求生游戏中闪退掉线无法重连回去的问题
《绝地求生》(PUBG),作为一款在全球范围内掀起热潮的战术竞技游戏,以其栩栩如生的战场环境和令人心跳加速的生存冒险博得了广大玩家的青睐。然而,一些玩家在经历了一场惊心动魄的对局后,却面临了一个不大不…...

24 Debian如何配置Apache2(4)LAMP+phpMyAdmin部署
作者:网络傅老师 特别提示:未经作者允许,不得转载任何内容。违者必究! Debian如何配置Apache2(4)LAMP+phpMyAdmin部署 《傅老师Debian小知识库系列之24》——原创 ==前言== 傅老师Debian小知识库特点: 1、最小化拆解Debian实用技能; 2、所有操作在VM虚拟机实测完成;…...

centos安装paddlespeech各种报错解决方案
背景 windows系统安装paddlespeech一路顺利 centos安装之前也是正常 今天centos再次安装各种报错,避免以后遇到浪费时间,记录下来,也给大家节约时间 报错 报错1 module numpy has no attribute complex. 解决方案 降低numpy # 1. 卸载当前numpy库 pip uninstall numpy…...

谈基于ATTCK框架的攻击链溯源
引言 网络安全在当今数字化时代变得尤为关键,而MITRE公司开发的ATT&CK框架则成为了安全专业人员的重要工具。ATT&CK是一种广泛使用的攻击行为分类和描述框架。其目的在于提供一个共同的语言,使安全专业人员能够更好地理解攻击者的行为和目标&…...

在Ubuntu下搭建自己的以太坊私有链
最近要对链及链上应用进行压测,为了方便操作及分析问题,就自己搭建了一个eth私链。当前版本安装官方指引发现有卡点,于是决定整理一个文档,为其他有需要的朋友提供便捷操作,节约时间。 一、环境配置 linux操作系统:Ubuntu 20.04.6 LTS (Focal Fossa) go version: go1…...

巩固学习4
python中函数逆置的几种方法 s input()for i in range(len(s)-1,-1,-1):#从最后一位开始,步长为-1print(s[i],end)用for语句循环逆置 s input() s list(s) n len(s) for i in range(n//2):s[i],s[n-1-i] s[n-1-i],s[i]#从中间反转字符串 res "".j…...

Conda安装rasterio报错
Conda安装rasterio报错 文章目录 Conda安装rasterio报错问题解决参考 问题 在conda环境中安装rasterio包之后,本来可以正常运行的,但是之后又重新安装了一个gdal,导致原来的引用rasterio的包的程序不可正常运行了 conda install rasterio c…...

linux安装 mysql
环境:centOS8 一、安装 1 安装wget库 sudo yum -y install wget 2. 安装 mysql 换yum源 亲测成功!!!!!! 换yum源 1.下载对应版本的repo文件 wget -O CentOS-Base.repo http://mirrors…...

暴力法解决最近对问题和凸包问题-实现可视化
目录 最近对问题 凸包问题 最近对问题 顾名思义就是采用蛮力法求出所有点之间的距离,然后进行比较找出第一个最近对,一个一个进行比较。 大概思路就是如图(每个圈代表一个数对) 第一个和其他四个比较 第二个和其他三个比较 …...

[Kubernetes] Rancher 2.7.5 部署 k8s
server: 192.168.66.100 master: 192.168.66.101 node1: 192.168.66.102 文章目录 1.rancher server 安装docker2.部署k8s3.kubeconfig4.测试集群 1.rancher server 安装docker 所有主机开通ipv4 vi /etc/sysctl.conf#加入 net.ipv4.ip_forward 1#配置生效 sysctl -prancher…...