Learning Platform
Online Education System
Design an online course platform: courses built from modules and lessons, enrollment with prerequisites, per-learner progress, auto-graded quizzes with limited attempts, and a certificate that can be verified.
Overview
An online learning platform lets instructors publish courses and lets learners enroll, work through lessons, take quizzes and earn a certificate. A course is a tree: it holds modules, and modules hold lessons. Each learner moves through the same tree, but their progress is their own.
The problem tests three things. First, whether you model the course tree so that a course, a module and a lesson can all answer the same questions (how long is it, which lessons does it contain) without type checks: this is the Composite pattern. Second, whether you keep the shared course content separate from each learner's progress, so a thousand learners do not copy the course. Third, whether rules such as prerequisites, quiz attempts and 'issue the certificate exactly once' hold when requests arrive at the same time.
A strong answer scopes quickly, draws the tree and the enrollment as separate things, adds question types without touching the quiz code, and shows that a certificate cannot be issued twice or forged.
Scoping the problem
- How deep is the course tree? — A fixed depth or a real tree — Course, module, lesson; modules may nest
- Which lesson kinds exist? — Video, text, exercise — All three; they differ in content, not in progress rules
- How is a lesson completed? — Viewed, or passed a quiz — Marked done; a lesson with a quiz is done when the quiz is passed
- Which question types, and how many attempts? — Grading must be pluggable — Single choice, multi select, short answer; a fixed attempt limit
- Are prerequisites enforced? — Checked at enrollment — Yes: the prerequisite course must be completed
- What makes a certificate trustworthy? — Anyone can type a code — A code the platform can check and a learner cannot forge
- Do we need video streaming, payments, reviews? — Separate systems — Out of scope
The course tree as a Composite
A module's length is the sum of its children's lengths, whatever those children are. Because a lesson and a module both implement minutes() and lessons(), the sum is one line and works for any depth.
- minutes() — Its own minutes — Sum of minutes() of its children
- lessons() — A list with itself — All lessons of its children, in order
In the demo, Python Basics has modules Start (10 and 15 minutes) and Check (5 minutes), so basics.minutes() is 30 and basics.lessons() has 3 items. Progress is then only a set of lesson ids per enrollment, and percent done is its size over len(course.lessons()). Module and course progress are computed, never stored twice.
Progress through a course
The demo follows this path and adds the failure cases.
- 1 — enroll in py201 before py101 is done — Refused: missing prerequisite
- 2 — complete L1 twice — 33 percent: done is a set, so a repeat changes nothing
- 3 — quiz attempt 1: two of three right — Score 0.67, below 0.7, lesson not done
- 4 — quiz attempt 2: all right — Score 1.0, lesson done
- 5 — quiz attempt 3 — Refused: max_attempts is 2
- 6 — 20 threads complete L2 at once — Status COMPLETED, exactly one certificate issued
- 7 — verify the code for Ana, then for Ben — True, then False
- 8 — enroll in py201 again — Allowed now
What you will be able to do
- Model a course tree with the Composite pattern and compute length and progress at any level.
- Keep shared content (Course) apart from each learner's record (Enrollment).
- Add a question type as a new class without changing the quiz or the platform.
- Enforce prerequisites and attempt limits, and issue a certificate exactly once under concurrency.
- Make a certificate code that the platform can verify and a learner cannot forge.
Functional requirements
- Courses are trees: a course holds modules, a module holds lessons or other modules
- Lessons are video, text or exercise; a lesson may carry a quiz
- publish() makes a course open for enrollment; it needs at least one lesson
- enroll(user, course) requires every prerequisite course to be completed
- complete_lesson marks a plain lesson done; submit_quiz grades an attempt and marks the lesson done on a pass
- Quizzes support single choice, multi select and short answer, a pass ratio and a limit on attempts
- When every lesson is done the enrollment becomes COMPLETED and a certificate code is issued; verify(user, course, code) checks it
Non-functional requirements
- Course content is shared; each enrollment stores only a set of done lesson ids and attempt counts
- Progress at any level is computed from the tree, never stored twice
- Safe under concurrency: each enrollment has a lock; the certificate is issued exactly once
- A new question type or lesson kind is a new class; Quiz and LearningPlatform do not change
- Certificate codes cannot be forged without the platform secret
Interview questions
- Two requests complete the last lesson at the same moment. How do you avoid two certificates?
- How do you add a new question type, such as a coding exercise with tests?
- How do you stop a learner from forging a certificate code?
- An instructor edits a course after learners have finished half of it. What happens to their progress?
- How would you store this in a database?
Sign up free to read the full topic
More Low-Level Design topics
Start free on Cariara · Coding problems · System design studio