Bird
Raised Fist0

Design a Social Media Profile System - User, Follow, Post, Like, Feed OOP

LLDhardInterview freq: high
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/4
FollowManager Singleton

FollowManager is a Singleton with a volatile instance field and synchronized getInstance method.

🎯 Tests whether candidate knows volatile prevents instruction reordering allowing safe lazy initialization in Java Singleton pattern.
public class FollowManager {
    private static volatile FollowManager instance;
    private FollowManager() {}
    public static synchronized FollowManager getInstance() {
        if (instance == null) {
            instance = new FollowManager();
        }
        return instance;
    }
}
User-FollowManager association

User class associates with FollowManager to manage follow relationships, but User lifecycle is independent (association).

🎯 Tests understanding of association vs composition: User exists independently, so FollowManager holds references but does not own User lifecycle.
public class User {
    private String userId;
    private String userName;
    public synchronized void follow(User other) {
        FollowManager.getInstance().addFollow(this, other);
    }
    public synchronized void unfollow(User other) {
        FollowManager.getInstance().removeFollow(this, other);
    }
}
FeedGenerator Singleton and Observer pattern

FeedGenerator is a Singleton responsible for generating user feeds, potentially observing FollowManager or Post updates (Observer pattern).

🎯 Tests if candidate understands Singleton with volatile and synchronized methods plus Observer pattern realization for feed updates.
public class FeedGenerator {
    private static volatile FeedGenerator instance;
    private FeedGenerator() {}
    public static synchronized FeedGenerator getInstance() {
        if (instance == null) {
            instance = new FeedGenerator();
        }
        return instance;
    }
    public List<Post> generateFeed(User user) {
        // Logic to aggregate posts from followed users
        return new ArrayList<>();
    }
}
Post class association with User

Post holds a reference to its author User, but User lifecycle is independent (association).

🎯 Tests understanding that Post references User without owning it, so association is correct to avoid lifecycle coupling.
public class Post {
    private String postId;
    private String content;
    private User author;
    public synchronized void like(User user) {
        // Increment likes count atomically
    }
    public int getLikesCount() {
        return 0; // return current likes count
    }
}
📐
Class Diagram
Class Diagram
       +----------------+
       |     <<class>>  |
       |      User      |
       +----------------+
       | -userId: String|
       | -userName: String|
       +----------------+
       | +follow(User):void [sync]|
       | +unfollow(User):void [sync]|
       | +createPost(String):Post|
       +----------------+
              │
              │ association (User follows other Users, independent lifecycle)
              │
       +----------------+
       | <<Singleton>>  |
       | FollowMgr     |
       +----------------+
       | -instance: volatile FollowMgr|
       | -followersMap: Map<User, Set<User>>|
       +----------------+
       | +getInstance(): FollowMgr [sync]|
       | +addFollow(follower, followee):void [sync]|
       | +removeFollow(follower, followee):void [sync]|
       +----------------+
              │
              │ composition (FollowMgr manages follow relationships tightly)
              │
       +----------------+
       | <<class>>      |
       |    Post        |
       +----------------+
       | -postId: String|
       | -content: String|
       | -author: User|
       +----------------+
       | +like(User):void [sync]|
       | +getLikesCount():int|
       +----------------+
              │
              │ association (Post references User author, User exists independently)
              │
       +----------------+
       | <<Singleton>>  |
       | FeedGen       |
       +----------------+
       | -instance: volatile FeedGen|
       +----------------+
       | +getInstance(): FeedGen [sync]|
       | +generateFeed(User): List<Post>|
       +----------------+

This class diagram illustrates four core classes of a social media profile system: User, FollowManager, Post, and FeedGenerator. FollowManager and FeedGenerator are implemented as thread-safe Singletons using volatile instance fields and synchronized getInstance methods to prevent unsafe publication and ensure safe lazy initialization. User and Post classes demonstrate association relationships, reflecting independent lifecycles where User can exist without Posts and vice versa. FollowManager composes follow relationships tightly, managing follower mappings internally. The design leverages the Observer pattern implicitly by having FeedGenerator respond to follow and post changes to generate user feeds. Synchronization on key methods ensures atomic state changes, enforcing thread safety in concurrent environments.

Primary Focus

✓ Singleton volatile + Observer pattern realization + Composition vs Association lifecycle

Practice

(1/5)
1. In a system using the Prototype pattern, should the Vehicle base type be an abstract class or an interface? Why?
easy
A. Abstract class, because it can hold common state and provide default cloning behavior
B. Interface, because it allows multiple inheritance and enforces method signatures without state
C. Interface, because cloning requires no shared implementation or state
D. Abstract class, because interfaces cannot declare clone() methods

