已閱讀5頁(yè),還剩147頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
代碼審查技術(shù) 學(xué)習(xí)目標(biāo) 掌握代碼分析和評(píng)審技術(shù)掌握自動(dòng)化代碼分析工具的使用 建筑工程師的第一堂課 關(guān)注細(xì)節(jié) 關(guān)注并弄清楚橋梁修建細(xì)節(jié) 否則你建起來的橋就有可能坍塌 安全編程 代碼靜態(tài)分析 1940年TacomaNarrows大橋600英尺的一段坍塌落入普吉特灣 代碼審查對(duì)成本的節(jié)省 黑盒測(cè)試的缺陷 黑盒測(cè)試既不充分 而且效率也低 在系統(tǒng)完成之前 測(cè)試就無法開始 測(cè)試人員只有軟件版本發(fā)布時(shí)才能拿到版本進(jìn)行測(cè)試 Staticwhite boxtesting FindbugsearlyFindbugsthatwouldbedifficulttouncoverorisolatewithdynamicblack boxtestingCosteffectiveSidebenefit giveblack boxtesterideasfortestcasestoapplywhentheyreceivethesoftwarefortesting 不懂開發(fā)怎么做代碼審查 霍元甲因?yàn)樗救松眢w虛弱 所以父親從小不讓練武功 而生長(zhǎng)在那樣的環(huán)境中 他天天可以看到兄弟們?cè)诰毠?招式已經(jīng)記憶在心里 但是苦在沒有練功的機(jī)會(huì) 他利用體力勞動(dòng)的過程中 改變勞動(dòng)方式 趁機(jī)練功 后來發(fā)展到獨(dú)創(chuàng) 迷蹤拳 代碼靜態(tài)分析 靜態(tài)分析是指在不執(zhí)行的情況下對(duì)代碼進(jìn)行評(píng)估的過程 包括 類型檢查 風(fēng)格檢查 程序理解 BUG查找 安全審查 靜態(tài)分析 類型檢查 在Java中 下面的語(yǔ)句雖然符合類型檢查規(guī)則 但是會(huì)在運(yùn)行時(shí)失敗 拋出一個(gè)ArrayStoreException異常 Object objs newString 1 objs 0 newObject lint w2 lint e734 include stdafx h intmain charch 0 intn 0 ch n return0 VC6編譯通過 但是PCLint可以通過靜態(tài)代碼檢查找出類型轉(zhuǎn)換造成的精度丟失問題 靜態(tài)分析 風(fēng)格檢查 常見工具C C PC LintJAVA PMD NET StyleCop 風(fēng)格檢查更加挑剔 也更加注重空格 縮進(jìn) 命名 注釋 程序結(jié)構(gòu)這些表面的東西 風(fēng)格檢查程序所展示的錯(cuò)誤往往都是影響代碼的可讀性和可維護(hù)性的問題 typedefenum red green blue Color char getColorString Colorc char ret NULL switch c casered printf red returnret gcc的 Wall 選項(xiàng)將檢查出其中的問題 typedefconstchar CSTRING CSTRINGrevere intlights CSTRINGmanner byland if lights 0 if lights 2 manner bysea elsemanner returnmanner intmain printf TheBritisharecoming s n revere 1 return0 靜態(tài)分析 程序理解 程序理解工具能幫助我們搞懂代碼庫(kù)中的大量代碼 洞察程序運(yùn)轉(zhuǎn)之道 集成開發(fā)環(huán)境 IDE 一般至少都包含某些程序理解功能 例如 查找本方法的所有應(yīng)用 常用工具 代碼流程圖 CodeVisualtoFlowchart UML與源代碼雙向工程 例如Fujaba Fujiaba能在UML視圖和源代碼之間來回轉(zhuǎn)換 靜態(tài)分析 Bug查找 BUG查找的目的不像風(fēng)格檢查那樣抱怨格式方面的問題 而是根據(jù) BUG慣用法 規(guī)則 來描述代碼中潛在的缺陷 常用工具 PMD FindBugs Coverity Klocwork EmptyCatchBlock EmptyCatchBlockfindsinstanceswhereanexceptioniscaught butnothingisdone Inmostcircumstances thisswallowsanexceptionwhichshouldeitherbeactedonorreported Example publicvoiddoSomething try FileInputStreamfis newFileInputStream tmp bugger catch IOExceptionioe stringstr for inti 0 i 100 i str i ToString 靜態(tài)分析 安全審查 最早的安全工具ITS4 RATS Flawfinder比素有美名的grep多不了多少東西 絕大多數(shù)情況下 它們將對(duì)代碼進(jìn)行掃描 尋找對(duì)strcpy 這樣的函數(shù)所進(jìn)行的調(diào)用 intmain intargc char argv charbuf1 1024 charbuf2 1024 char shortstring ashortstring strcpy buf1 shortstring safestrcpy buf2 argv 0 dangerous 好的安全分析工具將會(huì)區(qū)分出第一個(gè)strcpy調(diào)用是安全的 盡管可能不需要 而第2個(gè)調(diào)用則是危險(xiǎn)的 靜態(tài)安全分析工具測(cè)試基準(zhǔn) SecuriBench是一個(gè)基于Web的開源Java程序集合 包含一些已知的安全缺陷 http suif stanford edu livshits securibenchSecuriBenchMicro是SecuriBench的縮減版 http suif stanford edu livshits work securibench microABM AnalyzerBenchmark 測(cè)試基準(zhǔn)由一些小程序和大型的真實(shí)程序構(gòu)成 http samate nist gov比較靜態(tài)安全分析工具的最佳方法是使用這些工具分析同一代碼并比較其結(jié)果 把工具引入到代碼審查流程中 練習(xí) 讀代碼 找錯(cuò)誤 intmain intargc char argv charheightString 12 charweightString 12 intheight weight floatbmi printf Enteryourheightininches gets heightString printf Enteryourweightinpounds gets weightString height atoi heightString weight atoi weightString bmi float weight float height height 703 0 printf nBodymassindexis 2 2f n n bmi return0 通過代碼審查找出常見安全問題 不恰當(dāng)?shù)靥幚磔斎刖彌_區(qū)溢出錯(cuò)誤和異常處理 審查輸入處理錯(cuò)誤 懷疑 審慎是安全之本 本杰明 富蘭克林 絕對(duì)不要相信輸入 程序員不得不接收用戶輸入 但是又不能夠相信輸入 那該怎么做呢 明智的方法是充分檢查輸入 并且驗(yàn)證輸入的正確性 輸入包括 命令行參數(shù)配置文件從數(shù)據(jù)庫(kù)中檢索出來的數(shù)據(jù)環(huán)境變量網(wǎng)絡(luò)服務(wù)注冊(cè)表值臨時(shí)文件 不要盲目依賴數(shù)據(jù)庫(kù)的數(shù)據(jù)來保證應(yīng)用程序的正確運(yùn)行 這段代碼沒有對(duì)查詢所返回的記錄行數(shù)進(jìn)行檢驗(yàn) 只是簡(jiǎn)單地調(diào)用返回的第一行記錄 ResultSetrs stmt executeQuery rs next intbalance rs getInt 1 對(duì)來自數(shù)據(jù)庫(kù)的數(shù)據(jù)加以驗(yàn)證 確保數(shù)據(jù)表中唯一值所對(duì)應(yīng)的數(shù)據(jù)行的唯一性 如果存在2個(gè)數(shù)據(jù)行 則表明可能有攻擊者試圖插入偽造的數(shù)據(jù)行 修正后的代碼檢驗(yàn)了返回的數(shù)據(jù)行 以保證只返回一行數(shù)據(jù) ResultSetrs stmt executeQuery if rs next thrownewLookupException 沒有余額數(shù)據(jù)行 if rs isLast thrownewLookupException 余額數(shù)據(jù)行多余一行 intbalance rs getInt 1 千萬不要依賴DNS域名或者IP地址來進(jìn)行認(rèn)證 因?yàn)槿绻粽攉@取了DNS更新權(quán)限 DNS緩存中毒 則可能將數(shù)據(jù)包路由到自己的機(jī)器上 或者偽裝IP地址 使得系統(tǒng)誤認(rèn)為是同一個(gè)域中的機(jī)器 structhostent hp structin addrmyaddr char tHost myaddr s addr inet addr ip addr string hp gethostbyaddr char 黑名單vs 白名單 黑名單法 blacklisting 嘗試枚舉所有不能接受的輸入值 白名單法 whitelisting 通過已知正確值清單來進(jìn)行檢查 下面是摘自Tomcat5 1 31版本中的一段程序 采用了一個(gè)黑名單 假定在Web頁(yè)面中只有4個(gè)特殊的字符輸入才會(huì)導(dǎo)致程序的安全問題 for inti 0 i resule append 黑名單法只拒絕已知惡意的數(shù)據(jù) 而在給定環(huán)境中 惡意值的集合通常是難于枚舉的 或者可能是無限的 所以黑名單法一般是不完善的 即使可能列出一個(gè)危險(xiǎn)輸入值的完整清單 也很可能隨著時(shí)間的變遷而過時(shí) 黑名單法是不利于應(yīng)用程序安全的 審查緩沖區(qū)溢出錯(cuò)誤 緩沖區(qū)溢出 bufferoverflow 將大量數(shù)據(jù)塞入一個(gè)較小的緩沖區(qū)中所導(dǎo)致的程序漏洞緩沖區(qū)溢出通常被攻擊者用于重寫內(nèi)存中的數(shù)據(jù) 近10年來 緩沖區(qū)溢出漏洞的數(shù)量沒有明顯下降的趨勢(shì) voidtrouble inta 32 charline 128 gets line 緩沖區(qū)溢出就是將長(zhǎng)度超過緩沖區(qū)大小的數(shù)據(jù)寫入程序的緩沖區(qū) 造成緩沖區(qū)的溢出 從而破壞程序的堆棧 使程序轉(zhuǎn)而執(zhí)行其他指令 當(dāng)一個(gè)超長(zhǎng)的數(shù)據(jù)進(jìn)入到緩沖區(qū)時(shí) 超出部分就會(huì)被寫入其他緩沖區(qū) 其他緩沖區(qū)存放的可能是數(shù)據(jù) 下一條指令的指針 或者是其他程序的輸出內(nèi)容 這些內(nèi)容都被覆蓋或者破壞掉 可見一小部分?jǐn)?shù)據(jù)或者一套指令的溢出就可能導(dǎo)致一個(gè)程序或者操作系統(tǒng)崩潰 天生危險(xiǎn)的函數(shù) gets cin scanf strcpy wcscpy lstrcpysprintf fprintf swprintf 禁用函數(shù)列表 Linux和Windows平臺(tái)上替換C類庫(kù)的字符串解決方案 GNU LinuxBstrlib FireString http firestuff org wordpress projects firestringGLib http developer gnome org doc API 2 0 glib index htmlLibmib 審查整數(shù)溢出錯(cuò)誤 當(dāng)一個(gè)整數(shù)值大于或者小于其范圍時(shí) 就會(huì)產(chǎn)生整數(shù)溢出錯(cuò)誤 integeroverflow 回繞 unsignedlongreadamt readamt getstringsize if readamt 1024 return 1 readamt buf malloc readamt 如果getstringsize返回0 則readamt 1將等于4294967295 無符號(hào)32位整數(shù)的最大值 這個(gè)操作可能會(huì)因?yàn)閮?nèi)存不足而失敗 檢測(cè)整數(shù)溢出 IntSafe數(shù)學(xué)函數(shù) 對(duì)于C語(yǔ)言 微軟開發(fā)了IntSafe類庫(kù) 它可以幫助檢測(cè)和防止整數(shù)操作中的漏洞IntSafe函數(shù)庫(kù)包含200多個(gè)轉(zhuǎn)換函數(shù) 審查異常處理錯(cuò)誤 charbuf 10 cp buf 10 fgets buf 10 stdin strcpy cp buf buf 如果發(fā)生I O錯(cuò)誤 fgets將不給buf添加NULL終止符 在buf中缺少NULL終止符將可能會(huì)導(dǎo)致在后續(xù)的strcpy調(diào)用時(shí)發(fā)生緩沖區(qū)溢出 Trycatchfinally C 和Java都支持try finally的語(yǔ)法 不論異常是否拋出 finally模塊總是在try模塊后執(zhí)行 但是 如果finally模塊包含一個(gè)return語(yǔ)句 將抑制異常拋出 審查資源泄漏問題 未能及時(shí)釋放資源 包括數(shù)據(jù)庫(kù)對(duì)象 文件句柄和套接字 可能會(huì)導(dǎo)致嚴(yán)重的性能問題 在C程序中 在單個(gè)函數(shù)體中查找多個(gè)return語(yǔ)句 通常是分布式錯(cuò)誤處理代碼的標(biāo)志 也是資源泄漏的滋生地 函數(shù)有多個(gè)出口時(shí) 沒有在每個(gè)出口處對(duì)動(dòng)態(tài)申請(qǐng)的內(nèi)存進(jìn)行釋放 一般在異常處理時(shí)容易出現(xiàn)這種錯(cuò)誤 下面的代碼段就是這樣的例子 pRecord newchar pTable GetRecordLength assert pRecord NULL if pTable GoTop FALSE DBIERR NONE return 如果從這里返回 pRecord將得不到釋放 pTable Close delete pRecord char getBlock intfd char buf char malloc BLOCK SIZE if buf returnNULL if read fd buf BLOCK SIZE BLOCK SIZE returnNULL returnbuf 如果read調(diào)用失敗 將導(dǎo)致已經(jīng)分配的buf內(nèi)存泄漏 try Statementstmt conn createStatement ResultSetrs stmt executeQuery CXN SQL harvestResult rs stmt close catch SQLExceptione logger log Level ERROR errorexecutingsqlquery e 如果在執(zhí)行SQL或處理結(jié)果時(shí)出現(xiàn)了異常 那么stmt對(duì)象將不能被關(guān)閉 假如這種情況經(jīng)常發(fā)生 數(shù)據(jù)庫(kù)將耗盡可用的指針 不能執(zhí)行任何其他的查詢 C C 代碼審查 C C 語(yǔ)言編碼規(guī)范C C 常見代碼問題檢測(cè) 循環(huán)語(yǔ)句的效率 for row 0 row 100 row for col 0 col 5 col sum sum a row col 在多重循環(huán)中 如果有可能 應(yīng)當(dāng)將最長(zhǎng)的循環(huán)放在最內(nèi)層 最短的循環(huán)放在最外層 以減少CPU跨切循環(huán)層的次數(shù) for col 0 col 5 col for row 0 row 100 row sum sum a row col 指針的使用 UC puc card config tab Get Config Table AMP CPM CARD CONFIG TABLE b middle data ok generate trans middle data from original data puc card config tab Ul card config num 分配資源是否正確釋放 voidWarnSvr SaveWarnData for intm 0 mCsn Buffer EVENT ALARM m Csn item Position m RecordsInHistoryFile RecordsInBuffer EVENT ALARM IfawarnwithacertainCsnisnotinEventFilterIndex itisnotnecessarytobeaddedtoHistoryFilterIndexintitem total EventFilterIndex GetItemsInContainer BOOLfind flag false for intk 0 kCsn item Csn find flag true break if find flag HistoryFilterIndex Add item if HistoryFilterIndex IsFull ClearIndexEntry PC Lint LINT工具是一種軟件質(zhì)量保證工具 許多國(guó)外的大型專業(yè)軟件公司 如微軟公司 都把它作為程序檢查工具 在程序合入正試版本或交付測(cè)試之前一定要保證通過了LINT檢查 他們要求軟件工程師在使用LINT時(shí)要打開所有的編譯開關(guān) 如果一定要關(guān)閉某些開關(guān) 那么要給出關(guān)閉這些開關(guān)的正當(dāng)理由 PC LINT是GIMPELSOFTWARE公司的產(chǎn)品 其中的內(nèi)容是非常廣泛的 光是選項(xiàng)就有300多個(gè) 涉及到程序編譯及語(yǔ)法使用中的方方面面 練習(xí) PC Lint的安裝和使用 1 2 char report shortm shortn char p 3 4 intresult 5 char temp 6 longnm 7 inti k kk 8 charname 11 JoeJakeson 9 10 nm n m 11 temp p null p 12 for i 0 i0 result 1 16 elseif kk 0 result 1 17 if m result returntemp 18 elsereturnname 19 Off By OneExample includeintmain inti inta 1 2 3 intn sizeof a sizeof int for i 0 i n i printf a d d n i a i return0 defineNStu3000 defineNCrs400externintconstStuCourse NStu NCrs externdoubleconstCostBook NCrs doubletotal cost inti j doublecost 0 for i 0 i NStu i for j 0 j NCrs i cost StuCourse i j CostBook j returncost JAVA代碼審查 代碼審查和語(yǔ)法錯(cuò)誤檢查是兩個(gè)不同層次的概念 語(yǔ)法錯(cuò)誤是低層次 強(qiáng)制性的檢查 任何違反語(yǔ)法的程序都是無法通過編譯的 也就是說可運(yùn)行的程序必須是語(yǔ)法正確的 而代碼審查是高級(jí)別 非強(qiáng)制性的檢查 它對(duì)語(yǔ)法正確的程序施加了更高更嚴(yán)格的要求 從而提升程序的可讀性 降低因變量命名 方法定義 程序邏輯的不完整性等問題而導(dǎo)致程序的潛在出錯(cuò)機(jī)率 增加程序的可維護(hù)性和健壯性 switch StatementShouldIncludeaDefaultCase 1 switch formatType 2 3 case1 4 formatStr yyyyMMddHHmmss 5 break 6 case2 7 formatStr yyyy MM ddHH mm ss 8 break 9 case3 10 formatStr yyyy MM ddHH mm ss 11 break 12 case4 13 formatStr yyyy 年 MM 月 ddHH mm ss 14 break 15 根據(jù)Sun的編碼規(guī)范 每個(gè)switch流程控制語(yǔ)句都必須帶一個(gè)default分支 以保證邏輯分支的完整性 如果沒有第15 16行的default代碼 代碼審查將給出警告 1 switch formatType 2 3 case1 4 formatStr yyyyMMddHHmmss 5 break 6 case2 7 formatStr yyyy MM ddHH mm ss 8 break 9 case3 10 formatStr yyyy MM ddHH mm ss 11 break 12 case4 13 formatStr yyyy 年 MM 月 ddHH mm ss 14 break 15 default 16 formatStr yyyy MM ddHH mm ss 17 AccessingStaticMembersbytheDescendantClassName 1 publicclassASMO12 3 voidfunc 4 5 ASMO1obj1 newASMO1 6 ASMO2obj2 newASMO2 7 obj1 attr 10 8 obj2 attr 20 9 obj1 oper 10 obj2 oper 11 this attr 12 this oper 13 14 15 staticintattr 16 staticvoidoper 17 18 19 20 classASMO221 22 staticintattr 23 staticvoidoper 24 25 類中所有的靜態(tài)方法或變量都應(yīng)該通過類名來引用 如果通過類的實(shí)例來引用這些靜態(tài)的成員將影響到程序的可讀性 如果通過類名來引用靜態(tài)變量 將容易分辨出這些成員的靜態(tài)屬性 因?yàn)轭愳o態(tài)成員變量在JVM中僅存在一份 而非每個(gè)對(duì)象實(shí)例各自一份 因此靜態(tài)成員變量可以看成類的成員 ComplexAssignment 1 inti 0 2 intj 0 3 intk 0 4 intl 0 5 i j 6 7 k j 10 8 9 l j 15 10 11 i j 20 12 13 i j 25 30 14 15 i j 20 16 17 i j 25 30 往往有些程序員熱衷于將Java的語(yǔ)法發(fā)揮到極致 以資其對(duì)Java語(yǔ)法精通的憑據(jù) 如果是為了練習(xí)語(yǔ)法 理解語(yǔ)法 無可厚非 但如果在需要充分協(xié)作溝通的軟件項(xiàng)目中 簡(jiǎn)潔明了 清晰易懂將會(huì)受到推崇 晦澀難懂的語(yǔ)句將會(huì)受到奚落 故此 大部分的軟件公司的規(guī)范都對(duì)語(yǔ)句的精簡(jiǎn)明了提出了要求 ComplexInitializationorUpdateClausesin for Loops 1 for i 0 j 0 k 10 l 1 i 10 i j k l 2 2 3 dosomething4 由于for循環(huán)控制語(yǔ)句的高度靈活性 所以for 中的代碼往往是復(fù)雜晦澀代碼的樂園 在for語(yǔ)句中以逗號(hào)分隔的賦值語(yǔ)句最多不應(yīng)超過3個(gè) 1 for i 0 j 0 k 10 l 1 i 10 i j k l 2 2 3 dosomething4 5 應(yīng)改寫成下面的樣式6 l 1 7 for i 0 j 0 k 10 i cnt i j k 8 9 dosomething10 l 2 11 UseAbbreviatedAssignmentOperator 1 voidoper 2 inti 0 3 i i 20 4 i 30 i 5 在可能的情況下使用縮減賦值運(yùn)行符 12 CodingStyle MultipleStatementsonOneLine PlaceStatementinBlock Use L insteadof l attheEndofIntegerConstants 1 i j 23 if val 10 6 val 10 7 8 voidfunc 9 longvar 0 x0001111l 10 2020 3 10 77 可編輯 不應(yīng)將多行語(yǔ)句寫在同一行代碼中 代碼塊應(yīng)以 框起來 雖然增長(zhǎng)了代碼 但代碼結(jié)構(gòu)性更強(qiáng) 聲明長(zhǎng)整型使用大寫的 L 類型指定符 而非小寫的 l 因?yàn)楹笳吆蛿?shù)字1相似 HidingNames 1 publicclassHideName2 3 intindex 4 voidfunc 5 6 intindex 7 dosomething8 9 voidsetIndex intindex 10 11 this index index 12 index 13 14 類成員變量被局部變量隱藏 因類方法體中的局部變量和類成員變量具有相同的名字 而使成員變量被屏蔽1 publicclassHideName2 3 intindex 4 voidfunc 5 6 intindex 隱藏了成員變量index 應(yīng)改成另一個(gè)名字 如intnewIndex 7 dosomething8 9 voidsetIndex intindex 10 11 this index index 該語(yǔ)句行中帶this顯式引用成員變量進(jìn)行賦值 審查規(guī)則將不報(bào)警12 index 該語(yǔ)句行沒有this顯式引用 審查規(guī)則將報(bào)警13 14 HidingInheritedField 1 classWindow2 3 protectedintstyle 4 5 6 classButtonextendsWindow7 8 protectedintstyle 9 子類成員變量隱藏父類成員變量 子類成員變量和可繼承的父類成員變量名字相同 1 classWindow2 3 protectedintstyle 4 5 6 classButtonextendsWindow7 8 protectedintstyle 具有和父類相同的成員變量 應(yīng)改為另一個(gè)名字 如anStyle9 HidingInheritedStaticMethods 1 classAnimal2 3 staticvoidoper1 4 staticvoidoper2 5 6 7 classElephantextendsAnimal8 9 staticvoidoper1 10 staticvoidoper2 11 子類覆蓋父類靜態(tài)方法 和非靜態(tài)的方法覆蓋不一樣 靜態(tài)的父類方法不應(yīng)被子類覆蓋 成員變量和局部變量的隱藏 常常會(huì)使開發(fā)人員張冠李戴 犯一些不經(jīng)意的錯(cuò)誤 而子類隱藏父類的成員和靜態(tài)變量常常是由于沒有注意到父類中已經(jīng)具有相同的名字而引起的 由此而生產(chǎn)的程序Bug由于其隱身性強(qiáng) 是很難被發(fā)現(xiàn) 1 classAnimal2 3 staticvoidoper1 4 staticvoidoper2 5 6 7 classElephantextendsAnimal8 9 staticvoidoper1 隱藏了父類中的靜態(tài)方法 應(yīng)取另一個(gè)名字 如anOper1 10 staticvoidoper2 隱藏了父類中的靜態(tài)方法 應(yīng)取另一個(gè)名字 如anOper2 11 UseConventionalVariableNames 1 voidmethod doubled 2 3 inti 4 Exceptione 5 chars 6 Objectf 7 Stringk 8 ObjectUK 9 ObjectCOM 10 避免用過于簡(jiǎn)單的變量名除了循環(huán)體中的臨時(shí)變量 及一些沒有特殊意義的常見數(shù)據(jù)類型 應(yīng)該盡量避免使用一個(gè)字符作為變量 那些無特殊意義且常見的數(shù)據(jù)類型 所選取的單字符變量名必須按表1進(jìn)行命名 為了減少潛在的沖突 避免不必要的混淆 不允許以大寫域名或國(guó)家代碼作變量名 1 voidmethod doubled 2 3 inti 4 Exceptione 5 chars 應(yīng)該改為c6 Objectf 應(yīng)該改為o7 Stringk 應(yīng)該改為s8 ObjectUK 和英國(guó)國(guó)家代碼相同 應(yīng)改為其他的名字 如ukObj9 ObjectCOM 和域名相同 應(yīng)改為其他的名字 如obj 110 BreakStatementisMissingbeforeCaseclause 1 switch c 2 case 3 4 break 5 case 6 7 case n 8 9 case case t 10 11 break 12 根據(jù)Sun編碼慣例 程序入口點(diǎn)從一個(gè)case進(jìn)入 直接到達(dá)下一個(gè)case代碼段 前一個(gè)case沒有對(duì)應(yīng)的break語(yǔ)句時(shí) 在跨過的地方必須給出一個(gè)顯示的注釋 表示是特定流程控制的要求 而非無意遺漏 Non CaseLabelinSwitchstatement 1 publicclassCaseLabel2 3 點(diǎn) 4 publicstaticfinalintPOINT 1 5 線 6 publicstaticfinalintLINE 2 7 多邊形 8 publicstaticfinalintPOLYGON 3 9 10 publicStringgetFigureType intkind 11 12 StringtempName null 13 switch kind 14 15 casePOINT 16 LINE 17 tempName POINTandLINE 18 break 19 casePOLYGON 20 tempName POLYGON 21 break 22 default 23 tempName UNDEFINE 24 25 returntempName 26 27 在switch中出現(xiàn)非case的標(biāo)簽 在Java語(yǔ)句中有兩個(gè)標(biāo)簽 即case分支標(biāo)簽 另一個(gè)則是語(yǔ)句標(biāo)簽 如果case分支標(biāo)簽語(yǔ)句誤刪或遺漏了case關(guān)鍵字 則case分支標(biāo)簽將變成語(yǔ)句標(biāo)簽 而編譯器無法識(shí)別這個(gè)錯(cuò)誤 SuspiciousBreak Continue 1 voidscan char arr 2 3 loop 4 for inti 0 i arr length i 5 6 switch arr i 7 8 case 0 case 1 case 2 case 3 case 4 9 5 6的數(shù)字10 case 5 case 6 case 7 case 8 case 9 11 12 if processDigit arr i 13 14 continueloop 15 16 else17 18 break 19 20 21 case case t 22 23 processWhitespace arr i 24 continue 25 26 default 27 processLetter arr i 28 break 29 30 有錯(cuò)誤嫌疑的break和continue break和continue用于switch和循環(huán)中的跳轉(zhuǎn)控制 break用于提前結(jié)束循環(huán)以及從switch中退出 break的這種 多態(tài)性 使得在循環(huán)體中內(nèi)嵌switch語(yǔ)句時(shí) 常會(huì)帶來一些隱患 即開發(fā)者本希望退出外層循環(huán) 結(jié)果卻只退出內(nèi)層的switch語(yǔ)句而已 ComparingFloating PointValues 1 voidcalc doublelimit 2 3 if limit 0 0 4 5 System out println thefloat pointnumberisexactly0 6 7 避免對(duì)浮點(diǎn)值進(jìn)行等值邏輯判斷浮點(diǎn)數(shù)都是一定精度的數(shù)據(jù) 由于內(nèi)部表示的誤差 往往字面上相同的兩個(gè)浮點(diǎn)數(shù) 其內(nèi)部表示也不完全相同 故此應(yīng)避免對(duì)浮點(diǎn)值數(shù)進(jìn)行等值邏輯判斷 而應(yīng)采用邏輯比較判斷 1 voidcalc doublelimit 2 3 if limit 0 0 應(yīng)改為通過和較小值比較來判斷 如if Math abs limit 0 0000001 4 5 System out println thefloat pointnumberisexactly0 6 7 MixingLogicalOperatorsWithoutParentheses 1 booleana b c 2 3 if a b c 4 5 6 添加 清晰化復(fù)雜的表達(dá)式寫復(fù)雜的表達(dá)式時(shí)不應(yīng)過度依賴運(yùn)算操作符的計(jì)算優(yōu)先順序 而應(yīng)養(yǎng)成使用 的好習(xí)慣 當(dāng)一個(gè)邏輯表達(dá)式由多個(gè)邏輯運(yùn)算組成時(shí) 應(yīng)該用 劃分不同的部分 1 booleana b c 2 3 if a b c 應(yīng)該替換成if a b c 4 5 6 MemberisNotUsed 1 publicclassUnuse2 3 privateStringname 4 publicObjectvalue 5 6 privateObjectgetValue 7 8 returnvalue 9 10 11 privatevoidprint 12 13 System out println getValue value 14 15 類中private的成員方法和成員變量不可能在外部類中調(diào)用 如果發(fā)現(xiàn)private的成員變量或方法并沒有在內(nèi)部的protect或public方法中使用 即這個(gè)成員永遠(yuǎn)不會(huì)在運(yùn)行期得到引用 而成為一個(gè)無用的成員變量和方法 代碼清單中name變量 getValue 及print 方法都是無用的方法 因?yàn)椴豢赡芡ㄟ^外面的類訪問到這些成員 Unuse也沒有提供調(diào)用這些成員的接口 所以這些成員都可以從類中清除 ComparisonalwaysproducestheSameResult 1 voidhandleEvent Evente 2 if e null 3 4 if e null 5 6 7 8 9 10 voidputChar charc booleanisLetter booleanisDigit 11 if isDigit 12 booleanisLetterOrDigit isLetter isDigit 13 14 15 無作為的表達(dá)式比較表達(dá)式總是返回相同的值 1 voidhandleEvent Evente 2 if e null 3 4 if e null 該表達(dá)式的值永遠(yuǎn)都是false 因?yàn)檫M(jìn)入這個(gè)代碼段的e恒為非空5 6 7 8 9 10 voidputChar charc booleanisLetter booleanisDigit 11 if isDigit 12 booleanisLetterOrDigit isLetter isDigit 該表達(dá)式的值永遠(yuǎn)都是true13 14 15 OperationhasNoEffect 1 publicclassNoEffect2 3 privateStringname 4 privateintindex 5 6 NoEffect Stringn intindex 7 8 this name name 9 this index index 10 11 12 intgetPosition 13 14 intbase 0 15 returnindex base 16 17 18 intgetModule 19 20 intx 1 y 2 21 returnx y 22 23 無效的算術(shù)運(yùn)算 例如 當(dāng)進(jìn)行加法和減法運(yùn)算時(shí) 有一個(gè)操作數(shù)是0 當(dāng)進(jìn)行乘法運(yùn)算時(shí) 乘法或被被乘數(shù)為1 當(dāng)進(jìn)行除法運(yùn)算時(shí) 除數(shù)為1 當(dāng)進(jìn)行取模運(yùn)算時(shí) 左邊的操作數(shù)的絕對(duì)值比右邊操作數(shù)的絕對(duì)值小 此時(shí)x y x 屬性賦值時(shí) 將本身的值賦給自己 StatementisUnreachable 1 int arr newint size 2 if arr null 3 4 returnnull 5 流程控制中存在不可到達(dá)的語(yǔ)句有些流程控制由于測(cè)試條件恒為false 則流程中的程序無法到達(dá) 1 int arr newint size 2 if arr null 由于arr不為空 則該測(cè)試邏輯不可能通過 程序無法進(jìn)入該程序塊中3 4 returnnull 5 JBuilder的CodeAudits功能的使用 JBuilder根據(jù)Sun的編碼規(guī)范及軟件開發(fā)界總結(jié)出的一套行之有效的編碼習(xí)慣 對(duì)Java開發(fā)中的編碼風(fēng)格 聲明風(fēng)格 Javadoc文檔注釋 EJB規(guī)范 命名風(fēng)格 潛在錯(cuò)誤 編碼中的畫蛇添足等諸多方面進(jìn)行代碼審查并給出警示 以便開發(fā)人員發(fā)現(xiàn)這些不足和隱患予以及時(shí)更正 C 代碼審查 C 編碼規(guī)范C 常見代碼問題檢測(cè) 避免不必要的強(qiáng)制轉(zhuǎn)換 publicstaticvoidUnderPerforming ArrayListlist foreach objectobjinlist if objisControl ControlaControl objasControl UseaControl 使用字符串長(zhǎng)度屬性測(cè)試是否為空字符串 strings1 test publicvoidEqualsTest if s1 Console WriteLine s1equalsemptystring 優(yōu)先使用交錯(cuò)數(shù)組而非多維數(shù)組 int multiDimArray 1 2 3 4 5 6 7 0 8 0 0 0 9 0 0 0 屬性不應(yīng)返回?cái)?shù)組 publicclassTest string nameValues publicTest nameValues newstring 100 for inti 0 i 100 i nameValues i Sample publicstring Names get return string nameValues Clone publicstaticvoidMain Testt newTest for inti 0 i t Names Length i if t Names i SomeName Performsomeoperation publicclassPhotoLibrary privatePhoto photos null publicPhoto Photos get Photo copyOfPhotos newPhoto photos Length for inti 0 ilibrary Photos i Height Console WriteLine Landscape elseif library Photos i Width library Photos i Height Console WriteLine Portrait else Console WriteLine Square 避免過多的繼承 classBaseClass classFirstDerivedClass BaseClass classSecondDerivedClass FirstDerivedClass classThirdDerivedClass SecondDerivedClass classFourthDerivedClass ThirdDerivedClass classFifthDerivedClass FourthDerivedClass 避免異常的發(fā)生 privatevoidDrawBox Rectanglerect Brushbrush Graphicsg this CreateGraphics try g FillRectangle brush rect catch ArgumentNullException g FillRectangle SystemBrushes Desktop rect finally g Dispose 控制異常 foreach stringexpinexpressions try intnum int Parse exp s num catch FormatException Console WriteLine exp 包含無效的Int32數(shù)值 catch OverflowException Console WriteLine exp 溢出 注意多個(gè)catch子句的排列順序 try if path null FileStreamfstream File Open path FileMode Open catch ArgumentException MessageBox Show 文件名格式不正確或包含非法字符 catch ArgumentOutOfRangeException MessageBox Show 無效的打開文件模式 異常信息的隱藏 publicAccountInfoSignIn stringuserName byte key byte savedKey GetSavedKeyByUserName userName try for inti 0 i savedKey Length i if savedKey i key i thrownewInvalidPasswordException 密碼無效 returnGetAccountInfo userName catch IndexOutOfRangeExceptionex thrownewInvalidPasswordException 密碼無效 ex 異常提示信息 thrownewArgumentOutOfRangeException age 年齡不能為負(fù)數(shù) 訪問控制 publicstructPerson publicintAge publicclassProgram publicstaticvoidmain Personperson person Age 3 字段其實(shí)就是結(jié)構(gòu)或類中的普通變量成員 這將意味著 一旦字段被公開 對(duì)其的訪問便處于完全失控的狀態(tài) FxCop FxCop是一款專門用于分析 NET托管代碼程序集的工具 它能檢查 NET代碼是否滿足Microsoft NETFramework設(shè)計(jì)規(guī)范 它使用反射 MSIL解析等技術(shù)來分析程序集 可以檢查超過200個(gè)缺陷 包括庫(kù)設(shè)計(jì) 本地化 命名規(guī)范 性能 安全等方面的內(nèi)容 FxCop的使用 FxCop命令行運(yùn)行方式 FxCopCmd f F CNJ C6 CodeAnalysisTest1 CodeAnalysisTest1 bin Debug CodeAnalysisTest1 exe out C 1 txt s rule E ProgramFiles MicrosoftVisualStudio8 TeamTools StaticAnalysisTools FxCop Rules DesignRules dll ruleid Microsoft Design CA2210 練習(xí) 利用FxCop檢查C 代碼問題 privatevoidbutton1 Click objectsender EventArgse stringstr for inti 0 i 100 i str i ToString FxCop的規(guī)則定義方法 FxCop支持用戶自定義檢查規(guī)則 通過使用FxCop的SDK 繼承基類BaseIntrospectionRule 并編寫自定義的檢查方法 可針對(duì)項(xiàng)目的代碼添加更多的檢查規(guī)則 FxCop的代碼分析原理 大多數(shù)代碼分析工具掃描的是源代碼 但是FxCop則直接對(duì)編譯好的代碼進(jìn)行掃描 NET的每個(gè)程序集都有metadata 可稱為元數(shù)據(jù) metadata是關(guān)于一個(gè)程序集中各元素的類型信息庫(kù) 它本身也存放在這個(gè)程序集中 metadata對(duì)程序集以及程序集內(nèi)用到的所有類型進(jìn)行描述 FxCop會(huì)利用metadata的信息來獲得代碼內(nèi)部的運(yùn)行情況 另外 FxCop也對(duì)代碼編譯時(shí)生成的中間語(yǔ)言 MSIL 進(jìn)行檢查 通過對(duì)metadata和MSIL檢查的結(jié)合 FxCop可以得出大量信息 以此獲得對(duì)代碼執(zhí)行時(shí)的行為的相關(guān)信息 它把代碼和各條規(guī)則逐一比較檢查 當(dāng)找到不符合規(guī)則的代碼時(shí)就會(huì)生成一條消息 練習(xí) 定義FxCop代碼檢查規(guī)則 DevPartner DevPartnerStudio8 0ProfessionalEdition是一款與VisualStudio緊密結(jié)合的測(cè)試工具 它能幫助檢測(cè)和診斷各種 NET代碼問題 包括代碼評(píng)審 CodeReview 錯(cuò)誤檢測(cè) 性能分析 覆蓋率分析 內(nèi)存分析等功能 DevPartner的CodeReview功能 在RuleManager中編輯代碼規(guī)則 DevPartner通過掃描和匹配代碼中符合正則表達(dá)式的代碼來判斷代碼是否違反了規(guī)則 因此可以說正則表達(dá)式是制定規(guī)則 識(shí)別代碼缺陷的關(guān)鍵 練習(xí) 設(shè)計(jì)規(guī)則自動(dòng)檢查代碼錯(cuò)誤 在使用完SqlDataReader后應(yīng)該調(diào)用其Close方法 例如下面是一個(gè)錯(cuò)誤的例子 publicvoidmyMethod2 SQL查詢語(yǔ)句stringmySelectQuery SELECTOrderID CustomerIDFROMOrders 新建連接SqlConnectionmyConnection newSqlConnection myConnString 新建SQL命令SqlCommandmyCommand newSql
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 【名師金典】2022新課標(biāo)高考生物總復(fù)習(xí)限時(shí)檢測(cè)8降低化學(xué)反應(yīng)活化能的酶-
- 陜西省西安市西咸新區(qū)部分學(xué)校2024-2025學(xué)年九年級(jí)上學(xué)期期末考試歷史試題(含答案)
- 期末測(cè)評(píng)卷(二)(Lesson10 ~ 12)綜合測(cè)評(píng)卷 2024-2025學(xué)年科普版(三起)英語(yǔ)五年級(jí)上冊(cè)(含答案)
- 《AIDS抗病毒治療》課件
- 【志鴻優(yōu)化設(shè)計(jì)】2020高考地理(人教版)一輪教學(xué)案:第6章-第1講人口的數(shù)量變化與合理容量
- 【復(fù)習(xí)參考】2020高考語(yǔ)文(江蘇)二輪專題訓(xùn)練:專題4-散文閱讀-1句子作用分析題
- 【名師一號(hào)】2020-2021學(xué)年高中英語(yǔ)(北師大版)必修二-第五單元綜合測(cè)評(píng)
- 【高考總動(dòng)員】2022屆高考語(yǔ)文一輪總復(fù)習(xí)-知識(shí)清單古代詩(shī)歌常識(shí)
- 【KS5U原創(chuàng)】新課標(biāo)2021高二地理暑假作業(yè)四
- 同學(xué)造句子一年級(jí)簡(jiǎn)單
- 2024-2030年中國(guó)無糖壓縮餅干行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 安全管理三級(jí)體系
- 2024年商用密碼應(yīng)用安全性評(píng)估從業(yè)人員考核試題庫(kù)-下(判斷題)
- 快樂讀書吧《愛的教育》復(fù)習(xí)小結(jié)(知識(shí)點(diǎn))-統(tǒng)編版語(yǔ)文六年級(jí)上冊(cè)
- 2024年人教版初一生物(上冊(cè))期末考卷及答案(各版本)
- 光伏發(fā)電工程建設(shè)標(biāo)準(zhǔn)工藝手冊(cè)(2023版)
- 2024至2030年中國(guó)無糖壓縮餅干行業(yè)市場(chǎng)全景監(jiān)測(cè)及投資策略研究報(bào)告
- 食品安全追溯管理體系制度
- 監(jiān)理工作質(zhì)量保證體系
- 辦公家具采購(gòu)?fù)稑?biāo)方案(投標(biāo)書+技術(shù)方案)
- 律所之間轉(zhuǎn)委托合同范本
評(píng)論
0/150
提交評(píng)論