Java后端程序員1年工作經(jīng)驗總結(jié)

1.引言


畢業(yè)已經(jīng)一年有余,這一年里特別感謝技術(shù)管理人員的器重,以及同事的幫忙,學(xué)到了不少東西。這一年里走過一些彎路,也碰到一些難題,也受到過做為一名開發(fā)卻經(jīng)常為系統(tǒng)維護和發(fā)布當救火隊員的苦惱。遂決定梳理一下自己所學(xué)的東西,為大家分享一下。


經(jīng)過一年意識到以前也有很多認識誤區(qū),比如:


偏愛收集,經(jīng)常收集各種資料視頻塞滿一個個硬盤,然后心滿意足的看著容量不行動。


不重基礎(chǔ),總覺得很多基礎(chǔ)東西不需要再看了,其實不懂的地方很多,計算機程序方面任何一個結(jié)果都必有原因,不要只會用不知道原理,那是加工廠出來的。現(xiàn)在ide查看代碼那么方便,ctrl+點擊就進入了JDK查看實現(xiàn)細節(jié)。


好高騖遠,在計算機基礎(chǔ)不牢固的情況下,總想著要做架構(gòu),弄分布式,搞大數(shù)據(jù)之類。


不重視性能,只求能實現(xiàn)功能,sql查詢是不是可以優(yōu)化,是否有算法妙用,大對象是否要清除。


不重視擴展性,模塊之間緊密耦合,常用方法不提取成工具類,調(diào)用關(guān)系混亂等問題。


……


本文重點不在這些,故只列舉了一小部分,下面進入正題。


2.語法基礎(chǔ)


2.1 值傳遞和引用傳遞


可能很多人對此不屑一顧,心想老子都工作一年了,對這些還不熟悉嗎?但實際情況并非這樣,JDK中東西全部熟悉了嗎?以一個最簡單的例子開始,你覺得下圖中代碼執(zhí)行完之后fatherList中的元素是什么?


這是一個最基礎(chǔ)的值傳遞和引用傳遞的例子,你覺得好簡單,已經(jīng)想躍躍欲試的挑戰(zhàn)了,那么請看下面的,StringBuffer很好理解,但是當你執(zhí)行一遍之后發(fā)現(xiàn)是不是和預(yù)想中的輸出不一樣呢?String不是引用類型嗎,怎么會這樣呢?如果你無法理解,那么請看下String的實現(xiàn)源碼,了解下什么是不可變類,什么是享元模式。


2.2 集合的使用這部分幾乎每個人都會用到,而且大家還都不陌生。下圖來源于互聯(lián)網(wǎng),供大家復(fù)習(xí)一下。但是利用集合的特性進行巧妙的組合運用能解決優(yōu)化很多復(fù)雜問題。Set不可重復(fù)性,List的順序性,Map的鍵值對,SortSet/SortMap的有序性,我在工作中有很多復(fù)雜的業(yè)務(wù)都巧妙的使用了這些,涉及到公司保密信息,我就不貼出代碼了。工作越久越發(fā)現(xiàn)這些和越巧妙。


2.3 異常處理


1.看著try、catch、finally非常容易,如果和事務(wù)傳播結(jié)合在一起,就會變得極其復(fù)雜。


2.finally不一定必須執(zhí)行,return在catch/finally中處理情況(建議親自操刀試一下)。


3.catch中可以繼續(xù)拋自定義異常(并把異常一步步傳遞到控制層,利用切面抓取封裝異常,返回給調(diào)用者)。


2.4 面向?qū)ο笏枷?/p>


一提起面向?qū)ο?,大家都知道抽象、封裝、繼承、和多態(tài)。但是實際工作經(jīng)驗中又知道多少呢,對于項目中如何巧用估計更不要提了。


共性的機會每個都需要用的建立基類,如每個控制層方法可能要通過security獲取一個登錄用戶id,用于根據(jù)不同的用戶操作不同的數(shù)據(jù),可以抽象出一個應(yīng)用層基類,實現(xiàn)獲取id的protect方法。同理DAO層可以利用泛型提取出一個包含增刪改查的基類。


