精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

防御性編程:讓系統堅不可摧

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-07-25 14:04 ? 次閱讀

1. 引言

面對復雜多變的運行環境、不可預測的用戶輸入以及潛在的編程錯誤,如何確保軟件在遭遇異常情況時依然能夠穩定運行,是每位開發者必須面對的挑戰。防御性編程(Defensive Programming)正是為解決這一問題而生的一種編程范式,它強調在編程過程中預見并防范潛在的錯誤和異常情況,從而增強軟件的健壯性和穩定性。作為一種細致、謹慎的編程方法,通過提前考慮并防范可能出現的錯誤,從而有效減少軟件漏洞和故障。本文將詳細介紹防御性編程的基本概念、關鍵策略,并通過實際案例展示其在實際項目中的應用。

2. 防御性編程的基本概念

防御性編程的核心思想在于承認程序總會存在問題和需要修改,因此聰明的程序員會提前考慮并防范可能的錯誤。它強調在編程過程中不僅要實現功能,還要確保程序在面對錯誤輸入、異常情況和并發操作時能夠穩定運行

3. 防御性編程的核心原則

3.1 風險識別

非系統性風險:只影特定場景下的響單次調用,不對系統整體穩定性產生影響。比如空指針異常、數據越界等。

系統性風險:導致整個服務不可用的風險。比如 死循環,分頁查詢pageSize過大等。

3.2 防御原則

1.假設輸入總是錯誤的:不依賴外部輸入的絕對正確性,對所有輸入進行驗證和清理。

2.最小化錯誤的影響范圍:通過異常處理、錯誤隔離等措施,限制錯誤對系統整體的影響。

3.使用斷言進行內部檢查:在代碼的關鍵位置加入斷言,確保程序狀態符合預期。

4.代碼清晰易懂:編寫易于理解和維護的代碼,便于團隊成員發現潛在問題。

5.持續測試:通過單元測試、集成測試等手段,不斷驗證軟件的正確性和穩定性。

4. 防御性編程案例

4.1 輸入驗證與清理

場景

用戶輸入數據到Web表單中,系統需要處理這些數據以進行后續操作。

防御性編程實踐

風險識別:系統性風險,可能導致系統整體不可用。

防御策略

?驗證數據類型:確保用戶輸入的數據類型符合預期(如數字、字符串、日期等)。如果類型不匹配,應給出錯誤提示并要求用戶重新輸入。

?長度和范圍檢查:對于字符串、數字等類型的數據,進行長度和范圍檢查,確保它們不超過系統處理能力的限制。

?清理輸入數據:去除輸入數據中的非法字符或格式,如去除字符串兩端的空格、將特殊字符轉換為普通字符等。

分頁參數防御式編程案例

下面以分頁參數防御式編程為案例進行舉例說明:

場景描述: 假設開發一個Web API,該API需要根據用戶請求返回特定數據的分頁結果。分頁請求包含以下參數:

?pageSize:每頁應顯示的記錄數。

?pageNumber:用戶請求的當前頁碼。

防御性編程措施

1.驗證pageSize:確保pageSize是一個正整數,并且不超過一個合理的最大值(例如100),以防止資源過度消耗。

2.驗證pageNumber:確保pageNumber是一個正整數,并且不會請求到不存在的頁碼(即基于總記錄數和pageSize計算出的最大頁碼之后)。

3.處理無效參數:如果參數無效,則返回清晰的錯誤消息,并可能設置一個默認的頁碼或每頁記錄數。

4.計算總頁數:基于總記錄數和pageSize計算總頁數,以便在返回分頁信息時包含給用戶。

示例代碼(偽代碼):

