軟件架構(gòu)VI: 測(cè)量和控制架構(gòu)特征

架構(gòu)師必須處理軟件項(xiàng)目所有不同方面的各種架構(gòu)特征墙贱。 諸如性能剿吻、彈性和可伸縮性之類(lèi)的運(yùn)維方面與諸如模塊化和可部署性之類(lèi)的結(jié)構(gòu)性問(wèn)題融合在一起纺棺。這里著重于具體定義一些較常見(jiàn)的架構(gòu)特征并為其建立治理機(jī)制。

測(cè)量架構(gòu)特征

組織中有關(guān)架構(gòu)特征的定義存在幾個(gè)常見(jiàn)問(wèn)題:

他們不是物理學(xué)
常用的許多架構(gòu)特征含義不明確剑令。例如,架構(gòu)師如何設(shè)計(jì)敏捷性或可部署性碍脏?業(yè)界對(duì)通用術(shù)語(yǔ)的看法大相徑庭钾埂,有時(shí)是由合理的不同上下文所驅(qū)動(dòng),有時(shí)是偶然的故源。

定義千差萬(wàn)別
即使在同一組織內(nèi)矢腻,不同部門(mén)也可能在關(guān)鍵功能(例如績(jī)效)的定義上存在分歧。在開(kāi)發(fā)人員竣灌,架構(gòu)和運(yùn)維可以統(tǒng)一一個(gè)共同的定義之前屯烦,要進(jìn)行適當(dāng)?shù)膶?duì)話就很困難温眉。

太復(fù)合
許多所需的架構(gòu)特征在較小規(guī)模上包含許多其他特征谴蔑。例如,開(kāi)發(fā)人員可以將敏捷性分解為諸如模塊化、可部署性和可測(cè)試性之類(lèi)的特征洒琢。

架構(gòu)特征的客觀定義解決了所有三個(gè)問(wèn)題:通過(guò)在組織范圍內(nèi)就架構(gòu)特征的具體定義達(dá)成一致呛踊,團(tuán)隊(duì)圍繞架構(gòu)創(chuàng)建了一種普遍存在的語(yǔ)言。同樣,通過(guò)鼓勵(lì)客觀定義,團(tuán)隊(duì)可以解開(kāi)組合特征以發(fā)現(xiàn)他們可以客觀定義的可測(cè)量特征狭吼。

可操作的測(cè)量

許多架構(gòu)特征具有明顯的直接度量层坠,例如性能或可伸縮性。但是搏嗡,即使根據(jù)團(tuán)隊(duì)的目標(biāo)窿春,這些也提供了許多細(xì)微的解釋拉一。例如延赌,也許一個(gè)團(tuán)隊(duì)測(cè)量了某些請(qǐng)求的平均響應(yīng)時(shí)間,這是運(yùn)維架構(gòu)特性測(cè)量的一個(gè)很好的例子待榔。但是稽荧,如果團(tuán)隊(duì)僅測(cè)量平均值趁冈,那么如果某些邊界條件導(dǎo)致1%的請(qǐng)求花費(fèi)的時(shí)間比其他時(shí)間長(zhǎng)10倍,會(huì)發(fā)生什么情況坯辩?如果該站點(diǎn)有足夠的流量,則異常值甚至可能不會(huì)出現(xiàn)涯塔。因此践惑,團(tuán)隊(duì)可能還需要測(cè)量最大響應(yīng)時(shí)間以捕獲異常值配深。

高水平的團(tuán)隊(duì)不只是建立出色的性能數(shù)字俐镐; 他們的定義基于統(tǒng)計(jì)分析。 例如奥洼,假設(shè)視頻流服務(wù)希望監(jiān)視可伸縮性爆阶。 工程師沒(méi)有設(shè)置任意數(shù)字作為目標(biāo)理盆,而是隨著時(shí)間的推移測(cè)量規(guī)模并建立統(tǒng)計(jì)模型,然后在實(shí)時(shí)指標(biāo)超出預(yù)測(cè)模型時(shí)發(fā)出警報(bào)。 失敗可能意味著兩件事:模型不正確(哪些團(tuán)隊(duì)想知道)或某事不正確(哪些團(tuán)隊(duì)也想知道)襟雷。

