Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Design Patterns (GoF and modern) Module 10

Anti-patterns and refactoring to patterns interview questions

Interview questions on anti-patterns and refactoring to patterns: warm-ups, then what each harder question tests and how a good answer starts.

19 questions: 5 warm-ups and 14 with model answers · Levels: Fresher to staff

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher

    What is a god object, and how do you start splitting one?

    Answered in the lesson Anti-patterns: god objects and golden hammers

  2. Fresher to mid

    Why is a mutable default argument dangerous in a Python Builder, and what is the fix?

    Answered in the lesson Language-specific traps when applying patterns

  3. Fresher to mid

    What is a code smell, and is every smell a problem that needs fixing?

    A code smell is a symptom that is quick to see on the surface of the code and usually points to a deeper problem: the same switch in several functions, a function with many parameters, checks for a missing value everywhere. Kent Beck coined the term while helping Martin Fowler with Refactoring. A smell is a reason to look closer, not a verdict. A long method can be perfectly clear, and a switch that has had three cases for five years and is used in one place costs little. The test is whether the smell makes the next change harder: if new cases keep arriving or the same edit has to be made in several places, remove it with the smallest refactoring that works, and keep the tests passing at every step.

    From the lesson Code smells that point to a pattern

  4. Fresher to mid

    What is a characterization test, and how does it differ from an ordinary unit test?

    A characterization test records what existing code does today, right or wrong, so that a later change in behaviour shows up at once; Michael Feathers named the idea in Working Effectively with Legacy Code. An ordinary unit test states what the code should do, written from the requirement. A characterization test is written from the code: you call it with inputs, often many seeded ones plus the boundaries, and write down whatever it answers, including answers that look wrong, such as a negative total. Its job is to make a refactoring safe, not to judge the behaviour. Bugs it reveals are fixed later, as deliberate changes with their own tests, and once the code is understood, focused unit tests replace the recorded answers.

    From the lesson Refactoring safely with characterization tests

  5. Fresher to mid

    What does it mean to refactor toward a pattern, and when would you refactor away from one?

    Refactoring toward a pattern means changing existing code in small steps that keep its behaviour, until the pattern's structure appears, for example moving the branches of a conditional into strategy objects once a new rule keeps being requested. Joshua Kerievsky's Refactoring to Patterns treats patterns this way, as destinations reached when the code needs them, not designs drawn up front. Refactoring away from a pattern is the reverse: when the variation the pattern served is gone, such as a factory that only ever makes one class or a Singleton that only makes tests share state, you take the structure out, again in small tested steps. Both directions are decided by evidence in the code's history, and both keep every answer the same at each step.

    From the lesson Refactoring toward, and away from, patterns

Questions with model answers

