The 50 Programs Challenge — Muscle Memory¶
Reading Java without typing Java is memorization theater. This is the actual work of Phase 01: fifty small programs, hand-typed, no AI, no copy-paste, no Stack Overflow for syntax. Concept lookups are fine — syntax lookups are the thing you are trying to eliminate.
The programs are grouped in five sets of ten. Each program is small (5–30 minutes) but forces one specific slice of the language into your fingers. Do them in order. Do not skip. If a program takes over the estimated time by 2×, you found a hole — fill it before moving on.
The rules¶
No AI assistant. Copilot off, Claude tab closed, ChatGPT closed. Even for autocomplete.
No copy-paste of code, even from your own earlier programs. Retype.
You may read the docs (
https://docs.oracle.com/en/java/javase/21/docs/api/). You may not search “how to do X in Java”.Each program lives in its own file or its own class inside
main. One repo:java-50-programs.Log time-taken per program in a
LOG.md. After all 50, look at the outliers — those are the areas to shore up.Write JUnit or a
main-based smoke test for every program. No exception — the point is verified correctness, not “looks right”.
Repo layout suggestion¶
java-50-programs/
├── pom.xml (Maven, Java 21, JUnit 5)
├── LOG.md (per-program time log)
└── src/main/java/dev/raghul/
├── set1_warmup/ P01..P10
├── set2_collections/ P11..P20
├── set3_io/ P21..P30
├── set4_oop/ P31..P40
└── set5_mixed/ P41..P50
Set 1 — Strings & Arrays Warmup (10 programs, ~90 min)¶
Basic syntax reflex. Loops, arrays, String, StringBuilder.
# |
Program |
What it tests |
Acceptance |
Est |
|---|---|---|---|---|
P01 |
Reverse a string without |
char-array, loops, index math |
|
5 min |
P02 |
Check if a string is a palindrome (ignore case, ignore non-alphanumeric) |
|
|
8 min |
P03 |
Count vowels and consonants in a string |
switch on |
Returns two ints; test with mixed case |
5 min |
P04 |
Find the first non-repeating char in a string |
|
|
10 min |
P05 |
Fizz-buzz 1..100 using switch expression |
switch expression on modulo booleans |
Exact expected output |
5 min |
P06 |
Print all prime numbers up to N |
Sieve of Eratosthenes with |
|
10 min |
P07 |
Rotate an int array left by K positions in place |
reverse trick or extra array |
|
10 min |
P08 |
Find the missing number in an array of 1..N with one missing |
sum formula OR XOR trick |
Two implementations, both O(n) |
8 min |
P09 |
Compress a string: |
|
Correct behavior on both paths |
10 min |
P10 |
Given a 2D int array (matrix), print its transpose |
nested loops, index swap |
Non-square matrix works |
8 min |
Set 2 — Collections Drills (10 programs, ~2 hours)¶
Every List, Set, Map, Queue, Deque API in your fingers.
# |
Program |
What it tests |
Acceptance |
Est |
|---|---|---|---|---|
P11 |
Word frequency counter from a |
|
Output stable, ties broken alphabetically |
10 min |
P12 |
Find top-K frequent words using |
min-heap of size K, custom |
O(n log k), test with k=3 |
15 min |
P13 |
Group a |
|
Same output both ways |
10 min |
P14 |
LRU cache with capacity 5 by extending |
|
Test sequence: put 6 items, verify eviction of eldest-accessed |
15 min |
P15 |
Detect duplicates in a |
|
Test with all unique and with duplicates |
5 min |
P16 |
Merge two sorted |
two-pointer, iterators |
No |
10 min |
P17 |
Given |
vertical scan or |
|
10 min |
P18 |
Rotate a |
|
k > size handled with modulo |
8 min |
P19 |
Given |
|
Verify both keys present even if empty |
5 min |
P20 |
Implement a bounded |
generic class, custom exception |
Push/pop/peek/isFull; test overflow |
15 min |
Set 3 — File I/O Tasks (10 programs, ~2 hours)¶
NIO.2 in your fingers. Every one uses Path / Files.
# |
Program |
What it tests |
Acceptance |
Est |
|---|---|---|---|---|
P21 |
Read a text file, print each line prefixed with line number |
|
1-indexed line numbers, no trailing blank line |
8 min |
P22 |
Count lines, words, chars in a file (mini |
|
Compare to real |
10 min |
P23 |
Copy a file byte-for-byte using buffered streams |
|
Verify size and MD5 match |
10 min |
P24 |
Split a large text file into N smaller files by line count |
streaming write with buffered writer |
Line total preserved; no ordering bugs |
15 min |
P25 |
Recursively list all files under a directory larger than 1 MB |
|
Correct on nested dirs with symlinks handled |
15 min |
P26 |
Grep-lite: given a regex and a file, print matching lines with line numbers |
|
Case-insensitive flag |
15 min |
P27 |
Write a |
|
Round-trip preserves all entries |
10 min |
P28 |
Given a directory, compute total size and file count in it (non-recursive vs recursive) |
|
Two methods, both return same on flat dir |
10 min |
P29 |
Watch a directory and print any newly-created file names for 30 seconds |
|
Create a file externally, event fires |
20 min |
P30 |
Read a CSV without a library: 3 columns, quotes may contain commas |
manual state machine on chars |
Test with |
20 min |
Set 4 — Basic OOP Kata (10 programs, ~2.5 hours)¶
Records, sealed types, interfaces, equals/hashCode, exception design.
# |
Program |
What it tests |
Acceptance |
Est |
|---|---|---|---|---|
P31 |
|
record with methods & static factory |
|
8 min |
P32 |
Sealed |
sealed + pattern switch |
Exhaustive switch, no |
15 min |
P33 |
|
compact constructor validation |
Throws on bad input |
10 min |
P34 |
|
encapsulation, custom exception |
Balance never goes negative silently |
15 min |
P35 |
Generic |
generics, single-pass min-max |
Handles empty via |
10 min |
P36 |
|
Comparable vs Comparator |
Sort a |
15 min |
P37 |
Enum |
enum with fields & static lookup map |
Unknown code → |
10 min |
P38 |
Interface |
interface default methods |
Two impls: |
15 min |
P39 |
Abstract class |
abstract vs concrete methods |
Test polymorphic dispatch |
10 min |
P40 |
|
sealed generics, ADT |
|
15 min |
Set 5 — Mixed / Integration (10 programs, ~3 hours)¶
Combines everything. Slightly larger. Each is basically a mini-project.
# |
Program |
What it tests |
Acceptance |
Est |
|---|---|---|---|---|
P41 |
CLI calculator: parses |
Shunting-yard or recursive descent, |
5 correctness tests incl. parentheses |
30 min |
P42 |
Word-count from a directory of text files, aggregated across all files |
|
Matches |
20 min |
P43 |
Roman numeral ↔ integer converter (both directions) |
switch expression, order-sensitive parsing |
3999 max; symmetric round-trip test |
20 min |
P44 |
In-memory key-value store with |
|
Test with 100ms TTL |
25 min |
P45 |
Log-line parser: given |
regex, |
Output a Map<Level, Map<Hour, count>> |
30 min |
P46 |
Priority-based task scheduler: takes tasks with priority, |
|
Ties correct |
20 min |
P47 |
JSON-ish printer for arbitrary records (single-level): use reflection to print |
|
Works on any record you pass in |
20 min |
P48 |
Directory-diff: given two dirs, print files added / removed / modified (by size) between them |
|
Symlink-safe |
25 min |
P49 |
Rate limiter: allow max N calls per T seconds, |
|
Concurrent-unsafe is fine for now |
20 min |
P50 |
Simple TCP echo server that handles multiple clients using virtual threads |
|
Telnet-testable; graceful shutdown |
30 min |
After you finish¶
Open LOG.md and look at:
The three programs that took longest. Which topic? Re-read the corresponding file, then redo one of them from scratch.
Programs where you looked up syntax. Which syntax? That’s your weak spot. Write two more programs exercising it.
Programs where your tests failed on first run. What did you miss (edge case? null? empty input?). Make a mental note of the pattern.
⚠️ What most people get wrong¶
They race through the list to feel productive. The point is not to reach 50. The point is that when you sit down for a coding round in month 8, Files.lines(path).filter(...).collect(...) flows out without a pause. If you rush and don’t verify with tests, you finish 50 shaky programs and gain nothing.
Also: do not skip the OOP kata (Set 4) because “you know OOP”. That set drills modern Java’s specific OOP surface — records, sealed, pattern switch — which is what employers screen for on Java 21.
Return to README.md · Next: projects.md