自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(71)
  • 收藏
  • 关注

转载 【转】GO中的select3个特性

原文链接作者:大彬链接:https://segmentfault.com/a/1190000017410112来源:SegmentFault 思否select的三个特性nil的通道永远阻塞当case上读一个通道时,如果这个通道是nil,则该case永远阻塞。这个功能有1个妙用,select通常处理的是多个通道,当某个读通道关闭了,但不想select再继续关注此case,继续处理其他case,把该通道设置为nil即可。下面是一个合并程序等待两个输入通道都关闭后才退出的例子,就使用了这个特性。

2020-07-22 08:29:27 257

转载 【转】Golang并发模型:并发协程的优雅退出

原文链接Golang并发模型:并发协程的优雅退出本文作者:大彬前言goroutine作为Golang并发的核心,我们不仅要关注它们的创建和管理,当然还要关注如何合理的退出这些协程,不(合理)退出不然可能会造成阻塞、panic、程序行为异常、数据结果不正确等问题。goroutine在退出方面,不像线程和进程,不能通过某种手段强制关闭它们,只能等待goroutine主动退出。方法一:使用for-range退出for-range是使用频率很高的结构,常用它来遍历数据,range能够感知chann

2020-07-21 23:46:56 339

原创 【读书笔记二】:RPC和PROTOBUF

前言RPC,远程过程调用,通俗的讲就是调用远程的一个函数;RPC可能会涉及到不同语言的函数,这时候就需要Protobuf来支持多种不同的语言,而且Protobuf本身就很方便描述服务的接口,因此非常适合作为RPC世界的接口交流语言。RPC通过一个的例子来实现简单的Rpc功能// 服务端package mainimport ( "log" "net" "net/rpc")type HelloService struct {}//Go语言的Rpc规则:方法只能有2个可序列化的参

2020-07-16 21:38:07 414

原创 读书笔记【一】:数组、字符串、切片

Go语言的赋值和函数传参规则:除了闭包函数以引用的方式对外部变量访问之外,其他赋值和函数传参都是以传值的方式处理。数组的长度是数组类型的组成部分,不同长度或不同类型的数据组成的数据都是不同的类型,不同长度的数组因为类型不同而无法直接赋值,数组Go语言的数组是值语义。一个数组变量即表示整个数组,它并不是隐式地指向第一个元素的指针,而是一个完整的值。每一次传递或者赋值实际上都是赋值整一个数组,为了避免复制数组带来的开销,可以传递一个指向数组的指针,但是数组指针并不是数组。但是指向不同长度的数组指针的.

2020-07-13 09:35:19 171

原创 Go接口扫盲

Go接口接口嵌入接口,保持深度在0或1为最佳。接口中直接定义的方法数量10个之内最佳参考RuneJava的char类型是UTF-16的code unit,也就是两个字节,字符串是UTF-16 code unit的序列,因此每个字符都是定长的,要想获得某个位置字符,很容易计算出它的字节在字符串中的位置。Go语言使用UTF-8作为字符串的内部编码,因此对于大部分字符串都是ascii字符的情况下,占用的内存空间就会大大减少,但是带来的问题是,从字符串的字节slice中查找第n个字符比较麻烦,因为

2020-07-09 11:45:16 124

原创 modoule

设置代理首先在命令行设置GOPROXY设置代理,多个代理服务器可以用逗号隔开,direct关键字表示直连不适用代理,export GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy,https://goproxy.io,direct然后cd目录到项目根目录执行go mod tidygo modules 模块化管理通过GO1111MODILE环境变量来开启或关闭,默认是autooff\on\auto:关闭,开

2020-07-09 11:42:46 590

原创 【持续更】go语言避免踩坑

slice切片使用之前要判断长度在对slice进行操作时,必须判断长度是否合法,防止程序panic// 使用data前应判断长度是否合法 func decode(data [] byte) bool { if len(data) == 6 { if data[0] == 'F' && data[1] == 'U' && data[2] == 'Z' && data[3] == 'Z' && data[4] == '

