作为一名 Senior Java 开发,面试官问 Maven 通常不会只问 mvn clean install,而是看你对依赖冲突解决、生命周期底层逻辑、以及私服仓库管理的理解。
以下是高频面试题及核心点:
1. Maven 的坐标(GAV)是什么?
面试官: “怎么唯一标识一个 Maven 工程?”
-
回答核心:
-
G (GroupId): 项目组 ID,通常是域名反写(如
com.google)。 -
A (ArtifactId): 项目 ID,模块名称。
-
V (Version): 版本号。
-
Packaging: 打包方式(jar/war/pom),默认为 jar。
-
2. 依赖冲突:两个 Jar 包版本不同,Maven 听谁的?
面试官: “如果 A 依赖 B(1.0),C 依赖 B(2.0),项目同时依赖 A 和 C,最后用哪个 B?”
-
原则 1:路径最短优先。
-
Project -> A -> B(1.0)(层级 2) -
Project -> C -> D -> B(2.0)(层级 3) -
结果: 使用 B(1.0),因为路径更短。
-
-
原则 2:声明顺序优先(路径长度相同时)。
-
如果在
pom.xml里先写 A 的依赖,再写 C 的依赖,则用 A 里的版本。
-
3. 怎么解决依赖冲突?
面试官: “发现 Jar 包冲突导致 NoSuchMethodError,你怎么处理?”
-
排查工具: 使用
mvn dependency:tree查看依赖树,或者在 IDEA 中使用 Maven Helper 插件。 -
解决方法:
-
<exclusion>: 在配置依赖时,使用exclusion标签排除掉不想要的低版本。 -
锁定版本: 在父工程的
<dependencyManagement>中明确指定版本。
-
4. dependencyManagement vs dependencies
面试官: “父工程里这两个标签有什么区别?”
-
dependencies: 这里的依赖会被子项目强制继承。 -
dependencyManagement: 只是声明版本,不引入依赖。子项目需要用到时仍需写依赖,但不用写版本号。-
作用: 统一管理版本,避免不同模块版本不一致。
-
5. Maven 的生命周期有哪些?
面试官: “说说 clean、compile、package、install、deploy 的区别。”
Maven 有三套独立的生命周期:Clean、Default(核心)、Site。
-
Default 生命周期核心阶段(按顺序执行):
-
compile:编译源码。
-
test:运行单元测试。
-
package:打包(jar/war)。
-
install:将包安装到本地仓库,供本地其他项目使用。
-
deploy:将最终的包推送到远程私服(Nexus),供全公司使用。
重点: 执行后面的命令会自动触发前面所有的步骤。比如执行
install,会自动先执行compile和package。 -
6. 什么是 Snapshot(快照)版本?和 Release 有什么区别?
面试官: “为什么开发阶段要用 -SNAPSHOT?”
-
Snapshot (快照): 不稳定版。每次构建时,Maven 会去私服检查是否有更新并强制下载。不需要频繁改版本号(如
1.0-SNAPSHOT)。 -
Release (发行): 稳定版。一旦发布到仓库,版本号就不再变更。Maven 不会重复下载相同版本的 Release 包。
-
场景: 团队协作时,你改了底层代码,如果不发 Snapshot,同事的本地仓库就不会更新你的改动。
-
7. 聚合 (Aggregation) vs 继承 (Inheritance)
面试官: “多模块项目中,这两者怎么体现?”
-
继承: 为了消除重复配置。子
pom指定parent。 -
聚合: 为了一键构建。在一个总的
pom中使用<modules>包含所有子模块,只需对总pom执行一次mvn install,所有子模块都会按依赖顺序被构建。
8. Maven 仓库的搜索顺序?
面试官: “Maven 去哪找我的 Jar 包?”
-
本地仓库 (Local Repository)
-
远程私服 (Remote Mirror/Nexus)
-
中央仓库 (Central Repository)
面试加分项:
如果你提到你在之前的 或者自动交易系统项目中,如何通过 profiles 区分 dev/prod 环境(比如不同环境打不同的 application.yml),面试官会觉得你对工程化的实践非常到位。
你前年做的项目里,遇到过最头疼的 Maven 依赖冲突是什么?(通常是日志框架 slf4j 或者 guava 冲突)