Skip to content

필사 모드: Reading What Others Wrote — Entering a Codebase and Reverse-Engineering an Undocumented System

English
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

Writing Gets Practiced Under Compulsion, Reading Does Not

Write code at work and the result is graded whether you like it or not. It runs or it does not, it gets reviewed, it ships. Writing badly shows.

Reading is not like that. Skim carelessly and nobody notices. Pretend to understand, bolt your change on beside it, and it usually works. If something does break it breaks months later, and by then nobody can see that the cause was shallow reading.

So reading became the skill everyone performs daily and nobody trains. Onto that asymmetry the recent shift landed: the volume of code entering repositories that nobody on the team typed by hand went up. As the relative value of producing code falls, the value of reading and judging what someone else produced rises.

What Never Survives Into Code

The root reason reading is hard is that code preserves the result of a decision and discards the process.

Code shows one adopted option. The three alternatives considered and dropped, the reason they were dropped, the constraints in force at the time, the external system whose scheduling forced this shape — none of that is anywhere. So readers stall at "why is this so strange," and usually the strangeness had a reason.

The distinction Fred Brooks drew in 1986 in "No Silver Bullet" is useful here. He split software complexity into accidental and essential, held that tooling improves the accidental kind, and argued the essential kind comes from the problem itself and cannot be removed. His thesis was that no single development promises a tenfold improvement within a decade.

Apply that to reading and it comes out like this. Syntax and idiom are accidental complexity and take help from tooling well. Why this domain carries this rule, why these two systems may only talk in this order, is essential complexity and does not reconstruct from text alone. Reading practice aims at the second kind.

Seven Steps Into a Large Codebase

There is an order for a repository you have never seen. Keeping the order alone changes the first week substantially.

  1. Run it first. Build, boot, get a health check passing. Reading in a state where you cannot run it is all guesswork. The points where you got stuck are themselves a list of the hidden dependencies.
  2. Find the entry points. Route definitions, message consumers, the scheduler registry. This is the coastline of your map.
  3. Follow one request all the way through. Do not sweep broadly; cut one vertical slice. The simplest read-only request will do. That single pass hands you the layering, the naming conventions, and the error-handling habits at once.
  4. Look at the data model. Schema and migration history are the fossil record of the domain. Columns added and renamed tell you how the business changed, more honestly than the code does.
  5. Read the tests as a specification. Tests are the list of what this team believes must hold. Areas without tests are areas where nobody set a contract.
  6. Look at change density. The files that change often are both the dangerous places and the important ones.
  7. Rewrite it in your own words. Produce a one-page summary, show it to someone who knows the system, and let them mark what is wrong. Skip this step and the previous six stay unverified.
# Example — the 20 files changed most often in the last year
git log --since=1.year --name-only --pretty=format: \
  | grep -v '^$' | sort | uniq -c | sort -rn | head -20

Reading the files at the top of this list first buys the most understanding per hour. Frequent change means requirements touch that spot often, and where requirements land often is the heart of the system.

An Undocumented System Documents Itself While Running

Faced with an undocumented system, people dig into the source first. Often that is backwards. A running system is the most current documentation of itself. The code might not even be what got deployed, but the process running right now does not lie.

Start from observation and these surface first: which ports are open and who holds connections to them, which environment variables and config are actually injected, which logs appear at what rate, which schedules fire at what hour. That alone sketches the system boundary and its external dependencies.

Then going into the code gives the reading a purpose. Read without one and you skim a file listing; walk in holding "why does this connection exist" and you read exactly the parts you need.

One trap worth writing down in advance: being in the repository does not mean being alive. Spending days reading dead code happens more often than you would think. Before reading, confirm that traffic currently passes through. One log line or one call counter answers it.

Why Reading Stays on the Expensive Side

Back to this series' test: reading clearly belongs on the expensive-to-verify side, for two reasons.

One is that the output of reading is understanding, and understanding cannot be inspected directly. To inspect it you have to get it outside your head — write a summary, explain it, or make a prediction and check it. So training reading requires an attached output, and that is why step seven is not optional.

The other is the essential complexity above. A large share of what must be read lives outside the code and has to be asked of the person holding it. Knowing what to ask is itself a product of reading, so this capability is bound less to text processing than to the ability to source information inside an organization.

Try It This Week

Pick one merged pull request somebody else wrote. Summarize it in five sentences: what changed, why, what alternatives probably existed, what could break, and what you still do not understand. Then send it to the author and ask what you got wrong. The last sentence generates the most valuable question.

  • Git Playground — repeat history digging, reverting, and bisecting without risking a real repository.
  • Logical Reasoning Trainer — practice reconstructing someone else's argument accurately, which uses the same muscle as reading someone else's code.

Where this does not apply: if the system is about to be retired, deep reading is waste. Then you only need the boundary, not the understanding. Knowing what goes in and what comes out is enough to swap it out.

Further Reading

What Stays Expensive series

Sources

  • No Silver Bullet — Wikipedia summary — Fred Brooks and his 1986 split between accidental and essential complexity, plus the claim that no single development promises a tenfold improvement within a decade. Read 2026-08-15.
  • The seven-step procedure and the observation-first reverse-engineering order are not from that source; they are assembled in this post.

현재 단락 (1/35)

Write code at work and the result is graded whether you like it or not. It runs or it does not, it g...

작성 글자: 0원문 글자: 6,089작성 단락: 0/35