Bird
Raised Fist0

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

LLDmediumInterview freq: high
Choose your preparation mode4 modes available
๐ŸŽฏ
Design Facebook in OOP - User, Friend, Post, Group, Event, Privacy Model
40 min ยท hard
hard

Design a social networking system like Facebook that supports users, friendships, posts with privacy controls, groups, and events. The system must handle privacy settings at multiple levels and ensure thread-safe updates to user relationships and posts.

  • Users can send and accept friend requests; friendship is mutual and must be consistent under concurrent requests.
  • Posts have privacy settings: PUBLIC, FRIENDS_ONLY, GROUP_ONLY, or CUSTOM (specific users).
  • Groups have members and admins; only admins can add/remove members and moderate posts.
  • Events are created by users and can have invitees with RSVP status.
  • Privacy checks must be efficient and thread-safe to handle concurrent reads and writes.
๐Ÿ“‹
Guided Steps
1/5
Step 1
Design User and Friend Relationship Model
Design the User class and the friend relationship management ensuring mutual friendship consistency under concurrency.
๐Ÿ’ก Hint
Use synchronized methods or locks to atomically update friend lists. Use a Set<User> for friends to avoid duplicates.
User class with private final Set<User> friends guarded by synchronized addFriend(User) and removeFriend(User) methods to ensure atomic mutual friendship updates.
Mid: Uses synchronized methods to update friends. Senior: Explains thread interleaving where Thread 1 adds friend A, Thread 2 removes friend A concurrently, and how synchronized prevents inconsistent state.
โš ๏ธCommon Wrong Answer
Using unsynchronized HashSet for friends leads to race conditions where one thread adds a friend while another removes, causing inconsistent friendship state and potential ConcurrentModificationException.
Step 2
Implement Post with Privacy Model
Design the Post class with privacy settings and efficient privacy checks for viewing posts.
๐Ÿ’ก Hint
Use an enum for PrivacyLevel. Store custom allowed viewers as a thread-safe collection like CopyOnWriteArraySet. Use volatile for privacyLevel field if it can change.
Post class with volatile PrivacyLevel privacyLevel and thread-safe Set<User> customViewers using CopyOnWriteArraySet to allow concurrent reads without locking.
Mid: Uses enum PrivacyLevel and thread-safe collections. Senior: Explains why volatile is needed for privacyLevel to ensure visibility of updates across threads without locking.
โš ๏ธCommon Wrong Answer
Using String for privacy levels causes runtime bugs due to typos and no compile-time checks; using non-thread-safe collections for viewers causes visibility and concurrency bugs.
Step 3
Design Group with Membership and Admin Controls
Design the Group class managing members and admins with thread-safe add/remove operations and role checks.
๐Ÿ’ก Hint
Use composition: Group has Sets of User for members and admins. Use synchronized blocks or concurrent collections for thread safety. Admins must be a subset of members.
Group class with private final ConcurrentHashMap<User, Boolean> members and admins; synchronized methods addMember(User), removeMember(User), addAdmin(User) enforcing admins โІ members invariant.
Mid: Uses concurrent collections for members and admins. Senior: Explains how synchronized methods prevent race conditions where a user is removed from members but still remains admin, violating invariants.
โš ๏ธCommon Wrong Answer
Using separate unsynchronized Sets for members and admins leads to inconsistent state where a user can be admin but not a member, violating business rules.
Step 4
Design Event with Invitees and RSVP Status
Design the Event class supporting invitees with RSVP statuses and thread-safe updates.
๐Ÿ’ก Hint
Use an enum RSVPStatus. Store invitees in a ConcurrentHashMap<User, RSVPStatus> for atomic updates. Use synchronized methods for adding/removing invitees.
Event class with private final ConcurrentHashMap<User, RSVPStatus> invitees; synchronized methods updateRSVP(User, RSVPStatus) to atomically update RSVP status.
Mid: Uses enum RSVPStatus and concurrent map for invitees. Senior: Explains thread interleaving where two threads update RSVP concurrently and how synchronized updateRSVP prevents lost updates.
โš ๏ธCommon Wrong Answer
Using a non-thread-safe Map for invitees causes race conditions and inconsistent RSVP states under concurrent updates.
Step 5
Implement Efficient Privacy Checks Across Entities
Design a privacy check mechanism that efficiently determines if a user can view a post or event considering privacy settings and group memberships.
๐Ÿ’ก Hint
Use method boolean canView(User viewer) in Post and Event. Cache group membership lookups if needed. Use volatile or synchronized to ensure visibility of privacy-related state.
Implement canView(User) with volatile privacy fields and synchronized access to group membership data; cache group membership in ConcurrentHashMap for O(1) lookups.
Mid: Implements canView with correct privacy logic. Senior: Explains how volatile and concurrent collections ensure visibility and atomicity of privacy state during concurrent reads/writes.
โš ๏ธCommon Wrong Answer
Not synchronizing privacy checks or using stale cached data leads to incorrect access decisions and privacy leaks.
๐Ÿ”Œ
API Design Challenge
Design APIs for managing users, friendships, posts with privacy controls, groups with admin roles, and events with RSVP functionality ensuring thread safety and consistency.
  • Design User APIs with synchronized methods for friend management to ensure mutual friendship consistency.
  • Use enums and thread-safe collections in Post APIs to handle privacy settings and custom viewers.
  • Implement Group APIs with synchronized methods enforcing admins are always members, using concurrent collections.
