Creational PatternsSingleton PatternHard⏱️ ~3 min

Singleton Pattern: Common Interview Questions

Question 1: How do you make Singleton thread-safe?
Answer: Three approaches, each with trade-offs:

First, Eager Initialization: Create instance at class load time before any threads run. Thread-safe by default because class loading is synchronized by the class loader. Drawback: Instance created even if never used.

class Singleton:
  instance = new Singleton() // at class load
  public static getInstance():
    return instance // always thread-safe
Second, Synchronized Method: Add synchronization to getInstance() to prevent concurrent creation. Drawback: Every call acquires a lock, even after initialization completes, causing performance bottleneck.

public static synchronized getInstance():
  if instance is null:
    instance = new Singleton()
  return instance
Third, Double-Checked Locking: Check null without lock first (fast path). Only acquire lock if null, then check again inside lock (slow path). Critical: Instance variable must be marked volatile or equivalent to prevent instruction reordering. Best choice when lazy initialization is needed and performance matters.

instance = null // must be volatile

public static getInstance():
  if instance is null: // first check (no lock)
    lock():
      if instance is null: // second check (with lock)
        instance = new Singleton()
  return instance
Interview Tip: Explain why double-checked locking needs two null checks. Without the second check inside the lock, two threads could both pass the first check, and both would create instances.
Question 2: How do you prevent Singleton from being cloned or serialized?
Cloning Attack: If Singleton implements Cloneable, calling clone() creates a second instance, violating the pattern.

Solution: Override clone() to throw an exception:

public clone():
  throw new CloneNotSupportedException("Cannot clone singleton")
Serialization Attack: Deserializing a serialized singleton creates a new instance because deserialization bypasses the constructor.

Solution: Implement readResolve() method to return the existing instance:

private readResolve():
  return getInstance() // return existing instance
Better Approach: Use enum-based singleton (language-dependent). Enums prevent both cloning and serialization attacks by default and are inherently thread-safe.
Question 3: Design a ConfigurationManager as Singleton for a Library Management System.
Requirements: Load configuration once from file, provide settings to all components, support reloading without restart.

Design:
ConfigurationManager
- instance: ConfigurationManager
- settings: Map<String, String>
- filePath: String
- lastModified: Timestamp
- ConfigurationManager()
+ getInstance(): ConfigurationManager
+ getSetting(key: String): String
+ setSetting(key: String, value: String): void
+ reloadFromFile(): void
+ getMaxBorrowDays(): Integer
+ getLateFeePerDay(): Money
Key Design Decisions:

First, Private constructor loads settings from filePath into settings map during initialization.

Second, getSetting(key) provides type-agnostic access. Convenience methods like getMaxBorrowDays() parse and return typed values.

Third, reloadFromFile() re-reads the file and updates settings map. Critical: This method must be synchronized to prevent race conditions if called while other threads read settings. Alternatively, use copy-on-write strategy: create new map, populate it, then atomically swap the reference.

Fourth, lastModified timestamp tracks file changes. A background thread can periodically check if the file changed and auto-reload.

Testing Consideration: To make testable, add a method setInstanceForTesting(ConfigurationManager mock) that replaces the singleton with a test double, but mark it clearly as test-only and ensure production code never calls it.
Question 4: When would you use multiple singletons versus one singleton managing multiple instances?
Multiple Singletons: Use when you have multiple independent logical resources. Example: ConfigurationManager.getInstance(), Logger.getInstance(), CacheManager.getInstance(). Each manages its own domain and does not interact directly.

One Singleton Managing Multiple Instances: Use when you have one coordinator that manages multiple similar resources. Example: DatabaseConnectionPoolManager.getInstance() manages multiple connection pools (one per database). The manager is singleton, the pools are not.

Decision Rule: If the resources need centralized coordination or resource limits (total connections across all pools cannot exceed X), use one manager singleton. If resources are independent, use separate singletons or avoid singletons entirely through DI.
Interview Tip: Explain that machine coding rounds test your ability to balance pattern theory with practical concerns like testability and thread safety. Always ask clarifying questions about concurrency requirements and testing strategy.
Question 5: What is the relationship between Singleton and the Open/Closed Principle (OCP)?
Tension: Singleton often violates OCP (Open/Closed Principle) because direct calls to Singleton.getInstance() tightly couple code to the concrete class. If you need to extend or modify singleton behavior, you must change existing code rather than extending through inheritance.

Resolution: Program to an interface, not the singleton directly. Define IConfigurationManager interface, have singleton implement it, and inject the interface. Now you can create alternative implementations (mock configurations, remote configurations) without modifying client code. The singleton still exists but is accessed through abstraction, preserving OCP.
💡 Key Takeaways
Thread safety requires eager initialization, synchronized methods, or double-checked locking
Double-checked locking needs volatile variable and two null checks
Prevent cloning by throwing exception in clone() method
Prevent serialization attack by implementing readResolve() to return existing instance
ConfigurationManager singleton should support reloading with thread-safe updates
Use multiple singletons for independent resources; one manager for coordinated resources
Singleton can violate Open/Closed Principle; use interfaces to mitigate coupling
📌 Examples
1Thread-safe Logger using double-checked locking
2ConfigurationManager with readResolve() to handle deserialization
3DatabaseConnectionPoolManager singleton managing multiple connection pool instances
← Back to Singleton Pattern Overview
Singleton Pattern: Common Interview Questions | Singleton Pattern - System Overflow