應屆生必讀:Java真實項目的開發流程和常用工具

本文出自本人寫的書,謝絕轉載,更勿抄襲。

本人有多年的Java面試官經驗,經常要和一些包裝項目經驗的求職者打交道。當然平時也兼職做些Java面試輔導工作,最近也陸續幫一些在校生朋友成功找到Java工作。

在輔導在校生朋友找工作的過程中,本人發現,其實真有不少朋友,是跟着視頻跑通了一個或多個學習項目,再背了些面試題和算法題,然後去找工作,對此本人也有專門的文章來說明。

雖然校招其實是沒有商業項目要求的,換句話說,如果零項目經驗再去找工作,其實也能成,但這樣就和其它大多數在校生沒差別了,事實上本人在輔導就業的過程中深有體會,如果求職者朋友能在面試過程中充分展示商業項目經驗,一定能提升面試成功的可能。

這點其實很多在校生朋友也知道,所以不少人真會把學習項目包裝成商業項目,或者乾脆在沒項目的前提下自己去編一個,所謂就是“吹牛不打草稿”,對此其實很多面試官是能輕易看出的,本人在面試官的經歷中也經常聽到些啼笑皆非的回答。

對此,本文先不說如何介紹商業項目經驗,就先講講Java真實項目的開發流程和常用工具,這樣,對於那些有真實Java項目經驗的朋友,至少也知道該如何說。

1 接需求和前期設計

商業項目的需求一般來自兩個途徑,一類是本公司的產品設計人員提出需求,另一類是公司對接客戶方需求的業務人員從客戶方承接需求。

如果是公司自研的項目,比如某公司自研一個支付類的app,那麼該公司的產品設計人員會設計出該app的界面和功能,然後交付程序員開發。如果是公司從客戶方承接項目,那麼該公司的項目開發團隊是通過該公司的業務人員,從客戶方獲取界面、功能以及業務流程方面的需求。

在明確需求後,項目經理或架構師會根據業務需求點,在linux等操作系統的服務器上創建數據庫服務器,並在其中創建數據庫和數據表。在此基礎上,項目經理或架構師會在服務器上搭建所需的基礎設置,比如Redis等分佈式組件、Nacos等微服務組件,或者是Git等代碼管理組件。

隨後,前端開發人員會用Vue.js等組件搭建前端框架,而後端架構師會用Spring Boot框架內加入控制器、服務層和整合MyBatis的數據服務層代碼,同時整合Logback日誌組件以及AOP切面組件,這樣程序員就能在該框架內,通過加入必要的模板類代碼,較爲高效地實現各種基於增刪改查的業務流程。

而在開發商業項目的過程中,程序員如果對功能點或業務流程有疑問,那麼應當通過項目經理,向產品方或業務方確認,而不是用自己理解的方式來開發。

有些軟件工程教科書會把開發項目的流程細分成“需求分析”、“概要設計”、“詳細設計”以及之後的開發測試部署等環節,在“需求分析”、“概要設計”和“詳細設計”等環節裏,需要產出需求和設計文檔,只有當所需文檔通過評審後,才能進入下個環節,而且一旦需求發生變更,還需要及時更新相關的需求和設計文檔。

但是在不少真實項目的開發場景裏,由於開發工期較緊,項目組會用較爲簡單的文檔來和產品或客戶方確認需求,在中小型項目或者是外包型項目裏,這種情況尤爲明顯。

比如在一個文檔裏畫出客戶所需的界面以及記錄各業務的開發流程,而不會詳細地按規範地編寫文檔。而且在需求變更後,也不會及時更新相關文檔,甚至是有些需求和變動是直接從客戶方這邊獲取到,然後通過郵件而不是文檔來確認。

也就是說,在開發中小型項目或外包項目時,由於項目利潤不高,項目經理會盡可能地壓縮開發週期,所以,一般不會有太多的時間來按規範整理、評審和更新文檔。相比之下,在開發學習項目時,一般會按部就班地按規範來寫文檔。