public class PaginationService {        
    private static final int MAX_PAGE_SIZE = 100;        
        /**       
         * 獲取分頁信息并進行參數校驗       
         *        
         * @param totalRecords 總記錄數       
         * @param pageSize 每頁記錄數       
         * @param pageNumber 當前頁碼       
         * @return 分頁信息,包括總頁數、當前頁碼等       
         */      
         public PaginationInfo getPaginationInfo(int totalRecords, int pageSize, int pageNumber) {          
             // 校驗pageSize          
             if (pageSize <= 0 || pageSize > MAX_PAGE_SIZE) {              
                 throw new IllegalArgumentException("pageSize必須為正整數且不超過" + MAX_PAGE_SIZE);          
             }            
             // 校驗pageNumber          
             if (pageNumber <= 0) {              
                 pageNumber = 1; // 默認為第一頁          
             }            
             // 計算總頁數          
             int totalPages = (totalRecords + pageSize - 1) / pageSize;            
             // 確保pageNumber不超過總頁數          
             if (pageNumber > totalPages) {              
                 pageNumber = totalPages;          
             }            
             // 計算當前頁的數據起始索引(可選,根據具體需求)          
             int startIndex = (pageNumber - 1) * pageSize;            
             // 返回分頁信息          
             return new PaginationInfo(totalPages, pageNumber, startIndex);      
         }        
         // PaginationInfo 是一個簡單的類,用于封裝分頁信息 
         ...

在這個例子中,getPaginationInfo 方法首先驗證了 pageSize 和 pageNumber 參數的有效性,確保了它們符合預期的約束條件。如果參數無效,方法會拋出一個 IllegalArgumentException 異常,這有助于調用者識別并處理錯誤情況。然后,方法計算了總頁數,并根據需要調整了 pageNumber 以確保它不會超出范圍。最后,方法返回了一個包含分頁信息的 PaginationInfo 對象。

這種防御性編程策略有助于防止因無效的分頁參數而導致的程序錯誤,提高了API的健壯性和用戶體驗。

4.2 預防死循環

場景

在循環或者遍歷場景中,沒有明確的退出機制。

防御性編程實踐

風險識別:系統性風險,可能導致系統整體不可用。

防御策略

?參數驗證:檢查涉及循環步長的入參是否有效。

?循環終止條件必達性確認:在涉及條件校驗的場景中,避免等值條件判斷,防止跳過循環終止點。

?日志記錄:在關鍵位置添加日志記錄,幫助調試和追蹤問題。

示例代碼Java):

/**  
 * 生成時間段。  
 *  
 * @param startMinutes 開始時間
 * @param endMinutes 結束時間
 * @param interval 時間段間隔
 * @param duration 時間的時長
 * @return 時間段列表 
 */  
public List generateList(int startMinutes, int endMinutes, int interval, int duration) {

    List result = new ArrayList();
    int nextStartTime = startMinutes;

    while (nextStartTime == endMinutes) {
        int currentStartMinutes = nextStartTime;
  
        int currentEndMinutes = currentStartMinutes + duration;

        result.add(currentStartMinutes + "-" + currentEndMinutes);
  
        nextBatchStartTime += interval;
    }
    return result;
}

針對以上代碼,我們可以添加一些防御式編程的元素來確保代碼的健壯性和可靠性。防御式編程側重于預防錯誤的發生,包括輸入驗證、錯誤處理和邊界條件檢查。以下是修改后的代碼,包含了防御式編程的改進:

/** 
 * 生成時間段。 
 * 
 * @param startMinutes 開始時間
 * @param endMinutes 結束時間
 * @param interval 時間段間隔
 * @param duration 時間的時長
 * @return 時間段列表 
 */ 
public List generateList(int startMinutes, int endMinutes, int interval, int duration) {
    // 改進點1:校驗 interval,以保證循環中的步長能夠正向增長
    // 一般情況下,還需要對步長,和 endMinutes與startMinutes的區間大小做限制,避免生成“巨大”的列表。
    if (interval <= 0) {
        throw new IllegalArgumentException("Invalid parameters: interval must be positive integers.");
    }
    List result = new ArrayList();
    int nextStartTime = startMinutes;

    //改進點2:避免使用等號做循環終止條件,以防跳過循環終止點。
    while (nextStartTime <= endMinutes) {
        int currentStartMinutes = nextStartTime;
  
        int currentEndMinutes = currentStartMinutes + duration;

        result.add(currentStartMinutes + "-" + currentEndMinutes);
  
        nextBatchStartTime += interval;
    }
    return result;
}