結(jié)合工具和細(xì)致入微的理解,團(tuán)隊(duì)現(xiàn)在可以衡量的各種特征正在迅速發(fā)展眠副。 例如防嗡,許多團(tuán)隊(duì)最近將精力集中在性能預(yù)算上,以衡量指標(biāo)慕匠,例如第一幅有意義的圖表和第一次發(fā)生的CPU空閑闷尿,這兩者都為移動(dòng)設(shè)備上的網(wǎng)頁(yè)用戶指出了性能問(wèn)題窿克。 隨著設(shè)備先较、目標(biāo)渴杆、功能和其他眾多事物的變化穴亏,團(tuán)隊(duì)將找到新的事物和測(cè)量方法。

結(jié)構(gòu)化測(cè)量

一些客觀指標(biāo)并不像績(jī)效指標(biāo)那么明顯。 內(nèi)部結(jié)構(gòu)特征如何采蚀,例如定義明確的模塊化呢熄赡? 遺憾的是把篓,還沒(méi)有用于內(nèi)部代碼質(zhì)量的綜合指標(biāo)口芍。 但是,某些度量標(biāo)準(zhǔn)和通用工具的確可以使架構(gòu)師解決代碼結(jié)構(gòu)的某些關(guān)鍵方面凤价,盡管范圍狹窄君珠。

代碼的一個(gè)明顯的可測(cè)量方面是復(fù)雜度寝志,由循環(huán)復(fù)雜度度量定義。

架構(gòu)師和開(kāi)發(fā)人員普遍同意策添,過(guò)于復(fù)雜的代碼代表著代碼臭味(Code Smell)材部。 它實(shí)際上損害了代碼庫(kù)的每個(gè)令人希望的特性:模塊化、可測(cè)試性唯竹、可部署性等乐导。 但是,如果團(tuán)隊(duì)不關(guān)注逐漸增加的復(fù)雜性浸颓,那么這種復(fù)雜性將主導(dǎo)代碼庫(kù)物臂。

過(guò)程測(cè)量

一些架構(gòu)特征與軟件開(kāi)發(fā)過(guò)程相交旺拉。例如,敏捷性經(jīng)常表現(xiàn)為理想的功能棵磷。但是账阻,這是架構(gòu)師可以分解為可測(cè)試性和可部署性等功能的復(fù)合架構(gòu)特征。

可通過(guò)幾乎所有評(píng)估測(cè)試完整性的平臺(tái)的代碼覆蓋率工具來(lái)衡量可測(cè)試性泽本。像所有軟件檢查一樣淘太,它不能代替思想和意圖。例如规丽,一個(gè)代碼庫(kù)可以具有100%的代碼覆蓋率蒲牧,但是斷言不佳,實(shí)際上并不能使人們對(duì)代碼的正確性充滿信心赌莺。但是冰抢,可測(cè)試性顯然是客觀可測(cè)量的特征。同樣艘狭,團(tuán)隊(duì)可以通過(guò)多種指標(biāo)來(lái)衡量可部署性:成功部署與失敗部署的百分比挎扰,部署需要花費(fèi)多長(zhǎng)時(shí)間,部署引發(fā)的問(wèn)題/錯(cuò)誤以及許多其他問(wèn)題巢音。每個(gè)團(tuán)隊(duì)都有責(zé)任進(jìn)行一組良好的評(píng)估遵倦,以捕獲其組織在質(zhì)量和數(shù)量上有用的數(shù)據(jù)。其中許多措施歸結(jié)為團(tuán)隊(duì)的重點(diǎn)和目標(biāo)官撼。