所以如果求職者給出項目規模較小,但說明在開發過程中用1個月的時間準備文檔,而且項目開發流程完全符合教科書級別的軟件開發規範,那麼面試官還真可能會質疑該項目的真實性。

或者,如果有求職者說,在項目開發過程中,參與了接需求、設計數據表、繪製前端頁面和開發後端代碼等全部的工作,那麼也是不大可信的。比如初級開發,在項目組裏的開發工作一般是,在項目經理搭建好的Spring Boot框架裏,參考現有的代碼,完成開發工作。

2 敏捷開發模式

當下不少項目經理,尤其是需要趕工期的項目經理,是用敏捷模式來管理項目。在實踐過程中,敏捷模式包含“每天例會”和“迭代開發”這兩個實踐要點。

在每天的例會里,項目組的每位成員需要說下當前任務的開發情況,如果遇到個人無法解決的問題就提出來,由組內成員幫助或協調解決,如果程序員完成開發了一個任務點,在例會中還可以演示一下,讓相關人員確認下是否符合預期。

而迭代開發的含義是,項目經歷根據開發週期和工作量,需求點合理地拆分到每個週期內,每個週期在完成任務後做一次發版。比如某項目開發週期是8個月,有50個功能點,那麼項目經理能以“月”爲單位設計8個迭代週期,併爲每個週期制定如下表所示的工作任務。

迭代週期編號 工作任務 完成標誌
1 完成創建數據表,完成搭建日誌、Redis和Nacos等開發環境,完成3個功能點 相關組件搭建完成,成功發版,發版後的代碼包含對應業務功能
2到7個週期 平均每個週期完成8個功能點,同時解決之前發現的線上問題 成功發版,發版後的代碼包含對應業務功能,同時線上問題成功修復
8 全面測試,修復問題 成功發版,發版後的代碼包含對應業務功能,同時線上問題成功修復

每個迭代週期有固定的發版日,比如是第四周的週五,當然在實際開發過程中,如果有待緊急上線的功能點或出現比較嚴重的線上問題,還可以再額外發版。而在每個迭代週期內,一般再會以“周”爲單位來安排任務並管理代碼,相關情況如下表所述。

時間段 工作任務 實踐要點
該迭代週期開始後的1到2天內 項目經理會和產品或客戶確認該週期內需要完成的任務點,同時確認該週期內需要解決的線上問題 項目經理用jira或禪道等工具,爲每個程序員創建開發任務,同時不定期地爲程序員分配修bug等任務
前三週 程序員根據所分配的任務開發功能點,或修復bug 完成後的代碼應及時部署到測試環境,同時經過測試後的代碼應及時提交到Git或其它代碼管理工具上
最後一週 全面測試,修復問題 發版後的代碼在經測試後,應當在Git等工具上打上標記,以便管理

上文提到的,在每個迭代週期結束後的發版,是發佈到生產環境。比如某項目組做的是自研項目,那麼一般會在買的或租的服務器上搭建對外提供服務的生產環境,發版後的項目,即能對外提供服務。如果做的是外包項目,那麼發版的環境一般是客戶方提供的服務器。

每次發版結束後,項目經理一般也會讓產品或業務人員來確認功能點。而在迭代開發過程中,難免會遇到需求變更等情況,此時項目經理可能就不得不更改原有計劃,在對應的迭代週期內添加任務點。通過這種迭代模式,項目經理能有效地拆分任務,並且能定期演示所完成的功能點。

3 開發、測試與測試環境

在每個迭代開發週期內,程序員會根據所分配的任務,在Spring Boot等框架內開發增刪改查功能點。

項目開發完成後,最終是需要部署到生產環境,這點上文已經提到過。不過大多數項目組還會在生產環境之外,在另外一臺服務器上搭建測試環境,在測試環境上,一般也會安裝Redis和數據庫等項目基礎設置,程序員一般有權限部署或修改測試環境的代碼和配置文件。

大多數學習項目更注重功能開發,一般沒有測試和部署等環節,也不會專門搭建測試環境和生產環境,這也是商業項目和學習項目的一個重要差別。事實上大多數的學習項目一般是在Windows操作系統的開發主機上啓動並運行,所以如果求職者只做過學習項目,一般在面試過程中是說不好測試和部署的流程。

