• Go 程序到机器码的编译之旅

    在 [Stream](https://getstream.io/) 里,我们广泛地使用 Go,它也的确巨大地提高了我们的生产效率。我们也发现 Go 语言性能的确出众。自从使用了 Go 以后,我们也完成了类似于我们内部使用的基于 gRPC, Raft 和 RocksDB 存储引擎这类技术栈关键性部分的目标。 今天我们根据 Go 1.11 版本的编译器,来看一下它是如何将我们的 Go 源代码编译成可执行程序的。以此我们能更加了解我们每天工作所用到的工具。我们也会看到为何 Go 语言如此之快并且...

  • Go 语言 HTTP 请求超时入门

    在分布式系统中,超时是基本可靠性概念之一。就像这条 [tweet](https://twitter.com/copyconstruct/status/1025241837034860544) 中提到的,它可以缓和分布式系统中不可避免出现的失败所带来的影响。 ## 问题 > 如何条件性地模拟 504 http.StatusGatewayTimeout 响应。 当尝试在 [zalando/skipper](https://github.com/zalando/skipper/iss...

  • 1 行 Go 代码实现反向代理

    暂且放下你的编程语言来瞻仰下我所见过的最棒的标准库。 ![This is all the code you actually require…](https://raw.githubusercontent.com/studygolang/gctt-images/master/reverse-proxy/1_y3GxXdKfZlqa95bl19Rytg.png) 为项目选择编程语言和挑选你最爱的球队不一样。应该从实用主义出发,根据特定的工作选择合适的工具。 在这篇文章中我会告诉你...

  • Map 在 Go runtime 中的高效实现(不使用范型)

    这篇文章基于我在日本东京 [GoCon Spring 2018](https://gocon.connpass.com/event/82515/) 上的演讲讨论了,Go 语言中的 map 是如何实现的。 ## 什么是映射函数 要明白 map 是如何工作的的,我们需要先讨论一下 *map 函数*。一个 map 函数用以将一个值映射到另一个值。给定一个值,我们叫 *key*,它就会返回另外一个值,称为 *value*。 ``` map(key) → value ``` 现...

  • 不要对 I/O 上锁

    锁可用于同步操作。但如果使用不当的话,也会引发显著的性能问题。一个比较常见出问题的地方是 HTTP handlers 处。尤其很容易在不经意间就会锁住网络 I/O。要理解这种问题,我们最好还是来看一个例子。这篇文章中,我会使用 Go。 为此,我们需要编写一个简单的 HTTP 服务器用以报告它接收到的请求数量。所有的代码可以从 [这里](https://github.com/gobuildit/gobuildit/tree/master/lock) 获得。 报告请求数量的服务看起来是这...

  • 120
    Golang 中 strings.builder 的 7 个要点

    自从 Go 1.10 发布的一个月以来,我多少使用了一下 `strings.Builder`,略有心得。你也许知道它,特别是你了解 `bytes.Buffer` 的话。所以我在此分享一下我的心得,并希望能对你有所帮助。 ## 1. 4 类写入(write)方法 与 `bytes.Buffer` 类似,`strings.Builder` 也支持 4 类方法将数据写入 builder 中。 ```go func (b *Builder) Write(p []byte) (int,...

  • 以后台进程方式运行 Go 程序

    从 1999 年那时开始我就为 windows 写过服务,一开始用 C/C++,后来用 C#。现在我在 Linux 上用 Go 编写服务端软件。然而我没辙了。更令人沮丧的是,我一开始编写软件所用的操作系统并不是我即将部署所用的操作系统。当然,那是后话了。 我想要在我的 Mac 上以后台进程(守护进程)的方式运行代码。而我的问题也是,我无从下手。 我很幸运在 Bitbucket 上找到了由 Daniel Theophanes 编写的名为 [service](https://bitbuc...

  • Golang 中的回环栅栏

    这篇文章中我们会研究一个基本的同步问题。并使用 Golang 中原生的 Buffered Channels 来为这个问题找到一个简洁的解决方案。 ## 问题 现在假设我们我们有一堆 workers。为了充分发挥 CPU 多核的能力,我们让每个 worker 运行在单独的 goroutine 中: ```go for i := 0; i < workers; i++ { go worker() } ``` worker 需要做一系列的工作 job: ```g...

  • 自动代码生成的 5 点建议

    `//go:generate` 的引入使得 Go 语言在构建过程中集成自动代码生成工具更加简单。`stringer` 使得编写重复代码更轻松,而 `yacc` 和 `ragel` 这类程序则让优化解析器的生成变得可能。在 [GoGenerateTools](https://github.com/golang/go/wiki/GoGenerateTools) 上你可以找到关于这类工具的一份不完整的列表。 **给自动生成的代码做标记**。为了让构建工具能够识别出自动生成的代码,必须使用一个符合...

  • Go 如何编写简洁测试 -- 表格驱动测试

    表格驱动测试是一种编写易于扩展测试用例的测试方法。表格驱动测试在 Go 语言中很常见(并非唯一),以至于很多标准库<sup>[1](#reference)</sup>都有使用。表格驱动测试使用匿名结构体。 在这篇文章中我会告诉你如何编写表格驱动测试。继续使用 [errline repo](https://github.com/virup/errline) 这个项目,现在我们来为 `Wrap()` 函数添加测试。`Wrap()` 函数用于给一个 `error` 在调用位置添加文件名和行数的修...