提到面向?qū)ο?,就不可避免的要說設(shè)計模式,在工作中,一個技術(shù)大牛寫的一個類似策略模式(更復(fù)雜一點),十分巧妙的解決了各種業(yè)務(wù)同一個方法,并且實現(xiàn)了訂單、工單、業(yè)務(wù)的解耦,看得我是非常佩服。我想很多面試中都會問道單例模式吧,還沒有理解的建議去看一看。


3.多線程


3.1 線程安全


這個是老生常談的問題了,但是確實是問題和bug高發(fā)區(qū)。線程同步問題不需要單獨寫了,想必大家都清楚,不太熟悉的建議百度一下。


3.1.1 線程安全問題


1.代碼中如果有同步操作,共享變量要特別注意(這個一般都能意識到)


2多個操作能修改數(shù)據(jù)表中同一條數(shù)據(jù)的。(這個容易被忽略,業(yè)務(wù)A可能操作表a,業(yè)務(wù)B也可以操作表a,業(yè)務(wù)A、B即使在不同的模塊和方法中,也會引起線程安全問題。例如如果一個人訪問業(yè)務(wù)A接口,另一個人訪問業(yè)務(wù)B接口,在web中每個業(yè)務(wù)請求都是會有單獨的一個線程進行處理的,就會出現(xiàn)線程安全問題)。


3.不安全的類型使用,例如StringBuffer、StringBuild,HashTable、HashMap等。在工作中我就遇到過有人在for循環(huán)進行l(wèi)ist的remove,雖然編譯器不報錯,程序可以運行,但是結(jié)果卻可想而知。


4.Spring的bean默認是單例的,如果有類變量就要特別小心了(一般情況下是沒人在控制層、業(yè)務(wù)層、DAO層等用類變量的,用的話建議是final類型,例如日志log,gson等)。


5.多個系統(tǒng)共享數(shù)據(jù)庫情況,這個其實和分布式系統(tǒng)類似


用戶重復(fù)提交問題(即使代碼中從數(shù)據(jù)庫讀取是否存在進行限制不能解決問題)


3.1.2 線程安全解決


在需要同步的地方采用安全的類型。


JDK鎖機制,lock、tryLock,synchronized,wait、notify、notifyAll等


Concurrent并發(fā)工具包,在處理一些問題上,誰用誰知道。強烈建議查看源碼!


數(shù)據(jù)表加鎖。(除非某個表的訪問頻率極低,否則不建議使用)


涉及分布式的,采用中間件技術(shù)例如zookeeper等解決。


3.2 異步


異步使用場景不影響主線程,且響應(yīng)較慢的業(yè)務(wù)。例如IO操作,第三方服務(wù)(短信驗證碼、app推送、云存儲上傳等)。


如果異步任務(wù)很多,就需要使用任務(wù)隊列了,任務(wù)隊列可以在代碼級別實現(xiàn),也可以利用redis(優(yōu)勢太明顯了)。


3.3 多線程通信


這方面文章非常多,這里不在詳述。


1.共享變量方式(共享文件、全局變量,信號量機制等)


2.消息隊列方式


3. 忙等,鎖機制


3.4多線程實現(xiàn)


1.集成Thread類,重寫(這里的重寫指的是override)run方法,調(diào)用start方法執(zhí)行。


2.實現(xiàn)Runable接口,實現(xiàn)run方法,以Runable實例創(chuàng)建thread對象。


3.實現(xiàn)Callable接口,實現(xiàn)call方法,F(xiàn)utureTask包裝callable接口,F(xiàn)utureTask對象創(chuàng)建thread對象,常用語異步操作,建議使用匿名內(nèi)部類,方便閱讀和使用。


額外需要說明的是:


1.理解thread的join方法;


