后端面试高频问题
作者:admin | 分类:随笔 | 浏览:128 | 日期:2025年04月19日
以下是整理后的 **PHP后端面试高频问题(20题)**,采用清晰的层级结构和列表格式,方便复制查看:
### **一、数据库相关**
1. **聚簇索引与非聚簇索引的原理和区别?**
- **原理**:
- 聚簇索引:数据存储与索引键绑定(如InnoDB的主键索引),索引结构包含完整数据行。
- 非聚簇索引:索引单独存储,索引键指向数据行的物理地址(如InnoDB的普通索引)。
- **区别**:聚簇索引查询效率更高(直接取数据),非聚簇索引可能需回表;一张表只能有一个聚簇索引。
2. **索引如何提高查询效率?索引失效的场景有哪些?**
- **原理**:通过数据结构(如B+树)快速定位数据,减少磁盘I/O。
- **失效场景**:
- 条件中使用函数或表达式(如`WHERE age+1=20`)。
- 模糊查询左匹配(如`LIKE '%abc'`)。
- 字段类型隐式转换(如`WHERE id='123'`且`id`为数值型)。
3. **Hash索引与B+树索引的区别?**
- **Hash索引**:适合等值查询(O(1)复杂度),不支持范围查询,存在哈希冲突。
- **B+树索引**:支持范围查询(有序结构),查询效率稳定,适用于大多数场景。
4. **如何分析MySQL慢查询?Explain输出重点看哪些字段?Rows如何计算?**
- **慢查询分析**:开启慢查询日志,用`EXPLAIN`分析执行计划。
- **Explain重点字段**:
- `type`(连接类型,最优为`const`/`eq_ref`)。
- `key`(实际使用的索引)。
- `rows`(预估扫描行数,越小越好)。
- **Rows计算**:根据统计信息(如索引基数)估算,非精确值。
5. **MySQL的B+树如何存储数据?最左前缀原则是什么?**
- **存储方式**:叶子节点存储数据行,非叶子节点仅存储索引键和指针,形成有序树结构。
- **最左前缀原则**:复合索引按索引列顺序匹配,查询条件需包含索引的最左列(如索引`(a,b,c)`支持`a`、`a+b`、`a+b+c`查询)。
### **二、缓存与消息队列**
6. **Redis的使用场景有哪些?高性能体现在哪些方面?**
- **场景**:缓存热点数据、分布式锁、计数器、消息队列(List/Stream)等。
- **高性能原因**:
- 单线程+多路复用(处理高并发IO)。
- 内存存储(响应速度纳秒级)。
- 批量操作(Pipeline)减少网络延迟。
7. **Redis分布式锁的原理是什么?有哪些注意事项?**
- **原理**:通过`SET key value NX PX timeout`命令实现原子加锁,释放时验证`value`避免误删。
- **注意事项**:
- 锁过期时间需大于业务执行时间(防止锁提前释放)。
- 集群模式下需考虑主从同步延迟(如RedLock算法)。
8. **缓存雪崩、穿透、击穿的解决方案?**
- **雪崩**:设置不同过期时间、加互斥锁、熔断降级。
- **穿透**:布隆过滤器拦截无效请求、空值缓存。
- **击穿**:热点数据永不过期、加互斥锁。
9. **对比Kafka与RabbitMQ的特点和适用场景?**
- **Kafka**:高吞吐量、分布式流处理,适合日志收集、实时分析。
- **RabbitMQ**:支持复杂路由(如主题模式)、可靠性强,适合企业级消息队列。
10. **Kafka消费速度慢如何优化?积压消息怎么处理?**
- **优化方法**:
- 增加消费者线程数(对应Kafka分区数)。
- 批量拉取消息(增大`fetch.max.bytes`)。
- **积压处理**:
- 新建Topic重新消费(复制数据)。
- 临时增加消费者实例并行消费。
### **三、并发与性能优化**
11. **线程池的核心参数有哪些?执行流程是怎样的?**
- **核心参数**:
- `corePoolSize`(核心线程数)、`maximumPoolSize`(最大线程数)、`keepAliveTime`(空闲线程存活时间)。
- **执行流程**:
1. 任务提交,优先创建核心线程处理。
2. 核心线程满则存入队列(如`BlockingQueue`)。
3. 队列满则创建非核心线程,直至达到最大线程数。
4. 仍无法处理则触发拒绝策略(如`AbortPolicy`)。
12. **synchronized与ReentrantLock的区别?**
- **锁机制**:
- `synchronized`:JVM内置锁,自动释放(基于进入/退出Monitor)。
- `ReentrantLock`:API层面锁,需手动释放(`lock()`/`unlock()`)。
- **特性**:
- `ReentrantLock`支持公平锁、可中断锁、多个条件变量(`Condition`)。
13. **如何定位线上慢查询?Explain的`type`字段取值含义?**
- **定位步骤**:
1. 开启慢查询日志(`slow_query_log=ON`)。
2. 用`EXPLAIN`分析SQL执行计划,查看`type`是否为低效类型(如`ALL`全表扫描)。
- **`type`值优先级**:`system > const > eq_ref > ref > range > index > ALL`。
14. **压测关注哪些指标?如何用JMeter进行压测?**
- **核心指标**:
- QPS(每秒请求数)、TPS(事务处理量)、响应时间(95%/99%分位值)、错误率。
- **JMeter操作**:
- 添加线程组(模拟用户并发)。
- 配置HTTP请求(URL、参数、Headers)。
- 监听聚合报告(`Summary Report`)和图形结果。
### **四、综合场景与架构**
15. **订单流程设计:主表字段、子订单关系、库存扣减方式?**
- **主表字段**:订单ID、用户ID、总金额、创建时间、状态(待支付/已支付等)。
- **子订单关系**:主表与子表通过订单ID关联(一对多,记录商品详情)。
- **库存扣减**:
- 高并发场景用Redis预扣(异步回写数据库)。
- 普通场景直接操作数据库(需加锁防超卖)。
16. **分布式事务的解决方案有哪些?如何处理回滚?**
- **框架**:Seata(AT模式)、TCC(Try-Confirm-Cancel)、事务消息(如RocketMQ)。
- **回滚机制**:
- 基于全局事务ID,协调各服务执行反向操作(如订单回滚则库存回退)。
17. **MySQL引擎对比:InnoDB与MyISAM的区别?**
- **InnoDB**:支持事务、行级锁、外键,适合OLTP(联机事务处理)。
- **MyISAM**:不支持事务、表级锁,查询性能高,适合只读场景。
18. **MVCC能否解决幻读?InnoDB如何处理幻读?**
- **MVCC作用**:解决不可重复读,**无法直接解决幻读**。
- **InnoDB方案**:通过`REPEATABLE READ`隔离级别+间隙锁(Gap Lock),锁定查询范围防止新数据插入。
19. **Redis内存淘汰策略有哪些?如何实现冷热数据分离?**
- **淘汰策略**:
- LRU(最近最少使用)、LFU(最少频率使用)、TTL(过期时间优先)。
- **冷热分离**:
- 热数据:设置短TTL或永不过期,存储在Redis内存。
- 冷数据:持久化到数据库或分布式存储(如HBase)。
20. **分布式锁的Key如何设计?如何避免锁失效?**
- **Key设计**:`{业务场景}:{资源ID}`(如`order:123`),保证唯一性。
- **防失效**:
- 锁值使用UUID标识请求,释放时校验(避免误删其他请求的锁)。
- 延长锁过期时间(如通过Redisson的看门狗机制自动续期)。
如需进一步补充细节或调整格式,请随时告知!
