分类 Go 中的文章

Go源码阅读 | context.Context设计与实现

本文基于 Go1.14.2 Go 自带的 context 包设计的很巧妙,最近阅读了下源码实现,可谓是短小精悍,很值得投入时间去学习。 什么是 context Go1.7 开始引入的 context 标准库包,主要用来在协程之间传递上下文信息,包括:取消信号、超时控制、截止时间、k……

阅读全文

如何借助Go指令生成随机数

如何在 Go 开发中高效而又快速地生成随机数呢?相信大家首先想到的就是使用标准库自带的 math/rand 包,或者使用开源的第三方包(比如 github.com/valyala/fastrand)来实现。 Go 运行时自带了 runtime.fastrand 函数来……

阅读全文

[转]简单围观一下有趣的//go:指令

前言 如果你平时有翻看源码的习惯,你肯定会发现。咦,怎么有的方法上面总是写着 //go: 这类指令呢。他们到底是干嘛用的? 今天我们一同揭开他们的面纱,我将简单给你介绍一下,它们都负责些什么。 go:linkname 1 //go:linkname localname importpath.name 该指令指示编译……

阅读全文

Go源码阅读 | sync.WaitGroup设计与实现

前言 当我们的程序在运行过程中需要执行多个子任务时,我们可以利用 Go 协程并发地执行这些子任务,然后等待它们执行结束,从而缩短程序串行执行的耗费时间。Go 语言标准库自带了该组件:sync.WaitGroup……

阅读全文

Go源码阅读 | sync.Once设计与实现

介绍 sync.Once 是 Go 官方自带的标准库,实现了 exactly once 的功能。通过使用 sync.Once 我们可以很方便地实现单例模式,确保对象只被初始化一次。 首先看一个 sync.Once 的 Go 官方例子,源码链接在这里: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 var once sync.Once onceBody := func() { fmt.Println("Only once") }……

阅读全文

Go中如何实现禁止拷贝

背景 最近看 Go 标准库源码时经常遇到禁止拷贝对象的使用场景,比如当我们使用 strings.Builder 或者 sync.Pool 对象的时候会被禁止拷贝,这是如何实现的呢? 主要有以下两种方式: 方式一:手动检查 这种需要我们在运行时通过 copyCheck 方法来检查是否发生……

阅读全文

Go源码阅读 | strings.Builder设计与实现

背景之字符串拼接 在 Go 语言中,对于字符串的拼接处理有很多种方法,那么那种方法才是效率最高的呢? 1 2 3 4 5 6 str := []string{"aa", "bb", "cc"} ss := "" for _, s := range str { ss += s } fmt.Println(ss) 相信大部分人都会使用+操作符或者fmt.Sprinf进行……

阅读全文

Go Hijack黑科技

最近在看Go标准库里面的rpc源码,发现了下面一段代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // ServeHTTP implements an http.Handler that answers RPC requests. func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { if req.Method != "CONNECT" { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusMethodNotAllowed) io.WriteString(w, "405 must CONNECT\n") return } conn, _, err := w.(http.Hijacker).Hijack() //注意看这里 if err != nil { log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error())……

阅读全文

Nginx基于权重的轮询算法实现

Nginx平滑的基于权重轮询算法描述为: Algorithm is as follows: on each peer selection we increase current_weight of each eligible peer by its weight, select peer with greatest current_weight and reduce its current_weight by total number of weight points distributed among peers. 算法执行2步,选择出1个当前节点: 每个节点,用它们的当前值加上它们自己的权重。 选择当前值……

阅读全文

Go踩坑系列 | 为什么request.URL.Scheme取不到值

遇到的问题 最近在阅读echo框架的源码,发现context.go文件在读取请求的scheme时是单独封装了个方法。就很奇怪,go语言标准库不是自带了方法吗,干嘛不用? 于是写了段代码来验证: 1 2 3 4 5 6……

阅读全文