Software Engineering: Code Is Read Far More Than It Is Written
A reasonable assumption about software engineering is that the job is writing programs. That is the visible part, and it is the smaller part.
Most engineering time is spent on code that already exists — reading it to understand what it does, changing it carefully, finding out why it stopped working, and extending it to do something it was not designed for. Writing genuinely new code from nothing is a minority activity for most working engineers.
That single fact reorders most of the advice in the field. If code is read far more often than written, then the property that matters most is how easy it is to understand and change, not how quickly it was produced or how clever it is.
Almost everything that follows is downstream of that.
Why the field cares about things that look fussy
Practices that seem like professional fastidiousness usually turn out to be economic once you account for where the time goes.
Naming things carefully. A variable is named once and read hundreds of times. The cost is trivial and the return is paid on every future reading.
Keeping functions small. Not aesthetics. A small function can be understood without holding the rest of the system in your head, which matters because human working memory is limited and most bugs come from misunderstanding what existing code does.
Writing tests. Tests are not primarily about proving code correct today. They are about making it safe to change tomorrow — a test suite tells you whether your change broke something a hundred files away. Without that, engineers become reluctant to touch anything, and the codebase ossifies.
Code review. Partly catching defects, partly spreading knowledge so the system is not dependent on one person's memory.
The unifying logic is a cost curve. A defect caught while designing costs almost nothing. Caught in review, a little. Caught in testing, more. Caught in production, considerably more — and if it has been corrupting data quietly for months, the cost includes repairing everything it touched.
That curve is the entire argument for testing, review, and short release cycles. Not craftsmanship for its own sake — arithmetic.
The parts that reliably go wrong
Certain failures recur across teams and decades.
Building the wrong thing. By far the most expensive failure, and it is not a technical one. Software built to a specification that nobody validated with actual users is frequently completed successfully and used by nobody. Engineering excellence applied to the wrong problem produces excellent waste.
Adding people to a late project. This usually makes it later. New people need to be brought up to speed by the people who are already behind, and communication paths grow much faster than headcount — with ten people there are forty-five possible pairs. This is Brooks's observation and it has held up remarkably well.
Accumulating debt without tracking it. Shortcuts are often the right call. Shortcuts nobody recorded become indistinguishable from deliberate design, and six months later nobody can tell which oddities were compromises. See technical debt.
Estimating badly, and being surprised each time. Software estimates are systematically optimistic, mostly because the work involves discovering unknowns that by definition were not visible when estimating. The reliable correction is not to demand better estimates but to build in margin and to break work into pieces small enough that being wrong is cheap.
Rewriting instead of evolving. The rewrite is perpetually tempting and usually goes badly, because the old system does more than anyone has catalogued. Gall's Law covers why, and Conway's Law covers why the rewrite drifts back toward the original shape if the organisation is unchanged.
Where to spend effort
Quality is not uniform across a system, and treating it as uniform wastes most of the effort.
Code that changes constantly and matters when it breaks deserves genuine investment — tests, clear structure, careful review. This is where engineering discipline pays.
Code that is stable and low-stakes usually does not, however untidy it appears. Refactoring something nobody has touched in three years is often a purely aesthetic exercise. The interest rate on that debt is near zero because nobody is paying it.
This is the theory of constraints applied to a codebase: improve at the bottleneck, not at whatever is most visually offensive.
Two closing observations that engineers tend to learn late.
Simplicity is worth more than it looks. Fewer moving parts means fewer interactions to reason about, fewer failure modes, less to keep in your head. The strongest available technique is usually deleting something rather than adding a better version of it.
Most hard problems in software are not technical. They are questions of what to build, which trade-off to accept, and how to coordinate people — which is why senior engineering work drifts steadily away from writing code and toward deciding what is worth writing. The typing was never the hard part.