0%

Storage Engine Comparison

  1. In InnoDB, primary key index and data are stored together, with the primary key index B+ tree containing complete data rows; in MyISAM, index and data are stored separately, with the B tree storing index values and physical addresses of rows
  2. InnoDB supports ACID transactions, MyISAM does not
  3. InnoDB supports row-level locking, MyISAM does not

What is Page Split

When inserting new data into a full index page (usually 16KB), the storage engine will split the current page into two pages to accommodate the new data

Reflection

Reflection is Java’s ability to dynamically obtain class information (such as class names, methods, properties, constructors, etc.) and manipulate classes at runtime.

API

Getting Class Objects

1
2
3
4
5
6
7
String str="test";
Class<?> clazz = String.class;

String str = "test"; 
Class<?> clazz = str.getClass();

Class<?> clazz = Class.forName("java.lang.String");

Creating Objects Through Reflection

1
2
3
4
5
Class<?> clazz = Class.forName("com.example.User");
Object obj = clazz.getDeclaredConstructor().newInstance();

Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("Alice", 25);

Getting Fields

getDeclaredField(“fieldName”)

Reflection

Reflection is Java’s ability to dynamically obtain class information (such as class name, methods, fields, constructors, etc.) and manipulate classes at runtime.

API

Getting a Class Object

1
2
3
4
5
6
7
String str="test";
Class<?> clazz = String.class;

String str = "test";
Class<?> clazz = str.getClass();

Class<?> clazz = Class.forName("java.lang.String");

Creating Objects via Reflection

1
2
3
4
5
Class<?> clazz = Class.forName("com.example.User");
Object obj = clazz.getDeclaredConstructor().newInstance();

Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("Alice", 25);

Getting Fields

getDeclaredField("fieldName")

Global Lock

Generally used when doing full database backup. It blocks write operations and only allows read requests. Therefore, it’s usually chosen during business low-peak periods for full database backup.

1
flush tables with read lock

Table-Level Locks

Table Lock

  1. Table shared read lock. Multiple threads can acquire this lock simultaneously. Threads with this lock can read the table but cannot write to it. MyISAM acquires table shared read locks when processing read requests. InnoDB defaults to row locks and handles read requests through MVCC.
  2. Table exclusive write lock. Only one thread can acquire this lock and perform write operations on the table. No other threads can read this table.
1
lock tables t_student read;

Table locks are triggered by: ALTER/DROP/TRUNCATE TABLE

Global Locks

Typically used for full backups. Blocks writes and allows only reads, so usually run during off-peak.

1
flush tables with read lock

Table-Level Locks

Table Locks

  1. Shared read lock: multiple threads can read the table concurrently, but cannot write. MyISAM uses a shared read lock for reads; InnoDB prefers row locks and MVCC for reads.
  2. Exclusive write lock: only one thread can acquire it; others cannot read or write.
1
lock tables t_student read;

DDL such as ALTER/DROP/TRUNCATE triggers table locks.

Reference: Xiaolin coding

ACID Properties

  • Atomicity: implemented via undo log.
  • Consistency: ensured by the other three properties. Before and after execution, the database transitions between consistent states.
  • Isolation: MVCC/locks. One transaction’s execution should not affect others.
  • Durability: redo log. Once committed, changes are permanent even after crash.

Starting a Transaction

  • begin/start transaction marks the beginning. The transaction actually starts only when the first SELECT after this statement executes.
  • start transaction with consistent snapshot: immediately starts the transaction and takes a snapshot.

Isolation Levels

Possible anomalies: dirty read, non-repeatable read, phantom read.

https://leetcode.cn/discuss/post/3579164/ti-dan-er-fen-suan-fa-er-fen-da-an-zui-x-3rqn/

Closed Interval Approach

Find Target

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution:
    # Standard binary search framework, returns index of target element, -1 if not found
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1

        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] < target:
                left = mid + 1
            elif nums[mid] > target:
                right = mid - 1
        return -1

Find Left Boundary

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def search(self, nums: List[int], target: int) -> int:
    left = 0
    right = len(nums) - 1

    while left <= right:
        mid = left + (right - left) // 2
        if nums[mid] == target:
            right=mid-1
        elif nums[mid] < target:
            left = mid + 1
        elif nums[mid] > target:
            right = mid - 1
    return left

Left-Closed Right-Open

Find Left Boundary

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def left_bound(nums: List[int], target: int) -> int:
    left = 0
    right = len(nums)
    
    while left < right:
        mid = left + (right - left) // 2
        if nums[mid] == target:
            right = mid
        elif nums[mid] < target:
            left = mid + 1
        elif nums[mid] > target:
            right = mid

    return left

If target doesn’t exist, left-bound binary search returns index of smallest element > target.

Alt text

SMS Verification Code Login

  1. User enters phone number on login page and clicks “Get Code”. Backend validates phone format, generates a verification code, stores phone:code in Redis with 2-minute expiry.
  2. User enters code and clicks “Login”. Backend compares submitted code with stored value.
  3. If user doesn’t exist, create and save to database.
  4. Generate random token as login credential; convert User object to Hash and store as token:userHash in Redis.

Login Status Validation

  1. Requests carry token in header. RefreshTokenInterceptor intercepts all requests (passes through if no token).
  2. Extract token from header, retrieve user Map from Redis using token.
  3. If user exists, convert Map to UserDTO, store in ThreadLocal, and refresh token expiry.

LoginInterceptor intercepts all paths except specified public ones. If UserHolder is empty (not logged in), request is rejected.

Exceptions

Throwable

Alt text Throwable has two subclasses: Exception and Error

The Error class represents serious errors that are generally not recommended to be caught with catch in our programs. We can only optimize Error by optimizing code. When Error occurs, JVM generally chooses to terminate the thread.

The Exception class has two subclasses: Checked Exception and Unchecked Exception.
Checked Exception indicates that the exception will be checked at compile time. If the exception is not caught with catch or declared with throws, it won’t pass compilation. This includes IOException, ClassNotFoundException.
Unchecked Exception indicates that it won’t be checked at compile time. It includes RuntimeException and its subclasses, such as NullPointerException, ArrayIndexOutOfBoundsException, and ClassCastException that may occur during forced type conversion.

Exceptions

Throwable

Alt text Throwable has two subclasses: Exception and Error.

Error class represents serious errors, which are generally not recommended to be caught by catch in our programs. We can only optimize Errors by optimizing the code. When an Error occurs, JVM generally chooses to terminate the thread.

Exception class has two subclasses: Checked Exception and Unchecked Exception. Checked Exception means that the exception will be checked at compile time. If the exception is not caught by catch or not throws, it will not pass compilation. This includes IOException, ClassNotFoundException. Unchecked Exception means that it will not be checked at compile time. It includes RuntimeException and its subclasses, such as NullPointerException, ArrayIndexOutOfBoundsException, and ClassCastException that may occur during forced type conversion.