敏捷及其相關(guān)部分顯然與軟件開(kāi)發(fā)過(guò)程有關(guān)梧躺。但是,該過(guò)程可能會(huì)影響架構(gòu)傲绣。例如掠哥,如果易于部署和可測(cè)試性是重中之重,那么架構(gòu)師將在架構(gòu)級(jí)別更加注重良好的模塊化和隔離性秃诵,這是驅(qū)動(dòng)結(jié)構(gòu)決策的架構(gòu)特征示例续搀。實(shí)際上,如果軟件項(xiàng)目范圍內(nèi)的任何事情都能夠滿足我們的三個(gè)標(biāo)準(zhǔn)菠净,那么它就可能會(huì)升至架構(gòu)特征的水平禁舷,從而迫使架構(gòu)師做出設(shè)計(jì)決定以考慮到這一點(diǎn)。

治理和適應(yīng)功能

一旦架構(gòu)師確定了架構(gòu)特征并對(duì)其進(jìn)行了優(yōu)先排序嗤练,他們?nèi)绾未_保開(kāi)發(fā)人員將尊重這些優(yōu)先事項(xiàng)榛了?模塊化是架構(gòu)方面的一個(gè)重要例子,它很重要但并不緊迫煞抬。在許多軟件項(xiàng)目中霜大,緊迫性占主導(dǎo)地位,但是架構(gòu)師仍然需要一種治理機(jī)制革答。

主導(dǎo)架構(gòu)特征

源自希臘語(yǔ)Kubernan(轉(zhuǎn)向)的治理是架構(gòu)師角色的重要職責(zé)战坤。顧名思義曙强,架構(gòu)治理的范圍涵蓋了架構(gòu)師(包括企業(yè)架構(gòu)師之類(lèi)的角色)想要施加影響的軟件開(kāi)發(fā)過(guò)程的任何方面。例如途茫,確保組織內(nèi)的軟件質(zhì)量屬于架構(gòu)治理的范疇碟嘴,因?yàn)樗鼘儆诩軜?gòu)的范圍,而過(guò)失可能導(dǎo)致災(zāi)難性的質(zhì)量問(wèn)題囊卜。

幸運(yùn)的是娜扇,存在越來(lái)越復(fù)雜的解決方案,可以減輕架構(gòu)師的困擾栅组,這是軟件開(kāi)發(fā)生態(tài)系統(tǒng)中功能不斷增長(zhǎng)的一個(gè)很好的例子雀瓢。極限編程催生的軟件項(xiàng)目實(shí)現(xiàn)自動(dòng)化,實(shí)現(xiàn)了持續(xù)集成玉掸,進(jìn)一步實(shí)現(xiàn)了操作的自動(dòng)化刃麸,現(xiàn)在我們將其稱為DevOps,一直持續(xù)到架構(gòu)治理司浪。 《構(gòu)建演化架構(gòu)》(O’Reilly)一書(shū)描述了稱為適應(yīng)度函數(shù)的一系列技術(shù)泊业,這些技術(shù)可用于自動(dòng)執(zhí)行架構(gòu)管理的許多方面。

適應(yīng)度函數(shù)

