Nov 10, 2020 (updated: Jun 13, 2021) ▪ 16 min read

This is a work-in-progress list with recommended learning material and programming languages for computer science students. It works well on its own (for self-learners) or as a complement to the typical undergraduate degree in computer science, which is often lacking some lower-level details and mathematical content. The goal is to provide a more solid foundation to build upon. This list will be updated whenever I find that something is missing, incorrect, or to add additional learning material.

Programming is the constant in most tasks related to computer science and computational problem solving, and should be the primary focus of any computer science curriculum (showcasing different uses in computer systems, application software, and so on). If you prefer to work on projects while learning, get ideas at github.com/tuvtran/project-based-learning.

The goal is to get comfortable with programming and to understand the software abstraction model (via Assembly, C/C++, and Python; low-level to high-level, with Python representing the highest-level of abstraction). You probably don't need to be fluent in Assembly (or any specific architecture), but it's a good idea to understand enough to be able to read and find errors.

**Assembly**

- x86, ARM (could also explore other architectures if more appropriate); see x86 Assembly Guide and ARM Hardware and Assembly Language

- Get familiar with registers; see x86 Assembly/X86 Architecture

**C/C++**

- Learn basics of memory allocation and pointers; try to understand the assembly code for smaller programs (gcc -S option)

- Get familiar with C++ (could also get fluent if appropriate, it's a very powerful programming language)

**Python**

- Get fluent (look at some numerical libraries as well, especially NumPy, maybe Pandas)

- Try to implement game of life; see Programming Projects for Advanced Beginners #2: Game of Life

- Try to implement an interpreter; see Letâ€™s Build A Simple Interpreter

**Bonus:**Experiment with some quantum libraries (maybe Qiskit, or TensorFlow Quantum)

Recommended learning material: Computer Systems: A Programmer's Perspective, The Art of Assembly Language, C Programming Language, A Tour of C++, Python Crash Course.

The goal is to get familiar with a range of programming paradigms, understand parts of the hardware abstraction model (via Verilog), and become a more confident computer scientist in general (via more advanced reading). A few notes on programming languages: C/C++ and Python are considered multi-paradigm (as in supporting more than one style), but more specifically imperative and structured (i.e. there are limited jump instructions, read this: Edgar Dijkstra: Go To Statement Considered Harmful).

**Haskell**

- Functional

- Try to build a compiler, transpiler, or parser; see Building a modern functional compiler from first principles

**Prolog**

- Logic-based

- Probably most popular logic programming language (could also explore Clojure.core.logic if more appropriate, see clojure/core.logic)

**Coq** (Gallina)

- Dependently-typed functional

- Probably most popular proof assistant; see Coq in a Hurry

**Verilog**

- Hardware description language; probably most popular language to design and verify digital systems

- Try to implement designs at different abstraction levels (gate-level, register-transfer-level, behavioural-level); see Verilog Tutorial

Recommended learning material: Thinking Functionally with Haskell, The Elements of Computing Systems, Structure and Interpretation of Computer Programs.

What about object-oriented programming? This is a quote by Paul Graham (Viaweb, Y Combinator): "*[at] big companies, software tends to be written by large (and frequently changing) teams of mediocre programmers. Object-oriented programming imposes a discipline on these programmers that prevents any one of them from doing too much damage*", read this: Why Arc Isn't Especially Object-Oriented.

The goal is to get exposed to machine learning and the idea that output is based on data instead of design, watch this: Building the Software 2.0 Stack.

**Neural Networks** (Python)

- Get familiar with Keras, TensorFlow, and PyTorch; try challenges at Kaggle: Competitions (or look at solutions if stuck)

- Try to build a neural network from scratch; see How to build your own Neural Network from scratch in Python

Recommended learning material: The Hundred-Page Machine Learning Book.

The above topics provides familiarity with different paradigms and modern developments (such as ML). Below are a few more programming languages to consider, somewhat based on the "most loved" programming languages: Stack Overflow Developer Survey 2020.

**Rust** (backed by Mozilla)

- Natural transition from C++, could also explore Scala if more familiar with Java

- Try to build an OS; see Writing an OS in Rust

**Clojure**

- Lisp-like, could also explore Lisp if more appropriate

**Nim**

- Python-like but compiled, could also explore Lua if interested in embedded applications (or game development)

**Kotlin**

- Probably most popular language for Android development (see Kotlin is now Google's preferred language for Android app development), compiles to JVM and JavaScript (could also explore JavaScript if more appropriate)

**Go** (backed by Google)

- Memory safe C (if you don't like Rust, could also explore Dart)

Mathematics has a central role in any computer science curriculum. A solid foundation in selected mathematical topics can be highly valuable, especially in more advanced computing (not to mention ML).

The Goal is to get familiar with data structures and theory of computation, these topics could also be covered in recommended learning material for some programming languages.

**Discrete Mathematics**

- Get familar with sets, permutations, trees, graphs, and related concepts

- Try to implement common algorithms in different programming languages (optimize based on different conditions); get ideas at The Algorithms

**Probability Theory**

- Learn basics of probability distributions and conditionality; see Khan Academy: Statistics and probability

**Bonus**: Try to implement concepts based on random processes (maybe MDP solver, see aimacode), could also explore game theory if interested in AI applications

Recommended learning material: Discrete Mathematics, Introduction to Algorithms.

The goal is to build a strong general background in mathematics, such as typically taught in undergraduate science-related degrees. Many topics are useful in several tasks related to computer science, but in particular ML, computer vision, and scientifc computing.

**Calculus**

- Get familiar with derivatives and anti-derivatives, multivariable derivatives, and vector calculus

- Learn basics of partial derivatives, Jacobian computations, and relevant optimization techniques

**Linear Algebra**

- Get familiar with vectors, spaces, matrix transformations, and related concepts

- Learn basics of inverse, determinant, and transpose (get fluent if interested in computer vision)

**Differential Equations**

- Learn basics of first-order, second-order, and partial differential equations

**Number Theory**

- Get familiar with topics in number theory (whichever interesting); see List of number theory topics

**Bonus**: Try to solve computational problems; see Project Euler

Recommended learning material: Calculus: Early Transcendentals, No bullshit guide to linear algebra, Ordinary Differential Equations, Elementary Analysis: The Theory of Calculus, Number Theory.

This section contains additional topics and commonly used tools, it's somewhat based on the "*missing semester*" by MIT: The Missing Semester of Your CS Education.

**Git**

- Probably most common version control system

**Bash**

- Domain-specific command language (Unix shell)

- Get familiar with frequently used commands at Bash scripting cheatsheet

**JavaScript**

- Event-driven (control flow based on events)

- Get familiar if you ever want to build web applications, could also explore any of the other *Script languages (TypeScript, CoffeeScript, or maybe AssemblyScript)

It's also a good idea to get familiar with virtual machines, such as Vagrant or Docker, build systems, such as Make, cloud platforms, such as AWS or Google Cloud, and parallel computing, such as CUDA or OpenCL. Finally, learning basics of working with notebooks is probably a good idea, such as Jupyter (Python), which is a very popular development environment for ML and deep learning.