Being self-taught
The term is misleading; people are self-taught insofar as they learn the most after their formal training. That said, formal training gives structured practice and an environment that makes for a better baseline; more comprehensive tools with which to continue learning. In some cases this baseline is an absolute requirement and there is no alternative path. You can be a self-taught photographer, but not a self-taught neurosurgeon. In any case, it is better to get a formal education than not to get one.
Teaching yourself is difficult, lacking the guidance and concrete feedback of institutional structure and rules. The lack of standardized resources and encouraging surroundings take away important formative benefits. At the very least, it takes time to find the necessary information and determine that it is not garbage, a process that is not helped by the ignorance of the matter in the first place. It is a chicken and egg problem to know enough about a subject to tell the chaff from the grain when it comes to the resources to learn about that very subject.
It also takes focus and discipline different from those required by formal learning. It is less clear what the payoff will be after working through a book, and there are no negative consequences if it does not happen. There are no exams, no deadlines, no external validation or peers to compare to.
People who do or make unusually great things are inspiring and good guidance. Uber-engineer Jeff Bonwick invented ZFS and the slab allocator. The slab allocator paper is an instructive and accessible read. Valerie Aurora fixed a bug in the lasers that calibrated nuclear explosion detection satellites. Her Kernel Hacker’s Bookshelf series is a curated pool of resources; when a smart person thinks something is good, it is advisable to heed their words. Jart’s low level explorations and genuine hacker ethos have given us the Cosmopolitan C library, a mix between discovery and creation that seems unlikely when first seen.
The people smart people consider smart are likely to be good role models. Role models who write, or speak, or otherwise are generous with their thoughts are valuable for their intellectual lineage as much as for their own knowledge.
Resources
Books, papers, lecture recordings, conference talks, and articles, are all fair game for learning. This is obvious to everyone who does not need to hear it, but permission is not required to learn about any subject. There is no gatekeeping of areas of expertise and subjects of knowledge.
However, it is easy to look towards the adjacent and more easily solved problem of collection. As with gear in any hobby that supports variety of tools, the potential for engagement feels good and is a quicker reward than actual engagement. It is simple to imagine how good it would be to know how to play the piano, but the path from here to there is made of hundreds of thousands of repetitions of grueling exercises. The unavoidable reality of learning is that it demands struggle; there is no such thing as picking up group theory by keeping an open book in your peripheral vision.
For computer science and software engineering concretely, there is a natural categorization of books as principles and practice. The former teach about theory, the possible known ways of approaching a problem in the abstract, while the latter meld that theory with the trade-offs forced upon it by the real world. Both are valuable and play off of each other. A bias for the concrete serves pragmatic objectives; conversely, a bias for the theoretical serves knowledge for its own sake.
The Teach Yourself Computer Science list is biased towards practicality. Skiena’s book truly is a manual, and he explicitly maintains a strict no-theorem/proof policy for it. Crafting Interpreters is a guided walk through the building of a programming language, with concepts explained when necessary and only to the required depth. Kleppmann’s book, while a bit more academic in its bibliography, is concerned throughout with real systems the author has studied. These are by no means the only available books, and there is no law when it comes to choosing the material. Mixing and matching books and lectures, building a personalized program, choosing exercises and projects are all legitimate options.
OSTEP, Skiena, SICP, CS:APP and Kleppmann are instructive resources that remain usable after reading. The same cannot be said of Crafting Interpreters. Providing every snippet of code is a detrimental methodology that favors a feeling of learning more than learning.
Advanced Programming in the UNIX environment is thick and solemn, but precise and useful for someone programming against UNIX-y interfaces. Jan Schaumann’s APUE course lectures, notes and projects are an excellent way to work through it.
Old books should not be readily discarded. In the Kernel Hacker’s Bookshelf, Valerie Aurora disguises a review of UNIX Internals, a book from 1996 that describes aspects of long gone UNIX variants with barely a passing mention of Linux, and goes on to demonstrate why it is still one of the best Operating System books available.
Dan Luu said he has gotten more mileage out of Probability and Computing than any other algorithms book. It is not the canonical algorithms textbook, as its title conveys, but probabilistic algorithms are a stepping stone to a different level of engineering and computer science applications. Beyond binary trees and linked lists and hash maps, beyond sorting and searching and basic graph algorithms, lies a vast world of knowledge mostly actionable by those who have paid the learning of the canonical program. A cursory reading through the material of Stanford’s CS168, The Modern Algorithmic Toolbox, will make it apparent that probability, linear algebra, combinatorics has to be brought to bear on these applications.
Most software engineering must touch on matters of concurrency; a single-threaded, purely sequential model of execution is too limiting for anything but Advent of Code solutions or the simplest applications. Resources in this area go from the more theoretical, like The Art of Multiprocessor Programming which still uses Java and some C++, to concrete language approaches, like C++ Concurrency in Action, and Rust Atomics and Locks, both of which curiously coincide at times when the writing is perfectly precise at the cost of being impenetrably abstruse. The Little Book of Semaphores is a free, short, fun introduction to the problems of synchronization and solving its scenarios makes for great practice with concurrent execution.
Fundamentals
Anyone will only ever read a finite number of books, so it pays to be ruthlessly selective. This demands an understanding of personal goals and aspirations, momentary needs, and where they intersect. It may be useful to read a book on vibe coding in 2026, but it will always be useful to learn the rudiments of computability and complexity, or operating systems, or the lingua franca underlying most technology. Again, there are no rules, but there are more or less favorable choices. Choosing to spend time using the Vala programming language may come at a high opportunity cost.
A less conspicuous part of fundamentals is the history of the field. It is not only instructive because old problems have a way of coming back new and improved, but also because for a self-taught learner they provide a folklore of how things used to work, a sense of the rate of change and the astonishing progress in a young area of study. It imbues work with a feeling of community and it nurtures the genuine hacker ethos Jart shows in her playful, deeply technical projects.
Where The Wizards Stay Up Late is a story of the development of the ARPANET that gives names to hackers barely known relative to the impact of the work they did. Ingenuity and pragmatism are a unifying theme; Licklider’s foresight of computers as devices that would expand the intellectual capacity of humans, as well as serve as a means of communication, shows how far back people imagined the technology we have today.
The Cuckoo’s Egg is a fascinating story of computing in the 80s, an odyssey triggered by a seemingly innocuous accounting error that would have the author juggle a tangle of logging terminals, law enforcement agencies, the responsibilities of his job and his personal life. It reads like a techno thriller.
Sometimes you get the elevator and sometimes you get the shaft.
Dennis Ritchie’s paper The Development of the C Programming Language paints a picture of the late 60s, how Ken Thompson came to put together the initial pieces of UNIX out of what he had seen in the Multics project, and how BCPL evolved into B which then evolved into C. It shows what an astonishing achievement this was back then; it is normal to condemn C today as the root of all that is wrong with software development, but the context of its time shows it in a more favorable light and explains at least some of its shortcomings. Respect for what came before befits a craftsman. Worse is Better is Worse is a refutation of a false dichotomy between a right thing and a wrong thing.
Syntax, folks, is religion, and Lisp is the wrong one. Lisp is used by weirdos who do weirdo science.
Practice
The ideal learning projects are reasonably feasible within a time frame of a few weeks to a few months, with close to daily engagement. One Saturday morning a month will not work wonders as a workout, and it will not work for learning either. Moreover, there is a toll to pay to gain momentum and load context into the mind for learning to be as effective as possible. This has some consequences. One is that if too much time passes without engaging with the object of study, there is a risk that all the partial work will fizzle out. Coming back to it will mean starting from scratch, or at least having to pay extra time in reviewing and reloading all that context to get back up to speed.
A second consequence is a limit to the number of concurrent threads of learning that can be scheduled. The cost of context switching will eventually dominate over the time spent doing productive work, so it is important to restrain curiosity, especially when the going gets hard and it becomes easier to switch to the beginning of a new subject than to go deeper in the current one. The larger a subject, the harder it is to maintain the concentration on it for the time needed to make it through, and the more likely it is that interruptions will cause the momentum to be lost. On the other hand, trivially easy efforts will only add up to so much, and at some point one must undertake a real piece of work to get something substantial.
What matters is delaying gratification. Because even your favorite thing in the world will have shitty bits if you chew on a big enough chunk of it. A few months or years worth of work are always a big enough chunk, so there will be shitty bits. Unfortunately, it’s also the minimum-sized chunk to do anything of significance.
Habit is a strong compounding force. Where motivation dwindles, habit has a way of regularly acting by, well, force of habit. Introspection into habits that are conducive to the completion of projects is worth the effort, since such a big part of seeing things through is to show up in the first place.
Completion is important, both for the accumulation of knowledge and experience that build on themselves, and for a psychological sense of closure and achievement. It is hard to be as proud for a plethora of half baked projects as for a single completed one. But it is possible though to go too far in this direction. Some projects will be beyond what is reasonable; more likely than not, you will not do every exercise in The Art of Computer Programming. It is fine to let go of endeavors that turn out to be larger than they seemed, or that have stopped yielding what was of interest in them, or that have been explored to a satisfying degree.
In conclusion, life is messy and I don’t have any advice.
Links
- The Slab Allocator: An Object-Caching Kernel Memory Allocator
- Bug in calibrating the giant laser that shoots at satellites
- Cosmopolitan Libc
- Teach Yourself Computer Science
- CS631 Advanced Programming in the UNIX Environment
- The Kernel Hacker’s Bookshelf: UNIX Internals
- Programming book recommendations and anti-recommendations
- CS168 The Modern Algorithmic Toolbox
- The Little Book of Semaphores
- The Development of the C Language
- Worse is Better is Worse
- Fun won’t get it done