成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

關(guān)于防御性編程,你應(yīng)該知道的事

開(kāi)發(fā) 前端
關(guān)于防御性編程,這一概念開(kāi)始來(lái)自于汽車的防御性駕駛技術(shù),意為你永遠(yuǎn)無(wú)法確定另一位司機(jī)將要做什么,才能確保他人做出危險(xiǎn)動(dòng)作時(shí)不會(huì)傷害到你。

提起編程,對(duì)于程序員同學(xué)而言并不陌生,關(guān)于防御性編程相信大家也有所耳聞,但是它具體包括哪些內(nèi)容呢?又有哪些行之有效的處理方案呢?我們又該如何正確應(yīng)用呢?

本文作者結(jié)合實(shí)際工作中的一些應(yīng)用經(jīng)驗(yàn),來(lái)全面解析一下防御性編程。

本文主要內(nèi)容:

  • 什么是防御性編程      
  • 防御性編程的重要性
  • 輸入檢查          
  • 斷言的應(yīng)用        
  • 錯(cuò)誤處理          
  • 隔離              
  • 防御策略及建議    

1. 什么是防御性編程

關(guān)于防御性編程,這一概念開(kāi)始來(lái)自于汽車的防御性駕駛技術(shù),意為你永遠(yuǎn)無(wú)法確定另一位司機(jī)將要做什么,才能確保他人做出危險(xiǎn)動(dòng)作時(shí)不會(huì)傷害到你。

防御性編程應(yīng)用過(guò)程中,并不是指讓你從保護(hù)自身,對(duì)他人持有“批判或攻擊”的態(tài)度,而是將保護(hù)的意識(shí)落地到自身程序上,通過(guò)一些防御手段讓你的代碼程序不因傳入的錯(cuò)誤數(shù)據(jù)而出錯(cuò)崩潰。大家通常會(huì)說(shuō),“代碼有問(wèn)題很正常的呀”,的確是這樣,那更應(yīng)該在編寫(xiě)程序的時(shí)候提高防御性的重要性,尤其核心程序能力,做好程序錯(cuò)誤影響的包容性。

2. 防御性編程的重要性

隨著目前互聯(lián)網(wǎng)已滲透到各行各業(yè),每個(gè)細(xì)微的風(fēng)險(xiǎn)問(wèn)題都可能會(huì)被放大,足以影響整個(gè)行業(yè)。

  • 1996年6月4日,歐洲航天局的 Ariane 5 Flight 501 在起飛后 40 秒被引爆。因?yàn)閷?dǎo)航軟件里的一個(gè) bug,這個(gè)價(jià)值 10 億美金的運(yùn)載火箭不得不自毀。
  • 2019年1月,拼多多被爆出現(xiàn)重大BUG,用戶可領(lǐng)100元無(wú)門檻券,造成大批用戶開(kāi)始‘薅羊毛’,一晚上200多億都是話費(fèi)充值。
  • 2019年5月時(shí)候,部分用戶反映其支付寶出現(xiàn)網(wǎng)絡(luò)故障,賬號(hào)無(wú)法登錄或支付。支付寶官方表示,該故障是由于杭州市蕭山區(qū)某地光纖被挖斷導(dǎo)致,這一事件造成部分用戶無(wú)法使用支付寶。

系統(tǒng)服務(wù)的穩(wěn)定性對(duì)于企業(yè)來(lái)說(shuō)非常重要,不僅僅會(huì)對(duì)企業(yè)帶來(lái)直接的經(jīng)濟(jì)損失,甚至?xí)?duì)行業(yè)、人們的生活造成非常嚴(yán)重的影響。

3. 輸入檢查

在學(xué)習(xí)編碼的時(shí)候,估計(jì)大家都聽(tīng)過(guò)“不要相信用戶的輸入”,指的就是對(duì)用戶輸入做檢查的必要性。談到輸入,常見(jiàn)Web開(kāi)發(fā)主要包括以下兩個(gè)方面:

3.1 檢查所有來(lái)自系統(tǒng)外部的數(shù)據(jù)

在系統(tǒng)建設(shè)過(guò)程中,我們經(jīng)常會(huì)需要跟外部系統(tǒng)做數(shù)據(jù)交互處理,這里包括:文件、接口、消息隊(duì)列、表單用戶輸入等等,對(duì)于來(lái)自系統(tǒng)外部輸入的數(shù)據(jù)內(nèi)容,我們需要明確做到:

  • 數(shù)據(jù)格式是否準(zhǔn)確
  • 數(shù)據(jù)類型是否準(zhǔn)確
  • 數(shù)據(jù)長(zhǎng)度是否準(zhǔn)確

