Bird
Raised Fist0
LLDsystem_design~20 mins

User, Group, Expense classes in LLD - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
UserGroupExpense Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
🧠 Conceptual
intermediate
2:00remaining
Identify the correct relationship between User, Group, and Expense classes

In a system where users can belong to groups and share expenses, which of the following best describes the relationship between User, Group, and Expense classes?

AUsers belong to a single Group only; Expenses belong to Users only; Groups do not track Expenses.
BA User can belong to multiple Groups; a Group contains multiple Users; an Expense is linked to a Group and paid by a User.
CAn Expense belongs to multiple Users; Groups are independent and do not contain Users; Users pay Expenses individually.
DA Group belongs to a single User; an Expense belongs to a User only; Users do not belong to Groups.
Attempts:
2 left
💡 Hint

Think about how users collaborate in groups and how expenses are shared.

Architecture
intermediate
1:30remaining
Choose the best class attribute to represent an Expense's payer

Which attribute best represents the payer of an Expense in the Expense class?

Apayer_group: stores the Group object that paid the expense.
Bpayer_name: stores the name of the User who paid the expense as a string.
Cpayer_id: stores the unique identifier of the User who paid the expense.
Dpayer_amount: stores the amount paid by the User.
Attempts:
2 left
💡 Hint

Consider how to uniquely identify the payer without duplicating user data.

scaling
advanced
2:30remaining
Scaling the Group class for thousands of Users

When a Group contains thousands of Users and hundreds of Expenses, which design choice helps maintain performance and scalability?

AStore only User IDs in the Group class and fetch User details on demand.
BStore User objects directly inside the Group class as a list.
CDuplicate User data inside each Group to avoid fetching from User class.
DStore Expense objects inside each User instead of the Group.
Attempts:
2 left
💡 Hint

Think about memory usage and data duplication when handling large numbers.

tradeoff
advanced
3:00remaining
Tradeoff between storing Expense split details in Expense vs User

Where should the details of how an Expense is split among Users be stored for best design?

AStore split details in a separate Split class linking Users and Expenses.
BStore split details inside each User class as a list of Expenses and amounts.
CStore split details inside the Expense class as a map of User IDs to amounts.
DDo not store split details; calculate splits dynamically each time.
Attempts:
2 left
💡 Hint

Consider separation of concerns and flexibility for future changes.

estimation
expert
3:00remaining
Estimate storage for 1 million Users, 100k Groups, and 10 million Expenses

Estimate the approximate storage needed if each User object requires 1KB, each Group object 2KB, and each Expense object 0.5KB. Ignore overhead and indexes.

AApproximately 8.5 GB
BApproximately 7.5 GB
CApproximately 5.5 GB
DApproximately 6.5 GB
Attempts:
2 left
💡 Hint

Calculate total size by multiplying counts by sizes and summing.

Practice

(1/5)
1. Which class is primarily responsible for storing information about individual people in a shared expense system?
easy
A. Payment
B. User
C. Expense
D. Group

Solution

  1. Step 1: Understand the role of each class

    User class represents individual people, Group holds multiple users, Expense tracks costs.
  2. Step 2: Identify which class stores individual info

    User class stores personal details like name and ID for each person.
  3. Final Answer:

    User -> Option B
  4. Quick Check:

    User = Individual person [OK]
Hint: User class = individual person info [OK]
Common Mistakes:
  • Confusing Group with User
  • Thinking Expense stores user details
  • Assuming Payment is a class here
2. Which of the following is the correct way to define a Group class that holds multiple User objects in Python?
easy
A. class Group: def __init__(self): self.users = []
B. class Group: def __init__(self): self.user = {}
C. class Group: def __init__(self): self.expenses = []
D. class Group: def __init__(self): self.members = None

