JAVA INTERVIEW · TECHNICAL DIRECTOR EDITION

高级 Java 工程师面试题

围绕 IoT 微服务、DDD、JVM、MySQL、Redis、消息队列、分布式事务与架构治理设计。点击每道题下方的「答案解析」展开参考答案,再结合自己的真实项目经历补充细节。

50 道核心题
5 大知识模块
点击展开答案
支持打印 / 保存 PDF

一、项目经历与架构设计

重点考察架构拆分、业务建模、服务治理、稳定性与团队交付。

01
请介绍企业级 IoT 平台的整体架构。
考察:是否真正负责过架构设计与生产交付

参考回答

平台采用 Spring Cloud Alibaba 微服务架构,覆盖采购、销售、库存调拨、设备运维和实时状态监控等业务。可从五层介绍:

  1. 接入层:统一网关处理路由、身份认证、权限校验与流量控制。
  2. 业务服务层:按业务边界划分采购、库存、调拨、设备监控等服务。
  3. 中间件层:Nacos 管理注册与配置,Sentinel 进行流量治理,Seata 处理特定跨服务事务,Redis 缓存热点数据,RocketMQ 处理异步业务。
  4. 数据层:MySQL 承载结构化交易数据,MongoDB 等存储适合文档模型的数据。
  5. 运维监控层:结合容器部署、日志、监控、告警和故障预案保障稳定性。

核心不是服务数量,而是业务边界、数据归属、故障边界清晰,并控制服务间调用复杂度。

深度追问

  • 为什么拆成 20 多个服务,而不是 8 个或 10 个?
  • 哪些链路同步执行,哪些可以异步化?
  • 如何防止一个服务故障扩散?

回答提醒结合真实服务名、调用链路和部署方式,不要只罗列技术栈。

02
你们如何使用 DDD 进行微服务拆分?
考察:领域建模、限界上下文、数据所有权

参考回答

先从业务流程和业务能力识别核心领域、子领域及限界上下文,而不是按数据库表或技术功能直接拆分。明确上下文的职责、领域模型、数据所有权,再定义稳定的 API 契约或领域事件。

例如库存服务负责库存数量和库存变更规则,调拨服务负责调拨流程。调拨服务可以调用库存服务执行预留或扣减,但不应直接修改库存服务的数据库。

关键点:一个聚合根不等于一个微服务。服务边界还要考虑业务变化频率、团队职责、事务范围、部署成本和调用关系。

深度追问

库存服务和调拨服务需要同时修改数据时,如何处理一致性?为什么不直接用一个数据库事务?

03
20 多个微服务之间如何避免循环依赖和隐式耦合?
考察:服务边界与工程治理

参考回答

  • 明确每个服务的数据所有权,禁止其他服务直接操作其业务表。
  • 通过稳定 API 契约或领域事件交互,避免 A 调 B、B 又反向调 A。
  • 统一错误码、超时规范、幂等约定和版本兼容策略。
  • 在 CI 流程中加入接口契约检查与依赖检查。

如果多个服务总是一起发布、一起修改,说明边界可能不合理,需要重新评估。

04
如何设计库存调拨业务的完整流程?
考察:状态机、库存安全、异常恢复

参考回答

可将调拨设计为有明确状态和业务约束的状态机:

创建调拨单 → 库存预留 → 物流单创建 → 出库确认 → 入库确认 → 调拨完成

  1. 调拨单设置唯一业务编号,防止重复创建。
  2. 库存预留采用原子条件更新,避免并发超卖。
  3. 用状态机约束合法状态迁移,避免重复出库或入库。
  4. 跨服务调用设置超时、重试和幂等机制。
  5. 对超时或失败流程执行状态查询、重试或人工补偿。

根据一致性要求选择 Seata、可靠消息加最终一致性,或业务补偿方案。

追问

库存扣减成功但物流单创建失败,应该回滚库存还是保留预留?要结合库存模型、业务状态和恢复策略判断。

05
简历中 Seata 让交易回滚率下降 70%,你如何解释?
考察:分布式事务原理与指标可信度

参考回答

先说明原有问题、选择 Seata 的原因、实际采用的事务模式,以及如何验证改造效果。

  • AT:基于数据源代理、undo log 和全局事务协调,在相应约束下支持自动回滚。
  • TCC:通过 Try、Confirm、Cancel 三阶段,由业务代码实现预留、确认和取消。
  • Saga:通过一系列本地事务及补偿操作管理长流程。
  • XA:基于数据库 XA 能力实现两阶段提交。

选择时评估数据库支持、操作类型、事务时长、锁竞争、性能和补偿复杂度。外部 HTTP 调用通常不会因为数据库回滚而自动撤销。

“下降 70%”还必须明确统计口径、时间范围和因果依据。

06
供应商接口超时导致线程池打满,如何解决?
考察:故障止血、资源隔离与恢复

参考回答

  1. 止血:暂时限制异常供应商流量,避免故障继续扩散。
  2. 定位:查看活跃线程数、队列长度、请求耗时、超时比例和线程堆栈。
  3. 治理:配置连接超时、读取超时、并发隔离、熔断、限流和有界队列。
  4. 恢复:按业务优先级降级、异步化或切换备用供应商,并补齐告警。

Sentinel 能提供流量控制和熔断降级,但不能代替 HTTP 客户端超时,也不能解决所有线程池设计问题。

追问

为什么设置 Sentinel 熔断后,线程仍可能被打满?请求可能在进入保护代码前已占用线程,也可能阻塞在没有超时的网络调用中。还需要线程池隔离、超时和有界资源控制。

07
Nacos 管理 150 多个环境变量,如何保证配置变更安全?
考察:配置治理、权限与回滚

参考回答

区分普通业务参数、动态开关、敏感配置和基础设施参数;按环境隔离、按应用组织,统一命名、权限、版本管理和变更审计。生产重要配置应审批,支持灰度验证与回滚。

密钥、数据库密码等敏感信息应通过适当的密钥管理机制保存,避免直接暴露在普通配置文件或日志中。还需验证客户端是否收到配置、配置是否真正生效,以及发布失败时的应用行为。

08
Gateway 如何实现鉴权、灰度发布和限流?
考察:网关设计与流量治理

参考回答

  • 鉴权:校验身份凭证,并按业务要求进行权限判断。
  • 灰度:依据用户、租户、请求头或经过验证的规则路由到新版本。
  • 限流:按用户、接口、租户或服务维度限制请求速率。
  • 安全:限制请求体大小,设置超时,处理敏感头并进行访问审计。

灰度发布还要考虑同一用户请求的一致性、数据库兼容、新旧版本共存及回滚策略。

09
系统可用性 99.9% 如何实现和统计?
考察:SLA/SLO、故障预算与业务监控

参考回答

99.9% 可用性意味着约定统计周期内允许的不可用时间约为:30 天 43.2 分钟,365 天约 8.76 小时。

首先定义指标:网关成功率、核心业务成功率还是平台服务可用率;是否排除计划维护,以及如何处理部分功能不可用。技术措施包括多实例部署、健康检查、故障隔离、超时、降级、备份恢复、监控告警和应急预案。

进程存活不等于业务可用,应建立端到端业务探测。

10
带领 12 人团队,如何平衡研发速度、质量和稳定性?
考察:团队工程实践与管理

参考回答

  • 需求阶段明确范围、依赖、验收标准和风险。
  • 设计阶段评审事务、性能、安全和兼容性方案。
  • 开发阶段执行代码评审、自动化测试、契约测试和静态检查。
  • 发布阶段按风险采用灰度、监控观察和回滚预案。
  • 线上建立故障分级、根因分析和改进项跟踪。

明确模块负责人和技术决策边界,避免问题全部集中到架构负责人。除了交付数量,还要关注缺陷率、变更失败率、恢复时间和交付周期。

二、Java 核心与 JVM

关注底层原理、适用场景、生产排查方法与常见误区。

11
volatile 能保证线程安全吗?
考察:JMM、可见性、原子性

参考回答

不能笼统地说能。volatile 主要提供可见性和相应的有序性保证,但不保证复合操作的原子性。count++ 包含读取、计算、写入多个步骤,并发时可能丢失更新。可根据语义使用 synchronized、AtomicInteger、LongAdder 或锁机制。

12
synchronized 和 ReentrantLock 有什么区别?
考察:锁机制与并发控制

参考回答

synchronized 是语言内置同步机制,退出同步块时自动释放锁。ReentrantLock 是显式锁,支持可中断获取、tryLock()、公平性配置和多个 Condition。显式锁通常需要在 finally 中解锁。普通互斥场景优先选择简单安全的方案,确实需要额外能力时再使用显式锁。

13
线程池核心参数如何设置?
考察:任务类型、队列与容量控制

参考回答

主要参数包括核心线程数、最大线程数、空闲线程存活时间、工作队列、线程工厂和拒绝策略。CPU 密集型任务可从接近 CPU 核数的规模开始测试;IO 密集型任务要结合等待时间、CPU 消耗、外部服务并发限制和内存预算。使用有界队列,并监控活跃线程、排队时间、执行耗时与拒绝次数。

拒绝策略要结合任务能否丢弃、是否允许调用方执行、是否需要持久化补偿来选择。

14
如何排查 Java 服务 CPU 飙高?
考察:线上诊断工具链

参考回答

  1. 通过监控确认实例、时间点和持续时间。
  2. 用 top 找到高 CPU 进程,再用 top -H -p PID 查看高消耗线程。
  3. 用 jcmd、jstack 等采集线程信息,必要时做性能分析。
  4. 将线程 ID 转成十六进制,与线程栈的 nid 对应。
  5. 排查死循环、频繁 GC、正则回溯、锁竞争或异常重试。
  6. 修复后用监控和压力测试验证。

若 CPU 高源于频繁 GC,应结合 GC 日志和堆使用情况分析。

15
Java 内存泄漏有哪些常见原因?
考察:对象可达性与堆分析

参考回答

对象只要仍然可达,即使业务上不再使用,也可能无法回收。常见原因有静态集合持有对象、ThreadLocal 残留、监听器或回调未注销、无界缓存增长、线程池任务持有大量对象。

通过堆转储分析对象数量、保留大小和 GC Roots 引用链,找出是谁持有对象,而不只是观察堆内存是否增长。

16
G1 垃圾收集器的基本原理是什么?
考察:GC 区域组织、标记与疏散

参考回答

G1 将堆划分为多个 Region,结合并发标记和存活对象复制等机制,优先回收收益较高的区域,并尝试满足暂停时间目标。年轻代和老年代是逻辑角色,不等于固定不变的物理区域。暂停时间目标是调度目标,不是硬实时保证。

排查 Full GC 或长暂停时,应查看堆占用、分配速率、晋升情况、Humongous 对象、GC 日志及容器内存限制。

17
HashMap 为什么不是线程安全的?ConcurrentHashMap 如何解决?
考察:并发容器与原子操作

参考回答

HashMap 不为并发读写提供完整同步保证,多个线程修改可能造成数据覆盖或不符合预期的状态。现代 JDK 的 ConcurrentHashMap 使用 CAS、局部同步等机制协调并发,减少整表竞争。不同 JDK 版本实现有区别,例如 JDK 8 与早期基于 Segment 的实现不同。

线程安全容器不代表所有复合业务操作自动原子化。可根据需要使用 compute、putIfAbsent 等原子操作。

18
什么是 Java 内存模型中的 happens-before?
考察:并发可见性与有序性规则

参考回答

happens-before 定义操作之间的可见性与有序性保证。常见规则包括:同一线程内的程序顺序;volatile 写先行发生于后续相应读;监视器解锁先行发生于后续成功加锁;调用 Thread.start() 前的操作对启动线程中的相应操作可见。

它不要求物理执行必须串行,而是定义并发环境下哪些结果必须可被正确观察。

19
线上频繁 Full GC,怎么排查?
考察:GC 日志、堆分析与根因定位

参考回答

先判断 Full GC 频率、单次耗时及其对请求的影响,再查看 GC 日志和内存指标。重点检查老年代持续增长、大量对象晋升、大对象分配、内存泄漏、容器内存限制及 GC 参数是否匹配负载。

必要时采集堆转储分析保留链,使用分配分析定位大量对象来源。不能将所有 Full GC 问题都归结为堆太小。

20
接口 P99 从 100ms 上升到 2s,如何定位?
考察:长尾延迟与全链路诊断

参考回答