2020-07-09 11:42:02 140

原创 Go语言系列(十六):上下文context

背景在 Go http包的Server中,每一个请求在都有一个对应的 goroutine去处理。请求处理函数通常会启动额外的goroutine用来访问后端服务,比如数据库和RPC服务。一个上游服务通常需要访问多个下游服务,比如终端用户的身份认证信息、验证相关的token、请求的截止时间。 当一个请求被取消或超时时,所有用来处理该请求的 goroutine 都应该迅速退出,然后系统才能释放这些 goroutine 占用的资源。传统方案一:使用sync.WaitGroup问题:只有所有的goroutine

2020-07-02 07:04:52 592

原创 Go语言系列(十五):反射reflect

反射的一些基本概念和需要知道的知识Golang语言实现的反射机制就是指在运行时动态的调用对象的方法和属性,官方自带的reflect包就是反射相关的。go的变量包括type, value两部分,type 包括static type和concrete type. (static type是你在编码是看见的类型(如int、string),concrete type是runtime系统看见的类型)。类型断言能否成功,取决于变量的concrete type,而不是static type. 因此,一个 reade

2020-07-01 10:14:16 319

原创 Go中的定时器Timer

前言在go1.14 版本中,首先把存放定时事件的四叉堆放到p结构中,使用netpoll的epoll wait来做就近时间的休眠等待。在每次runtime.schedule调度时都检查运行到期的定时器。大概使用有时候我们会在开发中会使用到time.NewTicker或者time.NewTimer进行定时或者延时的处理,两者的底层实现基本是一样的,我们可以先来看看Timer的大概使用方式import ( "fmt" "time")func main() { timer :=

2020-06-30 11:13:37 650

原创 Go语言中的no copy机制

前言在go语言的源码中,有很多的结构体上面都被注解上了no copy强调no copy的原因是为了安全,因为结构体对象中包含指针对象的话,直接赋值拷贝是浅拷贝,是极不安全的。Go中如何保证no copy2.1 runtime checkingstrings.Builderpackage mainimport "strings"func main() { var testA strings.Builder testA.Write([]byte("a")) testB :=tes

2020-06-29 22:49:05 1495

原创 Go语言:限流算法

前言之前写过java版本的限流算法,最近刚好在学习go语言,那就当作练习,写一下go的限流算法简单计数器// 简单计数器package mainimport ( "fmt" "sync" "time")func main() { service := NewRequestLimitService(time.Second, 2) for true { hasToken := service.AddRequestCount() if hasToken { fmt.Pri

2020-06-29 20:28:54 357

原创 Go语言import一个包但是不调用,那它import干啥子

一开始学习Go的时候,看到如下import _ "xxx/xxx"其实这是调用里面的init方法做一些初始化,注册之类的。例子package mainimport ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" // 导入驱动程序 "time")func main() { dsName := "root:xxxxxx@tcp(127.0.0.1:3306)/resk?charset=utf8&par

2020-06-23 20:30:00 576

原创 框架设计:基础公共资源starter管理

前言如果系统中基础公共资源比较多,并且每个基础资源都有自己特定的构造和初始化,启动方法,有些简单有些复杂,有些基础公共资源之间还可能存在依赖,所以就要设计基础资源管理程序来管理基础资源的启动过程。基础资源上下文结构体首先定义一个基础资源上下文结构体,用于管理基础资源启动过程上下文依赖资源的传递,(结构化设计和编程实例),定义一个启动器接口,抽象和定义了各种资源加载和启动的阶段,各种基础资源实现这个启动器接口,完成资源自身的启动逻辑// 资源启动器,每个应用都少不了依赖其他资源,比如数据库,缓存,

2020-06-23 16:31:53 171

原创 Go语言中channel有关的知识点

channel容量为0和为1的区别容量为1的channel是有缓冲channel的特殊情况,可以用在2个goroutine之间同步状态,或者其中一个等待另一个完成时才继续执行任务的情况。无缓存的channel的容量始终为0,发送者发送数据和接受者接受数据时同时的,无任何中间态,不能缓冲任何数据。容量为1的channel是可以缓冲1个数据,发送者和接受者之间可以不同时进行,可以发送者可以先把数据放进去,接受者可以过会儿再读取数据。无缓存的 channel 的发送者和接受者是相互等待,发送者等待接受者准

2020-06-23 15:12:35 626

原创 goland中报错: Unresolved reference 错误解决

前言今天早上项目导入的包标红了,而且也包了unresolved reference的错误,但是程序却可以正常运行,在网上找了多种方法,最后可以了,但是并不知道是哪一个起了作用,但是把试过的都记录整理下来。方法一把这个勾上方法二在file的invalidate caches...

2020-06-23 09:46:39 13083

原创 Go语言踩坑:源代码import的是文件路径,而调用的时候使用的是包名

import 后面跟的是相对文件夹路径(非文件路径)包名是golang文件中package后面的字符,但包导入后使用的是包名非路径文件夹名称文件名称在golang中仅仅是文件名称,没有编码含义

2020-06-22 09:26:00 1103

原创 关于接口的几个要注意的点

调用函数时的隐式转换Go 语言中的函数调用都是值传递的,变量会在方法调用前进行类型转换。import ( "fmt")// 类型转换为interface类型func printType(i interface{}) { //Go把传入函数的参数值的类型隐式的转换成 interface{} 类型。 // interface类型才能进行类型断言 switch i.(type) { case int: fmt.Println("参数的类型是 int")

2020-06-19 17:54:10 193

原创 用Go 写一个简易版单机爬虫

前言爬虫一般是一个递归过程,每一种类型的页面应该配置一个不同的解析器,从一个种子页面开始爬取,然后把爬取到的信息进行处理,这个页面的其他url放入一个任务队列里面排队,并附加一个对应的解析器。package enginetype Request struct { Url string ParserFunc func([]byte) ParseResult // 处理url的函数}// 任务队列requests 接下来可以递归的url和解析器// items 获取的值ty

2020-06-16 10:04:53 248

翻译 Go中的一些有用的模式

参考文章pattern装饰器(Decorator)Authenticate(http.HandlerFunc(w http.ResponseWriter,r *http.Request){ // Code here})一个简单的Authenticate实现:func Authenticate(h http.Handler) http.Handler { return http.HandlerFunc(w http.ResponseWriter,r *http.Request){ if

2020-06-15 16:13:45 168

原创 Go语言系列(十四) :struct{}和struct{}{}

struct{} 和 struct{}{}一般我们知道struct在Go语言中是用于定义结构类型type User struct { Name string Age int}而struct {}是一个无元素的结构体类型,通常在没有信息存储时使用。优点是大小为0,不需要内存来存储struct {}类型的值。struct {} {}是一个复合字面量,它构造了一个struct {}类型的值,该值也是空。比如我们可以用map[string]struct{}来当作成一个set来用

2020-06-09 20:13:20 3436

原创 Go语言系列(十三):补充一些库知识

http使用http客户端发送请求使用http.Client控制请求头部使用httputil简化工作func main() { resp, err := http.Get("http://www.baidu.com") if err != nil { panic(err) } defer resp.Body.Close() s, err := httputil.DumpResponse(resp, true) if err != nil { panic(err) } f

2020-06-05 15:50:36 423 1

原创 Go语言系列(十二):测试

测试少DEBUG,多Testinggo语言采用表格驱动测试分离的测试数据和测试逻辑明确的出错信息可以部分失败go语言的语法使得我们更容易实践表格驱动测试// 如果要测试add函数,那么文件名就叫做add_test.go// 测试方法名字就叫做TestAddpackage mainimport "testing"func add(a, b int) int { return a + b}func TestAdd(t *testing.T) { tests := [

2020-06-05 12:46:59 544

原创 Go语言系列(十二):复习,写一个迷宫

package mainimport ( "fmt" "os")// 广度遍历// 读取迷宫func readMaze(filename string) [][]int { file, err := os.Open(filename) if err != nil { panic(err) //这里先不做处理 } var row, col int // 行 列 fmt.Fscanf(file, "%d %d ", &row,

2020-06-04 22:09:35 292

原创 ProtoBuf

简介Protocol Buffer(Protobuf): 轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或PRC数据交换格式。可用于通讯协议,数据存储等领域的语言无关,平台无关,可扩展的序列化结构数据格式。可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。如何工作首先需要一个.proto文件中定义需要串行化的数据结构信息。每个ProtocolBuffer信息是一小段逻辑记录,包含一系列的键值对。在protobuf术语中,结构化数据被称为Mes

2020-06-04 20:55:22 198

原创 Go语言系列(十一):channel

channel不要通过共享内存来通信,要通过通信来共享内存channel是用来协程通信的错误做法package mainimport "fmt"func chanDemo() { // var c chan int // chan 通道里面是int类型 c == nil c := make(chan int) // 这里定义没有缓存,所以接收到一个他就会阻塞的到这个值被取走 c <- 1 // 把 1 送到c中 c <- 2 c <- 3 n:= &

2020-06-04 10:06:15 301

原创 Go语言系列(十):Goroutine

Goroutine协程,轻量级线程非抢占式多任务处理,由协程主动交出控制权,go1.14版本之后,也支持抢占式切换,在并发系统中,对goroutine的切换时机和运行结果就没有唯一的保证性。在go语言中,我们采用channel来进行goroutine之间的通信,能更容易的保证结果的一致性编译器/解释器/虚拟机/go语言(有自己的调度器)层面的多任务,不是系统的多个协程可以在一个或多个线程上面运行go run -race xx.go -race查看是否有数据访问冲突//func ma

2020-06-03 18:11:42 171

原创 Go语言系列(九):错误处理和资源管理

defer调用确保调用在函数结束时执行参数在调用defer语句时计算,然后押入栈中func tryDefer() { for i := 0; i < 30; i++ { defer fmt.Println(i) //29 //28 //27 //26 //.... //1 //0 }}defer列表是一个栈结构,后进先出,func tryDefer() { defer fmt.Println(3) defer fmt.Println(2)

2020-06-03 15:54:41 181

原创 Go语言系列(八):函数式编程

函数式编程闭包闭包 = 匿名函数 + 自由变量的引用

2020-06-03 09:30:55 327

原创 Go语言系列(七):接口

接口// 主函数package mainimport ( "fmt" "learn2/test")// 返回接口类型func getRetriever() retriever { return test.Retriever{} //由使用者来定义这个结构体是不是实现了retriever接口,而test.Retriever{}本身并没有和retriever有任何的关系}// 接口 接口的作用就是// something can Gettype retriever interfa

2020-06-03 08:42:28 192

原创 Go标准库系列(五):sort排序

3.1 sort —— 排序算法该包实现了四种基本排序算法:插入排序、归并排序、堆排序和快速排序。 但是这四种排序方法是不公开的,它们只被用于 sort 包内部使用。所以在对数据集合排序时不必考虑应当选择哪一种排序方法,只要实现了 sort.Interface 定义的三个方法:获取数据集合长度的 Len() 方法、比较两个元素大小的 Less() 方法和交换两个元素位置的 Swap() 方法,就可以顺利对数据集合进行排序。sort 包会根据实际数据自动选择高效的排序算法。 除此之外,为了方便对常用数据类.

2020-06-02 21:36:32 225

原创 Go系列(六):面向对象

结构体和方法go语言仅支持封装,不支持继承和多态go语言没有class 只有structgo语言没有构造函数的说法结构创建在堆上还是栈上? 不需要知道在调用的时候,编译器很聪明的,要值还是指针,编译器会帮我们转换package mainimport "fmt"type treeNode struct { value int left, right *treeNode}// 给结构定义方法// (node treeNode):接受者 这个参数也是传值// 和普通

2020-06-02 19:19:50 112

原创 Go标准库系列(四):基本的IO 接口

Reader接口type Reader interface { Read(p []byte) (n int, err error)}Read 将len(p)个字节读取到 p 中。它返回读取的字节数n(0 <= n <= len§)以及任何遇到的错误。即使 Read 返回的 n < len§,它也会在调用过程中占用 len§ 个字节作为暂存空间。若可读取的数据不到 len§ 个字节,Read 会返回可用数据,而不是等待更多数据。当 Read 在成功读取 n > 0 个

2020-06-02 19:19:28 608

原创 go标准库系列(三):strconv包转换

strconv包定义了两个error类型变量ErrRange:表示值超过了类型能表示的最大范围ErrSyntax:表示语法错误字符串转为整形// base 指定进制, 如果base为0,按照字符串的前缀来判断什么类型的进制// bitSite 整数取值范围, 0,8,16 int,int8 int 16func ParseInt(s string, base int bitSize int) (i int64, err error)func ParseUint(s string, b.

2020-06-02 13:04:40 148

原创 Go标准库系列(二):bytes

func Contains(b, subslice []byte) boolfunc Count(s , sep []byte) intfunc Rune(s []byte) []runeReader 类型type Reader struct { s []byte i int64 //当前读取的下标 prevRune int // 前一个字符的下标 可能<0}func NewReader(b []byte) *Reader//读取r的数据至bfunc (r *Reader

2020-06-02 11:38:34 138

原创 go系列(五):内建容器

数组func main() { //数组的定义方式 //[0,0,0] var nums1 [3]int nums2 := [3]int{1, 2, 3} // 如果要让编译器判断我们有几个元素,要用... 没有...是切片 nums3 := [...]int{3, 4, 5} fmt.Println(nums1, nums3, nums2) // 遍历方式 // 第一种 for i:=0;i<len(nums3);i++{ fmt.Println(nums3[i])

2020-06-02 10:19:25 149

原创 Go系列(三):接口

接口Go语言中接口类型的独特之处在于它是满足隐式实现的。我们没有必要对于给定的具体类型定义所要满足的接口类型;简单地拥有一些必需的方法就足够了。这种设计可以让你创建一个新的接口类型满足已经存在的具体类型却不会去改变这些类型的定义。当我们使用的类型来自于不受我们控制的包时这种设计时尤其有用。接口约定具体类型:一个具体类型可以准确的描述它所代表的值,并且展示出对类型本身的一些操作方式。抽象类型: 接口类型就是一种抽象类型。他不会暴露出它所代表的对象的内部值的结构和这个对象支持的基础操作的集合。他

2020-06-01 21:58:29 172

原创 Go系列(零):Go基础

Go语言入门Go是一门编译型语言,Go语言的工具链将源代码及其依赖转换成计算机的机器指令Go语言提供的工具都通过一个单独的命令go调用,go命令有一系列子命令。go run helloworld.go # run指令,编译源文件,链接库文件,并允许最终生产的可执行文件go build helloworld.go # build指令,生成名为helloworld的可执行的二进制文件go get gopl.io/ch1/helloworld # get指令,可以从网上获取代码,并放到对应目录

2020-06-01 21:57:56 427

原创 Go标准库系列(一):字符串 strings

字符串比较// 比较大小, // a > b 1// a < b -1// a = b 0func Compare(a, b string) int// 忽略大小写后是否相等func EqualFold(s,t string) bool是否存在某个字符或子串// 子串substr 是否在s中func Contains(s, substr string) bool// chars 中任何一个 unicode 代码点在 s 中,返回truefunc ContainsAny(

2020-06-01 21:39:17 178

原创 Go系列(一):Go基础

常量、变量package mainimport "fmt"// var可以放在函数内,或直接放在包里// var a, b, c bool// var a, b string = "hello", "word"//使用var()集中定义变量// := 定义变量,只能用在函数里面// 可以不写类型 编译器可以自动辨认类型 cc = "string"var ( aa = 1 bb = 3 cc = "string")func variableZero() { var a

2020-06-01 21:05:04 220

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除