對(duì)數(shù)據(jù)做預(yù)期準(zhǔn)確性檢查,保證輸入數(shù)據(jù)在我們程序的可接受范圍以內(nèi)。其實(shí),所有的安全問(wèn)題的本質(zhì)都是信任的問(wèn)題。數(shù)據(jù)檢查,這個(gè)跟車站、機(jī)場(chǎng)的安全檢查相似。通過(guò)一個(gè)安全檢查(過(guò)濾,凈化)的過(guò)程,可以梳理未知的人或物,使其變得可信任。被劃分出來(lái)的具有不同信任級(jí)別的區(qū)域,我們稱為信任域,劃分兩個(gè)不同信任域之間的邊界,我們稱之為信任邊界。對(duì)于異常數(shù)據(jù)處理情況,做好防御檢查的,同時(shí)需要做好日志記錄,以防追后賬呢,哈哈~

3.2 檢查接口API的參數(shù)值

對(duì)于系統(tǒng)內(nèi)部接口API請(qǐng)求,需要檢查程序的輸入?yún)?shù)的值。這個(gè)跟檢查來(lái)自外部系統(tǒng)的數(shù)據(jù)一樣。

/**
* 請(qǐng)求處理通用類
**/
public class CommonRequest {
@NotBlank(message="參數(shù)str不能為空")
private String str;
@NotNull(message = "參數(shù)i不能為空")
private Integer i;

@Min(value =0,message = "最小值不能小于0")
private int min;

@Max(value=100,message = "最大值不能大約100")
private int max;
}

通常情況下,需要驗(yàn)證如下幾項(xiàng):

  • 字段必傳和非必傳
  • 字段類型是否一致
  • 參數(shù)值是否合法
  • 長(zhǎng)度是否符合要求

對(duì)于接口參數(shù)/字段異常情況,大家可以按照以下思路來(lái)驗(yàn)證問(wèn)題:

  • Q1:如果參數(shù)缺失或者漏傳,會(huì)有默認(rèn)值么?
  • Q2:如果參數(shù)問(wèn)題,業(yè)務(wù)邏輯會(huì)發(fā)生哪些不合理的情況?
  • Q3:字段缺失、不合法情況,對(duì)于寫(xiě)操作,是否會(huì)造成垃圾數(shù)據(jù)的產(chǎn)生?

注意:補(bǔ)充一個(gè)關(guān)鍵情況,需要結(jié)合業(yè)務(wù)場(chǎng)景來(lái)評(píng)估可能的影響范圍。

必要情況,設(shè)置白名單而不是黑名單。

舉個(gè)栗子,在你設(shè)置圖像擴(kuò)展名的時(shí)候,不要設(shè)置無(wú)效的類型,而是檢查有效的類型并排除其他類型。在 PHP 有無(wú)數(shù)的開(kāi)源校驗(yàn)庫(kù),讓你的工作更簡(jiǎn)單。

要記住:進(jìn)攻是最好的防守。總而言之,不要將代碼外部的函數(shù)調(diào)用或方法調(diào)用想得太過(guò)美好。請(qǐng)確保你調(diào)用外部的API和庫(kù)之前理解并測(cè)試了錯(cuò)誤。

4. 斷言的應(yīng)用

4.1 何謂斷言?

所謂斷言,是指在開(kāi)發(fā)期間使用的,讓程序在運(yùn)行時(shí)進(jìn)行自檢的代碼。通常是一個(gè)子程序或者宏。

斷言的目的為了表示與驗(yàn)證軟件開(kāi)發(fā)者預(yù)期的結(jié)果,當(dāng)程序執(zhí)行到斷言的位置時(shí),對(duì)應(yīng)的斷言應(yīng)該為真;若斷言不為真時(shí),程序會(huì)中止執(zhí)行,并給出錯(cuò)誤信息。

舉個(gè)例子:

如果系統(tǒng)假定一份數(shù)據(jù)信息文件所包含的記錄數(shù)不超過(guò)20000,那么程序中可以設(shè)置一個(gè)斷定記錄數(shù)<=20000 的斷言。只要 記錄數(shù)<= 20000,這一斷言都不會(huì)觸發(fā),然而一旦記錄數(shù)超過(guò)20000,它就會(huì)斷言程序存在一個(gè)錯(cuò)誤。

4.2 斷言的形式

斷言可以有兩種形式:

  • assert Expression1
  • assert Expression1:Expression2

