What this topic covers
26 subtopics- Singleton5
- Strategy5
- Decorator4
- Factory3
- Observer3
- Basics2
- Command2
- Composite2
- Iterator2
- Adapter1
- Builder1
- Chain of Responsibility1
Show all 26 subtopics
- Choosing patterns1
- Creational patterns1
- Facade1
- Flyweight1
- Mediator1
- Memento1
- Null Object1
- Pipeline1
- Prototype1
- Proxy1
- State1
- Structural patterns1
- Template Method1
- Visitor1
- Beginner 15
- Intermediate 15
- Advanced 15
About this topic
Design patterns are named, reusable solutions to problems that keep coming back in object-oriented code. The Gang of Four grouped them as creational (how objects are made), structural (how objects are composed) and behavioural (how objects share work). Interviews ask you to recognise a pattern from a diagram or a description, and to predict what a small implementation prints. Every implementation here was run, and the structures are drawn as UML.
Free preview
Sample questions
Try each one first, then open the answer for the explanation and why the other options are wrong.
Which grouping of Gang of Four patterns is correct?
Show answer and explanation
Explanation
Creational patterns control object creation, structural ones compose classes and objects, behavioural ones distribute responsibilities and communication.
Why the other options are wrong
- AEach is in the wrong group.
- CThere are three groups.
- DEach is in the wrong group.
What does this print?
import java.util.*;
import java.util.function.Consumer;
public class Main {
static class EventBus {
private final List<Consumer<String>> listeners = new ArrayList<>();
Runnable subscribe(Consumer<String> l) {
listeners.add(l);
return () -> listeners.remove(l);
}
void publish(String e) { for (Consumer<String> l : List.copyOf(listeners)) l.accept(e); }
}
public static void main(String[] args) {
EventBus bus = new EventBus();
StringBuilder out = new StringBuilder();
Runnable stopA = bus.subscribe(e -> out.append("A:").append(e).append(' '));
bus.subscribe(e -> out.append("B:").append(e).append(' '));
bus.publish("login");
stopA.run();
bus.publish("logout");
System.out.println(out.toString().trim());
}
}
Show answer and explanation
Explanation
subscribe returns an "unsubscribe" handle; after it runs, A no longer receives events. Iterating over a copy lets a listener unsubscribe during a publish without a ConcurrentModificationException.
Why the other options are wrong
- AB still receives logout.
- BA received login.
- CA unsubscribed before logout.
Joshua Bloch recommends an enum singleton. What does this print?
public class Main {
enum IdGenerator {
INSTANCE;
private long next = 1000;
synchronized long nextId() { return next++; }
}
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> { for (int i = 0; i < 500; i++) IdGenerator.INSTANCE.nextId(); });
t.start();
for (int i = 0; i < 500; i++) IdGenerator.INSTANCE.nextId();
t.join();
System.out.println(IdGenerator.INSTANCE.nextId() + " " + (IdGenerator.valueOf("INSTANCE") == IdGenerator.INSTANCE));
}
}
Show answer and explanation
Explanation
The JVM guarantees exactly one INSTANCE, created thread-safely, and enums cannot be cloned or duplicated through serialisation or reflection. synchronized makes the counter safe across both threads: 1000 + 1000 ids handed out, so the next is 2000.
Why the other options are wrong
- A1000 ids were already handed out.
- BThere is only one instance.
- Dsynchronized prevents lost updates.