Hidden Assumptions Hunt
Overview
Every algorithm you memorized and every system guarantee you quote comes with a list of preconditions that nobody states out loud. Binary search assumes sorted input, a total order, and an overflow-safe midpoint. Big-O assumes a machine where every memory access costs the same. A “cached” value assumes the world did not change underneath it. This collection takes common textbook rules, makes their hidden assumptions explicit, breaks each one with a concrete counterexample, and rebuilds a corrected statement that survives contact with production.
The framing matters because interviews and incidents rarely punish you for knowing a rule; they punish you for not knowing when the rule stops applying. A candidate who says “binary search is O(log n)” is fine. A candidate who says “binary search is O(log n) comparisons, provided the array is sorted under a strict weak order and the midpoint computation cannot overflow — which the JDK got wrong for nine years” is demonstrating a different level of understanding. That second sentence is the product of this collection’s method. The collection currently audits forty assumption families, from binary-search preconditions to service-registry staleness; the File Inventory below is the authoritative list.
Why Textbook Rules Break at Boundaries
Textbooks optimize for clarity of the core idea, so they study the interior of the design space: sorted arrays, well-behaved hash functions, balanced workloads, infinite memory, single-threaded execution, reliable networks. Production lives at the boundaries: adversarial inputs, sizes that cross integer limits, concurrent access, data that does not fit in RAM, networks that partition, clocks that drift. The rule itself was never false — it was conditional, and the conditions were unstated.
Three forces consistently create the gap:
- Idealized cost models. The RAM model charges one unit per memory access, so O(1) array access and O(1) hash lookup look equivalent. Real hardware has caches, TLBs, page faults, and NUMA, so the constants differ by orders of magnitude and sometimes the asymptotics themselves change (external-memory algorithms).
- Idealized semantics. “The midpoint of
lowandhigh” is mathematically(low + high) / 2. In 32-bit arithmetic that expression overflows. The algorithm is correct; the translation into a bounded type is not. Textbooks reason in integers; languages hand you fixed-width types. - Idealized environments. “The cache returns the current value” assumes no concurrent writer. “The network delivers the request” assumes no partition. “REPEATABLE READ means the same thing everywhere” assumes the SQL standard was implemented identically — it was not, and the divergence between MySQL and PostgreSQL is documented in both vendors’ manuals.
None of this makes the textbooks wrong. It makes them incomplete, and the missing parts are exactly what senior interviews probe.
The Method Used in Every Chapter
Each chapter follows the same five-step pattern, applied to a specific family of assumptions. When you read or recall any chapter, you should be able to reconstruct it from this skeleton:
- The taught rule. Stated fairly, the way a textbook or a lecture would state it. No strawmen — the rule is genuinely correct under its intended conditions.
- The hidden assumptions. An explicit list of the preconditions the rule silently relies on, with a note on why each one is usually invisible (usually because it holds in the demo, the unit test, and the classroom example).
- Counterexample / boundary case. A concrete input, timing, or environment where the rule fails. Every counterexample in this collection is real and checkable — no invented pathology. Where a claim is subtle (integer overflow points, isolation-level behavior, memory-model guarantees), the numbers and quotes were verified against primary sources: the C11 standard draft, the JLS, the Go memory model, PostgreSQL and MySQL manuals, and the original engineering posts.
- What changes when the assumption is removed. The corrected statement — the same rule, restated with its preconditions explicit, plus the standard defenses (safer idiom, alternative algorithm, explicit contract).
- Practical consequences and interview implications. Where this shows up in code review, incidents, and interview questions, including the follow-up questions that separate memorized answers from understood ones.
Worked micro-example, so the pattern is visible before you dive in:
- Taught rule: “Binary search runs in O(log n) time.”
- Hidden assumptions: the array is sorted; the comparison is a total (strict weak) order; indices fit in the index type; the midpoint expression cannot overflow.
- Counterexample: Joshua Bloch’s 2006 Google Research post documented that
int mid = (low + high) / 2throwsArrayIndexOutOfBoundsExceptiononce the sum oflowandhighexceeds2^31 - 1, which is reachable for arrays of roughly 2^30 elements or more. The bug sat in the JDK for about nine years. - Corrected statement: “Binary search performs O(log n) comparisons and O(log n) index computations, provided the input is sorted under the comparator’s order and index arithmetic is overflow-safe, e.g.
mid = low + (high - low) / 2.” - Consequences: in interviews, this is the canonical “your trivial code has a bug” probe; in practice, it is a template for auditing every arithmetic expression that aggregates sizes, counts, or timestamps.
How This Differs From the Sibling Projects
The research projects share a subject pool but not an angle. Use this directory when the question is “what precondition was silently assumed?”; use the others when the question is different:
- Misconceptions targets claims that are false as stated (for example, “hash lookup is always O(1)”). Here, the rules are true as stated — the failure is in the unstated conditions.
- Why-Not Handbook explains why you would choose mechanism A over mechanism B. Here we are not choosing; we are auditing the chosen mechanism’s fine print.
- Follow-up Tree escalates a question into the depth an interviewer adds, layer by layer. The assumptions here are the material those follow-ups are made of.
- Failure Casebook documents named incidents with timelines and primary sources. When an assumption failure has a famous incident behind it, the chapter links to the casebook instead of retelling the story.
- Connection Atlas maps dependencies between topics. The assumptions collection is frequently the reason an edge exists in that graph (for example, isolation-level semantics depending on the concurrency-control mechanism).
If you find the same concept in two projects, the treatment is deliberately different rather than duplicated. Hash tables, for instance, appear in all five projects from five angles: escalation chain (followup), adversarial hashing (this project’s complexity claims), versus binary search (why-not), the O(1) claim (misconceptions), and as database index structure (atlas).
File Inventory
| File | Domain | Assumptions audited |
|---|---|---|
| input-constraints.md | Algorithms | Sortedness, total order, overflow-safe midpoint, partition invariants, int-sized sums, in-memory input, ASCII text, non-empty inputs |
| memory-model.md | Systems | Zeroed memory, valid pointers, contiguity, no padding, unbounded stack, deterministic uninitialized reads, signed overflow, data races and UB, volatile semantics |
| concurrency-and-scheduling.md | Concurrency | Atomicity of compound operations, check-then-act, single-core visibility intuitions, volatile as synchronization, sleep durations, priority scheduling, instant thread startup, timeouts as guarantees |
| complexity-claims.md | Algorithms | O(1) memory access, uniform hashing, the comparison-sort lower bound, recursion depth, “better big-O wins” |
| caching.md | Infrastructure | Locality, read-heavy workloads, free coherence, tolerated staleness, TTL as consistency, transferable hit rates, “no downsides” |
| database-isolation.md | Databases | “Transactions are isolated”, SELECT never blocks, commit order equals transaction order, REPEATABLE READ portability, phantom reads, ORM-managed races |
| network-distributed.md | Networking & distributed | LAN reliability, localhost parity, in-order delivery, zero-latency calls, synchronized clocks, accurate failure detection, safe retries, the Eight Fallacies |
| floating-point.md | Numerics | Exact decimal representation, associativity of addition, == as value comparison, NaN semantics, floats for money, naive summation order |
| filesystem-durability.md | Storage | “write() returned, so it is safe”, page-cache flush, fsync targets (file and directory), rename atomicity, disk persistence after power loss |
| timeouts-and-retries.md | Infrastructure | Timeouts as upper bounds, idempotent retries, backoff preventing amplification, independent per-layer timeout budgets |
| api-contracts.md | Integration | Docs match behavior, stable pagination under concurrent writes, null vs absent, stable error codes, “additive” changes are safe |
| security-crypto.md | Security | HTTPS as endorsement, Math.random() as unpredictable, fast unsalted hashes for passwords, obscurity as access control |
| testing-assumptions.md | Quality | Passing tests imply correctness, mocks mirror reality, order independence, coverage as correctness, green CI as risk-free |
| storage-durability.md | Infrastructure | Untested backups as recoverable, RAID as backup, object-storage durability as availability, replication lag as loss-free |
| clocks-and-time.md | Systems & distributed | Clock monotonicity, wall-clock differences as durations, synchronized clocks as event ordering, cross-machine timestamp comparability, NTP steps and leap seconds, timezone-explicit encodings |
| encodings-and-text.md | Text & encodings | Strings as sequences of characters, safe truncation at N, trivial uppercasing and folding, UI validation as boundary validation |
| containers-and-resources.md | Infrastructure | CPU quota as N dedicated cores, memory limits as OOM protection, GC as an escape hatch under pressure, CPU throttling as latency-neutral |
| dns-assumptions.md | Networking | TTL as a failover bound, quick DNS reversibility, client TTL compliance, round-robin as load balancing, negative caching |
| ordering-and-pagination.md | Databases | ORDER BY determinism without tie-breakers, OFFSET pagination under concurrent writes, auto-increment IDs as insertion time, deep OFFSET as a linear scan, stable-sort portability, engine NULL ordering |
| randomness-and-ids.md | Security | Library PRNGs as unpredictable, UUID uniqueness as secrecy, UUIDv1 MAC/time leakage, random ids as unenumerable, seed-once-at-boot |
| serialization-compatibility.md | Integration | Additive field changes as safe, JSON numbers as precise, field order as meaningless, canonical serialization for signatures, schema evolution as deploy-day-scoped |
| rate-limit-headers.md | APIs | 429 as a clean backoff signal, Retry-After presence, limit stability, header dialect agreement, quota truthfulness |
| certificate-rotation.md | Security | Certificates renew themselves, renewal propagates trust everywhere, revocation works at incident time, expiry alerting is universal |
| locale-and-formatting.md | Text | Decimal point universality, collation as comparison, calendar and week-start universality, symmetric case conversion |
| regex-input-assumptions.md | Text | Bounded runtime on user input, guaranteed termination, dialect-consistent semantics, Unicode classes as characters |
| logging-and-pii.md | Observability | Logs are private, redaction is a retrofittable post-filter, structured schemas are stable, levels mean the same thing everywhere |
| configuration-assumptions.md | Systems | Defaults are safe, config is static per process lifetime, a flag implies the feature is on, environments run the same config |
| git-workflow-assumptions.md | Tooling | History immutability, merge/rebase equivalence, clean tree as pushed work, tag immutability, force-push as a private operation |
| proxy-header-assumptions.md | Networking & security | X-Forwarded-For as the client IP, Host as trustworthy, headers I set are headers the app sees |
| scheduled-jobs-assumptions.md | Infrastructure | Cron fires exactly on time, missed runs execute later, jobs never overlap, DST is handled by cron |
| temp-files-and-atomicity.md | Storage | Write-then-rename atomic everywhere, /tmp is mine, the temp file gets cleaned up, disk-full fails loudly on every write |
| distributed-lock-assumptions.md | Distributed | An acquired lock means exclusivity, the lock TTL covers my work, the lock service is always reachable |
| backup-restore-assumptions.md | Infrastructure | Restore is backup in reverse, green backup jobs as tested restores, RPO equals backup frequency, partial restore is possible |
| environment-parity-assumptions.md | Infrastructure | Case-insensitive dev volumes, /bin/sh and tool defaults, locale and time-zone defaults, floating base-image tags, the lockfile as the whole environment, resource-limit and topology parity, prod-shaped data |
| filesystem-paths-assumptions.md | Storage | Separators and working-directory dependence, case folding, reserved names, Unicode normalization, path-length budgets, join-and-traverse, symlink resolution, check-then-open races |
| integer-overflow-assumptions.md | Numerics | Signed overflow as wraparound, post-hoc overflow checks surviving optimization, promotion and signed-unsigned comparison traps, allocation-size multiplication, type width versus unit and horizon, language defaults as detection |
| process-shutdown-assumptions.md | Infrastructure | SIGTERM as termination, in-flight survival across deregistration lag, grace period versus p99, shutdown hooks as durability, PID 1 signal semantics, clean resume, predecessor ghosts (locks, registrations) |
| idempotency-assumptions.md | Integration | Method names as retry safety, at-most-once delivery, idempotency keys as leases (scope, lifetime, stored result), atomic dedupe-plus-effect, dedupe TTL versus replay age |
| secrets-handling-assumptions.md | Security | Configuration as private, orchestration metadata and image layers as secret stores, rotation as instant, scrubbers over unknown shapes, CI logs as confidential, history as removable |
| service-discovery-assumptions.md | Networking & distributed | Registry as current truth (heartbeat + eviction + refresh staleness), health-check depth and vantage, DNS as member-list discovery, discovery as a policy-neutral lookup, aligned cache expiry |
Coverage Ledger
Status per file, the primary sources each relies on, and known gaps. Primary sources marked “verified” were fetched and checked (HTTP 200 plus content inspection) during writing; factual claims from them are quoted or closely paraphrased in the chapters.
| File | Status | Primary sources | Known gaps / future work |
|---|---|---|---|
| index.md | Complete | This collection’s own method; sibling-project indexes | Sibling links assume the other research-project directories land per the coverage plan |
| input-constraints.md | Complete | Bloch, Google Research blog, 2006 (verified, quotes extracted); C11 overflow semantics via the N1570 draft (verified) | McIlroy’s “killer adversary” paper cited by name only (no URL included); could add a worked UTF-8 byte-table |
| memory-model.md | Complete | C11 N1570 (verified), JLS ch. 17 (verified), Go memory model (verified, race-semantics quote extracted), JSR-133 Cookbook (verified) | C++ standard wording cited by section name ([intro.races]) without URL by design; store-buffer litmus test described, not benchmarked |
| concurrency-and-scheduling.md | Complete | JLS §17.7 tearing via the JLS (verified); POSIX sleep semantics from the POSIX.1-2017 specification (text-level knowledge, no URL included); Pathfinder account cited as the JPL team’s write-up (name only) | Priority-inheritance mechanics could use a diagram; sleep/signal counterexample could include a compilable reproducer |
| complexity-claims.md | Complete | oCERT-2011-003 (verified) for hash-flooding; SipHash adoption in Python (PEP 456) and Rust std referenced as documented facts; OpenJDK/TimSort thresholds stated as implementation facts (checkable in source) | Paper URLs (Vattani et al. stampede paper; McIlroy) deliberately omitted rather than risk unverified links; matrix-traversal numbers are hardware-dependent ranges, not single figures |
| caching.md | Complete | Probabilistic early expiration attributed to Vattani, Chierichetti, Lowenstein (VLDB 2015) by name; cache-aside race sequence standard in the repo’s own cache-patterns page | No direct stampede reproducer with numbers; hit-rate distribution examples are illustrative, not measured datasets |
| database-isolation.md | Complete | PostgreSQL transaction isolation (verified, default-level and RR-error quotes extracted), MySQL InnoDB isolation levels (verified), MySQL consistent reads (verified, SELECT-vs-DML snapshot quote extracted) | Write-skew example reasoned from documented SI semantics, not executed; SQL Server/Oracle defaults stated from common documentation (no URLs) |
| network-distributed.md | Complete | Cloudflare leap-second post (verified), Eight Fallacies (verified), RFC 5905 and RFC 768 (verified via rfc-editor.org; datatracker blocks bots with 403) | Retry-storm and ECMP-reordering mechanics described from protocol knowledge without packet-trace evidence; no QUIC RFC cited yet (RFC 9000 would be the source) |
| floating-point.md | Complete | IEEE 754 semantics via worked examples (0.1+0.2, catastrophic cancellation, Kahan summation order, NaN propagation) | Goldberg’s “What Every Computer Scientist Should Know About Floating-Point Arithmetic” cited by title; no language-specific decimal-library survey |
| filesystem-durability.md | Complete | SQLite atomic commit docs (verified); ext4 delayed-allocation zero-length-file episode cited by title (kernel mailing-list threads) | Cross-filesystem rename semantics described generally, not per-kernel-release |
| timeouts-and-retries.md | Complete | Google SRE book: Addressing Cascading Failures (verified) | Retry-storm arithmetic worked, not simulated; no packet-trace evidence |
| api-contracts.md | Complete | AIP-158 pagination, GraphQL pagination, Pact, semver, Kubernetes API deprecation policy (all verified) | Schema-diff tooling named, not benchmarked |
| security-crypto.md | Complete | OWASP Password Storage Cheat Sheet (verified), RFC 8725 (verified) | GPU-cracking cost figures are order-of-magnitude reasoning from documented hash-cost parameters, not new measurements |
| testing-assumptions.md | Complete | Fowler, TestCoverage (verified), Hypothesis docs (verified) | Mutation-testing tools named, not surveyed in depth |
| storage-durability.md | Complete | AWS S3 durability, S3 Object Lock, RDS automated backups, PostgreSQL PITR (all verified); GitLab 2017 postmortem | Restore-time arithmetic uses stated bandwidth figures, not a reproduced restore drill |
| clocks-and-time.md | Complete | POSIX clock contracts (CLOCK_MONOTONIC vs CLOCK_REALTIME) and NTP slew/step behavior stated at specification level (no URL cited by design); Go’s monotonic time.Time and TrueTime described from documented language/database references | Leap-second incident narrative delegated to network-distributed.md; no NTP fetch log in this file |
| encodings-and-text.md | Complete | Unicode Standard annexes (UAX #15 normalization, UTS #10 collation) and Python’s Unicode HOWTO cited by title, per the chapter’s citation line | No per-language table of uppercasing edge cases (Turkish dotless-i described, not tabulated); no property-based test corpus included |
| containers-and-resources.md | Complete | cgroup v2 CPU/memory controller and CFS quota semantics from kernel documentation, referenced via the cgroups, namespaces, and CFS scheduling book pages; JVM container-aware defaults stated as documented facts | Throttling plateaus are worked arithmetic, not measured traces; no runtime-by-runtime memory-reclaim comparison |
| dns-assumptions.md | Complete | RFCs 1034/1035 (DNS core), 2181 (TTL semantics), 2308 (negative caching), 8767 (serving stale) cited by number from rfc-editor.org; the October 2021 Facebook incident linked to the casebook chapter | Resolver-specific TTL behavior (glibc, musl, JDK) described generally, not per-release; no measured TTL-compliance survey |
| ordering-and-pagination.md | Complete | PostgreSQL SELECT reference (NULLS default) and LIMIT clause (offset cost), MySQL LIMIT optimization and clustered index notes (all verified) | Quadratic export arithmetic worked, not executed; keyset cursor encoding sketched, not benchmarked |
| randomness-and-ids.md | Complete | RFC 4086, RFC 4122, RFC 9562, OWASP Session Management Cheat Sheet, Python secrets and random docs (all verified) | MT19937 state recovery stated from the documented algorithm structure, not demonstrated in code; the Debian OpenSSL 2008 episode cited by name only |
| serialization-compatibility.md | Complete | RFC 8259 (JSON precision caveat) and RFC 8785 (canonicalization), Protobuf proto3 guide (field-number, reserved, enum rules) (all verified) | Registry compatibility modes (BACKWARD/FORWARD/FULL) described, not exercised against a live registry; double-rounding arithmetic worked, not run in a JS engine |
| rate-limit-headers.md | Complete | RFC 6585 (429 status); provider header dialects cited by title (IETF ratelimit-headers draft, platform docs) | Provider-specific header dialects described from public documentation, not surveyed live per provider |
| certificate-rotation.md | Complete | RFC 5280, RFC 6960, RFC 8555, Let’s Encrypt rate-limit docs (all verified) | Internal-CA failure modes described generically; no per-vendor auto-renewal behavior surveyed |
| locale-and-formatting.md | Complete | Unicode CLDR, UTS #10, ECMA-402 (all verified) | Engine-specific collation differences described, not benchmarked |
| regex-input-assumptions.md | Complete | OWASP ReDoS, google/re2 docs (both verified) | Per-engine timing curves described qualitatively; no benchmark data invented |
| logging-and-pii.md | Complete | RFC 5424, OWASP Logging Cheat Sheet (verified) | GDPR retention analysis framed as engineering guidance, not legal advice |
| configuration-assumptions.md | Complete | 12factor config principle (verified) | Framework-specific hot-reload behaviors described generally, not per-release |
| git-workflow-assumptions.md | Complete | Pro Git, 2nd ed. (verified) | Hosting-platform branch-protection behaviors described generically |
| proxy-header-assumptions.md | Complete | RFC 9110 (verified), RFC 7239 (verified), MDN X-Forwarded-For (verified) | Trust-hop-count arithmetic described, not tested against live per-provider CDN header behavior |
| scheduled-jobs-assumptions.md | Complete | POSIX crontab (verified), systemd.timer (verified), Kubernetes CronJob (verified) | DST transitions reasoned from zone rules, not exercised on a live crond; per-distro crond variance described generally |
| temp-files-and-atomicity.md | Complete | SQLite atomic commit (verified), Python tempfile (verified), open(2) manual page (verified) | Power-loss counterexample reasoned from documented ext4 delayed-allocation behavior, not reproduced; Windows rename semantics described generally |
| distributed-lock-assumptions.md | Complete | Kleppmann, How to do distributed locking (verified), Redis distributed locks (verified), Chubby paper (verified) | GC-pause scenario worked from Kleppmann’s account, not reproduced; Redlock debate summarized with both sources linked |
| backup-restore-assumptions.md | Complete | SRE book: Data Integrity (verified), PostgreSQL continuous archiving (verified), pg_dump (verified), S3 durability (verified); GitLab 2017 delegated to the casebook | RPO-chain arithmetic worked, not measured on a real incident; restore-drill cadence framed as engineering practice, not a surveyed policy set |
| environment-parity-assumptions.md | Complete | Debian wiki Shell (dash as /bin/sh) and Node.js 17 release notes (OpenSSL 3.0) (verified); APFS/NTFS case semantics stated from vendor filesystem documentation | Locale-dependent sort and parse examples reasoned from documented collation behavior, not run side-by-side; descriptor-limit figures illustrative |
| filesystem-paths-assumptions.md | Complete | Windows naming rules, path_resolution(7), open(2), Snyk’s Zip Slip research (all verified) | Traversal counterexample worked, not exploited against a live service; NFC/NFD normalization behavior described, not tabulated per platform |
| integer-overflow-assumptions.md | Complete | C11 N1570 (expression evaluation), Java Math (addExact), Rust operator reference, CWE-190, UBSan (all verified) | Counter-wrap numbers worked from 2^32 arithmetic, not captured from device traces; Ariane 5 delegated to the casebook chapter |
| process-shutdown-assumptions.md | Complete | signal(7), Kubernetes pod lifecycle, JVM Runtime shutdown-hook contract (all verified) | Grace-versus-p99 arithmetic worked, not measured on a live rolling deploy; PID 1 signal semantics stated from documented kernel behavior |
| idempotency-assumptions.md | Complete | RFC 9110 (idempotent methods), Stripe idempotent requests (24-hour retention), Kafka delivery semantics (all verified) | Retry-versus-retention scenarios worked, not executed against a payment sandbox; outbox pattern referenced, not benchmarked |
| secrets-handling-assumptions.md | Complete | 12factor config, OWASP Secrets Management Cheat Sheet, GitHub push protection (all verified) | Environment, pod-spec, and image-layer leak paths described from documented mechanics, not reproduced per runtime; rotation-storm arithmetic worked, not measured |
| service-discovery-assumptions.md | Complete | Kubernetes pod DNS, RFC 2782, Envoy service-discovery overview, Consul DNS discovery (all verified) | Staleness and stampede arithmetic worked, not measured on a live registry; Eureka self-preservation described from documented behavior without a URL |
Ledger maintenance rule: when a gap is closed, update this table in the same change so status never outruns content.
Interview Questions
- Why do hidden assumptions matter more in system design interviews than in coding interviews? In coding interviews the constraints are printed in the problem statement (sizes, ranges, sortedness); the assumptions are handed to you. In system design they are not — the interviewer’s follow-ups (“what if the cache goes stale?”, “what if the network partitions?”) are precisely asking you to name and handle assumptions you never wrote down. Candidates who volunteer assumptions preempt half the follow-ups.
- Give an example where the algorithm was correct but the implementation still failed. Binary search: Bentley proved the algorithm correct, yet the JDK implementation overflowed the midpoint computation for arrays near 2^30 elements, throwing
ArrayIndexOutOfBoundsExceptionafter roughly nine years in production. The gap was between the mathematical integers of the proof and the fixed-width integers of the machine. - How do you systematically find hidden assumptions in your own code? Ask for each quantity: what are its bounds, and what happens at them (empty, one element, maximum, zero, negative)? For each operation: what interleaving would break it? For each external dependency: what does it promise (delivery, ordering, consistency, timing), and what does it merely usually do? Then test the boundaries deliberately rather than incidentally.
- What is the difference between a misconception and a hidden assumption? A misconception is false as stated (“SELECT never blocks”). A hidden assumption is a true rule plus unstated preconditions (“binary search is O(log n) — if the input is sorted and the midpoint is overflow-safe”). Misconceptions get corrected by denial; assumptions get corrected by completing the sentence.
- Which hidden assumption has caused the most expensive real-world failures in this collection? Strong candidates: uninitialized memory reads (security-relevant data leaks), lost updates from ORM read-modify-write cycles (financial data corruption), and the “retrying is safe” assumption (duplicate charges and amplified outages). All three are cheap to prevent and expensive to discover in production.
Key Takeaways
- A rule and its preconditions are inseparable; learning the rule without the preconditions is learning half of it.
- Boundary behavior — empty input, maximum input, concurrent access, degraded network — is where textbook rules and production behavior diverge, and it is exactly where interviewers and incidents probe.
- The five-step pattern (taught rule, hidden assumptions, counterexample, corrected statement, consequences) turns any memorized fact into an auditable claim.
- Every counterexample in this collection is real and source-backed; treat the primary sources cited in each chapter as part of the material, not decoration.
- Stating assumptions out loud is the cheapest performance improvement available in an interview: it converts unknown-unknowns into answered follow-ups.
Cross-References
- Misconceptions project — claims that are false as stated, the complement of hidden assumptions.
- Why-Not Handbook — mechanism-level comparisons that rest on the assumptions audited here.
- Follow-up Tree — interview escalation chains built from these boundary cases.
- Failure Casebook — named incidents where one of these assumptions failed in production.
- Connection Atlas — dependency graph between topics, with assumptions as the edges.
- Complexity claims — the RAM-model assumptions behind big-O, audited in depth.
- Memory model — the assumptions about memory and language semantics that underlie every systems claim.