Below is quite a personal story about my particular past and experiences. I have decided to share this publicly, hoping that this might help others in some way.
How I got started
It’s not a secret that I don’t have formal education in Computer Science, that I don’t have any formal education after high-school at all. I thought this was the way to go and University was just teaching old stuff you don’t need (and how wrong I was, we’ll come back to that in a bit). It was at this time I was involved into some cringy programmer stuff, like passionately discussing about tabs vs spaces (and dismissing Go because it enforces tabs) or arguing Java should never be used for greenfield projects. You can say this was my ‘peak of mount stupid'.
Learning through freelancing and figuring things out along the way had been my way to learn until around early 2017. I realized that my ‘learn as you go, when you need it’-approach had reached it’s limits and there were many things I did not know that I really should know, it like learning a new (human spoken) language by just learning the new words and not the grammar. After realizing this, I started reading a lot of books on different programming languages, styles, frameworks, software architecture, site reliability engineering and soft skills. This has brought me a long way.
Hitting a roadblock
Around the beginning of 2020, I felt like I was hitting the limit of this approach, like I knew a lot, but I could not comprehend how everything fit together. Like I’ve learned to play many instruments from sheet music, but never learned the underlying principles, the music theory. I could use a lot of tools, but I could not make them myself. I realized there was a lot to learn, not to learn what to do, I knew that already, but why it is done this way. I started digging into topics not directly related to what I had always been focussing on (web and mobile development), I read about compiler engineering, assembly languages, virtual machines and operating systems. I learned a ton (I’d say this is the point where I turned from a software developer into a true software engineer). But still, there were pieces missing in the puzzle. To continue with the music metaphor, I understood how symphonies were written, but I could not write them myself from start to finish.
In May of 2020, during the COVID-19 pandemic, I finally had the time for self-reflection. I came to the realization that I was utterly and completely wrong about Universities teaching you only old stuff you don’t need. I realized that you need the old stuff, like calculus and algebra, to understand (and build!) the new stuff, like artificial intelligence and embedded systems systems (yes, the systems used to build embedded systems). This is something many people pointed out to me, but I was too stubborn to accept earlier. I could write a simple domain-specific language parser, but I could not prove it to be working through mathematics. I knew what my code would do with system calls, but I didn’t know how the CPU actually performed the task at the metal-level. I knew how to establish and use TCP connections, but I could not explain how the payloads are verified. I missed the theoretical side of computer science.
Enrolling in formal education?
During June of 2020, I seriously considered going through a three year Bachelor’s degree program, but I unfortunately could not find a University that would be a great fit, considering I still have to work full-time at Bytecode and it was already June. The Open University curriculum did not offer enough of a challenge for me and the TU Delft (less than 5 minutes from both my home and Bytecode’s office) requires full-time (and I had to apply before January).
Another issue was that there would be quite a lot of overlap between the some courses’ content and what I already know (especially in the first and second year), not gaining (a lot of) new knowledge while taking quite some time to complete. The thing is, my focus wasn’t on getting a degree, it was purely about the knowledge gained in the process. For me, the best solution would be to follow a few Bachelor’s courses to fill some knowledge gaps and then follow a Master’s track (not getting a degree, just following the lectures and excercises) to gain in-depth knowledge, but this would be very unlikely to happen, as Universities don’t tend to be so flexible.
Subjects for study
Another issue I faced during this time was that in The Netherlands, there is only a very small part for study in other fields. In the US, there is a concept called a Major, in The Netherlands, the Major will be your only focus, with a 6-month period for a Minor where you can choose what to do. During my self-reflection I noticed I was laser-focussed on software engineering for many years, neglecting other parts of study that would help me develop into a better human being and in turn helping me grow in my day-job too. I wrote down what areas interest me, what I’d like to learn more about and categorized them:
- Computer science
- Fundamentals (maths and physics that allow computers to work on the metal-level, algorithms and data structures)
- Theories (theory of computation, automata, complexity theory, computability)
- Networking (how computers communicate on the lowest level, the ones and zeroes)
- Computer graphics (how it’s possible to display graphics onto a screen, AR/VR)
- Compilers (the mathematical and scientific side of compilers)
- Databases (not how to use them, but how to build them, how data is stored and retrieved)
- Robotics (how embedded systems allow hardware to move, the electrical engineering behind it)
- Computational Science (computer science, applied to solve large problems)
- Cyber security fundamentals (not just how to use metasploit, but true cybersec fundamentals)
- Fundamentals of linguistics
- Koine Greek
- Modern philosophy
- Ancient Roman
- Ancient Greek
- Communist revolution
- American history
- Economic and political theories
- Music theory
- Classical music
- Speaking and presenting
- Debating and negotiation
- Cooking different cuisines
Note: wanting to learn about a subject is not the same as believing in it. For example, wanting to learn about socialism does not mean I’m a socialist.
As you can see, this is a pretty long list, and it does not even include the detailed subjects, like ‘P vs NP’ in theory of computation. But this is absolutely not meant as a ‘in the coming year I will learn to’-list, far from it. It is my long-term roadmap for learning. I don’t believe I can become a true master at any of them, but for the subjects I can come close to mastering the subject, there can only be a select few. When I decide to learn about a topic, even when I initially finished learning about it, I will probably come back to it later, either to improve my skills even further (for example sports), or to revise my knowledge to get a quick refresher, so I can combine it with other things I’ve learned. When first picking up a subject, my primary goal is understanding what is needed for near-mastery of the subject. To see my own true competence and not to be over-confident (see: Dunning-Kruger effect).
By the way, notice how there this list is pretty timeless, there is no ‘Elm for front-end web development’ or ‘Haskell for REST API development’ on the list. Most subjects would be on this list 10 years ago, and many - if not all - of them will be in 10 years. Learning Elm or Haskell are on my wishlist too, but I see that as separate from learning the fundamentals, the fundamentals I need to actually make the right choices when building with Elm or Haskell. And that’s the power of University programs I was too stubborn to see, anyway, back to the topic.
Attempting to become a self-taught computer scientist
As of writing this, we are halfway through July 2020, with 5 of my Bytecode team members graduating their Bachelor’s degree (and 3 of them continuing to get their Master’s too), just starting their summer vacation (for school, many of them spending a lot of time at Bytecode). But for me there will probably not be a lot of vacationing going on. I have decided not to enroll in any University program. I have decided to attempt to become a true computer scientist on my own (well, with the help of books and the internet of course, but I mean without a University). I will try this for around one year to see if it works (and if it does, continue it afterwards). Of course I hope to succeed, but if I don’t, I will probably follow some form of formal education that will allow me to fill in some gaps and then allowing me to follow a Master’s program.
How I will get started
For my learning journey, I have decided to spend around 60% (12 h/week) of my time on computer science, and 40% (8 h/wk) on a small selection of other subjects. For the computer science part of the journey, the website Teach Yourself CS has helped me a great deal for how to get started and giving me a roadmap and a list of resources to use. For the computer science part, I will start with:
- Computer science fundamentals
- Learning about how maths and physics allow computers to work the way they do, computer architecture and basic automata;
- Dipping my toes into some theories to get to know them (and go in-depth later on);
- While learning some discrete maths, physics and electrical engineering along the way
- The basics of calculus and linear algebra
- Algorithms and data structures
To do this, I will use the following (in roughly this order):
- As the resources I will use will be in English, but I only know maths in Dutch, I will use Brilliant.org and maybe some Khan Academy so I can understand the English math jargon and such, this is just to understand maths in English, not to gain new knowledge
- When my math skills in English are around the same level as in Dutch, I will use the resources mentioned above to gain some additional knowledge, after that, I will continue by reading Concrete Mathematics by Donald Knuth and see if the lectures mentioned on teachyourselfcs.com are helpful
- For learning from the bottom (from the logic gates level) up how computers work, I will use nand2tetris, although I doubt whether this will be in-depth enough.
- If I want to continue after nand2tetris, I will use the book Computer Systems: A Programmer’s Perspective by Randal Bryant and David O’Hallaron
- My first goal will be to learn what’s required to understand the maths in The Art of Computer Programming (TAOCP) part 1 by Donald Knuth and then work through this book cover to cover (later I will continue with part 2 to 4A). The reason I chose to go with Concrete Mathematics by Donald Knuth is because he wrote this book to understand the maths in TAOCP
- For understanding the basics of the Theory of Computation, I will use the book “Introduction to the Theory of Computation” by Michael Sipser
- For algorithms and data structures, I will follow what teachyourselfcs.com recommends, maybe combined with reading the book Introduction to Algorithms
For the 40% left, I have decided to focus on the following subjects with the corresponding methods:
- The Latin language (using Lingua Latina Per Se Illustrata, Pars 1 and a guide on how to use it I want to get the basics and then see if I want to continue with Latin or another language)
- Golf (taking lessons together with Thomas, one of my closest friends, when we have our handicaps, practice often on ourselves and then see how to progress further)
- Meditation (I’ve got a 1 month Headspace subscription to see whether meditation is something I want to spend time on or not)
- Chess (I will follow a short only video course on Masterclass.com by Garry Kasparov to learn basic strategies, and then practice online, to get to a rating around 1000, then I’ll see how to progress further)
As a final note, I’d like to express that - even though I realize my changed opinion about the value of formal education - I do not regret not following the University path. I do believe it is a lot easier, to have people way with way more knowledge about certain subjects than you ever will, telling you what the best path it to gain some of this knowledge. But I also realize that this approach - whilst easier - is also very rigid, and would probably not allow for me staying at Bytecode or learning about other subjects too. Even if I’d be given the possibility to enroll at TU Delft in September, I think I’d still choose to go down the self-learning path, or at least try it out first for a year.
I will update this page and add a log of what I have used for learning, so that others encountering the same issues as I can reference this list and take inspiration from it for their own learning path.
Progress and timeline
As time progresses, I will add a sort of timeline of my learnings, mostly for myself as reference later, but also so I can advice others on how to progress.
Update September 4th, 2020
My plan was to focus at least 60% on learning computer science. Well, I failed that part. It’s been around 10-20%. Although I have learned quite a bit about mathematics in particular, computer science has not been my focus in the last few months.
Instead, I have spent most of my learning hours on philosophy, with some Latin during the weekends. I really, really enjoy learning about philosophy (stoicism in particular - crazy how ancient life is so similar to the present in many ways, and how wise some guys were 2000 years ago, anyway, I digress), as it changes your modus operandi, the way you look at the world. It has been beneficial for me on multiple occasions.
Latin has been way more fun than I imagined. Using comprehensible input with Lingua Latina has been awesome. Learning Latin this way even makes working with grammatical cases intuitive, compared to my struggle learning the German case system in high school, having to learn lists of conjugations with limited context.
I do plan to increase the computer science/mathematics part a bit - maybe to 30-40% of the total - but not to the 60% level I initially planned. One last golf-related thing: yesterday, Thomas and I got our course permission! We will practice over the winter and we are planning to get our handicap 54s in the spring of next year.