在六月份时,Gustavo Niemeyer 在他的博客 [Labix.org](http://blog.labix.org/) 上提出了下面这个问题: *假设 uf 是一个无符号的 64 位整型,但包含的内容却是符合 IEEE-754 标准的二进制浮点数,你怎么去区分 uf 是表示整型还是浮点型呢?* 由于我对这方面的了解并不是很多,所以无法快速得出这个问题的答案,而且我也无法用语言来向你解释,只能通过写一个相关的程序来进行示范。幸运的是 Gustavo 发布了答案的思路,我认为非...
-
在 Go 中探索 IEEE-754 标准
-
Go 测试风格指南
Go 测试的一个小风格(自认为)指南。关于写好测试的文章比我在这写的要多的多。但我写的主要是关于风格而不是技术。 ## 使用 table-drive 测试,并始终使用 tt 作为测试用例 尝试在可行的情况下使用 table-driven 测试,但当不可行时,可以复制一些代码;不要强制使用它(例如,有时候除了一两个案例之外,更容易为这之外的情况编写一个 table-driven 的测试;实际情况就是如此)。 始终为一个测试用例使用相同变量名会使它更容易为大量代码工作。你不必使用 ...
-
Go 语言 HTTP 请求超时入门
在分布式系统中,超时是基本可靠性概念之一。就像这条 [tweet](https://twitter.com/copyconstruct/status/1025241837034860544) 中提到的,它可以缓和分布式系统中不可避免出现的失败所带来的影响。 ## 问题 > 如何条件性地模拟 504 http.StatusGatewayTimeout 响应。 当尝试在 [zalando/skipper](https://github.com/zalando/skipper/iss...
-
Go 语言的 Modules 系统介绍
即将发布的 Go 语言 1.11 版本将会给我们带来对 *modules*(模块)的实验性支持,这是 Go 语言新的一套依赖管理系统。 (译注:很多编程语言中,把 modules 译作「模块」,但由于目前该机制在 Go 语言还没正式发布,因此尚未有非常普及的译法。而类似的 vendor 一词的翻译,大多中文文章都是采取保留英文原文的方式处理,因此本文对 modules 的翻译参考 vendor 的处理:保留英文原文) 前些日子,[我简单地写了一编关于它的文章](https://rob...
-
我这几年来是如何编写 Go HTTP 服务的
我是从 [r59](https://golang.org/doc/devel/pre_go1.html#r59) —— 1.0 之前的一个发布版本,就开始写 Go 了,并且在过去七年里一直在用 Go 构建 HTTP API 和服务。 在 [Machine Box](https://machinebox.io/?utm_source=matblog-3May2018&utm_medium=matblog-3May2018&utm_campaign=matblog-3May2018&utm_...
-
1 行 Go 代码实现反向代理
暂且放下你的编程语言来瞻仰下我所见过的最棒的标准库。 ![This is all the code you actually require…](https://raw.githubusercontent.com/studygolang/gctt-images/master/reverse-proxy/1_y3GxXdKfZlqa95bl19Rytg.png) 为项目选择编程语言和挑选你最爱的球队不一样。应该从实用主义出发,根据特定的工作选择合适的工具。 在这篇文章中我会告诉你...
-
Go 中不定长度集合
如果你在使用像 C# 或 Java 这样的编程语言后来到 go,你发现的第一件事就是没有像 `List` 和 `Dictionary` 这样的传统集合类型。 这真让我困惑了好几个月。 我找到了一个名为 `container/list` 的软件包,并且几乎用它做所有的东西。 我脑后一直有一个声音在唠叨。语言设计者不应该不直接支持对未知长度的集合管理的功能。每个人都在讨论切片是如何在语言中被广泛使用,但我只是在有明确定义的容量或者它们通过函数返回时我才使用切片,这有点不对劲!! 因此,我...
-
goroutine 的同步(第一部分)
![image](https://raw.githubusercontent.com/studygolang/gctt-images/master/sync-goroutine/part1.jpeg) 假设 Go 程序启动了两个 goroutine: ```go package main import ( "fmt" "sync" ) func main() { var v int var wg sync.WaitGroup ...
-
Go 语言中的比较操作符
这篇文章专注于 6 个操作符,==,!=,<,<=,> 和 >=。我们将深入探讨它们的语法和用法的细微差别。对很多人来说,这听起来不像是吸引人的事,或者他们可能已经从其他编程语言获得了糟糕的经验。然而,在 Go 中它们定义的很好并简洁。下面讨论的主题,如可比性将出现在其他场合,如 maps。为了使用上述操作符,至少有一个操作数需要[可赋值](https://studygolang.com/articles/12381)给第二个操作数: ```go package main import...
-
在 Go 语言中自动插入分号
正式的语法指定什么是在 Go 语言(或者其他的语言)中依据语法构成有效的程序。 ``` Block = "{" StatementList "}" . StatementList = { Statement ";" } . ``` 以上定义取自 Go 规范。它使用[扩展的 Backus-Naur](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form) 形式(EBNF)。这意味着代码块是用分号分隔的一个或...
-
Go 语言中的方法(第一部分)
Golang 程序中定义的类型有与其相关的方法。让我们来看一个例子: ```go type T struct { name string } func (t T) PrintName() { fmt.Println(t.name) } func main() { t := T{name: "Michał"} t.PrintName() } ``` 正如您可能怀疑程序输出名字。方法是一个函数,拥有附加的,单独元素的参数列表,称之为接...
-
Go 中的匿名函数和反射
我最近在浏览 Hacker News 时看到一篇吸引我眼球的文章《[Python中的Lambdas和函数](http://www.thepythoncorner.com/2018/05/lambdas-and-functions-in-python.html?m=1)》,这篇文章 —— 我推荐你自己阅读一下 —— 详细讲解了如何运用 Python 的 lambda 函数,并举了一个例子展示如何使用 Lambda 函数实现干净,[DRY](https://en.wikipedia.org/wiki...
-
Go 语言中的 Monkey 补丁
很多人认为 monkey 补丁只能在动态语言,比如 Ruby 和 Python 中才存在。但是,这并不对。因为计算机只是很笨的机器,我们总能让它做我们想让它做的事儿!让我们看看 Go 中的函数是怎么工作的,并且,我们如何在运行时修改它们。本文会用到大量的 Intel 汇编,所以,我假设你可以读汇编代码,或者在读本文时正拿着[参考手册](https://software.intel.com/en-us/articles/introduction-to-x64-assembly). **如果你...
-
无停机优雅重启 Go 程序
## 什么是优雅重启 在不停机的情况下,就地部署一个应用程序的新版本或者修改其配置的能力已经成为现代软件系统的标配。这篇文章讨论优雅重启一个应用的不同方法,并且提供一个功能独立的案例来深挖实现细节。如果你不熟悉 Teleport 话,Teleport 是我们使用 Golang 针对弹性架构设计的 [SHH 和 Kubernetes 特权访问管理解决方案](https://gravitational.com/teleport/)。使用 Go 建立和维护服务的开发者和网站可靠性工程师(SRE)...
-
理解 Go 语言的类型
当我使用 C/C++ 编写代码时,理解类型(type)是非常有必要的。如果不理解类型,你就会在编译或者运行代码的时候,碰到一大堆麻烦。无论什么语言,类型都涉及到了编程语法的方方面面。加强对于类型和指针的理解,对于提高编程水平十分关键。本文会主要讲解类型。 我们首先来看看这几个字节的内存: FFE4 | FFE3 | FFE2 | FFE1 ---|---|---|--- 00000000 | 11001011 | 01100101 | 00001010 请问地址 FFE1 ...
-
Go 中的 “简单语句”
![](https://raw.githubusercontent.com/studygolang/gctt-images/master/simple-statement/1_HO_nLfJ1LDrODqso68AcwA.jpeg) [https://en.wikipedia.org/wiki/Kiss_(band)](https://en.wikipedia.org/wiki/Kiss_%28band%29) 在 Golang [规范](https://golang.org/ref...
-
在 Go 中使用 C 语言的动态库
我和我的儿子在上周末干了一件非常有意思的事情,我们开发了一个用 Go 编写的命令行游戏,最近我正在重写一款曾经在年轻时开发的游戏,当时用的还是 Kaypro II。 ![](https://raw.githubusercontent.com/studygolang/gctt-images/master/Using-C-Dynamic-Libraries-In-Go-Programs/kayproii.jpg) 我钟爱这台电脑,回想起曾经使用 BASIC 在上面日日夜夜开发游戏,它非常...
-
Go 中的可变参函数
当函数最后一个参数为 *...T* 时(*T* 前面的三个点是特意的),就叫*可变参函数*: ```go package main import "fmt" func sum(numbers ...float64) (res float64) { for _, number := range numbers { res += number } return } func main() { fmt.Println(sum(1...
-
使用 JWT 保护 API 访问
APIs 的一个常见用例是提供一个授权中间件,允许客户端向 APIs 发送授权请求。通常来说,客户端会执行一些授权逻辑,产生一个「会话标识」。最近比较流行的 JWT ( JSON Web Tokens ) 提供了一个带超时时间的「会话标识」,使用它不需要额外的空间来执行验证逻辑。 本文是接着上一篇文章写的,在阅读下面内容之前建议先看一下之前的那篇文章 [用 go-chi 处理 HTTP 请求](https://scene-si.org/2018/03/12/handling-http-re...
-
图解 Go 并发编程
你很可能从某种途径听说过 Go 语言。它越来越受欢迎,并且有充分的理由可以证明。 Go 快速、简单,有强大的社区支持。学习这门语言最令人兴奋的一点是它的并发模型。 Go 的并发原语使创建多线程并发程序变得简单而有趣。我将通过插图介绍 Go 的并发原语,希望能点透相关概念以方便后续学习。本文是写给 Go 语言编程新手以及准备开始学习 Go 并发原语 (goroutines 和 channels) 的同学。 ## 单线程程序 vs. 多线程程序 你可能已经写过一些单线程程序。一个常用的编...
-
理解 golang 中的 context(上下文) 包
![](https://raw.githubusercontent.com/studygolang/gctt-images/master/understanding-the-context-package-in-golang/0_exTPQ4ppfrdjuXcR.jpg) Go 中的 context 包在与 API 和慢处理交互时可以派上用场,特别是在生产级的 Web 服务中。在这些场景中,您可能想要通知所有的 goroutine 停止运行并返回。这是一个基本教程,介绍如何在项目中使用它以...
-
Go 中的 init 函数
main 标识符是随处可见的,每一个 Go 程序都是从一个叫 main 的包中的 main 函数开始的,当 main 函数返回时,程序执行结束。 init 函数也扮演着特殊的角色,接下来我们将描述下 init 函数的属性并介绍下怎么使用它们。 init 函数在包级别被定义,主要用于: - 初始化那些不能被初始化表达式完成初始化的变量 - 检查或者修复程序的状态 - 注册 - 仅执行一次的计算 - 更多其它场合 除了下面将要讨论到的一些差异外,你还可以在正则函数中放置任何...
-
使用 Go 在 WASM 中进行图像处理的实验
Go 的主分支最近完成了一个 WebAssembly 的工作原型实现。作为 WASM 的爱好者,我自然要把玩一下。 这篇文章,我要记下周末我用 Go 做的处理图像实验的想法。这个演示只是从浏览器中获取图像输入,然后应用各种图像变换,如亮度,对比度,色调,饱和度等,最后将其转储回浏览器。这测试了两件事 - 简单的CPU绑定执行,这是图像转换应该做的事情,以及在 JS 和 Go 之间传递数据。 ## 回调 应该明确如何在 JS 和 Go 之间进行调用,不是我们在 emscripte...
-
在 Go 中用 Context 取消操作
许多使用 Go 的人都会遇到 context 包。大多数时候 context 用在下游操作, 比如发送 Http 请求、查询数据库、或者开 go-routines 执行异步操作。最普通用法是通过它向下游操作传递数据。很少人知道,但是非常有用的context功能是在执行中取消或者停止操作。 这篇文章会解释我们如何使用 Context 的取消功能,还有通过一些 Context 使用方法和最佳实践让你的应用更加快速和健壮。 ## 我们为什么需要取消操作? 简单来说,我们需要取消来避免...
-
Go 语言的 append 不总是线程安全的
## 示例问题 我经常看到一些 bug 是由于没有在线程安全下在 slice 上进行 append 而引起的。下面用单元测试来举一个简单的例子。这个测试有两个协程对相同的 slice 进行 append 操作。如果你使用 `-race` flag 来执行这个单元测试,效果更好。 ```go package main import ( "sync" "testing" ) func TestAppend(t *testing.T) { x := []stri...
-
为什么 Go 语言允许百万级别的 goroutines,而 Java 只允许数千级别的 threads?
原文链接:[https://rcoh.me/posts/why-you-can-have-a-million-go-routines-but-only-1000-java-threads/ ](https://rcoh.me/posts/why-you-can-have-a-million-go-routines-but-only-1000-java-threads/) 很多有过 JVM 相关语言工作经验的程序员或许都遇到过如下问题: ``` [error] (run-main-...
-
关于 Go 即将支持的 WebAssembly 的一些注意事项
这是一篇关于 webassembly 的即时记录,它的目的是给我做个备忘而不仅仅是如果使用它的教程。 即将发布的 Go 1.11 版本将支持 Wasm。@neelance 做了大部分的实施工作。对 wasm 的支持已经可以通过他在 github 上的工作分支进行测试。 看[这篇文章](https://blog.gopheracademy.com/advent-2017/go-wasm/)了解更多信息 ## 工具链设置 要从 go 源码生产一个 wasm 文件,您需要...
-
在 Go 中使用 Time, Timezones 和 Location
今天我遇到个问题。我在编写代码处理 NOAA 的潮汐站 XML 文档时,很快意识到我遇到了麻烦。这是一小段 XML 文档: ```xml <timezone>LST/LDT</timezone> <item> <date>2013/01/01</date> <day>Tue</day> <time>02:06 AM</time> <predictions_in_ft>19.7</predictions_in_ft> <predictions_in_cm>600</predic...
-
Go 语言的指针切片
![Image courtesy — https://xkcd.com/138/](https://raw.githubusercontent.com/studygolang/gctt-images/master/uh-oh-is-in-go-slice-of-pointers/1.png) Go 让操作 Slice 和其他基本数据结构成为一件很简单的事情。对于来自 C/C++ 令人畏惧的指针世界的人来说,在大部分情况下使用 Golang 是一件令人幸福的事情。对于 **JS/Python...
-
概述 Go 中读取文件的方式
当我开始学习 Go 时,我很难掌握各种用于读取文件的 API 和技术。我尝试编写支持多核的单词计数程序([KGRZ/KWC](https://github.com/kgrz/kwc)),通过在一个程序中使用多种读取文件方式来展示我初始的困惑。 在今年的 [Advent of Code](http://adventofcode.com/2017) 中,有些问题需要采用不同的方式来读取输入。我最终每种技术都至少使用过一次,现在我将对这些技术的理解写在本文中。我列出的方法是按照我使用的顺序,并不...
-
Go 中如何有效的比较字符串
当优化软件时字符串比较可能和你想的有些不同。特别是包括拆分跨 goroutines 的循环, 找到一个更快的哈希算法,或者一些听起来更科学的方式。当我们做出这样的修改时,会有一种成就感。然而, 字符串比较通常是信息传递中(in a pipeline)的最大瓶颈。下面的代码段经常被使用,但它是最糟糕的解决方案 (参见下面的 benchmarks),并导致了实际问题。 ```go strings.ToLower(name) == strings.ToLower(othername) ```...
-
Golang 下的微服务 - 第 10 部分 - 总结
一路走来,多么奇妙的一段旅程啊!完成这些文章花了好几个月的时间。第一篇文章发布于 2017 年底,现在 2018 年已经过去快一半了,我才刚刚在写本系列最后一篇文章。 写这一系列文章花费了我不少时间和精力。对我来说这是一个令人生畏的任务,首先是因为我对各部分知识只是有个大概的了解,其实,写这些文章的部分初衷也是想提高我对相关知识的理解,同时也想得到社区的反馈,没有比得到社区的认可更棒的事情了。在写作过程中,我学到了很多,和很多又酷又聪明的人进行了讨论,他们给了我很大帮助。其次,这一系列文章...
-
Golang 下的微服务 - 第 9 部分 - 使用 CircleCI 部署
欢迎大家在 [Patreon](https://www.patreon.com/ewanvalentine) 上向我提供更多诸如此类的素材。 在本系列的这一章节,我们将简要介绍使用 [CircleCI](http://circleci.com/) 与我们的其中一项服务建立持续集成。 [CircleCI](http://circleci.com/) 是一款不可思议的工具,它有一个非常实用的免费平台。这个平台就是 SaaS, 因此与 Jenkins 不同的是,它是被完全管理的。同时它的配...
-
关于结构化并发的笔记 —— Go 语言中有害的声明语句
## 前言 每一个并发的 API 背后的代码都需要允许并发运行的,以下是使用不同 API 的例子: ``` go myfunc(); // Golang pthread_create(&thread_id, NULL, &myfunc); /* C with POSIX threads */ spawn(modulename, myfuncname, []) % Erlang th...
-
为什么 Go 类型系统中没可变性?
**本文解释了协变、逆变和不变性是什么,以及对 Go 类型系统的影响。特别是解释了为什么在 slices 中不可能有可变性。** 一个 Go 初学者经常问的问题是“为什么我不能把 `[]int` 类型变量传递给函数 `func ([]interface{ })`”?在这篇文章中,我想探讨这个问题及其对 Go 的影响。但是可变性(本文所描述)的概念在其他语言也是有用的。 可变性描述了子类型关系应用在复合类型中使用时发生的情况。在这种情况下,“A是B的子类型”意味着,A类型的实例始终可以...
-
Go 功能:将 Go 程序员带向极限(Functional Go: Taking The Gopher to it's extremes)
## 功能范式(The Functional Paradigm) 函数式编程基于简单的规则,目的是使程序保持一致,使并行(更)人性化和简单化,函数是存粹的,它不会改变(变量的)状态,不会改变对象,也不共享状态,代码是声明式的,计算只不过是数学函数的一种实现。 我们来看一个纯粹的函数语言的函数例子: ``` isPalindrome :: (Eq a) => [a] -> Bool isPalindrome x = x == reverse x ``` 上面的代码是 ...
-
什么我不能将这个函数作为一个 Http Handler 来传递?!
当我帮助人们学习网页开发时,一个超级常见的问题是,“为什么我不能把这个函数传入 `http.Handle` 方法中?它看起来与 `http.HandlerFunc` 是一模一样的!” ```go func demo(h http.Handler) {} func handler(w http.ResponseWriter, r *http.Request) {} func main() { // 这行代码在编译时会报错 demo(handler) } ``` >...
-
Go 语言中的包是怎么工作的
自从我开始用 Go 写代码以来,如何组织好代码并用好 package 关键字对我来说一直是个迷样的难题。package 关键字类似于 C# 中的命名空间,但是它的约定却是将 package 名字与目录结构绑定在一起。 Go 语言有一个网页试图解释如何编写 Go 代码。 http://golang.org/doc/code.html 当我开始用 Go 编程时,这是我最开始读的资料之一。可能因为之前一直在 Visual Studio 中工作,代码被解决方案和项目打包的很好,这个文档...
-
使用 ReJSON 在 Redis 中保存 Go 结构体
![image](https://raw.githubusercontent.com/studygolang/gctt-images/master/rejson/1_w3hPEpsPFtHs36dJMUdl7w.jpeg) > 图像授权 https://Redislabs.com/blog/Redis-go-designed-improve-performance/ 大部分人可能对 Redis 都很熟悉了。对于外行人来说,Redis 是最广为人知并广泛应用的数据库/缓存产品,起码也是...
-
Go 语言中的作用域
理解 Go 语言中的作用域是怎么起作用的,需要一些关于块的预备知识,这在 “[Go 语言中的代码块](https://studygolang.com/articles/12632)” 文章中有讲。 一个标识符的作用域是标识符与某个值,比如变量、常量、包等,进行绑定的那一部分源码(有时甚至是全部)。 ```go package main import "fmt" func main() { { v := 1 { ...
-
与 Jupyter 交互的 Go 编程
![](https://raw.githubusercontent.com/studygolang/gctt-images/master/jupyte/go_jupyter_1.jpeg) 最近几年,Go 语言变得非常流行。我是 Python 的狂热粉丝,三年前我的第一个业余项目也是用 Python 实现的。而现在我开始使用 Go 语言来取代 Python,因为不管是业余爱好的小项目还是公司里的大项目,Go 语言能让我的编码效率更高。 与此同时,随着机器学习和数据科学(data sc...
-
Map 在 Go runtime 中的高效实现(不使用范型)
这篇文章基于我在日本东京 [GoCon Spring 2018](https://gocon.connpass.com/event/82515/) 上的演讲讨论了,Go 语言中的 map 是如何实现的。 ## 什么是映射函数 要明白 map 是如何工作的的,我们需要先讨论一下 *map 函数*。一个 map 函数用以将一个值映射到另一个值。给定一个值,我们叫 *key*,它就会返回另外一个值,称为 *value*。 ``` map(key) → value ``` 现...
-
Go 语言中的初始化依赖项
让我们直接从两个 Go 语言小程序开始: **程序1** ```go package main import "fmt" var ( a int = b + 1 b int = 1 ) func main() { fmt.Println(a) fmt.Println(b) } ``` **程序2** ```go package main import "fmt" func main() { var ( a int = b + ...
-
Go 实在是令人惊叹,但是我想说说我不喜欢它的地方
通过我的上一篇文章以及最近几个月期间对于Go编程语言的间接推广,我与许多开始对这门语言感兴趣的人们进行了交流,所以现在我打算转而去写一些我对这门语言的不满,依据我目前积累的经验来提供一种更加全面的看法,借此可以让一部分人意识到Go语言终究并不是他们项目的最佳选择。 **备注1** 需要重点指出的是,文章里的部分观点(如果不是全部的话)是基于我个人的主观想法并且跟我的编程习惯有关,它们没有必要也不应该被描述成“最佳解法”。还有就是,我现在仍旧是一个 Go 语言的菜鸟,我接下来要说的一些...
-
Golang 中好的代码 vs 不好的代码
最近我被问到关于 `Golang` 好代码和不好的代码的一些细节问题,我发现这个问题非常有趣,有趣到可以就这个问题写一篇文章。为了阐明我的观点,我举了一些我在 `Air Traffic Management`(`ATM`)航空交通管制领域的代码例子,这些代码托管在 [Github](https://github.com/teivah/golang-good-code-bad-code) 上。 ## 背景 首先,简短地描述一下项目的背景。 `Eurocontrol` (欧洲航管组...
-
如何泄漏一个协程然后修复它
很多 go 语言开发者都知道这句格言,[永远不要启动一个你不知道如何停止的协程](https://dave.cheney.net/2016/12/22/never-start-a-goroutine-without-knowing-how-it-will-stop),但是泄漏一个协程还是超级的简单。让我们看一种常碰到的泄漏协程的方式,然后修复它。 为了实现这个,我们先建立一个包含一个自定义 `map` 类型的库,这个 `map` 类型的 key 在经过了一段可配置的时间后过期。我们把这个库...
-
以 SQL 作为 API
如果你不是在石头下住着,那么你也应该听过最近兴起一种新的对“函数作为服务”的理解。在开源社区,Alex Ellis 的 [OpenFaas](https://github.com/openfaas/faas) 项目受到了很高的关注,并且 [亚马逊Lambda宣布对Go语言的支持](https://aws.amazon.com/blogs/compute/announcing-go-support-for-aws-lambda/)。这些系统允许你按需扩容,并且通过 API 调用的方式来调用你的 ...
-
在 Go 1.11 下调试延迟问题
诊断和调试复杂系统是一件复杂的事。经常需要多个层次的诊断数据来弄清楚延迟问题可能的原因。 一个分布式系统由多个服务器组成,这些服务器互相依赖,共同完成对用户请求的服务。在任何时候, - 系统中的一个进程可能会处理大量的请求。 - 在高并发的服务器中,没有容易的途径能将一个请求生命周期内的各个事件分离出来。 - 在高并发的服务器中,对于响应一个请求所发生的事件,我们没有很好的可见性。 随着 Go 在近些年来变成编写服务器的一门流行语言,我们意识到理解 Go 进程在一个请求的生...
-
使用 defer 的运行时开销
在 Go 语言中有一个特殊的关键字 `defer`。对于它更多的介绍请看[这里](https://blog.golang.org/defer-panic-and-recover)。`defer` 语句会把一个函数追加到函数调用列表。这个列表会在函数返回的时候依次调用。`defer` 常用来进行各种清理操作。 但是 `defer` 本身是有开销的。使用 Go 的基准测试工具我们可以量化这种开销。 下面两个函数做同样的工作。一个使用 `defer` 语句而另一个不使用: ```go...
-
Cgo 和 Python
如果你研究过 [新近的 Datadog Agent](https://github.com/DataDog/datadog-agent/) ,你可能会注意到大部分代码库是用 Go 语言编写,而我们用来收集指标的检查工具仍然是用的 Python 。这是有可能的,因为 Datadog Agent(一个标准的 Go 二进制程序),内嵌了一个 CPython 解释器,在需要运行 Python 代码的时候就会调用这个解释器。通过使用一个抽象层可以让整个过程是透明的,由此,你尽可以编写惯用的 Go 代码,...