FREE COURSE / REAL PRACTICE
Systems & production C++
Investigate native memory, synchronization, measurement and production interfaces through C++ systems exercises.
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
#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.
Pipelines and memory
- 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 - 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
Concurrency
- 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 - 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 - 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 - 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
Performance
- 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 - 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 - 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
Production C++: build, test, debug, ship
- 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 - 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 - 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 - 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
Qt and Linux application integration
- 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 - 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 - 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 - 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
Unix/Linux: files, descriptors & filesystem
- 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 - 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 - 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
Unix/Linux: processes, memory & signals
- 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 - 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 - 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
Unix/Linux: event-driven networking & IPC
- 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 - 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 - 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