java開發經驗分享

來源:互聯網
上載者:User

開發經驗分享 一、 編碼

1. 約束自己,規範編碼習慣

充足的代碼注釋、標準縮排的格式、注意命名規範。參考《開發管理規範》

"看上去"專業能促進代碼品質。越是難看的代碼,在它的演化過程中會越來越差。因為當你看到你要bugfix的代碼很亂,那麼在bugfix的時候一般也會草草了事。一個方法有400行,在修改這個方法的時候大家不會在意再加上幾十行代碼。因為它看起來很差,它就是很差,我沒必要美化它。反過來說,如果待改的代碼很整潔很規範,那麼修改者也會比較小心。

2. 避免冗長的方法和類

應將方法設計成簡要的、功能性單元,用它描述和實現一個不連續的類介面部分。理想情況下,方法應簡明扼要。若長度很大,可考慮通過某種方式將其分割成較短的幾個方法。這樣做也便於類內代碼的重複使用(有些時候,方法必須非常大,但它們仍應只做同樣的一件事情)。

3. 不要向標準輸出寫無用資料

System.out.println(); 此語句在程式中隨處可見,都是在調試時使用的,在程式正式運行時也沒有將其去掉,結果就是日誌中有大量的無用資料,不僅使得日誌不易分析,也增加了系統的開銷。

如要調試可用LogWriter,將WEB-INF/ini/merpserver.ini中loglevel設為4

4. 調用方法前注意參數校正,判斷參數是否為空白或無意義的值

5. 使用對象前,檢查對象是否為空白

if(names!=null&&names.length>0){

String[] nameArray = names.split(‘,’);

}

if(userEn!=null){

String name = userEn.getName();

}

6. 避免過多過常的建立java對象

盡量避免在經常調用的方法、迴圈中new對象,由於系統不僅要花費時間來建立對象,而且還要花時間對這些對象進行記憶體回收和處理,在我們可以控制的範圍內,最大限度的重用對象,最好能用基本的資料類型或數組來替代對象。

7. 盡量避免隨意使用類成員變數

當某個對象被定義為stataic變數所引用,那麼gc通常是不會回收這個對象所佔有的記憶體的。此時類成員變數的生命週期與類同步,如果類不卸載,那麼該對象會常駐記憶體,直到程式終止

8. 減少對變數的重複計算

如

for(int i=0;i<list.size();i++)

應該改為

for(int i=0,len=list.size();i<len;i++)

並且在迴圈中應該避免使用複雜的運算式,在迴圈中,迴圈條件會被反覆計算,如果不使用複雜運算式,而使迴圈條件值不變的話,程式將會啟動並執行更快

9. 避免不必要的建立對象

如

A a = new A();

if(i==1){

list.add(a);

}

應該改為

if(i==1){

A a = new A();

list.add(a);

}

10. 原則上迴圈裡面不要聲明對象,一律在迴圈外面聲明

for(int i=0;i<size;i++){

String title = “標題”;

}

改為

String title = null;

for(int i=0;i<size;i++){

title = “標題”;

}

11. 盡量在finally塊中釋放資源

程式中使用到的資源應當被釋放,以避免資源泄漏。這最好在finally塊中去做。不管程式執行的結果如何,finally塊總是會執行的,以確保資源的正確關閉。

12. 使用StringBuilder和StringBuffer進行字串串連

StringBuffer提供了同步機制,所以並發線程訪問是安全執行緒的,適合多線程。

StringBuilder沒有提同步機制,所以線程不安全,適合單線程,但如果是單線程的話,要比StringBuffer快。

13. 遍曆HashMap使用entrySet

當需要遍曆HashMap的時候,請盡量使用entrySet,而不要用keySet,entrySet的效率要比keySet高,實際上使用entrySet是只需要遍曆一次hash,即將key和value的映射關係放入到entry中,再取之;而keySet需要兩次遍曆hash,第一次取所有的key,第二次用key去取出對應的value。

Iterator iter = hashMap.entrySet().iterator();

while (iter.hasNext()) {

Map.Entry entry = (Map.Entry) iter.next();

String key = String.valueOf(entry.getKey());

String val = String.valueOf(entry.getValue());

}

14. 盡量緩衝經常使用的對象