P99 表示 99% 的观测请求延迟不超过该值,但不能单独说明瓶颈。依次检查入口排队、线程池等待、锁竞争、GC、数据库慢查询与锁等待、连接池、Redis、消息积压及外部依赖。对比异常与正常时间段,结合 Trace、日志和线程栈定位,并通过单变量验证。

平均耗时正常而 P99 很高时,尤其要检查少量慢请求、排队和长尾依赖。

三、MySQL、Redis 与海量数据

重点准备 SQL、索引、数据规模、迁移方案与性能指标。

21
订单创建接口如何做到 200ms 以内?
考察:性能指标、SQL、事务和调用链

参考回答

先明确 200ms 是平均值、P95 还是 P99,以及统计的是单个服务还是完整链路。拆分数据库查询、事务、外部 RPC、库存校验和会员规则计算耗时。

  • 为高频查询设计合适联合索引,减少扫描和回表。
  • 避免在订单事务中执行不必要的远程调用。
  • 非核心操作可采用可靠消息异步化。
  • 缩短持锁时间,减少重复查询。
  • 合理使用缓存,但不让缓存替代交易一致性校验。
  • 用压测验证并发下的延迟分布。

单次 200ms 与高并发下 P99 小于 200ms 是两回事。

22
MySQL 联合索引为什么遵循最左前缀原则?
考察:B+ 树与索引排序

参考回答

假设索引为 (customer_id, status, create_time)。组合键按字段顺序组织,因此通常可支持从最左字段开始的查询:

  • customer_id = ?
  • customer_id = ? AND status = ?
  • customer_id = ? AND status = ? AND create_time >= ?

只查询 status = ? 通常不能直接有效利用该索引的最左前缀。最终仍需结合执行计划、数据分布和优化器判断。

23
MySQL 索引失效有哪些常见情况?
考察:执行计划与 SQL 调优

参考回答

  • 对索引列做某些函数计算或发生隐式类型转换。
  • 联合索引查询未满足适用的最左前缀条件。
  • 前置通配符模糊查询,如 LIKE '%abc'。
  • 返回数据比例过高,优化器认为全表扫描更划算。
  • 复杂 OR 条件限制索引利用。
  • 统计信息不准确,导致执行计划不理想。

使用 EXPLAIN,必要时查看实际执行情况,重点关注访问类型、候选索引、实际扫描行数和过滤比例,不要看到慢 SQL 就盲目加索引。

24
MySQL 高并发下如何避免库存超卖?
考察:原子更新与业务一致性

参考回答

使用带库存条件的原子更新:

UPDATE inventory
SET available_stock = available_stock - 1
WHERE sku_id = ?
  AND available_stock >= 1;

检查受影响行数:成功更新一行表示扣减成功,零行表示条件不满足。跨服务流程还要考虑幂等、事务一致性、预留超时释放和失败补偿。单条 SQL 的原子性不能自动保证整个业务流程一致。

25
9000 万条会员数据迁移,如何保证效率和正确性?
考察:批量迁移、增量同步与校验

参考回答

  1. 梳理新旧表结构、字段映射、类型和业务规则。
  2. 用主键或稳定业务键分批读取,避免深分页。
  3. 批量转换与写入,控制事务大小。
  4. 通过唯一约束、幂等写入或进度表支持重试。
  5. 单独处理空值、重复、格式异常记录。
  6. 分批核对数量、关键字段并抽样验证。
  7. 设计增量同步、切换窗口和回滚方案。

若旧系统仍持续写入,需要基于可靠变更日志或业务事件同步增量,并处理重复、乱序、延迟和切换前追平。

26
MySQL 大表如何优化深分页?
考察:游标分页与索引设计

参考回答

LIMIT 1000000, 20 可能需要扫描并跳过大量记录。若业务允许,可用稳定排序键进行游标分页:

SELECT id, customer_id, status
FROM orders
WHERE id > ?
ORDER BY id
LIMIT 20;

若按创建时间排序,可使用 (create_time, id) 作为稳定组合键并设计对应索引。游标分页适合连续翻页;任意跳页需要结合访问模式另行设计。

27
缓存穿透、击穿、雪崩有什么区别?
考察:缓存保护策略

参考回答

  • 穿透:查询不存在的数据,缓存无法拦截。可用参数校验、合理缓存空值、布隆过滤器。
  • 击穿:热点 Key 失效,大量请求同时访问后端。可用互斥重建、逻辑过期、热点保护。
  • 雪崩:大量 Key 同时失效或缓存整体不可用。可用 TTL 随机化、多级缓存、限流降级与容量预案。

