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
Model core Facebook entities and interactions with extensible privacy and concurrency control
mediumSocial and Professional PlatformsFreq: high
Prerequisites:OOP FundamentalsJava Concurrency BasicsDesign Patterns (Factory, Observer, Strategy)SOLID Principles
⚙️
Functional Requirements
  • Users can send, accept, and remove friends
  • Users can create posts with privacy levels (Public, FriendsOnly, GroupOnly)
  • Groups can have members and admins; admins can add/remove members
  • Events have organizers and attendees; users can RSVP
  • Privacy model enforces visibility rules at runtime
  • Concurrency control prevents race conditions on friend requests and post visibility
  • Users can view posts based on privacy and friendship status
👤
Use Cases
  • User sends and accepts friend requests
  • User creates posts with privacy settings
  • User joins and interacts in groups
  • User creates and RSVPs to events
  • Privacy settings control post visibility
  • System handles concurrent friend requests and post updates
🧑‍💻
Actors
  • User
  • Group Admin
  • Event Organizer
  • System
❓
Clarifying Questions to Ask
  • How many concurrent friend requests can a user receive? (Concurrency gates)
  • Is there a pricing or quota model for group/event creation?
  • How to handle edge cases like circular friend requests or privacy conflicts?
  • Should privacy settings be extensible for future types?
  • What consistency guarantees are expected for friend lists and post visibility?
Out of Scope
✗ News feed ranking algorithms
✗ Messaging between users
✗ Media storage and delivery
✗ Notifications system
✗ Payment or advertising features
⚡
QPS Calculation
read qps10000
write qps2000
🖥️
Server Estimate
web servers50
db servers20
cache servers10
🔢
Enumerations
enum PrivacyLevel
PUBLIC | FRIENDS_ONLY | GROUP_ONLY | PRIVATE
Defines post visibility scope; enum prevents typo bugs and enables exhaustive switch statements for privacy enforcement.
enum FriendRequestStatus
PENDING | ACCEPTED | REJECTED
Tracks lifecycle of friend requests; enum ensures type safety and clear state transitions.
enum EventStatus
UPCOMING | ONGOING | COMPLETED | CANCELLED
Represents event lifecycle states; enum enables clear state management and UI filtering.
📦
User
8 fields
private final String userIdprivate String nameprivate volatile Set<User> friendsprivate volatile Map<String, FriendRequest> incomingFriendRequestsprivate volatile Map<String, FriendRequest> outgoingFriendRequestsprivate List<Post> postsprivate List<Group> groupsprivate List<Event> events
Represents a Facebook user; manages friends, friend requests, posts, groups, and events; enforces concurrency on friend requests and friend list updates.
public synchronized boolean sendFriendRequest(User toUser)Atomically sends a friend request to another user if not already friends or pending.
public synchronized boolean acceptFriendRequest(String fromUserId)Atomically accepts a pending friend request and updates both users' friend lists.
public synchronized boolean removeFriend(String friendUserId)Removes a friend relationship atomically.
public Post createPost(String content, PrivacyLevel privacyLevel)Creates a new post with specified privacy.
public synchronized boolean joinGroup(Group group)Adds user to a group if not already a member.
📦
FriendRequest
4 fields
private final String requestIdprivate final User fromUserprivate final User toUserprivate volatile FriendRequestStatus status
Represents a friend request between two users; tracks status with concurrency-safe updates.
public synchronized void updateStatus(FriendRequestStatus newStatus)Atomically updates the friend request status.
📦
Post
5 fields
private final String postIdprivate final User authorprivate final String contentprivate final PrivacyLevel privacyLevelprivate final long timestamp
Represents a user post with privacy settings; immutable after creation to simplify concurrency.
public boolean isVisibleTo(User viewer)Determines if the post is visible to a given user based on privacy rules.
📦
Group
4 fields
private final String groupIdprivate String nameprivate final User adminprivate final Set<User> members
Represents a Facebook group; manages membership and admin privileges.
public synchronized boolean addMember(User user)Adds a user to the group atomically.
public synchronized boolean removeMember(User user)Removes a user from the group atomically.
📦
Event
5 fields
private final String eventIdprivate String nameprivate final User organizerprivate final Set<User> attendeesprivate volatile EventStatus status
Represents an event; manages attendees and event lifecycle with concurrency-safe status updates.
public synchronized boolean rsvp(User user)Adds a user to attendees atomically.
public synchronized void updateStatus(EventStatus newStatus)Atomically updates the event status.
📦
PrivacyStrategy
0 fields
Interface defining contract for privacy enforcement strategies; enables Open-Closed Principle for extensible privacy models.
public boolean canView(User viewer, Post post)Determines if viewer can see the post.
📦
FriendsOnlyPrivacyStrategy
0 fields
Concrete privacy strategy allowing only friends to view posts.
public boolean canView(User viewer, Post post)Returns true if viewer is friend of post author.
📦
PublicPrivacyStrategy
0 fields
Concrete privacy strategy allowing all users to view posts.
public boolean canView(User viewer, Post post)Always returns true, allowing all users to view the post.
🗄️
Users
PK: userId
userIdnamefriendsgroupsevents
🗄️
Posts
PK: postId
postIdauthorIdcontentprivacyLeveltimestamp
🔌
/friendRequest/send
Request
{
  "fromUserId": "String",
  "toUserId": "String"
}
Response
{
  "success": "boolean",
  "message": "String"
}
Sends a friend request from one user to another.
🔌
/post/create
Request
{
  "authorId": "String",
  "content": "String",
  "privacyLevel": "PrivacyLevel"
}
Response
{
  "postId": "String",
  "success": "boolean"
}
Creates a new post with specified privacy.
🔌
/group/join
Request
{
  "userId": "String",
  "groupId": "String"
}
Response
{
  "success": "boolean",
  "message": "String"
}
User joins a group if not already a member.