What each question tests, the first step of a good answer and the follow-ups to expect.

  1. Mid to staff

    A 3,000-line OrderService is changed by most pull requests and its test suite takes nine minutes. The team cannot stop feature work for a rewrite. How do you split it, and how do you show that nothing broke along the way?

    What it tests
    Choosing where to start from change history, protecting behaviour with characterization tests, extracting behind a facade in small steps, and keeping feature work flowing.
    First step
    Find the hotspots before touching any code: count the commits that changed each method, multiply by its length, and rank. Then group the fields by the job they serve and list the methods that use several groups. The first extraction is the group that changes most, behind the existing public methods.
    Follow-ups

    From the lesson Anti-patterns: god objects and golden hammers

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.

    Opening the model answers with your pass…

    Model answers open with any MySmartCoPilot pass.

    • Pro pass · 1 week₹79$2.99
    • 30 days₹179$5.99
    • 1 year₹1,699$45

    One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

    It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  2. Mid to senior

    A pull request replaces the constructor parameters of twenty classes with calls to a global ServiceLocator, to make wiring easier. Do you approve it? What would you ask for or change?

    What it tests
    Telling a trade-off from an anti-pattern: hidden dependencies, coupling to the locator, tests that share a registry, and the difference between application code and a library.
    First step
    Ask what problem the change solves. If constructors grew long, that is a design signal, not a wiring problem. Then name what the locator costs here: a class's signature no longer shows what it needs, and every class now depends on the locator itself.
    Follow-ups

    From the lesson Anti-patterns: god objects and golden hammers

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  3. Fresher to mid

    A Java price cache finds entries by product id and compares the boxed ids with ==. Every test passes, yet in production some products are always cache misses. What is happening, and how do you fix it so that it cannot come back?

    What it tests
    The boxing cache range, reference equality against value equality, why the tests missed it, and turning a one-off fix into a rule that a build checks.
    First step
    Look at which ids miss. If every id above 127 misses and the small ones hit, the comparison is checking identity: the Java Language Specification guarantees one boxed object per value only from -128 to 127, and test ids are usually small.
    Follow-ups

    From the lesson Language-specific traps when applying patterns

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 2 minutes
  4. Mid to senior

    A team ports a report framework from Java to C++. In Java the base constructor calls an overridable title() hook. Explain what that design does in each language, why neither compiler stops it, and how you would redesign it.

    What it tests
    Construction order, dispatch during construction in two languages, and a redesign that removes the base class's need for its subclass while it is being built.
    First step
    Walk through construction. In Java the fields start at their defaults, then the base constructor runs and dispatches to the override, which sees null fields. In C++ the object is only a base object until the derived constructor starts, so the base version runs.
    Follow-ups

    From the lesson Language-specific traps when applying patterns

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  5. Mid to senior

    A Rust desktop app keeps its observers as Rc<RefCell<Observer>> in each document, and every observer holds an Rc back to its document. Memory grows each time a document window is closed. Explain why, how you would confirm it, and how you would fix it.

    What it tests
    Reference counting and cycles, choosing which side holds a Weak pointer, and what notification does when an observer is gone.
    First step
    Draw the pointers. The document owns its observers and each observer owns the document, so when the window drops its handle, both counts stay at 1 or more and Drop never runs. Confirm it with Rc::strong_count, or with a Drop implementation that logs.
    Follow-ups

    From the lesson Language-specific traps when applying patterns

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  6. Mid to senior

    A pricing module has the same switch on the customer's tier, standard, gold or partner, in five functions. Would you replace it with polymorphism, a lookup table, Strategy or State? Walk through how you decide.

    What it tests
    Telling the four options apart by what varies and how often, using the change history as evidence, and choosing the smallest change that removes the duplication.
    First step
    Ask what the switch decides and how it changes. If each tier only supplies numbers, a table is enough. If tiers carry behaviour, polymorphism or Strategy fit; State only if a customer's tier changes as a result of what the customer does.
    Follow-ups

    From the lesson Code smells that point to a pattern

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  7. Mid to senior

    In a review, a colleague has replaced a four-line chain of if statements in a request handler with a Chain of Responsibility of four handler classes. The tests still pass. What do you say, and what would change your mind?

    What it tests
    Weighing a pattern's cost against the variation it serves, giving review feedback with evidence, and knowing the conditions under which the pattern pays.
    First step
    Measure the change first: lines, classes and how a reader follows one request. Then ask what variation the chain serves. If every route runs the same four checks in the same order, the if chain is the smallest correct code.
    Follow-ups

    From the lesson Code smells that point to a pattern

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  8. Mid to senior

    A code base checks for a missing discount plan in twelve places, with a slightly different default in some of them. Compare a default value at the boundary, a Null Object and an Option type, choose one, and say how you would make the change.

    What it tests
    Recognising inconsistent special cases as the real bug, choosing between data and behaviour for the missing case, and refactoring twelve call sites safely.
    First step
    First list the twelve checks and what each one does when the plan is missing: the differing defaults are a bug or a hidden rule, and the team must decide which before any refactoring. Then choose by whether a missing plan only changes values or also behaviour.
    Follow-ups

    From the lesson Code smells that point to a pattern

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  9. Mid to senior

    You have to change a 400-line pricing function that has no tests, reads the current date and a global settings object, and has a bug report open against it. Describe your first hour, step by step.

    What it tests
    Ordering the work safely: seams before tests, characterization before refactoring, and keeping the bug fix separate from the structural change.
    First step
    Do not touch the logic yet. First make the function callable from a test: add seams for the date and the settings, such as parameters with defaults, so existing callers do not change. Then record what it answers for many inputs, including the case from the bug report.
    Follow-ups

    From the lesson Refactoring safely with characterization tests

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  10. Mid to senior

    Your team's snapshot tests change on almost every pull request, and people approve the new snapshots without reading them. What has gone wrong, and how do you make the tests useful again?

    What it tests
    Knowing what makes snapshots unstable or too broad, restoring review of intended changes, and knowing when to replace a snapshot with focused tests.
    First step
    Look at what changes in a typical update. If it is timestamps, random ids or unordered output, the snapshot records noise; if it is whole pages of markup, it records far more than callers depend on. Either way, approving has become a reflex, so the test detects nothing.
    Follow-ups

    From the lesson Refactoring safely with characterization tests

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 2 minutes
  11. Mid to staff

    A service has 95 % line coverage, but a mutation testing run kills only 60 % of the mutants. What does that tell you, what do you do next, and how would you use mutation testing in a team without slowing everyone down?

    What it tests
    Understanding what coverage and mutation scores measure, triaging surviving mutants, recognising equivalent mutants, and fitting a slow tool into a team's workflow.
    First step
    Coverage says which lines ran; the mutation score says how many deliberate changes the tests noticed. So most lines run without their results being checked closely. Start with the surviving mutants in the code that matters most and changes most.
    Follow-ups

    From the lesson Refactoring safely with characterization tests

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  12. Mid to senior

    A test suite passes on developers' machines but fails in CI about one run in five, always in tests that send notifications through a Singleton. Explain the likely cause, and plan the refactoring away from the Singleton without one big change.

    What it tests
    Recognising shared state as the cause of order-dependent tests, and planning Inline Singleton as small steps that never break callers.
    First step
    Suspect test order: CI often runs tests in a different order, or in parallel. Run the failing tests alone and then after each of their neighbours; if one order fails, a test changes the Singleton's state and another depends on it.
    Follow-ups

    From the lesson Refactoring toward, and away from, patterns

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  13. Mid to senior

    You are moving three pricing flags, gift wrap, insurance and express delivery, into decorators. Insurance is a percentage of the total. What can go wrong with the order of the decorators, and how do you prove that the refactoring changed no price?

    What it tests
    Understanding that decorators compose in order, choosing a characterization strategy that covers every combination, and keeping the order in one place.
    First step
    Write down which extras depend on the total so far: insurance does, so whatever it wraps decides its base. Then pin the old function's answers for every combination of the three options, eight per basket, before moving anything.
    Follow-ups

    From the lesson Refactoring toward, and away from, patterns

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  14. Senior to staff

    A Java 25 code base has a Visitor over six AST node types with nine visitors. A colleague proposes replacing it with sealed interfaces and switch expressions. What do you weigh, and how would you migrate safely if you agree?

    What it tests
    Weighing Visitor against exhaustive pattern matching, knowing what the compiler checks in each design, and planning an incremental migration.
    First step
    Ask whether the node set is closed: if only this code base adds node types, a sealed interface lets the compiler check every switch, which is what the visitor interface did. If plugins add nodes, Visitor, or another open design, stays.
    Follow-ups

    From the lesson Refactoring toward, and away from, patterns

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes

All Design Patterns (GoF and modern) interview questions · The Design Patterns (GoF and modern) track

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.