4.3 異常處理

場景

程序在讀取文件、進行網絡請求或執行其他可能失敗的操作時,需要處理潛在的異常。

防御性編程實踐

風險識別:非系統性風險,影響單次請求。

防御策略

?使用try-except語句:將可能拋出異常的代碼塊放在try語句中,并在except語句中捕獲并處理這些異常。

?區分異常類型:根據實際需要捕獲特定的異常類型,或捕獲所有異常(使用Exception作為異常類型)。

?記錄錯誤信息:在捕獲異常后,記錄詳細的錯誤信息(如異常類型、錯誤消息、堆棧跟蹤等),以便后續分析和調試。

示例代碼(Java):

/**  
 * 讀取文件內容。  
 *  
 * @param filePath 文件路徑  
 * @return 文件內容,如果文件不存在或讀取失敗則返回null  
 */  
public static String readFile(String filePath) {  
    try {  
        byte[] encoded = Files.readAllBytes(Paths.get(filePath));  
        return new String(encoded);  
    } catch (FileNotFoundException e) {  
        log.info("文件未找到:" + filePath);  
        return null;  
    } catch (Exception e) {  
        log.info("讀取文件時發生錯誤:" + e.getMessage());  
        return null;  
    }  
}  

4.4 邊界條件檢查

場景

在循環、條件判斷或數組訪問等操作中,需要確保不會超出預期的范圍或邊界。

防御性編程實踐

風險識別:非系統性風險,影響單次請求。

防御策略

?檢查循環條件:確保循環條件在每次迭代后都能正確更新,以避免無限循環。

?數組和集合訪問:在訪問數組、列表、字典等集合的元素之前,檢查索引或鍵是否有效。

?邊界值測試:對函數或方法的輸入進行邊界值測試,以確保它們在邊界條件下也能正常工作。

示例代碼(Java):

public class ArrayAccess {      
    public static void main(String[] args) {          
        int[] numbers = {1, 2, 3, 4, 5};          
        int index = getIndexFromUser(); // 假設這是從用戶那里獲取的索引                    
        if (index >= 0 && index < numbers.length) {              
            log.info(numbers[index]);          
        } else {              
            log.info("索引超出數組范圍");          
        }      
    }                 
    
    // 假設這個方法從用戶那里獲取索引值,并進行基本的驗證 
    private static int getIndexFromUser() {       
        // 為了示例,我們直接返回一個示例值          
        return 2; // 假設用戶輸入了有效的索引值2      
    }  
}

4.5 使用斷言進行內部檢查

場景

在代碼的關鍵路徑上,需要確保某些條件始終為真,否則程序將無法正確執行。

防御性編程實踐

?使用斷言:在代碼的關鍵位置添加斷言(如Python的assert語句),以驗證程序狀態是否符合預期。如果斷言失敗,則拋出AssertionError異常。

?注意斷言的使用場景:斷言主要用于開發和測試階段,用于捕獲那些理論上不應該發生的錯誤。在生產環境中,應該依賴更健壯的錯誤處理機制。

示例代碼(Java):

/**  
 * 計算年齡。  
 *  
 * @param birthYear 出生年份  
 * @return 年齡,如果輸入無效則返回-1。  
 */  
public static int calculateAge(int birthYear) {  
    // 輸入驗證:確保出生年份是一個合理的值  
    if (birthYear <= 0 || birthYear > java.time.Year.now().getValue()) {  
        // 拋出IllegalArgumentException來指示方法接收到了非法參數  
        throw new IllegalArgumentException("出生年份必須是一個大于0且小于當前年份的整數");  
    }  
  
    // 計算年齡  
    int currentYear = java.time.Year.now().getValue();  
    return currentYear - birthYear;  
}  
  