空值缓存要考虑数据新增后的过期策略;逻辑过期会允许一定陈旧度,不适合所有交易数据。

28
Redis 缓存与 MySQL 如何保证数据一致性?
考察:缓存失效时序与补偿机制

参考回答

常见做法是以 MySQL 为权威数据源,数据库更新成功后删除缓存,让后续读取重新加载。但并发时序仍可能造成旧值回填,因此要根据业务考虑:

  • 缓存删除失败后的重试。
  • 延迟双删或基于变更事件的失效方案。
  • 缓存重建的并发控制。
  • 版本号校验,防止旧值覆盖新值。
  • 监控、定期校验与补偿。

需要先明确允许的陈旧时间,以及是否涉及库存、余额等强约束业务。

29
Redis 分布式锁有哪些坑?
考察:租约、误删与 fencing token

参考回答

可使用 SET key value NX PX ... 原子获取锁,value 使用唯一标识。释放锁时必须验证持有者,不能无条件删除。

  • 业务执行超过租约时,锁可能过期,其他线程会获得锁。
  • 网络延迟、进程暂停和重试可能导致并发执行。
  • 锁不能代替数据库唯一约束和原子更新。
  • 严格防止旧持有者写入时,可考虑资源端校验单调递增的 fencing token。

核心数据仍应尽量通过数据库约束与事务保证安全。

30
报表统计从 10 小时缩短到 30 分钟,如何优化?
考察:批处理、预聚合与资源隔离

参考回答

先分析数据量、执行计划、聚合方式、索引和实时性要求。复杂大规模聚合可考虑增量统计、预聚合表、按时间分区、交易与报表隔离、历史数据批处理及任务分片。

同时对结果抽样、汇总对账,保证准确性。盲目增加线程数可能加剧数据库 I/O 竞争,影响在线交易。

四、Spring Cloud Alibaba 与分布式系统

关注服务发现、流量治理、事务、消息可靠性与一致性。

31
Nacos 注册中心的服务发现原理是什么?
考察:注册、健康状态与故障行为

参考回答

服务提供者启动后向注册中心注册实例,消费者获取可用实例列表并结合负载均衡选择目标。需要理解临时实例与持久实例、健康状态维护、心跳或探测机制,以及注册中心不可用时的行为。

生产环境还需关注实例过期、网络分区、客户端缓存和本地实例列表更新。

32
Sentinel 的限流和熔断有什么区别?
考察:流量控制、慢调用与降级

参考回答

  • 限流:控制请求速率或并发量,防止超过承载能力。
  • 熔断:依赖出现异常或慢调用达到规则条件时,暂时限制调用。
  • 降级:非核心能力不可用时提供受限功能或替代结果。

规则需结合 QPS、并发线程数、异常比例、慢调用比例和业务优先级,通过压测确定阈值。Sentinel 不能代替所有客户端超时和资源隔离措施。

33
Seata AT 模式的工作原理是什么?
考察:undo log、全局事务与锁竞争

参考回答

AT 模式通过代理数据源拦截业务 SQL,在本地事务阶段记录前后镜像信息,并在全局事务协调下提交或回滚。典型过程是开启全局事务、分支执行本地数据库操作并记录 undo log、协调器决定提交或回滚,回滚时依据日志恢复数据并进行校验。

要关注全局锁、脏写检测、数据库与 SQL 兼容性及事务时长。跨服务事务越长,锁竞争和故障恢复复杂度通常越高。

34
Kafka、RabbitMQ、RocketMQ 如何选择?
考察:消息模型与业务需求

参考回答

  • Kafka:高吞吐、日志和流式数据场景。
  • RabbitMQ:灵活路由、队列语义和任务分发场景。
  • RocketMQ:业务消息场景,可结合版本与配置使用顺序、事务等能力。

还要评估消息顺序、重复投递、消费失败、运维复杂度和团队经验,不能只比较谁更快。

35
如何保证消息不丢失?
考察:生产者、Broker、消费者全链路可靠性

