
Go 1.14 发布于 2020-02-25。这一版对服务端程序很重要：运行时加入异步抢占，调度延迟和长循环阻塞问题得到明显改善。

源码侧 `api/go1.14.txt` 有 8914 条公开 API 增量，大量来自 FreeBSD arm64 syscall；公开标准库目录新增 `hash/maphash`。

## 主要变化

### 1. goroutine 支持异步抢占

Go 运行时需要在 goroutine 之间调度执行权，也需要让 GC 有机会观察线程状态。Go 1.14 的异步抢占让不含函数调用的长循环也更容易被打断，避免单个 goroutine 长时间占住 P。这个变化对尾延迟、GC 暂停和 CPU 密集型任务都很重要。

典型问题是这类循环：

```go
for {
    x += 1
}
```

如果循环体里没有函数调用，旧运行时很难在合适位置插入调度点。异步抢占让运行时可以通过信号等机制打断执行，给调度器和 GC 机会。它改变的是运行时调度能力，不是 goroutine API。

### 2. 模块 vendor 语义更完整

模块模式下的 vendor 不只是复制依赖源码。`vendor/modules.txt` 会记录模块版本和显式依赖信息，Go 命令可以据此判断 vendor 目录是否和 `go.mod` 一致。它让离线构建、固定依赖快照和源码审计更明确。

当模块声明 `go 1.14` 且存在 vendor 目录时，Go 命令会更倾向使用 vendor 内容。这样 vendor 从“手工约定”变成 Go 命令理解的依赖来源。`modules.txt` 则防止 vendor 目录和模块文件悄悄不一致。

### 3. `defer` 性能继续优化

`defer` 原本有一定运行时成本，很多性能敏感代码会手写清理逻辑。Go 1.14 继续优化常见 defer 场景，让资源释放、锁释放、panic 恢复这类代码可以更自然地写，而不必过早牺牲可读性。

最常见的受益代码是：

```go
mu.Lock()
defer mu.Unlock()
```

`defer` 的优势是和资源获取写在一起，不容易遗漏。性能成本下降后，这种写法在更多热点路径里也能接受。

### 4. `hash/maphash` 提供随机哈希

`hash/maphash` 面向自定义哈希表、缓存索引和去重结构。它提供带随机种子的哈希，避免把固定哈希算法暴露给外部输入后产生碰撞攻击。它不是加密哈希，不适合做签名或摘要校验。

使用时通常先创建 `maphash.Seed`，再对字符串或字节计算哈希。seed 不同，结果也不同，因此不应该把结果写入持久化文件或跨进程协议。它的定位是进程内哈希表，而不是稳定摘要。

## 语言与规范

Go 1.14 没有新增语法。语言兼容性仍然保持稳定，重点变化集中在运行时、工具链和标准库。

## 工具链与运行时

运行时最关键的变化是异步抢占。过去某些不含函数调用的紧密循环可能长时间不让出执行权，影响 GC 和其他 goroutine 的调度。Go 1.14 后运行时可以更主动地抢占，服务端尾延迟更可控。

模块工具链方面，`go mod vendor` 和模块模式下的 vendor 行为更完整。测试、flags、环境变量和模块下载也有细节调整。

## 标准库与新增包

新增公开包：

- `hash/maphash`：提供带随机种子的哈希，适合实现 map-like 数据结构时降低碰撞攻击风险。

其他重要变化：

- `crypto/tls`、`crypto/x509` 继续收紧默认安全行为。
- `net/http`、`net/http/httptest` 改进 HTTP 行为和测试能力。
- `runtime/pprof`、`runtime` 增加诊断和运行时信息。
- `encoding/json`、`reflect`、`strconv` 等包有兼容性修正。

## 小版本特殊变化

Go 1.14 系列共有 15 个小版本，异步抢占上线后，runtime 和工具链修复非常密集。

这里的安全修复可以按攻击面分组。`crypto/x509`、`crypto/elliptic`、`math/big` 影响密码学基础，重点是证书验证、椭圆曲线运算和大整数运算的正确性。`net/http/cgi`、`net/http/fcgi` 是 Web 入口组件，历史上容易受到环境变量、头部转发和请求解析边界影响。`encoding/binary` 影响二进制解析，安全问题通常和长度、整数转换或异常输入有关。`go` 命令的安全修复则属于构建和依赖获取链路。

- `go1.14.5` 修复 `crypto/x509` 和 `net/http` 安全问题。
- `go1.14.7` 修复 `encoding/binary` 安全问题。
- `go1.14.8` 修复 `net/http/cgi` 和 `net/http/fcgi` 安全问题，这类包虽然使用面较窄，但一旦暴露在 Web 入口风险很高。
- `go1.14.12` 修复 `go` 命令和 `math/big` 安全问题。
- `go1.14.14` 修复 `go` 命令和 `crypto/elliptic` 安全问题。
- 其他小版本频繁涉及 runtime、compiler、linker、testing、plugin、`encoding/json`、`database/sql`，适合和 1.14 的调度器变化一起看：运行时能力增强通常会伴随一串边界修复。

## 参考

- [Go 1.14 Release Notes](https://go.dev/doc/go1.14)
- [Go Release History](https://go.dev/doc/devel/release)
- [Go 1.14 source tag](https://go.googlesource.com/go/+/refs/tags/go1.14)
- [api/go1.14.txt](https://go.googlesource.com/go/+/refs/tags/go1.14/api/go1.14.txt)