๐Ÿ“Š
Scoring Rubric
โ–ผ Show
Must Have - 60%
  • User class with synchronized addFriend(User) and removeFriend(User) methods
  • Post class with volatile PrivacyLevel privacyLevel and thread-safe custom viewers collection
  • Group class with synchronized methods enforcing admins โІ members invariant using concurrent collections
  • Event class with synchronized updateRSVP(User, RSVPStatus) and concurrent invitees map
  • Use of enums for PrivacyLevel and RSVPStatus to ensure type safety and exhaustive checks
Good to Have - 30%
  • Efficient caching of group membership lookups for privacy checks
  • Use of CopyOnWriteArraySet for custom viewers in Post
  • Detailed explanation of thread interleaving scenarios in concurrency
  • Clear separation of concerns in class design with composition and aggregation
Bonus - 10%
  • Use of volatile for visibility without locking overhead
  • Synchronized methods for atomic compound operations
  • Comprehensive privacy check logic covering all privacy levels
โœ…
Model Answer
โ–ผ Reveal

This design models Facebook's core features focusing on thread-safe user friendships, posts with privacy controls, groups with admin roles, events with RSVP, and efficient privacy checks. Java concurrency primitives like synchronized methods, volatile fields, and concurrent collections ensure consistency and visibility under concurrent access.

  • Use of synchronized methods in User to atomically update friend relationships preventing race conditions.
  • Volatile PrivacyLevel field in Post to ensure visibility of privacy changes across threads without locking.
  • CopyOnWriteArraySet for custom viewers in Post to allow concurrent reads and writes without explicit synchronization.
  • ConcurrentHashMap for Group members and admins with synchronized methods enforcing admins โІ members invariant.
  • ConcurrentHashMap for Event invitees with synchronized updateRSVP method to ensure atomic RSVP updates.
  • Enums for PrivacyLevel and RSVPStatus to prevent runtime errors and enable exhaustive switch-case handling.
  • Caching group membership lookups in ConcurrentHashMap to optimize privacy checks with O(1) access.
  • Synchronized privacy check methods to ensure up-to-date and thread-safe access control decisions.
  • User class uses synchronized methods to atomically add/remove friends ensuring mutual friendship consistency (Thread 1 adds friend, Thread 2 removes friend interleaving explained).
  • Post class uses enum PrivacyLevel and volatile privacyLevel field to guarantee visibility of privacy changes across threads without locking.
  • Custom viewers in Post stored in CopyOnWriteArraySet for thread-safe concurrent reads and writes without explicit synchronization.
  • Group class uses ConcurrentHashMap for members and admins with synchronized methods enforcing admins โІ members invariant to maintain consistent roles.
  • Event class stores invitees and RSVP statuses in ConcurrentHashMap with synchronized updateRSVP method to prevent lost updates under concurrent modifications.
  • Privacy checks implemented with volatile fields and synchronized access to group membership data to ensure up-to-date and thread-safe access control decisions.
  • Enums used for PrivacyLevel and RSVPStatus to prevent runtime bugs from string typos and enable exhaustive switch statements.
  • Composition relationships: User owns friends (aggregation), Group owns members/admins (composition), Event owns invitees (composition).
  • Use of volatile ensures visibility of mutable fields like privacyLevel and RSVPStatus across threads without full synchronization overhead.
  • Synchronized methods provide atomicity for compound operations like mutual friendship updates and role changes, preventing race conditions.

