Skip to content

Commit

Permalink
第一章纠错
Browse files Browse the repository at this point in the history
  • Loading branch information
qiangmzsx committed Jul 19, 2024
1 parent 086313a commit b95d151
Showing 1 changed file with 3 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ In our experience, this axiom is a dominant factor in any discussion of changing

Hyrum’s Law represents the practical knowledge that—even with the best of intentions, the best engineers, and solid practices for code review—. As an API owner, you will gain some flexibility and freedom by being clear about interface promises, but in practice, the complexity and difficulty of a given change also depends on how useful a user finds some observable behavior of your API. If users cannot depend on such things, your API will be easy to change. Given enough time and enough users, even the most innocuous change will break something;[^9] your analysis of the value of that change must incorporate the difficulty in investigating, identifying, and resolving those breakages.

海勒姆定律代表了一种实践知识,即使有最好的规划、最好的工程师和可靠的代码评审实践,我们也不能假设完全遵守已发布的契约或最佳实践。作为API所有者,通过明确地接口约定,你将获得一定的灵活性和自由度,但在实践中,给定更改的复杂性和难度还取决于用户对你的API的一些可观察行为的有用程度。如果用户不能依赖这些东西,那么你的API将很容易更改。如果有足够的时间和足够的用户,即使是最无害的变更也会破坏某些东西;你对变更价值的分析必须包含调查、识别和解决这些缺陷的难度。
海勒姆定律体现了实际知识,即便有良好的意图、顶尖的工程师和扎实的代码审查流程,也不能保证完全遵守契约或最佳实践。作为API所有者,通过明确地接口约定,你将获得一定的灵活性和自由度,但在实践中,给定更改的复杂性和难度还取决于用户对你的API的一些可观察行为的有用程度。如果用户不能依赖这些东西,那么你的API将很容易更改。如果有足够的时间和足够的用户,即使是最无害的变更也会破坏某些东西;你对变更价值的分析必须包含调查、识别和解决这些缺陷的难度。

> [^8]: To his credit, Hyrum tried really hard to humbly call this “The Law of Implicit Dependencies,” but “Hyrum’s Law” is the shorthand that most people at Google have settled on.
>
Expand Down Expand Up @@ -175,7 +175,7 @@ Most programmers know that hash tables are non-obviously ordered. Few know the s

As a result, if you ask any expert “Can I assume a particular output sequence for my hash container?” that expert will presumably say “No.” By and large that is correct, but perhaps simplistic. A more nuanced answer is, “If your code is short-lived, with no changes to your hardware, language runtime, or choice of data structure, such an assumption is fine. If you don’t know how long your code will live, or you cannot promise that nothing you depend upon will ever change, such an assumption is incorrect.” Moreover, even if your own implementation does not depend on hash container order, it might be used by other code that implicitly creates such a dependency. For example, if your library serializes values into a Remote Procedure Call (RPC) response, the RPC caller might wind up depending on the order of those values.

因此,如果你问任何一位专家“我能为我的散列容器设定一个的输出序列吗?”这位专家大概会说“不”。总的来说,这是正确的,但过于简单。一个更微妙的回答是,“如果你的代码是短期的,没有对硬件、语言运行时或数据结构的选择进行任何更改,那么这样的假设是正确的。如果你不知道代码的生命周期,或者你不能保证你所依赖的任何东西都不会改变,那么这样的假设是不正确的。”,即使你自己的实现不依赖于散列容器顺序,也可能被隐式创建这种依赖关系的其他代码使用。例如,如果库将值序列化为远程过程调用(RPC)响应,则RPC调用程序可能会根据这些值的顺序结束。
因此,如果你问任何一位专家“我能为我的散列容器有特定的输出序列吗?”这位专家大概会说“不”。总的来说,这是正确的,但过于简单。一个更微妙的回答是,“如果你的代码是短期的,没有对硬件、语言运行时或数据结构的选择进行任何更改,那么这样的假设是正确的。如果你不知道代码的生命周期,或者你不能保证你所依赖的任何东西都不会改变,那么这样的假设是不正确的。”,即使你自己的实现不依赖于散列容器顺序,也可能被隐式创建这种依赖关系的其他代码使用。例如,如果库将值序列化为远程过程调用(RPC)响应,则RPC调用程序可能会根据这些值的顺序结束。

This is a very basic example of the difference between “it works” and “it is correct.” For a short-lived program, depending on the iteration order of your containers will not cause any technical problems. For a software engineering project, on the other hand, such reliance on a defined order is a risk—given enough time, something will make it valuable to change that iteration order. That value can manifest in a number of ways, be it efficiency, security, or merely future-proofing the data structure to allow for future changes. When that value becomes clear, you will need to weigh the trade- offs between that value and the pain of breaking your developers or customers.

Expand Down Expand Up @@ -483,7 +483,7 @@ Much of the time, our major themes of time and scale overlap and work in conjunc

Occasionally time and scale come into conflict, and nowhere so clearly as in the basic question: should we add a dependency or fork/reimplement it to better suit our local needs?

有时时间和规模会发生冲突,而且没有什么地方能像在基本问题中那么明显:我们应该添加一个依赖性,还是分支/重新实现它,来更好地满足我们的需求
有时,时间和规模的考量会发生冲突,尤其是在这样一个基本问题上:我们应该添加一个外部依赖,还是对其进行分支或重新实现,以更好地满足我们的本地需求

This question can arise at many levels of the software stack because it is regularly the case that a bespoke solution customized for your narrow problem space may outperform the general utility solution that needs to handle all possibilities. By forking or reimplementing utility code and customizing it for your narrow domain, you can add new features with greater ease, or optimize with greater certainty, regardless of whether we are talking about a microservice, an in-memory cache, a compression routine, or anything else in our software ecosystem. Perhaps more important, the control you gain from such a fork isolates you from changes in your underlying dependencies: those changes aren’t dictated by another team or third-party provider. You are in control of how and when to react to the passage of time and necessity to change.

Expand Down

0 comments on commit b95d151

Please sign in to comment.