DocumentationPractising

Guides

Practising

The daily loop in detail: how to start and test a problem, when to use hints, how a grade is computed, and how cstudy decides what you practise next.

On this page
  1. The loop
  2. Choosing a language
  3. Starting and resuming
  4. Testing
  5. Hints and solutions
  6. Finishing an attempt
  7. Stopping without finishing
  8. Reviews and spaced repetition
  9. What cstudy next picks
  10. Finding problems
  11. Guides and paths
  12. Problem sets
  13. Checking performance
  14. Timers and mock interviews
  15. Tracking progress
  16. Starting over

The loop

Every problem goes through the same commands, whatever the language:

the core loop
cstudy next  ->  cstudy start <slug> --lang kotlin  ->  edit in your editor  ->  cstudy test --watch
         ->  cstudy bench (optional)  ->  cstudy done --rating ok  ->  cstudy solution (optional)

Commands that take a problem accept its slug (two-sum), its id, or the path of one of your solution files. Without one, they act on the active attempt: your most recent attempt still in progress.

cstudy serve runs the same loop on a local page; see Practising in the browser.

Choosing a language

Pass --lang python, typescript, java, kotlin, go or rust to cstudy start, or set default_lang in your configuration. Reviews are scheduled per problem, so you can solve a problem in one language and review it in another.

A file path names both the problem and the language, which is how editors run cstudy on the open file: cstudy test python/practice/two_sum.py is cstudy test two-sum --lang python.

Where cstudy writes each language's stub
LanguageYour solution file
Pythonpython/practice/two_sum.py
TypeScripttypescript/practice/two-sum.ts
Javajvm/java/src/main/java/practice/two_sum/Solution.java
Kotlinjvm/kotlin/src/main/kotlin/practice/two_sum/Solution.kt
Gogo/practice/two_sum/two_sum.go
Rustrust/practice/two_sum.rs

Starting and resuming

cstudy start <slug> writes the stub, renders the statement to .statements/<slug>.md, begins an attempt and opens both files in $VISUAL or $EDITOR. The stub opens with the problem’s title, a short summary, the path of the statement and the command that runs it. Starting a problem you already have in progress in the same language resumes that attempt and keeps your file.

cstudy start flags
FlagEffect
--lang LThe language; default: default_lang
--freshMove your existing file to .archive/ and write a new stub; a review attempt does the same, and nothing is deleted
--timer 25mA time box, such as 25m or 1h; finishing over it caps the grade at hard
--no-openDo not launch the editor

Set open_on_start = false in your configuration if you never want cstudy to launch the editor.

Testing

cstudy test runs your code against the problem’s cases. With --watch it runs again each time you save. Visible cases are always listed; passing hidden cases collapse into a count unless you pass --all; a failing hidden case shows its input, the expected answer and yours.

terminal
$ cstudy test --time-limit
two-sum · kotlin · 16 cases (2 visible, 13 hidden, 1 generated) · time limit 5x · timer 12:31 / 25:00
build  1.8s (gradle, warm)

PASS     ex1   0.04ms
PASS     ex2   0.03ms
FAIL     h1    hidden
         input     nums=[-3, 8, 0, 3]  target=0
         expected  [0, 3]  (unordered)
         actual    [2, 2]
         note      negatives and zero
TLE      g1    hidden · 412ms > limit 95ms (5x hash-map, calibrated)
PASS     12 hidden cases

14/16 passed · 1 failed · 1 tle · total 2.6s
Case statuses
StatusMeaning
PASSThe comparator accepted your output
FAILWrong answer
ERRORYour code raised an exception or crashed
TIMEOUTThe hang guard (10 seconds by default) stopped a run that did not finish
TLERight answer, but over the time limit (only with time limits on)
INVALIDYour output cannot be read as the declared type
STALLEDA concurrent stress run was still unfinished at its deadline, or a project case on a virtual clock deadlocked
NOT RUNThe case did not run

Useful flags

