Q& a Forum Thinking Questions and Answers One

Q&A Forum Thinking Questions and Answers One #

Hello, I am Editor Xiao Xin.

Today is a Q&A class. Our column is coming to an end. In addition to the first batch of students who have kept up with the updates, we are also happy to see more new friends join the learning of this column.

The comments from many students have also added a lot of color to this course. Most of the questions have been answered by the teacher in the comment section. We look forward to more students sharing their experiences, asking questions, or attempting to answer others’ questions in the comment section. Let’s build a good atmosphere of collaborative learning and active communication together.

In order to give you enough time for thinking and research, we have chosen to release the reference answers for each lesson as an additional supplement, and we will also select some excellent students’ answers to showcase. Here, I would like to remind you that it is recommended to first do your own thinking before checking the answers. In addition, each lesson has hyperlinks for you to review.

Lesson 1

Q: Please consider whether the records of users inviting other users to register belong to historical records or relationship records?

A: I think the records of users inviting other users to register belong to relationship records.

Although this type of record has characteristics of historical records, the user who is invited to register can only be invited once, so the total amount is controllable. At the same time, the purpose of this table is very clear, which is to record relationship records. When querying, it is usually done by the inviter’s or the invitee’s user ID.

There are also many wonderful answers in the comment section, and I recommend you take a look. For example, the answer given by @移横为固:

Initially, I thought the registration invitation table should be treated as a historical table. After thinking about it, it can also be treated as a relationship table.

Under the premise of meeting the following registration invitation requirements:

  1. The inviter shares the invitation in a QR code-like manner, and the invitee actively scans the code to register (not using peer-to-peer invitation as the invitee may not accept it).

  2. Only one successful registration is allowed. - In this way, each invitation record is a registration record for a user: We can define the following fields: (inviter, invitee, registration time, method of invitation). - The field structure of the table is very simple, and the total number of records is at most the number of accounts, so it will not continuously expand over time. Therefore, it can handle the query requirements of a relationship table.

In actual projects, we will encounter many similar situations that require us to prevent unexpected operations. The key lies in how we can constrain the users who use the table, and how we can use the data in the table.

Lesson 2

Q1: When using Bloom Filter to identify hot keys, sometimes there may be false positives, resulting in the data not being found. How can we avoid this situation?

A1: There is a special method to reduce the probability. The original key is checked once through the Bloom Filter, and then checked again after applying the MD5 hash with another Bloom Filter.

Q2: When using Bloom Filter, we can only add new keys but cannot delete a specific key. Is there any other way to better update and maintain the Bloom Filter?

A2: Please refer to the implementation of Cuckoo Filter in Redis.

Lesson 3

Q: If a user changes their nickname, how can we quickly update the user nickname saved in the token?

A: When changing the user nickname, also update the token in the modification terminal. If our user has multiple clients, we can use cache refreshing by updating the Version version number mentioned, which allows the clients to periodically check and determine if the token needs to be updated.

Regarding this question, there is also an interesting answer from @徐曙辉:

If I were to implement the function of quickly changing nickname, there are two ways:

a. After the user modifies the nickname, add a user identifier in memory. After parsing the token, read the identifier. If it exists, return a specific code to make the client request a new token. We can even make the client not participate and directly return a 301 redirect to the route for obtaining a new token.

b. The token does not contain user information but only contains the user ID. When user information is needed, it is read from the cache.

The first solution provided by Xu is quite straightforward but interesting.

The second approach is also intriguing. Here, let me add an application tip: We can directly obtain a user’s avatar by setting a fixed URL in the format of user/userID/header.jpg, so we do not need to consider the update problem.

There are further discussions on this topic based on my supplement. I will also showcase the answer from Xu again. It is still in progress and Xu’s response is as follows:

By doing this, avatars can be in the format of http://xx.com/user/userID/header.jpg, and static files are fine because they are remotely rendered via HTTP anyway. But handling nicknames and other information in this way, putting each item into remote addresses might not be very efficient. Can we use http://xxx.com/user/userID/info.json and then deserialize it?

This certainly occupies additional storage space, but the advantage is that we do not need to query the database and cache, reducing their load. In web applications, reading user information is quite frequent I think this idea is excellent, and I suggest using object storage as much as possible. Regarding the topic of object storage, you can also refer to the content of Lesson 21, where I shared in detail how object storage manages small files and large texts.

Lesson 4

Q: If the synchronization link of Otter is circular, how can we ensure that the data does not keep synchronizing in a loop?

A: Otter inserts synchronization identifiers at the beginning and end of transactions, and these identifiers prevent the initiator from executing the same transaction during the parsing process.

Lesson 5

Q: Please think about why adding or removing members in a Raft cluster needs to be done differently?

A: This is a complex topic, and the key is that after adding or removing members, data needs to be synchronized and they will participate in the election. I think the analysis in the later article is relatively complete. You can click here to view the original text.

Lesson 6

Q: Some concepts in this lesson overlap with DDD, but there are still some small differences. Can you compare the differences between the MVC three-tier approach and the implementation of DDD?

A: This question does not have a standard answer. Let’s take a look at the answers from our classmates.

@Geek_994f3b’s answer is as follows:

Personally, I think the two are only different in scope. From the perspective of the program, the MVC pattern is used for inter-thread communication (monolithic application), while DDD is used for inter-process communication (microservices). So MVC + RPC protocol + Business decomposition ≈ DDD (just my personal opinion:), like adding another layer to a monolith.

@徐曙辉’s answer is as follows:

MVC focuses on the functional layered design of the project directory and is more framework-oriented, while DDD focuses more on the business entity domain and the relationship between them, and is more business-oriented.

Let me add my thoughts as well. I suggest considering the differences between an anemic model and a rich model, as well as the differences between domain models and services when thinking about this question.

Lesson 7

Q1: Please think about how to reduce the problem of slow interfaces after the inventory is reduced to 0 when implementing the inventory plan using atomic operations and splitting the inventory.

A1: We can set another key to indicate which keys still have inventory.

Q2: The content of this lesson is not only about inventory, but also includes many ingenious designs for locks that are not easy to discover. Can you share some interesting design ideas from your practical experience?

A2: There is no standard answer to this question. I hope you can be an attentive person and pay attention to various interesting lock designs in practice.

Lesson 8

Q: What method can be used to periodically check for unsynchronized data between two systems?

A: Add a modification time or version number to the data, and synchronize the version number whenever it is updated. The version number can help us identify the latest data.

Let’s see the answer from @LecKeyt:

Each data has a unique identifier (generally an auto-incrementing ID or a unique sequence of numbers), and they are usually small to large. Based on the maximum value, we should be able to determine it. If the data is not synchronized, we should find the corresponding data node and perform compensation operations.

After reading his answer, I added another question “How to avoid updating the same data?” You can also think about it before continuing.

The following answer is also from @LecKeyt:

Regarding the problem of inconsistent data caused by updates, I think it depends on the specific business requirements. If real-time requirements are not high, you can use an event queue for processing. If strong consistency is required, the best approach should be to use distributed transactions to ensure it.

Lesson 9

Q: There are many ways to implement distributed systems in the market now. Which method do you think has better performance?

A: I suggest considering using the AT or Seata method.

These are the answers to the questions from the chapters of the User Center and E-commerce System. I hope they can inspire you. Next, the teacher will answer the remaining homework questions and your questions. As always, feel free to interact with us in the comment area if you have any questions.