golang

Golang设计模式-单例模式

為{幸葍}努か 提交于 2020-02-27 15:10:37
Golang单例模式实现 go语言做开始的必然是并发业务,所谓的单例模式也必须加锁否则会不断生成新的实例,不加锁的部分就不写了. 直接记录几个能用的到的单例模式,由浅入深. 懒汉加锁模式 package pattern import "sync" type singleton struct{} var instance *singleton var mu sync.Mutex //获取实例 func GetInstance() *singleton { //这种结构的单例模式,会导致每次都加锁,严重浪费性能 mu.Lock() defer mu.Unlock() if instance == nil { instance = &singleton{} } return instance } 懒汉双重锁检测模式 package pattern import "sync" //单例模式 type singleton struct{} var instance *singleton var mu sync.Mutex //获取实例 func GetInstance() *singleton { //不会导致每次都加锁,因为率先判断了随后才加的锁 //如果没有被实例化 if instance == nil { //加锁 mu.Lock() //实例化返回,并解锁 defer mu

32.从上到下打印二叉树

筅森魡賤 提交于 2020-02-27 13:39:12
其实就是二叉树的层次遍历,用队列来实现。我想说的是像队列,栈这两种数据结构在golang里面真的很方便,直接拿着slice上手就是天生的栈和队列,这也许就是golang并没有实现自己的栈和队列的原因吧。 要注意的是,假如某个节点为nil,就不要加入队列中了,刚开始因为这个原因给我报异常了 代码如下: 来源: CSDN 作者: qq_40058686 链接: https://blog.csdn.net/qq_40058686/article/details/104531790

GRPC搭建: Golang篇

血红的双手。 提交于 2020-02-27 11:41:48
一. Protobuffer 搭建篇 1. 下载golang版的protobuf 国内墙等的问题, 直接访问github下载即可 https://github.com/golang/protobuf 2. 编译 (1) 下载好之后解压 (2) 解压后使用命令行跳到protobuf的路径下 (3) 命令行输入 go build ./protoc-gen-go, 等待编译, 一小会之后, 到protoc-gen-go目录查看, 便会看到protoc-gen-go.exe (4) 将编译好的protoc-gen-go.exe 放到之前备好的protoc.exe同目录下, 即可使用protoc.exe --go_out=. ./xx.proto (5) 最后一步也是极其重要的一步, 将库放到gopath下, 在生成的文件发现 import (proto "github.com/golang/protobuf/proto"), 所以不将protobuf的go源文件放到对应gopath的路径下, 使用时将出现引用查找不到的问题, 路径参考 “xxx/src/github.com/golang” Note: 没有事先准备好protoc.exe的朋友自行下载 https://github.com/protocolbuffers/protobuf/releases 二. Grpc搭建篇 1.

GoLang的包

不羁岁月 提交于 2020-02-27 00:30:02
包 1、原理 2、概念 go的每一个文件都是属于一个包的,也就是说go是以包的形式来管理文件和项目目录结构的 3、作用 区分相同名字的函数、变量等标识符 当程序文件很多时,可以很好的管理项目 控制函数、变量等访问范围,即作用域 4、打包和引包 4.1、打包 import 包名 4.2、引包 import "包的路径" 5、注意事项 在给一个文件打包时,该包对应一个文件夹,比如这里的utils文件夹对应的包名就是utils,文件的包名通常和文件所在的文件夹名一致,一般为小写字母。 当一个文件要使用其它包函数或变量时,需要先引入对应的包 // 方式一 import "包名" // 方式二 // // import ( "包1", "包2" ) package指令在文件第一行,然后是import指令 在import包时,路径从 $GOPATH 的 src 下开始,不用带src,编译器会自动从src下开始引入 为了让其它包的文件,可以访问到本包的成员,则该 成员名的首字母需要大写 ,类似其它语言的public,这样才能跨包访问 在访问其它包函数,变量时,其语法是包名.函数名 如果包名较长,Go支持给包取别名,注意细节:取别名后,原来的包名就不能使用了 import 别名 "包路径" 如果你要编译成一个可执行程序文件,就需要将这个包声明为main,即 package main

golang实现冒泡排序算法

本小妞迷上赌 提交于 2020-02-26 16:30:38
package alg //冒泡排序 func Bubbling(arr []int) []int { len := len(arr) if len <= 1 { return arr } for i := 0; i < len; i++ { //提前退出冒泡循环的标志位 flag := false //len-i-1 减去已经排好序,不用再循环无畏的值 for j := 0; j < len-i-1; j++ { //交换值 if arr[j] > arr[j+1] { tmp := arr[j] arr[j] = arr[j+1] arr[j+1] = tmp //标识符 flag = true } } if !flag { break; } } return arr } 来源: oschina 链接: https://my.oschina.net/hackdebug/blog/3158298

golang json解码编码总结

