0%

所有DML操作(INSERT/UPDATE/DELETE)都先在Buffer Pool中完成

redo log

视频讲解 Alt text

  1. 实现事务的持久性。redo log先刷盘,脏页再刷盘

物理存储特性

  1. 文件结构

Zset

压缩列表

当元素数量 ≤ zset-max-ziplist-entries(默认128)且所有元素长度 ≤ zset-max-ziplist-value(默认64字节)时使用,内存紧凑。

存储引擎对比

  1. InnoDB中主键索引和数据放在一起,主键索引的B+树里放完整的数据行;MyISAM中索引和数据分开放,B树里存索引值和该行的物理地址
  2. InnoDB 支持 ACID 事务,MyISAM 不支持
  3. InnoDB支持行级锁,MyISAM 不支持

什么是页分裂

当向已满的索引页(通常是16KB)插入新数据时,存储引擎会将当前页分裂成两个页,以容纳新数据

面经

2025.03.19 小红书日常一面

  1. IO和NIO的区别
  2. JVM内存模型,堆里面具体有哪些东西
  3. 手写监听者模式/单例模式
  4. ThreadLocal实现原理,并发安全吗,map里面放什么东西,内存泄露如何排查
  5. get请求里面放什么,参数如何区分
  6. 讲一下泛型,泛型类的字节码文件是怎样的。
  7. Spring 注解,RequestBody什么用处
  8. ArrayList如何扩容
  9. 虚拟机栈有多大?一个栈帧有多大?
  10. SQL的UPDATE语句的准确写法

2025.03.20 SAP日常二面

  1. two sum, three sum
  2. 缓存空值有问题,应选择布隆过滤器
  3. 限流
  4. Zookeeper 了解吗(因为我讲 Redisson 的时候提到了)
  5. 如果用户名+密码登录,如何保证数据安全。如何加密?RSA?
  6. 点评项目中,点赞数量太多怎么办。(大 key问题)

2025.03.20 阿里云暑期一面

  1. 前缀树:输入法提示
  2. Redis内部有锁吗
  3. 讲讲SETNX
  4. sorted set的底层实现
  5. RDB,AOF的优缺点
  6. 分布式锁
  7. 登录验证,为什么要把token存在redis里面,还有更好的方法吗?了解Oauth2吗?
  8. ThreadLocal 使用的时候需要注意什么问题?
  9. 是先拿锁,再判断库存;还是先在 lua 脚本里面判断库存,再拿锁
  10. 有对商户列表做缓存吗?如何解决按照不同的条件排序还能做到缓存?

2025.03.21 PayPal上海 full stack 暑期实习一面

  1. 合并排序数组
  2. 数字符串里面一共有多少个 palindrome

2025.03.22 月之暗面搜推实习一面

  1. 协程
  2. 讲讲go reduce这个项目的细节
  3. 手写单例模式,除了双重检验锁,还有什么别的方法可以实现吗?懒汉/饿汉。为什么加 volatile,禁止指令重排序,开辟空间,(实例化,分配给该对象)。
  4. Redis的数据结构,为什么不用string而是用hash,我说少一步序列化操作

2025.03.24 SAP日常二面

  1. 为什么用Kafka?优点;用的是Confluent Kafka吗?
  2. 讲讲对分布式锁的理解,项目代码里面如何实现?我回答MultiLock.

2025.03.25 字节暑期一面

  1. 如果某条 SQL 执行太慢,怎么排查,用过什么工具。联表查询:小表驱动大表。
  2. EXPLAIN 会出现一个表格,表格最后有一个 extra column,请介绍
  3. 方法区里面有什么?
  4. 讲一讲 G1
  5. 为什么需要四次挥手?client 最后为什么要 wait?
  6. 讲一讲建立HTTPS连接的过程
  7. 手撕 48 和 3
  8. MySQL主从复制讲一下
  9. 讲一下Spring的AOP,并且除了动态代理的实现,还有什么实现方法?ASM 字节码操作。

2025.03.26 PayPal暑期二面

  1. 手写快排
  2. 为啥要把用户信息存到ThreadLocal里面去
  3. filter和interceptor的区别
  4. interceptor 和 AOP的区别

2025.03.27 字节暑期二面

  1. 合并 k个有序数组
  2. 讲讲 redo log
  3. 讲讲MySQL锁

2025.03.27 初创团队实习

  1. 有用过AWS实现多个服务之间通信吗?

2025.04.01 淘天暑期一面

  1. 讲SpringMVC如何处理请求
  2. 联合索引最左匹配
  3. 线程池

面试准备

git

git merge:适合团队协作

将两个分支的提交历史合并,生成一个新的合并提交(merge commit),保留原始分支的完整历史(包括分叉和合并的痕迹)。 Alt text

反射

反射是Java在运行时动态获取类的信息(如类名、方法、属性、构造方法等)并操作类的能力

API

获取Class对象

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");

通过反射创建对象

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);

获取字段

getDeclaredField(“字段名”)

全局锁

一般在做全库备份的时候用到。会阻塞写操作,只允许读请求。因此一般选在业务低峰期去做全库备份。

1
flush tables with read lock

表级锁

表锁

  1. 表共享读锁。多个线程能同时获取这个锁,获取锁的线程可以读这个表,但不能写这个表。MyISAM 处理读请求时,会获取该表的表共享读锁。而 InnoDB 默认是行锁,通过 MVCC 来处理读请求。
  2. 表独占写锁。只有一个线程能获取这个锁,它可以对表进行写操作。其它任何线程都不可以读这张表。
1
lock tables t_student read;

触发表锁:ALTER/DROP/TRUNCATE TABLE

主从复制

主要优点:数据备份、读写分离,通常和哨兵模式结合使用。 Alt text 主服务器负责读写请求,从服务器默认只负责读请求
主节点在执行完写请求之后,将写命令同步到从节点,然后从节点再执行这条命令,保证和主节点的数据一致。

闭区间写法

找该数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution:
    # 标准的二分搜索框架,搜索目标元素的索引,若不存在则返回 -1
    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

找左边界

 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

左闭右开

找左边界

 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

如果 target 不存在,搜索左侧边界的二分搜索返回的索引是大于 target 的最小索引。

Alt text

短信验证码登录

  1. 登录界面输入手机号,然后点获取验证码。此时后端首先校验手机号格式是否正确,接着生成一个验证码。把手机号和对应的验证码存入 Redis,设置过期时间为 2 分钟。
  2. 登录界面填写验证码,然后点击登录。此时后端对比传过来的手机号和验证码。如果一致,则进行下一步。
  3. 如果该用户不存在,则创建用户并且保存用户到数据库。
  4. 随机生成token,作为登录令牌;并将 User 对象转成 Hash,以 token 为 key,以 hash为 value,存入 Redis。

校验登录状态

  1. 前端携带的请求会带有 token,所有请求都会被RefreshTokenInterceptor拦截。如果没有token直接放行
  2. 首先获取请求头中的 token,然后基于token获取redis中存储的用户(一个 Map对象)。
  3. 如果用户存在,则将Map对象转换为UserDTO,并且把它存储在ThreadLocal中,并且刷新 token 的有效期。

第二个Interceptor:除了指定的(不需要用户登陆的)路径之外,其它请求路径都会被 LoginInterceptor 拦截,如果此时没有登录,(UserHolder里为空—),则无法处理请求。

图题单

网格图题单

DFS

找连通块、判断是否有环

261. 以图判树

无向图,判断是否无环并且联通

用vis[i]=True判断即可。但是由于是无向图,在遍历邻居的时候要跳过父节点,所以需要作为参数被传递