参考回答

  • 生产者:发送确认、失败重试和可靠的本地业务状态记录。
  • Broker:持久化策略、复制机制和确认语义。
  • 消费者:业务成功后确认,或通过事务和重试保证处理可靠。
  • 业务层:幂等、异常告警、死信处理和定期对账。

发送成功不代表消费者业务处理成功;重复投递也不一定意味着消息系统故障。

36
如何解决消息重复消费?
考察:幂等键、唯一约束和事务边界

参考回答

为业务事件设置唯一 ID,在消费端通过数据库唯一约束或消费记录防止重复执行。库存、订单等更新可结合条件更新、状态机和事务。

注意幂等记录生命周期与并发插入。如果先记已消费再执行业务,崩溃可能导致业务丢失;先执行业务再记录则可能重复执行。需要设计正确的事务边界或恢复机制。

37
消息积压如何排查和处理?
考察:吞吐、消费能力和下游瓶颈

参考回答

先判断是生产过快、消费能力不足,还是部分消息持续失败。观察生产与消费速率、积压量、最老消息等待时间、消费者实例数、线程池队列、单条处理耗时和下游瓶颈。

扩容前确认分区数、队列并发和下游容量允许扩展。盲目增加消费者可能导致数据库连接耗尽或下游雪崩。

38
Kafka 如何保证同一订单的消息有序?
考察:分区键与消费并发

参考回答

将同一订单的消息使用相同 Key,使其进入同一分区,再依赖分区内顺序消费。但 Kafka 不保证跨分区全局顺序;分区内异步并发处理也可能破坏业务完成顺序。增加分区数可能改变 Key 的映射,重试和失败跳过也会影响业务顺序。

可结合业务序列号、状态校验或按订单串行处理。

39
分布式系统为什么需要幂等和最终一致性?
考察:超时语义、重试和补偿

参考回答

网络超时不代表远端操作一定失败:服务端可能已扣库存,只是响应没有返回。重试可能导致重复操作,因此要使用幂等键、唯一约束和状态校验。

跨服务业务不适合单个原子事务时,可以使用本地事务加可靠消息、事务消息或 Saga 补偿实现最终一致性。必须定义业务不变量、重试策略、补偿流程和对账机制。

40
Kubernetes 与 Spring Cloud Alibaba 是什么关系?
考察:平台能力与应用治理边界

参考回答

Kubernetes 主要负责容器编排、部署、调度、健康检查、扩缩容和资源管理;Spring Cloud Alibaba 提供应用层服务治理能力,如服务发现、配置管理、流量控制和分布式事务集成。

两者可以配合使用。Kubernetes Service/DNS 与 Nacos 服务发现存在部分功能交叉,架构中应明确服务发现、网络入口和配置管理分别由谁负责。

五、项目场景与技术总监综合题

将简历中的项目成果转化为可验证的技术方案,回答时请结合真实经历。

41
日均 10 万+ 设备状态监控系统应该如何设计?
考察:设备接入、消息处理、状态存储和峰值容量

参考回答

先区分设备总量、每日活跃量、上报频率、消息大小、峰值分布和在线连接数。日均设备量不直接等于高 QPS,实际压力取决于消息频率和峰值。

可采用:设备接入 → 消息接入层 → 消息队列 → 状态处理服务 → Redis/数据库 → 告警与查询接口。接入层负责身份校验和协议适配;队列缓冲峰值;处理服务按设备 ID 或业务键分区;Redis 保存最新状态;数据库或时序存储保存历史数据。

还需处理心跳、重复上报、消息乱序、断线重连、离线判定和补传。通过事件时间、序列号和版本校验,避免旧消息覆盖新状态。

42
IoT 设备在线状态如何判断?
考察:心跳、超时与大规模调度

参考回答

结合心跳、最后一次有效消息时间和连接状态。超过离线阈值后,可先标记疑似离线,再结合连接状态或探测确认。要考虑网络抖动、设备休眠、心跳丢失和服务端延迟。

大规模场景下,可采用分片调度、时间轮、延迟消息或批量扫描,避免对每台设备进行高频独立数据库查询,并通过压测确定策略。

43
如何设计高并发设备实时状态查询接口?
考察:热点查询、缓存和批量接口保护

参考回答

