5 exercises — idioms you will hear in code reviews, retrospectives, and architecture discussions. These describe common code quality problems and practices.
Idioms covered in this set
"Band-aid fix" — a temporary fix that hides symptoms
"Code smell" — a warning sign of deeper design problems
"Technical debt" — accumulated cost of shortcuts and deferred work
"Reinvent the wheel" — build something that already exists
0 / 5 completed
1 / 5
In a code review, a senior developer comments: "This is a band-aid fix. It hides the symptom but doesn't solve the root cause." What does "band-aid fix" mean?
"Band-aid fix" — a quick, superficial fix that covers a problem without actually solving it.
Origin: A Band-Aid (brand name) is an adhesive bandage — it stops bleeding temporarily but does not heal the wound.
In software: Any fix that makes the symptoms disappear (tests pass, errors stop showing) without addressing the root cause. Often generates technical debt.
Examples of band-aid fixes in code: • Adding a try/catch that silently swallows exceptions instead of fixing the cause • Hard-coding a value to make a test pass • Restarting a service on a cron schedule instead of fixing the memory leak • Adding a null check everywhere instead of fixing the data model
Common usage: "This null check is a band-aid — we need to fix the API response schema." "We band-aid'd it for the release, but it's on the backlog." "Stop band-aiding it and actually fix the data pipeline."
Related concepts: technical debt, root cause analysis (RCA), workaround, hotfix (can be legitimate or a band-aid)
2 / 5
The team lead says: "We've been adding features on top of features. This codebase is turning into spaghetti code." What does "spaghetti code" mean?
"Spaghetti code" — code with a disorganized, tangled structure that is extremely difficult to understand, maintain, or modify.
Origin: Like a plate of spaghetti — if you pull one strand, others get pulled with it. The structure has no clear beginning or end; everything is entangled.
Characteristics of spaghetti code: • Deeply nested conditionals (pyramid of doom) • Heavy use of global state and global variables • Functions that do everything (no separation of concerns) • Unclear flow of execution — hard to trace a bug • Historical accumulation of "band-aid fixes" • No consistent patterns or architecture
Common causes: • Growing a codebase without refactoring • Multiple developers adding code without coordination • Deadline pressure forcing shortcuts over time
In conversation: "The legacy billing module is pure spaghetti — nobody wants to touch it." "We need to refactor this spaghetti before we can add any new features."
Related terms: "big ball of mud" (no visible architecture), "lasagna code" (too many layers), "ravioli code" (too many small, isolated pieces).
3 / 5
During a code review, a developer notes: "I'm not going to block this PR, but I want to flag a code smell here." What is a "code smell"?
"Code smell" — a characteristic of code that suggests there may be a deeper problem with the design, even if the code technically works.
Term coined by Kent Beck; popularized by Martin Fowler's book Refactoring.
Important nuance: A code smell is not necessarily a bug. The code runs correctly. But the smell indicates that the code may be hard to maintain, extend, or test — and might break in the future.
Common code smells (with names): • Long method — function doing too many things • Large class (God Object) — class with too many responsibilities • Duplicate code — same logic in multiple places • Primitive obsession — using primitives instead of objects for domain concepts • Feature envy — a method using data from another class more than its own • Dead code — code that is never executed
In conversation: "There's a code smell here — this method is 200 lines. Let's discuss when we refactor." "I smell something in this module — every new feature requires changing four files." "We should schedule a code smell session before the next sprint."
4 / 5
The team's backlog contains this item: "Reduce technical debt in the authentication module." What is technical debt?
"Technical debt" — the accumulated cost of shortcuts, deferred refactoring, and suboptimal decisions made during development. Just like financial debt, it accrues "interest" over time: the longer it remains, the harder and more expensive future changes become.
Term coined by Ward Cunningham.
Sources of technical debt: • Deliberate shortcuts taken to meet deadlines ("we'll fix this later") • Band-aid fixes that weren't cleaned up • Outdated dependencies never updated • Missing tests, documentation, and error handling • Old architecture that doesn't fit current requirements
The "debt" metaphor: • Principal = the actual work needed to clean it up • Interest = extra time/complexity every new feature costs because of the debt • Bankruptcy = the codebase becomes unmaintainable; rewrite required
Vocabulary in context: "We're paying interest on our technical debt every sprint." "The tech debt in the payment system is slowing us down — we need to pay it down." "We have sprint capacity to either ship the feature or pay down tech debt — your call, PM."
Related: "refactoring", "paying down debt", "legacy code"
5 / 5
A developer is asked to add a feature but says: "Let's not reinvent the wheel — there's an open-source library that does exactly this." What does "reinvent the wheel" mean?
"Reinvent the wheel" — to waste time and effort building something from scratch that already exists in a good, working form.
Origin: The wheel is one of humanity's oldest and most useful inventions. There is no need to invent it again — it already works. Building your own version would be wasteful unless you had very specific requirements a wheel doesn't meet.
IT context — when NOT to reinvent the wheel: • Building your own authentication system when Passport.js, Auth0, Keycloak exist • Writing a custom JSON parser instead of using the language's built-in • Building your own ORM from scratch when Hibernate, SQLAlchemy exist • Implementing your own UUID generator when a library handles edge cases properly
When reinventing the wheel IS justified: • Existing solutions are too heavy for your requirements • Security requirements prevent using third-party code • Performance constraints require a custom implementation • Learning purposes (but make it clear it's not for production)
In conversation: "Why are we writing our own queue system? Don't reinvent the wheel — use RabbitMQ." "The team reinvented the wheel with a custom logger instead of using the standard one." "I reinvented the wheel once as a learning exercise — I don't regret it, but we didn't ship it."