Library Management System

Book Lending Platform

Design a library: a catalog of books with physical copies, members with lending rules, loans with due dates and fines, and a hold queue that offers a returned copy to the next member in line.

Overview

A library lends physical copies of books to members for a fixed period, charges a fine when a copy comes back late, and lets a member wait in line for a book whose copies are all out. The domain is familiar, which is why interviewers use it: there is no algorithm to hide behind, and the quality of the object model is the whole answer.

The problem tests three modeling decisions. First, a book is not a copy: the catalog entry is one object, each physical copy is another, and only copies are lent. Second, lending rules belong in a policy object attached to the member, not in a chain of if member.type == ... checks. Third, a returned copy does not simply become available; if members are waiting, it is held for the first of them until a deadline, and the checkout code has to respect that hold.

A strong answer draws the entities and the copy's life cycle before writing code, passes the current date into the library instead of reading the clock inside it so that due dates and fines are testable, and puts one lock around checkout and return so that two members can never borrow the same copy.

Scoping the problem

  • Can a book have several copies? — Splits Book from BookCopy, the key modeling step — Yes
  • Do member types differ? — Loan limit, loan length and fine rate become a policy per member — Yes, at least two kinds
  • What happens when every copy is out? — A hold queue per book, with a pickup deadline — Queue, first come first served
  • How are fines charged? — Per day late, from the policy; paid before the next checkout or not — Per day late, capped or not by choice
  • Who calls the system? — Librarian at a desk, or members online, changes the concurrency story — Both, so the library needs a lock
  • Search, notifications, renewals, lost copies? — Each is a follow-up; ask which the interviewer wants — Notifications and one more

Book versus copy

  • What it is — The catalog entry: ISBN, title, author — One physical item with a barcode
  • How many — One per title — One per item on the shelf
  • Changes over time — Rarely — Every checkout and return
  • Lent to a member — Never — Yes
  • Holds attach to — The book: a member wants any copy — Nothing; a copy is assigned when one returns
  • Status — Derived: how many copies are available — Available, on loan, on hold, lost

Without the split you cannot say which copy a member has, cannot mark one copy damaged while the others circulate, and cannot count what is left on the shelf. Interviewers listen for this distinction in the first minutes.

Checkout

Every check happens under the library's lock, and the copy changes status in the same step as the loan is created. That is what stops two members from borrowing one copy.

Return, fines and the hold queue

  • Find the open loan for the copy — The copy's loan, not a scan of every member — Library.copies and the loan on the copy
  • Compute the fine — max(0, today - due) * policy.fine_cents_per_day — The member's Policy
  • Close the loan — returned = today; remove from the member's open loans — Library
  • Offer the copy — If a hold exists for the ISBN, the copy is OnHold for that member with a pickup deadline, and the member is notified — Library plus Notifier
  • Otherwise — Status back to Available — Library

Fines use whole cents, computed from a date the caller passes in. The example policies below are illustrations, not real library rules.

  • Student — 3 — 14 — 25 cents
  • Faculty — 10 — 30 — 10 cents

Thread safety

One threading.Lock in Library wraps checkout, return_copy, place_hold and expire_holds. Each of them reads a status and then writes it, and that pair has to be atomic.

  • One lock per library (the code) — Every status change — Simple; a desk-sized library never contends
  • One lock per copy — Two members racing for one copy — Return also touches the hold queue, so it needs the queue lock too; ordering matters
  • A database row lock — The same read-then-write, across processes — SELECT ... FOR UPDATE on the copy row, or a unique index on open loans per copy

What you will be able to do

  • Draw the entity model with Book separate from BookCopy and explain what breaks without the split.
  • Put lending rules in a Policy object and add a member type without touching checkout.
  • Trace a copy through checkout, late return, hold and pickup, including the fine.
  • Explain why checkout and return take one lock and how the database version enforces the same rule.
  • Extend the design with notifications, renewals and lost copies as follow-ups.

Functional requirements

  • Catalog books by ISBN and register any number of physical copies per book
  • Register members, each with a policy: maximum open loans, loan length in days, fine per day late
  • Check out an available copy to an eligible member and record the due date
  • Return a copy, compute the fine for late days, and close the loan
  • Place a hold on a book whose copies are all out; a returned copy is held for the first member in line until a pickup deadline
  • Expire holds whose deadline passed and pass the copy to the next member or back to the shelf
  • Notify a member when a held copy is ready

Non-functional requirements

  • A copy is never on loan to two members: checkout and return are atomic under one lock
  • Dates come from the caller, never from the system clock, so due dates and fines are testable
  • Fines are integers in cents
  • Lookups by copy id, ISBN and member id are O(1) via dictionaries
  • Adding a member type or a notification channel needs no change to checkout or return

Interview questions

  • Why not a Book class with a count of copies? Why a BookCopy object per item?
  • How do you support member types with different rules without an if-chain?
  • Design the hold queue. What goes wrong with the simple version?
  • How does this survive many desks and a database? What stops two checkouts of one copy?
  • What would you add next: renewals, lost copies, search?

Sign up free to read the full topic

More Low-Level Design topics

Start free on Cariara · Coding problems · System design studio