Solution

  1. Step 1: Identify correct attribute for multiple users

    A list is suitable to hold multiple User objects, so self.users = [] is correct.
  2. Step 2: Check other options for correctness

    class Group: def __init__(self): self.user = {} uses a dict named user which is not typical for holding users; class Group: def __init__(self): self.expenses = [] uses expenses which belongs to Expense class; class Group: def __init__(self): self.members = None sets members to None which is not a collection.
  3. Final Answer:

    class Group: def __init__(self): self.users = [] -> Option A
  4. Quick Check:

    Group holds list of users = self.users = [] [OK]
Hint: Group holds list of users with self.users = [] [OK]
Common Mistakes:
  • Using dict instead of list for users
  • Confusing expenses with users
  • Initializing members as None instead of a list
3. Given the following code snippet, what will be the output?
class Expense:
    def __init__(self, amount, paid_by, split_between):
        self.amount = amount
        self.paid_by = paid_by
        self.split_between = split_between

    def split_amount(self):
        return self.amount / len(self.split_between)

expense = Expense(120, 'Alice', ['Alice', 'Bob', 'Charlie'])
print(expense.split_amount())
medium
A. Error
B. 60
C. 120
D. 40.0

Solution

  1. Step 1: Understand the split_amount method

    It divides total amount by number of people in split_between list.
  2. Step 2: Calculate the split

    Amount = 120, split_between has 3 people, so 120 / 3 = 40.0.
  3. Final Answer:

    40.0 -> Option D
  4. Quick Check:

    120 divided by 3 = 40.0 [OK]
Hint: Divide amount by count of split_between list [OK]
Common Mistakes:
  • Forgetting to divide by number of people
  • Dividing by 2 instead of 3
  • Assuming paid_by affects split amount
4. Identify the bug in this Expense class method that calculates each user's share:
class Expense:
    def __init__(self, amount, paid_by, split_between):
        self.amount = amount
        self.paid_by = paid_by
        self.split_between = split_between

    def split_amount(self):
        return self.amount // len(self.split_between)
medium
A. Using integer division (//) may lose cents in split
B. split_between should be a dictionary, not a list
C. paid_by should be a list, not a single user
D. amount should be a string, not a number

Solution

  1. Step 1: Analyze the division operator used

    The method uses integer division (//) which truncates decimals.
  2. Step 2: Understand impact on money split

    Using // can lose fractional cents, causing inaccurate splits.
  3. Final Answer:

    Using integer division (//) may lose cents in split -> Option A
  4. Quick Check:

    Integer division truncates decimals, causing loss [OK]
Hint: Use float division (/) for accurate money splits [OK]
Common Mistakes:
  • Ignoring decimal loss from integer division
  • Confusing data types for paid_by or split_between
  • Thinking amount should be string
5. You want to design a system where multiple users in a group can add expenses, and the system automatically calculates how much each user owes or is owed. Which design approach best supports scalability and clear responsibility?
hard
A. Make User class handle all expense calculations and group management to centralize logic
B. Use only a single Expense class that stores all users and groups inside it to simplify design
C. Create User, Group, and Expense classes where Group manages users and expenses; Expense tracks amount and split; User tracks individual balances updated by Group
D. Store all data in a flat file and calculate splits manually each time without classes

Solution

  1. Step 1: Identify responsibilities for each class

    User holds personal info and balances, Group manages users and expenses, Expense tracks costs and splits.
  2. Step 2: Evaluate design for scalability and clarity

    Create User, Group, and Expense classes where Group manages users and expenses; Expense tracks amount and split; User tracks individual balances updated by Group cleanly separates concerns, making it easier to maintain and scale.
  3. Final Answer:

    Create User, Group, and Expense classes where Group manages users and expenses; Expense tracks amount and split; User tracks individual balances updated by Group -> Option C
  4. Quick Check:

    Clear class roles = scalable design [OK]
Hint: Separate concerns: User, Group, Expense each handle distinct roles [OK]
Common Mistakes:
  • Putting all logic in one class
  • Ignoring separation of concerns
  • Using flat files for complex data