What are the best resources for learning things like memory management, understanding the ideas and tradeoffs of machine code, and digging deep into the specific languages of the month?
I can second @MatthijsBlom 's recommendation of the Rust learning resources. I’d like to add Jon Gjengset’s YouTube channel to the list. He makes fantastic long-form videos diving deep into the most difficult (and fascinating) aspects of Rust. The playlist is called Crust of Rust.
If you really want to go into the nitty-gritty details of the very basics, I happily advise building a computer to play Tetris from scratch. Logical-gate-level scratch.
I think it is widely known, but if you have not tried it yet: nand2tetris.
It really helped me to understand how things work. It might seem too technical and a better fit for the assembler months, but there is so much to learn here for system languages - it’s mesmerizing.
It’s an old book, but the concepts it teaches are still relevant. Talks about stacks, memory, compiling, linking, processor architecture, number representation, threads, garbage collection, etc…What I liked most about the book it’s that it goes into low-level detail on topics, but never leaving the realm of software. In that sense, the book’s title is incredibly accurate - it teaches you all about computer systems…from a programmer’s perspective. The examples and exercises are in C, with assembly for a good measure. But since most of the code in C you can translate to more modern languages easily, I think it’s still easy to follow.
Learning Go
Tour of Go
The place I recommend everyone to start. A quick guided introduction to Go. The information is introduced bit by bit, with examples. Runs on the browser so you don’t have to install anything, and you can get a feel for the language and if it’s something you want to invest more time on.
Gophercises
Focus on building some mini-projects with Go, each highlighting different language features.
Search “Rob Pike” on Youtube and look for his talks
Rob Pike is one of the creators of Go and has given some talks over the years about the design of Go and some decisions. This won’t teach you about Go itself, it’s more background info about why Go exists, what makes it great and how to think like a gopher. Some of the most popular ones include:
I haven’t read them, but I think the Write Great Code series might provide a relatively easy introduction to a good foundation for systems programming, particularly Book 1 and maybe Book 2.
I found Rustlings particularly useful for learning the basic ins-and-outs of things like String vs &str, handling Option and Results, and the other low-level things you need in order to tackle something like the Rust Exercism track without constantly getting bogged down with trivia.
For applications programmers that want to dip into systems for the first time, my general suggestion is to follow the track of our forefathers and invest time into C, UNIX, and other UNIX-y tools like bash. C is a tiny language that is essentially at the same level of abstraction as assembly code. C and UNIX grew up together and are inseparable. Additionally, C is a tiny language that can be learned quickly. The UNIX philosophy is based around the idea of tiny pieces of functionality that you wrap with a high-level language like bash. Once you learn the UNIX heritage, investigate FFI with your daily-driver languages.
Yes, you will shoot your foot off, segfault, buffer overflow, etc. In my opinion, in a learning context, this is a feature, not a bug. Companies are not going to go out of business if your exercism solution has a buffer overflow, and writing problematic code in an unsafe systems programming language will allow you to have more intelligent discussions with mentors. Instruction Set Architectures presented by processors are low-level and have these faults, and C inherits them. In contrast, a safe systems programming language, like Rust, models a higher-level abstract machine, and your mentorship discussions will be around “appeasing the borrow checker.” If you haven’t already worked in C, you will not really understand why you have to annotate lifetimes in types, and you still won’t feel comfortable calling native syscalls (because they are in C and unsafe). If you want to be a professional systems programmer, it is probably worth looking at C++ or Rust, but I would defer that until you have a strong intermediate grasp of C, UNIX, and are able to write utilities like cat, cd, wc, mkdir, etc. by hand and then use them in bash scripts.
C Stuff
The C Programming Language
The Standard C Library
The Practice of Programming
C++ Stuff:
A Tour of C++
C++ Crash Course
The Design and Evolution of C++
Scott Myers’ Books (Effective C++, Effective STL, Effective Modern C++)