CodeRigor

FREE COURSE / REAL PRACTICE

Systems & production C++

Investigate native memory, synchronization, measurement and production interfaces through C++ systems exercises.

Free lessons & exercises26 authored lessons8 units

What you’ll work toward

Use tests, diagnostics and measurements to investigate failures and support engineering decisions.

Read an explanation, inspect the diagrams and work through the available checks, debugging exercises and builds. Feedback and prerequisite links guide the next step.

Before you start

This course builds on these skills:

Individual lessons can add prerequisites. The course map shows your actual readiness.

A look inside the first lesson

Allocators and std::pmr

C++
#include <cstddef>
#include <cstdlib>
#include <new>
#include <print>
#include <vector>

template <class T>
struct Mallocator {
    using value_type = T;

    Mallocator() = default;
    template <class U>
    Mallocator(const Mallocator<U>&) noexcept {}  // "rebind" conversion

    T* allocate(std::size_t n) {
        if (void* p = std::malloc(n * sizeof(T))) return static_cast<T*>(p);
        throw std::bad_alloc{};
    }
    void deallocate(T* p, std::size_t) noexcept { std::free(p); }

    // Stateless: any two Mallocators can free each other's memory.
    friend bool operator==(const Mallocator&, const Mallocator&) = default;
};

int main() {
    std::vector<int, Mallocator<int>> v{1, 2, 3};
    v.push_back(4);
    std::println("{}", v);
}

Your course outline

Follow the lessons in curriculum order. Open a unit to preview the ideas you’ll work with.

UNIT 012 lessons Pipelines and memory
  1. LESSON 01.01

    Allocators and std::pmr

    Control where containers get their memory: the allocator model, propagation traits, polymorphic memory resources, arenas, and the lifetime rules that keep them safe.

    Open lesson
  2. LESSON 01.02

    Memory layout, alignment and caches

    Know what your objects look like in memory: padding and member order, alignment, empty members, object representation without UB, and laying data out for the cache.

    Open lesson
UNIT 024 lessons Concurrency
  1. LESSON 02.01

    Threads, jthread and cooperative cancellation

    Start, stop and join threads safely: jthread and stop tokens for cancellation, mutexes and condition variables without races or deadlocks, futures for results.

    Open lesson
  2. LESSON 02.02

    Atomics and the C++ memory model

    Share data between threads without locks: atomic operations, compare-exchange loops, and the memory orders (relaxed, acquire/release, seq_cst) that decide what other threads are guaranteed to see.

    Open lesson
  3. LESSON 02.03

    std::execution: senders and receivers

    Understand C++26's async model — lazy senders, receivers with three completion channels, operation states — by building a small standards-shaped implementation of just, then, when_all and sync_wait.

    Open lesson
  4. LESSON 02.04

    Safe memory reclamation: hazard pointers and RCU

    Free nodes of a lock-free structure safely and promptly: hazard pointers that protect what a thread is reading, and epoch-based RCU that frees an old version only after every reader that could see it has moved on.

    Open lesson
UNIT 033 lessons Performance
  1. LESSON 03.01

    Profiling and benchmarking

    Measure before optimising: honest timing loops, the right statistic, keeping the optimiser from deleting your benchmark, and reading perf counters.

    Open lesson
  2. LESSON 03.02

    SIMD and auto-vectorisation

    Make one instruction do four (or sixteen) lanes of work: what compilers vectorise on their own and why they refuse, then explicit portable SIMD with exact tails, masks and reductions.

    Open lesson
  3. LESSON 03.03

    Data-oriented design

    Design around the data and how it's accessed: hot/cold splits, struct-of-arrays, dense storage with generational handles instead of pointers, batching by type, and branch-friendly data.

    Open lesson
