当前位置: 首页 > article >正文

Go 语言中的海勒姆定律

在这里插入图片描述

原文:Abenezer Belachew

最近,我在探索 Go 代码库时偶然发现了一个有趣的注释:

“根据海勒姆定律(Hyrum’s law),这文本不可更改。”

func (e *MaxBytesError) Error() string {
    // Due to Hyrum's law, this text cannot be changed.
	// 根据海勒姆定律,这文本不可更改。
	return "http: request body too large"
}
  • 在此之前,我从未听说过海勒姆定律。
  • 简单搜索后得知,这是一个以 Hyrum Wright 命名的原则,他是 Google 的一名软件工程师。

这个“定律”非常简单:

当一个 API 拥有足够多的用户时,无论你在接口合约中承诺了什么:系统的所有可观察行为都会被某些人依赖。

换句话说,代码中任何可以被观察到的行为——无论是有意的还是偶然的——最终都会成为某个地方、某个人依赖的东西。

因此在上述代码中,作者明确指出该错误信息无法更改,因为可能已经有人在某处依赖它。虽然看似微不足道的更改,例如调整错误信息的措辞,却可能对依赖于这条特定消息的代码造成意想不到的问题。在这种情况下,一个看似微小的改动可能会破坏现有代码,因为有人依赖于 “http: request body too large” 的确切措辞。

例如,以下是一些开源代码库,如果更改错误消息将会受到影响:

  • http: request body too large

这并不是唯一的例子。我在 Go 的 crypto/rsainternal/weak 包中也发现了引用海勒姆定律的类似注释。

一些例子

crypto/rsa/rsa.go

func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
    // Note that while we don't commit to deterministic execution with respect
    // to the random stream, we also don't apply MaybeReadByte, so per Hyrum's
    // Law it's probably relied upon by some. It's a tolerable promise because a
    // well-specified number of random bytes is included in the ciphertext, in a
    // well-specified way.
    // 请注意,虽然我们没有承诺随机流的执行是确定性的,但我们也没有调用 MaybeReadByte,
    // 因此根据海勒姆定律,这可能已经被某些人依赖了。
    // 这是一个可以接受的承诺,因为在密文中以明确的方式包含了一个明确数量的随机字节。
}

crypto/rsa/pss.go

func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) {
    // Note that while we don't commit to deterministic execution with respect
    // to the rand stream, we also don't apply MaybeReadByte, so per Hyrum's Law
    // it's probably relied upon by some. It's a tolerable promise because a
    // well-specified number of random bytes is included in the signature, in a
    // well-specified way.
    // 请注意,虽然我们没有承诺随机流的执行是确定性的,但我们也没有调用 MaybeReadByte,
    // 因此根据海勒姆定律,这可能已经被某些人依赖了。
    // 这是一个可以接受的承诺,因为在签名中以明确的方式包含了一个明确数量的随机字节。

    if opts != nil && opts.Hash != 0 {
        hash = opts.Hash
    }
}

internal/weak

Using go:linkname to access this package and the functions it references is explicitly forbidden by the toolchain because the semantics of this package have not gone through the proposal process. By exposing this functionality, we risk locking in the existing semantics due to Hyrum's Law.

使用 go:linkname 访问该包及其引用的函数是被工具链明确禁止的,
因为该包的语义尚未经过提案流程。如果公开了此功能,
我们可能会因为海勒姆定律而锁定现有的语义。

观察

显然,这不仅仅是 Go 语言的专属现象,它在其他代码库中也有提及。

坦白说,这让我想起 JavaScript 在过去几年中的演变,它的许多奇怪且意料之外的行为因为被广泛依赖而变成了事实上的标准。现在,我终于知道该如何称呼这种现象了——海勒姆定律

最后的思考

  • 这是一则很好的提醒:当你修改别人可能依赖的代码时需要格外小心——并尽量设计出不会意外锁定奇怪行为的系统。
  • 更好的做法是,从一开始就设计可以最大程度减少意外行为被依赖可能性的系统。
  • 毕竟,你知道那句老话:“仅仅一个小小的改动就足以让整个系统崩溃。”

😶‍🌫️️


http://www.kler.cn/a/408927.html

相关文章:

  • shell脚本(完)—脚本互调重定向的学习
  • 2.langchain中的prompt模板 (FewShotPromptTemplate)
  • 无线电磁波在自由空间的衰减
  • 搜索二维矩阵
  • 【tensorflow的安装步骤】
  • “iOS profile文件与私钥证书文件不匹配”总结打ipa包出现的问题
  • Jenkins-Git Parameter 插件实现指定版本的发布和回滚
  • 解释 Python 中的可变与不可变数据类型?
  • 框架学习07 - SpringMVC 地址映射
  • Sqlite: Java使用、sqlite-devel
  • 深度学习图像视觉 RKNN Toolkit2 部署 RK3588S边缘端 过程全记录
  • 初识算法 · 分治(3)
  • Excel求和如何过滤错误值
  • 设计模式——数据访问对象模式
  • Spring Boot与MyBatis-Plus的高效集成
  • 不需要双手离开键盘 vscode
  • 复古风格渐变褪色人像旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!
  • 电脑的ip地址怎么换掉:全面指南
  • [Java网络安全系列面试题] GET 和 POST 的区别在哪里?
  • SHELL笔记(循环)
  • 神经网络的初始化
  • SQL 语句访问路径的方式
  • 【数据结构与算法】 LeetCode:回溯
  • 解锁PPTist的全新体验:Windows系统环境下本地部署与远程访问
  • [C/C++][FFmpeg] 增加引用计数和显式释放的接口
  • RHCE——DNS域名解析服务器