orion_intervew

后端面试题

🟢 一、NestJS

Q1: NestJS 依赖注入(DI)如何实现?相比 Express 有什么优势?

参考答案要点: - 基于 TypeScript 的 reflect-metadata 实现 IOC 容器 - 通过 @Injectable() 装饰器注册 provider,自动管理实例生命周期 - 优势:解耦业务逻辑,利于测试和模块化,天然支持 TypeScript

Q2: Guard、Interceptor、Middleware、Pipe、Filter 的区别和适用场景?

参考答案要点: | 组件 | 执行时机 | 适用场景 | |------|----------|----------| | Middleware | 路由前 | 日志、CORS、请求解析 | | Pipe | 路由处理前 | 参数验证、数据转换 | | Guard | 路由处理前(Pipe 之后) | 权限校验、认证 | | Interceptor | 路由调用前后 | 响应格式化、缓存、超时控制 | | Filter(Exception Filter) | 异常捕获时 | 全局异常处理、错误格式化 |

Q3: NestJS 全局异常处理方案?

参考答案要点: - @Catch() 自定义异常过滤器 - APP_FILTER 注册全局过滤器 - 统一错误响应格式(HTTP 状态码 + 业务错误码 + 消息) - 生产环境隐藏堆栈信息

Q4: NestJS 模块化设计最佳实践?

参考答案要点: - 按业务领域拆分模块(UserModule、OrderModule 等) - forRoot() / forFeature() 动态模块模式 - 共享模块(SharedModule)封装通用组件 - 使用 @nestjs/config 管理环境变量 - 依赖注入层次清晰,避免循环依赖


🟢 二、Node.js 运行时

Q1: Event Loop 机制?v11 前后差异?阻塞场景及解决方案?

参考答案要点: - 六个阶段:Timers → Pending → Idle/Prepare → Poll(I/O)→ Check → Close - 执行优先级process.nextTick > Promise.then > setTimeout > setImmediate - v11 差异:v11 前每阶段结束后执行微任务;v11+ 每宏任务后执行微任务(与浏览器对齐) - 阻塞场景:同步大计算、fs.readFileSync、复杂 JSON.stringify、正则回溯 - 解决方案:Worker Threads(CPU 密集型)、Stream(大文件)、子进程

Q2: 内存泄漏定位与修复?

参考答案要点: - 常见原因:全局变量、闭包引用、缓存无限制、事件监听器未解绑、Stream 未关闭 - 定位工具heapdump、Chrome DevTools Memory、clinic.js - 修复:WeakMap、LRU 缓存、事件解绑、Stream 正确处理

Q3: 高并发服务设计?

参考答案要点: - 集群模式(cluster / PM2)利用多核 - 连接池(数据库、Redis) - 多级缓存(本地 + Redis) - 限流降级(express-rate-limit / Opossum) - 异步日志(pino / winston)


🟢 三、Koa2

Q1: Koa2 中间件洋葱模型原理?

参考答案要点: - 基于 async/await + compose 函数实现 - 请求从外层进入中间件链,经过所有中间件后从外层返回 - await next() 之前是请求处理阶段,之后是响应处理阶段 - 与 Express 的线性模型不同,Koa2 中间件可以感知响应

Q2: Koa2 vs Express 对比?

参考答案要点: | 维度 | Koa2 | Express | |------|------|---------| | 异步模型 | async/await | callback | | 中间件模型 | 洋葱模型 | 线性模型 | | 内置功能 | 极简(仅核心) | 丰富(路由、模板等) | | 错误处理 | try/catch | 中间件捕获 | | 适用场景 | 需要精细控制的场景 | 快速开发、传统项目 |

Q3: Koa2 错误处理最佳实践?

参考答案要点: - 全局 error 事件监听 - 中间件层 try/catch 统一捕获 - 自定义错误类(HttpError)区分业务/系统错误 - 结构化日志记录


🟢 四、MongoDB

Q1: MongoDB 与关系型数据库相比,适合什么场景?

参考答案要点: - 适合:文档型数据、快速迭代、非结构化/半结构化数据、横向扩展 - 不适合:复杂事务、强一致性要求、多表 JOIN 频繁