UNIT 044 lessons Production C++: build, test, debug, ship
  1. LESSON 04.01

    Building real C++ projects: translation units, linking and CMake targets

    How a multi-file C++ project becomes binaries: headers and the ODR, reading linker errors, static vs shared libraries, and target-based CMake — usage requirements, presets, packages and compile_commands.json.

    Open lesson
  2. LESSON 04.02

    Testing a C++ project: CTest, fixtures and golden images

    Test a real C++ library the way production teams do: CTest labels and fixtures, doctest, deterministic fixtures from a specified PRNG, golden images with documented tolerances, regression tests from observed failures, test seams and malformed input.

    Open lesson
  3. LESSON 04.03

    Debugging failures: sanitizer reports, core dumps, minimal repros

    Read ASan, LSan, UBSan and TSan reports frame by frame, debug a core dump with gdb, tell a lifetime bug from a concurrency bug, shrink the failure to a minimal reproduction and pin it with a regression test — then build a parser that triages sanitizer reports automatically.

    Open lesson
  4. LESSON 04.04

    CI, reproducible builds and releases

    Ship C++ like a team does: a GCC/Clang × Debug/ASan/TSan/Release matrix as a local script and a hosted-CI config, warnings as errors in CI only, reproducible builds, semantic versions from git describe, install rules, RPATH and a CPack tarball, and a release checklist.

    Open lesson
UNIT 054 lessons Qt and Linux application integration
  1. LESSON 05.01

    Qt object lifetime: parents, deleteLater and QPointer

    Who deletes a QObject and when: parent/child trees, deleteLater and the event loop, QPointer and destroyed, connection lifetime with context objects, thread affinity, and Qt's implicitly shared containers.

    Open lesson
  2. LESSON 05.02

    Qt models, QML and model tests

    Write a QAbstractListModel that keeps every view in sync: the begin/end change protocol, the move-destination rule, precise dataChanged roles, invalid-index handling, QAbstractItemModelTester and QSignalSpy tests, and how the model reaches QML.

    Open lesson
  3. LESSON 05.03

    Background work in a Qt application

    Keep the UI thread responsive: QThread workers, QtConcurrent and std::jthread backends, queued delivery, cooperative cancellation, latest-wins request coalescing, generation counters and clean shutdown while work is in flight.

    Open lesson
  4. LESSON 05.04

    Linux I/O, IPC and process lifecycle

    The plumbing of a Linux service: RAII file descriptors, partial reads and writes, EINTR/EAGAIN, poll with deadlines, pipes and Unix sockets, message framing, backpressure and reconnects, signals for clean shutdown, child processes and systemd units.

    Open lesson
UNIT 063 lessons Unix/Linux: files, descriptors & filesystem
  1. LESSON 06.01

    Descriptors & open file descriptions

    Own Linux descriptors in C++: move-only RAII, atomic close-on-exec duplication, shared offsets and status flags, independent descriptor flags and errno-safe cleanup.

    Open lesson
  2. LESSON 06.02

    Syscalls, short I/O & positioned files

    Handle errno, EINTR, short reads/writes and EOF; use pread/pwrite without disturbing shared offsets, reject Linux append-mode traps, and test error paths deterministically.

    Open lesson
  3. LESSON 06.03

    Directories, inodes & relative path operations

    Separate names, inodes and open handles; walk directory descriptors with openat, reject symlinks, understand unlink/rename, permissions and the limits of userspace path policies.

    Open lesson
UNIT 073 lessons Unix/Linux: processes, memory & signals
  1. LESSON 07.01

    Processes: fork, exec, pipes & wait

    Launch a program without a shell, arrange inherited descriptors, distinguish exec failure from exit status, drain a pipe before waiting and reap every child.

    Open lesson
  2. LESSON 07.02

    Virtual memory & mapped file windows

    Map an unaligned file slice with page-aligned mmap, separate ownership from spans, transfer mappings safely, and understand MAP_PRIVATE, page faults and SIGBUS after truncation.

    Open lesson
  3. LESSON 07.03

    Signals & descriptor-based notifications

    Distinguish signal delivery from queued work; consume blocked signals with signalfd and aggregate wakeups with eventfd without allocating or logging in a signal handler.

    Open lesson
UNIT 083 lessons Unix/Linux: event-driven networking & IPC
  1. LESSON 08.01

    Nonblocking I/O & epoll readiness

    Build a level-triggered readiness layer with 64-bit tokens, bounded nonblocking drains, buffered-data-plus-hangup handling, and explicit EAGAIN versus EOF semantics.

    Open lesson
  2. LESSON 08.02

    TCP sockets, connection state & half-close

    Bind a loopback listener to an ephemeral port, complete a nonblocking connect with SO_ERROR, accept safely, and distinguish TCP byte streams, EOF and half-close.

    Open lesson
  3. LESSON 08.03

    Unix sockets & passing open descriptors

    Transfer a kernel open-file reference with SCM_RIGHTS, parse ancillary messages, set close-on-exec at receipt, and close every installed descriptor on malformed/truncated messages.

    Open lesson