2021-06-29 23:45:20
飞书一面(已约二面)面经核心问题及解答要点如下:
1. MySQL事务实现及特性实现机制:MySQL通过InnoDB引擎的undo log(回滚日志)和redo log(重做日志)实现事务。
undo log:记录事务修改前的数据状态,用于回滚(保证原子性)。
redo log:记录事务修改后的数据状态,用于崩溃恢复(保证持久性)。
锁机制:通过行锁或表锁实现隔离性(如SELECT ... FOR UPDATE加排他锁)。
事务特性对应:
原子性(Atomicity):undo log回滚未提交事务。
持久性(Durability):redo log确保已提交事务的修改永久化。
隔离性(Isolation):锁机制和MVCC(多版本并发控制)实现。
一致性(Consistency):通过原子性、持久性和隔离性共同保证。
数据行实际存储在索引的叶子节点中(如InnoDB的主键索引)。
表数据按主键物理排序,一个表仅有一个聚簇索引。
叶子节点存储主键值而非数据行,需回表查询(如二级索引)。
支持多列组合索引,查询效率依赖索引覆盖情况。
消息唯一ID:消费者记录已处理消息的ID,处理前检查是否重复。
幂等设计:业务逻辑支持重复操作(如数据库唯一约束)。
生产者:确认机制(如RabbitMQ的confirm模式)。
MQ服务端:持久化存储(如Kafka的日志文件)。
消费者:手动提交偏移量(如Kafka的enable.auto.commit=false)。
随机过期时间:避免缓存集中失效。
多级缓存:本地缓存(如Caffeine) + 分布式缓存(如Redis)。
熔断机制:数据库压力过大时临时拒绝请求。
限流降级:通过Sentinel或Guava RateLimiter控制请求速率。
滑动窗口算法:维护一个时间窗口(如10分钟)内的错误次数计数器,每次错误更新计数器并检查是否超限。
Redis实现:
键:user_id:login_errors,值:错误次数。
键:user_id:lock_time,记录锁定时间(超限后设置)。
逻辑:
def check_login_limit(user_id): current_time = time.time() lock_key = f"{user_id}:lock_time" error_key = f"{user_id}:login_errors" # 检查是否被锁定 if redis.exists(lock_key): lock_time = float(redis.get(lock_key)) if current_time - lock_time < 600: # 10分钟锁定 return False else: redis.delete(lock_key) # 解锁 # 检查错误次数 errors = int(redis.get(error_key) or 0) if errors >= n: redis.setex(lock_key, 600, current_time) # 锁定10分钟 return False else: redis.incr(error_key) return True一致性(Consistency):所有节点数据一致。
可用性(Availability):每个请求都能收到响应。
分区容错性(Partition Tolerance):网络分区时系统仍能运行。
2PC(两阶段提交):协调者统一决策提交或回滚(阻塞,性能差)。
TCC(Try-Confirm-Cancel):业务层实现补偿逻辑(如扣款Try、Confirm确认、Cancel回滚)。
Saga模式:长事务拆分为多个本地事务,通过事件驱动协调(允许回滚链)。
本地消息表:事务提交后写入消息表,异步消费保证最终一致性。
ClientHello:客户端发送支持的加密套件和随机数Client Random。
ServerHello:服务端选择加密套件,发送随机数Server Random和证书。
密钥交换:
RSA:服务端用私钥加密预主密钥(Pre-Master Secret),客户端用公钥解密。
ECDHE:双方生成临时密钥对,交换公钥后计算共享密钥(更安全,支持前向保密)。
生成会话密钥:客户端和服务端基于Client Random、Server Random和Pre-Master Secret生成Master Secret,进一步派生出对称加密密钥。