構(gòu)建演化架構(gòu)中的“演化”一詞更多地來(lái)自于演化計(jì)算啊易,而不是生物學(xué)吁伺。其中一位作者Rebecca Parsons博士在演化計(jì)算領(lǐng)域花費(fèi)了一些時(shí)間,其中包括遺傳算法之類(lèi)的工具认罩。遺傳算法執(zhí)行并產(chǎn)生答案箱蝠,然后通過(guò)進(jìn)化計(jì)算世界中定義的眾所周知的技術(shù)進(jìn)行變異。如果開(kāi)發(fā)人員試圖設(shè)計(jì)一種遺傳算法以產(chǎn)生一些有益的結(jié)果垦垂,則他們通常希望對(duì)算法進(jìn)行指導(dǎo),從而提供指示結(jié)果質(zhì)量的客觀指標(biāo)牙瓢。該指導(dǎo)機(jī)制稱為適應(yīng)度函數(shù):一種目標(biāo)函數(shù)劫拗,用于評(píng)估輸出與達(dá)到目標(biāo)的接近程度。例如矾克,假設(shè)開(kāi)發(fā)人員需要解決移動(dòng)營(yíng)業(yè)員問(wèn)題页慷,這是一個(gè)著名的問(wèn)題,是機(jī)器學(xué)習(xí)的基礎(chǔ)胁附。給定一個(gè)銷(xiāo)售員和他們必須訪問(wèn)的城市列表酒繁,以及它們之間的距離,最佳路線是什么控妻?如果開(kāi)發(fā)人員設(shè)計(jì)了一種遺傳算法來(lái)解決此問(wèn)題州袒,則一個(gè)適應(yīng)度函數(shù)可能會(huì)評(píng)估路線的長(zhǎng)度,因?yàn)樽疃痰目赡艽碜畲蟮某晒颉A硪粋€(gè)適應(yīng)性功能可能是評(píng)估與路線相關(guān)的總成本郎哭,并嘗試將成本保持在最低水平他匪。另一個(gè)可能是評(píng)估移動(dòng)銷(xiāo)售人員離開(kāi)的時(shí)間,并進(jìn)行優(yōu)化以縮短總旅行時(shí)間夸研。

演化架構(gòu)的實(shí)踐借用了這個(gè)概念來(lái)創(chuàng)建架構(gòu)適應(yīng)性功能:

架構(gòu)適應(yīng)度函數(shù)
提供對(duì)某些架構(gòu)特征或架構(gòu)特征組合進(jìn)行客觀完整性評(píng)估的任何機(jī)制

適應(yīng)度函數(shù)不是供架構(gòu)師下載的某些新框架邦蜜,而是對(duì)許多現(xiàn)有工具的新視角。注意定義中的“任何機(jī)制”一詞-用于架構(gòu)特征的驗(yàn)證技術(shù)隨其特征而變化亥至。適應(yīng)度函數(shù)與許多現(xiàn)有的驗(yàn)證機(jī)制重疊悼沈,具體取決于它們的使用方式:作為度量標(biāo)準(zhǔn)、監(jiān)控姐扮、單元測(cè)試庫(kù)井辆、混亂工程等等,如圖所示溶握。

image.png

根據(jù)架構(gòu)特征杯缺,可以使用許多不同的工具來(lái)實(shí)現(xiàn)適應(yīng)度函數(shù)。例如睡榆,在“耦合”中萍肆,我們引入了度量標(biāo)準(zhǔn),以允許架構(gòu)師評(píng)估模塊性胀屿。以下是適合度函數(shù)的幾個(gè)示例塘揣,它們可以測(cè)試模塊化的各個(gè)方面。

循環(huán)依賴

模塊化是大多數(shù)架構(gòu)師關(guān)心的隱式架構(gòu)特征宿崭,因?yàn)榫S護(hù)不當(dāng)?shù)哪K化會(huì)損害代碼庫(kù)的結(jié)構(gòu)亲铡。因此,架構(gòu)師應(yīng)高度重視保持良好的模塊化葡兑。但是奖蔓,在許多平臺(tái)上,團(tuán)隊(duì)與架構(gòu)師的良好意圖背道而馳讹堤。例如吆鹤,在任何流行的Java或.NET開(kāi)發(fā)環(huán)境中進(jìn)行編碼時(shí),一旦開(kāi)發(fā)人員引用了尚未導(dǎo)入的類(lèi)洲守,IDE就會(huì)幫助顯示一個(gè)對(duì)話框疑务,詢問(wèn)開(kāi)發(fā)人員是否要自動(dòng)導(dǎo)入該引用。這種情況經(jīng)常發(fā)生梗醇,以至于大多數(shù)程序員習(xí)慣于像反射動(dòng)作一樣將自動(dòng)導(dǎo)入對(duì)話框拖走知允。但是,任意地在彼此之間導(dǎo)入類(lèi)或組件對(duì)于模塊化來(lái)說(shuō)是災(zāi)難叙谨。例如温鸽,圖展示了一種架構(gòu)師渴望避免的特別有害的反模式。