2.不要認為volitate是線程安全的(不明白原因的建議去看jvm運行時刻內(nèi)存分配策略);


3.sleep時間片結(jié)束后并不保證立馬獲取cpu。


4.ThreadLocal能夠為每一個線程維護變量副本,常用于在多線程中用空間換時間。


4. 開源框架


4.1 Hibernate、Mybatis


相信每一個java程序員對這些都不陌生,這里不再詳述。


需要說明的主要以下幾點:


1.hibernate一級緩存(內(nèi)置session緩存),二級緩存(可裝配sessionFactory緩存),二級緩存會引起并發(fā)問題。


2.hibernate延遲加載原理理解。


3.hibernate 的get、load方法,sava、persist、savaOrUpdate方法區(qū)別


4.session重建了關(guān)聯(lián)關(guān)系卻并沒有同數(shù)據(jù)庫進行同步和更新


5.hibernate session關(guān)聯(lián)關(guān)系:detached對象、persistent對象


6.Spring data集成,注解方式配置屬性和實體。


7.mybatis 插件。


8.分頁查詢(數(shù)據(jù)庫)。


9.連接池技術(shù)


4.2 Spring IOC


4.1.1 Spring bean


1.bean注入 注解方式方便易讀,引用第三方(數(shù)據(jù)庫連接,數(shù)據(jù)庫連接池,JedisPool等)采用配置文件方式。


2. bean作用域:Singleton,prototype,request,session,global session


3.bean生命周期:如下圖所示

4.3 Spring AOP


基本概念:關(guān)注點、切面Aspect、切入點pointcut、連接點joinpoint、通知advice、織入weave、引入introduction。


Spring AOP支持5中類型通知,分別是MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice、MethodInterceptor、IntroductionInterceptor(吐槽一下名字太長)


實現(xiàn)方式如下:


1.基于代理的AOP


2.基于@Aspect注解驅(qū)動的切面。(強烈推薦:可讀性好,易維護,易擴展,開發(fā)快)


3.純POJO切面。


4.注入式Aspect切面。


4.4 Srping事務(wù)


4.4.1 事務(wù)傳播


概念:某些操作需要保證原子性,如果中間出錯,需要事務(wù)回滾。如果某個事務(wù)回滾,那么調(diào)用該事務(wù)的方法中的事務(wù)的作出如何的動作,就是事務(wù)傳播。


短時間內(nèi)寫不清楚,建議訪問 http://www.cnblogs.com/yangy608/archive/2010/12/15/1907065.html 查看。


事務(wù)傳播屬性:


1. PROPAGATION_REQUIRED--支持當前事務(wù),如果當前沒有事務(wù),就新建一個事務(wù)。這是最常見的選擇。


2. PROPAGATION_SUPPORTS--支持當前事務(wù),如果當前沒有事務(wù),就以非事務(wù)方式執(zhí)行。


3. PROPAGATION_MANDATORY--支持當前事務(wù),如果當前沒有事務(wù),就拋出異常。


4. PROPAGATION_REQUIRES_NEW--新建事務(wù),如果當前存在事務(wù),把當前事務(wù)掛起。


5. PROPAGATION_NOT_SUPPORTED--以非事務(wù)方式執(zhí)行操作,如果當前存在事務(wù),就把當前事務(wù)掛起。


6. PROPAGATION_NEVER--以非事務(wù)方式執(zhí)行,如果當前存在事務(wù),則拋出異常。


事務(wù)隔離級別:


  1. ISOLATION_DEFAULT: 這是一個PlatfromTransactionManager默認的隔離級別,使用數(shù)據(jù)庫默認的事務(wù)隔離級別.另外四個與JDBC的隔離級別相對應(yīng)


2. ISOLATION_READ_UNCOMMITTED: 這是事務(wù)最低的隔離級別,充許令外一個事務(wù)可以看到這個事務(wù)未提交的數(shù)據(jù)。這種隔離級別會產(chǎn)生臟讀,不可重復(fù)讀和幻像讀。