Q2: MongoDB 地理位置搜索如何实现?

参考答案要点: - 2dsphere 索引支持 GeoJSON 格式 - $near / $geoWithin / $geoIntersects 查询 - 按范围(如地铁口 N 公里内)、多边形区域搜索

Q3: 多条件检索性能优化?

参考答案要点: - 复合索引(价格区间 + 标签 + 面积) - 覆盖查询(投影所需字段,避免全文档返回) - 聚合管道优化($match 前置、$project 精简)


🟢 五、Redis

Q1: Redis 常见数据结构及使用场景?

参考答案要点: | 数据结构 | 场景 | |----------|------| | String | 缓存 token / 计数 / 分布式锁 | | Hash | 用户对象 / 商品详情 | | List | 消息队列 / 最近浏览 | | Set | 去重 / 共同关注 | | SortedSet | 排行榜 / 延迟队列 | | Bitmap | 签到统计 / 在线状态 | | HyperLogLog | UV 统计 |

Q2: Redis 缓存过期策略?

参考答案要点: - 惰性删除:访问时检查过期,CPU 友好但可能内存泄漏 - 定期删除:每 100ms 随机抽查 20 个 Key,过期 Key 占比 > 25% 则重复 - 内存淘汰:volatile-lru / allkeys-lru / volatile-ttl 等策略 - 持久化关联:RDB 过滤过期 Key,AOF 追加 DEL 命令 - 最佳实践:差异化过期时间、加随机偏移防雪崩、避免永不过期 Key

Q3: Redis 分布式锁实现?

参考答案要点: - 基础:SET key value NX EX seconds - 进阶:RedLock 算法(多 Redis 实例) - 注意事项:锁续期(看门狗)、死锁预防、锁释放原子性(Lua 脚本)

Q4: Redis 优化 RAG 检索或 LLM 请求性能?

参考答案要点: - 缓存高频查询的 Embedding 结果 - 缓存 LLM 回复(相同 prompt 直接返回) - 会话状态管理(用户上下文、对话历史)


🟢 六、Elasticsearch

Q1: ES 核心概念?倒排索引原理?

参考答案要点: - 核心概念:Index(索引)→ Type(类型,7.x 废弃)→ Document(文档)→ Field(字段) - 倒排索引:将文档分词后建立"词项→文档ID"的映射,支持快速全文检索 - Analyzer:分词器(标准分词、IK 中文分词、自定义分词)

Q2: ES 查询优化?

参考答案要点: - 优先使用 Filter(缓存结果)而非 Query - 避免深度分页(使用 search_after / scroll) - 合理设置分片和副本数量 - 使用 _source 过滤返回字段 - 批量写入(Bulk API)替代单条写入

Q3: ES 在业务中的应用场景?

参考答案要点: - 全文搜索(商品搜索、文档检索) - 日志分析(ELK Stack) - 聚合统计(用户行为分析、销售数据报表) - 地理位置搜索(附近的人/房源)


🟢 七、RabbitMQ

Q1: RabbitMQ 核心概念?消息模型?

参考答案要点: - 核心概念:Producer → Exchange → Queue → Consumer - Exchange 类型:Direct(精确路由)、Fanout(广播)、Topic(模式匹配)、Headers - 消息确认:Publisher Confirm(发布确认)、Consumer Ack(消费确认)

Q2: 消息可靠性保证?

参考答案要点: - 生产者端:Publisher Confirm + Return 机制 - MQ 端:消息持久化(Exchange + Queue + Message 都声明为 durable) - 消费者端:手动 Ack(处理成功后确认),失败重试 + 死信队列 - 幂等性:消息 ID 去重、业务唯一标识

Q3: 常见应用场景?

参考答案要点: - 异步解耦(订单创建 → 发邮件/发短信) - 流量削峰(秒杀、批量导入) - 任务队列(异步处理耗时任务) - 事件驱动(微服务间事件通知)


🟢 八、MySQL

Q1: 索引原理?B+ 树 vs Hash 索引?