cstudy test flags for practice
FlagEffect
--case IDRun only these cases; repeatable
--allList every case, passing hidden ones included
--time-limit[=VALUE]Turn time limits on. The default gives each case 5 times the reference’s time (5x), with a floor of 100 ms; --time-limit=1500ms sets one limit for every case
--no-time-limitTurn them off, even when your configuration turns them on
--perfAfter every case passes, run a short benchmark and print its verdict
--typecheckTypeScript: also run tsc, since Node’s type stripping does not type-check
--stress NFunction and design problems: also check your code on N generated inputs against a brute-force oracle; concurrent problems: run each stress case N times
--debugWait for your debugger; see Debugging

On a full pass the summary ends with all passed. Next: cstudy done --rating easy|ok|hard. Every run except a debug run is recorded, so cstudy knows whether your latest run passed when you finish.

Hints and solutions

cstudy hint reveals the next hint of the problem. Hints are counted per attempt, and using any caps the grade at ok.

terminal
$ cstudy hint
two-sum · hint 1 of 3
Fix one element. Which single value would complete the sum with it?

cstudy solution shows, through your pager, the explanation of the optimal approach and its code in your language. Before your attempt has passed, it asks first, because revealing the solution grades the attempt as again:

text
Reveal the solution? The attempt will be graded as again. [y/N]
cstudy solution flags
FlagEffect
--lang LShow the code in another language
--approach IDShow one approach, such as brute-force
--allShow every approach, in ladder order
--explanation-onlyLeave out the code
--broken[=ID]Concurrent problems and projects with stress cases: show a deliberately broken reference, as a spot-the-bug exercise
--yesSkip the confirmation

Finishing an attempt

cstudy done closes the attempt and schedules the review. When your latest test run passed every case, rate how it went with --rating easy, ok or hard; when it did not, finish with --gave-up. Add --notes "…" to keep a note on the attempt.

A problem with levels needs only level 1 for a rating: the attempt passes through the highest level you passed, as in passed · through level 2 of 4, and comes back on its normal review schedule. The next attempt starts at level 1, and its statement and cstudy status name the level to try. A mock interview still needs every level.

terminal
$ cstudy done --rating ok
two-sum · kotlin · passed · 18m 40s · rating ok · hints 0
next review  2026-10-27 (in 3 days) · ease 2.50

The rating becomes a grade, and some things cap it. The lowest cap wins:

How a grade is computed
SituationGrade
Gave up, or revealed the solution before passingagain (0)
Rated easy, ok or hardeasy (3), ok (2), hard (1)
Used a hintat most ok
Finished over the --timer time boxat most hard
Latest benchmark of the attempt is suboptimal, at medium or high confidenceat most hard (turn this off with penalize_suboptimal = false under [schedule])

Solve time is the wall-clock time from cstudy start to cstudy done; there is no pause.

Stopping without finishing

cstudy abort stops working on a problem: after a question, the attempt ends as abandoned, with no grade and no rating, and your review schedule does not change. Your files stay where they are, and the attempt’s hints and runs stay in cstudy history. It refuses while a run or a job is active.

terminal
$ cstudy abort --yes
two-sum · python · abandoned · 2s
kept    python/practice/two_sum.py
next    cstudy start two-sum

The next cstudy start of the problem begins a new attempt in the file that stayed. For a problem with a review scheduled, the file first moves to .archive/; nothing is deleted.

Reviews and spaced repetition

cstudy schedules each problem with a simplified SM-2 algorithm. A good grade pushes the next review further out; a lapse brings the problem back tomorrow. This is how one problem moves through 6 reviews:

A worked review sequence
ReviewGradeNext review inEase after
1ok3 days2.50
2ok7 days2.50
3ok18 days2.50
4hard22 days2.35
5again1 day2.15
6ok3 days2.15

Intervals never exceed 180 days (max_interval_days). A problem counts as mastered once its interval reaches 21 days with a last grade of ok or better, and as due on and after its review date. While an attempt is open it shows as in progress instead.