3. ISOLATION_READ_COMMITTED: 保證一個事務(wù)修改的數(shù)據(jù)提交后才能被另外一個事務(wù)讀取。另外一個事務(wù)不能讀取該事務(wù)未提交的數(shù)據(jù)


4. ISOLATION_REPEATABLE_READ: 這種事務(wù)隔離級別可以防止臟讀,不可重復(fù)讀。但是可能出現(xiàn)幻像讀。它除了保證一個事務(wù)不能讀取另一個事務(wù)未提交的數(shù)據(jù)外,還保證了避免下面的情況產(chǎn)生(不可重復(fù)讀)。


5. ISOLATION_SERIALIZABLE 這是花費最高代價但是最可靠的事務(wù)隔離級別。事務(wù)被處理為順序執(zhí)行。除了防止臟讀,不可重復(fù)讀外,還避免了幻像讀。


4.5 其他Spring 技術(shù)棧


spring boot 輕量級啟動框架


spring security 用戶權(quán)限管理,根據(jù)角色和用戶,實現(xiàn)UserDetailsService,進行自定義權(quán)限管理。


spring task 代碼級定時任務(wù),注解方式,使用起來非常方便。需要注意的是,如果某次定時任務(wù)出了異常而沒有進行處理,會導(dǎo)致接下來定時任務(wù)失效。如果各個任務(wù)相互獨立,可以簡單用try,catch包圍(之前就吃過這方面的虧)。


spring data 注解方式定義實體,屬性等


spring mvc 簡單明了的mvc框架。url傳值、數(shù)組傳值、對象傳值、對象數(shù)組等傳值類型,上傳/下載文件類型需要注意。


spring restful 注意命名,對命名要求很嚴格。


spring shell 命令行方式執(zhí)行命令,救火、導(dǎo)入導(dǎo)出數(shù)據(jù)等用起來非常方便、制作報表。


5. Web基礎(chǔ)


5.1 web容器啟動


1.web.xml加載順序: listener -> filter -> servlet


2.webt容器啟動過程,java新手很怕配置文件,理解完這些有助于熟悉配置文件 http://blog.csdn.net/u014431852/article/details/47042895


5.2 Servlet、Interceptor、Listener、Filter


Servlet 接收請求返回響應(yīng),最原始的web業(yè)務(wù)處理類。


Interceptor 攔截器,可以實現(xiàn)HandlerInterceptor接口自定義攔截器,在日志記錄、權(quán)限檢查、性能監(jiān)控、通用行為等場景使用,本質(zhì)是AOP。


Listener 監(jiān)聽器 常用于統(tǒng)計在線人數(shù)等縱向功能。


Filter 過濾器 在請求接口處理業(yè)務(wù)之前改變requset,在業(yè)務(wù)處理之后響應(yīng)用戶之前改變response。如果某些數(shù)據(jù)不加密,很容易用抓包工具加filter作弊。


5.3 web項目結(jié)構(gòu)


5.3.1 mvn結(jié)構(gòu)


熟練掌握幾種常見的mvn項目結(jié)構(gòu),mvn可以自動生成,這里不再詳述。


5.3.2 mvn包管理


1.版本號盡量幾種在一個文件中便于管理。


2.spring milestone包解決spring包沖突問題。


3.mvn dependency:tree命令分析所有包依賴,對于沖突的在pom文件中<exclusion> 包圍起來


5.3.3 版本控制


1.git、svn等


2.代碼沖突解決方案


3.分支管理。


對于某個穩(wěn)定版本上線后,如果在此基礎(chǔ)上開發(fā)新功能,一定要新建分支,在新分支上提交代碼,最后在新版發(fā)布時合并分支。修改運營環(huán)境bug切換到主分支進行修改


5.4 Http請求


5.4.1 請求方法


post、get、put、head、delete、copy、move、connect、link、patch,最常用的是前4、5個。


5.4.2 請求頭,狀態(tài)碼