儘可能將經常使用的對象進行緩衝,可以使用數組,或HashMap的容器來進行緩衝,但這種方式可能導致系統佔用過多的緩衝,效能下降。

推薦參考《開發指南》,使用EHCache

15. 使用統一的工具類

使用hanwebcommon.jar中的通用方法,具體參考《開發指南》

使用項目中已經存在的工具類,不要重複創造功能近似的類和方法,如果必要可進行擴充

如:接收參數使用Convert.getParameter(request, 參數名);

16. 減少不必要的空格和空行,參考《開發管理規範》

17. java代碼中不要出現黃色警告。注釋或刪除未使用的變數;儲存時去掉多餘的import;…

18. 前台接收Stirng型別參數,要進行跨站指令碼和sql注入過濾

Convert.getParameter(request,"keyword","",true,true);

19. 不要在jsp中實現商務邏輯,放到類中去完成

分層設計實現了軟體之間的解耦;便於進行分工;便於維護;提高軟體組件的重用;便於替換某種產品,比如持久層用的是hibernate,需要更換產品用toplink,就不用改其他業務代碼,直接把配置一改;便於產品功能的擴充;便於適用使用者需求的不斷變化。

20. 避免在迴圈體中使用try-catch 塊,最好在迴圈體外使用try--catch 塊以提高系統性

21. oracle大欄位操作

先插入一個空的clob類型 empty_clob(),然後再單獨更新clob欄位

InsertSql insql = new InsertSql( strTableName ); 

    insql.addString("vc_name", name);

    if (("oracle").equals(SysInit.getM_strDB_Type())){

     insql.addClob("vc_adress");

     insql.addClob("vc_path");

    }else{

        insql.addString("vc_adress", address);

        insql.addString("vc_path", path);

}

boolean bl = Manager.doExcute(strAppID , insql.getSql());

if(bl){

if (("oracle").equals(SysInit.getM_strDB_Type())){

String[] strFieldValue = {address, path};

String[] strFieldName ={"vc_adress","vc_path"};

Manager.doClob(strAppID, strFieldName, strFieldValue, strTableName, " WHERE i_id = " + getMaxId());

}

}

22. 使用統一的<!DOCTYPE>,保證不同瀏覽器下的頁面相容

建議使用:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

23. HTML結構要完整、正確

標準的HTML文檔結構:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Insert title here</title>

……

</head>

<body>

……

</body>

</html>

其它:

<ul>

<li>……</li>

<li>……</li>

</ul>

<table>

<tr>

<td>……</td>

</tr>

</table>

24. HTML標籤要完整

標籤名稱及屬性統一使用小寫,標籤要成對出現,如:

<div id=”search”>………</div>

不用於包含內容的標籤,可在標籤結尾使用“/”標記結束,如:

<input type=”text” name=”username” value=”tony” />

<br/> 

25. 標籤屬性值必須用雙引號包住

26. HTML代碼使用標準縮排

27. 指令碼每一條語句都要以分號結尾

28. 具有獨特性、不需要重複使用的樣式,使用內嵌樣式:

<div style=”title”>標題<div>

能夠重複使用的樣式,在樣式表中定義:

<li class=”menu”>菜單</li>

頁面內使用的樣式,使用內嵌樣式表:

<style type="text/css">

.menu{

color:black;

font-size:13px;

}

</style>

多個頁面公用的樣式使用鏈入外部樣式表:

<link href="../global.css" rel="stylesheet" type="text/css" />

29. 頁面內使用的指令碼函數,在head中定義:

<script type=”text/javascript”>

function checkForm(){

……

}

</script>

重複使用的指令碼函數或代碼較多的指令碼,寫到外本指令檔中,在head中連結:

<script type=”text/javascript” src=”../checkform.js” />

不影響頁面本身展示的指令碼可考慮放在body結束的位置調用,如廣告代碼:

……

<script type=”text/javascript” src=”../adv.js” />

</body>

30. 風格統一,儲存時要對代碼進行格式化,Ctrl+Shift+F

31. 養成程式最佳化的意識