public static void main(String[] args) {  
    try {  
        // 假設我們從某個地方(如用戶輸入)獲取了出生年份  
        int birthYear = 1990; // 這里直接賦值作為示例  
  
        int age = calculateAge(birthYear);  
            if (age != -1) { // 注意:這個例子中calculateAge實際上不會返回-1,但為了展示如何處理可能的異常情況,我們可以這樣設計  
                log.info("年齡是:" + age);  
            }  
  
        } catch (IllegalArgumentException e) {  
            // 捕獲并處理IllegalArgumentException  
            log.info("錯誤:" + e.getMessage());  
        }  
  
        // 如果需要從用戶輸入中獲取出生年份,你可以添加相應的邏輯來處理字符串到整數的轉換和驗證  
    }  
  
    // 注意:在這個例子中,我們沒有直接使用assert,因為Java的assert主要用于調試,且默認是禁用的。  
    // 而是通過顯式的條件檢查和異常拋出來實現防御性編程。  

5. 防御式編程的挑戰

5.1 是不是防御式代碼越多越好呢?

No,過度的防御式編程會使程序會變得臃腫而緩慢,增加軟件的復雜度。

要考慮好什么地方需要進行防御,然后因地制宜地調整進行防御式編程的優先級。

一般在入口處或者接入層做通用性防御性編程,比如數據準入校驗;但對于循環類邏輯,應始終在使用處做細節性防御

5.2 通用性防御措施 優于 細節性的防御

例如對于網絡請求,一般是統一處理超時、鑒權、各種錯誤code,而不是在業務層個別處理

5.3 根據使用場景,調整防御力度

如項目內部使用的utils函數和公開發布的package,后者防御要求更高

6. 結論

防御性編程是一種積極主動的編程策略,它要求開發者在編寫代碼時,不僅要關注功能的實現,更要關注代碼的健壯性和穩定性。通過預見并防范潛在的錯誤和異常情況,防御性編程能夠顯著提升軟件的質量,減少因外部因素導致的程序崩潰,提升系統穩定性。

文章中難免會有不足之處,希望讀者能給予寶貴的意見和建議。謝謝!

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編程
    +關注

    關注

    88

    文章

    3596

    瀏覽量

    93610
