總結程序員的(de)幾大經驗教訓

發布時間:2023-11-07 | 編輯:深圳網站建設公司(sī)

第一、保障安全刻不(bù)容緩


保障安全刻不(bù)容緩,你不(bù)能輕描淡寫地(dì)說(shuō):“今後系統會(huì)加強安全性。”


強大的(de)應用(yòng)程序安全應該被當作開發過程中的(de)首要問題,應該從第1天開始就需要讨論,絕對不(bù)能等到第300天。将安全性留到最後一分鐘實際上會(huì)增加開發的(de)時間,因為(wèi)你不(bù)得不(bù)返工,通過重構實現安全要求。


更糟糕的(de)是,屆時你就沒有那麼多時間來解決安全問題了,最終隻能發布易受攻擊的(de)代碼。雅虎等公司(sī)的(de)遭遇就是前車之鑒。


每個(gè)應用(yòng)程序各不(bù)相同,且有各自的(de)需求,根據應用(yòng)程序的(de)需求選擇,不(bù)要屈服(fú)于市(shì)場流行(xíng)度。


每個(gè)應用(yòng)程序各不(bù)相同,這(zhè)點無需多說(shuō)。世上沒有一套适用(yòng)于所有應用(yòng)程序的(de)萬全之策。在(zài)啟動新(xīn)應用(yòng)程序時,應該由應用(yòng)程序及其體系結構來規定使用(yòng)的(de)技術或标準化(huà)(huà)的(de)平台。


如果在(zài)你搞清楚“應用(yòng)程序需要什麼”之前,就決定使用(yòng)gRPC或Kubernetes系統,那麼隻會(huì)阻礙代碼的(de)編寫工作。這(zhè)就是為(wèi)什麼Canonical等公司(sī)誤入歧途,在(zài)物(wù)聯網設備上運行(xíng)Kubernetes。


引用(yòng)Jeff Goldblum的(de)一句話:“科(kē)學(xué)家們忙于思考他(tā)們能夠幹什麼,不(bù)能夠幹什麼,以至于他(tā)們沒有時間停下來思考是否應該這(zhè)樣幹。”


第二、你可能并不(bù)需要微服(fú)務(wù)


微服(fú)務(wù)非常有魅力,我(wǒ)完全理(lǐ)解。即便隻是想一想能夠單獨擴展應用(yòng)程序中的(de)各個(gè)小功能,就足以讓人興奮不(bù)已,因為(wèi)你可以感受到滿滿的(de)成就感。


但(dàn)是,說(shuō)實話你可能不(bù)需要微服(fú)務(wù)。比如“我(wǒ)希望将功能X的(de)代碼從功能Y的(de)代碼中分離(lí)出來”,“防止不(bù)良代碼滲透到應用(yòng)程序的(de)其他(tā)部分”,或者“最小化(huà)(huà)受影響的(de)應用(yòng)”等到這(zhè)些理(lǐ)由不(bù)是使用(yòng)微服(fú)務(wù)的(de)原因,這(zhè)些不(bù)過是糟糕的(de)開發實踐導緻的(de)惡果,你需要的(de)是更嚴格的(de)代碼審查标準(不(bù)要合并不(bù)良代碼),以及更為(wèi)細緻的(de)安全控制。


你是否需要單獨擴展應用(yòng)程序的(de)各個(gè)部分,而且目前的(de)組件(jiàn)(例如登錄流程)是否存在(zài)容量的(de)問題?然後再探索那些需要擴展成獨立服(fú)務(wù)的(de)組件(jiàn)。


你是否需要運行(xíng)基于虛拟服(fú)務(wù)器(qì)的(de)架構并希望降低成本?如果是,那麼就不(bù)應該探索微服(fú)務(wù)。即便采用(yòng)微服(fú)務(wù),充其量也不(bù)過是功過相抵。惡劣的(de)情況下,最終隻是多了幾個(gè)需要單獨啟動的(de)實例。


假設你的(de)整體式架構包含5個(gè)服(fú)務(wù),而你卻将其分解成了微服(fú)務(wù)。那麼,現在(zài)你有5個(gè)應用(yòng),你所面臨的(de)局面是:


a)你需要逐個(gè)啟動專用(yòng)實例,而占空的(de)空間是最初的(de)5倍;


b)你利用(yòng)現有的(de)空間,同時承擔額外的(de)運營成本。


第三、标準化(huà)(huà)的(de)開發環境


在(zài)與多個(gè)開發人員合作時,标準化(huà)(huà)整個(gè)團隊使用(yòng)的(de)開發環境可以讓你受益無窮。我(wǒ)并不(bù)是說(shuō)你必須将一些基于容器(qì)的(de)虛拟開發環境通過魔法混合在(zài)一起。雖然你要這(zhè)麼幹我(wǒ)也攔不(bù)住,但(dàn)是你隻需使用(yòng)同一個(gè)版本的(de)語言就可以為(wèi)團隊帶來奇迹。