A problem with levels is mastered level by level, each on its own reviews: it reads mastered through level 2 of 4 until every level is, and a plain mastered means every level.

These are the defaults. The fixed intervals, the cap and the mastered threshold are yours to change, under [schedule] in your configuration. A new interval applies to reviews scheduled from then on, and dates already set do not move.

What cstudy next picks

cstudy next answers “what should I practise now?” the same way every time for the same progress and date:

  1. An attempt you have open, the one you used most recently, with any others listed after it. --new and --review skip this step.
  2. Otherwise a due review, ranked by how overdue it is relative to its interval, plus how weak its pattern is.
  3. Otherwise a new problem from the weakest pattern (or, outside the algorithms track, the weakest track). Within it, easy problems come first; medium opens once you pass an easy one, and hard once you pass a medium one.
  4. Otherwise it prints nothing due and no new problems in scope.
terminal
$ cstudy next
resume  merge-intervals  (medium · intervals)  attempt 3 in python, last used 2026-11-07
start   cstudy start merge-intervals --lang python
also    lru-cache (python)
terminal
$ cstudy next
review  merge-intervals  (medium · intervals)  overdue 3d, interval 7d
start   cstudy start merge-intervals --lang kotlin
terminal
$ cstudy next
new     koko-eating-bananas  (medium · binary-search)  weakest pattern: binary-search (0.75)
start   cstudy start koko-eating-bananas --lang kotlin

Weakness combines your recent fail rate, how much of the group you have mastered, and how long ago you last practised it. An untouched group scores 0.75, so cstudy rotates through new patterns before going deep on one.

cstudy next flags
FlagEffect
--set NAMEFrom this set of yours, in its order
--track TTracks to pick from, repeatable; default dsa, or next.tracks in your configuration, and every track with --set, --domain, --role or --scope
--pattern POnly problems with this pattern
--difficulty Deasy, medium or hard
--lang LOnly problems available in this language, and start in it
--domain D, --role R, --scope SOnly what lists this label
--new / --reviewOnly new problems, or only reviews
--startStart the pick right away

Finding problems

cstudy list browses the catalog. Its filters combine, and cstudy next takes the same labels, so you can ask for what you are preparing for:

shell
cstudy list --domain security      # also --role and --scope
cstudy list --search retry         # a slug or a title
cstudy next --role ai-engineer --lang typescript
terminal
$ cstudy list --domain security
ID    SLUG              DIFF    PATTERN          STATUS       DUE         REFS
0255  token-claim-...   medium  arrays-hashing   new          -           py ts
0256  refresh-toke...   medium  arrays-hashing   new          -           py ts
0257  authorizatio...   medium  graphs           new          -           py ts
-     review-auth-...   medium  code-review      new          -           -
terminal
$ cstudy next --domain security
new     token-claim-validator  (medium · arrays-hashing)  weakest track: practical (0.75)
start   cstudy start token-claim-validator --lang python

--search finds the problems and items whose slug or title holds the text, in any case:

terminal
$ cstudy list --search retry
ID    SLUG              DIFF    PATTERN          STATUS       DUE         REFS
0274  vendor-retry...   hard    -                new          -           ts
-     review-payme...   hard    code-review      new          -           -

Guides and paths

A guide is a short reading that teaches one idea before you practise it: the idea in plain words, a worked example, when to use it, the common traps, the cost, notes for experts and the problems that practise it. A path puts guides and problems in order, from a topic’s first idea to an expert’s. There are 74 guides and 11 paths: algorithm topics such as binary search and graphs, AI engineering, data engineering, and getting started, from the terminal and package managers to easy first problems.

shell
cstudy learn                       # the guides and the paths, with what you have read
cstudy learn --path hashing        # a path's steps and the next one
cstudy learn hash-functions        # read a guide; add --done once you have
cstudy learn hash-functions --open # read it in the page, with the diagrams drawn

cstudy learn <guide> prints the guide in the terminal, with each diagram as a text drawing. Reading needs no workspace; --done, which marks the guide read, needs one. cstudy learn --path shows a path’s steps, what is done and the next command:

terminal
$ cstudy learn --path hashing
hashing  Hashing: from your first hash map to content-addressed storage
From what a hash function is to Merkle proofs, through the problems that practise each idea.
3 of 22 done
#   KIND     STEP                        TARGET   STATUS          TITLE
1   guide    hash-functions                       read            What a hash function is
2   guide    hash-maps-and-sets                   read            Hash maps and sets
3   problem  contains-duplicate                   passed          Contains Duplicate
4   problem  two-sum                              attempted       Two Sum
...
20  problem  tamper-evident-ledger       level 2  level 1 passed  Tamper-Evident Ledger
next      cstudy start two-sum

A problem step is done once the problem passes, or, with a target such as level 2, once that level passes. The page shows the same guides with their diagrams drawn; see Guides in the page.

Problem sets

A set is a list you choose, in the order you want to study it: make one for an upcoming interview, add problems and items to it, and study from it without searching. A problem can be in several sets.

shell
cstudy set create backend-loop --description "The backend loop on the 12th"
cstudy set add backend-loop two-sum lru-cache url-shortener
cstudy next --set backend-loop
cstudy list --set backend-loop
terminal
$ cstudy set show backend-loop
backend-loop  The backend loop on the 12th
0 of 3 passed
#   ID    SLUG              DIFF    PATTERN          STATUS       DUE         REFS
1   0001  two-sum           easy    arrays-hashing   new          -           py ts java kt go rs
2   0002  lru-cache         medium  linked-list      new          -           py ts java kt go rs
3   -     url-shortener     medium  system-design    new          -           -
next    cstudy next --set backend-loop

cstudy next --set picks an attempt you have open in the set, then the first entry you have not passed, then a due review from the set. It searches every track unless --track narrows it, and it says so when the set is finished or empty.

terminal
$ cstudy next --set backend-loop
new     two-sum  (easy · arrays-hashing)  next in backend-loop, 1 of 3
start   cstudy start two-sum --lang python
set     backend-loop  0 of 3 passed

For a problem with levels, an entry can aim at a level below the last: cstudy set add backend-loop tamper-evident-ledger --level 2, or - {slug: tamper-evident-ledger, level: 2} in sets.yaml. The set then counts it as passed once level 2 passes, and so does cstudy next --set.

Sets live in sets.yaml at the root of your workspace, so you can read it, edit it by hand and commit it; a change from cstudy touches only the lines it must, so your comments stay. cstudy reset keeps your sets. A problem the catalog no longer has shows as missing and stops nothing. The page that cstudy serve runs has your sets too. Every subcommand is in the command reference.

Checking performance

cstudy bench runs your solution and every reference approach on the same generated inputs at growing sizes, fits how the time grows, and compares you with the optimal reference. It checks your answers at every size too.

terminal
$ cstudy bench
two-sum · python · sizes 1e2..1e5 · reps 7 · power AC · load 1.2

TARGET       DECLARED  n=1e2   n=1e3   n=1e4   n=1e5   SLOPE  BAND      MEMORY
brute-force  O(n^2)    0.21ms  19.8ms  2.04s   budget  2.00   ~n^2      constant
hash-map     O(n)      0.01ms  0.09ms  0.94ms  10.1ms  1.00   ~n|nlogn  linear
you                    0.01ms  0.11ms  1.10ms  11.8ms  1.01   ~n|nlogn  linear

verdict   optimal: matches hash-map, 1.17x at n=1e5 · confidence high (spread 3%, R^2 0.999)
space     linear, same as hash-map · confidence high
history   best previous 13.0ms at n=1e5 (2026-09-12) · now 9% faster · 1st of 3 runs
Bench verdicts
VerdictMeaning
optimalSame growth band as the optimal reference, at most 1.5 times its time at the largest size, and not growing apart
near-optimalSame band, but the ratio grows with n, likely an extra log factor, or stays above 1.5: a slower constant factor
suboptimalA worse growth band, or over the budget where the optimal reference finished
unknownToo few usable sizes, or no optimal reference in this language

Each verdict comes with a confidence, high, medium or low, and a warning when your machine was busy or on battery. Benchmarks compare you with the references and with your own earlier runs, never with other people.

cstudy bench flags
FlagEffect
--sizes LISTComma-separated input sizes, such as 100,1000,10000
--reps NRepetitions per size (default 7)
--refs-onlyBenchmark only the references; needs no attempt
--no-memorySkip the memory measurement
--lang LThe language of the attempt to benchmark

Note

Concurrent and project problems have no benchmark. See the performance analysis spec for what a slope can and cannot tell.

Timers and mock interviews

Any attempt can have a time box: cstudy start two-sum --timer 25m. cstudy test then shows the time left, and finishing over it caps the grade at hard.

cstudy mock simulates an interview. It picks new medium and hard problems, each from a different group where it can, starts them together with one shared timer, and locks cstudy hint and cstudy solution until the timer ends or every problem is done.

terminal
$ cstudy mock
mock interview · 2 problems · 45 min shared timer · python
1  group-anagrams  (medium · arrays-hashing)  weakest pattern: arrays-hashing (0.75)
   stub       python/practice/group_anagrams.py
   statement  .statements/group-anagrams.md
2  three-sum  (medium · two-pointers)  weakest pattern: two-pointers (0.75)
   stub       python/practice/three_sum.py
   statement  .statements/three-sum.md
locked     cstudy hint and cstudy solution, until the timer ends or every problem is done
next       cstudy test group-anagrams --watch
cstudy mock flags
FlagEffect
--minutes NThe shared timer (default 45)
--count NHow many problems (default 2)
--track TTracks to pick from, repeatable
--lang LThe language to start them in

In a mock attempt of a project problem, cstudy submit reports only how many hidden cases failed per level, as an interview would.

Tracking progress

cstudy stats summarises your progress per group: problems, attempts, passes, mastered problems, the pass rate of the last 10 attempts, median solve time and weakness. Below come your streak, the reviews due and your latest benchmark verdicts.

terminal
$ cstudy stats
GROUP                 PROBLEMS  ATTEMPTED  PASSED  MASTERED  PASS RATE  SOLVE TIME  WEAKNESS
arrays-hashing              12          5       4         1        80%     14m 10s      0.42
two-pointers                 8          0       0         0          -           -      0.75
...
system-design               10          1       1         0       100%     45m 00s      0.30

attempts  6 finished · 5 in the last 7 days · streak 3 days
reviews   1 due today · 1 overdue
bench     4 benched · 2 optimal · 1 near-optimal · 1 suboptimal · 0 unknown

Group by --by pattern (the default), track, lang or difficulty; narrow the attempt columns with --since 2026-10-01; or print --json. To browse problems with their status and next review date, use cstudy list, filtered with --status new|in_progress|attempted|passed|due|mastered:

terminal
$ cstudy list
ID    SLUG              DIFF    PATTERN          STATUS       DUE         REFS
0001  two-sum           easy    arrays-hashing   passed       2026-10-27  py ts java kt go rs
0002  lru-cache         medium  linked-list      in progress  -           py ts java kt go rs
0046  koko-eating-...   medium  binary-search    due          2026-10-21  py ts java kt go rs

Starting over

cstudy reset deletes your progress in this workspace, an open attempt included: attempts, scheduled reviews, benchmark runs, run folders and rendered statements. You see what goes and what stays, with counts, before anything does, and you type reset to confirm. It can’t be undone, so run cstudy export first if you may want your progress back.

Your practice files, project folders and notes stay unless you pass --files, and .archive/ stays unless you pass --archive. Your configuration, toolchains, own problems and sets always stay. See the command reference.

Written for cstudy 0.46.0. The specs in the cstudy repository are the source of truth for every detail.