Programming lessons & courses
127 lessons · 29 learning paths · free, quiz-checked, no signup required
Compilers, concurrency, databases, reverse engineering, and the other load-bearing layers under everyday code. Each lesson explains what the machinery actually does (parsers, locks, B-trees, loaders) with worked examples and realistic code.
Learning paths
Performance Profiling: Finding the Bottleneck That Matters
Most optimisation effort goes into code that was never the problem, because intuition about where time goes is reliably wrong. This path builds the discipline instead: the arithmetic that caps what any optimisation can buy, how profilers work and how to read a flame graph, the six causes behind almost all real slowness, and how to benchmark honestly and recognise the point where optimising stops paying.
Deployment Strategies: Shipping Without Breaking Things
A deploy replaces a working system with a different one while people are using it. This path covers how teams make that routine: the four strategies as answers to how many users meet a bad version, canary releases as controlled experiments, feature flags separating deploy from release, and the compatibility discipline that decides whether the rollback you are counting on actually works.
The AWS Ecosystem: A Map of the Platform
AWS lists hundreds of services, which makes it look like a catalogue to memorise. It is not. This path gives you the scaffolding everything else hangs from: the geography of regions and availability zones, accounts and IAM as your blast radius, the compute spectrum from machines to functions, the three shapes of storage and how to choose a database, and the network layout that quietly decides your bill.
Testing Strategy: What Is Worth Testing
Tests are a purchase, not a virtue: you spend writing time, run time and maintenance time to buy confidence about specific breakages. This path works out how to spend that budget. What each level of test can and cannot catch, how test doubles buy speed by trading away fidelity, how property-based testing finds the inputs you would never have imagined, and why flakiness destroys a suite faster than any missing test.
Observability: Knowing Why Production Is Slow
Monitoring answers the questions you wrote down in advance; production fails in ways you did not. This path builds observability from its raw materials: the three telemetry signals and their very different bills, the percentile and cardinality arithmetic that decides what your data can honestly say, tracing and the craft of throwing spans away, and the SLO machinery that turns reliability into a number a team can actually spend.
Kubernetes: Orchestration as a Set of Control Loops
Kubernetes looks like a pile of object types until you notice it is one idea repeated. Store a description of the desired state, and run loops that compare it to reality and act on the difference. Because those loops read the current state rather than react to events, missed and duplicated messages are harmless and an interrupted controller simply resumes. This path builds the loop, shows every object as a controller joined by label matching, covers the two resource numbers that drive most cost and latency bugs, and ends with the failures the design itself creates.
Containers From First Principles
There is no container object in the Linux kernel and no container system call. A container is an ordinary process with several isolation features switched on, all of which predate the technology by years. So the thing that actually changed practice was not the kernel: it was an image format that is immutable, content-addressed and shippable, built on the same idea as Git's object store. This path covers the primitives, the format and its consequences, where data and traffic have to go, and the honest answer on how much the isolation is worth.
Git Internals: The Model Under the Commands
Git's command line has a deserved reputation, and the data model underneath is small and regular. It is a content-addressed store of four object types, plus a set of files holding hashes. This path derives the object hash by hand, shows that a branch is a forty-character file, explains what a three-way merge actually computes and why rebase creates new commits rather than moving them, and ends with recovery. Every command turns out to add objects or move a pointer.
Go: Goroutines, Channels, and What Was Left Out
A thread costs enough that programs are architected around not having many. A goroutine costs little enough that the constraint disappears, and the designs that become available are the point. This path builds the scheduler that makes them cheap, the channels that let them coordinate without shared memory, and the leak that is the characteristic Go bug because nothing stops a goroutine but its own return. It ends on the omissions: no exceptions, no inheritance, no formatting choices, and what each one trades.
Rust: Ownership, Borrowing, and What They Buy
Every language decides who frees memory and when, and Rust decides it at compile time from one rule: each value has exactly one owner. This path builds that rule, then the borrowing discipline that lets values be lent without transferring them. The payoff arrives in the third lesson, where data races turn out to be compile errors for free, because a race is aliasing plus mutation and the checker already forbids that. It ends on the escape hatches and where the guarantee genuinely stops.
No-Code Automation: Building Workflows That Keep Working
These platforms remove the cost of writing integration code, which was real, and leave the cost of operating an integration, which is larger and arrives later. This cursus covers why automations break once they run unattended, why partial failure is worse than total failure, and the idempotency problem behind most real damage. Then the patterns that survive production: validation, safe retries, rate limits, testing what you cannot test, and credentials. It ends on ownership, shadow automation, and when a flow has outgrown the tool.
Deploying Open-Source LLMs Privately
Self-hosting is usually justified on privacy grounds, and the argument is weaker than assumed: it changes who owns the controls, not whether controls are needed. This cursus examines the decision honestly, the reasons that hold up better than privacy, and the middle options the either-or framing hides. Then the serving stack: why generation is memory-bandwidth-bound, how continuous batching and KV cache management decide throughput, and sizing hardware. Then operating it, including the safety layer you inherited and must now rebuild.
Building an AI QA Function
Software QA assumes a specification, deterministic behaviour, and a system that changes only when you change it. An AI feature violates all three, and a provider updating a model shifts behaviour with no commit for your pipeline to catch. This cursus covers what replaces the old practice: characterising a distribution rather than asserting correctness, the evaluation set as the function's real asset, a release gate with thresholds set before results are seen, and how to stand the function up in ninety days without it quietly dying.
Subversion (SVN): The Centralized Version Control System
Git won, but Subversion never left, and plenty of long-lived, high-value codebases still run on it. Knowing SVN makes you useful where the code actually lives, and it sharpens your sense of what Git chose and why. This short cursus covers SVN on its own terms: the centralized model with its global revision numbers and atomic commits, the everyday update-edit-commit workflow with conflicts and locking, and branches, tags, and merging built from cheap directory copies, plus how to bridge to Git with git svn.
Healthcare Interoperability: HL7, FHIR, and Integration Engines
Clinical systems do not speak the same language by default, and someone has to make them. Healthcare interoperability is a durable, in-demand engineering niche with a low barrier to practice. This cursus builds it from the ground up: the interoperability problem and the HL7 v2 message model that still carries most hospital traffic, then FHIR's modern resource and REST API model, and finally the integration engine, Mirth Connect, that routes and transforms clinical data between systems, plus the concrete skills to break in.
How Unity works: the engine under your game
Stop fighting the engine and start using it. Learn why Unity is built on composition instead of class hierarchies, exactly when your code runs across Awake, Update, and the physics loop, how prefabs and serialization decide what survives to disk, and why physics runs on its own 50Hz clock. Finish able to explain the bugs that stump most Unity developers: the field that keeps resetting, the object that tunnels through walls, and the script that mysteriously never runs.
How Python really works: CPython internals
Go under the hood of the interpreter that runs most Python. Start with the object and data model, where every value is a heap object and behavior lives in dunder methods. See how source becomes bytecode and runs on a stack machine with an adaptive interpreter. Learn how reference counting and the cyclic collector reclaim memory. Finish with the GIL and the free-threading build that makes it optional. Come out able to reason about performance, memory, and concurrency from mechanism, not folklore.
Reverse engineering fundamentals
How to read a compiled binary back into something a human can reason about. The file format and loader, disassembly and decompilation of x86-64, and dynamic analysis with debuggers and instrumentation. Three lessons of mechanism — what the toolchain on each side actually does, and what no amount of effort can recover.
Advanced Python for backend
The advanced syntax and runtime patterns that production Python backends rely on. Async and asyncio fundamentals, the type system as both static contract and runtime spec, FastAPI's dependency-injection model, and SQLAlchemy 2.0's async ORM — four lessons of mechanism over framework hagiography.
Scalable System Design
Design systems that handle millions of users without falling over. You will size and scale app tiers with load balancers and autoscaling, apply caching strategies that cut DB load by 95%, partition databases with sharding and replication, and wire services together with message queues and resilience patterns — leaving you ready to lead a real system design review.
How Compilers Work
Follow source code on its full journey from raw characters to machine instructions. You will build intuition for each compiler phase — scanning, parsing, semantic analysis, and code generation — and understand why each exists, what can go wrong inside it, and how the phases connect. By the end you will be able to read compiler error messages with precision, write a toy expression evaluator, and reason about what your compiler is doing when you flip on -O2.
Distributed Systems Fundamentals
After finishing this cursus you will be able to design, evaluate, and reason about distributed systems with engineering precision: model failures and time correctly, choose the right consistency level for a workload, explain why consensus is hard and how Raft solves it safely, and architect replication and partitioning strategies that scale without creating hot spots or correctness bugs.
Database Internals
Go beneath the SQL surface and understand how databases actually work. After this track you will be able to explain how data is laid out on disk, why B-trees dominate relational indexes, when to reach for an LSM-tree instead, and how MVCC lets Postgres serve thousands of concurrent readers and writers without blocking. You will read query plans, tune buffer pools and checkpoints, design indexes that avoid heap fetches, and reason precisely about isolation levels and concurrency anomalies.
Concurrency and Parallel Programming
Master the full concurrency stack: from race conditions and lost updates, through mutexes and deadlock prevention, to CPU memory models and lock-free atomics, and finally to async event loops and coroutines. After this cursus you can reason about any concurrent system, pick the right synchronization primitive, and debug races and deadlocks methodically.
Applied Modern Cryptography
Build the cryptographic judgment to evaluate any system's security posture. You will be able to choose the right primitive for each job (AES-GCM, HMAC, Argon2, ECDH, Ed25519), explain why common constructions fail (ECB, textbook RSA, nonce reuse, bare CTR), read a TLS 1.3 handshake trace, and audit real code for the most dangerous cryptographic misuses.
Full-Stack with Node.js, React, and Next.js
An eight-lesson path that builds a full-stack engineer from the runtime up. Start with the Node.js event loop, build a REST API with Express, learn React fundamentals and hooks, master modern data fetching, then move into Next.js App Router, Server Components, Server Actions, and a Prisma + Postgres deployment.
Parallel Programming with CUDA
A six-lesson path from why GPUs exist to writing your own performant CUDA kernels. Learn the programming model, memory hierarchy, and optimization techniques that turn a 100x speedup from theoretical into practical.
API Design & Reliability
Six lessons on shipping an HTTP API that other engineers actually enjoy using. Start with REST principles and status codes, secure it with OAuth 2.0, then make it survive real traffic with rate limiting, idempotency, and load balancing.
Data Engineering Foundations
An eight-lesson path from SQL fundamentals to a modern data stack. You'll learn how to query and tune relational data, cache hot reads, model with dbt, choose between lakehouse and warehouse architectures, and wire pipelines together with Kafka and Airflow. By the end you can reason about every layer a production data platform actually runs on.
All Programming lessons
Scaling and Load Balancing
Master the mechanics of scaling distributed systems: when to scale up versus out, why statelessness is the prerequisite for horizontal scale, how L4 and L7 load balancers differ, which balancing algorithm fits which workload, and how to avoid turning your load balancer into the next single point of failure.
Queues, Async, and Microservices
Learn how message queues and pub/sub decouple services, why at-least-once delivery demands idempotent consumers, how backpressure and dead-letter queues protect the system, and when microservices are worth the complexity — with a sequenceDiagram of async order processing.
Caching Strategies
Understand where caches live, how cache-aside, read-through, write-through, and write-back differ, how to choose eviction policies, and how to prevent cache stampedes — with hit ratio math and a concrete cache-aside code snippet.
Replication and Partitioning
How do you scale a database beyond one machine while keeping it reliable? This lesson covers every major replication topology, the quorum math behind leaderless systems, and partitioning strategies from range keys to consistent hashing — including how to avoid hot partitions and handle rebalancing.
Failure and Time in Distributed Systems
Distributed systems break in ways single machines don't: nodes crash silently, messages vanish, and clocks lie. Learn the standard failure taxonomy, why a global clock is physically impossible, and how Lamport and vector clocks let you reason about causality without one.
Consensus: Raft and Paxos
Consensus is the hardest fundamental problem in distributed systems — and the one everything else depends on. Understand why FLP makes it theoretically impossible in async systems, how quorums work, and exactly how Raft solves leader election, log replication, and commitment safely.
CAP and Consistency Models
CAP is the most misquoted theorem in distributed systems. Get the precise statement, learn why PACELC is more useful in practice, and master the consistency spectrum from linearizability down to eventual consistency — with concrete trade-offs for each level.
Transactions, Isolation, and MVCC
Transactions are a promise. Learn the ACID guarantees, the exact anomalies each SQL isolation level prevents or allows, why two-phase locking blocks and MVCC does not, and how Postgres uses row versions plus a transaction ID visibility check to give you snapshot isolation without holding a single read lock.
Storage Engines and Page Layout
Disk geometry dictates database design. Learn why sequential I/O beats random I/O by 100x, how fixed-size pages and slotted page headers work, why row-stores and column-stores suit different workloads, how the buffer pool keeps hot pages in RAM, and how the write-ahead log makes durability cheap.
LSM-Trees and Write-Optimized Storage
B-trees rule read-heavy OLTP; LSM-trees rule write-heavy workloads. Learn how the memtable and immutable SSTable pipeline converts random writes into sequential I/O, why compaction is unavoidable, how bloom filters slash unnecessary reads, and when to pick LSM over B-tree.
B-Tree Indexes
B+ trees are the workhorse of relational databases. Learn why their high fanout and shallow depth match disk perfectly, how point lookups and range scans work, the difference between clustered and secondary indexes, how covering indexes eliminate table lookups, and the hidden write cost of keeping indexes up to date.
Symmetric Ciphers and Modes of Operation
AES and block ciphers are primitive building blocks, not complete encryption schemes. Learn how ECB leaks structure, why CBC and CTR modes work differently, and why GCM is the modern default — including the catastrophic consequences of nonce reuse.
Public-Key Cryptography: RSA and ECC
Trapdoor functions power every TLS handshake, code signature, and SSH session. Master RSA key generation and its math, why textbook RSA is trivially broken, what elliptic curves add, and how ECDSA and Ed25519 compare — with key-size equivalences you can quote in code reviews.
Key Exchange and TLS 1.3
Every HTTPS connection negotiates a fresh secret over an untrusted network. Learn Diffie-Hellman and ECDH from first principles, why forward secrecy matters when private keys leak, how TLS 1.3 cut the handshake to one round-trip, and how certificate chains stop man-in-the-middle attacks.
Hash Functions, MACs, and Password Hashing
Hash functions are not all equal and MACs are not just hashes with a secret. Learn the three resistance properties, why length-extension attacks break naive HMAC constructions, how KDFs differ from hashes, and why bcrypt/scrypt/Argon2 exist for passwords.
Threads and Shared State
Threads look deceptively simple — create a few, share some memory, done. In practice, shared mutable state is a minefield: race conditions, non-deterministic output, and bugs that vanish under a debugger. This lesson dissects concurrency vs parallelism, why `count++` is three operations the CPU can interleave, Amdahl's law, and what a critical section actually means.
Memory Models, Atomics, and Lock-Free
The CPU and compiler silently reorder your code. Cache coherence does not mean coherent behavior. This lesson explains the happens-before relation, memory fences, C++ and Java atomic operations, compare-and-swap, and why `volatile` is not a synchronization primitive.
Locks and Synchronization
Mutexes, condition variables, semaphores, and reader-writer locks — the primitives that make concurrent code correct. Understand the four Coffman deadlock conditions, how lock ordering prevents them, and why contention turns a performance win into a bottleneck.
Async, Event Loops, and Futures
Threads are not the only model for concurrency. Learn how blocking vs non-blocking I/O works, how the event loop and reactor pattern scale to millions of connections, and how callbacks evolved into futures, promises, and async/await — plus where coroutines fit and when async loses to threads.
Semantic Analysis and Type Checking
The parser only checks syntax — it happily accepts `x = y + z` even if none of those names exist. Semantic analysis adds meaning: it builds symbol tables, resolves names, enforces scoping rules, and runs the type checker that catches the errors a grammar cannot. Learn what happens between the raw AST and the typed AST the IR generator gets.
Parsing: Tokens to ASTs
The parser takes a flat token stream and recovers the hierarchical structure the programmer intended. Learn context-free grammars, recursive-descent parsing, operator precedence, the difference between a parse tree and an AST, and when LL versus LR parsers matter — including the classic dangling-else ambiguity.
Lexical Analysis: Source to Tokens
Before a compiler can understand your code it has to chop it into meaningful pieces. Learn how scanners work, how regular expressions become finite automata, why maximal munch is the rule, and what a real token stream looks like — the foundation every later compiler phase depends on.
IR, Optimization, and Code Generation
The typed AST is high-level — too high for a CPU. Learn why compilers lower to an intermediate representation first, what SSA form buys you, how classic optimizations (constant folding, dead-code elimination, CSE) transform IR, and how instruction selection and register allocation finally produce machine code.
GitHub Copilot: Niche Power Features You Probably Aren't Using
You already let Copilot autocomplete your code. This lesson dives into the underused power features: chat participants, slash commands, Copilot Edits, agent mode, custom instructions, prompt files, the model picker, MCP servers, and Copilot Spaces.