参考答案要点: - B+ 树:范围查询友好,支持排序,叶子节点链表连接,InnoDB 默认索引 - Hash 索引:等值查询 O(1),不支持范围/排序,Memory 引擎使用 - 聚集索引(主键):叶子节点存储完整行数据 - 二级索引:叶子节点存储主键值,需要回表

Q2: 事务隔离级别?MVCC 原理?

参考答案要点: | 隔离级别 | 脏读 | 不可重复读 | 幻读 | |----------|------|-----------|------| | Read Uncommitted | ✅ | ✅ | ✅ | | Read Committed | ❌ | ✅ | ✅ | | Repeatable Read | ❌ | ❌ | ✅(InnoDB 通过 MVCC + Gap Lock 解决) | | Serializable | ❌ | ❌ | ❌ |

Q3: SQL 优化思路?

参考答案要点: - EXPLAIN 分析执行计划(type、key、rows、Extra) - 避免全表扫描(加索引、避免 SELECT *) - 避免索引失效(函数、隐式转换、前缀通配符 %) - 分页优化(延迟 JOIN、游标分页) - 慢查询日志定位瓶颈


🟢 九、MQTT

Q1: MQTT 协议核心概念?

参考答案要点: - 发布/订阅模型:Publisher → Broker → Subscriber - QoS 级别: - QoS 0:最多一次(不保证送达) - QoS 1:至少一次(保证送达,可能重复) - QoS 2:恰好一次(保证送达且不重复) - 保留消息(Retained):新订阅者立即收到最后一条消息 - 遗嘱消息(Last Will):客户端异常断开时自动发布

Q2: MQTT 在 IoT / 实时通信中的应用?

参考答案要点: - IoT 设备状态上报与控制 - 实时消息推送(比 WebSocket 更轻量) - 边缘计算与云端通信 - 智能家居、车联网场景


🟢 十、事务

Q1: 本地事务 vs 分布式事务?

参考答案要点: - 本地事务:单数据库 ACID 保证,BEGIN → COMMIT/ROLLBACK - 分布式事务:跨服务/跨数据库,一致性保证困难

Q2: 分布式事务方案?

参考答案要点: | 方案 | 原理 | 适用场景 | |------|------|----------| | 2PC(两阶段提交) | 协调者 + 参与者,prepare → commit | 强一致性,性能差 | | TCC | Try → Confirm → Cancel,业务层面补偿 | 高可用,开发成本高 | | 本地消息表 | 业务 + 消息同事务写入,异步发送 | 最终一致性 | | Saga | 长事务拆分为子事务,失败时反向补偿 | 微服务场景 | | 可靠消息最终一致性 | MQ 保证消息必达,消费者幂等处理 | 异步解耦场景 |

Q3: 补偿机制设计?

参考答案要点: - 正向操作与补偿操作成对设计 - 补偿接口幂等性保证 - 补偿失败重试 + 告警 - 人工介入兜底


🟢 十一、幂等

Q1: 什么是幂等?为什么需要幂等?

参考答案要点: - 定义:同一操作执行多次与执行一次效果相同 - 场景:网络重试、前端重复提交、消息重复消费、定时任务重复执行

Q2: 幂等实现方案?

参考答案要点: | 方案 | 原理 | 适用场景 | |------|------|----------| | 唯一索引 | 数据库约束,重复插入报错 | 插入操作 | | Token 机制 | 提交前获取一次性 Token,验证后删除 | 表单提交 | | 状态机 | 基于状态变更判断(仅允许特定状态转换) | 订单状态更新 | | 乐观锁 | 版本号 / 时间戳控制 | 更新操作 | | Redis 去重 | SETNX + 过期时间,请求 ID 去重 | 分布式场景 | | 业务唯一标识 | 订单号、流水号等天然幂等键 | 支付、退款 |


🟢 十二、编程思想

详细设计模式表格已移至独立文档,以下为核心考察点。

Q1: 创建型模式(单例、工厂、建造者)

Q2: 结构型模式(适配器、装饰器、代理、外观)

Q3: 行为型模式(观察者、策略、责任链、模板方法)

Q4: SOLID 原则?