Solution

  1. Step 1: Consider cloning and shared state

    Cloning often requires copying internal state; an abstract class can hold this state and provide a default clone() implementation.
  2. Step 2: Evaluate interface limitations

    Interfaces define behavior but cannot hold state or provide default cloning logic (in Java before default methods). Thus, abstract class fits better.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Abstract class holds state + cloning logic -> correct OOP design [check]
Hint: Clone needs shared state -> abstract class better than interface [check]
Common Mistakes:
2. In the Jigsaw Puzzle System, the Board class has a placePiece() method that first checks if a position is free and then places the piece. Without synchronizing placePiece(), what exact sequence of thread interleaving causes two threads to place different pieces at the same position (double-booking)?
medium
A. Thread 1 checks position free -> true, context switch; Thread 2 checks position free -> true; both place pieces concurrently.
B. Thread 1 places piece, Thread 2 waits, then places piece after Thread 1 finishes.
C. Thread 1 and Thread 2 both call placePiece() but on different board instances, causing no conflict.
D. Thread 1 locks the board, Thread 2 spins waiting, so no double-booking occurs.

Solution

  1. Step 1: Identify the check-then-act race condition

    Without synchronization, Thread 1 checks position free and sees true, but before placing, context switches.
  2. Step 2: Thread 2 also checks position free -> true and proceeds to place piece concurrently, causing double-booking.

  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Unsynchronized check-then-act allows both threads to place pieces at same position [check]
Hint: Check-then-act without sync -> double-booking race [check]
Common Mistakes:
3. In the ESPNcricinfo system, the Scorecard class has a recordBall() method that checks if the ball is valid and then updates the score. Without synchronizing recordBall(), what exact sequence of Thread 1 and Thread 2 causes double-counting of runs?
medium
A. Thread 1 and Thread 2 both call recordBall() simultaneously and both update the score atomically.
B. Thread 1 checks ball validity -> valid, context switch; Thread 2 checks ball validity -> valid; both update score causing double-count.
C. Thread 1 updates score, then Thread 2 reads stale score and overwrites it with old value.
D. Thread 1 and Thread 2 both wait on a lock causing deadlock and no score update.

Solution

  1. Step 1: Identify check-then-act race condition

    Both threads check ball validity before updating score; without synchronization, both see valid state.
  2. Step 2: Trace interleaving causing double-count

    Thread 1 checks valid -> context switch; Thread 2 checks valid -> both proceed to update score independently causing double-count.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Check-then-act gap without sync -> double update [check]
Hint: Check-then-act gap -> both threads proceed -> double update [check]
Common Mistakes:
4. You want to add a WeekendFeeStrategy to calculate weekend parking fees without modifying existing classes. Which SOLID principle guides the minimum change, and what is the correct approach?
medium
A. Modify the ParkingLot class to add weekend fee logic, enforcing Single Responsibility Principle.
B. Add weekend fee logic inside existing FeeStrategy implementations, following Dependency Inversion Principle.
C. Create a WeekendFeeStrategy subclass of ParkingLot to override fee calculation, following Liskov Substitution Principle.
D. Create a new WeekendFeeStrategy class implementing FeeStrategy interface, and inject it where needed, following Open/Closed Principle.

Solution

  1. Step 1: Identify the SOLID principle for extensibility

    Open/Closed Principle (OCP) requires adding new functionality without modifying existing code.
  2. Step 2: Evaluate approaches

    Creating a new FeeStrategy implementation and injecting it respects OCP and DIP; modifying ParkingLot or existing strategies violates OCP or mixes responsibilities.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    New FeeStrategy class + injection -> OCP and DIP respected [check]
Hint: New strategy class + injection -> Open/Closed Principle [check]
Common Mistakes:
5. The Restaurant Management System needs to support ElectricCar vehicles that require ChargingSpots. What is the minimum change to the current Java design to add this feature without modifying existing classes?
hard
A. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally.
B. Modify Vehicle class to include a boolean isElectric field and add charging logic inside existing methods.
C. Create a new ChargingSpot class extending Spot and modify TableManager to handle charging spots explicitly.
D. Add charging logic inside the existing Spot class and modify all subclasses to support electric vehicles.

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    Adding new enum values and subclasses without changing existing classes respects OCP and avoids class explosion.
  2. Step 2: Update compatibility externally

    Updating SpotCompatibility map outside existing classes allows new vehicle and spot types to integrate without modifying existing code.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    New enums + subclass + external compatibility update -> minimal change [check]
Hint: Add enums + subclass + external map update -> minimal change [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard