Should the Like function use MySQL or Redis?

Should the Like function use MySQL or Redis?

This is an interview question I was asked recently. This blog summarizes and shares this question.

1. Common mistakes made by beginners

Maybe many novices (including me back then, haha) would first think of writing something like this:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("Nuggets");
 
    for (String platform : platformList) {
        if (platform.equals("博客园")) {
            platformList.remove(platform);
        }
    }
 
    System.out.println(platformList);
}

Then I ran it with confidence, but it turned out to be
java.util.ConcurrentModificationException is an exception, which means concurrent modification exception in Chinese.

Like function: use MySQL or Redis?

Are you confused and wondering why this is happening?

Let's first look at the bytecode generated by the above code, as shown below:

Like function: use MySQL or Redis?

From this we can see that when the foreach loop is actually executed, it actually uses Iterator, and the core methods used are hasnext() and next().

Then let’s take a look at how the Iterator of the ArrayList class is implemented?

Like function: use MySQL or Redis?

It can be seen that when the next() method is called to get the next element, the first line of code is to call checkForComodification();, and the core logic of this method is to compare the values ​​of the two variables modCount and expectedModCount.

In the above example, at the beginning, the values ​​of modCount and expectedModCount are both 3, so there is no problem in getting the element "博客园" for the first time, but when the following line of code is executed:

platformList.remove(platform);

The value of modCount is changed to 4.

Like function: use MySQL or Redis?

So when getting the element for the second time, the values ​​of modCount and expectedModCount are not equal, so the error is thrown.
java.util.ConcurrentModificationException.

Like function: use MySQL or Redis?

Since foreach cannot be used to achieve this, how can we implement it?

There are three main methods:

  • Using Iterator's remove() method
  • Use for loop to traverse in positive order
  • Use for loop to traverse in reverse order

Next, I will explain them one by one.

2. Use the remove() method of Iterator

The implementation of the remove() method using Iterator is as follows:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("Nuggets");
 
    Iterator<String> iterator = platformList.iterator();
    while (iterator.hasNext()) {
        String platform = iterator.next();
        if (platform.equals("博客园")) {
            iterator.remove();
        }
    }
 
    System.out.println(platformList);
}

The output is:

[CSDN, Nuggets]

Why can we use iterator.remove()? Let's look at its source code:

Like function: use MySQL or Redis?

It can be seen that each time an element is deleted, the value of modCount is reassigned to expectedModCount, so that the two variables are equal and will not trigger
java.util.ConcurrentModificationException. For more interview questions, please follow the official account Java Interview Questions Selection

3. Use for loop to traverse in positive order

The implementation of forward traversal using a for loop is as follows:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("Nuggets");
 
    for (int i = 0; i < platformList.size(); i++) {
        String item = platformList.get(i);
 
        if (item.equals("博客园")) {
            platformList.remove(i);
            i = i - 1;
        }
    }
 
    System.out.println(platformList);
}

This implementation is relatively easy to understand, that is, to delete by array subscript, but there is a note that after deleting the element, the subscript value must be corrected:

i = i - 1;

Why do we need to correct the value of the subscript? Because the initial element subscript is like this:

Like function: use MySQL or Redis?

After deleting the element "博客园" in the first loop, the subscript of the element becomes as follows:

Like function: use MySQL or Redis?

In the second loop, the value of i is 1, which means that the element "Nuggets" is taken, which causes the element "CSDN" to be skipped. Therefore, after deleting the element, we need to correct the subscript, which is also the purpose of i = i - 1; in the above code. For more interview questions, you can follow the WeChat subscription number Jiangjiji and reply to the interview to get

4. Use for loop to traverse in reverse order

The implementation of reverse traversal using a for loop is as follows:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("Nuggets");
 
    for (int i = platformList.size() - 1; i >= 0; i--) {
        String item = platformList.get(i);
 
        if (item.equals("Nuggets")) {
            platformList.remove(i);
        }
    }
 
    System.out.println(platformList);
}

This implementation is similar to using a for loop to traverse in forward order, but there is no need to correct the subscripts because the subscripts of the elements at the beginning are like this:

Like function: use MySQL or Redis?

After deleting the element "Nuggets" in the first loop, the subscripts of the elements become as follows:

Like function: use MySQL or Redis?

In the second loop, the value of i is 1, which means that the element "CSDN" is obtained, which will not cause the element to be skipped, so there is no need to correct the subscript.

So when getting the element for the second time, the values ​​of modCount and expectedModCount are not equal, so the error is thrown.
java.util.ConcurrentModificationException.

Like function: use MySQL or Redis?

Since foreach cannot be used to achieve this, how can we implement it?

There are three main methods:

  • Using Iterator's remove() method
  • Use for loop to traverse in positive order
  • Use for loop to traverse in reverse order

Next, I will explain them one by one.

5. Use Iterator’s remove() method

The implementation of the remove() method using Iterator is as follows:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("Nuggets");
 
    Iterator<String> iterator = platformList.iterator();
    while (iterator.hasNext()) {
        String platform = iterator.next();
        if (platform.equals("博客园")) {
            iterator.remove();
        }
    }
 
    System.out.println(platformList);
}

The output is:

[CSDN, Nuggets]

Why can we use iterator.remove()? Let's look at its source code:

Like function: use MySQL or Redis?

It can be seen that each time an element is deleted, the value of modCount is reassigned to expectedModCount, so that the two variables are equal and will not trigger
java.util.ConcurrentModificationException. For more interview questions, please follow the official account Java Interview Questions Selection

6. Use for loop to traverse in positive order

The implementation of forward traversal using a for loop is as follows:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("Nuggets");
 
    for (int i = 0; i < platformList.size(); i++) {
        String item = platformList.get(i);
 
        if (item.equals("博客园")) {
            platformList.remove(i);
            i = i - 1;
        }
    }
 
    System.out.println(platformList);
}

This implementation is relatively easy to understand, that is, to delete by array subscript, but there is a note that after deleting the element, the subscript value must be corrected:

i = i - 1;

Why do we need to correct the value of the subscript? Because the initial element subscript is like this:

Like function: use MySQL or Redis?

After deleting the element "博客园" in the first loop, the subscript of the element becomes as follows:

Like function: use MySQL or Redis?

In the second loop, the value of i is 1, which means that the element "Nuggets" is taken, which causes the element "CSDN" to be skipped. Therefore, after deleting the element, we need to correct the subscript, which is also the purpose of i = i - 1; in the above code. For more interview questions, you can follow the WeChat subscription number Jiangjiji and reply to the interview to get

7. Use for loop to traverse in reverse order

The implementation of reverse traversal using a for loop is as follows:

public static void main(String[] args) {
    List<String> platformList = new ArrayList<>();
    platformList.add("博客园");
    platformList.add("CSDN");
    platformList.add("Nuggets");
 
    for (int i = platformList.size() - 1; i >= 0; i--) {
        String item = platformList.get(i);
 
        if (item.equals("Nuggets")) {
            platformList.remove(i);
        }
    }
 
    System.out.println(platformList);
}

This implementation is similar to using a for loop to traverse in forward order, but there is no need to correct the subscripts because the subscripts of the elements at the beginning are like this:

Like function: use MySQL or Redis?

After deleting the element "Nuggets" in the first loop, the subscripts of the elements become as follows:

Like function: use MySQL or Redis?

In the second loop, the value of i is 1, which means that the element "CSDN" is obtained, which will not cause the element to be skipped, so there is no need to correct the subscript.

This is the end of this article about whether to use MySQL or Redis for the like function. For more relevant MySQL\Redis like content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • An example of using thinkphp5 to operate redis to implement article popularity ranking and likes ranking
  • Detailed code for using Redis to implement likes and cancel likes
  • Sample code for using Redis cache to implement likes and unlikes
  • Springboot + redis implements the increase and decrease operations of the number of likes, views, favorites, comments, etc.
  • Detailed explanation of the design ideas of the like function based on redis
  • Teach you step by step how to use Redis to implement the like function and synchronize with the database

<<:  Core skills that web front-end development engineers need to master

>>:  The most common declaration merge in TS (interface merge)

Recommend

Native js implementation of magnifying glass component

This article example shares the specific code for...

Detailed explanation of binary and varbinary data types in MySQL

Preface BINARY and VARBINARY are somewhat similar...

How to solve the problem of automatic package update in Debian system

I don't know when it started, but every time ...

jQuery implements time selector

This article example shares the specific code of ...

WeChat applet implements a simple calculator

A simple calculator written in WeChat applet for ...

Detailed explanation of mysql replication tool based on python

Table of contents 1. Introduction Second practice...

Vue implements infinite loading waterfall flow

This article example shares the specific code of ...

Vue uses canvas to realize image compression upload

This article shares the specific code of Vue usin...

Vue project realizes login and registration effect

This article example shares the specific code of ...

MySQL 8.0 can now handle JSON

Table of contents 1. Brief Overview 2. JSON basic...

How to modify the scroll bar style in Vue

Table of contents First of all, you need to know ...

WeChat applet picker multi-column selector (mode = multiSelector)

Table of contents 1. Effect diagram (multiple col...

Detailed explanation of setting up DNS server in Linux

1. DNS server concept Communication on the Intern...

Getting the creation time of a file under Linux and a practical tutorial

background Sometimes we need to get the creation ...

How to realize vertical arrangement of text using CSS3

In a recent project, I wanted to align text verti...