参考答案要点: - S 单一职责:一个类只做一件事 - O 开闭原则:对扩展开放,对修改关闭 - L 里氏替换:子类可替换父类 - I 接口隔离:接口尽量小而专一 - D 依赖倒置:依赖抽象而非具体实现


🟢 十三、文件处理

Q1: Node.js 文件流(Stream)?

参考答案要点: - 四种类型:Readable、Writable、Duplex、Transform - 管道操作:readable.pipe(writable) 自动处理背压 - 优势:处理大文件时内存占用恒定(vs 全量读取)

Q2: 文件上传方案?

参考答案要点: - 小文件:直接上传(multipart/form-data) - 大文件:分片上传 + 断点续传(MD5 校验 + 分片编号) - 存储:本地磁盘 → 对象存储(OSS/S3)→ CDN 加速 - 安全:文件类型校验(Magic Number,非仅扩展名)、大小限制、病毒扫描

Q3: 文件下载优化?

参考答案要点: - 流式下载(避免全量加载到内存) - Range 请求支持(断点续传) - 压缩传输(gzip/brotli)


🟢 十四、Docker

Q1: Docker 核心概念?

参考答案要点: - 镜像(Image):只读模板,分层存储 - 容器(Container):镜像的运行实例 - 仓库(Registry):镜像存储和分发中心 - Dockerfile:镜像构建脚本 - Volume:数据持久化 - Network:容器间通信(bridge / host / overlay)

Q2: Docker 最佳实践?

参考答案要点: - 多阶段构建减小镜像体积 - 非 root 用户运行容器 - .dockerignore 排除不必要文件 - 健康检查(HEALTHCHECK) - 资源限制(--memory, --cpus) - 日志驱动(json-file / syslog / fluentd)

Q3: Docker Compose vs Kubernetes?

参考答案要点: - Docker Compose:单机编排,适合开发和测试 - Kubernetes:集群编排,自动扩缩容、服务发现、负载均衡、自愈,适合生产


🟢 十五、CI/CD

Q1: CI/CD 流程设计?

参考答案要点: - CI(持续集成):代码提交 → 自动构建 → 单元测试 → 代码扫描 → 合并 - CD(持续交付/部署):构建产物 → 测试环境 → 自动化测试 → 生产环境 - 工具链:GitHub Actions / GitLab CI / Jenkins

Q2: 部署策略?

参考答案要点: | 策略 | 说明 | 适用场景 | |------|------|----------| | 蓝绿部署 | 两套环境交替切换 | 低风险、资源充足 | | 滚动更新 | 逐台替换,逐步放量 | 生产环境常用 | | 金丝雀发布 | 小流量验证 → 逐步扩大 | 高风险变更 | | 功能开关(Feature Flag) | 代码部署但功能未激活 | 灰度验证 |

Q3: 构建优化?

参考答案要点: - 缓存依赖(node_modules 缓存) - 并行构建(多 Job 并行) - 按需构建(仅变更模块触发构建) - 增量构建


🟢 十六、Python / Flask / FastAPI

Q1: Flask vs FastAPI 对比?

参考答案要点: | 维度 | Flask | FastAPI | |------|-------|---------| | 异步支持 | 原生不支持(需第三方) | 原生 async/await | | 类型检查 | 无 | 基于 Pydantic 自动校验 | | 文档 | 需手动配置 | 自动生成 OpenAPI/Swagger | | 性能 | 一般 | 高(Starlette + Uvicorn) | | 适用场景 | 简单 API、原型开发 | 高性能 API、ML 服务 |

Q2: Python 异步编程?

参考答案要点: - asyncio 事件循环 + async/await - aiohttp 异步 HTTP 请求 - GIL(全局解释器锁)限制:CPU 密集型用多进程,I/O 密集型用异步

Q3: Flask/FastAPI 中间件 / 依赖注入?

参考答案要点: - Flask:before_request / after_request 钩子 - FastAPI:Depends() 依赖注入,支持嵌套和全局依赖


🟢 十七、自动化高阶爬虫

Q1: 爬虫架构设计?

