golang 基础 泛型编程

(一) 示例1

package _caseimport "fmt"// 定义用户类型的结构体
type user struct {ID   int64Name stringAge  uint8
}// 定义地址类型的结构体
type address struct {ID       intProvince stringCity     string
}// 集合转列表函数,接受一个 map,返回一个切片
func mapToList[k comparable, T any](mp map[k]T) []T {// 创建切片,长度与 map 的长度相同list := make([]T, len(mp))var i intfor _, data := range mp {list[i] = datai++}return list
}// 打印通道内容的函数,接受一个通道并打印通道中的每一个数据
func myPrintln[T any](ch chan T) {for data := range ch {fmt.Println(data)}
}// 主函数,执行类型转换和打印
func TTypeCase() {// 创建一个用户类型的 mapuserMp := make(map[int64]user, 0)// 向 map 中添加用户数据userMp[1] = user{ID: 1, Name: "heheda", Age: 18}userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}userMp[3] = user{ID: 3, Name: "Tom", Age: 22}// 将用户 map 转换为用户列表userList := mapToList[int64, user](userMp)// 创建用户类型的通道,并启动 goroutine 打印通道数据ch := make(chan user)go myPrintln(ch)// 将用户列表中的数据发送到通道for _, u := range userList {ch <- u}close(ch)// 创建一个地址类型的 mapaddrMp := make(map[int64]address, 0)// 向 map 中添加地址数据addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}// 将地址 map 转换为地址列表addrList := mapToList[int64, address](addrMp)// 创建地址类型的通道,并启动 goroutine 打印通道数据ch1 := make(chan address)go myPrintln(ch1)// 将地址列表中的数据发送到通道for _, addr := range addrList {ch1 <- addr}close(ch1)
}// 泛型切片的定义
type List[T any] []T// 泛型 map 的定义
// 声明两个泛型,分别为 k 、 v
type MapT[k comparable, v any] map[k]v// 泛型通道的定义
type Chan[T any] chan Tfunc TTypeCase1() {// map[int64]user -> MapT[int64, user]userMp := make(MapT[int64, user], 0)userMp[1] = user{ID: 1, Name: "heheda", Age: 18}userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}userMp[3] = user{ID: 3, Name: "Tom", Age: 22}var userList List[user]userList = mapToList[int64, user](userMp)ch := make(Chan[user])go myPrintln(ch)for _, u := range userList {ch <- u}close(ch)// map[int64]address -> MapT[int64, address]addrMp := make(MapT[int64, address], 0)addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}var addrList List[address]addrList = mapToList[int64, address](addrMp)ch1 := make(Chan[address])go myPrintln(ch1)for _, addr := range addrList {ch1 <- addr}close(ch1)
}

这段代码展示了如何使用 Go 语言中的泛型、结构体和通道进行数据处理和打印。以下是对代码各部分的解释:

1.包和导入

package _caseimport "fmt"
  • 导入 fmt 包用于格式化输入输出

 2.结构体定义

  • user 结构体 有三个字段:ID(类型 int64)、Name(类型 string)和 Age(类型 uint8)
  • address 结构体 有三个字段:ID(类型 int)、Province(类型 string)和 City(类型 string)

 3.泛型函数

func mapToList[k comparable, T any](mp map[k]T) []T {list := make([]T, len(mp))var i intfor _, data := range mp {list[i] = datai++}return list
}
  • mapToList 是一个泛型函数,它接受一个 map 类型的参数 mp,并将其转换为切片(列表)
  • 这里使用了两个泛型类型参数:k(可比较类型)和 T(任意类型)

4.打印通道内容的泛型函数

func myPrintln[T any](ch chan T) {for data := range ch {fmt.Println(data)}
}
  • myPrintln 是一个泛型函数,接受一个通道类型的参数 ch,并打印通道中的每一个数据

5.主函数 TTypeCase

