Bird
Raised Fist0

Design Facebook in OOP - User, Friend, Post, Group, Event, Privacy Model

LLDmediumInterview freq: high
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/3
User and FriendRequest inheritance and composition

User is an abstract class with state (id, name, friends) and FriendRequest extends User showing inheritance. FriendRequest composes two User references (fromUser, toUser) representing composition with lifecycle ownership.

🎯 Tests whether candidate understands abstract class usage for shared state and composition for lifecycle ownership of FriendRequest's users.
public abstract class User {
    protected String id;
    protected String name;
    protected List<User> friends;
    public abstract void sendFriendRequest(User toUser);
    public abstract void acceptFriend(User fromUser);
}
public class FriendRequest extends User {
    private User fromUser;
    private User toUser;
    private enum Status {PENDING, ACCEPTED, REJECTED}
    private Status status;
    public synchronized void accept() {
        this.status = Status.ACCEPTED;
        // add to friends list
    }
    public void reject() {
        this.status = Status.REJECTED;
    }
}
Post class composition and PrivacyStrategy interface realization

Post composes a PrivacyStrategy interface reference to delegate privacy checks, illustrating composition with independent lifecycle. PrivacyStrategy is an interface realized by concrete classes.

🎯 Tests candidate's knowledge of Strategy pattern using interface for OCP and composition for flexible privacy behavior.
public class Post {
    private String content;
    private PrivacyStrategy privacy;
    public void setPrivacy(PrivacyStrategy privacy) {
        this.privacy = privacy;
    }
    public boolean canView(User user) {
        return privacy.canView(user, this);
    }
}
public interface PrivacyStrategy {
    boolean canView(User user, Post post);
}
Concrete PrivacyStrategy implementations

FriendsOnlyPrivacyStrategy and PublicPrivacyStrategy realize PrivacyStrategy interface, providing different privacy behaviors without modifying Post class, enforcing OCP.

🎯 Tests whether candidate explains interface realization enables extensibility without modifying existing classes (OCP) and why interface is used over abstract class here.
public class FriendsOnlyPrivacyStrategy implements PrivacyStrategy {
    public boolean canView(User user, Post post) {
        // check if user is friend of post owner
        return true; // simplified
    }
}
public class PublicPrivacyStrategy implements PrivacyStrategy {
    public boolean canView(User user, Post post) {
        return true; // everyone can view
    }
}
📐
Class Diagram
Class Diagram
       +----------------+
       |    <<Abstract>>|
       |      User      |
       +----------------+
       | -id: String    |
       | -name: String  |
       | -friends: List |
       +----------------+
       | +sendFriendReq |
       | +acceptFriend  |
       | +createPost()  |
       +----------------+
              │ extends
              │
       +----------------+
       | FriendRequest  |
       +----------------+
       | -fromUser: User|
       | -toUser: User  |
       | -status: enum  |
       +----------------+
       | +accept() [sync]|
       | +reject()      |
       +----------------+
              │
              │ composition
              │
       +----------------+
       |     Post       |
       +----------------+
       | -content: String|
       | -privacy: PrivacyStrat|
       +----------------+
       | +setPrivacy()  |
       | +canView(User):bool|
       +----------------+
              │ ─ ─ ─► realization
              │
       +----------------------------+
       |     PrivacyStrategy        |
       |     <<Interface>>          |
       +----------------------------+
       | +canView(User, Post):bool |
       +----------------------------+
              │ ─ ─ ─► realization
              │
       +----------------------------+
       |  FriendsOnlyPrivacyStrategy|
       +----------------------------+
       | +canView(User, Post):bool  |
       +----------------------------+
              │ ─ ─ ─► realization
              │
       +----------------------------+
       |  PublicPrivacyStrategy     |
       +----------------------------+
       | +canView(User, Post):bool  |
       +----------------------------+

This class diagram illustrates key Java OOP design decisions for Facebook's core entities. User is an abstract class holding shared state like id and friends list, which interfaces cannot hold, justifying abstract class usage. FriendRequest extends User and composes two User references, showing composition with lifecycle ownership. Post composes a PrivacyStrategy interface reference, enabling flexible privacy behavior via the Strategy pattern, adhering to the Open-Closed Principle by allowing new privacy strategies without modifying Post. PrivacyStrategy is an interface realized by concrete classes FriendsOnlyPrivacyStrategy and PublicPrivacyStrategy, demonstrating interface realization for extensibility. The FriendRequest's accept method is synchronized to ensure thread-safe state changes, illustrating precise concurrency control in Java.