参考答案要点: - 调度器:URL 队列管理、优先级调度、去重(Bloom Filter / Redis Set) - 下载器:并发控制、代理池、请求重试 - 解析器:HTML 解析(BeautifulSoup/lxml)、动态页面渲染(Playwright/Selenium) - 存储层:结构化存储(MySQL/MongoDB)、原始数据存档

Q2: 反爬策略应对?

参考答案要点: - IP 封禁:代理池轮换 - 验证码:打码平台 / OCR 识别 / 人工标注 - 动态渲染:Headless Browser(Playwright) - 指纹检测:浏览器指纹伪装 - 请求频率:合理间隔 + 随机延迟

Q3: 分布式爬虫?

参考答案要点: - Scrapy-Redis:分布式调度 + 去重 - URL 去重:Redis Bloom Filter - 任务分配:Master-Worker 架构 - 数据汇总:消息队列 → 消费者 → 数据库

Q4: 法律与合规?

参考答案要点: - robots.txt 遵守 - 数据采集频率控制(避免影响目标服务) - 个人隐私数据不采集 - 遵守《数据安全法》和《个人信息保护法》


🟢 十八、TTS(语音合成)

Q1: TTS 技术方案?

参考答案要点: - 传统方案:拼接式(录制语音片段拼接)、参数式(HMM 生成) - 深度学习方案: - Tacotron 2 + WaveNet:端到端,质量高 - FastSpeech 2:非自回归,速度快 - VITS:端到端变分推理,质量与速度兼顾 - 开源工具:Coqui TTS、Edge TTS、PaddleSpeech - 商用 API:Azure TTS、阿里云 TTS、讯飞 TTS

Q2: TTS 优化方向?

参考答案要点: - 流式合成(首包延迟降低) - 多语言 / 方言支持 - 情感控制(喜怒哀乐语气) - SSML 标记语言(语速、停顿、音调控制)


🟢 十九、ASR(语音识别)

Q1: ASR 技术方案?

参考答案要点: - 传统方案:GMM-HMM、DNN-HMM - 端到端方案: - CTC(Connectionist Temporal Classification) - RNN-T(Transducer,流式友好) - Whisper(多语言、零样本能力强) - Paraformer(阿里达摩院,中文效果好) - 开源工具:Whisper、FunASR、Kaldi

Q2: ASR 实际应用优化?

参考答案要点: - 领域语言模型适配(专有词汇识别率提升) - 说话人识别(区分不同说话者) - 流式识别 vs 非流式识别 - 实时性优化(VAD 语音检测 → 分段识别)


🟢 二十、单元测试

Q1: 单元测试核心原则?

参考答案要点: - FIRST 原则:Fast(快速)、Independent(独立)、Repeatable(可重复)、Self-validating(自验证)、Timely(及时编写) - AAA 模式:Arrange(准备)→ Act(执行)→ Assert(断言) - 覆盖率:行覆盖率、分支覆盖率、条件覆盖率

Q2: 测试框架与工具?

参考答案要点: - Node.js:Jest(断言 + Mock + 覆盖率一体)、Vitest(Vite 生态)、Mocha + Chai + Sinon - Python:pytest、unittest - Mock:隔离外部依赖(数据库、API、文件系统) - 集成测试:Testcontainers(真实数据库容器)

Q3: TDD(测试驱动开发)流程?

参考答案要点: 1. 编写失败的测试(Red) 2. 编写最小代码使测试通过(Green) 3. 重构代码(Refactor) 4. 循环迭代


🟢 附录:Redis 缓存过期策略(完整参考)

Redis 缓存过期是控制内存占用、保证数据时效性的核心机制。采用「惰性删除 + 定期删除」结合策略:

  1. 惰性删除:访问时检查过期,CPU 友好,但大量未访问过期 Key 会占用内存
  2. 定期删除:每 100ms 随机抽查 20 个 Key,过期占比 > 25% 重复扫描
  3. 内存淘汰:volatile-lru / allkeys-lru / volatile-ttl 等策略兜底
  4. 持久化关联:RDB 过滤过期 Key,AOF 追加 DEL 命令
  5. 最佳实践:差异化过期时间 + 随机偏移防雪崩、避免永不过期 Key

Page Source