# 面试题 **Repository Path**: wordpress_3/interview-question ## Basic Information - **Project Name**: 面试题 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-29 - **Last Updated**: 2026-06-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PHP后端面试精简背诵版(临场快速回忆) > 整合Redis、Nginx、MySQL、MQTT四大技术栈核心面试点,面试前快速浏览 > 推荐配合各技术详细笔记(redis.md、nginx.md、mysql.md、mqtt.md)一起复习 --- ## 一、Redis(必考) ### 基础数据结构 - **String**:缓存、计数器、分布式锁、Token、验证码、分布式ID - **List**:消息队列、任务调度(FIFO)、最新列表、聊天记录 - **Hash**:用户画像、购物车(局部字段更新,节省内存) - **Set**:去重、好友推荐、共同好友(sinter/sunion/sdiff) - **ZSet**:排行榜、延迟队列(score分数排序,权重任务) ### 过期机制 & 内存淘汰 - **expire/setex**:手动设置Key过期时间 - **TTL返回值**:-1永不过期,-2不存在,-2表示key不存在 - **淘汰策略**: - allkeys-lru:所有key中淘汰最近最少使用(生产首选) - volatile-lru:仅淘汰带过期的key - noeviction:内存满直接报错 - **LRU**:Least Recently Used,最近最少使用 - **LFU**:Least Frequently Used,最不经常使用 ### 缓存三大问题 - **穿透**:查询不存在数据,请求直打DB - 方案:空值缓存(短期)、布隆过滤器 - **击穿**:热点Key过期瞬间,高并发打垮DB - 方案:互斥锁(set nx ex)、热点永不过期 - **雪崩**:大量Key同时过期 - 方案:过期时间+随机偏移(300秒内)、集群高可用 ### 缓存一致性 - **延时双删**:先删缓存→更新DB→延时删缓存(500ms) - **问题场景**: - 先删缓存后更新DB:并发时线程B回填旧缓存 - 先更新DB后删缓存:并发时线程A回填旧缓存 ### 分布式锁(重中之重) - **四大特性**:互斥性、防死锁、防误删、原子性 - **方案对比**: - SETNX:低安全,无过期时间,易死锁(不推荐) - SET NX EX:中等安全,生产基础方案 - Lua原子释放:高安全,生产推荐(eval脚本) - Redisson:最高安全,企业级(看门狗自动续期) - **唯一标识**:UUID/雪花算法,防误删他人锁 - **看门狗**:自动续期,防业务未完锁过期 - **可重入锁**:同一线程重复获取,计数器+1 ### 三大集群模式 - **主从模式**:读写分离,分担读压力,数据备份 - **哨兵模式**:主从+监控+自动故障转移(3个哨兵奇数) - **Cluster模式**:数据分片、横向扩容、百万级QPS ### 哈希槽分片 - **槽位数量**:16384个(0-16383) - **计算公式**:`slot = CRC16(key) % 16384` - **3主3从**:每主约5461槽,每主1从负责备份 - **故障转移**:主观下线→客观下线→投票选举→晋升新主→切换复制→MOVED重定向 --- ## 二、Nginx(必考) ### 基础概念 - **Worker进程**:`worker_processes auto` 或 CPU核心数,单Worker单线程 - **epoll模型**:Linux高性能IO多路复用,事件驱动,仅监听活跃连接,支撑高并发 - **正向代理**:代理客户端,隐藏用户真实IP(爬虫翻墙、内网上网) - **反向代理**:代理服务端,隐藏后端服务器集群(项目主流部署方式) - **动静分离**:静态资源Nginx直接返回,动态请求转发后端API - **Master进程**:管理Worker进程 reload重启、热更新 ### proxy_pass 区别 - **无 /**:保留原始请求路径,如 `/api/user` 转发为 `/api/user` - **有 /**:替换路径,如 `/api/user` 转发为 `/user` ### 负载均衡(重中之重) - **轮询**:默认方式,请求按顺序逐一分发到各后端 - **weight权重**:性能不均时调整权重,用于灰度发布、A/B测试 - **ip_hash**:按客户端IP哈希,同一用户固定访问同一节点(解决Session) - **least_conn**:最少活跃连接,请求转发至当前连接数最少的节点 - **url_hash**:按URL哈希,提升后端缓存命中率(需安装插件) - **健康检查**:`max_fails` 失败次数,`fail_timeout` 隔离时长 ### 缓存 & 压缩 & 防盗链 - **proxy_cache**:多级缓存,减少后端请求,抵御突发流量 - **Gzip压缩**:压缩html/js/css/json等文本资源,图片/视频/压缩包不开 - **防盗链**:校验Referer请求头,白名单放行,其他返回403 ### SSL / HTTPS - **HTTP vs HTTPS**:HTTP明文传输端口80,HTTPS加密传输端口443 - **配置步骤**:申请证书→Nginx开启SSL模块→443端口绑定证书→80重定向HTTPS - **证书类型**:单域名、通配符(*.example.com)、EV SSL(绿色地址栏) ### 性能优化 & 限流 - **并发计算**:`worker_processes × worker_connections`,反向代理÷2 - **limit_req**:令牌桶算法,限制请求频率,防止爬虫、CC攻击 - **limit_conn**:限制同一IP并发连接数,防止单IP占满资源 - **sendfile**:零拷贝,提升文件传输效率 - **tcp_nopush**:合并数据包,减少网络帧数 ### 高可用 - **Nginx + Keepalived**:主备架构,两台Nginx共用一个VIP虚拟IP - **VRRP协议**:Virtual Router Redundancy Protocol,心跳检测 - **主备区别**:MASTER的priority数值高,BACKUP的priority数值低 - **故障场景**:主节点宕机 → VIP自动漂移 → 备份节点接管 ### 故障排查 - **403 Forbidden**:权限不足、防盗链拦截、目录无索引文件 - **404 Not Found**:资源不存在、proxy_pass转发路径错误 - **502 Bad Gateway**:后端服务宕机、端口不通、防火墙拦截 - **504 Gateway Timeout**:后端请求超时、网络延迟高、后端处理慢 ### 常用命令 - `nginx -t`:检查配置文件语法是否正确 - `nginx -s reload`:热重载配置(生产最常用,不中断服务) - `nginx -s stop`:快速停止服务 - `nginx -s quit`:优雅停止(处理完当前请求再关闭) - `nginx -v`:查看Nginx版本 --- ## 三、MySQL(必考) ### 存储引擎 - **InnoDB**(默认):支持事务、行锁、MVCC多版本并发控制、崩溃恢复 - **MyISAM**:表级锁、无事务、不支持崩溃恢复,适用于只读静态数据 - **选择建议**:业务系统必选InnoDB,只读统计表可用MyISAM ### 事务ACID - **原子性(Atomicity)**:事务中的操作要么全部成功,要么全部回滚 - **一致性(Consistency)**:事务前后数据状态保持合法和一致 - **隔离性(Isolation)**:并发事务之间互不干扰,各自独立执行 - **持久性(Durability)**:事务提交后,修改永久保存到磁盘 ### 隔离级别 - **读未提交 RU**:最低隔离,可能脏读(读取未提交数据) - **读已提交 RC**:解决脏读,互联网公司常用(Oracle默认) - **可重复读 RR(默认)**:解决脏读、不可重复读,存在幻读(MySQL默认) - **串行化 SERIALIZABLE**:完全隔离,性能最差,锁表 ### 索引(核心重点) - **B+树**:InnoDB默认索引结构,非叶子节点存储索引,叶子节点存储数据 - **主键索引**:叶子节点存储完整数据行(聚簇索引) - **普通索引**:叶子节点存储主键值,需回表查询(辅助索引) - **最左匹配**:联合索引从最左列开始匹配,跳过中间列会导致索引失效 - **回表查询**:普通索引查询需要先查主键索引再查数据 - **覆盖索引**:查询的字段全部在索引中,无需回表,性能最优 - **索引失效场景**: - 左模糊查询 `like %xxx` - 隐式类型转换(如字符串字段用数字查询) - 使用函数或运算(如 `WHERE age+1=20`) - 跳过最左列(如 `WHERE b=1` 跳过了a列) - OR连接(前面有索引也会失效) ### 锁机制 - **行锁**:锁定单行记录,并发高,需命中索引否则降级为表锁 - **表锁**:锁定整张表,并发低,MyISAM默认锁 - **悲观锁**:`SELECT ... FOR UPDATE`,适合高并发写操作 - **乐观锁**:版本号控制(version字段),适合读多写少场景 - **间隙锁**:RR级别下锁定范围,防止幻读 ### MVCC - **作用**:多版本并发控制,无锁读取,提升读写并发性能 - **实现原理**:隐藏列(DB_TRX_ID、DB_ROLL_PTR)+ undo日志 + readview - **快照读**:普通SELECT语句,无锁,读取历史版本 - **当前读**:UPDATE/DELETE/FOR UPDATE,加锁读取最新数据 - **ReadView**:可见性判断,RR级别下每个事务使用同一个视图 ### SQL优化 - **慢查询优化**:开启慢查询日志 → explain分析 → 优化索引 → 调整SQL → 架构优化 - **explain关键字段**: - type:ref>range>index>all(全表扫描最差) - key:实际使用的索引 - rows:扫描行数,越少越好 - Extra:Using filesort(需要额外排序)、Using index(覆盖索引) - **深分页优化**:`WHERE id > xxx LIMIT 10` 改用主键分页,避免 `OFFSET 100000` - **小表驱动**:小表放外层用EXISTS,大表放内层用IN - **批量插入**:INSERT INTO ... VALUES (...), (...), (...) 减少IO ### 日志与主从 - **redo log**:重做日志,崩溃恢复,事务持久化,物理日志 - **undo log**:回滚日志,事务回滚、MVCC版本链,逻辑日志 - **binlog**:二进制日志,主从复制、数据恢复(DDL/DML) - ** relay log**:中继日志,从库relay线程拉取主库binlog - **主从复制流程**:主库事务提交→写binlog→从库IO线程拉取→SQL线程重放→同步完成 ### 实战方案 - **超卖问题**:悲观锁(FOR UPDATE)、乐观锁(version)、Redis分布式锁 - **缓存一致性**:先更新数据库 → 再删除缓存(推荐) - **大表优化**:创建合适索引、避免大事务、深分页优化、读写分离、分库分表 - **分库分表**:垂直拆分(按业务)、水平拆分(按数据量),需考虑分片键 --- ## 四、MQTT(物联网方向) ### 基础概念 - **定义**:MQTT(Message Queuing Telemetry Transport),轻量级发布/订阅模式即时通讯协议 - **设计目标**:专为低带宽、弱网络、资源受限设备设计,IoT物联网首选协议 - **端口说明**: - 1883:明文TCP通信(生产推荐TLS加密) - 8883:SSL/TLS加密TCP通信 - 8083:WebSocket明文(网页端、小程序) - 8084:WSS加密WebSocket - **三大角色**: - Publisher(发布者):发送消息的客户端 - Broker(服务端):中转消息的服务器(如EMQ X、Mosquitto) - Subscriber(订阅者):接收消息的客户端 - **优缺点**: - 优点:报文体积小、流量消耗低、支持断线重连、QoS服务质量、遗嘱消息、心跳保活、会话持久化 - 缺点:不适合大文件传输、灵活性弱于HTTP、消息堆积内存压力大 ### 主题规则 - **分层符号**:`/` 用于主题层级分隔,如 `device/123/temp` - **单层通配符**:`+` 匹配单层任意值,如 `device/+/temp` 匹配 `device/001/temp`、`device/002/temp` - **多层通配符**:`#` 匹配当前层级及所有子层级,仅可用于订阅结尾,如 `device/#` 匹配 `device/123`、`device/123/temp` - **主题规范**:纯英文小写、避免中文、避免特殊字符 ### QoS服务质量(必考) - **QoS 0 最多一次**:发送一次,无需应答,可能丢包,速度最快 - 场景:温湿度传感器上报、实时性要求高、可容忍丢失 - **QoS 1 至少一次**:确保送达,可能重复(需业务方幂等处理) - 场景:普通指令下发、状态推送(业务最常用) - **QoS 2 恰好一次**:四次握手确保不丢不重,资源消耗最大 - 场景:计费数据、关键控制指令、金融交易 ### 核心特性 - **遗嘱消息 Last Will**:客户端异常断线时,Broker自动推送预设消息 - 配置:设置Will主题、Will消息、QoS、Retained标志 - 场景:设备离线告警、状态变更通知 - **保留消息 Retained**:新订阅者立即收到该主题的最后一条消息 - 场景:设备初始状态推送、配置参数下发、历史数据获取 - **心跳保活 Keep Alive**:客户端与Broker定时心跳,超时判定离线 - 建议值:10~60秒,根据网络状况调整 - 场景:检测连接有效性、及时发现断线 - **CleanSession 会话**: - true(默认):临时会话,连接断开时清空订阅关系和离线消息 - false:持久会话,离线消息保留,重连后补发(需Broker开启磁盘存储) - 场景:需要接收离线消息时设为false ### PHP开发 - **依赖安装**:`composer require php-mqtt/client` - **发布消息**:`publish(主题, 消息内容, QoS等级, 保留标志)` - **遗嘱配置**:`setWill(主题, 内容, QoS, 保留标志)` - **订阅代码**:`subscribe() + 回调函数 + loop(true)持续监听` - **持久化配置**:`CleanSession=false + QoS≥1 + Broker开启磁盘存储` - **连接参数**:设置ConnectTimeout连接超时、KeepAliveInterval保活间隔 ### 实战方案 - **断线重连**:异常捕获 + while循环 + sleep重试间隔 + 持久会话 + 心跳 - **防重复消费**:全局唯一消息ID + 业务幂等去重 + QoS2 + 消费状态记录 - **集群部署**:多台Broker集群 + 客户端随机连接 + 负载均衡 - **消息堆积**:监控队列深度 + 消费者扩容 + 过期消息清理 ### 适用场景 - **适合**:智能家居、车载设备、工业传感器、小程序消息推送、工业物联网、APP消息推送 - **不适合**:大文件传输(建议用FTP/S3)、金融交易系统(实时性要求高) --- ## 快速复习提示 ### Redis重点 - **分布式锁四种方案**:SETNX → SET NX EX → Lua原子释放 → Redisson - **缓存三大问题**:穿透(布隆过滤器)、击穿(互斥锁)、雪崩(随机过期+高可用) - **Cluster哈希槽**:16384槽,CRC16算法,3主3从架构 - **三大集群模式对比**:主从(读写分离)、哨兵(自动故障转移)、Cluster(分片) ### Nginx重点 - **负载均衡策略选择**:轮询默认、Session选ip_hash、性能选weight、缓存选url_hash - **proxy_pass斜杠区别**:有/替换路径,无/保留路径 - **limit_req/limit_conn**:req限制请求频率(令牌桶),conn限制并发连接数 - **Keepalived高可用**:VIP漂移、VRRP心跳、主备priority差异 - **故障码排查**:403权限/防盗链、404路径错、502后端挂、504超时 ### MySQL重点 - **索引最左匹配原则**:从最左列开始,跳过中间列失效 - **隔离级别与幻读**:RC解决脏读、RR解决不可重复读、存在幻读(间隙锁解决) - **MVCC原理**:undo日志版本链 + ReadView可见性判断 + 隐藏列 - **主从复制流程**:主库写binlog → 从库IO拉取 → SQL重放 → 同步完成 - **慢查询优化**:开启慢日志 → explain分析 → 优化索引 → 调整SQL ### MQTT重点 - **QoS三级区别**:0最快可能丢、1常用可能重、2保证不丢不重 - **遗嘱消息与保留消息**:遗嘱是离线自动发、保留是订阅立即收 - **CleanSession作用**:true临时会话false持久会话,决定离线消息是否保留 - **主题通配符规则**:+单层匹配、#多层匹配(仅末尾)、/层级分隔