系统设计的两种抽象:隐藏或简化
The Two Abstractions of System Design: Hide or Reduce

原始链接: http://muratbuffalo.blogspot.com/2026/05/the-two-abstractions-of-system-design.html

作者认为,尽管计算机科学家受过“抽象”思维的训练,但在该术语的两种用法之间存在着严重的认知断层: * **模块化抽象 (Modularity Abstraction):** 这是计算机科学的传统方法,侧重于封装、API 以及隐藏内部复杂性,从而构建简洁的接口。其目标是通过封锁“泄漏”并简化使用方式(通常会掩盖并发性)来降低难度。 * **建模抽象 (Modeling Abstraction):** 这是形式化方法(如 TLA+)和数学中采用的方法。它不隐藏内部细节,而是侧重于“精简”——剥离一切无关因素,以提取出系统的“最小行为骨架”。 建模能力的缺失,其核心原因在于这两种方法截然相反。模块化旨在隐藏复杂性,而建模则旨在揭示系统的基本行为和交互——即使是那些会导致“泄漏”的行为——以便对系统的一致性和并发性等属性进行推演。 尽管设计精良的系统有时可以同时兼顾这两种目的,但它们的目标依然迥异:模块化通过划定边界来管理复杂性,而建模则是穿透这些边界以揭示底层的逻辑。学习建模需要实现思维的转变:从“隐藏内部细节”转向“归纳至本质”。

```Hacker News最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交登录系统设计的两种抽象:隐藏或简化 (muratbuffalo.blogspot.com)16 分,由 ubolonton_ 于 2 小时前发布 | 隐藏 | 过往 | 收藏 | 1 条评论 帮助 BoiledCabbage 30 分钟前 [–] 我通常听到的这两个概念是抽象与泛化。抽象隐藏了不必要的细节。泛化则是发现/提取事物之间的共性。> oop - 抽象和泛化有什么区别? - Stack Overflow - https://stackoverflow.com/questions/19291776/whats-the-diffe...创建过程/方法是一种抽象形式。允许它接受参数是一种泛化形式(通过允许它用于多个相似的输入)。简单地创建一个整数数据类型是一种非常简单的泛化形式。允许操作针对任何整数进行通用处理。回复 准则 | 常见问题 | 列表 | API | 安全 | 法律 | 加入 YC | 联系 搜索: ```
相关文章

原文

When talking about TLA+, I keep referring to "abstraction" as the most important thing to learn. And it is about the hardest to learn as well.

But a contradiction has been bugging me. Aren't CS people already supposed to be good at abstraction? Isn't abstraction supposed to be at the root of OS, networking, software engineering? Abstract Data Types (ADTs) are a staple of every in CS curriculum. So why do I (and every other formal methods/modeling person) see such a large skill gap in abstraction, and flag it as the core, make-or-break skill for modeling?

I think I finally get to the root of this cognitive disonance. There are two kinds of "abstraction" conflated under the same umbrella term.

  • Modularity abstraction: This is the traditional abstraction taught in CS curricula as ADTs, APIs, layered design, etc. It is all about encapsulation, drawing boundaries, and hiding internals.
  • Modeling abstraction: This is what I talk about when I talk about abstraction in the context of modeling. This is the same sense of abstraction mathematicians and physicists when building models for thinking and reasoning. The goal is to find the minimal and most elegant description that preserves the property you care about. It is all about cutting away everything orhtogonal to the essence of that property.

These two couldn't be further apart in terms of their goal! Let me try to explain in the next two sections.

Modularity abstraction hides. Modeling abstraction reduces.

Modularity abstraction is about interfaces that hide internals. Modeling abstraction is about behaviors, and about reducing a system to its minimal behavioral skeleton for the property you care.

Modularity abstraction encapsulates, draws a vertical boundary, and hides the layer below. Modeling abstraction is crosscutting: it slices the system along a behavioral plane and keeps only what is absolutely relevant to the property under investigation, and even then in the form of "what", not "how". This slice usually looks nothing like the system's organization.

Modularity abstraction hides concurrency. Modeling abstraction exposes it.

Modularity abstraction is all about sealing the leaks, hence Joel Spolsky's famous post lamenting that "all abstractions are leaky". [ Note that his list is all about modularity abstraction: TCP (hide IP), string libraries (hide character arrays), file systems (hide spinning disks), virtual memory / flat address space (hide MMU and paging), SQL (hide query plans), NFS / SMB (hide the network), C++ string classes (hide char*). ] Modularity abstraction aspires to hide the interleavings and present operations as if they were atomic. Its goal is to make the module easy to use, but in doing so it forgoes exposing concurrency or efficiency opportunities.

In stark contrast, the modeling abstraction is about identifying what should leak and leveraging it! It exposes the fine-grained actions and orderings, and proves that invariants hold despite the interleavings. The payoff for this work is to harvest the maximum safe concurrency from the system.

Examples of modeling abstraction 

There is an abundance of modeling abstraction in distributed systems field. It feels like almost all protocols are designed this way.

  • Lamport logical clocks: throw away wall-clock time, keep happens-before
  • Hybrid logical clocks: keep wall-clock and causality, throw away the rest
  • TrueTime: time as a bounded-uncertainty interval 
  • Consensus: agree on a single decision. The way Lamport designed Paxos is a masterclass in abstraction; from Consensus, Voting, to the final protocol. 
  • Linearizability (and really all consistency models ): throw away replication, caching, retries
  • Log is the database idea: throw away materialized state as the source of truth; keep only the ordered, append-only sequence of events.
  • MapReduce/Spark: throw away orchestration, parallelism, scheduling, and fault tolerance. Keep a DAG of deterministic transforms over partitioned data—and let the framework reconstitute the rest from that skeleton.
Sometimes it may look like the two definitions overlap (e.g., linearizability, consensus, log is the database, map-reduce). But this is actually a reuse rather than an overlap. A really well-designed artifact can serve simultaneously as a spec to refine against (modularity) and a skeleton to reason from (modeling). This just means the two coincided on one artifact, but the abstraction roles still remain distinct. 
联系我们 contact @ memedata.com