在開發完成後,雖然項目組一般還會配置測試人員,但是程序員一般還需要通過單元測試、接口測試和功能測試等手段來確保代碼的質量,上述測試動作一般是在測試環境上進行,相關測試的實踐要點歸納如下。

1. Spring Boot的單元測試一般用Junit進行,程序員通過編寫測試案例,來確保自己所開發的方法和模塊的正確性,在不少項目裏,還會專門引入Sonar等組件來確保單元測試代碼的覆蓋率。

2. 程序員在完成開發代碼並通過單元測試初步確定功能正確後,可以把後端代碼打包部署到測試環境。Spring Boot項目會通過控制器類定義對外服務的URL接口和測試,程序員可以通過Postman等工具,向測試環境發出攜帶參數的URL請求,從而確保每個接口的正確性。

3. 接口測試能確保後端接口的正確性,此時如果在前端代碼裏已經包含了調用後端接口方法,那麼程序員可以通過操作前端頁面的方式來驗證功能的正確性。當然這部分的測試更多地應該是由測試人員來完成,但如果有些項目規模很小,沒配置專門的測試人員,這塊一般也是由程序員自行完成。

4 項目部署細節說明

在商業項目的開發過程中,一般都會在每個迭代開發週期的結束時把項目代碼發佈待生產環境上,這個動作也叫項目部署。

在項目部署前,項目經理往往會帶領程序員和測試人員完成如下的動作。

1. 通過接口測試和功能測試,確保待發布業務功能點的正確性。

2. 明確本次發佈對應的功能點,以及明確對應功能點的檢查方式。

3. 明確待發布項目的代碼分支,比如用Git的master分支來發布,在發佈前若干天,除非有緊急修復等需求,應當禁止程序員再修改該分支的代碼。

4. 明確發佈時需要運行的數據庫腳本以及待修改的項目配置文件。

下表歸納了發佈當前的常規任務。

操作人員 工作任務
項目經理或運維人員 打包前後端代碼,比如把後端項目打成jar包。並把功能包部署到生產服務上的指定路徑,並啓動項目。
項目經理或運維人員 根據事先準備好的數據庫腳本,更新生產環境上的數據庫,同時更新生產環境上的項目配置文件
項目經理或運維人員 如果有必要,通過腳本等方式導入數據,或者在生產服務器上做其它操作
測試人員和程序員 發佈完成後,程序員到生產環境上驗證自己所開發功能的正確性,同時測試人員通過測試,驗證質量

後端Spring Boot項目的發佈流程一般是,用Maven等工具把項目打成jar包,再把該jar包複製粘貼到生產環境上,再通過java -jar等命令啓動該jar包,當然整個過程也可以用jenkins等自動化部署工具來完成。

在發佈過程中,如果發現所開發的功能有bug,項目經理能根據實際情況決定是完成部署還是終止部署。如果要終止部署,就需要把生產環境上的代碼、數據和配置參數回退到本次部署前的狀態。發佈完成後,項目經理也可以請產品設計人員或業務人員等提出需求的人員,到生產環境上通過實際操作,來確認所開發的功能符合預期。

5 監控系統,解決線上問題

在生產環境上,運維人員一般會搭建監控系統,用來監控系統運行的狀態。常用的監控系統有newrelic, cat和zabbix,程序員一般不需要關心監控系統是如何搭建和如何運行的,但監控系統一旦發現問題,會通過郵件或手機短信等方式告知程序員,此時程序員就需要排查解決問題。

不管是哪種監控系統,一般都會提供如下表所示的監控服務。

監控維度 告警時機
服務器 比如某項目部署在3臺服務器上,一旦有一臺服務器宕機,且時間操作30秒,監控系統會告警。
慢查詢 數據庫的某SQL語句運行時間超過10秒,監控系統會告警
慢請求 某後端請求的處理時間超過10秒,監控系統會告警
CPU負載過高 某服務器的CPU負載率高於50,且持續時間超過2分鐘,監控系統會告警
內存負載過高 某服務器的JVM虛擬機負載率高於75,且持續時間超過2分鐘,監控系統會告警
異常數過多 比如在5分鐘內,某服務器日誌裏出現Error或Exception等關鍵字的次數超過10次,監控系統會告警

