go编程基础
学习笔记666
这个作者很懒,什么都没留下…
展开
-
并发安全和锁
有时候在Go代码中可能会存在多个goroutine同时操作一个资源,这种情况会发生数据竞态问题。举例:var x int64var wg sync.WaitGroupfunc add() { for i := 0; i < 5000; i++ { x = x + 1 } wg.Done()}func main() { wg.Add(2) go add() go add() wg.Wait() fmt.Println(x)}上面的代码中开启了 2 个gorout原创 2021-03-21 13:15:16 · 443 阅读 · 0 评论 -
select多路复用
在某些场景下我们需要同时从多个通道接收数据。通道在接收数据时,如果没有数据可以接收发生阻塞。你也许会写出代码使用遍历的方式来实现:for { //尝试从ch1接收值 data,ok := <-ch1 //尝试从ch2接收值 data,ok := <-ch2}这种方式虽然可以实现从多个channel接收值的需求,但是运行性能会差很多。为了应对这种场景,Go内置了select关键字,可以同时响应多个通道的操作。select的使用类似于switch语句,它有一些列case分支和一个原创 2021-03-19 14:41:50 · 548 阅读 · 0 评论 -
go协程池
编写代码实现了一个计算随机数的每个位置数字之和的程序,要求使用goroutine和channel构建生产者和消费者模式,可以指定启动的goroutine数量-woker pool模式。在工作中我们通常使用workerpool模式,控制goroutine的数量,防止goroutine泄露和暴涨。一个简易的workerpool示例代码如下:package mainimport ( "fmt" "time")func worker(id int, jobs <-chan int, res原创 2021-03-19 14:19:23 · 457 阅读 · 0 评论 -
多协程执行收集结果
##多协程执行收集结果1、先假设有一个比较耗时的任务//假设有一个比较耗时的任务func job(index int) int { //模拟耗时,延迟500毫秒 time.Sleep(time.Millisecond * 500) return index}2、使用非协程的方式,看看需要多少时间func main() { //记录当前时间 start := time.Now() //假设这个工作需要 5 次 num := 5 for i := 0; i < num; i原创 2021-03-15 17:10:39 · 266 阅读 · 0 评论 -
Go在MacOS上打包成Win 及 Linux运行文件
打包命令CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.goCGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.gowin的会打包成.exe文件,win下面直接运行即可原创 2020-05-20 15:54:53 · 1740 阅读 · 1 评论 -
gorm:结合Model进行数据映射
0、有这样一张表CREATE TABLE `news_category` ( `category_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `category_name` varchar(255) DEFAULT NULL, `category_remark` varchar(255) DEFAULT NULL, PRIMARY ...原创 2019-08-28 09:02:15 · 2190 阅读 · 1 评论 -
Gorm入手、执行原始SQL
1、安装//安装mysql驱动go get -u github.com/go-sql-driver/mysql//安装gorm库go get -u github.com/jinzhu/gorm2、连接mysqlpackage mainimport ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jinzhu/go...原创 2019-08-25 17:41:18 · 4793 阅读 · 0 评论 -
go的包依赖管理(1): go.mod文件、简单使用
随便cd到一个目录(英文路径)下执行:go mod init mytest 然后用编辑器打开这个目录。可以看到一个go.mod文件。然后创建core/functions.go文件,代码如下:package coreimport "fmt"func ShowName() { fmt.Println("我的名字叫张三")}可以看出在functions.go中写了一个函数。...原创 2019-08-21 18:37:44 · 827 阅读 · 0 评论 -
创建一个最简单的mysql代理
先介绍一个开源第三方库关于go module 环境:export GO111MODULE=onexport GOPROXY=https://goproxy.io/在go module 环境下go get -u github.com/siddontang/go-mysql注意:这不是一个纯mysql驱动,而是包含了mysql协议解析、复制(mysql replication)和类似j...原创 2019-08-22 11:45:30 · 403 阅读 · 0 评论 -
Gin框架速学:内置验证器的初步使用
准备1、创建model/NewsModel.go文件:package model//新闻模型定义type NewsModel struct { //新闻id Id int `json:"id"` //新闻标题 Title string `json:"title"` //新闻内容 Content string `json:"content"` //作者 Author str...原创 2019-08-25 11:54:34 · 1505 阅读 · 0 评论 -
简易FailOver机制: 普通轮询算法下的计数器机制(上)
https://blog.csdn.net/github_26672553/article/details/99764970在上面实现了简单服务器健康检查机制。设置服务状态为up或down。之前说了,不能一次检查没有通过就设为down,所以需要有个计数器机制。来简单粗暴的实现一下:1、定期向url发送http请求,根据接口响应码和响应时间判断2、每个server计数器为03、如果异常,...原创 2019-08-20 23:05:59 · 233 阅读 · 0 评论 -
负载均衡算法:轮训算法的简单实现
所谓的轮询,就是挨个访问。//负载均衡类type LoadBalance struct{ Servers []*HttpServer //指向当前访问的服务器 CurIndex int //添加这个变量}轮询算法实现://轮询算法func (this *LoadBalance) RoundRobin() *HttpServer { server := this.Servers...原创 2019-08-20 21:58:15 · 457 阅读 · 0 评论 -
Gin框架速学:创建Model、参数绑定Model的初步使用
创建Model1、创建model/bbsModel.go文件,代码如下:package modeltype bbs struct { Id int //帖子id Title string //帖子标题}//创建帖子模型func CreateBBSModel(id int, title string) bbs { return bbs{Id:id,Title:title}}...原创 2019-08-25 08:26:55 · 1550 阅读 · 0 评论 -
Gin框架速学:简单Dao层代码封装、使用中间件模拟"用户认证"
简单的Dao层代码封装创建dao/bbsDao.go文件,里面代码如下:package daoimport ( "github.com/gin-gonic/gin")//获取某一帖子详细func GetBBSDetail(context *gin.Context) { context.String(200, "获取id=%s的帖子", context.Param("id"))...原创 2019-08-24 21:59:07 · 1622 阅读 · 0 评论 -
Gin框架速学:路由分组
/v1/bbs?user=zhangsan/v1/bbs/12通过之前这个2路由地址,可以发现它们具有相同部分/v1/bbs可以分到一个路由组里,下面看gin框架如何实现: //路由分组 routerV1 := router.Group("/v1/bbs") // /v1/bbs routerV1.GET("", func(context *gin.Context) { if...原创 2019-08-24 18:55:34 · 608 阅读 · 0 评论 -
随机算法 实现 负载均衡
需求:实现一个最简单的负载均衡(均衡算法采用随机算法)。具体实现:前端用户访问localhost:8080,通过反向代理随机分配到localhost:9091或lcalhost:9092。1、确保启动这2个(或多个)9091、9092web服务实现代码查看:https://blog.csdn.net/github_26672553/article/details/991650652、前...原创 2019-08-18 10:26:29 · 307 阅读 · 0 评论 -
负载均衡算法之ip_hash简单应用
1、前面用go实现了一个超级简单的负载均衡。采用的均衡算法是“随机”。https://blog.csdn.net/github_26672553/article/details/99701928主要代码: rand.Seed(time.Now().UnixNano()) //设置随机因子,精确到纳秒 index := rand.Intn(len(this.Servers)) return...原创 2019-08-18 11:46:05 · 718 阅读 · 0 评论 -
Context上下文包套路入门(1)
context包被称为上下文包,go 1.7加入,用于协程之间的上下文数据的传递、中止核控制超时。在网络编程中可用于请求的中止,比如服务访问链的中止:a用户注册->b调用用户服务->c调用积分服务。其中a调用b,b调用c。如果由于a和b之间因为某些原因被取消或者超时了,那么b和c之间也要取消。Context接口源码解读:type Context interface{ //返回...原创 2019-09-01 10:34:35 · 435 阅读 · 0 评论 -
RPC入门(2):JSONRPC使用、使用PHP调用
https://blog.csdn.net/github_26672553/article/details/100172819之前介绍的方式只适合go系统和go系统之间调用(因为它数据编码使用了go的gob编码格式)。想要其他异构系统(比如php)调用,就需要使用通用的编码格式,比如JSON。1、jsonrpc服务端代码: jsonrpc.ServeConn(client)一句就搞定...原创 2019-08-31 17:26:05 · 1688 阅读 · 0 评论 -
go自带的rpc包
包:net/rpc1、基于tcp且使用socket,所以必须创建socket服务端l, err := net.Listen("tcp",":8080")2、创建一个struct,基本规则如下:方法可导出(首字母大写);方法有2个参数,都是可导出类型或内建类型;方法的第二个参数是指针类型,第一个参数是接收的参数,第二个参数是返回的参数(客户端得到的值);函数有error返回typ...原创 2019-08-31 14:50:06 · 749 阅读 · 0 评论 -
协程通信:认识channel
有一个函数,做累加计算,如:func sum(max int) { result := 0 //从1累加到max for i := 1; i <= max; i++ { result = result + i } //最后打印结果 fmt.Println(result);}调用这个函数:func main() { sum(100); //5050}go的协...原创 2019-08-31 13:14:19 · 21651 阅读 · 0 评论 -
入手redis第三方库
官网:https://github.com/gomodule/redigo安装:go get github.com/gomodule/redigo/redis文档地址:https://godoc.org/github.com/gomodule/redigo/redis#pkg-examples1、简单封装redis连接客户端新建src/MyRedis.go:package src...原创 2019-08-31 09:43:21 · 653 阅读 · 0 评论 -
gorm:数据库连接池
连接池http://gorm.io/docs/generic_interface.html// 设置空闲连接池中的最大连接数db.DB().SetMaxIdleConns(10)// 设置到数据库的最大打开连接数db.DB().SetMaxOpenConns(100)// 设置可重用连接的最大时间量db.DB().SetConnMaxLifetime(time.Hour)改造...原创 2019-08-28 21:25:48 · 10136 阅读 · 0 评论 -
gorm:新增数据、封装DB初步、结合Gin实现查询API
新增数据 db, _ := gorm.Open("mysql", "root:root@/test?charset=utf8mb4&parseTime=True&loc=Local") defer db.Close() // 打开日志日志,查看执行的sql db.LogMode(true) // 新增数据 news := model.NewsModel{Title:"...原创 2019-08-28 14:21:24 · 1441 阅读 · 0 评论 -
mysql代理:创建自己的Handler处理类、支持查询数据返回
回顾https://blog.csdn.net/github_26672553/article/details/100011650在前面使用第三方库,创建了简单的msyql代理服务。我们可以:mysql -h127.0.0.1 -P4000 -uroot -p就连接上了。创建自己的Handlerconn, _ := server.NewConn(c, "root", "", server...原创 2019-08-22 22:31:48 · 212 阅读 · 0 评论 -
负载均衡算法之加权随机算法的简单实现
1、我们在前面写过“随机算法”来实现简单的负载均衡。https://blog.csdn.net/github_26672553/article/details/99701928用过nginx配置负载均衡,可能会写过类似这样的配置:upstream lb { server xxxxxx1 weight=1 server xxxxxx2 weight=2}这表示server1和serv...原创 2019-08-18 15:41:13 · 719 阅读 · 0 评论 -
Gin框架速学:API的URL规则设计、带参数的路由
比如我们要这样的路由地址/v1/bbs?user=zhangsan/v1/bbs/12gin框架实现代码如下: router.GET("/v1/bbs", func(context *gin.Context) { if context.Query("user") == "" { context.String(200,"获取帖子列表") }else { context....原创 2019-08-24 18:41:47 · 1355 阅读 · 0 评论 -
Gin框架速学:开发环境、最简单的服务启动
官网地址:https://github.com/gin-gonic/gin准备:1、在任意路径下(不要有中文)创建api.go.com/live2、cd到api.go.com/livego mod init live.go.com#其实这里叫 go mod init xxx 都行3、然后执行:go get -u github.com/gin-gonic/gin等下载完成,用编...原创 2019-08-24 17:15:57 · 960 阅读 · 0 评论 -
mysql调用(4): 查询返回通用map(字典)、可变参数用法
// 取出所有列 cols,_ := rows.Columns() // 定义所有行的大切片 allRows := make([]interface{},0) // 定义单独一行大小切片 oneRow := make([]interface{},len(cols)) scanRow := make([]interface{},len(cols)) for rows.Next(...原创 2019-06-09 20:15:05 · 1147 阅读 · 0 评论 -
mysql调用(3): 查询返回通用数组、空接口使用、类型断言、range
1、什么是空接口type all interface {}任何类型都可以是空接口var i all = UserModel{}var i all = 123var i all = "abc"如果不给它赋值,它里面每一项都是一个nil。var i interface{} = "hello"fmt.Println(i) // 打印:hello把它弄成切片var list ...原创 2019-06-09 18:37:23 · 326 阅读 · 0 评论 -
mysql调用(2):入门slice切片、查询返回实体集合
我们知道数组长度一旦定义就不能改变。所以我们今天需要另外一个数据类型:slice1、定义一个结构体// 定义一个结构type UserModel struct { Name string Age int}2、主要代码// 定义一个UserModel类型的切片 users := []UserModel{} // for循环 for rows.Next() { // ...原创 2019-06-09 18:06:53 · 1931 阅读 · 0 评论 -
集成mysql驱动、调用数据库、查询数据
1、安装第三方mysql驱动包go get -u github.com/go-sql-driver/mysql2、连接数据库基本代码package mainimport ( _"github.com/go-sql-driver/mysql" // 注意前面的下划线_, 这种方式引入包只执行包的初始化函数 "database/sql" "fmt")func main() ...原创 2019-06-09 17:45:02 · 183 阅读 · 0 评论 -
go-使用第三方包 json化结构体
前提条件:安装好操作系统对应的gitgo get -u github.com/pquerna/ffjson-u参数:如果本地已经存在该包,则强制更新。1、既然是把结构体转为json字符串,那么先来定义一个结构体// 定义一个结构体type NewsModel struct { Id int Title string}2、且看ffjson这包用什么方法来把结构体转为json字符...原创 2019-06-09 17:00:28 · 735 阅读 · 0 评论 -
2、Go的类型和变量
既然导入多个包可以简写,那么声明多个常量、全局变量或一般类型(非接口、非结构)是否也可以用同样的方式简写呢?// 常量定义const ( PI = 3.14 const1 = "1" const2 = 2)// 一般类型声明type ( newType int type1 float32 type2 string type3 byte)// 全局变量的声明与赋值v...原创 2018-12-01 22:13:32 · 215 阅读 · 0 评论 -
1、Go基础知识
Go程序是通过package来组织的(与Python类似)只有package名称为main的包可以包含mian()函数一个可执行程序有且仅有一个main包// 当前程序包名package mainimport "fmt"// 常量的定义const PI = 3.14// 全局变量的声明和赋值var name = "goer"// 一般类型的声明type newTy...原创 2018-12-01 20:48:50 · 166 阅读 · 0 评论 -
6、Go的Slice
其本身不是数组,指向底层的数组;作为变长数组的替代方案,可以关联底层数组的局部或全部;引用类型;可以直接创建或从底层数组获取生成;使用len()获取元素个数,cap()获取容量一般使用make()创建;如果多个slice指向相同的底层数组,其中一个值的改变会影响全部。 a := [5]int{1,2,3,4,5} fmt.Println(a) // [1 2 3 4 5] s1...原创 2018-12-04 22:16:40 · 206 阅读 · 0 评论 -
4、Go控制语句
指针Go虽然保留了指针,但和其他编程语言不同,在Go当中不支持指针运算以及->运算符,而直接采用.选择符来操作指针目标对象的成员。操作符&取变量地址,使用*通过指针间接访问目标对象。默认值为nil而非NUll。package mainimport "fmt"func main() { a := 1 var p *int = &a fmt.Println...原创 2018-12-02 21:33:59 · 217 阅读 · 0 评论 -
5、Go的数组
定义数组的格式:var <varName> [n] <type>数组长度也是类型的一部分,因此具有不同长度的数组为不同类型;注意区分指向数组的指针和指针数组;数组在Go中为值类型;数组之间可以使用==或!=进行比较,但不可以使用<或>;可以使用new来创建数组,此方法返回一个指向数组的指针。 // 定义数组a var a[2]int // 定义数...原创 2018-12-04 21:31:40 · 190 阅读 · 0 评论 -
协程通信之认识channel、阻塞
channel类型这是go里面的核心数据类型,有了它我们可以方便的进行协程间数据通信。其原理来源于csp模型理论,go实现了部分理论。简单说,csp模型由并发执行的实体(如进程或线程)组成,实体之间通过发消息进行通信,其中channel承担了实体和实体之间发送消息的通道。在go里面goroutine就是实体,它里面也有个channel来完成通信。// 定义一个函数func sum(num...原创 2019-06-10 21:48:28 · 2256 阅读 · 0 评论 -
创建最简单的Socket服务端和客户端代码
1、服务端代码package mainimport ( "fmt" "net")func main() { // 创建监听 listener,err := net.Listen("tcp","127.0.0.1:9111") if err!=nil { fmt.Println(err) return } defer listener.Close() fmt.P...原创 2019-06-30 09:05:38 · 1078 阅读 · 1 评论