旧巷老猫 提交于 2020-02-26 15:18:57
已知需要编码解码类型的 1.编码 json.NewEncoder ( < Writer > ) .encode ( v ) json.Marshal ( & v ) 2.解码 json.NewDecoder ( < Reader > ) .decode ( & v ) json.Unmarshal ( [ ] byte, & v ) 使用示例 package main import ( "encoding/json" "fmt" "bytes" "strings" ) type Person struct { Name string ` json: "name" ` Age int ` json: "age" ` } func main ( ) { // 1. 使用 json.Marshal 编码 person1 : = Person { "张三" , 24 } bytes1, err : = json.Marshal ( & person1 ) if err == nil { // 返回的是字节数组 [ ] byte fmt.Println ( "json.Marshal 编码结果: " , string ( bytes1 )) } // 2. 使用 json.Unmarshal 解码 str : = ` { "name" : "李四" , "age" :25 } ` //

Golang之变量去哪儿

蹲街弑〆低调 提交于 2020-02-26 07:30:36
目录 什么是逃逸分析 为什么要逃逸分析 逃逸分析是怎么完成的 逃逸分析实例 总结 参考资料 写过C/C++的同学都知道,调用著名的malloc和new函数可以在堆上分配一块内存,这块内存的使用和销毁的责任都在程序员。一不小心,就会发生内存泄露,搞得胆战心惊。 切换到Golang后,基本不会担心内存泄露了。虽然也有new函数,但是使用new函数得到的内存不一定就在堆上。堆和栈的区别对程序员“模糊化”了,当然这一切都是Go编译器在背后帮我们完成的。 一个变量是在堆上分配,还是在栈上分配,是经过编译器的 逃逸分析 之后得出的结论。 这篇文章,就将带领大家一起去探索 逃逸分析 ——变量到底去哪儿,堆还是栈? 什么是逃逸分析 以前写C/C++代码时,为了提高效率,常常将 pass-by-value (传值)“升级”成 pass-by-reference ,企图避免构造函数的运行,并且直接返回一个指针。 你一定还记得,这里隐藏了一个很大的坑:在函数内部定义了一个局部变量,然后返回这个局部变量的地址(指针)。这些局部变量是在栈上分配的(静态内存分配),一旦函数执行完毕,变量占据的内存会被销毁,任何对这个返回值作的动作(如解引用),都将扰乱程序的运行,甚至导致程序直接崩溃。比如下面的这段代码: int *foo ( void ) { int t = 3; return &t; }

golang调试工具Delve

拈花ヽ惹草 提交于 2020-02-26 05:43:33
 Devle是一个非常棒的golang 调试工具,支持多种调试方式,直接运行调试,或者attach到一个正在运行中的golang程序,进行调试。   线上golang服务出现问题时,Devle是必不少的在线调试工具,如果使用docker,也可以把Devle打进docker镜像里,调试代码。 安装Devle 安装Devle非常简单,直接运行 go get 即可: go get -u github.com/derekparker/delve/cmd/dlv   如果你的go版本为1.5请先设置环境变量GO15VENDOREXPERIMENT=1再运行go get。我的go版本为1.10,不用设置。 使用Devle调试golang服务   先写一个简单的web服务,然后使用Devle来进行调试。   在$GOPATH/src/github.com/mytest 文件夹下创建main.go package main import ( "fmt" "log" "net/http" "os" ) const port = "8000" func main() { http.HandleFunc("/hi", hi) fmt.Println("runing on port: " + port) log.Fatal(http.ListenAndServe(":" + port, nil)) }

[golang] 数据结构-鸡尾酒排序

醉酒当歌 提交于 2020-02-26 05:05:21
吐个槽 又是一个不正经取名的排序算法。真要说和鸡尾酒间的关系,大概就是想喝到鸡尾酒(得到排序好的队列)就要摇晃酒杯让不同的成分混合均匀(向两个方向冒泡排序) 原理 鸡尾酒排序(Cocktail Sort)是 冒泡排序 的一种优化算法。原本的冒泡排序只能在一轮中挑出一个值移动到最后,而鸡尾酒则可以在一轮里挑最大的移到最后,再挑最小的移到最前面。实际上就是先正向进行一轮普通的冒泡排序,然后再逆向进行一轮反向冒泡,每轮冒泡都缩小一点范围。 复杂度 最好情况是正序排列的数列O(n),最坏情况是逆序O(n^2),平均还是O(n^2)。空间复杂度都是O(1)。 排序过程 特别找来一张图,方便理解。注意看图中红色标记的元素,每次向右都是把最大的元素交换到后面,向左都是把最小的交换到前面。 代码 package main import ( "time" "fmt" "math/rand" ) func main() { var length = 10 var list []int // 以时间戳为种子生成随机数,保证每次运行数据不重复 r := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < length; i++ { list = append(list, int(r.Intn(1000))) } fmt

Golang http post error : http: ContentLength=355 with Body length 0

纵饮孤独 提交于 2020-02-26 05:05:16
参考: https://stackoverflow.com/questions/31337891/net-http-http-contentlength-222-with-body-length-0 问题阐述:在使用 golang http 包发送 post 请求时出现报错,类似 http: ContentLength=355 with Body length 0。大意是 ConlentLength 设置了一定长度,但是在读取 Body 时,发现 Body 中没有内容。 问题说明: func Post(URL string, form url.Values, cl *http.Client) ([]byte, error) { body := form.Encode() // req, err := http.newRequest("POST", URL, strings.NewReader(body)) //执行报错ContentLength=355 with Body length 0 for i := 0; i < 10; i++ { req, err := http.NewRequest("POST", URL, strings.NewReader(body)) //执行正确 if err != nil { log.Error(err) return nil, err }