
Go语言
Go语言基础知识
晴空~
又菜又爱玩!
展开
-
Go语言实现生产者消费者问题
生产者消费者模式某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。单单抽象出生产者和消费者,还够不上是生产者/消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。利用生产者消费者模式,设计一个简单的问题并通过编程解决。利用goroutine和channel实现一个计算int64随机数各位和的程序生产原创 2021-02-20 22:27:31 · 462 阅读 · 0 评论 -
Go语言实现读者写者问题
Go语言sync中内置了读写锁可以很简单的实现读者写者问题。读者写者是一个非常著名的同步问题。读者写者问题描述非常简单,有几个写者与很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件。package mainimport ( "fmt" "sync" "time")var ( x int wg sync.WaitGroup rwLock sync.RWMutex)func write() { defer wg原创 2021-02-20 22:11:45 · 247 阅读 · 1 评论 -
Go语言资源互斥——互斥锁/读写互斥锁/sync.Once()/atomic/sync.Map
sync包互斥锁互斥锁是一种常见的控制资源访问的方法,它可以保证同时只有一个goroutine可以访问临界资源。Go语言中可以使用sync包的Mutex类型来实现互斥锁。例:// 开启多个gorourtine执行add()操作,会导致两个goroutine读取到相同的x导致最终结果偏小var x = 0var wg sync.WaitGroupfunc add() { defer wg.Done() for i := 0; i < 5000; i++{ x += 1 }}原创 2021-02-20 22:04:41 · 436 阅读 · 1 评论 -
Go语言Select多路复用
Select多路复用在某些场景下,需要同时从多个通道接收数据。数据在接收数据时,如果没有数据可以接收将会发生阻塞。为了应对这种场景,Go内置了select关键字,可以同时相应多个通道的操作。select的使用类似于switch语句,其有一列case分支和一个默认分支。每一个case会对应一个通道的通信过程。select会一直等待,知道某个case的通信操作完成,就会执行case分支对应的语句。select{ case <- ch1: ... case data := <- ch原创 2021-02-20 22:01:39 · 801 阅读 · 0 评论 -
Go语言channel
channel单纯将函数并发是没有意义的.函数与函数间需要交换数据才能体现并发执行的意义.共享内存进行数据交换会导致goroutine发生竞态问题.为了保证数据交换的正确性,必须使用互斥量对内存进行加锁,这种做法势必会导致行呢个问题.Go语言的并发模型是CSP(Communicating Sequential Process),提倡通过通信共享内存而不是通过共享内存而实现通信.如果说goroutine是Go程序并发的执行体,channel就是它们之间的连接.channel是一个可以让一个gorout原创 2021-02-20 22:00:25 · 26512 阅读 · 0 评论 -
Go语言goroutine并发编程
启动多个goroutine在Go语言中实现并发只需要go关键字,就可以启动多个goroutine。// 使用sync.WaitGroup实现goroutine的同步func hello(i int){ defer wg.Done() // goroutine结束就登记-1 fmt.Println("Hello Goroutine!", i)}func main(){ for i := 0; i < 10; i++{ wg.Add(1) // 启动原创 2021-02-20 21:57:13 · 130 阅读 · 0 评论 -
Go语言goroutine与GMP模型
并行与并发并发:同一时段内执行多个任务并行:同一时刻执行多个任务Go语言并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,可以根据需要创建成千上万个goroutine并发工作。goroutine由Go语言的运行时(runtime)调度完成,而线程由操作系统调度完成。Go语言提供channel在多个goroutine进行通信。goroutine和channel是Go语言秉承的CSP(Communicating Sequential Process)并发模式的重要实现基础。原创 2021-02-20 21:52:42 · 264 阅读 · 0 评论 -
Go语言反射
反射反射是指在程序运行过程中对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身信息。支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口的访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改他们。Go语言程序在运行期使用reflect包访问程序的反射信息。使用:空接口可以存储任意类型的变量,通过反射在运行时动态获取一个变量的类型信息和原创 2021-02-15 12:19:08 · 216 阅读 · 0 评论 -
Go文件实现文件内容插入
在文件的中间部分插入内容由于Go语言不支持原生的在文件中插入数据(实际所有语言都不支持),在此采用的方案是新建一个file.tmp临时文件,先将要插入位置前的内容写到临时文件中,再将插入内容写入临时文件,最后将插入位置后的内容写入临时文件。操作完成后,删除旧文件,重命名临时文件为之前文件名。package mainimport ( "bufio" "fmt" "io" "io/ioutil" "os")func fileInsertInfo(){ // 打开要操作的文件 os.O原创 2021-01-29 20:30:34 · 1123 阅读 · 1 评论 -
Go语言实现简易学生管理系统
学生管理系统本程序是为了联系Go语言前期知识,包括常量、变量、结构体、文件调用等。StudentManage.go负责学生管理系统功能的实现package mainimport "fmt"// 学生信息管理系统// 1. 保存数据 --> 结构体字段// 2. 三个功能 --> 结构体方法type student struct { id int64 name string}type studentManager struct { allStudent map[原创 2021-01-29 20:29:59 · 604 阅读 · 0 评论 -
Go语言文件读写
文件读写文件读按字节读,每读读指定的字节file, err := os.Open()打开指定路径的文件defer file.Close()关闭文件var tmp = make([]byte, 128)创建字节缓冲区,用于读取文件内容n, err := file.Read(tmp[:]) 读取文件内容,n为当前读取的字节数// 打开文件fileObj, err := os.Open("./fileOperation/fileOperation.go")if err != nil{原创 2021-01-29 20:30:56 · 259 阅读 · 1 评论 -
Go语言接口
接口接口是一种类型,规定了变量的方法不关心变量的类型,只关心其调用的方法接口定义type 接口名 interface{ 方法名1(参数1,参数2,参数3...)(返回值...) 方法名2(参数1,参数2,参数3...)(返回值...) ...}用来给变量\参数\返回值\设置类型接口的实现:一个变量如果实现了接口中规定的所有方法,那么这个变量就实现了这个接口,可以称为这个接口的变量。只要实现了接口中的所有方法,就实现了这个接口接口类型变量接口类型变量原创 2021-01-25 21:33:32 · 72 阅读 · 0 评论 -
Go语言结构体
结构体定义结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。type struct_variable_type struct { member definition member definition ... member definition}定义与初始化type Books struct { title string author string原创 2021-01-25 21:32:35 · 388 阅读 · 0 评论 -
Go语言函数
函数函数定义func 函数名(参数...)(返回值){ 函数体}// 命名返回值func sum(x int, y int) (ret int){ ret = x + y return}// 无命名返回值func sum(x int, y int) int{ return x + y}// 多个返回值func fun() (int, string){ return 1, "haha"}// 参数类型简写// 参数类型连续时,只写最后一原创 2021-01-25 21:31:19 · 130 阅读 · 0 评论 -
Go语言指针
指针声明指针,一个指针变量指向了一个值的内存地址。var var_name *var-type指针使用流程定义指针变量为指针变量赋值访问指针变量中指向地址的值new()为指针变量申请内存var *a int // 报错,此时a为nil,无法执行下一句var a = new(int) // 使用new直接为指针a分配内存*a = 10fmt.Println(*a)make()make也用于内存分配,区别于new,只用于slice、map、chan的内存创建原创 2021-01-25 21:28:51 · 104 阅读 · 0 评论 -
Go语言切片
切片Go 语言切片是对数组的抽象。Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大定义var identifier []typevar slice1 []type = make([]type, len)slice1 := make([]type, len)使用make定义切片make([]T, length, capacity)切片的长原创 2021-01-25 21:27:05 · 133 阅读 · 0 评论 -
Go语言Map
Map无序的key-value数据结构,map是引用类型,必须初始化才能使用map[keyType]valueType声明var price map[string]intprice = make(map[string]int, 10)price["Chinese"] = 18price["English"] = 20fmt.Println(price)使用value, ok := price["Math"]if !ok{ fmt.Println("查无次key")原创 2021-01-25 21:24:31 · 84 阅读 · 0 评论 -
Go语言Array数组
Array数组声明var variable_name [SIZE] variable_type初始化(默认为零值)指定大小var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}自动推导var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}部分赋值(使用索引初始化)var balance = [5]float32{1.0, 2.0}数组的长度和类型是数组类原创 2021-01-25 21:23:00 · 136 阅读 · 0 评论 -
Go语言条件判断
条件语句if条件判断// if条件判断if 布尔表达式1 { /*布尔表达式1为true时执行*/} else if 布尔表达式2 { /*布尔表达式2为true时执行*/} else { /*以上条件都不满则时执行*/}switch条件判断case支持多条件匹配不同的case之间不适用break分割,默认只使用一个case使用fallthrough强制执行该条语句下面的所有语句,也可使用break终止// switch条件判断switch var1 {原创 2021-01-25 21:19:58 · 511 阅读 · 0 评论 -
Go语言变量与常量
Go语言变量与常量Go语言变量// 常规声明var identifier type // 类型推导var name = "Tom"// 省略 var, 注意 := 左侧如果没有声明新的变量,就产生编译错误// 使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明。age := 18// _抛弃符(匿名变量)// 匿名变量不会占用命名空间,不会分配内存,所以匿名变量之间不会存在重复声明问题Go语言原创 2021-01-25 21:17:40 · 124 阅读 · 0 评论 -
Go语言命令行编译与执行
Go语言编译编译使用go build在项目目录下执行go build在其他路径下执行go build,需要在后面加上项目的路径(项目路径从GOPATH/src后开始写起,编译之后的可执行文件就保存在当前目录下)go build -o hello.exe执行go run:像执行脚本文件一样执行go代码go install先编译得到一个可执行文件将可执行问价拷贝到GOPSTH/bincmd交叉编译SET CGO_ENABLE=0 // 禁用goSET GOOS=原创 2021-01-25 21:14:26 · 943 阅读 · 0 评论