如果你的(de)同事用(yòng)Go 1.11編寫代碼,而你卻在(zài)Go 1.12上發現了Bug,那麼可真是欲哭無淚。協調何時升級版本可能很困難,但(dàn)一旦協調成功,諸事都會(huì)順利。


第四、配置的(de)工作不(bù)簡單,請(qǐng)務(wù)必做(zuò)好(hǎo)(hǎo)相應的(de)計(jì)劃


雖然有些流行(xíng)的(de)網站說(shuō),配置隻不(bù)過是“将所有東西都扔進環境變量中”,然而事實遠(yuǎn)非如此。


我(wǒ)認為(wèi)配置應用(yòng)程序的(de)方法至少有四種:代碼內(nèi)的(de)默認值、本地(dì)配置文件(jiàn)、命令行(xíng)的(de)标志、環境變量、遠(yuǎn)程配置(如使用(yòng)Hashicorp的(de)Consul)等。我(wǒ)認為(wèi)遠(yuǎn)程配置是可選的(de),而其他(tā)四個(gè)都是必要的(de)。


對于開發來說(shuō),為(wèi)了在(zài)本地(dì)運行(xíng)應用(yòng)程序而不(bù)得不(bù)将27個(gè)不(bù)同的(de)配置值放入環境變量,這(zhè)會(huì)讓人萬分沮喪。另外,你可能需要更好(hǎo)(hǎo)的(de)自動化(huà)(huà)和Makefile。你可以利用(yòng)本地(dì)配置源的(de)方法,如application.yaml,并默認設置為(wèi)“dev”配置。


此外,如果深圳網站建設公司(sī)代碼中有默認值,則意味著(zhe)你需要更改它們的(de)默認值。在(zài)通過systemd等初始化(huà)(huà)系統運行(xíng)應用(yòng)程序時,命令行(xíng)的(de)标志非常實用(yòng),因為(wèi)在(zài)查看進程的(de)運行(xíng)情況時,你可以清楚地(dì)看到應用(yòng)程序的(de)配置方式。在(zài)容器(qì)內(nèi)運行(xíng)應用(yòng)程序時,環境變量非常實用(yòng),但(dàn)也有一些東西不(bù)适合放入環境變量,比如Secret。


你永遠(yuǎn)不(bù)能将Secret(密碼、身(shēn)份驗證令牌、證書(shū)等你不(bù)想洩露給公衆的(de)數(shù)據)放入環境變量,因為(wèi)它們不(bù)安全,而且主機上的(de)任何進程都可以讀取環境變量。你應該借助某種Secret管理(lǐ)工具。我(wǒ)個(gè)人喜歡使用(yòng)Vault(來自Hashicorp),但(dàn)你可以根據應用(yòng)選擇最合适的(de)工具。


第五、隻在(zài)必要時導入軟件(jiàn)包


我(wǒ)們都知道(dào)left-pad的(de)那個(gè)故事吧(https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/)。


隻因為(wèi)有人從代碼倉庫中删掉了一個(gè)11行(xíng)的(de)NPM軟件(jiàn)包,結果幾乎導緻整個(gè)互聯網癱瘓。


請(qǐng)務(wù)必小心。隻有當你面臨正當的(de)需求時,才應該導入軟件(jiàn)包,例如某個(gè)供應商特定的(de)SDK(比如AWS的(de)SDK),這(zhè)是一組高(gāo)度冗長(cháng)的(de)标準庫抽象(這(zhè)就是人們喜歡使用(yòng)Python的(de)請(qǐng)求而不(bù)是urllib的(de)原因) ,或廣泛使用(yòng)的(de)框架,比如Go的(de)Echo HTTP服(fú)務(wù)器(qì)或Python的(de)Flask WSGI服(fú)務(wù)器(qì)。


一些便捷的(de)庫也可以,比如JavaScript的(de)Lodash提供了标準庫中沒有的(de)一些常用(yòng)功能和附加功能。這(zhè)些外部的(de)依賴項可以減輕開發的(de)負擔,而且你不(bù)需要手動編寫樣闆或集成代碼,這(zhè)些都是包系統的(de)優勢。然而,就像left-pad一樣,你很容易被坑:“這(zhè)兒有一個(gè)庫,我(wǒ)可以使用(yòng)。”你導入的(de)依賴項每增加一個(gè),随之而來的(de)不(bù)穩定性和風險也會(huì)劇增,可能這(zhè)些庫根本沒人維護。

22

新(xīn)依賴項本身(shēn)導入的(de)每個(gè)包也會(huì)增加風險,這(zhè)稱之為(wèi)傳遞依賴。如果你導入了一個(gè)包,而這(zhè)個(gè)包又(yòu)導入了5個(gè)包,那麼恭喜你現在(zài)繼承了這(zhè)五個(gè)依賴關系以及随之而來的(de)所有風險。


我(wǒ)和這(zhè)個(gè)行(xíng)業的(de)許多其他(tā)人都認為(wèi)軟件(jiàn)包不(bù)應該引入傳遞依賴。雖然無法做(zuò)到萬無一失,但(dàn)至少應該盡可能減少,如果你需要更多功能,那麼就為(wèi)用(yòng)戶提供一種明确的(de)擴展方法。


