Free preview

Why this matters: the design in lesson 2 stands or falls on a handful of lines — the overlap comparison, and the floor/ceiling check against a sorted map. Interviewers watch whether you can produce exactly those lines cleanly, in the order a live round demands: vocabulary types first, the ordered structure next, then the two flows that matter. Everything here is written the way you'd write it on a shared editor, narration included.

Vocabulary types first

Start with the words the rest of the code will speak. Ten lines, and every later signature gets sharper:

java
enum Equipment { SCREEN, VIDEO_CONF, WHITEBOARD } record TimeSlot(Instant start, Instant end) { // Half-open: [start, end). Back-to-back slots do not overlap. boolean overlaps(TimeSlot other) { return start.isBefore(other.end) && other.start.isBefore(end); } } record Room(String id, int capacity, Set<Equipment> equipment) {} record Booking(String id, String roomId, String organizer, int attendees, TimeSlot slot) {}

Say the comment out loud as you type it: "half-open, so ten-to-eleven and eleven-to-twelve don't clash." The overlaps method is the only place in the program that knows the comparison — that was invariant #2, and here it is as code.

The calendar: one room's ordered truth

java
class RoomCalendar { // start time -> booking; sorted order is the whole point private final TreeMap<Instant, Booking> byStart = new TreeMap<>(); boolean isFree(TimeSlot candidate) { // Only the neighbors can clash: the booking starting just // before the candidate, and the one starting at/after it. var floor = byStart.floorEntry(candidate.start()); if (floor != null && floor.getValue().slot().overlaps(candidate)) return false; var ceiling = byStart.ceilingEntry(candidate.start()); if (ceiling != null && ceiling.getValue().slot().overlaps(candidate)) return false; return true; } void add(Booking b) { // caller has already passed isFree byStart.put(b.slot().start(), b); } void remove(Booking b) { byStart.remove(b.slot().start()); } }

Narrate the floor/ceiling reasoning as you write it — it's the round's centerpiece: "the floor entry is the last meeting to start before mine; if it doesn't run into me, nothing earlier can, because they start even sooner and bookings in this map never overlap each other. The ceiling entry is the next to start; if I don't run into it, I can't reach anything later." Two probes into a sorted map, each O(log n), and the scan is gone.

The scheduler: flows over the calendar

java
class Scheduler { private final Map<String, Room> rooms; // roomId -> Room private final Map<String, RoomCalendar> calendars; // roomId -> calendar private final Map<String, Booking> bookingsById; // for cancel private final RankingStrategy ranking; // smallest-fit today Booking book(String roomId, String organizer, int attendees, Set<Equipment> needed, TimeSlot slot) { Room room = rooms.get(roomId); require(room.capacity() >= attendees, "room too small"); require(room.equipment().containsAll(needed), "missing equipment"); RoomCalendar cal = calendars.get(roomId); require(cal.isFree(slot), "slot conflicts with an existing booking"); Booking b = new Booking(newId(), roomId, organizer, attendees, slot); cal.add(b); bookingsById.put(b.id(), b); return b; } void cancel(String bookingId) { Booking b = bookingsById.remove(bookingId); require(b != null, "no such booking"); calendars.get(b.roomId()).remove(b); // Slot is genuinely gone: every future isFree() is already correct. } }

Point at cancel and say it: removal, not a flag — no future code path has to remember cancelled bookings exist.

The finder: filter, then rank

java
interface RankingStrategy { Optional<Room> pick(List<Room> candidates); } class SmallestFit implements RankingStrategy { public Optional<Room> pick(List<Room> candidates) { return candidates.stream() .min(Comparator.comparingInt(Room::capacity)); } } Optional<Room> suggest(int attendees, Set<Equipment> needed, TimeSlot slot) { List<Room> fits = rooms.values().stream() .filter(r -> r.capacity() >= attendees) .filter(r -> r.equipment().containsAll(needed)) .filter(r -> calendars.get(r.id()).isFree(slot)) .toList(); return ranking.pick(fits); }

Two things to say while writing this. First: the availability filter calls the same isFree that book uses — one authority, no second opinion. Second: the filters are plain code because they're requirements, and the rank is a strategy because it's preference — the seam sits exactly where change is expected.

What you'd say about complexity

Conflict check: two TreeMap probes, O(log n) in bookings per room — thousands per room per year means about a dozen comparisons. Booking and cancellation: the same O(log n) plus hash-map work. Suggestion: O(R log n) for R rooms, since each surviving room pays one availability check — fine at hundreds of rooms; and say the honest caveat that if suggestion became the dominant operation, you'd want an index over rooms by capacity to shrink R before the per-room checks.

Key takeaway

Write it in this order: the half-open TimeSlot with its single overlaps line, the TreeMap calendar whose floor/ceiling probes replace the scan, then book and cancel through the calendar and suggest through filter-then-rank. Narrate the neighbor argument while typing it — "only the bookings adjacent in start order can clash, because the map never holds overlaps" — that sentence, plus the code matching it, is the round's core evidence.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue