v0.8.0 A command line for interview practice

Practise coding interviews in your own editor.

cstudy writes the stub into a real project for your language, tests your code against visible and hidden cases, tells you whether it scales like the optimal solution, and schedules each problem for review. It runs on your machine, in Python, TypeScript, Java, Kotlin, Go and Rust.

Install with Homebrew
brew install bkuberek/tap/cstudy
Solution.kttwo-sum.md
// Two Sum. Statement: .statements/two-sum.md. Run: cstudy test two-sum

package practice.two_sum

class Solution {
    fun twoSum(nums: IntArray, target: Int): IntArray {
        for (i in nums.indices) {
            for (j in i + 1 until nums.size) {
                if (nums[i] + nums[j] == target) return intArrayOf(i, j)
            }
        }
        return intArrayOf()
    }
}
~/cstudy-workspace
$ cstudy test --time-limit
two-sum · kotlin · 16 cases (2 visible, 13 hidden, 1 generated) · time limit 5x
build  1.8s (gradle, warm)

PASS     ex1   0.04ms
PASS     ex2   0.03ms
TLE      g1    hidden · 412ms > limit 95ms (5x hash-map, calibrated)
PASS     13 hidden cases

15/16 passed · 1 tle · total 2.6s
ready problems
254
languages
6
autograded tracks
5
algorithm patterns
23
project problems
6

From the cstudy 0.8.0 catalog, synced 2026-10-31.

01 What it is

A practice system that lives in your terminal

You solve original problems in your editor, and the cstudy command does the rest: it picks the next problem, runs your code, shows hints and reference solutions, measures performance and keeps track of your progress.

  • a.

    Your editor, real toolchains

    Each language is an ordinary project, built with uv, pnpm, Gradle, Go modules or Cargo, that your editor and its language server open directly. Breakpoints work too: cstudy test --debug waits for your debugger.

  • b.

    More than algorithms

    Data structures and algorithms, practical problems that grow over levels, low-level design, concurrency and debugging, plus system design and code review prompts that you grade yourself with a rubric.

  • c.

    Optimality, not only correctness

    cstudy bench measures how your solution grows with the input size and compares it with the reference approaches, so you know whether a passing solution is also the right one.

  • d.

    Spaced repetition

    cstudy done schedules the next review from how the attempt went, and cstudy next brings back what is due or picks a new problem from your weakest pattern.

02 How practice works

Pick, solve, test, come back later

One loop, the same in every language. Each step is one command you can also run from your editor.

  1. Pick a problem

    cstudy next suggests a review that is due, or a new problem from the pattern where you are weakest, and prints the command that starts it.

    terminal
    $ cstudy next
    new     koko-eating-bananas  (medium · binary-search)  weakest pattern: binary-search (0.75)
    start   cstudy start koko-eating-bananas --lang kotlin
  2. Start it

    cstudy start writes a stub with the right signature, renders the statement and opens both in your editor. The attempt’s clock starts here.

    terminal
    $ cstudy start two-sum --lang kotlin
    two-sum · easy · arrays-hashing · kotlin
    stub       jvm/kotlin/src/main/kotlin/practice/two_sum/Solution.kt
    statement  .statements/two-sum.md
    next       cstudy test --watch
  3. Solve it in your editor

    Your solutions live in a workspace of your own, next to your notes and progress. Open it in VS Code, IntelliJ IDEA, Neovim or anything else: completion, diagnostics and debugging work as in any project.

    workspace
    ~/cstudy-workspace
      python/        pyproject.toml, uv.lock, practice/
      typescript/    package.json, tsconfig.json, practice/
      jvm/           Gradle wrapper, java/ and kotlin/ projects
      go/            go.mod, practice/
      rust/          Cargo.toml, practice/
      projects/      one folder per project problem
      notes/         your answers to system design and code review prompts
      progress.db    your attempts and reviews, in SQLite
  4. Test on every save

    cstudy test --watch runs your code against the cases each time you save. Visible cases are always listed; a hidden case that fails shows its input, the expected answer and yours. Time limits are off unless you ask for them.

    terminal
    $ cstudy test --time-limit
    two-sum · kotlin · 14 cases (2 visible, 11 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     h3    hidden
             input     nums=[-3, 8, 0, 3]  target=0
             expected  [0, 3]  (unordered)
             actual    [3, 3]
    TLE      g1    hidden · 412ms > limit 95ms (5x hash-map, calibrated)
    PASS     10 hidden cases
    
    12/14 passed · 1 failed · 1 tle · total 2.6s
  5. Finish, and come back when it is due

    Rate the attempt easy, ok or hard. Hints, a revealed solution or a blown time box lower the grade, and the grade sets the next review.

    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

Stuck?cstudy hint reveals one hint at a time, and cstudy solution shows the reference approaches with their explanations. During an unsolved attempt it asks first, because revealing grades the attempt as again.

03 Coverage

6 languages, 5 autograded tracks, 254 problems

Every statement, test and solution is original. Tests are written once as language-neutral data, so a problem is the same problem in every language you practise it in.

  • Python239 problemsuv and Python 3.13
  • TypeScript235 problemsNode 24 and pnpm
  • Java240 problemsJDK 21, Gradle wrapper
  • Kotlin240 problemsJDK 21, Gradle wrapper
  • Go237 problemsGo 1.24 or newer
  • Rust236 problemsRust 1.80 or newer, via rustup

228 of the 254 problems have reference solutions in all 6 languages. The others are project problems, each written for one language, and problems that a language cannot express or whose bug exists only in some languages.

Tracks in the cstudy 0.8.0 catalog
TrackProblemsGraded byFormat
Data structures and algorithms dsa196Tests, in every languageFunctions and data-structure designs across 23 patterns
Practical practical28Tests, level by levelOne class whose API grows over levels, a project folder, or a business task with money and dates
Low-level design lld8Tests, then a design rubricObject-oriented design
Concurrency concurrency6Stress tests against invariantsThread-safe classes, with a concurrency model per language
Debugging debugging16TestsBuggy code to fix, including bugs that exist only in Go or Rust
System design system-design10Yourself, with a rubricA prompt, a notes template and a reference design
Code review code-review6Yourself, with a rubricA change to review, and the issues a strong reviewer finds

04 Project problems

Grow one codebase, level by level

A project problem starts from a seeded folder instead of a single function, and opens in levels that build on the same code, the way a longer practical exercise does.

There are 6 project problems, in Python, TypeScript, Java, Kotlin, Go and Rust. Each opens with level 1 and adds a level at a time, up to 4:

  1. level 1Accounts and transfers
  2. level 2Top spenders
  3. level 3Scheduled transfers
  4. level 4Merges and balance history

cstudy test runs the project’s own tests with the language’s native framework. cstudy submit grades every case of the open levels, hidden ones included, and opens the next level once they all pass.

terminal
$ cstudy submit
bank-project-python · python · submit levels 1-2 of 4 · timer 33:05 / 90:00

level 1  PASS     5/5 (2 visible, 3 hidden)
level 2  FAIL     4/5 (2 visible, 3 hidden)
FAIL     h3    hidden · level 2
         input     ops ["Bank", "create_account", ...]  args [[], [1, "zoe"], ...]
         expected  ["abe(60)", "zoe(60)", "mia(0)"]
         actual    ["zoe(60)", "abe(60)", "mia(0)"]

9/10 passed · level 3 opens when levels 1-2 pass

05 Complexity

Passing is good. Optimal is the goal.

cstudy bench runs your solution and every reference approach on the same generated inputs, fits how the time grows, and places you on the problem’s complexity ladder with an explicit confidence.

  • Separates growth classes such as n and n² reliably; tells n from n log n by the ratio to the optimal reference.
  • Measures extra memory too, and says how sure it is.
  • Compares you with your own previous runs, never with other people.
  • Optional time limits for cstudy test scale from the reference timings, so a brute force fails the large cases when you ask it to.

More about complexity checks

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

06 Install

From zero to your first problem

Install cstudy with Homebrew, create a workspace and let cstudy doctor set up the language projects. cstudy runs your code with each language’s real toolchain: uv and Python are required, and Node, JDK 21, Go and Rust only for the languages you use.

  • One install brings the problems, tracks and runners.
  • cstudy doctor checks every toolchain and prints the fix for anything missing.
  • Works offline after the one-time setup.
quick start
brew install bkuberek/tap/cstudy
cstudy init ~/cstudy-workspace --git   # --git runs git init; cstudy never commits
cd ~/cstudy-workspace
cstudy doctor --fix                    # uv sync, pnpm install, Gradle warm-up, runner checks
cstudy next                            # suggests a problem and prints the command to start it

Open source, under the MIT licence.

The code and the problem content are MIT licensed. The source, the specs and the decision records are all on GitHub.