# **How to Use This Book**

As the number of contributors grows, the content of this book keeps expanding. It is impractical and unnecessary to try to complete all the courses in the book. Attempting to do so might even be counterproductive, resulting in effort without reward. To better align with our readers and make this book truly useful for you, I have roughly divided readers into the following three categories based on their needs. Everyone can plan their own self-study program accurately according to their actual situation.

## **Freshmen**

If you have just entered the university or are in the lower grades, and you are studying or planning to switch to computer science, then you are lucky. As studying is your main task, you have ample time and freedom to learn what you are interested in without the pressure of work and daily life. You needn't be overly concerned with utilitarian thoughts like "is it useful" or "can it help me find a job". So, how should you arrange your studies? The first point is to break away from the passive learning style formed in high school. As a small-town problem solver, I know that most Chinese high schools fill every minute of your day with tasks, and you just need to passively follow the schedule. As long as you are diligent, the results won’t be too bad. However, once you enter university, you have much more freedom. All your extracurricular time is yours to use, and no one will organize knowledge points or summarize outlines for you. Exams are not as formulaic as in high school. If you still hold the mentality of a "good high school student", following everything step by step, the results may not be as expected. The professional training plan may not be reasonable, the teaching may not be responsible, attending classes may not guarantee understanding, and even the exam content may not relate to what was taught. Jokingly, you might feel that the whole world is against you, and you can only rely on yourself.

Given this reality, if you want to change it, you must first survive and have the ability to question it. In the lower grades, it’s important to lay a solid foundation. This foundation is comprehensive, covering both in-class knowledge and practical skills, which are often lacking in China's undergraduate computer science education. Based on personal experience, I offer the following suggestions for your reference.

First, learn how to write "elegant" code. Many programming introductory courses in China can be extremely boring syntax classes, less effective than reading official documentation. Initially, letting students understand what makes code elegant and what constitutes "bad taste" is beneficial. Introductory courses usually start with procedural programming (like C language), but even here, the concepts of **modularity** and **encapsulation** are crucial. If you write code just to pass on OpenJudge, using lengthy copy-pasting and bloated main functions, your code quality will remain poor. For larger projects, endless debugging and maintenance costs will overwhelm you. So, constantly ask yourself, is there a lot of repetitive code? Is the current function too complex (Linux advocates each function should do only one thing)? Can this code be abstracted into a function? Initially, this may seem cumbersome for simple problems, but remember, good habits are invaluable. Even middle school students can master C language, so why should a company hire you as a software engineer?