image.png

在圖中唉俗,每個(gè)組件都引用了其他組件嗤朴。 擁有這樣的組件網(wǎng)絡(luò)會(huì)破壞模塊化配椭,因?yàn)殚_(kāi)發(fā)人員無(wú)法重用單個(gè)組件,而又不能使其他組件一起使用雹姊。 而且股缸,當(dāng)然,如果將其他組件耦合到其他組件吱雏,則該架構(gòu)將越來(lái)越傾向于“大泥巴”反模式敦姻。 架構(gòu)師如何控制這種行為,而又不需時(shí)不時(shí)地看著那些對(duì)觸發(fā)器滿意的開(kāi)發(fā)人員歧杏? 代碼審查雖然有幫助镰惦,但在開(kāi)發(fā)周期中為時(shí)已晚,無(wú)法生效犬绒。 如果架構(gòu)師允許開(kāi)發(fā)團(tuán)隊(duì)在整個(gè)代碼庫(kù)中導(dǎo)入直到進(jìn)行代碼審查旺入,則代碼庫(kù)中已經(jīng)發(fā)生了嚴(yán)重?fù)p壞。

解決此問(wèn)題的方法是編寫(xiě)一個(gè)適應(yīng)度函數(shù)以查看周期凯力,如示例所示茵瘾。

示例 適應(yīng)度函數(shù)可檢測(cè)零件循環(huán)

public class CycleTest {
    private JDepend jdepend;

    @BeforeEach
    void init() {
      jdepend = new JDepend();
      jdepend.addDirectory("/path/to/project/persistence/classes");
      jdepend.addDirectory("/path/to/project/web/classes");
      jdepend.addDirectory("/path/to/project/thirdpartyjars");
    }

    @Test
    void testAllPackages() {
      Collection packages = jdepend.analyze();
      assertEquals("Cycles exist", false, jdepend.containsCycles());
    }
}

在代碼中,架構(gòu)師使用指標(biāo)工具JDepend來(lái)檢查包之間的依賴關(guān)系咐鹤。 該工具了解Java包的結(jié)構(gòu)拗秘,如果存在任何循環(huán),則測(cè)試失敗祈惶。 架構(gòu)師可以將此測(cè)試連接到項(xiàng)目的連續(xù)構(gòu)建中雕旨,而不必?fù)?dān)心觸發(fā)滿意的開(kāi)發(fā)人員意外引入周期。 這是一個(gè)適應(yīng)度函數(shù)捧请,可以保護(hù)重要而不是緊迫的軟件開(kāi)發(fā)實(shí)踐的一個(gè)很好的例子:這是對(duì)架構(gòu)師的重要關(guān)注凡涩,但對(duì)日常編碼幾乎沒(méi)有影響。

與主要序列適應(yīng)度函數(shù)的距離

在“耦合”中血久,我們引入了距主序列更深?yuàn)W的距離度量突照,架構(gòu)師也可以使用適應(yīng)度函數(shù)進(jìn)行驗(yàn)證,如示例所示氧吐。

示例—與主序列適應(yīng)度函數(shù)的距離

@Test
void AllPackages() {
    double ideal = 0.0;
    double tolerance = 0.5; // project-dependent
    Collection packages = jdepend.analyze();
    Iterator iter = packages.iterator();
    while (iter.hasNext()) {
      JavaPackage p = (JavaPackage)iter.next();
      assertEquals("Distance exceeded: " + p.getName(),
        ideal, p.distance(), tolerance);
    }
}

在代碼中,架構(gòu)師使用JDepend為可接受的值建立閾值末盔,如果類(lèi)超出范圍筑舅,則測(cè)試失敗。

