Skip to content
LLD Learn/Creational Patterns
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Singleton (and Why Interviewers Push Back)

7 min read

You'll learn to

  • -Implement a thread-safe Singleton and explain the double-checked locking and eager-initialization variants
  • -Articulate why interviewers often treat Singleton as an anti-pattern - global state, hidden dependencies, and test difficulty

Singleton guarantees a class has exactly one instance and provides a single global point of access to it - a logger, a configuration manager, or a connection pool are the classic candidates. It is also the pattern most likely to trigger pushback from an interviewer, and understanding why is more valuable than memorizing the implementation.

A Correct, Thread-Safe Implementation

Double-checked locking - the interview-standard thread-safe Singleton
import threading

class ConfigManager:
    _instance = None
    _lock = threading.Lock()

    def __new__(cls):
        if cls._instance is None:          # first check, no lock (fast path)
            with cls._lock:
                if cls._instance is None:  # second check, inside the lock
                    cls._instance = super().__new__(cls)
        return cls._instance

The double check matters: without the outer check, every single call acquires the lock, even after the instance already exists - a needless bottleneck. Without the inner check, two threads could both pass the outer check simultaneously and both proceed to construct an instance before either sets _instance, creating two "singletons." The lock, combined with re-checking inside it, closes that race.

Why Interviewers Push Back Anyway

  • -Hidden dependencies: any class can call ConfigManager() directly from anywhere, so its dependency on configuration never appears in its constructor signature - you cannot tell what a class needs just by reading its interface.
  • -Global mutable state: if the Singleton holds mutable state, every part of the codebase that touches it can affect every other part, which is exactly the kind of coupling SOLID spends five principles trying to prevent.
  • -Testing difficulty: a global singleton persists across test cases unless explicitly reset, which creates test pollution - one test's side effect leaks into the next test's assumptions.
  • -It quietly violates Dependency Inversion: high-level classes end up depending on a concrete global instance instead of an injected abstraction.

The stronger interview answer is rarely "never use Singleton" - genuinely singleton-scoped resources (a single hardware resource, a single OS-level lock) legitimately exist. The stronger answer is recognizing the trade-off and, where possible, achieving the same "one instance" guarantee via dependency injection instead - construct exactly one instance at application startup and pass it explicitly to everything that needs it, rather than letting every consumer reach into a global.

If you reach for Singleton in an interview, say why out loud, and mention the DI-based alternative you considered. Silently using it as your default tool for "there should be one of these" reads as reaching for the first pattern you remember rather than the one the requirement actually calls for.

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.

ScaleDojo Logo
Initializing ScaleDojo