diff --git a/docs/index.en.md b/docs/index.en.md index bdaa674ae..d98f2307f 100644 --- a/docs/index.en.md +++ b/docs/index.en.md @@ -2,7 +2,7 @@ ![Image title](./images/title.png){ width="600" } -# Foreword +# **Foreword** **The English version is still under development, please check [this issue](https://github.com/PKUFlyingPig/cs-self-learning/issues/222) if you want to contribute.** @@ -17,7 +17,7 @@ The book is currently organized to include the following sections (if you have o - Book recommendations: Those who have read the CSAPP must have realized the importance of good books. I will list links to books and resources in different areas of Computer Science that I find rewarding to read. - **List of high quality CS courses**: I will summarize all the high quality foreign CS courses I have taken into different categories and give relevant self-learning advice. Most of them will have a separate repository containing relevant resources as well as my homework/project implementations. -## The place where dreams start —— CS61A +## **The place where dreams start —— CS61A** In my freshman year, I was a novice who knew nothing about computers. I installed a giant IDE Visual Studio and fight with OJ every day. With my high school maths background, I did pretty well in maths courses, but I felt struggled to learn courses in my major. When it came to programming, all I could do was open up that clunky IDE, create a new project that I didn't know exactly what it was for, and then `cin`, `cout`, `for` loops, and then CE, RE, WA loops. I was in a state where I was desperately trying to learn well but I didn't know how to learn. I listened carefully in class but I couldn't solve the homework problems. I spent almost all my spare time doing the homework after class, but the results were disappointing. I still retain the source code of the project for Introduction to Computing course —— a single 1200-line C++ file with no header files, no class abstraction, no unit tests, no makefile, no version control. The only good thing is that it can run, the disadvantage is the complement of "can run". For a while I wondered if I wasn't cut out for computer science, as all my childhood imaginings of geekiness had been completely ruined by my first semester's experience. @@ -41,9 +41,9 @@ Imagine that if someone could chew up the hard knowledge and present it to you i If you think I'm exaggerating, start with [CS61A](https://cs61a.org/), because it's where my dreams began. -## Why write this book? +## **Why write this book?** -In the 2020 Fall semester, I worked as a teaching assistant for the class Introduction to Computer Systems at Peking University. At that time, I had been studying totally on my own for over a year. I enjoyed this style of learning immensely. To share this joy, I have made a [CS Self-learning Materials List](https://github.com/PKUFlyingPig/Self-learning-Computer-Science) for students in my seminar. It was purely on a whim at the time, as I wouldn't dare to encourage my students to skip classes and study on their own. +In the 2020 Fall semester, I worked as a teaching assistant for the class "Introduction to Computer Systems" at Peking University. At that time, I had been studying totally on my own for over a year. I enjoyed this style of learning immensely. To share this joy, I have made a [CS Self-learning Materials List](https://github.com/PKUFlyingPig/Self-learning-Computer-Science) for students in my seminar. It was purely on a whim at the time, as I wouldn't dare to encourage my students to skip classes and study on their own. But after another year of maintenance, the list has become quite comprehensive, covering most of the courses in Computer Science, Artificial Intelligence and Soft Engineering, and I have built separate repositories for each course, summarising the self-learning materials that I used. @@ -53,7 +53,7 @@ If you can build up the whole CS foundation in less than three years, have relat I firmly believe that if you have read to this line, you do not lack the ability and committment to learn CS well, you just need a good teacher to teach you a good course. And I will try my best to pick such courses for you, based on my three years of experience. -## Pros +## **Pros** For me, the biggest advantage of self-learning is that I can adjust the pace of learning entirely according to my own progress. For difficult parts, I can watch the videos over and over again, Google it online and ask questions on StackOverflow until I have it all figured out. For those that I mastered relatively quickly, I could skip them at twice or even three times the speed. @@ -61,7 +61,7 @@ Another great thing about self-learning is that you can learn from different per A third advantage of self-learning is that you do not need to go to the class, listening to the boring lectures. -## Cons +## **Cons** Of course, as a big fan of self-learning, I have to admit that it has its disadvantages. @@ -71,16 +71,16 @@ The second thing is that these courses are basically in English. From the videos The third, and I think the most difficult one, is self-discipline. Because have no DDL can sometimes be a really scary thing, especially when you get deeper, many foreign courses are quite difficult. You have to be self-driven enough to force yourself to settle down, read dozens of pages of Project Handout, understand thousands of lines of skeleton code and endure hours of debugging time. With no credits, no grades, no teachers, no classmates, just one belief - that you are getting better. -## Who is this book for? +## **Who is this book for?** As I said in the beginning, anyone who is interested in learning computer science on their own can refer to this book. If you already have some basic skills and are just interested in a particular area, you can selectively pick and choose what you are interested in to study. Of course, if you are a novice who knows nothing about computers like I did back then, and just begin your college journey, I hope this book will be your cheat sheet to get the knowledge and skills you need in the least amount of time. In a way, this book is more like a course search engine ordered according to my experience, helping you to learn high quality CS courses from the world's top universities without leaving home. Of course, as an undergraduate student who has not yet graduated, I feel that I am not in a position nor have the right to preach one way of learning. I just hope that this material will help those who are also self-motivated and persistent to gain a richer, more varied and satisfying college life. -## Special thanks +## **Special thanks** I would like to express my sincere gratitude to all the professors who have made their courses public for free. These courses are the culmination of decades of their teaching careers, and they have chosen to selflessly make such a high quality CS education available to all. Without them, my university life would not have been as fulfilling and enjoyable. Many of the professors would even reply with hundreds of words in length after I had sent them a thank you email, which really touched me beyond words. They also inspired me all the time that if decide to do something, do it with all heart and soul. -## Want to join as a contributor? +## **Want to join as a contributor?** There is a limit to how much one person can do, and this book was written by me under a heavy research schedule, so there are inevitably imperfections. In addition, as I work in the area of systems, many of the courses focus on systems, and there is relatively little content related to advanced mathematics, computing theory, and advanced algorithms. If any of you would like to share your self-learning experience and resources in other areas, you can directly initiate a Pull Request in the project, or feel free to contact me by email ([zhongyinmin@pku.edu.cn](mailto:zhongyinmin@pku.edu.cn)). diff --git "a/docs/\344\275\277\347\224\250\346\214\207\345\215\227.en.md" "b/docs/\344\275\277\347\224\250\346\214\207\345\215\227.en.md" new file mode 100644 index 000000000..368349b42 --- /dev/null +++ "b/docs/\344\275\277\347\224\250\346\214\207\345\215\227.en.md" @@ -0,0 +1,47 @@ +# **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](./编程入门/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](Web开发/mitweb.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). \ No newline at end of file diff --git "a/docs/\344\275\277\347\224\250\346\214\207\345\215\227.md" "b/docs/\344\275\277\347\224\250\346\214\207\345\215\227.md" index 458206b91..551bb7b12 100644 --- "a/docs/\344\275\277\347\224\250\346\214\207\345\215\227.md" +++ "b/docs/\344\275\277\347\224\250\346\214\207\345\215\227.md" @@ -10,7 +10,7 @@ 其一就是了解如何写“优雅”的代码。国内的很多大一编程入门课都会讲成极其无聊的语法课,其效果还不如直接让学生看官方文档。事实上,在刚开始接触编程的时候,让学生试着去了解什么样的代码是优雅的,什么样的代码 "have bad taste" 是大有裨益的。一般来说,编程入门课会先介绍过程式编程(例如 C 语言)。但即便是面向过程编程,**模块化** 和 **封装** 的思想也极其重要。如果你只想着代码能在 OpenJudge 上通过,写的时候图省事,用大段的复制粘贴和臃肿的 main 函数,长此以往,你的代码质量将一直如此。一旦接触稍微大一点的项目,无尽的 debug 和沟通维护成本将把你吞没。因此,写代码时不断问自己,是否有大量重复的代码?当前函数是否过于复杂(Linux 提倡每个函数只需要做好一件事)?这段代码能抽象成一个函数吗?一开始你可能觉得很不习惯,甚至觉得这么简单的题需要如此大费周章吗?但记住好的习惯是无价的,C 语言初中生都能学会,凭什么公司要招你去当程序员呢? -学过面向过程编程后,大一下学期一般会讲面向对象编程(例如 C++ 或 Java)。这里非常推荐大家看 [MIT 6.031: Software Construction](./软件工程/6031.md) 这门课的 Notes,会以 Java 语言为例非常详细地讲解如何写出“优雅”的代码。例如 Test-Driven 的开发、函数 Specification 的设计、异常的处理等等等等。除此之外,既然接触了面向对象,那么了解一些常见的设计模式也是很有必要的。因为国内的面向对象课程同样很容易变成极其无聊的语法课,让学生纠结于各种继承的语法,甚至出一些无聊的脑筋急转弯一样的题目,殊不知这些东西在地球人的开发中基本不会用到。面向对象的精髓是让学生学会自己将实际的问题抽象成若干类和它们之间的关系,而设计模式则是前人总结出来的一些精髓的抽象方法。这里推荐[大话设计模式](https://book.douban.com/subject/2334288/) 这本书,写得非常浅显易懂。 +学过面向过程编程后,大一下学期一般会讲面向对象编程(例如 C++ 或 Java)。这里非常推荐大家看 [MIT 6.031: Software Construction](./软件工程/6031.md) 这门课的 Notes,会以 Java 语言(22年改用了 TypeScript 语言)为例非常详细地讲解如何写出“优雅”的代码。例如 Test-Driven 的开发、函数 Specification 的设计、异常的处理等等等等。除此之外,既然接触了面向对象,那么了解一些常见的设计模式也是很有必要的。因为国内的面向对象课程同样很容易变成极其无聊的语法课,让学生纠结于各种继承的语法,甚至出一些无聊的脑筋急转弯一样的题目,殊不知这些东西在地球人的开发中基本不会用到。面向对象的精髓是让学生学会自己将实际的问题抽象成若干类和它们之间的关系,而设计模式则是前人总结出来的一些精髓的抽象方法。这里推荐[大话设计模式](https://book.douban.com/subject/2334288/) 这本书,写得非常浅显易懂。 其二就是尝试学习一些能提高生产力的工具和技能,例如 Git、Shell、Vim。这里强烈推荐学习 [MIT missing semester](./编程入门/MIT-Missing-Semester.md) 这门课,也许一开始接触这些工具用起来会很不习惯,但强迫自己用,熟练之后开发效率会直线提高。此外,还有很多应用也能极大提高的你生产力。一条定律是:一切需要让手离开键盘的操作,都应该想办法去除。例如切换应用、打开文件、浏览网页这些都有相关插件可以实现快捷操作(例如 Mac 上的 [Alfred](https://www.alfredapp.com/))。如果你发现某个操作每天都会用到,并且用时超过1秒,那就应该想办法把它缩减到0.1秒。毕竟以后数十年你都要和电脑打交道,形成一套顺滑的工作流是事半功倍的。最后,学会盲打!如果你还需要看着键盘打字,那么赶紧上网找个教程学会盲打,这将极大提高你的开发效率。