這既是針對(duì)架構(gòu)特性的客觀度量的示例陨舱,又是設(shè)計(jì)和實(shí)現(xiàn)適應(yīng)性功能時(shí)開(kāi)發(fā)人員與架構(gòu)師之間協(xié)作的重要性的示例翠拣。這樣做的目的不是讓一群架構(gòu)師登上象牙塔并開(kāi)發(fā)開(kāi)發(fā)人員無(wú)法理解的深?yuàn)W適應(yīng)度函數(shù)。

提示
架構(gòu)師必須確保開(kāi)發(fā)人員在將適應(yīng)度函數(shù)強(qiáng)加給他們之前了解其功能游盲。

在過(guò)去的幾年中误墓,適應(yīng)度函數(shù)工具(包括一些專(zhuān)用工具)的復(fù)雜性有所提高蛮粮。一個(gè)這樣的工具就是ArchUnit,這是一個(gè)Java測(cè)試框架谜慌,其靈感來(lái)自于JUnit生態(tài)系統(tǒng)的各個(gè)部分并使用了這些部分然想。 ArchUnit提供了各種預(yù)定義的管理規(guī)則,這些規(guī)則被編碼為單元測(cè)試欣范,并允許架構(gòu)師編寫(xiě)解決模塊化的特定測(cè)試变泄。考慮圖中所示的分層架構(gòu)恼琼。

image.png

設(shè)計(jì)分層整體結(jié)構(gòu)(例如圖6-4中的整體結(jié)構(gòu))時(shí)妨蛹,架構(gòu)師有充分的理由定義層(動(dòng)機(jī),權(quán)衡和分層體系結(jié)構(gòu)的其他方面在第10章中進(jìn)行了描述)晴竞。 但是蛙卤,架構(gòu)師如何確保開(kāi)發(fā)人員會(huì)尊重這些層? 一些開(kāi)發(fā)人員可能不了解這些模式的重要性噩死,而其他開(kāi)發(fā)人員則可能會(huì)采用“更好地請(qǐng)求寬恕而不是允許”的態(tài)度颤难,這是因?yàn)橐恍┲T如性能之類(lèi)的對(duì)本地問(wèn)題的關(guān)注。 但是甜滨,允許實(shí)施者侵蝕架構(gòu)的原因會(huì)損害架構(gòu)的長(zhǎng)期健康乐严。

ArchUnit允許架構(gòu)師通過(guò)適應(yīng)性函數(shù)解決此問(wèn)題,如示例所示衣摩。

示例—ArchUnit適應(yīng)度函數(shù)可控制圖層

layeredArchitecture()
    .layer("Controller").definedBy("..controller..")
    .layer("Service").definedBy("..service..")
    .layer("Persistence").definedBy("..persistence..")

    .whereLayer("Controller").mayNotBeAccessedByAnyLayer()
    .whereLayer("Service").mayOnlyBeAccessedByLayers("Controller")
    .whereLayer("Persistence").mayOnlyBeAccessedByLayers("Service")

在例中昂验,架構(gòu)師定義了各層之間的理想關(guān)系,并編寫(xiě)了驗(yàn)證適應(yīng)度函數(shù)來(lái)對(duì)其進(jìn)行控制艾扮。

.NET空間中的類(lèi)似工具NetArchTest允許對(duì)該平臺(tái)進(jìn)行類(lèi)似的測(cè)試既琴。 例中顯示了C#中的依賴驗(yàn)證。

示例—NetArchTest用于層依賴性

// Classes in the presentation should not directly reference repositories
var result = Types.InCurrentDomain()
    .That()
    .ResideInNamespace("NetArchTest.SampleLibrary.Presentation")
    .ShouldNot()
    .HaveDependencyOn("NetArchTest.SampleLibrary.Data")
    .GetResult()
    .IsSuccessful;