常用的請求頭有Accept(下載文件會特殊使用)、Accept-Charset(設(shè)置utf-8字符集)、Content-Type(json等配置)等


常用的響應(yīng)頭有Content-Type、Content-Type、Content-Length等,偏前端,不再詳述。


6. 系統(tǒng)架構(gòu)


接觸的不是特別多,目前用到的只是服務(wù)器主從備份。Nginx反向代理進行配置。


多個項目nginx配置


Spring Mvc 用json數(shù)據(jù)進行交互,配置json轉(zhuǎn)換的servlet。


封裝返回值


自定義RunEnvironmentException(狀態(tài)碼,原因),覆蓋原有Exception,切面ExceptionHandler抓取Exception并封裝到返回值中(前后端松耦合)


  令人頭疼的用戶重復(fù)(連續(xù)快速點擊)提交問題,前端限制治標不治本;后端用sessonid在切面上實現(xiàn),又需要前端存儲,對所有請求數(shù)據(jù)加sessionId。最后用jedis中存儲,用接口名+用戶名當做key,根據(jù)不同的接口對不同的key可以單獨設(shè)置時間,不僅保證了重復(fù)提交問題,也避免了惡意請求問題,同時還能自定義請求間隔。(期初擔心redis緩存讀寫時間延誤導(dǎo)致限制失效,后來發(fā)現(xiàn)多慮了,對一般的小系統(tǒng)來說,經(jīng)性能測試,發(fā)現(xiàn)即使請求頻率再提高100被也不會導(dǎo)致限制失效)


testNg單元測試、性能測試,覆蓋測試。


切面管理日期、權(quán)限。緩存等。


7. Nosql


1.Redis的java庫Jedis。


Jedispool配置。


項目中用到的有任務(wù)隊列、緩存。


  2. neo4j圖數(shù)據(jù)庫


處理社交、推薦


8. 服務(wù)端


linux操作系統(tǒng)熟悉以centos為例:


常用簡單命令:ssh、vim、scp、ps、gerp、sed、awk、cat、tail,df、top,shell、chmod、sh、tar、find、wc、ln、|


目錄結(jié)構(gòu)明細:/etc/、~/、/usr/、/dev/、/home/、/etc/init.d/


服務(wù)端:jdk、tomcat、nginx、mysql、jedis、neo4j啟動與配置(特別說明的是該死的防火墻,nginx啟動后一直訪問不了,查找一下午查不到原因,最后發(fā)現(xiàn)是防火墻問題)


監(jiān)控服務(wù)器狀態(tài)(cpu,磁盤,內(nèi)存),定位pid,日志查看


nginx負載均衡、反向代理、配置


自動化部署腳本


簡單shell腳本書寫,避免大量人力勞動。


監(jiān)控系統(tǒng),代碼拋fatal異常自動發(fā)郵件,系統(tǒng)指標持續(xù)偏高自動發(fā)郵件。


9. 數(shù)據(jù)庫相關(guān)


10. 第三方接口對接


10.1 支付接口


微信支付坑比較多,用將近兩周時間才把微信支付所有完成。需要在微信后臺配置的地方太多。


而支付寶支付模塊只用了2天時間就搞定了。


10.2 推送接口


為用戶定義tag、定義alias,注意當數(shù)據(jù)更新時需要同步更新tag、更新alias。如果沒采用異步實現(xiàn)(用戶體驗就是好卡?。?/p>


10.3 云存儲


大量文件上傳云端(七牛云),注意創(chuàng)建bucket


10.4 短信驗證


很簡單的第三方接口,引入依賴,直接調(diào)用即可。需要在第三方后臺設(shè)置模板等,注意限定用戶訪問次數(shù)。


? ? ? 在這里我推薦下我自己建的Java學(xué)習(xí)群:479121291,歡迎初學(xué)和進階中的Java小伙伴進入學(xué)習(xí)交流。?


10.5 郵件


很簡單小功能,工具類。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容