在(zài)導入庫時,通常我(wǒ)會(huì)遵循一個(gè)簡單的(de)規則:如果我(wǒ)可以在(zài)10-15分鐘內(nèi)自己編寫,那麼就自己寫;否則再考慮使用(yòng)外部的(de)庫。


在(zài)開發的(de)時候,牢記這(zhè)條規則可以避免将不(bù)必要的(de)內(nèi)容導入應用(yòng)程序,但(dàn)是你不(bù)必每次需要提供API時都考慮從頭開始編寫新(xīn)的(de)HTTP服(fú)務(wù)器(qì)。


第六、沒必要抽象所有代碼


還有一個(gè)很大的(de)坑:抽象一切。


有時,你會(huì)覺得“稍後我(wǒ)可能會(huì)再用(yòng)到這(zhè)個(gè)功能”,這(zhè)個(gè)想法可能會(huì)将你引向一條黑(hēi)暗又(yòu)可怕的(de)面向對象之路(lù)。


DRY原則(Don’t Repeat Yourself,不(bù)要自我(wǒ)重複)徹底征服(fú)了我(wǒ)們,盡管這(zhè)條原則有其充分的(de)理(lǐ)由。


然而,你需要注意不(bù)要在(zài)抽象上花(huā)費太多時間,以至于沒有足夠的(de)時間編寫邏輯。你的(de)工作是寫代碼!等到你發現你需要實現的(de)某個(gè)方法或函數(shù)之前已經寫過了,那麼可以再回過頭來抽象,但(dàn)是切記量力而行(xíng)。


我(wǒ)個(gè)人遵循的(de)原則是,如果抽象之前隻是一個(gè)隻有3行(xíng)的(de)函數(shù),那麼就重複好(hǎo)(hǎo)了。如果真的(de)隻有3行(xíng)代碼,也許你該想一想是否值得寫成函數(shù)。


第七、項目需要像“鳳凰”一樣,


經曆浴火(huǒ)重生的(de)洗禮


這(zhè)個(gè)想法令人不(bù)寒而栗。經理(lǐ)們會(huì)為(wèi)此感到緊張,産品所有者會(huì)為(wèi)此變得暴躁,而且開發人員也會(huì)因此而感到憤怒,但(dàn)你必須這(zhè)麼做(zuò)。


每隔一段時間就從頭開始其實是一件(jiàn)好(hǎo)(hǎo)事。你可以借機删掉代碼中的(de)冗餘,而且無需改造現有的(de)半個(gè)代碼庫就可以實現新(xīn)的(de)想法,同時還可以強制每個(gè)人重新(xīn)評估項目。


你可以把項目想象成一片森林(lín),每一行(xíng)代碼都是一棵參天大松樹(shù),綿延數(shù)裡(lǐ)。随著(zhe)時間一天天過去,這(zhè)片森林(lín)會(huì)布滿灌木叢、飄落的(de)松針、松果、枯枝和許多其他(tā)雜物(wù)。這(zhè)些都是你的(de)麻煩,你的(de)技術債務(wù)。


這(zhè)些東西越積累越多,直到受到某種外部力量的(de)影響。對于森林(lín)而言,這(zhè)種外部力量就是野火(huǒ)。火(huǒ)焰肆虐過的(de)森林(lín),地(dì)表寸草不(bù)生,隻有樹(shù)皮足夠厚的(de)樹(shù)木才能存活下來,所有未長(cháng)成的(de)樹(shù)木都會(huì)被大火(huǒ)燒盡。雖然這(zhè)對森林(lín)來說(shuō)是滅頂之災,但(dàn)其中蘊含著(zhe)一個(gè)驚天的(de)秘密:森林(lín)渴望大火(huǒ)。多年來,它一直在(zài)耐心地(dì)等待,等待火(huǒ)焰來淨化(huà)(huà)一切,因為(wèi)火(huǒ)焰在(zài)樹(shù)冠下肆虐過後,下一代的(de)參天大樹(shù)才會(huì)從松果中發芽。


當火(huǒ)焰橫掃過森林(lín)地(dì)面時,它會(huì)孵化(huà)(huà)出幼小脆弱的(de)樹(shù)苗,讓它們與被大火(huǒ)燒得漆黑(hēi)的(de)幸存者并肩而立。你的(de)應用(yòng)程序也需要這(zhè)樣的(de)洗禮:生命力旺盛、編寫良好(hǎo)(hǎo)的(de)代碼會(huì)從清理(lǐ)中存活下來,而新(xīn)的(de)想法和代碼會(huì)從累累白骨中站起來,宛如浴火(huǒ)重生的(de)鳳凰。



版權保護: 本文由深圳網站設計(jì)公司(sī)發布,轉載請(qǐng)保留鍊接: 總結程序員的(de)幾大經驗教訓
如有內(nèi)容侵權,請(qǐng)聯系我(wǒ)們。