適應(yīng)度函數(shù)的另一個(gè)例子來(lái)自Netflix的混亂的猴子和猴子部隊(duì)泡嘴。 整合安全性和管理猴子就是這種方法的例證甫恩。 從中猴子允許Netflix的架構(gòu)師定義生產(chǎn)中由猴子執(zhí)行的治理規(guī)則。 例如酌予,如果架構(gòu)師決定每個(gè)服務(wù)都應(yīng)該對(duì)所有RESTful動(dòng)詞做出有用的響應(yīng)磺箕,那么他們會(huì)將檢查內(nèi)容構(gòu)建到從眾猴子中。 同樣抛虫,安全猴子會(huì)檢查每個(gè)服務(wù)是否存在眾所周知的安全缺陷松靡,例如不應(yīng)激活的端口和配置錯(cuò)誤。 最終建椰,看門(mén)人猴子尋找不再有其他服務(wù)路由到的實(shí)例雕欺。 Netflix具有不斷發(fā)展的架構(gòu),因此開(kāi)發(fā)人員通常會(huì)遷移到較新的服務(wù),而無(wú)需協(xié)作者即可運(yùn)行舊服務(wù)屠列。 由于在云上運(yùn)行的服務(wù)會(huì)消耗金錢(qián)啦逆,因此看門(mén)人猴子會(huì)尋找孤立的服務(wù)并將其分解到生產(chǎn)環(huán)境之外。

幾年前笛洛,Atul Gawande撰寫(xiě)的頗有影響力的書(shū)《清單宣言》描述了航空飛行員和外科醫(yī)生等職業(yè)如何使用清單(有時(shí)是法律規(guī)定的)夏志。 這不是因?yàn)檫@些專(zhuān)業(yè)人士不了解工作或健忘。 相反撞蜂,當(dāng)專(zhuān)業(yè)人士一遍又一遍地完成非常詳細(xì)的工作時(shí)盲镶,細(xì)節(jié)容易流失。 簡(jiǎn)潔的清單可以有效地提醒您蝌诡。 這是適應(yīng)度函數(shù)的正確視角—適應(yīng)度函數(shù)不是重量級(jí)的治理機(jī)制溉贿,而是為架構(gòu)師提供了一種機(jī)制,可以表達(dá)重要的架構(gòu)原理并自動(dòng)進(jìn)行驗(yàn)證浦旱。 開(kāi)發(fā)人員知道他們不應(yīng)該發(fā)布不安全的代碼宇色,但是對(duì)于繁忙的開(kāi)發(fā)人員來(lái)說(shuō),優(yōu)先級(jí)會(huì)與數(shù)十或數(shù)百個(gè)其他優(yōu)先級(jí)競(jìng)爭(zhēng)颁湖。 特別是像安全猴子這樣的工具宣蠕,以及一般的適應(yīng)度函數(shù),允許架構(gòu)師將重要的治理檢查編入架構(gòu)的基礎(chǔ)甥捺。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抢蚀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子镰禾,更是在濱河造成了極大的恐慌皿曲,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吴侦,死亡現(xiàn)場(chǎng)離奇詭異屋休,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)备韧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)劫樟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人织堂,你說(shuō)我怎么就攤上這事叠艳。” “怎么了易阳?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵虑绵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我闽烙,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任黑竞,我火速辦了婚禮捕发,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘很魂。我一直安慰自己扎酷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布遏匆。 她就那樣靜靜地躺著法挨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪幅聘。 梳的紋絲不亂的頭發(fā)上凡纳,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音帝蒿,去河邊找鬼荐糜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛葛超,可吹牛的內(nèi)容都是我干的暴氏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼绣张,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼答渔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起侥涵,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤沼撕,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后独令,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體端朵,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年燃箭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冲呢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡招狸,死狀恐怖敬拓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裙戏,我是刑警寧澤乘凸,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站累榜,受9級(jí)特大地震影響营勤,放射性物質(zhì)發(fā)生泄漏灵嫌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一葛作、第九天 我趴在偏房一處隱蔽的房頂上張望寿羞。 院中可真熱鬧,春花似錦赂蠢、人聲如沸绪穆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)玖院。三九已至,卻和暖如春第岖,著一層夾襖步出監(jiān)牢的瞬間难菌,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工绍傲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扔傅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓烫饼,卻偏偏與公主長(zhǎng)得像猎塞,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子杠纵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容