Primary Focus

✓ Inheritance vs Realization + Composition lifecycle + Strategy pattern OCP + synchronized method usage

Practice

(1/5)
1. In the Food Ordering System, should the MenuItem be designed as an abstract class or an interface, considering it has both state (price, description) and behavior (calculateDiscount)? Why?
easy
A. Abstract class, because it can hold shared state like price and provide default behavior implementations.
B. Interface, because it allows multiple inheritance and enforces behavior without state.
C. Interface, because state can be stored externally and behavior defined in default methods.
D. Abstract class, because interfaces cannot define any methods with implementation.

Solution

  1. Step 1: Analyze state and behavior requirements

    MenuItem holds state (price, description) and behavior (calculateDiscount) that should be shared or overridden.
  2. Step 2: Abstract class vs interface capabilities

    Abstract classes can hold state and provide default method implementations; interfaces cannot hold instance state (before Java 8+ default methods, but still no fields).
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    State + behavior with shared code -> Abstract class [check]
Hint: State + behavior together -> abstract class, not interface [check]
Common Mistakes:
2. In the ATM system, the TransactionManager class has a processTransaction() method that checks if the ATM is available and then marks it busy. Without synchronization on this method, which exact thread interleaving causes double processing of transactions?
medium
A. Thread 1 and Thread 2 both call processTransaction() simultaneously and both fail immediately due to busy ATM.
B. Thread 1 checks isAvailable() -> true, context switch before marking busy; Thread 2 checks isAvailable() -> true, both proceed to process.
C. Thread 1 marks ATM busy, then Thread 2 checks isAvailable() -> false and waits, preventing double processing.
D. Thread 1 and Thread 2 both wait on a lock, so only one processes at a time, no double processing.

Solution

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

    Without synchronization, Thread 1 reads isAvailable() as true but is preempted before marking busy.
  2. Step 2: Thread 2 also reads isAvailable() as true and proceeds, causing both to process simultaneously.

    This is the classic check-then-act race leading to double processing.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Check isAvailable true twice before marking busy -> double processing [check]
Hint: Check-then-act without sync -> double processing 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. The current Tic-Tac-Toe design uses a WinStrategy interface for win detection. To add a WeekendWinBonusStrategy that applies only on weekends, what is the minimum change required to comply with SOLID principles?
medium
A. Create a new WeekendWinBonusStrategy class implementing WinStrategy and use it without modifying existing classes.
B. Add a boolean flag in the Board class to toggle weekend mode and update all win checks accordingly.
C. Modify the existing WinStrategy implementations to check the day and apply bonus logic.
D. Combine all win detection logic including weekend bonus into a single monolithic class.

Solution

  1. Step 1: Understand OCP and DIP in current design

    Open-Closed Principle (OCP) requires adding new behavior without modifying existing classes. Dependency Inversion Principle (DIP) encourages depending on abstractions.
  2. Step 2: Evaluate options for minimal change

    Create a new WeekendWinBonusStrategy class implementing WinStrategy and use it without modifying existing classes. adds a new strategy class but requires changing client code to use it, violating minimal change. Add a boolean flag in the Board class to toggle weekend mode and update all win checks accordingly. adds a toggle flag in Board, allowing existing strategies to adapt behavior without modifying their code, preserving OCP better than A or D.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Toggle flag in Board -> minimal change, respects OCP [check]
Hint: OCP: add new class or toggle flag, avoid modifying existing [check]
Common Mistakes:
5. In a parking lot system, parkVehicle() checks if a spot is available and then marks it occupied. Without synchronized, which exact thread interleaving causes double-booking?
medium
A. Thread 1 checks isAvailable() -> true, context switch before marking occupied; Thread 2 checks isAvailable() -> true, both mark occupied.
B. Thread 1 marks spot occupied, Thread 2 waits and then parks after spot is free.
C. Thread 1 parks vehicle, Thread 2 parks vehicle on a different spot simultaneously.
D. Thread 1 releases spot, Thread 2 parks vehicle immediately after.

Solution

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

    Without synchronization, Thread 1 reads spot as available but is preempted before marking it occupied. Thread 2 also reads available and proceeds to mark occupied.
  2. Step 2: Explain how this leads to double-booking

    Both threads believe the spot is free and mark it occupied independently, causing two vehicles to be assigned the same spot simultaneously.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Check-then-act gap without synchronization -> double-booking [check]
Hint: Check-then-act gap: both see available before marking occupied [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