其中 Expression1 應(yīng)該總是一個(gè)布爾值,Expression2是斷言失敗時(shí)輸出的失敗消息的字符串。

如果Expression1為假,則拋出一個(gè) AssertionError,這是一個(gè)錯(cuò)誤,而不是一個(gè)異常,也就是說(shuō)是一個(gè)不可控制異常(unchecked Exception),AssertionError由于是錯(cuò)誤,所以可以不捕獲,但不推薦這樣做,因?yàn)槟菢訒?huì)使你的系統(tǒng)進(jìn)入不穩(wěn)定狀態(tài)。

public class TestAssert{undefined
public static void main(String[] args){undefined
String name = "abner chai";
//String name = null;
assert (name!=null):"變量name為空null";
System.out.println(name);
}
}

5. 錯(cuò)誤處理

根據(jù)前面的介紹,斷言可以用于處理代碼中不應(yīng)該發(fā)生的錯(cuò)誤,那又該如何處理那些預(yù)料中可能要發(fā)生的錯(cuò)誤呢?

異常和錯(cuò)誤處理是防御性編程的一個(gè)組成部分。

想象一下,啟動(dòng)了一個(gè)異步操作,運(yùn)行并輸出結(jié)果,沒(méi)有異常,這是一個(gè)理想的情況。如果在執(zhí)行過(guò)程中發(fā)生錯(cuò)誤怎么辦?與任何未處理的異常一樣,應(yīng)用程序通常會(huì)崩潰。假設(shè)任何異步操作都會(huì)成功運(yùn)行而沒(méi)有任何錯(cuò)誤,那么可能會(huì)失敗。

高級(jí)語(yǔ)言中一般會(huì)采用try catch方式捕獲異常處理,如下示例:

try {
//邏輯代碼
} catch (exception e){
//異常處理代碼
}

try{
//邏輯代碼
} finally {
//一定要執(zhí)行的代碼
}

try {
//邏輯代碼
} catch (exception e){
//異常處理代碼
} finally{
//一定要執(zhí)行的代碼
}

而Golang的錯(cuò)誤處理規(guī)范也是Go語(yǔ)言的最大亮點(diǎn)之一。

  • error接口

標(biāo)準(zhǔn)庫(kù)把error定義為接口類型, 以便于自己定義錯(cuò)誤類型。

type error interface{
Error() string
}
  • Painc

golang的內(nèi)置方法,能夠改變程序的控制流。當(dāng)函數(shù)調(diào)用了panic,函數(shù)會(huì)停止運(yùn)行,但是defer函數(shù)會(huì)運(yùn)行,程序會(huì)在當(dāng)前panic的goroutine全部退棧以后crash。

  • Recover

recover也是golang的內(nèi)置方法,用于恢復(fù)發(fā)生panic的goroutine的控制,recover只在defer函數(shù)中生效。如果當(dāng)前goroutine將要發(fā)生panic的話, recover會(huì)捕獲這個(gè)panic,并恢復(fù)正常執(zhí)行。

  • Defer

聊到panic和recover,需要聊聊defer這個(gè)關(guān)鍵字,后面會(huì)看到defer在異常處理機(jī)制中起到的作用。go的defer是用來(lái)延遲執(zhí)行函數(shù)的,延遲的發(fā)生是在調(diào)用函數(shù)的returen之后。

6. 隔離

所謂隔離,是指程序可以包容由錯(cuò)誤造成的損害,稱為一種容損策略。這個(gè)在軟件行業(yè)中最常見(jiàn)的方案,就是多機(jī)房建設(shè)。實(shí)現(xiàn)服務(wù)雙機(jī)房部署建設(shè),承受單機(jī)房故障,保障用戶體驗(yàn)。這個(gè)實(shí)現(xiàn)的難點(diǎn)主要有如下三點(diǎn):

  • 跨機(jī)房網(wǎng)絡(luò)延遲和帶寬限制導(dǎo)致的數(shù)據(jù)層面一致性問(wèn)題
  • 機(jī)房之間流量調(diào)度
  • 業(yè)務(wù)改動(dòng)不能太大

各個(gè)大廠對(duì)于核心服務(wù)多機(jī)房部署的實(shí)現(xiàn),簡(jiǎn)單列舉以下幾種實(shí)現(xiàn)方案:

  • 高德

基于地理位置單元化,不同服務(wù)集群間雙向數(shù)據(jù)復(fù)制,內(nèi)部調(diào)用路由。

  • 微博

MySQL多機(jī)房同步(寫(xiě)入時(shí)寫(xiě)但機(jī)房,有專門的組件負(fù)責(zé)同步寫(xiě)入到另一個(gè)機(jī)房)。

