Maven基本面試題問答

Maven 是什麼?

  • Maven 主要服務於基於 Java 平臺的項目構建、依賴管理和項目信息管理。

Maven有哪些優點和缺點

  • 簡化了項目依賴管理:
  • 易於上手,對於新手可能一個"mvn clean package"命令就可能滿足他的工作
  • 便於與持續集成工具(jenkins)整合
  • 便於項目升級,無論是項目本身升級還是項目使用的依賴升級。
  • 有助於多模塊項目的開發,一個模塊開發好後,發佈到倉庫,依賴該模塊時可以直接從倉庫更新,而不用自己去編譯。
  • maven有很多插件,便於功能擴展,比如生產站點,自動發佈版本等。

缺點

  • maven是一個龐大的構建系統,學習難度大
  • maven是一個龐大的構建系統,學習難度大
  • maven採用約定優於配置的策略(convention over configuration),雖然上手容易,但是一旦出了問題,難於調試。
  • 當依賴很多時,m2eclipse 老是搞得Eclipse很卡。
  • 中國的網絡環境差,很多repository無法訪問,比如google code, jboss 倉庫無法訪問等。

Maven座標

  • 一般maven使用[groupID,artifactId,version,packaging]來表示一個項目的某個版本,有時還會使用classifier來表示項目的附屬構建,常見的附屬構建有javadoc和sources包。

你們項目爲什麼選用 Maven 進行構建?

  • 首先,Maven 是一個優秀的項目構建工具。使用maven,可以很方便的對項目進行分模塊構建,這樣在開發和測試打包部署時,效率會提高很多。
  • 其次,Maven 可以進行依賴的管理。使用 Maven ,可以將不同系統的依賴進行統一管理,並且可以進行依賴之間的傳遞和繼承。

Maven 規約是什麼?

  • /src/main/java/:Java 源碼。
  • /src/main/resource:Java 配置文件,資源文件。
  • /src/test/java/:Java 測試代碼。
  • /src/test/resource:Java 測試配置文件,資源文件。
  • /target:文件編譯過程中生成的 .class 文件、jar、war 等等。
  • pom.xml:配置文件

Maven 要負責項目的自動化構建,以編譯爲例,Maven 要想自動進行編譯,那麼它必須知道 Java 的源文件保存在哪裏,這樣約定之後,不用我們手動指定位置,Maven 能知道位置,從而幫我們完成自動編譯。
遵循“約定>>>配置>>>編碼”。即能進行配置的不要去編碼指定,能事先約定規則的不要去進行配置。這樣既減輕了勞動力,也能防止出錯。

Maven常見的依賴範圍有哪些?

  1. compile:編譯依賴,默認的依賴方式,在編譯(編譯項目和編譯測試用例),運行測試用例,運行(項目實際運行)三個階段都有效,典型地有spring-core等jar。
  2. test:測試依賴,只在編譯測試用例和運行測試用例有效,典型地有JUnit。
  3. provided:對於編譯和測試有效,不會打包進發布包中,典型的例子爲servlet-api,一般的web工程運行時都使用容器的servlet-api。
  4. runtime:只在運行測試用例和實際運行時有效,典型地是jdbc驅動jar包。
  5. system: 不從maven倉庫獲取該jar,而是通過systemPath指定該jar的路徑。
  6. import: 用於一個dependencyManagement對另一個dependencyManagement的繼承。

Maven的生命週期
maven有三套生命週期,分別爲:

  1. clean 週期:主要用於清理上一次構建產生的文件,可以理解爲刪除target目錄

  2. 默認週期,
    主要階段包含:
    process-resources 默認處理src/test/resources/下的文件,將其輸出到測試的classpath目錄中,
    compile 編譯src/main/java下的java文件,產生對應的class,
    process-test-resources 默認處理src/test/resources/下的文件,將其輸出到測試的classpath目錄中,
    test-compile 編譯src/test/java下的java文件,產生對應的class,
    test 運行測試用例,
    package 打包構件,即生成對應的jar, war等,
    install將構件部署到本地倉庫,
    deploy 部署構件到遠程倉庫

  3. site週期
    主要階段包含
    site 產生項目的站點文檔
    site-deploy 將項目的站點文檔部署到服務器

Maven 常用命令

  • mvn archetype:create:創建 Maven 項目。
  • mvn compile:編譯源代碼。
  • mvn deploy:發佈項目。
  • mvn test-compile:編譯測試源代碼。
  • mvn test:運行應用程序中的單元測試。
  • mvn site:生成項目相關信息的網站。
  • mvn clean :清除項目目錄中的生成結果。
  • mvn package:根據項目生成的 jar/war 等。
  • mvn install:在本地 Repository 中安裝 jar 。
  • mvn eclipse:eclipse:生成 Eclipse 項目文件。
  • mvn jetty:run啓動: Jetty 服務。
  • mvn tomcat:run:啓動 Tomcat 服務。
  • mvn clean package -Dmaven.test.skip=true:清除以前的包後重新打包,跳過測試類。

