Problem framing
Design a scheduler: submit jobs, run at a time or ASAP, support priority, cancellation, and retry on failure. Bridges LLD class design with concurrency concepts (worker pool).
| Class | Responsibility |
|---|---|
Job | id, payload, priority, runAt, retryCount, status |
JobQueue | Priority queue ordered by (runAt, priority) |
Worker | Pull job, execute, report success/failure |
Scheduler | schedule(job), cancel(id), owns queue + workers |
RetryPolicy | Strategy: max retries, backoff |
Scheduling flow
schedule(job) → enqueue if runAt <= now, else delayed queue (min-heap by time). Workers block on queue.poll() or wait/notify until job ready. On failure: RetryPolicy decides re-enqueue with incremented count or mark FAILED.
Command pattern connection
Each Job can wrap a Runnable or Command — encapsulates the unit of work. Enables undo, logging, and serialization. Worker is the invoker; it doesn't know job specifics.
Senior-level signal
Distinguish this from LeetCode 621 (CPU task ordering) — here you're designing runtime components, not minimizing idle intervals. Mention thread pool sizing, poison pill for shutdown, and that delayed jobs need a time wheel or sleeper thread — pick one, defer the other. Link to production: ScheduledExecutorService is the JDK embodiment.
Idempotency note
cancel(jobId) and duplicate schedule() should be safe — track job status (PENDING, RUNNING, DONE, CANCELLED) so workers don't double-execute after retry.
Where this goes next
Connection Pool applies object pooling and blocking concurrency — the pattern behind JDBC pools, HTTP keep-alive, and gRPC channel reuse.
Further Reading
Practice Tasks (Optional)
Design or implement locally in any language — no autograding. Focus on class structure, extensibility, and being able to explain trade-offs out loud.
- Design a job scheduler API40m
Classes: Job, JobQueue, Worker, Scheduler. API: schedule(job, runAt), cancel(jobId). Walk through: 3 jobs submitted, 2 workers, one job fails and retries. Sketch only — implementation optional.