func TTypeCase() {userMp := make(map[int64]user, 0)userMp[1] = user{ID: 1, Name: "heheda", Age: 18}userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}userMp[3] = user{ID: 3, Name: "Tom", Age: 22}userList := mapToList[int64, user](userMp)ch := make(chan user)go myPrintln(ch)for _, u := range userList {ch <- u}close(ch)addrMp := make(map[int64]address, 0)addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}addrList := mapToList[int64, address](addrMp)ch1 := make(chan address)go myPrintln(ch1)for _, addr := range addrList {ch1 <- addr}close(ch1)
}
  • 这个函数首先创建两个 map 分别存储用户和地址数据
  • 使用 mapToList 将 map 转换为列表(切片)
  • 创建通道并启动 goroutine 打印通道数据
  • 将列表中的数据写入通道并关闭通道

 6.型类型

  • 定义三个新的泛型类型:ListMapT 和 Chan
type List[T any] []T
type MapT[k comparable, v any] map[k]v
type Chan[T any] chan T

7.另一主函数 TTypeCase1

func TTypeCase1() {// map[int64]user -> MapT[int64, user]userMp := make(MapT[int64, user], 0)userMp[1] = user{ID: 1, Name: "heheda", Age: 18}userMp[2] = user{ID: 2, Name: "Jerry", Age: 20}userMp[3] = user{ID: 3, Name: "Tom", Age: 22}var userList List[user]userList = mapToList[int64, user](userMp)ch := make(Chan[user])go myPrintln(ch)for _, u := range userList {ch <- u}close(ch)// map[int64]address -> MapT[int64, address]addrMp := make(MapT[int64, address], 0)addrMp[1] = address{ID: 1, Province: "湖南", City: "长沙"}addrMp[2] = address{ID: 2, Province: "广东", City: "揭阳"}var addrList List[address]addrList = mapToList[int64, address](addrMp)ch1 := make(Chan[address])go myPrintln(ch1)for _, addr := range addrList {ch1 <- addr}close(ch1)
}
  • TTypeCase1 函数与 TTypeCase 类似,但使用了自定义的泛型类型 MapT 和 List

相关知识点

  • 泛型 泛型允许函数和数据结构定义中使用类型参数,从而提升代码的复用性
  • 结构体 结构体是 Go 中用于将多个字段组合成一个单一类型的数据结构
  • 通道(Channel)通道是在 goroutine 之间传递数据的管道,可以同步或者异步
  • goroutine goroutine 是 Go 中轻量级的线程,用于并发编程
  • map map 是一种内建的数据结构,用于存储键值对

可以尝试运行和修改代码,进一步理解这些概念。

(二) 示例2

package _caseimport "fmt"// 定义接口 ToString,有一个 String() 方法
type ToString interface {String() string
}// user 结构体实现 ToString 接口
func (u user) String() string {return fmt.Sprintf("ID: %d,Name: %s,Age: %d", u.ID, u.Name, u.Age)
}// address 结构体实现 ToString 接口
func (addr address) String() string {return fmt.Sprintf("ID: %d,Province: %s,City: %s", addr.ID, addr.Province, addr.City)
}// 定义泛型接口 GetKey,要求实现 Get() 方法返回类型 T
type GetKey[T comparable] interface {anyGet() T
}// user 结构体实现 GetKey 接口,Get() 返回 ID
func (u user) Get() int64 {return u.ID
}// address 结构体实现 GetKey 接口,Get() 返回 ID
func (addr address) Get() int {return addr.ID
}// 泛型函数 listToMap,将列表转换为 map
func listToMap[k comparable, T GetKey[k]](list []T) map[k]T {mp := make(map[k]T, len(list)) // 创建 map,长度为列表长度for _, data := range list {mp[data.Get()] = data // 使用 Get() 方法获取键}return mp
}// 主函数,演示列表转 map 的操作
func InterfaceCase() {// 创建 user 列表,元素实现了 GetKey[int64] 接口userList := []GetKey[int64]{user{ID: 1, Name: "张三", Age: 18},user{ID: 2, Name: "李四", Age: 19},}// 创建 address 列表,元素实现了 GetKey[int] 接口addrList := []GetKey[int]{address{ID: 1, Province: "广东", City: "揭阳"},address{ID: 2, Province: "湖南", City: "长沙"},}// 将 user 列表转换为 map,并打印结果userMp := listToMap[int64, GetKey[int64]](userList)fmt.Println(userMp)// 将 address 列表转换为 map,并打印结果addrMp := listToMap[int, GetKey[int]](addrList)fmt.Println(addrMp)
}

 1.包和导入

package _caseimport "fmt"

 导入 fmt 包用于格式化输入输出。

