畢業已經一年有餘,這一年裏特別感謝技術管理人員的器重,以及同事的幫忙,學到了很多東西。這一年裏走過一些彎路,也碰到一些難題,也受到過作爲一名開發卻常常爲系統維護和發佈當救火隊員的苦惱。遂決定梳理一下本身所學的東西,爲你們分享一下。html
通過一年意識到之前也有不少認識誤區,好比:前端
偏心收集,常常收集各類資料視頻塞滿一個個硬盤,而後心滿意足的看着容量不行動。java
不重基礎,總以爲不少基礎東西不須要再看了,其實不懂的地方不少,計算機程序方面任何一個結果都必有緣由,不要只會用不知道原理,那是加工廠出來的。如今ide查看代碼那麼方便,ctrl+點擊就進入了JDK查看實現細節。mysql
好高騖遠,在計算機基礎不牢固的狀況下,總想着要作架構,弄分佈式,搞大數據之類。linux
不重視性能,只求能實現功能,sql查詢是否是能夠優化,是否有算法妙用,大對象是否要清除。nginx
不重視擴展性,模塊之間緊密耦合,經常使用方法不提取成工具類,調用關係混亂等問題。git
……程序員
本文重點不在這些,故只列舉了一小部分,下面進入正題。web
這是全部狀況的類初始化順序,若是實際類中沒有定義則跳過:父類靜態變量——父類靜態代碼塊——子類靜態代碼塊——父類非靜態變量——父類非靜態代碼塊——父類構造函數——子類非靜態變量——子類非靜態代碼塊——子類構造函數面試
可能不少人對此不屑一顧,心想老子都工做一年了,對這些還不熟悉嗎?但實際狀況並不是這樣,JDK中東西所有熟悉了嗎?以一個最簡單的例子開始,你以爲下圖中代碼執行完以後fatherList中的元素是什麼?
這是一個最基礎的值傳遞和引用傳遞的例子,你以爲好簡單,已經想躍躍欲試的挑戰了,那麼請看下面的,StringBuffer很好理解,可是當你執行一遍以後發現是否是和預想中的輸出不同呢?String不是引用類型嗎,怎麼會這樣呢?若是你沒法理解,那麼請看下String的實現源碼,瞭解下其在內存中分配的實現原理。
這部分幾乎每一個人都會用到,並且你們還都不陌生。下圖來源於互聯網,供你們複習一下。可是利用集合的特性進行巧妙的組合運用能解決優化不少複雜問題。Set不可重複性,List的順序性,Map的鍵值對,SortSet/SortMap的有序性,我在工做中有不少複雜的業務都巧妙的使用了這些,涉及到公司保密信息,我就不貼出代碼了。工做越久愈加現這些和越巧妙。
1.看着try、catch、finally很是容易,若是和事務傳播結合在一塊兒,就會變得極其複雜。
2.finally不必定必須執行,return在catch/finally中處理狀況(建議親自操刀試一下)。
3.catch中能夠繼續拋自定義異常(並把異常一步步傳遞到控制層,利用切面抓取封裝異常,返回給調用者)。
一提起面向對象,你們都知道抽象、封裝、繼承、和多態。可是實際工做經驗中又知道多少呢,對於項目中如何巧用估計更不要提了。
共性的機會每一個都須要用的創建基類,如每一個控制層方法可能要經過security獲取一個登陸用戶id,用於根據不一樣的用戶操做不一樣的數據,能夠抽象出一個應用層基類,實現獲取id的protect方法。同理DAO層能夠利用泛型提取出一個包含增刪改查的基類。
多態的Override:基類的引用變量不只能夠指向基類的實例對象,也能夠指向其子類的實例對象,若是指向子類的實例對象,其調用的方法應該是正在運行的那個對象的方法。在策略模式中使用很廣泛。
提到面向對象,就不可避免的要說設計模式,在工做中,一個技術大牛寫的一個相似策略模式(更復雜一點),十分巧妙的解決了各類業務同一個方法,而且實現了訂單、工單、業務的解耦,看得我是很是佩服。我想不少面試中都會問道單例模式吧,尚未理解的建議去看一看。
這個是老生常談的問題了,可是確實是問題和bug高發區。線程同步問題不須要單獨寫了,想必你們都清楚,不太熟悉的建議百度一下。
1.代碼中若是有同步操做,共享變量要特別注意(這個通常都能意識到)
2多個操做能修改數據表中同一條數據的。(這個容易被忽略,業務A可能操做表a,業務B也能夠操做表a,業務A、B即便在不一樣的模塊和方法中,也會引發線程安全問題。例如若是一我的訪問業務A接口,另外一我的訪問業務B接口,在web中每一個業務請求都是會有單獨的一個線程進行處理的,就會出現線程安全問題)。
3.不安全的類型使用,例如StringBuffer、StringBuild,HashTable、HashMap等。在工做中我就遇到過有人在for循環進行list的remove,雖然編譯器不報錯,程序能夠運行,可是結果卻可想而知。
4.Spring的bean默認是單例的,若是有類變量就要特別當心了(通常狀況下是沒人在控制層、業務層、DAO層等用類變量的,用的話建議是final類型,例如日誌log,gson等)。
5.多個系統共享數據庫狀況,這個其實和分佈式系統相似
用戶重複提交問題(即便代碼中從數據庫讀取是否存在進行限制不能解決問題)
在須要同步的地方採用安全的類型。
JDK鎖機制,lock、tryLock,synchronized,wait、notify、notifyAll等
Concurrent併發工具包,在處理一些問題上,誰用誰知道。強烈建議查看源碼!
數據表加鎖。(除非某個表的訪問頻率極低,不然不建議使用)
涉及分佈式的,採用中間件技術例如zookeeper等解決。
異步使用場景不影響主線程,且響應較慢的業務。例如IO操做,第三方服務(短信驗證碼、app推送、雲存儲上傳等)。
若是異步任務不少,就須要使用任務隊列了,任務隊列能夠在代碼級別實現,也能夠利用redis(優點太明顯了)。
這方面文章很是多,這裏不在詳述。
1.共享變量方式(共享文件、全局變量,信號量機制等)
2.消息隊列方式
3. 忙等,鎖機制
1.集成Thread類,重寫(這裏的重寫指的是override)run方法,調用start方法執行。
2.實現Runable接口,實現run方法,以Runable實例建立thread對象。
3.實現Callable接口,實現call方法,FutureTask包裝callable接口,FutureTask對象建立thread對象,經常使用語異步操做,建議使用匿名內部類,方便閱讀和使用。
額外須要說明的是:
1.理解thread的join方法;
2.不要認爲volitate是線程安全的(不明白緣由的建議去看jvm運行時刻內存分配策略);
3.sleep時間片結束後並不保證立馬獲取cpu。
4.ThreadLocal可以爲每個線程維護變量副本,經常使用於在多線程中用空間換時間。
相信每個java程序員對這些都不陌生,這裏再也不詳述。
須要說明的主要如下幾點:
1.hibernate一級緩存(內置session緩存),二級緩存(可裝配sessionFactory緩存),二級緩存會引發併發問題。
2.hibernate延遲加載原理理解。
3.hibernate 的get、load方法,sava、persist、savaOrUpdate方法區別
4.session重建了關聯關係卻並無同數據庫進行同步和更新
5.hibernate session關聯關係:detached對象、persistent對象
6.Spring data集成,註解方式配置屬性和實體。
7.mybatis 插件。
8.分頁查詢(數據庫)。
9.鏈接池技術
1.bean注入 註解方式方便易讀,引用第三方(數據庫鏈接,數據庫鏈接池,JedisPool等)採用配置文件方式。
2. bean做用域:Singleton,prototype,request,session,global session
3.bean生命週期:以下圖所示(圖片來源於互聯網):
基本概念:關注點、切面Aspect、切入點pointcut、鏈接點joinpoint、通知advice、織入weave、引入introduction。
Spring AOP支持5中類型通知,分別是MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice、MethodInterceptor、IntroductionInterceptor(吐槽一下名字太長)
實現方式以下:
1.基於代理的AOP
2.基於@Aspect註解驅動的切面。(強烈推薦:可讀性好,易維護,易擴展,開發快)
3.純POJO切面。
4.注入式Aspect切面。
概念:某些操做須要保證原子性,若是中間出錯,須要事務回滾。若是某個事務回滾,那麼調用該事務的方法中的事務的做出如何的動做,就是事務傳播。
短期內寫不清楚,建議訪問 http://www.cnblogs.com/yangy608/archive/2010/12/15/1907065.html 查看。
事務傳播屬性:
1. PROPAGATION_REQUIRED--支持當前事務,若是當前沒有事務,就新建一個事務。這是最多見的選擇。
2. PROPAGATION_SUPPORTS--支持當前事務,若是當前沒有事務,就以非事務方式執行。
3. PROPAGATION_MANDATORY--支持當前事務,若是當前沒有事務,就拋出異常。
4. PROPAGATION_REQUIRES_NEW--新建事務,若是當前存在事務,把當前事務掛起。
5. PROPAGATION_NOT_SUPPORTED--以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
6. PROPAGATION_NEVER--以非事務方式執行,若是當前存在事務,則拋出異常。
事務隔離級別:
1. ISOLATION_DEFAULT: 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別.另外四個與JDBC的隔離級別相對應
2. ISOLATION_READ_UNCOMMITTED: 這是事務最低的隔離級別,充許令外一個事務能夠看到這個事務未提交的數據。這種隔離級別會產生髒讀,不可重複讀和幻像讀。
3. ISOLATION_READ_COMMITTED: 保證一個事務修改的數據提交後才能被另一個事務讀取。另一個事務不能讀取該事務未提交的數據
4. ISOLATION_REPEATABLE_READ: 這種事務隔離級別能夠防止髒讀,不可重複讀。可是可能出現幻像讀。它除了保證一個事務不能讀取另外一個事務未提交的數據外,還保證了避免下面的狀況產生(不可重複讀)。
5. ISOLATION_SERIALIZABLE 這是花費最高代價可是最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀外,還避免了幻像讀。
spring boot 輕量級啓動框架
spring security 用戶權限管理,根據角色和用戶,實現UserDetailsService,進行自定義權限管理。
spring task 代碼級定時任務,註解方式,使用起來很是方便。須要注意的是,若是某次定時任務出了異常而沒有進行處理,會致使接下來定時任務失效。若是各個任務相互獨立,能夠簡單用try,catch包圍(以前就吃過這方面的虧)。
spring data 註解方式定義實體,屬性等
spring mvc 簡單明瞭的mvc框架。url傳值、數組傳值、對象傳值、對象數組等傳值類型,上傳/下載文件類型須要注意。
spring restful 注意命名,對命名要求很嚴格。
spring shell 命令行方式執行命令,救火、導入導出數據等用起來很是方便、製做報表。
1.web.xml加載順序: listener -> filter -> servlet
2.webt容器啓動過程,java新手很怕配置文件,理解完這些有助於熟悉配置文件 http://blog.csdn.net/u014431852/article/details/47042895
Servlet 接收請求返回響應,最原始的web業務處理類。
Interceptor 攔截器,能夠實現HandlerInterceptor接口自定義攔截器,在日誌記錄、權限檢查、性能監控、通用行爲等場景使用,本質是AOP。
Listener 監聽器 經常使用於統計在線人數等縱向功能。
Filter 過濾器 在請求接口處理業務以前改變requset,在業務處理以後響應用戶以前改變response。若是某些數據不加密,很容易用抓包工具加filter做弊。
熟練掌握幾種常見的mvn項目結構,mvn能夠自動生成,這裏再也不詳述。
1.版本號儘可能幾種在一個文件中便於管理。
2.spring milestone包解決spring包衝突問題。
3.mvn dependency:tree命令分析全部包依賴,對於衝突的在pom文件中<exclusion> 包圍起來
1.git、svn等
2.代碼衝突解決方案
3.分支管理。
對於某個穩定版本上線後,若是在此基礎上開發新功能,必定要新建分支,在新分支上提交代碼,最後在新版發佈時合併分支。修改運營環境bug切換到主分支進行修改
post、get、put、head、delete、copy、move、connect、link、patch,最經常使用的是前四、5個。
經常使用的請求頭有Accept(下載文件會特殊使用)、Accept-Charset(設置utf-8字符集)、Content-Type(json等配置)等
經常使用的響應頭有Content-Type、Content-Type、Content-Length等,偏前端,再也不詳述。
接觸的不是特別多,目前用到的只是服務器主從備份。Nginx反向代理進行配置。
多個項目nginx配置
Spring Mvc 用json數據進行交互,配置json轉換的servlet。
封裝返回值
自定義RunEnvironmentException(狀態碼,緣由),覆蓋原有Exception,切面ExceptionHandler抓取Exception並封裝到返回值中(先後端鬆耦合)
使人頭疼的用戶重複(連續快速點擊)提交問題,前端限制治標不治本;後端用sessonid在切面上實現,又須要前端存儲,對全部請求數據加sessionId。最後用jedis中存儲,用接口名+用戶名當作key,根據不一樣的接口對不一樣的key能夠單獨設置時間,不只保證了重複提交問題,也避免了惡意請求問題,同時還能自定義請求間隔。(期初擔憂redis緩存讀寫時間延誤致使限制失效,後來發現多慮了,對通常的小系統來講,經性能測試,發現即便請求頻率再提升100被也不會致使限制失效)
testNg單元測試、性能測試,覆蓋測試。
切面管理日期、權限。緩存等。
1.Redis的java庫Jedis。
Jedispool配置。
項目中用到的有任務隊列、緩存。
2. neo4j圖數據庫
處理社交、推薦
linux操做系統熟悉以centos爲例:
經常使用簡單命令:ssh、vim、scp、ps、gerp、sed、awk、cat、tail,df、top,shell、chmod、sh、tar、find、wc、ln、|
目錄結構明細:/etc/、~/、/usr/、/dev/、/home/、/etc/init.d/
服務端:jdk、tomcat、nginx、mysql、jedis、neo4j啓動與配置(特別說明的是該死的防火牆,nginx啓動後一直訪問不了,查找一下午查不到緣由,最後發現是防火牆問題)
監控服務器狀態(cpu,磁盤,內存),定位pid,日誌查看
nginx負載均衡、反向代理、配置
自動化部署腳本
簡單shell腳本書寫,避免大量人力勞動。
監控系統,代碼拋fatal異常自動發郵件,系統指標持續偏高自動發郵件。
微信支付坑比較多,用將近兩週時間才把微信支付全部完成。須要在微信後臺配置的地方太多。
而支付寶支付模塊只用了2天時間就搞定了。
爲用戶定義tag、定義alias,注意當數據更新時須要同步更新tag、更新alias。若是沒采用異步實現(用戶體驗就是好卡啊)
大量文件上傳雲端(七牛雲),注意建立bucket
很簡單的第三方接口,引入依賴,直接調用便可。須要在第三方後臺設置模板等,注意限定用戶訪問次數。
很簡單小功能,工具類。
時間有限,目前先寫這麼多技術棧。對於代碼書寫和、算法技巧問題,會抽時間寫在(2)中。
Java學習交流QQ羣:589809992 禁止閒聊,非喜勿進!