Introduction

This book is just a dump of links I keep collecting as I progress as a software programmer. I use it to have a personal log of good stuff I discover while wandering about in the web.

While perusing the vast array of articles, books, videos, etc. linked, one must keep in mind that the focus of learning to code1 should always be on learning abstract concepts and their low-level implementation details, which underlie the tech stack used in modern software, rather than specific and ephemeral tools (e.g. libraries, frameworks, etc.):

Modern programming is becoming complex, uninteresting, full of layers that just need to be glued. It is losing most of its beauty. In that sense, most programming is no longer art nor high engineering (most programs written at big and small corporations are trivial: coders just need to understand certain ad-hoc abstractions, and write some logic and glue code). Only very few programmers are facing the artistic face of programming. Only very few programmers are facing high engineering in programming.

Salvatore Sanfilippo2

In fact, an application software usually consists of levels (or layers) of abstraction, wherein each level represents a different model of the same information and processes, but with varying amounts of detail. Each relatively abstract, higher level builds on a relatively concrete, lower level, which tends to provide an increasingly granular representation.

Abstractions are useful, but all non-trivial abstractions, to some degree, are leaky3. So, blindly ignoring what happens at lower levels can cause performance issues or (worst) unintended bugs which are hard to debug (e.g. inscrutable incidents in production4). Solving such issues thanks to Q&A websites like Stack Overflow does not help learning what actually went wrong leaving a certain sense of frustration (a common feeling for Linux users5).

Unfortunately, the enterprise software world is largely dominated by the use of frameworks (e.g. Spring vs Quarkus on the backend, Angular vs React on the frontend), an abstraction which is useful to avoid code bloat but limits the creative job of a programmer, making him just an expert user of a particular framework. These frameworks are also susceptible to be replaced by other competing frameworks, generically perceived as "innovative" for some reason. The only way to avoid to be forced to learn a framework every N years is to understand what happens behind the abstractions, which means to develop a good intuition of what happens at the hardware/software interface (getting closer to the metal, as the kool kids say). This is why so frequently people attempt to re-implement from scratch a good piece of software to understand "how things work"6.

Undoubtedly, this crafting or artistic view7 of the act of programming implies a longer (lifelong8?) and steeper learning curve than any fancy YouTube tutorial would commit to, but this is still better than getting stuck in a plateau after a brief exponential growth where developers end up acting merely as code monkeys or blue collars. Sometimes the working environment of IT companies with big moneys itself tricks you into:

voluntarily ceasing to improve because of a belief that expert status has been reached and thus further improvement is not possible.. This opting into indefinite mediocrity is the entry into an oblique phase in skills acquisition that I will call "Expert Beginner"[^10].

In this respect, the following chapters naturally derail from application programming to system programming, and finally to hardware stuff. The last chapters mostly deal with collateral and/or enjoyable aspects of programming.


4

Fabien Sanglard, A Linux evening...

6

Peter Norvig, pytudes