2.定义基本接口

type ToString interface {String() string
}

3.实现 ToString 接口

func (u user) String() string {return fmt.Sprintf("ID: %d,Name: %s,Age: %d", u.ID, u.Name, u.Age)
}func (addr address) String() string {return fmt.Sprintf("ID: %d,Province: %s,City: %s", addr.ID, addr.Province, addr.City)
}
  • user 和 address 结构体实现了 ToString 接口的 String 方法,返回结构体的字符串表示。

 4.定义泛型接口

type GetKey[T comparable] interface {anyGet() T
}

这是一个泛型接口声明。具体来说,GetKey 接口接受一个类型参数 T,这个类型参数必须是一个可比较的类型 (comparable)

(1)定义泛型接口

type GetKey[T comparable] interface {
  • GetKey 定义了一个泛型接口。
  • T 是一个类型参数,它必须是一个可比较的类型 (comparable)。可比较类型表示可以使用 == 和 != 运算符进行比较,常见的可比较类型包括整数、浮点数、字符串以及指针等。

(2)嵌入 any 接口

  • Go 1.18 引入了类型集合 any,它是 interface{} 的别名,表示任意类型
  • 在接口中嵌入 any 意味着该接口可以接受任何类型的实现

(3)定义方法

Get() T
  • 定义了一个方法 Get,这个方法返回类型 T
  • 因为 T 是一个类型参数,所以 Get 方法的返回值类型是泛型的,可以是任意 T 类型

5.实现 GetKey 接口

func (u user) Get() int64 {return u.ID
}func (addr address) Get() int {return addr.ID
}
  • user 和 address 结构体实现了 GetKey 接口的 Get 方法,分别返回结构体的 ID 字段
  • user 实现了 GetKey[int64] 接口,而 address 实现了 GetKey[int] 接口

 6.列表转集合函数

func listToMap[k comparable, T GetKey[k]](list []T) map[k]T {mp := make(MapT[k, T], len(list))for _, data := range list {mp[data.Get()] = data}return mp
}
  • listToMap 是一个泛型函数,将 list 转换为 map
  • 函数参数 k 为键的类型,T 为实现 GetKey[k] 接口的类型
  • data.Get() 返回键,作为 map 的键

 7.主函数 InterfaceCase

func InterfaceCase() {userList := []GetKey[int64]{user{ID: 1, Name: "张三", Age: 18},user{ID: 2, Name: "李四", Age: 19},}addrList := []GetKey[int]{address{ID: 1, Province: "广东", City: "揭阳"},address{ID: 2, Province: "湖南", City: "长沙"},}userMp := listToMap[int64, GetKey[int64]](userList)fmt.Println(userMp)addrMp := listToMap[int, GetKey[int]](addrList)fmt.Println(addrMp)
}
  • 创建 userList 和 addrList,分别包含 user 和 address 结构体
  • 调用 listToMap 将列表转换为 map,并打印结果

>>分解解读

(1)创建 user 结构体实例

user{ID: 1, Name: "张三", Age: 18},
user{ID: 2, Name: "李四", Age: 19},
  • user{ID: 1, Name: "张三", Age: 18} 创建一个 user 实例,ID 为 1,名字为 "张三",年龄为 18
  • user{ID: 2, Name: "李四", Age: 19} 创建一个 user 实例,ID 为 2,名字为 "李四",年龄为 19

 (2)实现 GetKey[int64] 接口

  • 上述 user 结构体实现了 GetKey[int64] 接口,因为 user 结构体定义了 Get() 方法,并且返回值类型为 int64

 (3)创建并初始化切片

userList := []GetKey[int64]{user{ID: 1, Name: "张三", Age: 18},user{ID: 2, Name: "李四", Age: 19},
}
  • 使用两个 user 实例来初始化一个切片 (slice)。
  • 该切片的类型是 []GetKey[int64],表示这个切片包含实现了 GetKey[int64] 接口的元素。

(4)作用

  • 创建并初始化一个包含多个 user 实例的切片,让这个切片可以作为 GetKey[int64] 接口的实现来传递和使用。
  • 这样的设计允许切片中的每个 user 实例都具备 Get 方法,从而可以在后续的泛型函数 listToMap 中使用这些 Get 方法来获取唯一键。

总结

  • GetKey 是一个泛型接口,带有类型参数 T,该参数必须是可比较类型。
  • 该接口要求实现者提供一个 Get 方法,返回类型为 T
  • 这是 Go 1.18 引入的泛型特性,允许编写更通用、更类型安全的代码。

相关知识点

接口 

  • 接口定义了方法集合,任意类型只要实现了这些方法,就实现了该接口

泛型 

  • 泛型允许定义通用的数据结构和函数,提高代码复用性。Go 1.18 开始引入泛型支持
  • 泛型接口和方法通过类型参数进行约束

结构体

  • 结构体是复合数据类型,将相关数据组织在一起

map

  • map 在 Go 中用于存储键值对,是内建的数据结构

导入包

  • fmt 包提供了格式化输入和输出功能,用于打印变量的值

(三)  示例3

package _receiverimport "fmt"// 定义一个泛型结构体 MyStruct
// 该结构体接受一个类型参数 T,T 只能是 *int 或 *string
type MyStruct[T interface{ *int | *string }] struct {Name string // 结构体的名字字段Data T      // 结构体的数据字段,类型为 T
}// 定义 MyStruct 结构体的泛型方法接收器
// GetData 返回结构体中的 Data 字段
func (myStruct MyStruct[T]) GetData() T {return myStruct.Data
}// 主函数,演示 MyStruct 结构体和其方法的使用
func ReceiverCase() {// 定义一个整型变量,并创建 MyStruct 实例data := 18myStruct := MyStruct[*int]{Name: "heheda",Data: &data, // 将整型变量的指针分配给 Data 字段}// 调用 GetData 方法获取 Data 字段的值并打印data1 := myStruct.GetData()fmt.Println(*data1) // 解引用指针打印值,输出 18// 定义一个字符串变量,并创建 MyStruct 实例str := "abcdefg"myStruct1 := MyStruct[*string]{Name: "heheda",Data: &str, // 将字符串变量的指针分配给 Data 字段}// 调用 GetData 方法获取 Data 字段的值并打印str1 := myStruct1.GetData()fmt.Println(*str1) // 解引用指针打印值,输出 "abcdefg"
}

这段代码展示了如何在 Go 语言中使用泛型定义结构体和方法接收器,以下是对代码各部分的解释:

1.包和导入

package _receiverimport "fmt"

导入 fmt 包用于格式化输入输出

2.定义泛型结构体

type MyStruct[T interface{ *int | *string }] struct {Name stringData T
}
  • MyStruct 是一个泛型结构体,结构体内包含两个字段:Name(类型为 string)和 Data(泛型类型 T
  • 这里 T 被约束为 *int 或 *string 类型

 3.定义泛型方法接收器

func (myStruct MyStruct[T]) GetData() T {return myStruct.Data
}
  • GetData 是 MyStruct 的方法,这个方法接受一个泛型类型 T,返回 MyStruct 结构体中的 Data 字段

 4.主函数 ReceiverCase

func ReceiverCase() {data := 18myStruct := MyStruct[*int]{Name: "heheda",Data: &data,}data1 := myStruct.GetData()fmt.Println(*data1)str := "abcdefg"myStruct1 := MyStruct[*string]{Name: "heheda",Data: &str,}str1 := myStruct1.GetData()fmt.Println(*str1)
}
  • 创建一个整型变量 data 并取其指针赋值给 MyStruct 实例 myStruct 的 Data 字段
  • 调用 GetData 方法获取 Data 字段的值并打印
  • 创建一个字符串变量 str 并取其指针赋值给 MyStruct 实例 myStruct1 的 Data 字段
  • 调用 GetData 方法获取 Data 字段的值并打印

相关知识点

(1)泛型

  • 泛型允许定义通用的数据结构和函数,增强代码复用性。Go 1.18 开始引入泛型支持
  • 泛型类型参数通过类型约束进行限制,如本例中的 interface{ *int | *string }

(2)结构体

  • 结构体是一种复合数据类型,可以包含多个字段,允许将相关的数据组织在一起

(3)方法接收器

  • 方法接收器是指与某个类型(如结构体或接口)关联的方法。在本例中,我们定义了 MyStruct 类型的泛型方法接收器 GetData

(4)指针

  • 指针保存了变量的内存地址,在 Go 中,使用 & 符号获取一个变量的指针,使用 * 符号解引用指针获取指针指向的值

(5)导入包

  • fmt 包提供了格式化输入和输出功能,用于打印变量的值

可以尝试运行和修改代码,进一步理解这些概念。

main.go

package mainimport ("context"_case "gomod/genetic-T/case""os""os/signal"
)func main() {_case.TTypeCase()_case.TTypeCase1()_case.InterfaceCase()_receiver.ReceiverCase()ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)defer stop()<-ctx.Done()
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

杰发科技Bootloader(2)—— 基于7840的Keil配置地址

序 在7840的sample代码里面有一个简单的Boot跳转APP的示例 PFlash地址从0开始 DFlash的地址从1000000开始 Boot解析 他的boot地址配置为0 Boot的代码主要是这几行&#xff0c;主要作用就是Flash的跳转 int main(void) {SystemClock_Config();InitDebug();printf("demo…

Leetcode 721.账户合并(hash+dfs)☆

思路&#xff1a; 最核心的地方在于如何合并&#xff1f;这里是通过具有相同的email进行账户的合并&#xff0c;这个相同的email类似于图中的共同节点将两个账户连接起来&#xff0c;所以将原来 账户名 -> 邮件1 邮件2.。。变成hash 邮件1 ->账户id1&#xff0c;账户id2…

ModelArts中sinh算子的开发

一、环境配置 1、创建notebook并连接 使用ModelArts新建一个notebook,我这里镜像选择第一个,里面含有cann和Ascend910处理器,我这里环境只能使用ssh连接,创建一个密钥对,保存到C盘中的user/Administrator/目录下。 在网页中选择使用vscode接入,等待vscode打开后,选择密…

【数据结构初阶】一篇文章带你超深度理解【单链表】

hi &#xff01; 目录 前言&#xff1a; 1、链表的概念和结构 2、单链表&#xff08;Single List&#xff0c;简写SList&#xff09;的实现 2.1 定义链表&#xff08;结点&#xff09;的结构 2.2 创建一个链表 2.3 打印链表 2.4 尾插 2.5 头插 2.6 尾删 2.7 头…

PT2262-IR

PT2262是一款很古老的编码芯片&#xff0c;其兼容型号有&#xff1a;SC2262&#xff0c;AD2262&#xff0c;SC2260(需改变匹配电阻)等。 依据其datasheet&#xff0c;PT2262射频模式工作原理: CODE BITS A Code Bit is the basic component of the encoded waveform, and ca…

Docker核心技术:Docker原理之Cgroups

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Docker核心技术 系列文章&#xff1a;Docker原理之Cgroups&#xff0c;其他文章快捷链接如下&#xff1a; 应用架构演进容器技术要解决哪些问题Docker的基本使用Docker是如何实现的 Docker核心技术&#xff1a;…

Maven学习——Maven的下载、安装与配置(详细攻略!)

目录 前言 1.下载与安装 2.配置Maven的环境变量 3.配置Maven的本地仓库 4. 配置Maven的镜像远程仓库 前言 我在之前写了一篇博客&#xff0c;是介绍Maven的基本概念和下载安装&#xff0c;但是由于篇幅过长&#xff0c;Maven的下载与安装写的并不详细&#x1f436;&#x…

Windows系统设置暂停更新,暂停时间可达3000天,“永久”暂停更新,亲测有效

好多小伙伴被Windows系统的更新搞得很烦&#xff0c;经常在使用中自己下载更新包&#xff0c;占用网路资源&#xff0c;过段时间就要更新&#xff0c;特别讨厌 今天教你一招&#xff0c;可以暂停更新长达3000天&#xff0c;亲测有效 1、打开系统CMD命令执行窗口&#xff0c;输…

Ideal窗口中左右侧栏消失了

不知道大家在工作过程中有没有遇到过此类问题&#xff0c;不论是Maven项目还是Gradle项目&#xff0c;突然发现Ideal窗口右侧图标丢失了&#xff0c;同事今天突然说大象图标不见了&#xff0c;不知道怎样刷新gradle。 不要慌张&#xff0c;下面提供一些解决思路&#xff1a; 1…

超声波俱乐部:AI应用大爆发前夜,场景、闭环与LLM进化

7月13日&#xff0c;第十九期超声波俱乐部内部分享会在北京望京举行&#xff0c;本期的主题是&#xff1a;AI应用大爆发前夜&#xff0c;场景、闭环与LLM进化。 到场的嘉宾有&#xff1a;超声波创始人杨子超&#xff0c;超声波联合创始人、和牛商业创始人刘思雨&#xff0c;豆…

硅纪元视角 | 语音克隆突破:微软VALL-E 2,Deepfake新纪元!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

IP协议和路由转发

文章目录 IP协议IP报头网段划分特殊的IP私有IP和公有IP IP分片 路由 IP协议 IP协议提供了一种能力&#xff0c;将数据报从A主机送到B主机&#xff0c;TCP可以保证可靠性&#xff0c;所以TCP/IP协议可以将数据可靠的从A主机送到B主机。 IP报头 4位版本号(version): 指定IP协议…

Java 面试 | Redis

目录 1. 在项目中缓存是如何使用的&#xff1f;2. 为啥在项目中要用缓存&#xff1f;3. 缓存如果使用不当会造成什么后果&#xff1f;4. redis 和 memcached 有什么区别&#xff1f;5. redis 的线程模型是什么&#xff1f;6. 为什么单线程的 redis 比多线程的 memcached 效率要…

android13禁用某个usb设备

总纲 android13 rom 开发总纲说明 目录 1.前言 2.触摸设备查看 3.功能修改 3.1 禁用usb触摸 3.2 禁用usb键盘 3.3 禁用usb遥感 4.查看生效与否 5.彩蛋 1.前言 用户想要禁止使用某些usb设备,需要系统不能使用相关的usb设备,例如usb触摸屏,usb键盘,usb遥感等等usb…

Unity:PC包直接查看Log日志

PC端会输出Log日志&#xff0c;位置在&#xff1a; C:\Users\用户名\AppData\LocalLow\公司名\项目名 在这里可以找到类似的文件&#xff1a; 打开便可以看到打印。

C++ 设计模式(五)——状态模式

状态模式 序言理解源码 序言 设计模式只是一个抽象的设计模式方法&#xff0c;并不是一个固定使用的搭配&#xff0c;就算是普通switch语句&#xff0c;Map&#xff0c;乃至状态机都是状态模式的其中一种实现方法 状态模式看起来好像和策略模式差不多&#xff0c;主要是其的侧…

10道JVM经典面试题

1、 JVM中&#xff0c;new出来的对象是在哪个区&#xff1f; 2、 说说类加载有哪些步骤&#xff1f; 3、 JMM是什么&#xff1f; 4、 说说JVM内存结构&#xff1f; 5、 MinorGC和FullGC有什么区别&#xff1f; 6、 什么是STW? 7、 什么情况下会发生堆/栈溢出&#xff1f…

来参与“向日葵杯”全国教育仿真技术大赛~

可点击进行了解&#xff1a;“向日葵杯”全国教育仿真技术大赛 (sunmooc.cn) 本次大赛共分为四个赛道&#xff1a;自主命题赛道、教育知识图谱设计赛道、FPGA硬件扑克牌对抗赛道、EasyAR元宇宙空间设计赛道。 参赛对象 &#xff1a; 具有正式学籍的在校研究生&#xff0c;本科…

面试场景题系列--(1)如果系统的 QPS 突然提升 10 倍该怎么设计?--xunznux

1. 如果系统的 QPS 突然提升 10 倍该怎么设计&#xff1f; 1.1 硬件的扩展微服务的拆分 如果所有的业务包括交易系统、会员信息、库存、商品等等都夹杂在一起&#xff0c;当流量一旦起来之后&#xff0c;单体架构的问题就暴露出来了&#xff0c;机器挂了所有的业务就全部无法…

【Mysql】Docker下Mysql8数据备份与恢复

[TOC] 【Mysql】Docker下Mysql8数据备份与恢复 1 创建Mysql容器 格式 docker run -d --name容器名称 -p 宿主端口号:3306 -e MYSQL_ROOT_PASSWORDmysql密码 -e MYSQL_PASSWORDmysql密码 -e TZAsia/Shanghai -v 宿主目录-数据:/var/lib/mysql -v 宿主目录-备份数据:/back…