現在我們經常遇到的一個問題是,程式在開發階段,執行的完全正常,找測試人員測試也沒問題,但是一到上線後,效能馬上出問題了,運行速度像蝸牛,客戶不堪忍受,為什麼。簡單的說,開發人員自測,估計也就幾條資料,測試人員測試,估計也就幾十上百條資料,一般的程式碼,在這個數量級,效能瓶頸根本就表現不出來。但是上線後,客戶的資料一般都上升到10000層級的,如果程式碼中沒有做到細微之處都很嚴謹的話,問題就馬上暴露出來了。

  二、 資料庫

1. SQL語句中保留字、函數名要大寫,表明、欄位名全部小寫

如:SELECT vc_name,vc_sex,i_age FROM user WHERE i_id = 100 AND i_type = 2

2. 使用標準SQL語句,防止資料庫相容問題

3. 迴圈裡面(包括迴圈調用方法內)避免過多操作資料庫

4. 選擇最有效率的表名順序

ORACLE 的解析器按照從右至左的順序處理FROM子句中的表名,FROM子句中寫在最後的表(基礎資料表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,必須選擇記錄條數最少的表作為基礎資料表。如果有3個以上的表串連查詢, 那就需要選擇交叉表(intersection table)作為基礎資料表, 交叉表是指那個被其他表所引用的表

5. 注意WHERE子句中的串連順序

ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的串連必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾

6. SELECT子句中避免使用*

ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間

7. 減少訪問資料庫的次數,盡量大量操作資料庫,如大量刪除

ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變數 , 讀資料區塊等

8. 避免在WHERE子句中使用in,not  in,or 或者having

可以使用 exist 和not exist代替 in和not in

9. 用WHERE子句替換HAVING子句

避免使用HAVING子句, HAVING 只會在檢索出所有記錄之後才對結果集進行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷。

10. 用好資料庫事務

事務是指作為單個邏輯工作單元執行的一系列操作。通過將一組相關操作組合為一個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢複並使應用程式更加可靠。

Transaction ts = null;

try{

ts = new Transaction(appId);

…

…

boolean bl = ts.execute(sql);

if(bl){

bl = ts.commit();

}

if(!bl){

throw new Exception();

}

}catch(Exception e){

if(ts!=null)

ts.roolback();

bl = false;

}

11. 注意SQL執行效率,考慮單表記錄10W以上的運行效果

setup中,日誌顯示層級為警告以上時,執行時間超過300ms的SQL語句,會在日誌中輸出warning

12. 索引

參考《開發管理規範》

  三、 項目開發

1. 需求:

1) 需求最終需要開發人員在產品中實現,開發不合理的設計會浪費時間,開發技術無法實現的設計帶來最大的痛苦:失敗。所以,開發人員要重視需求以及需求評審,提出自己能夠想到的所有異議;

2) 開發人員不但要做好需求分析,還要做出精確的估計。因為編碼工作保質保量的按時完成需要多方的準備工作,技術痛點需要進行充分的技術預言,不熟悉的依賴平台或類庫要進行熟悉;

2. 計劃:一棟樓很難估算重量,但是一塊磚頭可以精確估算重量。一個項目的時間很難準確的估計,但把項目開發劃分為不能再進行分割的模組功能點,對每個點的估計是可以更精準的估時的,由此由上至下,由下至上,可以得出近乎準確的開發時間。

3. 設計:

1) 一圖勝萬言,模組結構以及流程等很難用用文字描述,即使用文字描述出來也很難看懂,所以在設計中,要善用用圖;

2) 詳細設計過程中有思考的痛苦,繁瑣的痛苦,但是繞過這些痛苦,編碼期間將會面臨更大的痛苦,要以快樂的心態面對。

4. 編碼:

1) 對於一個實現可以有很多解決方案,花些時間精力選取你認為最好的解決方案可以總體上提高工作成效,往往還可以得到使用者更好的體驗效果;

2) 細緻認真嚴謹的工作即是對工作負責,更是對自己負責,讓這些成為習慣。任何一次,任何時候所進行的編碼工作,在邏輯、風格、簡單有效等方面都儘可能的做到最好,既能更好為公司實現價值,同時更有利自己在技能,崗位的進步;

3) 簡單是美,在有效前提下,越是簡單的處理方法越是珍貴的,代碼編寫也是,簡單的代碼便於理解維護,同時不容易產生錯誤

4) 慎做改動,當然不是說不做改動或不鼓勵改動,而是不做倉促、草率的代碼改動。沒有洞察全域,考慮全面,而倉促進行的改動往往沒有達到改動的目的卻帶來了其他問題

