Files
design-patterns/interview/README.md
T

65 lines
4.7 KiB
Markdown

# 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".