Practice

(1/5)
1. In a multi-threaded Chess game server, without synchronizing the makeMove() method, which exact sequence of thread interleaving causes two players to move simultaneously, violating turn order?
medium
A. Thread 1 reads current player as White, moves piece; Thread 2 reads current player as Black, moves piece simultaneously.
B. Thread 1 checks if it's White's turn -> true, context switch; Thread 2 checks if it's White's turn -> true; both proceed to move.
C. Thread 1 locks board, moves piece; Thread 2 waits but proceeds after unlock.
D. Thread 1 updates board state; Thread 2 reads stale board state but waits for turn.

Solution

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

    Both threads read the turn state before either updates it, causing both to believe it's their turn.
  2. Step 2: Trace thread interleaving

    Thread 1 checks turn -> true, context switch before move; Thread 2 checks turn -> true, both move simultaneously, violating turn order.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Check-then-act gap allows double move without synchronization [check]
Hint: Check turn then act without lock -> race condition [check]
Common Mistakes:
2. In the playback queue, the method addTrack() is not synchronized. Two threads concurrently check if the queue has space and then add tracks. Which exact sequence causes a race condition leading to queue overflow?
medium
A. Thread 1 checks queue size -> space available, context switch, Thread 2 checks queue size -> space available, both add tracks exceeding capacity.
B. Thread 1 adds a track, Thread 2 waits until Thread 1 finishes, then adds another track safely.
C. Thread 1 locks queue, Thread 2 spins waiting for lock, no race occurs.
D. Thread 1 removes a track while Thread 2 adds, causing inconsistent queue state.

Solution

  1. Step 1: Identify the check-then-act pattern in addTrack()

    Both threads check queue size before adding, but without synchronization, the state can change between check and add.
  2. Step 2: Trace the race condition sequence

    Thread 1 checks size -> space available, context switch before adding. Thread 2 checks size -> space available, both add tracks, causing overflow.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Unsynchronized check-then-act -> double add -> overflow [check]
Hint: Check-then-act without sync -> race condition [check]
Common Mistakes:
3. In the Amazon Locker Service, if the assignLocker() method is not synchronized, which exact sequence of thread interleaving causes two packages to be assigned the same locker?
medium
A. Thread 1 assigns locker and updates status; Thread 2 waits until Thread 1 finishes, then assigns a different locker.
B. Thread 1 and Thread 2 both call assignLocker() simultaneously and both fail to find any available lockers.
C. Thread 1 checks locker availability -> true, context switch; Thread 2 checks availability -> true; both assign the same locker before status update.
D. Thread 1 releases a locker; Thread 2 immediately assigns it without checking availability.

Solution

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

    Without synchronization, Thread 1 reads locker as available, then context switches before marking it occupied.
  2. Step 2: Thread 2 also reads locker as available and proceeds to assign it, causing double-booking.

    Both threads assign the same locker before either updates the status.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Check-then-act gap -> double assignment [check]
Hint: Check availability -> context switch -> both assign same locker [check]
Common Mistakes:
4. In a parking lot system, if parkVehicle() is not synchronized, which exact thread interleaving causes double-booking of the same spot?
medium
A. Thread 1 checks spot availability -> true, context switch; Thread 2 checks availability -> true; both park simultaneously.
B. Thread 1 parks vehicle, Thread 2 parks vehicle after Thread 1 finishes.
C. Thread 1 parks vehicle, Thread 2 waits for lock release before parking.
D. Thread 1 releases spot, Thread 2 immediately occupies it without checking.

Solution

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

    Without synchronization, Thread 1 reads spot as available but before marking it occupied, context switches to Thread 2 which also reads available.
  2. Step 2: Both threads proceed to park, causing double-booking

    Both threads believe the spot is free and park simultaneously, violating mutual exclusion.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Check-then-act gap without synchronization -> double-booking [check]
Hint: Check availability -> context switch -> both park -> double-booking [check]
Common Mistakes:
5. ElectricCar needs ChargingSpots in the Stack Overflow vehicle analogy. What is the minimum change to support this without modifying existing classes?
hard
A. Add charging logic directly inside existing Spot class with if-else for electric cars
B. Modify Vehicle class to add isElectric flag and add charging logic inside existing methods
C. Create a new ElectricCar class unrelated to Vehicle and a ChargingSpot class unrelated to Spot, manage compatibility externally
D. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar extends Vehicle, update SpotCompatibility.COMPATIBILITY_MAP accordingly

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    Adding new enum values and subclass ElectricCar extends Vehicle allows extension without changing existing class code.
  2. Step 2: Update compatibility map externally

    Updating SpotCompatibility.COMPATIBILITY_MAP supports new types without modifying core logic, preserving OCP.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Enum extension + subclass + external map update -> minimal change [check]
Hint: Extend enums + subclass + external map -> 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