5) 模組的效能不是減少一行或幾行執行代碼所能提高的,效能的最佳化首先是從演算法上考慮,降低時間複雜度,然後從執行邏輯入手,減少迴圈執行代碼的執行次數

6) 關鍵地方要列印日誌輸出到檔案中,在運行過程中不斷檢查日誌,發現任何異常都要檢查原因並修改

5. 測試:

1) 事出有因,任何bug都是由於代碼的疏漏造成的,利用排除法或跟蹤調試代碼等方法找到疏漏所在;

2) 遇到自身模組相關問題首先檢查自己,相互推諉只會浪費時間以及減弱在其他同事對你的信任;

3) 站的高看得遠,不同的視角有不同的風景。遇到比較難解決的問題而苦苦沒有思路時,轉換思路或把問題的考慮範圍放的更廣一點,往往可以找到解決方案

4) 功能提交測試前或bug修複提交驗證前,開發人員都要自己詳細的測試一下,驗證無誤再提交。(參考附錄2--測試常見問題)

6. 其它:

1) 善於及時的溝通。在項目的整個流程過程中,遇到他人的問題或自己解決不了的問題,切忌堆在自己心裡,要及時找問題解決方進行溝通,尋求解決方案

2) 善於發現並學習別人的長處。作為開發人員,我們在追求接近完美的同時,也需要學會欣賞別人的長處,發現別人的優點,並學習別人的優點,轉化為自己的潛質,這樣,我們才可以進步的更快,更全面

3) 善於協助他人解決問題以及進行知識經驗的分享,更有利於自己的提高,同時還可以獲得他人的尊重 四、 關於測試

1. 在整個專案計劃中,測試時間安排的合理性,對測試階段的情況應作充分預計,不可為了趕發布點而忽略品質。

2. 務必清楚產品包、更新包、bug包的提交規範。具體請參照《開發規範手冊》。不要出現測試過程中提交多個bug包,或者提交安裝包給測試人員更新的情況。

3. 提包時請先檢查,路徑是否正確、檔案是否完整、設定檔是否應該提交,原始碼修改記錄描述是否完善。之前經常出現,提包不檢查就直接提交來測試,導致出錯後環境不斷地還原或者重建新的環境。CVS使用不熟悉,提交檔案反覆出錯。

4. 產品品質需要嚴格控制,自己承認是問題的情況下,請不要試圖和測試商談希望可以不被追究。

5. 請注意提高修改bug的品質,目前,修改一個bug而引發更多的bug的情況特別多。

6. bug修改完成後,在提交測試前請自己先驗證通過後再提交,請不要修改完成後不驗證就直接提交給測試人員,防止導致bug被反覆reopen的情況。

7. 原則上不允許不通過CVS而直接提交檔案給測試人員調試問題、尋找原因。如果確有必要,測試人員可以協助調試,但次數不宜過多,防止測試環境版本難以控制。

8. bug是否存在的衡量標準以測試環境為準,不建議出現“我這邊是好的”這樣的解釋。

9. 修改bug時請修改完整,可能會有多個小問題提交在一個BUG裡面,BUG修改時多個小問題的地方均需修改。

10. 更新檔案必須通過配置發布,無論是否經過測試都不允許直接發給項目或直接更新客戶服務器

  五、 開發環境

1. Eclipse記憶體溢出、崩潰、無響應、啟動慢

1) 建立多個workspace

2) 將workspace中暫時不用的工程close

3) 修改eclipse設定檔eclipse.ini,參考知識庫:

-Xms512m

-Xmx512m

-XX:PermSize=96m

-XX:MaxPermSize=96m

2. Eclipse統一字元集為UTF-8

1) 進入Eclipse->Window->Preferences->General->Workspace介面,在“Text file encoding”中選擇“other”並在下拉式清單中選擇“UTF-8”,並點擊【Apply】後,點擊【OK】確認儲存

 

2) 修改jsp檔案頭部

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>

將字元集改為“UTF-8”

3) 進入Eclipse->Window->Preferences->Web->JSP Files介面,將“Encoding”屬性修改為“ISO 10646/Unicode(UTF-8)”

 