收藏 人收藏

    評論

    相關推薦

    探索分布式IO模塊的介質冗余:賦能工業自動化的穩健之心

    凸顯。明達技術自主研發的帶有介質冗余功能的MR30分布式IO模塊,正以其獨特的優勢,為工業自動化系統構建起一道堅不可摧的防護網。
    的頭像 發表于 09-25 10:45 ?200次閱讀
    探索分布式IO模塊的介質冗余:賦能工業自動化的穩健之心

    揭秘!霍尼韋爾MIP系列—無堅不摧的介質隔離壓力傳感器冷卻液、腐蝕介質環境

    揭秘霍尼韋爾MIP系列——無堅不摧的介質隔離壓力傳感器,引領工業監測新紀元在極端工業環境的洪流中,有這樣一款傳感器,它如同城堡般堅不可摧,名為霍尼韋爾MIP系列介質隔離壓力傳感器。這款傳感器不僅是
    的頭像 發表于 08-31 08:06 ?560次閱讀
    揭秘!霍尼韋爾MIP系列—無堅不摧的介質隔離壓力傳感器冷卻液、腐蝕<b class='flag-5'>性</b>介質環境

    微軟推出企業版付費人臉識別技術Face Check

    微軟近日宣布,其先進的人臉識別技術Face Check已全面向全球企業客戶開放,標志著微軟在身份認證安全領域邁出了重要一步。Face Check技術通過融合用戶手機自拍與已驗證的身份照片,為企業構建了一道堅不可摧的身份驗證防線。
    的頭像 發表于 08-14 17:38 ?980次閱讀

    特信反制無人機干擾設備防御策略

    無人機干擾設備的防御策略是一個綜合的過程,涉及多個方面的技術和措施。以下是一些主要的防御方法:
    的頭像 發表于 08-01 09:20 ?360次閱讀

    深圳濾波器廠家:電子設備的純凈守護者

    在電子設備日益普及的今天,電源濾波器作為保障電力純凈與穩定的關鍵元件,其重要愈發凸顯。電源濾波器,顧名思義,是一種專門用于過濾電源中雜波和干擾信號的電子裝置。它如同一道堅不可摧的防線,為電力系統提供了純凈的能源環境,確保各類電
    的頭像 發表于 07-10 09:28 ?183次閱讀
    深圳濾波器廠家:電子設備的純凈守護者

    深圳特信無人機反制與無人機干擾系統如何保護一線城市安全

    上空的安全與秩序。無論是保障重要活動的順利進行,還是維護市民的日常安寧,深圳特信都以其卓越的技術實力,為一線城市的安寧筑起堅不可摧的防線。
    的頭像 發表于 07-09 09:10 ?299次閱讀

    無人機主動防御系統不起作用嗎

    起作用。無人機主動防御系統是一種用于保護無人機免受攻擊的系統。這種系統可以有效地防止無人機被敵方攻擊,提高無人機的生存能力。然而,無人機主動防御
    的頭像 發表于 07-08 09:57 ?459次閱讀

    無人機主動防御系統有什么作用

    無人機主動防御系統是一種用于保護無人機免受攻擊或干擾的系統。這種系統可以提高無人機的安全和可靠
    的頭像 發表于 07-08 09:54 ?536次閱讀

    無人機主動防御系統有哪些

    無人機主動防御系統是一種用于保護無人機免受攻擊的系統。隨著無人機在軍事、民用和商業領域的廣泛應用,無人機的安全問題也日益凸顯。本文將介紹無人機主動防御
    的頭像 發表于 07-08 09:50 ?959次閱讀

    無人機主動防御系統安裝需要備案嗎

    無人機主動防御系統是一種用于保護無人機免受攻擊的系統,它可以有效地防止無人機被黑客攻擊、干擾、劫持等。在安裝無人機主動防御系統時,需要考慮以
    的頭像 發表于 07-08 09:46 ?340次閱讀

    知語云智能科技無人機防御系統:應對新興威脅的先鋒力量

    隨著科技的飛速發展,無人機技術在各個領域的應用日益廣泛,但隨之而來的是無人機威脅的不斷升級。為了有效應對這些新興威脅,知語云智能科技推出了先進的無人機防御系統,為空中安全保駕護航。 無人機防御
    發表于 02-26 16:35

    虛擬化軟件棧有哪些防御措施

    軟件棧的防御措施。 基礎防御措施 強化操作系統安全性:虛擬化軟件棧的基礎是操作系統,因此首先需要確保操作系統的安全
    的頭像 發表于 01-25 11:27 ?715次閱讀

    一種動態防御策略——移動目標防御(MTD)

    網絡攻擊的技術變得愈發難測,網絡攻擊者用多態、混淆、加密和自我修改喬裝他們的惡意軟件,以此逃避防御性的檢測,于是移動目標防御(MTD)技術出現了,通過動態地改變攻擊面,有效地對抗日益復雜和隱蔽
    的頭像 發表于 01-04 08:04 ?1443次閱讀
    一種動態<b class='flag-5'>防御</b>策略——移動目標<b class='flag-5'>防御</b>(MTD)

    Linux越來越容易受到攻擊,怎么防御

    在數字化時代,網絡安全已成為企業不可忽視的重要議題。尤其是對于依賴Linux服務器的組織,面對日益復雜的網絡攻擊,傳統安全措施已顯不足。Linux服務器面臨著哪些新型網絡威脅,有哪些有效的防御策略呢
    的頭像 發表于 12-23 08:04 ?1059次閱讀
    Linux越來越容易受到攻擊,怎么<b class='flag-5'>防御</b>?

    Morphisec革命:利用移動目標防御增強Windows安全

    Windows10安全工具陣列仍然存在明顯的防御漏洞,Morphisec通過其革命的自動移動目標防御(AutomatedMovingTargetDefense)技術,強化Windows10安全
    的頭像 發表于 12-09 10:00 ?1040次閱讀
    Morphisec革命:利用移動目標<b class='flag-5'>防御</b>增強Windows安全<b class='flag-5'>性</b>