What I learned in 2023 - Computer Science
Table of content
The pace of innovation and change in software is extraordinary. That is why, we have to constantly learn and deepen our knowledge. In this post, I reflect on the activities I did to improve skills as a software engineer. I acquired knowledge across various domains primarily through project work. I firmly believe that practical experience is the fastest way to learn.
- Compilers
I devote the first mention to the topic of compilers. It is a captivating journey into understanding how programming languages are created and function beneath the surface.
How it works?
A compiler is a (command-line) program that takes source code as input and produces machine code. Typically, it consists of two phases: syntax analysis and code generation. The former employs a tokenizer and a parser. The tokenizer scans the source code word by word, assigning meaning to each word, which could be keywords (class, let, return, function, etc.), variable names, symbols or constants. The parser then uses the output of the tokenizer to validate the correctness of the source code against the language’s grammar. Finally, code generator transforms the statements into a lower-level representation, such as machine code.
What you can learn:
- Understanding how parses operate and how syntax is validated for errors.
- Developing a mental map of how a high-level language is translated into a low-level language.
- Exploring how optimizations function during code generation.
- Exploring intermediate representations of languages (e.g. JVM bytecode) depending the language.
- Deepening knowledge across all aspects of a language (e.g. Jack).
I studied with the nand2tetris project, which delves into details of computer architecture, assemblers, virtual machines, compilers and basic operating systems concepts. I whole-heartedly recommend it. For those who wish to focus solely on compilers, I suggest picking up books from Thorsten Ball.
Links:
- https://github.com/thesems/nand2tetris/ (project 11 and 12 focus on compilers)
- https://www.nand2tetris.org/
- https://www.coursera.org/learn/build-a-computer
- https://interpreterbook.com/
- https://compilerbook.com/
- New languages (Rust and Go)
The key to learning new languages is to start using them in your daily life, just as you would with spoken languages. Similarly, with programming languages, engaging in projects that interest you is an effective method to learn.
In the initial part of the year, I immersed myself in the Go language for various side projects. I used it to complete the Advent of Code 2022 and subsequently to play with Go’s standard library and HTMX. During the latter part, I switched to Rust and completed the nand2tetris (hardware and software) courses and the Advent of Code 2023.
Learning multiple languages provides invaluable insights into the trade-offs each language makes and how to use them effectively. I would also caution against jumping from one language to another without attaining sufficient understanding. I decided to dedicate my focus on learing Rust for the time being. In my opinion, both are tremendously good languages.
Some points to think about (non-exhaustive):
- Type system: Dynamic or static typing?
- Memory system: Is memory allocations manually managed?
- Concurrency: Is there support for execution of concurrent/parallel tasks?
- Error handling: How are errors and exceptions handled?
- Ecosystem and libraries: How rich is the standard library? Is there a strong ecosystem?
- Ease of use and syntax: How long does it take you to learn it? Is it intuitive?
- Targets: Which platforms can it run on?
- Operating Systems
Studying operating systems is a vast and rewarding journey, but be careful not to overwhelm youself and to progress at a comfortable pace, gradually expanding your knowledge. I recommend writing your own mini operating system from scratch. Operating systems represent one of the remarkable pieces of software ever written. They have to be lean, fast and robust, otherwise all applications layered on top will feel sluggish. Throughout this learning journey you will encounter many topics of computer science and gain many valuable insights!
Topics in OS include:
- Booting process (BIOS, boot loaders, operating system)
- Interrupts (CPU exceptions, I/O components)
- Memory (covering segmentation and paging, heap allocation strategies)
- Scheduling (exploring preemtive and cooperative multitasking)
- Kernel/user-space inteface (understanding system calls)
- File system (storage, data retrieval, organization)
Resources I use:
- Operating Systems - William Stallings (book)
- https://os.phil-opp.com/ (writing an OS in Rust)
- https://littleosbook.github.io/ (practical insights into writing an OS in C)
- https://wiki.osdev.org/Main_Page (wiki about OS)
- Data structures and algorithms
I am not the type who can easily plow through pure, dry algorithmic problems. It gets boring too quickly. I prefer to apply them practically during a project. For example, when developing a heap allocator, I used a linked list. A virtual machine for the Hack computer required the use of a stack data structure. Video games require a variety of interesting algorithms for varous functionalities like path finding. However, I enjoy solving Advent of Code problems. These Cristmas-themed puzzle contain fun backstories and are hand-crafted each year. Each problem is designed to be solved by one or multiple methods. It’s a great way to practice dynamic programming concepts, shortest path algorithms, general programming skills, number theory (modulo, lcm, gcd) and much more.
Links:
- https://adventofcode.com
- Instruction to Algorithms, Thomas H. Cormen and others (book)
- https://github.com/thesems/advent-of-code-2022-go-lang
- https://github.com/thesems/advent-of-code-2023-rust
- Other projects I did/am doing:
Throughout the year, I found some time to delve into additional projects.
Terminal-based text editor
We spend a significant portion of our time within a text editor writing code. It seems only natural to spend some time investigating the inner workings of text editors. You will learn methods for storing and manipulating large amounts of text. It involved algorithms that can are capable of efficiently locating text (e.g. search and replace) and that can insert text at any point. You will also learn about termio, which describes the terminal interface API. Terminal programs can be powerful and it’s worth studying them.Links:
Neovim
This year, I transitioned to using Neovim as my primary text editor. I wanted a cleaner, custom-tailered coding experience for myself. Customizing Visual Studio Code wasn’t just enough. Additionally, Neovim is simply lighting-fast and I find that especially important. In my opinion, the vim motions are a game changer for any programmer. Even if I were to switch to another IDE one day (I’m looking at you Zed), I intend to keep my vim motions.Check out my config: https://github.com/thesems/.config/tree/main/nvim
Blockchain (bitcoin-clone)
The crypto-bug bit me long time ago, but I just didn’t start programming within this space yet. I began with creation of a simplified bitcoin clone. Blockchains are fascinating amalgamation of various software technologies. Developing this project provided insights into game theory, cryptography, virtual machines, p2p networking, storage and databases, web servers and APIs, among others.Resources:
- Mastering Bitcoin - Antonopoulos & Harding (book)