4) 已建立的項目,右鍵點擊項目名稱,進入Properties->Resource介面,選擇“Text file encoding”編碼為“UTF-8”

3. 開啟Eclipse記憶體監視及回收外掛程式

進入Eclipse->Window->Preferences->General介面,勾選“Show heap status”,點擊【Apply】後,點擊【OK】確認儲存。Eclipse右下角,會顯示JVM記憶體使用量情況。

 

點擊垃圾桶表徵圖,可進行手動回收

4. 設定斷點,進行調試

1) 行斷點

行斷點是最普通的斷點。只要在Eclipse Java 編輯區的行頭雙擊就會得到一個斷點,代碼會運行到此處時停止

 

2) 條件斷點

條件斷點,顧名思義就是一個有一定條件的斷點,只有滿足了使用者佈建的條件,代碼才會在運行到斷點處時停止。

在斷點處點擊滑鼠右鍵,選擇最後一個"Breakpoint Properties"

斷點的屬性介面及各個選項的意思如下圖,

3) 變數斷點

斷點不僅能打在語句上,變數也可以接受斷點

下圖就是一個變數的打的斷點,在變數的值初始化,或是變數值改變時可以停止,當然變數斷點上也是可以加條件的,和條件斷點的設定是一樣的

4) 方法斷點

方法斷點就是將斷點打在方法的入口處,方法斷點的特別之處在於它可以打在 JDK的源碼裡,由於 JDK 在編譯時間去掉了調試資訊,所以普通斷點是不能打到裡面的,但是方法斷點卻可以,可以通過這種方法查看方法的調用棧

5) 類型載入斷點

可以查看什麼時候載入的類

 

6) 異常斷點

當異常發生時,代碼會停在異常發生處,定位問題時應該比較有協助

開啟Breakpoints視圖,點擊按鈕,增加異常斷點

5. 修改代碼字型

進入Eclipse->Window->Preferences->General->Appearance->Colors and Fonts介面,選擇Basic->Text Font,點擊右側【Edit…】,選擇。點擊【Apply】後,點擊【OK】確認儲存

 

6. Eclipse快速鍵,見“附錄1—Eclipse快速鍵”

  六、 Linux

見《Linux_命令詳解》

常用命令:

cd 變換工作目錄

cd / 返回根目錄 cd ../ 返回上層目錄

ls 顯示指定工作目錄下的內容

mv 將一個檔案移至另一個檔案,或將數個檔案移至另一個目錄

mv /data/m3 /root 將/data/m3轉移到/root目錄下

mkdir 建立指定的目錄名

mkdir /root/temp 在root目錄下建立temp目錄

rm 刪除檔案及目錄

rm –rf 檔案/檔案夾 徹底刪除檔案/檔案夾

rmdir 刪除空的目錄

kill 終止進程

kill -9 2342 殺掉進程標識號PID為2342的進程

ps 報告進程狀況

ps –ef|grep java 查看java進程

tail 從指定點開始將指定的檔案寫到標準輸出

tail –f nohup.out 即時讀取日誌nohup.out的更新內容

su 變更為其它使用者的身份

su – user1 切換到使用者user1

cp 複製

cp config.xml /data/ 將config.xml檔案複製到/data/目錄下

reboot 重啟伺服器

halt 關閉伺服器

top 顯示目前正在系統中執行的程式

free 顯示系統記憶體與swap使用的情況

java –version 查看JDK版本

chromd 777 /temp/runthread.sh 賦予使用者/temp/runthread.sh最大許可權

cat /dev/null > nohup.out 清空日誌nohup.out檔案內容

df –hl 查看磁碟空間與使用方式

du 顯示目錄下所有檔案並列出檔案大小

pwd 查看當前所在路徑

export lang=zh_CN 修改環境變數lang值,解決linux亂碼

./startup.sh tomcat啟動

nohup ./startWeblogic.sh & weblogic啟動(不掛斷運行,防止登出後weblogic停止)

./startServer.sh server1  websphere啟動

  七、 常見問題

1. jsp出現getOutputStream() has already been called for this response

jsp中出現此錯誤一般都是在jsp中使用了輸出資料流(如輸出圖片驗證碼,檔案下載等),沒有妥善處理好造成的。

jsp編譯成servlet之後在函數</

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.