--- id: backend.java-spring.interview title: Java / Spring Boot(了解级)面试题 type: interview domain: backend stack: [java-spring] tags: [Java, Spring Boot, IoC, 事务, 面试] level: basic related: [backend.java-spring.awareness] week: [14, 16] --- # Java / Spring Boot(了解级)面试题 ## 基础 ### 【基础】什么是 IoC 和依赖注入? **参考答案**:控制反转:对象的创建和依赖组装由容器负责,而不是对象自己 `new`;依赖注入是实现方式,通过构造器、setter 或字段注入。好处是解耦、便于替换实现和测试。 **追问**:为什么推荐构造器注入?→ 依赖可以声明为 final、不会出现未初始化的状态、单元测试时直接传入假实现。 ### 【基础】Spring Boot 项目通常怎么分层? **参考答案**:Controller 处理 HTTP 和参数校验,Service 写业务逻辑和事务边界,Repository 负责数据访问;DTO 与实体分开,全局异常处理统一返回格式。 **追问**:和你写的 Go 项目怎么对应?→ handler / service / repository 三层,思路一致,只是 Go 中依赖在 main 中手动组装。 ### 【基础】Java 中金额用什么类型? **参考答案**:`BigDecimal`(或以分为单位的 `long`),不能用 `double`,二进制浮点数无法精确表示 0.1 等小数。 **追问**:`BigDecimal` 比较相等要注意什么?→ `equals` 会比较精度(`2.0` 和 `2.00` 不相等),数值比较用 `compareTo`。 ## 进阶 ### 【进阶】`@Transactional` 在什么情况下会失效? **参考答案**:同类内部方法调用(不经过代理)、方法不是 public(取决于代理方式和版本)、异常被捕获没有抛出、抛出受检异常而未配置 `rollbackFor`、数据库引擎不支持事务。 **追问**:Go 中怎么做类似的事?→ 显式开启事务并把 `tx` 传入各个仓储方法,或者封装一个 `WithTx(func(tx) error)` 帮助函数。 ### 【进阶】虚拟线程是什么?和 goroutine 有什么相似之处? **参考答案**:JDK 21 正式提供的轻量级线程,由 JVM 调度到少量平台线程上,阻塞 I/O 时让出载体线程,可以创建大量并发任务;与 goroutine 一样让“同步写法 + 高并发”成为可能。 **追问**:有什么需要注意?→ 不适合 CPU 密集任务;某些同步块或本地调用会“钉住”载体线程(不同 JDK 版本有改进,以官方说明为准);不要池化虚拟线程。 ### 【进阶】Java 团队说接口“已经幂等”,你怎么验证? **参考答案**:看实现:是否有唯一约束或幂等键表、状态机是否只允许合法转换;做测试:同一请求并发和重复发送,检查数据只产生一条、返回结果一致。 **追问**:幂等键应该谁生成?→ 调用方生成并在重试时复用;服务端存储键和结果,设定过期时间。 ## 场景题 ### 【场景题】你的 Python Agent 需要调用公司的 Java 订单系统,怎么做? **参考答案**:读 Controller / DTO 明确契约;Python 侧封装工具,透传用户身份;错误码映射为可重试、告知用户、转人工;非幂等接口推动增加幂等键;契约测试和 request id 联调。详见[调用 Java 服务场景](scenarios/call-java-service.md)。 **追问**:对方接口很慢怎么办?→ 设置超时,查询类接口加缓存,长操作改为异步(提交后轮询或回调),Agent 告诉用户“已提交,稍后通知”。 ### 【场景题】面试官问“你会 Java 吗”,你怎么回答? **参考答案**:如实说明:主语言是 Go / Python,能读懂 Spring Boot 项目的结构和代码,理解 IoC、分层、事务等核心概念,做过(或能做)与 Java 服务的对接;如果岗位需要,可以快速上手。不夸大。 **追问**:举个例子说明你读懂过 Java 代码?→ 讲清一次具体的对接:从哪个 Controller 读出了什么契约、发现了什么问题(例如非幂等)、怎么解决。