如果多数请求只需要最新状态,可用 Redis 加速查询,数据库负责持久化。设计合适的 Key 和 TTL,限制批量查询数量,对热点设备和高频调用方限流,并明确缓存与持久化的一致性策略。

监控缓存命中率、接口 P99、Redis 延迟和后端查询量。高频状态写入时还要评估 Redis 写入压力、过期策略和历史数据成本。

44
5G 基站规划中的空间映射算法如何设计?
考察:GIS、空间索引与边界规则

参考回答

  1. 统一坐标系和数据精度,识别不同来源的坐标偏移。
  2. 对网格建立空间索引,缩小候选区域。
  3. 按点是否位于网格内、边界容差和业务优先级匹配。
  4. 明确重叠区域、边界点和无匹配数据的处理规则。
  5. 使用历史数据和人工核验样本验证准确率。

复杂场景可用 R-Tree、GeoHash、四叉树或数据库空间索引做候选检索,再进行精确几何判断。

45
报表统计从 10 小时缩短到 30 分钟,如何证明没有牺牲准确性?
考察:结果校验与数据质量

参考回答

固定相同统计口径和数据范围,对比记录数、分组汇总、关键字段和业务指标;对边界数据、缺失坐标、重复记录和异常映射抽样核验。

异步管道还要明确数据延迟和统计截止时间,避免未处理完的数据被误认为最终结果。性能和质量应同时验收,例如执行耗时、资源消耗、完整率、异常率和结果差异率。

46
如何设计 9000 万会员数据迁移的切换方案?
考察:双系统协同、增量追平与回滚

参考回答

根据业务条件选择维护窗口冻结写入,或先全量迁移再通过变更日志/可靠事件同步增量。切换前追平增量、校验数据并切换读写入口。

提前验证主键映射、唯一约束、字段转换、历史兼容和查询性能。保留必要回滚能力,并明确回滚期间新增数据如何处理。切换后重点监控登录、会员查询、订单关联和积分等核心业务。

47
航空电商的订单与里程扣减如何保证正确性?
考察:账户变更、流水、幂等与事务

参考回答

里程扣减可设计为:请求幂等校验 → 账户与规则校验 → 原子扣减 → 记录不可变流水 → 返回结果。确保扣减和流水处于正确事务边界,并处理重复请求、并发扣减和失败重试。

若订单与里程分属不同服务,选择合适的一致性方案,并明确扣减失败时订单能否继续及补偿策略。请求超时后,使用业务请求号查询原结果,避免重复扣减。

48
外部供应商接口切换如何保证业务不中断?
考察:适配层、灰度、幂等与回滚

参考回答

先定义新旧供应商接口契约、字段映射、错误码、超时和业务语义,通过适配层隔离差异。在安全合规前提下按流量或业务范围灰度切换。

重点检查字段兼容、重试是否重复下单、超时后如何查询真实结果、双系统验证是否产生副作用、异常时如何切回,以及切换前后如何对账。

简历提到双系统并行验证 2 万+ 订单,面试时要解释是影子请求、测试流量还是实际交易,以及如何避免重复交易。

49
20 多个微服务突然大面积超时,你会怎么处理?
考察:故障指挥、级联故障与恢复

参考回答

  1. 通过监控确认影响范围、起始时间、核心业务成功率和共同依赖。
  2. 检查最近发布、配置变更、数据库连接池、线程池、消息积压、网关和公共中间件。
  3. 限制非核心流量、暂停风险变更,必要时回滚并保护非核心功能。
  4. 恢复后核对数据一致性、消息积压和未完成业务。
  5. 复盘根因,完善检测、演练和预案。

大量服务同时超时可能由公共数据库、注册中心、网络组件或下游依赖导致级联故障,不能只逐个重启服务。

50
如果重新设计 IoT 平台,你会做哪些改进?
考察:架构演进、复杂度控制与技术取舍

参考回答

  1. 架构复杂度:评估服务边界、调用耦合及可合并模块。
  2. 数据一致性:区分同步事务与最终一致性,缩小跨服务事务范围。
  3. 稳定性:完善链路追踪、容量评估、故障演练、告警和恢复预案。
  4. 交付效率:通过自动化测试、契约测试、灰度发布和统一规范降低风险。

架构演进应由真实问题驱动。成熟的架构负责人既知道如何增加能力,也知道哪些复杂度没有必要引入。