<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/github_26672553</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; github_26672553]]></copyright><item><title><![CDATA[并发安全和锁]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/115048054</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/115048054</guid><author>github_26672553</author><pubDate>Sun, 21 Mar 2021 13:15:16 +0800</pubDate><description><![CDATA[有时候在Go代码中可能会存在多个goroutine同时操作一个资源，这种情况会发生数据竞态问题。
举例：
var x int64
var wg sync.WaitGroup

func add() {
	for i := 0; i &lt; 5000; i++ {
		x = x + 1
	}
	wg.Done()
}

func main() {
	wg.Add(2)
	go add()
	go add()
	wg.Wait()
	fmt.Println(x)
}

上面的代码中开启了 2 个gorout]]></description><category></category></item><item><title><![CDATA[select多路复用]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/115006162</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/115006162</guid><author>github_26672553</author><pubDate>Fri, 19 Mar 2021 14:41:50 +0800</pubDate><description><![CDATA[在某些场景下我们需要同时从多个通道接收数据。通道在接收数据时，如果没有数据可以接收发生阻塞。
你也许会写出代码使用遍历的方式来实现：
for {
	//尝试从ch1接收值
	data,ok := &lt;-ch1
	//尝试从ch2接收值
	data,ok := &lt;-ch2
}

这种方式虽然可以实现从多个channel接收值的需求，但是运行性能会差很多。为了应对这种场景，Go内置了select关键字，可以同时响应多个通道的操作。
select的使用类似于switch语句，它有一些列case分支和一个]]></description><category></category></item><item><title><![CDATA[go协程池]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/115005469</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/115005469</guid><author>github_26672553</author><pubDate>Fri, 19 Mar 2021 14:19:23 +0800</pubDate><description><![CDATA[编写代码实现了一个计算随机数的每个位置数字之和的程序，要求使用goroutine和channel构建生产者和消费者模式，可以指定启动的goroutine数量-woker pool模式。
在工作中我们通常使用workerpool模式，控制goroutine的数量，防止goroutine泄露和暴涨。
一个简易的workerpool示例代码如下：
package main

import (
	"fmt"
	"time"
)

func worker(id int, jobs &lt;-chan int, res]]></description><category></category></item><item><title><![CDATA[多协程执行收集结果]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/114841339</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/114841339</guid><author>github_26672553</author><pubDate>Mon, 15 Mar 2021 17:10:39 +0800</pubDate><description><![CDATA[##多协程执行收集结果
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 &lt; num; i]]></description><category></category></item><item><title><![CDATA[Go在MacOS上打包成Win 及 Linux运行文件]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/106238004</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/106238004</guid><author>github_26672553</author><pubDate>Wed, 20 May 2020 15:54:53 +0800</pubDate><description><![CDATA[打包命令
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go

win的会打包成.exe文件，win下面直接运行即可

]]></description><category></category></item><item><title><![CDATA[Context上下文包套路入门(1)]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100180851</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100180851</guid><author>github_26672553</author><pubDate>Sun, 01 Sep 2019 10:34:35 +0800</pubDate><description><![CDATA[context包被称为上下文包，go 1.7加入，用于协程之间的上下文数据的传递、中止核控制超时。 在网络编程中可用于请求的中止，比如服务访问链的中止：a用户注册-&gt;b调用用户服务-&gt;c调用积分服务。 其中a调用b，b调用c。如果由于a和b之间因为某些原因被取消或者超时了，那么b和c之间也要取消。 Context接口源码解读： type Context interface{ //返回一个超时时间 Deadline()(deadline time.Time, ok bool) //返回只读chan]]></description><category></category></item><item><title><![CDATA[RPC入门(2):JSONRPC使用、使用PHP调用]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100175127</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100175127</guid><author>github_26672553</author><pubDate>Sat, 31 Aug 2019 17:26:05 +0800</pubDate><description><![CDATA[https://blog.youkuaiyun.com/github_26672553/article/details/100172819
之前介绍的方式只适合go系统和go系统之间调用（因为它数据编码使用了go的gob编码格式）。
想要其他异构系统（比如php）调用，就需要使用通用的编码格式，比如JSON。
1、jsonrpc服务端代码：
		jsonrpc.ServeConn(client)

一句就搞定...]]></description><category></category></item><item><title><![CDATA[go自带的rpc包]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100172819</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100172819</guid><author>github_26672553</author><pubDate>Sat, 31 Aug 2019 14:50:06 +0800</pubDate><description><![CDATA[包：net/rpc
1、基于tcp且使用socket，所以必须创建socket服务端
l, err := net.Listen("tcp",":8080")

2、创建一个struct，基本规则如下：
方法可导出（首字母大写）；
方法有2个参数，都是可导出类型或内建类型；
方法的第二个参数是指针类型，第一个参数是接收的参数，第二个参数是返回的参数（客户端得到的值）；
函数有error返回

typ...]]></description><category></category></item><item><title><![CDATA[协程通信：认识channel]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100171768</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100171768</guid><author>github_26672553</author><pubDate>Sat, 31 Aug 2019 13:14:19 +0800</pubDate><description><![CDATA[有一个函数，做累加计算，如：
func sum(max int) {
	result := 0
	//从1累加到max
	for i := 1; i &lt;= max; i++ {
		result = result + i
	}

	//最后打印结果
	fmt.Println(result);
}

调用这个函数：
func main() {
	sum(100); //5050
}

go的协...]]></description><category></category></item><item><title><![CDATA[入手redis第三方库]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100169294</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100169294</guid><author>github_26672553</author><pubDate>Sat, 31 Aug 2019 09:43:21 +0800</pubDate><description><![CDATA[官网：https://github.com/gomodule/redigo
安装：
go get github.com/gomodule/redigo/redis

文档地址：https://godoc.org/github.com/gomodule/redigo/redis#pkg-examples
1、简单封装redis连接客户端
新建src/MyRedis.go：
package src

...]]></description><category></category></item><item><title><![CDATA[gorm：数据库连接池]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100127121</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100127121</guid><author>github_26672553</author><pubDate>Wed, 28 Aug 2019 21:25:48 +0800</pubDate><description><![CDATA[连接池
http://gorm.io/docs/generic_interface.html
// 设置空闲连接池中的最大连接数
db.DB().SetMaxIdleConns(10)

// 设置到数据库的最大打开连接数
db.DB().SetMaxOpenConns(100)

// 设置可重用连接的最大时间量
db.DB().SetConnMaxLifetime(time.Hour)

改造...]]></description><category></category></item><item><title><![CDATA[gorm：新增数据、封装DB初步、结合Gin实现查询API]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100117974</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100117974</guid><author>github_26672553</author><pubDate>Wed, 28 Aug 2019 14:21:24 +0800</pubDate><description><![CDATA[新增数据
	db, _ := gorm.Open("mysql", "root:root@/test?charset=utf8mb4&amp;parseTime=True&amp;loc=Local")
	defer db.Close()
	// 打开日志日志，查看执行的sql
	db.LogMode(true)

	// 新增数据
	news := model.NewsModel{Title:"...]]></description><category></category></item><item><title><![CDATA[gorm：结合Model进行数据映射]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100112073</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100112073</guid><author>github_26672553</author><pubDate>Wed, 28 Aug 2019 09:02:15 +0800</pubDate><description><![CDATA[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 ...]]></description><category></category></item><item><title><![CDATA[Gorm入手、执行原始SQL]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100065576</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100065576</guid><author>github_26672553</author><pubDate>Sun, 25 Aug 2019 17:41:18 +0800</pubDate><description><![CDATA[1、安装
//安装mysql驱动
go get -u github.com/go-sql-driver/mysql
//安装gorm库
go get -u github.com/jinzhu/gorm

2、连接mysql
package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/go...]]></description><category></category></item><item><title><![CDATA[Gin框架速学：内置验证器的初步使用]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100061405</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100061405</guid><author>github_26672553</author><pubDate>Sun, 25 Aug 2019 11:54:34 +0800</pubDate><description><![CDATA[准备
1、创建model/NewsModel.go文件：
package model

//新闻模型定义
type NewsModel struct {
	//新闻id
	Id int	`json:"id"`
	//新闻标题
	Title string `json:"title"`
	//新闻内容
	Content string `json:"content"`
	//作者
	Author str...]]></description><category></category></item><item><title><![CDATA[Gin框架速学：创建Model、参数绑定Model的初步使用]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100059683</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100059683</guid><author>github_26672553</author><pubDate>Sun, 25 Aug 2019 08:26:55 +0800</pubDate><description><![CDATA[创建Model
1、创建model/bbsModel.go文件，代码如下：
package model

type bbs struct {
	Id int	//帖子id
	Title string	//帖子标题
}

//创建帖子模型
func CreateBBSModel(id int, title string) bbs  {
	return bbs{Id:id,Title:title}
}...]]></description><category></category></item><item><title><![CDATA[Gin框架速学：简单Dao层代码封装、使用中间件模拟"用户认证"]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100057437</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100057437</guid><author>github_26672553</author><pubDate>Sat, 24 Aug 2019 21:59:07 +0800</pubDate><description><![CDATA[简单的Dao层代码封装
创建dao/bbsDao.go文件，里面代码如下：
package dao

import (
	"github.com/gin-gonic/gin"
)

//获取某一帖子详细
func GetBBSDetail(context *gin.Context) {
	context.String(200, "获取id=%s的帖子", context.Param("id"))
...]]></description><category></category></item><item><title><![CDATA[Gin框架速学：路由分组]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100056055</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100056055</guid><author>github_26672553</author><pubDate>Sat, 24 Aug 2019 18:55:34 +0800</pubDate><description><![CDATA[/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...]]></description><category></category></item><item><title><![CDATA[Gin框架速学：API的URL规则设计、带参数的路由]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100055932</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100055932</guid><author>github_26672553</author><pubDate>Sat, 24 Aug 2019 18:41:47 +0800</pubDate><description><![CDATA[比如我们要这样的路由地址
/v1/bbs?user=zhangsan
/v1/bbs/12

gin框架实现代码如下：
	router.GET("/v1/bbs", func(context *gin.Context) {
		if context.Query("user") == "" {
			context.String(200,"获取帖子列表")
		}else {
			context....]]></description><category></category></item><item><title><![CDATA[Gin框架速学：开发环境、最简单的服务启动]]></title><link>https://blog.youkuaiyun.com/github_26672553/article/details/100053125</link><guid>https://blog.youkuaiyun.com/github_26672553/article/details/100053125</guid><author>github_26672553</author><pubDate>Sat, 24 Aug 2019 17:15:57 +0800</pubDate><description><![CDATA[官网地址：
https://github.com/gin-gonic/gin
准备：
1、在任意路径下（不要有中文）创建api.go.com/live
2、cd到api.go.com/live
go mod init live.go.com
#其实这里叫 go mod init xxx 都行

3、然后执行：
go get -u github.com/gin-gonic/gin

等下载完成，用编...]]></description><category></category></item></channel></rss>