# interview: 30 design pattern interview questions, each with a test Companion module for the article [Top 30 Design Patterns Interview Questions in Java (with Code)](https://ankurm.com/design-patterns-interview-questions-java/). Every claim in the article is an assertion in a test here; each test also writes the facts it checked to `output/`. Unlike the rest of this repository (plain `javac`), this module uses Maven because the tests need JUnit and Spring Framework. | | | |---|---| | JDK | 25 (Temurin 25.0.5) | | Spring Framework | 7.0.10 (`spring-context`, `spring-tx`) | | JUnit | 6.1.3 | | AssertJ | 3.27.7 | ## Run ```bash cd interview ./scripts/run-all.sh # runs mvn test, regenerates every file in output/ ``` ## Questions | Q | Topic | Source | Test | Output | |---|---|---|---|---| | 1 | Eager singleton | `singleton/EagerSingleton.java` | `SingletonInterviewTest` | `01-singleton.txt` | | 2 | Lazy singleton is not thread-safe | `singleton/NaiveLazySingleton.java` | `SingletonInterviewTest` | `01-singleton.txt` | | 3 | `synchronized` getInstance | `singleton/SynchronizedSingleton.java` | `SingletonInterviewTest` | `01-singleton.txt` | | 4 | Double-checked locking needs `volatile` | `singleton/DclSingleton.java`, `DclWithoutVolatile.java` | `SingletonInterviewTest` | `01-singleton.txt` | | 5 | Holder idiom | `singleton/HolderSingleton.java` | `SingletonInterviewTest` | `01-singleton.txt` | | 6 | Enum singleton vs serialization and reflection | `singleton/EnumSingleton.java`, `ClassicSingleton.java`, `HardenedSingleton.java` | `SingletonInterviewTest` | `01-singleton.txt` | | 7 | Spring singleton scope vs GoF Singleton | `spring/ScopeDemo.java` | `SingletonInterviewTest` | `01-singleton.txt` | | 8 | Simple factory vs Factory Method | `creational/SimpleFactory.java`, `Dialog.java` | `CreationalAndBehavioralTest` | `02-creational.txt` | | 9 | Factory Method vs Abstract Factory | `creational/GuiFactory.java` | `CreationalAndBehavioralTest` | `02-creational.txt` | | 10 | Builder vs Factory | `creational/HttpCall.java` | `CreationalAndBehavioralTest` | `02-creational.txt` | | 11 | Prototype: shallow vs deep copy | `creational/Doc.java` | `CreationalAndBehavioralTest` | `02-creational.txt` | | 12 | Strategy vs State | `behavioral/Order.java`, `Checkout.java` | `CreationalAndBehavioralTest` | `03-behavioral.txt` | | 13 | Strategy as a lambda | `behavioral/Checkout.java` | `CreationalAndBehavioralTest` | `03-behavioral.txt` | | 14 | Observer: unsubscribing while notified | `behavioral/EventSource.java` | `CreationalAndBehavioralTest` | `03-behavioral.txt` | | 15 | Template Method vs Strategy | `behavioral/ReportJob.java` | `CreationalAndBehavioralTest` | `03-behavioral.txt` | | 16 | Chain of Responsibility | `behavioral/Pipeline.java` | `CreationalAndBehavioralTest` | `03-behavioral.txt` | | 17 | Command with undo | `behavioral/Editor.java` | `CreationalAndBehavioralTest` | `03-behavioral.txt` | | 18 | Visitor vs sealed switch | `behavioral/Expr.java`, `src/broken/Q18Broken.java` | `CreationalAndBehavioralTest` | `03-behavioral.txt`, `06-q18-compile-error.txt` | | 19 | Decorator vs Proxy | `structural/Storage.java` | `StructuralTest` | `04-structural.txt` | | 20 | JDK dynamic proxy | `structural/Greeter.java` | `StructuralTest` | `04-structural.txt` | | 21 | Adapter vs Facade | `structural/Adapters.java` | `StructuralTest` | `04-structural.txt` | | 22 | Composite | `structural/FileNode.java` | `StructuralTest` | `04-structural.txt` | | 23 | Flyweight | `structural/GlyphFactory.java` | `StructuralTest` | `04-structural.txt` | | 24 | Factory in Spring: `FactoryBean` | `spring/Beans.java` | `SpringPatternsTest` | `05-spring.txt` | | 25 | Proxy in Spring: JDK vs CGLIB | `spring/Shared.java` | `SpringPatternsTest` | `05-spring.txt` | | 26 | Proxy traps: self-invocation, final methods | `spring/Shared.java` | `SpringPatternsTest` | `05-spring.txt` | | 27 | Observer in Spring: events | `spring/Beans.java` | `SpringPatternsTest` | `05-spring.txt` | | 28 | Template/callback: `TransactionTemplate` | (test only) | `SpringPatternsTest` | `05-spring.txt` | | 29 | Strategy by injection | `spring/Beans.java` | `SpringPatternsTest` | `05-spring.txt` | | 30 | Prototype inside a singleton | `spring/Beans.java` | `SpringPatternsTest` | `05-spring.txt` | ## What is NOT proven here Q4: the missing-`volatile` failure is allowed by the Java Memory Model but is practically unobservable on x86, so the test asserts the modifier (`volatile` present in `DclSingleton`, absent in `DclWithoutVolatile`) rather than reproducing a torn read. Q2 relies on a 20 ms sleep inside the constructor to make the race reliable; the exact number of extra instances varies per run, so the test only asserts "more than one".