Practice

(1/5)
1. In a multi-threaded parking lot system, if parkVehicle() is not synchronized, which exact sequence of Thread 1 and Thread 2 calls causes double-booking of the same spot?
medium
A. Thread 1 checks spot availability -> true, context switch; Thread 2 checks spot availability -> true; both park simultaneously.
B. Thread 1 parks vehicle, Thread 2 waits for Thread 1 to finish, then parks vehicle.
C. Thread 1 parks vehicle, Thread 2 parks vehicle immediately after without checking availability.
D. Thread 1 releases spot, Thread 2 parks vehicle before Thread 1 finishes updating status.

Solution

  1. Step 1: Identify race condition

    Without synchronization, both threads can read spot availability as true before either marks it occupied.
  2. Step 2: Trace exact interleaving

    Thread 1: isAvailable() -> true, context switch; Thread 2: isAvailable() -> true; both proceed to park, causing double-booking.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Check-then-act gap without synchronization -> double-booking [check]
Hint: Check availability then park must be atomic to avoid double-booking [check]
Common Mistakes:
2. Consider a tryConsume() method in TokenBucketRateLimiter that checks if tokens are available and then decrements the count without synchronization. Which exact thread interleaving causes double token consumption?
medium
A. Thread 1 reads tokens=1, decrements; Thread 2 waits until Thread 1 finishes
B. Thread 1 increments tokens while Thread 2 decrements tokens simultaneously
C. Thread 1 and Thread 2 both block on synchronized method, then proceed sequentially
D. Thread 1 checks tokens > 0 -> true, context switch; Thread 2 checks tokens > 0 -> true; both decrement tokens

Solution

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

    Without synchronization, both threads can read tokens > 0 before either decrements.
  2. Step 2: Trace exact interleaving causing double consumption

    Thread 1 checks tokens > 0 -> true, context switch; Thread 2 checks tokens > 0 -> true; both proceed to decrement, consuming same token twice.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Unsynchronized check-then-act allows double token consumption [check]
Hint: Check tokens > 0 twice before decrement -> double consume [check]
Common Mistakes:
3. The vending machine currently applies a flat pricing strategy. To add a WeekendFeeStrategy that charges extra on weekends, which minimal change respects SOLID principles?
medium
A. Create a new WeekendFeeStrategy class implementing PricingStrategy and inject it without modifying existing classes.
B. Modify the existing PricingStrategy class to add weekend fee logic inside its calculatePrice() method.
C. Add a boolean isWeekend flag to Product and adjust price accordingly.
D. Add conditional logic for weekend fees in the vending machine's dispense() method.

Solution

  1. Step 1: Identify the SOLID principle involved

    The Open-Closed Principle (OCP) requires classes to be open for extension but closed for modification.
  2. Step 2: Evaluate options against OCP

    Create a new WeekendFeeStrategy class implementing PricingStrategy and inject it without modifying existing classes. adds a new strategy class without modifying existing code, respecting OCP. Others modify existing classes or mix concerns.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    New strategy class extends pricing without modifying existing code [check]
Hint: OCP: extend pricing via new class, don't modify existing [check]
Common Mistakes:
4. Adding a WeekendFeeStrategy to calculate weekend parking fees requires which minimum change to the current design that uses a FeeStrategy interface?
medium
A. Combine all fee calculations into one class with if-else for weekend and weekday fees
B. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without modifying existing classes
C. Modify the existing FeeStrategy interface to add a isWeekend() method and update all implementations
D. Add a boolean flag isWeekend in ParkingLot and conditionally apply fees inside existing strategies

Solution

  1. Step 1: Understand current design with FeeStrategy interface

    FeeStrategy interface allows different fee calculation implementations, supporting OCP if new strategies are added as new classes.
  2. Step 2: Analyze minimal change for weekend fees

    Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without modifying existing classes respects OCP by adding a new class without modifying existing ones. Add a boolean flag isWeekend in ParkingLot and conditionally apply fees inside existing strategies modifies ParkingLot to add weekend logic, violating OCP but minimal change.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Minimal change but violates OCP -> modify ParkingLot with weekend flag [check]
Hint: Minimal change โ‰  OCP compliance; adding flag is minimal but not ideal [check]
Common Mistakes:
5. 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:
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