After procedural programming, the second semester of the freshman year usually introduces object-oriented programming (like C++ or Java). I highly recommend [MIT 6.031: Software Construction](软件工程/6031.md) course notes, which use Java (switch to TypeScript after 2022) to explain how to write “elegant” code in detail, including Test-Driven development, function Specification design, exception handling, and more. Also, understanding common design patterns is necessary when learning object-oriented programming. Domestic object-oriented courses can easily become dull syntax classes, focusing on inheritance syntax and puzzling questions, neglecting that these are rarely used in real-world development. The essence of object-oriented programming is teaching students to abstract real problems into classes and their relationships, and design patterns are the essence of these abstractions. I recommend the book ["Big Talk Design Patterns"](https://book.douban.com/subject/2334288/), which is very easy to understand.

Second, try to learn some productivity-enhancing tools and skills, such as Git, Shell, Vim. I strongly recommend the [MIT missing semester](编程入门/MIT-Missing-Semester.md) course. Initially, you may feel awkward, but force yourself to use them, and your development efficiency will skyrocket. Additionally, many applications can greatly increase your productivity. A rule of thumb is: any action that requires your hands to leave the keyboard should be eliminated. For example, switching applications, opening files, browsing the web - there are plugins for these (like [Alfred](https://www.alfredapp.com/) for Mac). If you find an daily operation that takes more than 1 second, try to reduce it to 0.1 seconds. After all, you'll be dealing with computers for decades, so forming a smooth workflow can greatly enhance efficiency. Lastly, learn to touch type! If you still need to look at the keyboard while typing, find a tutorial online and learn to type without looking. This will significantly increase your development efficiency.

Third, balance coursework and self-learning. We feel angry about the institution but must also follow the rules, as GPA is still important for postgraduate recommendations. Therefore, in the first year, I suggest focusing on the curriculum, complemented by high-quality extracurricular resources. For example, for calculus and linear algebra, refer to [MIT 18.01/18.02](./数学基础/MITmaths.md) and [MIT 18.06](./数学基础/MITLA.md). During holidays, learn Python through [UCB CS61A](./编程入门/Python/CS61A.md). Also, focus on good programming habits and practical skills mentioned above. From my experience, mathematics courses matter a lot for your GPA in the first year, and the content of math exams varies greatly between different schools and teachers. Self-learning might help you understand the essence of mathematics, but it may not guarantee good grades. Therefore, it’s better to specifically practice past exams. 

In your sophomore year, as computer science courses become the majority, you can fully immerse yourself in self-learning. Refer to [A Reference Guide for CS Learning](./CS学习规划.md), a guide I created based on three years of self-learning, introducing each course and its importance. For every course in your curriculum, this guide should have a corresponding one, and I believe they are of higher quality. If there are course projects, try to adapt labs or projects from these self-learning courses. For example, I took an operating systems course and found the teacher was still using experiments long abandoned by UC Berkeley, so I emailed the teacher to switch to the [MIT 6.S081](./操作系统/MIT6.S081.md) xv6 Project I was studying. This allowed me to self-learn while inadvertently promoting curriculum reform. In short, be flexible. Your goal is to master knowledge in the most convenient and efficient way. Anything that contradicts this goal can be “fudged” as necessary. With this attitude, after my junior year, I barely attended offline classes (I spent most of my sophomore year at home due to the pandemic), and it had no impact on my GPA.

Finally, I hope everyone can be less impetuous and more patient in their pursuit. Many ask if self-learning requires strong self-discipline. It depends on what you want. If you still hold the illusion that mastering a programming language will earn you a high salary and a share of the internet’s profits, then whatever I say is pointless. Initially, my motivation was out of pure curiosity and a natural desire for knowledge, not for utilitarian reasons. The process didn't involve “extraordinary efforts”; I spent my days in college as usual and gradually accumulated this wealth of materials. Now, as the US-China confrontation becomes a trend, we still humbly learn techniques from the West. Who will change this? You, the newcomers. So, go for it, young man!

## **Simplify the Complex**

If you have graduated and started postgraduate studies, or have begun working, or are in another field and want to learn coding in your spare time, you may not have enough time to systematically complete the materials in [A Reference Guide for CS Learning](./CS学习规划.md), but still want to fill the gaps in your undergraduate foundation. Considering that these readers usually has some programming experience, there is no need to repeat introductory courses. From a practical standpoint, since the general direction of work is already determined, there is no need to deeply study every branch of computer science. Instead, focus on general principles and skills. Based on my own experience, I've selected the most important and highest quality core professional courses to deepen readers' understanding of computer science. After completing these courses, regardless of your specific job, I believe you won't just be an ordinary coder, but will have a deeper understanding of the underlying logic of computers.

| Course Direction    | Course Name                                          |
|---------------------|------------------------------------------------------|
| Discrete Mathematics and Probability Theory | [UCB CS70: Discrete Math and Probability Theory](数学进阶/CS70.md) |
| Data Structures and Algorithms | [Coursera: Algorithms I & II](数据结构与算法/Algo.md) |
| Software Engineering | [MIT 6.031: Software Construction](软件工程/6031.md) |
| Full-Stack Development | [MIT Web Development Course](Web开发/mitweb.md) |
| Introduction to Computer Systems | [CMU CS15213: CSAPP](计算机系统基础/CSAPP.md) |
| Introductory System Architecture | [Coursera: Nand2Tetris](体系结构/N2T.md) |
| Advanced System Architecture | [CS61C: Great Ideas in Computer Architecture](体系结构/CS61C.md) |
| Principles of Databases | [CMU 15-445: Introduction to Database Systems](数据库系统/15445.md) |
| Computer Networking | [Computer Networking: A Top-Down Approach](计算机网络/topdown.md) |
| Artificial Intelligence | [Harvard CS50: Introduction to AI with Python](人工智能/CS50.md) |
| Deep Learning | [Coursera: Deep Learning](深度学习/CS230.md) |

## **Focused and Specialized**

If you have a solid grasp of the core professional courses in computer science and have already determined your work or research direction, then there are many courses in the book not mentioned in [A Reference Guide for CS Learning](./CS学习规划.md) for you to explore.

As the number of contributors increases, new branches such as **Advanced Machine Learning** and **Machine Learning Systems** will be added to the navigation bar. Under each branch, there are several similar courses from different schools with different emphases and experiments, such as the **Operating Systems** branch, which includes courses from MIT, UC Berkeley, Nanjing University, and Harbin Institute of Technology. If you want to delve into a field, studying these similar courses will give you different perspectives on similar knowledge. Additionally, I plan to contact researchers in related fields to share research learning paths in specific subfields, enhancing the depth of the CS Self-learning Guide while pursuing breadth.

If you want to contribute in this area, feel free to contact the author via email [zhongyinmin@pku.edu.cn](mailto:zhongyinmin@pku.edu.cn).