在實踐場景裏,運維人員會在Zabbix等監控組件裏設置多個告警條件,在其中配置告警的閾值,比如上文裏提到的“某後端請求的處理時間超過10秒會告警”,其中告警閾值是10秒還是其它,這可以在監控組件內設置。

程序員在商業項目裏一般會去解決實際的線上問題,而大多數的線上問題一般都是由監控系統發現。而程序員解決線上問題的一般步驟是,第一看系統日誌或運行linux明確確認問題,第二找到該問題對應的代碼或配置文件,同時明確修復步驟,第三在修復後測試並部署,併到生產環境上確認問題已經修復。

6 項目管理和部署工具

商業項目一般會用Maven或Gradle工具來管理系統,通過此類工具,程序員除了能引入該項目所需要的依賴包之外,還能設置編譯項目時的工作任務。

具體地,如果使用Maven工具, 一般是通過mvn build命令來編譯項目,如果是用Gradle工具,一般是用gradlew build命令來編譯,在編譯過程中,如果後端代碼有語法問題,編譯會失敗。

在實際項目裏,項目經理一般還會通過編寫配置文件的方式,設置Maven或Gradle工具在編譯時還要運行代碼檢查工具,從而確保項目代碼的質量。比如可以通過Maven整合Sonar組件的方式,確保後端項目的Junit單元測試覆蓋率要高於80%,否則就會編譯失敗。

而在上文提到的項目部署過程中,可以手動運行mvn build等命令把後端項目打成jar包,再把該jar部署到linux測試或生產環境上再啓動,但是爲了提升部署的效率,還可以用Jenkins等工具來部署。

具體在用jenkins等工具時,程序員可以通過編寫配置文件,指定待部署項目的Git分支,打包命令和部署項目的服務器地址以及部署後啓動項目的命令,這樣在部署時就能通過點擊Jenkins工具的菜單按鈕自動完成部署動作。

7 代碼管理工具

當下大多數項目是用Git來管理代碼,當然依然有不少項目採用SVN等工具來管理代碼。在每個迭代開發週期裏,程序員在開發任務和修復bug前,需要從master等主分支上創建具體的開發分支,在開發分支上完成開發後,再把代碼提交併合併到主分支,相關操作要點如下所述。

要點1:在上一個迭代週期結束時,主分支(master)上的代碼已經發布到生產環境,同時會給此時的master主分支代碼打上一個tag標籤,比如是20230825標籤,這樣如果之後在生產環境上發佈的代碼有問題,可以回退到由該標籤標誌的Git分支。

要點2:項目組裏的Git工具一般會安裝在專門的服務器上,這臺服務器也叫Git服務器。而程序員自己的主機上需要安裝Git客戶端,並通過git命令從服務器上拉取代碼或向服務器推送代碼,相關效果如下圖所示。而在不少學習項目裏, Git服務器和Git客戶端會被安裝在同一臺Windows操作系統的主機上。

要點3,程序員在開發功能或修復bug時,一般需要用git pull命令,把處在遠端Git服務器上的master代碼拉到本地主機,並在主分支代碼的基礎上創建一個開發分支。比如小張創建了一個名爲task_001的代碼分支,小李創建了名爲task_002的代碼分支,他們分別在各自的分支上開發代碼。此時請注意,這裏的task_001等開發分支只是處在本地,並沒有提交到Git服務器。

要點4,程序員在自己的分支上完成開發和測試後,可以通過git commit命令,把代碼提交到本地(即程序員電腦的Git客戶端)的task_001等開發分支上,並通過git push命令,把本地的task_001等開發分支推送到Git服務器。