隔離的應(yīng)用,同時(shí)體現(xiàn)了在架構(gòu)設(shè)計(jì)上規(guī)定應(yīng)該如何應(yīng)用如何處理錯(cuò)誤的價(jià)值。

7. 防御策略及建議

在防御性編程的路上,沒(méi)有銀彈。在產(chǎn)品中保留過(guò)多的防御性代碼,則會(huì)與精簡(jiǎn)代碼實(shí)現(xiàn)產(chǎn)生相矛盾的地方。從產(chǎn)品本身出發(fā),在不影響用戶體驗(yàn)的使用的情況下,使程序能夠穩(wěn)定的運(yùn)行,梳理了如下幾項(xiàng)建議:

  • 保留重要錯(cuò)誤檢查的代碼,去掉檢查細(xì)微錯(cuò)誤的代碼
  • 保留讓程序穩(wěn)妥地崩潰的代碼,去掉會(huì)導(dǎo)致程序硬性崩潰的代碼
  • 確認(rèn)代碼中的錯(cuò)誤消息是友好的,為技術(shù)支持人員做好錯(cuò)誤信息記錄

其實(shí),對(duì)于防御性編程,我們其實(shí)是要在保障程序穩(wěn)定和程序不過(guò)于臃腫之間找到一個(gè)合理的平衡。防御式編程技術(shù)可以讓錯(cuò)誤更容易發(fā)現(xiàn),更容易修改,并減少錯(cuò)誤對(duì)代碼的破壞,斷言可以幫助人們更早的發(fā)現(xiàn)錯(cuò)誤,關(guān)于如何處理錯(cuò)誤輸入的決策是一項(xiàng)關(guān)鍵的錯(cuò)誤處理決策,也是一項(xiàng)關(guān)鍵的高層設(shè)計(jì)決策。防范看似微小的錯(cuò)誤,收益價(jià)值可能遠(yuǎn)遠(yuǎn)超出你的想象。

責(zé)任編輯:武曉燕 來(lái)源: 架構(gòu)精進(jìn)之路
相關(guān)推薦

2023-12-15 08:17:13

防御性編程代碼

2015-11-05 18:03:15

虛擬化云計(jì)算資源池

2022-04-26 06:21:59

編程動(dòng)態(tài)內(nèi)存

2024-10-09 12:03:06

2017-11-03 13:43:24

云計(jì)算Saas信息化

2020-08-23 21:07:16

編程PythonJava

2024-07-26 10:01:16

2018-05-30 12:04:36

LinuxUbuntu 18.0

2022-05-07 19:18:16

防御性編碼代碼

2023-09-27 22:52:52

2012-02-07 13:29:35

2023-12-12 09:27:07

編程碼農(nóng)

2023-12-12 13:18:11

2020-06-05 10:36:30

云計(jì)算容器安全

2017-10-12 10:20:13

服務(wù)器運(yùn)行壽命

2016-11-01 23:16:52

光纖光纖線纜

2022-10-11 23:50:43

JavaScript編程Promise

2025-05-26 10:25:00

防御性編程開(kāi)發(fā)編程

2010-09-02 18:56:09

NoSQL數(shù)據(jù)庫(kù)DBA

2022-11-04 08:22:14

編譯代碼C語(yǔ)言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产免费自拍 | 一区二区三区在线观看免费视频 | 免费a国产 | 久久久久久久网 | 欧美成人专区 | 欧洲妇女成人淫片aaa视频 | 新超碰97| 久久午夜精品福利一区二区 | 免费一级黄 | 91精品久久久久久综合五月天 | 青青草社区 | 一区二区三区av夏目彩春 | 视频一区二区国产 | 欧美日韩在线成人 | 91久久久久久久久久久久久 | 污污免费网站 | 欧美高清视频一区 | 精品久久久久久亚洲综合网 | 久久久久网站 | 色小姐综合网 | 韩日精品一区 | 日本精品一区二区三区在线观看 | 久久久久久久久精 | 九九免费在线视频 | 国产综合一区二区 | 91av久久久| 国产视频福利一区 | 国产成人短视频在线观看 | 久操av在线 | 日本不卡免费新一二三区 | 国产日韩欧美 | 成人午夜网站 | 看片91| 久久久久国产成人精品亚洲午夜 | www.se91| 亚洲精品影院 | 日韩欧美一区二区三区免费观看 | 视频一区二区在线观看 | 国产在线视频在线观看 | 日本人爽p大片免费看 | 国产精品99久久久久久久久久久久 |