Special Planning Study Tips Volume 2 What Class Representatives Have to Say

Special Planning: Learning Tips Series (2): Let’s Hear What the Class Representatives Have to Say #

Hello, I am Ye Qian, the editor of the Rust course. Today marks the second installment of our special invitation for class representatives to share their personal learning experiences.

There has been a perpetual confusion among the newcomers about how to learn more smoothly: Why do I get more and more confused after watching the first 6 lectures? What kind of knowledge background is necessary to learn Rust, and to follow this column? They hope for a manual for this column or sorting out relevant background knowledge, among other requests…

In order to help you learn better in the new year, I have specially invited several class representatives to share their individual experiences and methods of learning this column and the Rust language. Hopefully, their stories will give you some reference and inspiration. Enjoy your learning.


@Marvichov #

Hello, I am Marvichov, a software engineer with 5 years of work experience. My current field of work is distributed machine learning, and my main programming language is Python. I also have previous experience with Cpp, including two and a half years with a search engine, and a year and a half with an open-source project. Additionally, I use Java and Go for personal project development and learning.

Like most people, I set a goal to complete this course but stopped at async.

When learning a language, it’s important to understand the reasons behind it. There are countless languages in the world, isn’t learning English also great? For me, the reason to learn Rust is simple: Rust’s safety model is really interesting and can solve many pain points of C/C++. For low-level development, safety is becoming increasingly important, with a higher priority than performance.

Let me share an example from a colleague: ever since the project shifted from C to Rust, he can now sleep soundly at night. He is no longer woken up in the middle of the night by a sudden Segfault. Some multithreaded bugs, which normally take a month to debug, have become the norm. Now, he can confidently merge the PRs from newcomers because the compiler steps in to prevent code with potential safety issues.

It is no surprise that Rust will dominate the low-level realm in the future. If you want to do low-level development, you can’t avoid this giant mountain.

At the beginning of my learning journey, I first read the official the book, which gave me a preliminary, intuitive understanding of Rust. However, The book is quite superficial, only touching on each knowledge point briefly. Especially the most important aspects like lifetime and borrow check, the book did not delve deep, and I still didn’t understand how the compiler calculates lifetimes after reading it. For deeper learning, one must turn to the nomicon and the official reference.

Then I encountered Non-Lexical Lifetime (NLL), and as I delved into the compiler’s implementation details, I realized I was in over my head, getting stuck on language syntax details. I spent a lot of time studying the language itself rather than accumulating practical project experience.

This is similar to my previous experience learning Cpp: getting hung up on various syntax features, wasting lots of time memorizing syntax I’d never use in practice. In the end, Cpp still required constant project work to master. Besides, most of the syntax is never used in practice – a lot of time was spent talking about tactics on paper. In conclusion, it was not learning but rather moving oneself.

Therefore, when learning a language, I prefer to get started quickly and jump straight into projects. Many experts learn new languages by rewriting projects they are familiar with in the new language.

I remember Uncle Rat mentioned in the “Listening to the Wind” column that his way of learning a language was to look at a few key aspects: memory management, error handling, type systems, etc., and then spend a day or two on a small project to master a new language. Different languages have many similarities, and after learning enough, you can quickly draw parallels. However, since I don’t have much end-to-end project experience, this method is still quite challenging for me.

Nevertheless, for most people including me, there’s a fast way to get familiar with the language, which is to do exercises, and rewrite those algorithms I’ve worked on before in Rust.

Leetcode’s support for Rust is rather limited and does not provide a stack trace when errors occur. Personally, I choose to use exercism, all code and tests can be run locally, making debugging convenient. Many Rust engineers around me have quickly got to grips with Rust by doing exercises and were then tasked with rewriting some of the Java projects. This method is also worth considering.

It so happens that Chen Tian’s Rust column provides many hands-on practical projects, making up for the shortcomings of various Rust books on the market, and avoiding the pitfall of ending up only studying the language itself. After all, languages are used to solve real problems. We learn Rust not to show off our knowledge but to create value with programs.

In fact, I was hesitant whether to purchase this course or not, because syntax knowledge is explained in great detail in the official The book and the nomicon. But as soon as I saw the hands-on project in the sixth lecture, I didn’t hesitate to place the order. I have a keen interest in compilers; the opportunity to handcraft an SQL parser, especially using Rust, is simply too good to miss.

How I Study This Column #

Here I also share how I study this course, in the hopes that it gives you some points of reference:

  • Lectures 1-3: Preliminary Knowledge on Memory

If you want to clear up how memory is managed or understand the address space of programs, I recommend taking the course “Computer Systems: A Programmer’s Perspective” (CSAPP). The professor Dave of this course said, “If you only take one computer systems foundation course in your life, CSAPP is enough.” I later made up for part of this course, which truly helped me understand many underlying system principles.

Simply put, at the machine code or assembly level, there is no notion of ownership, nor lifetime; there are only data and a series of instructions. The CPU only knows about executing instructions, data transfer, reading and writing various registers, as well as memory, such as the stack and heap from a programmer’s perspective.

Ownership and lifetime are just high-level language abstractions that are part of the Rust language, not part of the final machine code that the computer executes. Like loop invariants in algorithms, high-level language syntax rules ensure that the compiled code won’t have runtime errors causing memory safety issues.

  • Lectures 4-6: Get Hands Dirty

When I first learned them, I went through them quickly without aiming for complete understanding of the syntax details. A general idea that Rust is flexible for writing projects and supports many domains was enough for me. These lessons are quite information-dense and can easily deter newbies. For now, leave what you can’t understand and come back to it later when you learn more.

  • Lectures 7-14: Ownership & Containers

The basics of basics. Firstly, understand ownership and lifetime, which is the core issue that Rust aims to solve compared to C: memory safety. I personally hand-typed the examples in these courses line by line. First, I went through the examples, then wrote them again by myself. After all, according to the Learning Pyramid theory, the learning effect of hands-on practice is 50% stronger than that of reading alone. After that, understanding smart pointers and various basic data structures allows you to quickly start projects or do exercises.

  • Lecture 18: Error Handling

A focus point, also an example where Rust absorbs advantages from other languages. The built-in syntax support makes Rust stand out from other mainstream languages, such as C/C++ and Java. The approach to error handling also reveals Rust’s safety design philosophy.

  • Lectures 12-14, 23-25: Traits

One of the cores of Rust is Traits, the foundation of Rust’s abstractions. Familiarity with the abstract style of interface-oriented programming is essential to keep up with the various projects in the course. Many Traits must be mastered, such as AsRef, From, Deref, Drop, Send/Sync, etc. These Traits are like the basic elements that build the world of Rust. If you’re not familiar, you’ll have trouble reading documentation and designing interfaces.

  • Lectures 21-22, 26, 36-37, 41-42: Hands-On KV Server Series

You can set this series aside for the first time you learn it and wait until all your Rust knowledge comes together before learning it all at once. The course is arranged to study the KV server while interspersing new knowledge points continuously and iteratively updating the project with new syntax sugar. However, this project has a considerable amount of code, and it’s easy to forget various project details and context in the middle. When I was learning, I found it more effective to learn this project in one go, striking while the iron is hot.

  • Other Lectures

The rest are mainly about project practice, mainly to get familiar with various I/O and interfaces, and system design. Besides following the teacher’s thoughts and typing the code step by step, I can’t think of a better way. The teacher has rich practical project experience, and many of his designs take me a long time to understand. The further I progress, the harder it becomes to keep up with the teacher because I have to learn both the teacher’s design ideas and various Rust knowledge points at the same time. It can only be said that taking one course is as good as taking two, which is very cost-effective.

My Learning Method #

The first method is to create mind maps, as a picture is worth a thousand words. Only by describing knowledge points in your own language can you internalize them. The teacher is a really good role model in this regard, with every lesson starting with a knowledge map.

The second method is building your own knowledge system, with the central idea being holistic learning. Every knowledge point you learn is an island, and only by connecting them can you draw parallels easily, and what you learn becomes hard to forget.

To use an analogy, if the knowledge points aren’t connected, they become isolated islands that are easy to forget. When connections among the islands are established, they turn into a city. When you get lost in a city, it’s easy to navigate to your destination using a new guide. But if you get lost in the wilderness, the cost of reaching your destination can be substantial, often requiring a great deal of effort to start over.

When I was learning Rust, I liked to compare it with C, CPP, and Golang, linking similar knowledge points together.

For example, CPP’s templates and RAII correspond to Rust’s generics and Drop; Golang’s interface is similar to Rust’s trait, both related to interface-oriented programming. Rust’s unique feature compared to other languages is its safety model. Therefore, when learning, we can focus on mastering ownership, lifetime, and thread safety.

The third point is to practice diligently. In my opinion, 99% of coding is about being skilled; there are no shortcuts and no need for talent. High school level mathematics and logic are enough. In the industry, only 1% of people engage in mathematical programming, which involves creating, researching, optimizing, and writing core algorithms. To join that 1%, talent is necessary.

The difficulty of Rust does not come from a lack of coder talent, but from it demanding good foundational knowledge and a solid understanding of the memory model. If you hit a bottleneck in learning Rust and find it difficult to proceed, consider stepping back and solidifying your basics. I’ll take this opportunity to recommend CSAPP once more.

The fourth point I mentioned earlier: besides following along with projects, you can also solve programming problems. When I compare solutions to problems, I notice many students like to compress complicated logic into one line through functional programming. This is like the “one-liners” of the past where people boasted about solving Python problems in one line. Writing Python this way is fine because no one expects Python code to perform exceptionally. However, this is not quite appropriate for Rust.

Although Rust is highly expressive and encourages the use of functional programming, it remains a low-level language. The most important features of a low-level language are readability and optimizability. When you compress a complex program into a line or a statement, you’ll have a hard time identifying parts that need optimization. Some Rust engineers I know told me that this is not how code is written in practice. Most of the time, they opt for the simplest and most straightforward APIs, clear Generics, and designs based on interface-oriented programming concepts.

The last point is to debrief.

In a small sense, this means reviewing timely. Refreshing the Ebbinghaus forgetting curve from school, according to this crude model, you’ll forget 70% after one day without review. After a week, you’ll forget 77%. Nowadays, people are busy and it’s good just to find some time to review within a week. Otherwise, if you learn and forget, in the end, you’ll only alleviate anxiety and impress yourself.

I recommend the method shared by the great Jon Gjengset: during classes, he does not take notes but listens intently, trying to understand the material fully. After class, he uses the Cornell Notes system for note-taking. This note-taking method is specially designed for review and combating forgetting. It is proven effective. Many note-taking apps come with Cornell Notes templates.

In a broader sense, it’s about establishing a knowledge system and methodology. After the course, summarize the knowledge points learned, and, with the previously mentioned holistic learning approach, link the newly acquired knowledge with what has already been learned, while also reviewing previous knowledge.

Apart from reviewing knowledge points, you can also reflect on whether your learning methods are effective and whether your study plans are well-arranged. Debriefing is a very self-disciplined process, and I am still exploring it. I hope to make progress with you all in 2022 and continue to grow.

Study Resources #


This is today’s share from class representative Marvichov. If you have your own Rust learning stories, feel free to leave a comment below for mutual exchanges and to inspire and learn from each other.

See you in the third installment~