要點5,程序員在把自己的開發分支推送(push)到Git服務器後,需要創建一個合併請求(pull request,簡稱pr),請求把task_001裏的代碼合併到主分支裏。在創建合併請求時,一般需要指定由其它程序員評審(Review)代碼,經過評審後,task_001裏包含的實現新功能的代碼就能被合併(merged)到主分支上。

要點6,如果有多人同時修改同一個文件裏的同一段代碼,那麼在通過合併請求(pull request,簡稱pr)把分支代碼合併到主分支時,就會出現代碼衝突(conflict)的現象。此時相關人員就要一起討論,在確保功能正確的前提下修改代碼,從而解決代碼衝突的情況。

也就是說,如果程序員參與過真實的項目,那麼應該有上述Git等代碼管理工具的實踐經驗,相比之下,在學習項目的開發過程中,由於不涉及到多人協同開發,一般會直接在主分支上開發代碼,而不會有創建開發分支、把開發分支合併到主分支、代碼評審和和解決衝突等動作。

8 Java項目開發的常用組件

在商業項目裏,一般也是用到IDEA集成開發工具,也是用到Spring Boot框架,但是和學習項目相比,商業項目一般還會用到如下表所示的項目基礎設施組件。

功能效果 商業項目 學習項目
輸出日誌 用logback或log4j組件向控制檯和文件裏輸出日誌 一般僅會用System.out.println語句向控制檯輸出日誌
安全防護 通過Spring Security組件實現身份驗證和鑑權 不大會實現此類功能,或僅用Spring Security組件的基本功能
展示API 通過Swagger組件展示API,以供前端等人員調試 一般也會用到Swagger組件
提升數據庫性能 會綜合使用索引、Redis,再視情況使用MyCat分庫組件 一般僅用到Redis單機版節點
監控項目 Zabbix或Cat等 一般不會用到

從上表裏大家能看到,後端商業項目所用的一些組件,在開發學習項目時根本用不到,也就是說,如果大家能在面試中,結合場景和使用細節正確地說明日誌等組件的使用方式,其實也能從側面證明自己的商業項目開發經驗。

9 測試類工具

在實際項目裏,程序員一般也會用到Postman和Jmeter等測試工具,其中Postman一般用在接口測試(也叫API測試)場景,而Jmeter一般用在自動化測試或性能測試等場景。

比如某倉庫管理系統後端項目,在控制器層裏通過@urlmapping等註解定義瞭如下表所示的實現增刪改查功能的接口,其中分別用到了POST、DELETE、PUT和GET類型的http動作,當該項目部署到測試環境或生產環境後,程序員可以通過Postman工具發請求的方式來測試各API接口的正確性。

動作 URL請求 http動作 參數說明
查詢指定id的庫存 /stock/{id} GET {id}表示待查詢的庫存數據id
查詢所有庫存信息 /stocks GET 返回所有庫存,無需參數
創建新的庫存數據 /stock POST 在請求體(Body)裏傳入待插入的庫存數據
修改指定id的庫存 /stock/{id} PUT {id}表示待修改的庫存數據id,而具體待修改的庫存數據會通過請求體(Body)傳入
刪除指定id的庫存 /stock/{id} DELETE {id}表示待刪除的庫存數據id

比如通過Postman工具,發出了POST類型的/stock請求,並在該請求的參數裏設置了待插入的庫存信息,如果看到該請求的Http返回碼是200,那麼能說明該POST接口工作正常。再如,如果用Postman工具發出DELETE類型的/stock/{id}請求,並且正確地輸入了待刪除庫存的參數,如果看到返回碼是500,那麼就說明該接口的代碼有問題,程序員就需要介入並排查。

在項目部署前,一般需要確保該項目所有的接口都正常工作,如果該後端項目已經在控制器裏定義了20多個接口,那麼手動測試的工作量會比較大。

在此類場景裏,可在Jmeter里加入所有API接口,並設置每個接口正常工作的標準,比如返回碼是200就算工作正常,那麼就可以在每次部署前通過Jmeter自動發起針對所有接口的調用,並能通過返回結果自動確認接口的正確性,這就是用Jmeter進行自動化測試的一般步驟。