用到最多的命令

  • mvn eclipse:clean:清除 Project 中以前的編譯的東西,重新再來。
  • mvn eclipse:eclipse:開始編譯 Maven 的 Project 。
  • mvn clean package:清除以前的包後重新打包。

Maven 座標的含義?

<!-- FROM https://github.com/junit-team/junit4/blob/master/pom.xml -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13-BETA</version>

Maven 給我們制定了一套規則 —— 使用座標進行唯一標識。Maven 的座標元素包括 groupId、artifactId、version、packaging、classfier 。

只要我們提供正確的座標元素,Maven 就能找到對應的構件,首先去你的本地倉庫查找,沒有的話再去遠程倉庫下載。如果沒有配置遠程倉庫,會默認從中央倉庫地址(http://repo1.maven.org/maven2)下載構件,該中央倉庫包含了世界上大部分流行的開源項目構件,但不一定所有構件都有。

5 個元素中:

  • groupId、artifactId、version是必須定義的。
  • `packaging是可選的(默認爲 jar )。
  • classfier是不能直接定義的,需要結合插件使用。

Maven <dependencie />是什麼?
<dependencie />,依賴關係。屬性如下:

  • groupId:依賴項的 groupId 。

  • artifactId :依賴項的 artifactId

  • version :依賴項的 version

  • scope :依賴項的適用範圍。

     compile :默認值,適用於所有階段(開發、測試、部署、運行),本 jar 會一直存在所有階段。
     provided :只在開發、測試階段使用,目的是不讓 Servlet 容器和你本地倉庫的 jar 包衝突 。如 servlet.jar 。
     runtime :只在運行時使用,如 JDBC 驅動,適用運行和測試階段。
     test :只在測試時使用,用於編譯和運行測試代碼,不會隨項目發佈。
     system :類似 provided ,需要顯式提供包含依賴的 jar 包,Maven 不會在 Repository 中查找它。
     import :用於一個 <dependencyManagement /> 對另一個 <dependencyManagement /> 的繼承。非常重要,通過它,可以實現類似 《Maven Spring BOM (bill of materials)》 的功能。
    
  • exclusions:排除項目中的依賴衝突時使用。

對於一個多模塊項目,如果管理項目依賴的版本?

  • 方式一,通過在父模塊中聲明 和, 然後讓子模塊通過元素指定父模塊,這樣子模塊在定義依賴是就可以只定義 groupId 和 artifactId,自動使用父模塊的 version ,這樣統一整個項目的依賴的版本。
  • 繼承的方式
  • 方式二,使用 聲明 爲 import 的依賴,從而引入一個 pom 的 的。具體的,可以看看 《Maven Spring BOM (bill of materials)》文章。
  • 組合的方式

LASTEST、RELEASE、SNAPSHOT 的區別?

  • LASTEST :是指某個特定構件最新的發佈版或者快照版(SNAPSHOT),最近被部署到某個特定倉庫的構件。
  • RELEASE :是指倉庫中最後的一個非快照版本。
  • SNAPSHOT :泛指。如果不 SNAPSHOT ,如果名字不變,本地有了不會從遠程拉。如果每次更新都改名字,其他用的人也都改名字,太蛋疼了。

Maven 依賴原則?

  • 1、賴路徑最短優先原則。
  • 一個項目 Demo 依賴了兩個 jar 包,其中 A-B-C-X(1.0) , A-D-X(2.0) 。由於 X(2.0) 路徑最短,所以項目使用的是 X(2.0) 。
  • 2、pom文 件中申明順序優先。
  • 如果 A-B-X(1.0) ,A-C-X(2.0) 這樣的路徑長度一樣怎麼辦呢?這樣的情況下,Maven 會根據 pom 文件聲明的順序加載,如果先聲明瞭 B ,後聲明瞭 C ,那就最後的依賴就會是 X(1.0) 。
  • 3、覆寫優先
  • 子 pom 內聲明的優先於父 pom 中的依賴。

如何解決 jar 衝突?

遇到衝突的時候第一步,要找到 Maven 加載的到時是什麼版本的 jar 包,通過們 mvn dependency:tree 查看依賴樹,或者使用 IDEA Maven Helper 插件。
然後,通過 Maven 的依賴原則來調整座標在 pom 文件的申明順序是最好的辦法,或者使用將衝突中不想要的 jar 引入的 jar 進行<exclusions> 掉。

什麼是 Maven 插件?
Maven 生命週期的每一個階段的具體實現都是由 Maven 插件實現的。插件通常提供了一個目標的集合,並且可以使用下面的語法執行:mvn [plugin-name]:[goal-name]

Maven 提供了下面兩種類型的插件:

  • Build plugins :在構建時執行,並在 pom.xml 的 元素中配置。
  • Reporting plugins :在網站生成過程中執行,並在 pom.xml 的元素中配置。

下面是一些常用插件的列表:

  • clean :構建之後清理目標文件。刪除目標目錄。
  • compiler :編譯 Java 源文件。
  • surefile :運行 JUnit 單元測試。創建測試報告。
  • jar :從當前工程中構建 JAR 文件。
  • war :從當前工程中構建 WAR 文件。
  • javadoc :爲工程生成 Javadoc 。
  • antrun :從構建過程的任意一個階段中運行一個 ant 任務的集合。

什麼是 Maven 倉庫?
Maven 的倉庫只有兩大類:

  • 1、本地倉庫。
  • 2、遠程倉庫。在遠程倉庫中又分成了 3 種:
  • 中央倉庫。
  • 私服
  • 其它公共庫。

Maven 會先搜索本地倉庫(repository),發現本地沒有然後從遠程倉庫(中央倉庫)獲取。

  • 但中央倉庫只有一個,最好從其鏡象處下載。國內可以用阿里雲下的服務器。【其它公共庫】
  • 也有通過 Nexus 搭建的私服進行獲取的。【私服】

Maven 中的倉庫分爲兩種,SNAPSHOT 快照倉庫和 RELEASE 發佈倉庫。

  • SNAPSHOT 快照倉庫用於保存開發過程中的不穩定版本,RELEASE 正式倉庫則是用來保存穩定的發行版本。定義一個組件/模塊爲快照版本,只需要在 pom 文件中在該模塊的版本號後加上 -SNAPSHOT 即可(注意這裏必須是大寫),如下:

    <groupId>cc.mzone</groupId>
    <artifactId>m1</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    
  • Maven 會根據模塊的版本號(pom 文件中的 version)中是否帶有 -SNAPSHOT 來判斷是快照版本還是正式版本。

    • 如果是快照版本,那麼在 mvn deploy 時會自動發佈到快照版本庫中,會覆蓋老的快照版本。而在使用快照版本的模塊,在不更改版本號的情況下,直接編譯打包時,Maven 會自動從鏡像服務器上下載最新的快照版本。
    • 如果是正式發佈版本,那麼在 mvn deploy 時會自動發佈到正式版本庫中,而使用正式版本的模塊,在不更改版本號的情況下,編譯打包時如果本地已經存在該版本的模塊則不會主動去鏡像服務器上下載。

所以,我們在開發階段,可以將公用庫的版本設置爲快照版本,而被依賴組件則引用快照版本進行開發,在公用庫的快照版本更新後,我們也不需要修改 pom 文件提示版本號來下載新的版本,直接 mvn 執行相關編譯、打包命令即可重新下載最新的快照庫了,從而也方便了我們進行開發。

什麼是私服?

私服是一種特殊的遠程倉庫,它是架設在局域網內的倉庫服務,私服代理廣域網上的遠程倉庫,供局域網內的 Maven 用戶使用。當 Maven 需要下載構件的時候,它從私服請求,如果私服上不存在該構件,則從外部的遠程倉庫下載,緩存在私服上之後,再爲 Maven 的下載請求提供服務。我們還可以把一些無法從外部倉庫下載到的構件上傳到私服上。

Maven 私服的 5 個特性:

  • 1、節省自己的外網帶寬:減少重複請求造成的外網帶寬消耗。
  • 2、加速 Maven 構件:如果項目配置了很多外部遠程倉庫的時候,構建速度就會大大降低。
  • 3、部署第三方構件:有些構件無法從外部倉庫獲得的時候,我們可以把這些構件部署到內部倉庫(私服)中,供內部 Maven 項目使用。
  • 4、提高穩定性,增強控制:Internet 不穩定的時候,Maven 構建也會變的不穩定,一些私服軟件還提供了其他的功能。
  • 5、降低中央倉庫的負荷:Maven 中央倉庫被請求的數量是巨大的,配置私服也可以大大降低中央倉庫的壓力。

當前主流的 Maven 私服:

  • Apache 的 Archiva
  • JFrog 的 Artifactory
  • 【主流】Sonatype 的 Nexus 。

常見的 Maven 私服的倉庫類型:

  • (宿主倉庫)hosted repository 。
  • (代理倉庫)proxy repository 。
  • (倉庫組)group repository 。

如何配置遠程倉庫?

用文本編輯器工具打開 setting.xml文件,增加一個 <mirror />

<mirrors>
    <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>*</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>
</mirrors>
發佈了30 篇原創文章 · 獲贊 18 · 訪問量 1411
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章