如果某後端項目對接口的性能有要求,比如客戶方要求每個接口的響應時間應該小於2秒,那麼可以通過Jmeter,設置同時發起100個請求,再通過查看平均返回時間來分析接口的性能,如果有問題再進行性能調優工作。

10 數據庫服務器及其客戶端組件

在實際項目裏,一般也會在一臺服務器上搭建MySQL或Oracle等數據庫服務器,而程序員在本機開發時,是通過Navicat或MySQL WorkBench等客戶端組件連接到數據庫服務器。

事實上不少項目組同樣會在生產環境的數據庫服務器之外,再搭建測試環境的數據庫服務器,而且爲了節省資源,會在同一臺測試服務器上搭建數據庫環境、上文提到的Git服務器以及Redis緩存組件等項目開發的基礎設施。

程序員在開發功能的過程中,除非是排查產線問題,否則一般不會操作生產環境的數據庫服務器,而是使用測試環境的數據庫,在使用時一般會有如下的實踐要點。

1. 在一個後端項目裏,一般會包含兩個配置文件,分別用於編寫指向生產環境和測試環境的配置參數,而後端代碼在啓動時,能通過傳入參數指定是連向生產環境還是測試環境。

2. 程序員在本機開發代碼時,一般不會在自己的主機上再搭建數據庫服務器,而是通過修改配置文件的方式,讓本地運行的代碼指向測試數據庫。而後端代碼被放置到測試環境上測試時,一般也是連向測試服務器。

3. 如果程序員要調試數據庫方面的問題,比如要調試一句查詢的SQL語句,一般是在本地,通過Navicat等客戶端工具連上測試數據庫,再其中調試。

4. 在生產環境數據庫服務器上的任何操作,比如要創建索引或更改表結構,一般會先在測試環境的數據庫服務器上驗證,驗證成功後再到生產數據庫上執行。

相對應地,如果某程序員在面試時,向面試官說,在開發項目時,MySQL等數據庫服務器是搭建在本地主機,或者是說,開發項目時數據庫服務器不分生產環境和測試環境,只用一套環境,那麼該程序員所說的項目,一般是指學習項目,而不是商業項目。

11 linux連接組件

商業項目一般是部署並運行在linux操作系統的服務器上,具體是指,後端Spring Boot項目打成的jar包會被部署到linux服務器上並啓動,數據庫服務器和Redis服務器,以及其它必要的項目基礎設施(如分佈式組件或微服務組件),一般也是部署並運行在linux服務器。

也就是說,程序員在開發項目時,會在本地Windows操作系統上,通過SecureCRT等組件,在輸入目標服務器IP地址、連接用戶名和密碼之後,以命令終端或文件目錄的形式連接到測試或生產環境。

程序員在把後端代碼放置到測試服務器後,可通過Postman等工具發起請求測試API接口,如果發現問題,可用SecureCRT組件登到測試服務器,找到對應的日誌文件,把該日誌文件下載到本地再排查。

或者是在以命令端的方式登錄到linux服務器之後,通過linux命令打開日誌文件並排查問題。項目中常用的linux命令如下表1-8所示。

命令 含義和使用場景
cd /opt/abc 進入到指定路徑
Pwd 查看當前路徑
cp 複製文件
ls 通過cd命令進入到指定路徑後,用該命令查看當前路徑裏的文件,確認是否存在待分析的日誌文件按
vi 打開(日誌等)文件,打開後可通過/keyword的方式查找字符,以確認和排查問題

12 總結與預告

商業項目經驗是Java求職者技能的最好背書,所以在面試過程中證明自己的商業項目經驗尤爲重要,但不少Java程序員,尤其是商業項目經驗不多的程序員,在面試過程中往往表現得像零商業項目的求職者一樣,無法有效地通過項目細節來證明自己的經歷。

本章系統講述了Java商業項目的開發流程流程以及項目開發時經常會用到的組件和工具,在之後的章節,將會在此基礎上,具體給出如何證明商業項目經驗的詳細說辭和麪試準備技巧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章