軟件開(kāi)發(fā)中的缺陷隱含著極高的價(jià)值赦颇,但是許多組織都僅僅忍受了缺陷帶來(lái)的成本和后果啊鸭,卻讓價(jià)值白白溜掉了蛇摸。
缺陷的價(jià)值是其觸發(fā)的學(xué)習(xí)和成長(zhǎng)的機(jī)會(huì)急迂。把握缺陷帶來(lái)的學(xué)習(xí)機(jī)會(huì)影所,可以快速提高組織的能力,未來(lái)的缺陷更少僚碎,成本更低猴娩,更容易成功。但同時(shí),有效的缺陷分析和跟蹤行動(dòng)需要有效的方法和相應(yīng)的組織的支持胀溺。
缺陷隱含著極高的價(jià)值
最近我們做了一次關(guān)于缺陷分析的工作坊。
“發(fā)生缺陷是一件好事嗎皆看?” 在工作坊開(kāi)始的時(shí)候仓坞,我這么問(wèn)參與的同學(xué)。
“那當(dāng)然是一件壞事了腰吟∥薨#”
“不管是不是好事,它就在那兒毛雇。我覺(jué)得無(wú)所謂好不好嫉称,這是一件正常的事情×榇”
“這么說(shuō)好像也對(duì)织阅,但是缺陷很麻煩,我沒(méi)法喜歡缺陷震捣±竺蓿”
是的,沒(méi)有人喜歡缺陷蒿赢,它消耗研發(fā)成本润樱,影響開(kāi)發(fā)周期,但同時(shí)羡棵,缺陷又和軟件開(kāi)發(fā)如影隨形壹若,無(wú)論多少,始終都在皂冰。這是為什么呢店展?
軟件開(kāi)發(fā)和工業(yè)生產(chǎn)完全不同。工業(yè)生產(chǎn)通過(guò)消除過(guò)程中的各種可變性灼擂,能夠逐步逼近零缺陷的目標(biāo)壁查。所以,六西格瑪方法在工業(yè)生產(chǎn)中非常行之有效剔应。
軟件開(kāi)發(fā)的過(guò)程則恰恰相反睡腿。每一次開(kāi)發(fā),都是不確定的峻贮,我們往往都是在項(xiàng)目臨近結(jié)束的時(shí)候席怪,對(duì)整個(gè)項(xiàng)目的各種問(wèn)題和細(xì)節(jié)才變得清晰。在這種假設(shè)下纤控,與其追求零缺陷挂捻,倒不如說(shuō)是我們應(yīng)該追求降低缺陷的影響,比如船万,在缺陷產(chǎn)生的第一時(shí)間(注入時(shí)間甚至注入之前)就發(fā)現(xiàn)缺陷——因?yàn)檫@時(shí)候缺陷的成本幾乎為零刻撒,這也就可以等價(jià)為“零缺陷”了吧骨田。
如果說(shuō)工業(yè)生產(chǎn)中的六西格瑪方法來(lái)自于對(duì)生產(chǎn)系統(tǒng)的打造,那么声怔,在軟件開(kāi)發(fā)中态贤,“零缺陷”對(duì)應(yīng)的系統(tǒng)是什么呢?它當(dāng)然包含軟件研發(fā)的流程和工具醋火,但是悠汽,在我看來(lái),最重要的芥驳,應(yīng)該是打造軟件的核心主體——人柿冲。通過(guò)缺陷分析來(lái)持續(xù)學(xué)習(xí),才能不浪費(fèi)缺陷所消耗的成本兆旬。
為什么會(huì)重復(fù)踩坑
有不少團(tuán)隊(duì)是有缺陷原因分析的假抄。我曾經(jīng)仔細(xì)分析過(guò)一個(gè)團(tuán)隊(duì)的缺陷原因分析,發(fā)現(xiàn)了下面這些缺陷原因的高頻詞:
編碼有問(wèn)題丽猬,下次寫(xiě)代碼的時(shí)候想的更仔細(xì)一些慨亲。
代碼評(píng)審做的不好。下次代碼評(píng)審要充分宝鼓。
業(yè)務(wù)場(chǎng)景分析不全面刑棵,下次分析的更全面一些。
......
我相信愚铡,寫(xiě)下上述原因分析的同學(xué)蛉签,內(nèi)心一定是很真誠(chéng)的,也是真心覺(jué)得自己當(dāng)時(shí)代碼寫(xiě)的不夠好沥寥,業(yè)務(wù)場(chǎng)景分析的不全面碍舍,代碼評(píng)審不夠充分。但是邑雅,這個(gè)分析帶來(lái)的行動(dòng)片橡,卻往往是不可達(dá)成的。是真的想的不仔細(xì)嗎淮野,還是就是想不到捧书?這次評(píng)審做的不好,下次就肯定能做好了嗎骤星?這次場(chǎng)景分析不全经瓷,那么怎么才能更全呢?
這種原因分析過(guò)于寬泛了,以至于很難產(chǎn)生實(shí)際有效的改進(jìn)行動(dòng)洞难,下次往往還是會(huì)在同樣的地方跌倒——大家只要看一下在既往的原因分析中舆吮,有多少次類(lèi)似的答案?每一次重復(fù),就是一次新的踩坑色冀。
還有一類(lèi)原因分析潭袱,恰恰相反,又過(guò)于具體化了锋恬,具體化到了沒(méi)有學(xué)習(xí)價(jià)值的層面上敌卓。例如,這是當(dāng)時(shí)設(shè)計(jì)的不對(duì)伶氢,A 服務(wù)就不該調(diào)用 B 服務(wù),A 服務(wù)應(yīng)該考慮到B服務(wù)調(diào)用中的異常場(chǎng)景瘪吏,等等癣防。好吧,缺陷現(xiàn)在已經(jīng)修復(fù)了掌眠,A 服務(wù)調(diào)用 B 服務(wù)出現(xiàn)的異常場(chǎng)景已經(jīng)固化在代碼中了蕾盯,下一次如果是 C 服務(wù)調(diào)用 D 服務(wù)的異常場(chǎng)景應(yīng)該怎么辦呢?
最合適的缺陷原因應(yīng)該基于這樣的標(biāo)準(zhǔn):這些原因需要形成系統(tǒng)化的可行動(dòng)的結(jié)果蓝丙。這個(gè)標(biāo)準(zhǔn)的檢驗(yàn)方式是:下一次如果發(fā)生某某場(chǎng)景级遭,我們的應(yīng)對(duì)方案是否有效?
做好缺陷分析的 5 個(gè)要點(diǎn)
在實(shí)踐中,我們總結(jié)了 5 個(gè)要點(diǎn)渺尘,來(lái)最大化出于學(xué)習(xí)目的的缺陷分析的實(shí)踐操作挫鸽。它們是:
- 及時(shí)總結(jié),設(shè)置卡點(diǎn)
- 結(jié)對(duì)分析鸥跟,小組總結(jié)
- 負(fù)面清單支持下的全量分析
- 可操作的結(jié)果
- 團(tuán)體學(xué)習(xí)丢郊,機(jī)制建設(shè)
- 及時(shí)總結(jié),設(shè)置卡點(diǎn)
“缺陷分析很重要医咨,但是研發(fā)同學(xué)都太忙了枫匾,我們兩個(gè)月集中做一次怎么樣?”
別那么緊張——及時(shí)才是最節(jié)約的方式拟淮。要從忙碌中解放出來(lái)干茉,每次花 15 分鐘,做一次有效的缺陷分析很泊,時(shí)間已經(jīng)妥妥的啦角虫。
缺陷分析的最好時(shí)間是缺陷修復(fù)完成的時(shí)間。此時(shí)記憶最新鮮委造、也能早收益上遥。如果一個(gè)缺陷已經(jīng)過(guò)去了兩個(gè)月,那么缺陷分析的成本就變高了争涌,得找回原來(lái)的記憶和當(dāng)時(shí)的上下文粉楚,這個(gè)記憶準(zhǔn)確不準(zhǔn)確還是另一回事。
怎樣才能保證及時(shí)地做,從而保證這些重要而不緊急的事情發(fā)生呢模软?一個(gè)比較有效的方式伟骨,是設(shè)置流程中的卡點(diǎn):當(dāng)缺陷被設(shè)定為已修復(fù)狀態(tài)、或者設(shè)定為已關(guān)閉狀態(tài)時(shí)燃异,強(qiáng)制把缺陷分析設(shè)定為一個(gè)流程卡點(diǎn)携狭,這樣就能形成比較好的驅(qū)動(dòng)。
結(jié)對(duì)分析回俐,小組總結(jié)
誰(shuí)來(lái)負(fù)責(zé)缺陷分析逛腿?是讓具體這個(gè)缺陷的同學(xué)來(lái)做,還是召集整個(gè)團(tuán)隊(duì)一起仅颇?
召集整個(gè)團(tuán)隊(duì)來(lái)做缺陷分析单默,有時(shí)候代價(jià)過(guò)于高昂。即使僅僅分析比較后期的線上問(wèn)題忘瓦,即使每個(gè)缺陷僅僅分析 15 分鐘:100 個(gè)缺陷搁廓,每個(gè)團(tuán)隊(duì) 8 個(gè)人,乘積就是 12,000分鐘耕皮,合 200 個(gè)小時(shí)境蜕,也是一個(gè)驚人的數(shù)字,投入產(chǎn)出不成比例凌停。
解決缺陷的同學(xué)確實(shí)是對(duì)這個(gè)缺陷理解最好粱年。但是,這會(huì)不會(huì)形成“單點(diǎn)問(wèn)題”罚拟,降低問(wèn)題分析的有效性逼泣?
我們的方案是:
把結(jié)對(duì)分析作為制度
讓解決缺陷的同學(xué)擔(dān)任負(fù)責(zé)人,搭配上一個(gè)小伙伴舟舒。結(jié)對(duì)既形成了知識(shí)方面的互補(bǔ)拉庶,一定程度上消除了思維盲點(diǎn),也通過(guò)結(jié)對(duì)形成了更深入的討論秃励,也提前進(jìn)行結(jié)果的“驗(yàn)收”氏仗,提高分析的質(zhì)量。如果有必要夺鲜,結(jié)對(duì)的小組可以自主決定是否引入其他人參與皆尔。
團(tuán)隊(duì)定期討論學(xué)習(xí)
團(tuán)隊(duì)定期對(duì)重要的缺陷分析結(jié)果進(jìn)行討論,既是對(duì)小組成果的驗(yàn)收币励,更有利于在團(tuán)隊(duì)成員間形成傳播慷蠕,互相學(xué)習(xí)。
負(fù)面清單支持下的全量分析
缺陷分析的目的是提升食呻,所以流炕,重在解決那些“未知的未知”的問(wèn)題澎现。顯然不是每個(gè)缺陷都應(yīng)該深入分析。但是每辟,如果我們針對(duì)每個(gè)缺陷都定義它該不該分析剑辫,又會(huì)導(dǎo)致決策成本過(guò)高,而且質(zhì)量也不可靠渠欺。所以妹蔽,我們的做法是在默認(rèn)全量的基礎(chǔ)上,使用負(fù)面清單進(jìn)行過(guò)濾挠将。凡是負(fù)面清單不存在的胳岂,都進(jìn)行缺陷分析。負(fù)面清單是團(tuán)隊(duì)級(jí)別的舔稀。每個(gè)團(tuán)隊(duì)都應(yīng)該維護(hù)自己的列表乳丰,例如:
偶發(fā)問(wèn)題
已經(jīng)列在改進(jìn)項(xiàng)中的問(wèn)題(不斷擴(kuò)充)
這個(gè)事情和淘金有些類(lèi)似,明確不要什么镶蹋,能更高效地避免那些真正值得做的事情不被淹沒(méi)。事實(shí)上赏半,每次缺陷分析都會(huì)擴(kuò)充負(fù)面清單的長(zhǎng)度贺归,所需的缺陷分析數(shù)量將越來(lái)越少,問(wèn)題越來(lái)越聚焦断箫,時(shí)間也越來(lái)越節(jié)省拂酣。
可操作的結(jié)果
缺陷分析應(yīng)該產(chǎn)生有價(jià)值的洞見(jiàn),足夠的深度是重點(diǎn)仲义。在如何產(chǎn)生深度洞見(jiàn)方面已經(jīng)有非常多成熟的方法婶熬,最典型的是 5 Whys,此外還有魚(yú)骨圖等著名工具可用埃撵。為了控制篇幅赵颅,本文略去對(duì)這些方法的介紹,只通過(guò)一個(gè)實(shí)例來(lái)說(shuō)明在實(shí)際的缺陷分析中暂刘,我們是如何產(chǎn)生深度洞見(jiàn)的饺谬。
某缺陷描述了如下的場(chǎng)景(該實(shí)例在不影響問(wèn)題說(shuō)明的情況下做了適度抽象):
用戶(hù)持有某個(gè)虛擬設(shè)備,該設(shè)備有一些附屬資源谣拣,當(dāng)用戶(hù)刪除設(shè)備時(shí)募寨,該設(shè)備的附屬資源應(yīng)該被釋放。但是森缠,發(fā)現(xiàn)在一種特殊場(chǎng)景下拔鹰,這個(gè)附屬資源并沒(méi)有得到釋放。
代碼如下:
void releaseResources (resoure_id){ if (failedOfHardwareResourceRelease(resource_id)){ writeLog("resource release failed"); } }
下面是關(guān)于這個(gè)問(wèn)題的對(duì)話:
“原因是什么贵涵?”
“我們沒(méi)有在需求分析階段考慮到這種釋放不成功的場(chǎng)景列肢∏』”
“OK。需求分析是問(wèn)題例书,這是一個(gè)改進(jìn)點(diǎn)锣尉。——但是更重要的:最后發(fā)現(xiàn)這個(gè)問(wèn)題的最直接的機(jī)會(huì)點(diǎn)是哪個(gè)時(shí)間點(diǎn)决采?”
“寫(xiě)代碼的時(shí)候自沧。”
“寫(xiě)代碼的時(shí)候我們注意到這個(gè)問(wèn)題了嗎树瞭?”
“注意到了啊拇厢,所以寫(xiě)了 log,但是沒(méi)仔細(xì)想應(yīng)該怎么處理晒喷。這說(shuō)明我們對(duì)這段代碼的職責(zé)定義不清晰孝偎。”
==“也許我們可以在編程規(guī)范中加入一條:出現(xiàn)異常場(chǎng)景時(shí)不應(yīng)該只記錄 log凉敲,而應(yīng)該和負(fù)責(zé)人澄清場(chǎng)景和處理方案衣盾。在未來(lái),當(dāng)出現(xiàn)了僅僅出現(xiàn)寫(xiě)錯(cuò)誤 log爷抓,但是沒(méi)有其他處理的時(shí)候势决,我們就能注意到這一點(diǎn)±镀玻”
檢驗(yàn)分析深度是否足夠果复,最直接的指標(biāo)就是產(chǎn)生的結(jié)果是否是“可行動(dòng)的”。如果一個(gè)結(jié)果是不可行動(dòng)的渤昌,往往意味著深度或者抽象不夠虽抄。==
團(tuán)體學(xué)習(xí),機(jī)制建設(shè)
學(xué)習(xí)型組織并不總是容易建立独柑。除了上述心智模型和操作方法之外迈窟,組織機(jī)制往往是成功的重點(diǎn)。我們總結(jié)了如下幾點(diǎn):
- 是長(zhǎng)期存在的團(tuán)隊(duì)
- 建立持續(xù)學(xué)習(xí)的心智模型
- 持續(xù)維護(hù)和利用本組織的智力資產(chǎn)
這幾點(diǎn)似乎都毋需多言忌栅。但是關(guān)于智力資產(chǎn)菠隆,還是要多強(qiáng)調(diào)一下:分析結(jié)果最后可能會(huì)是流程改進(jìn)、編程習(xí)慣和編程規(guī)范狂秘、代碼評(píng)審的檢查單骇径、設(shè)計(jì)能力的提升、引入某些新的工程實(shí)踐如實(shí)例化需求等者春,不外乎有兩類(lèi):
短期的行動(dòng)
例如引入實(shí)例化需求實(shí)踐破衔、 建設(shè)自動(dòng)化測(cè)試機(jī)制等。對(duì)于這類(lèi)具體行動(dòng)钱烟,要定義責(zé)任人和結(jié)束日期晰筛,并且把它們和管理需求等工作項(xiàng)同等管理起來(lái)嫡丙,確保其發(fā)生。
長(zhǎng)期的規(guī)則
這類(lèi)是需要持續(xù)關(guān)注的東西读第,例如代碼評(píng)審的常見(jiàn)問(wèn)題列表曙博、采納某種設(shè)計(jì)思想如契約式設(shè)計(jì)、防御式編程等怜瞒。對(duì)于這類(lèi)問(wèn)題父泳,由于需要持續(xù)關(guān)注,需要維護(hù)它們吴汪,并把它們作為團(tuán)隊(duì)資產(chǎn)的一部分惠窄。當(dāng)然了,如果技術(shù)上可行漾橙,還是要把其中的一部分盡早做成工具杆融,減少記憶負(fù)擔(dān),提升可操作性霜运。
這種資產(chǎn)維護(hù)的越多脾歇,就會(huì)發(fā)現(xiàn)未來(lái)需要繼續(xù)分析的缺陷越少——當(dāng)然了,這也是一切資產(chǎn)的共性所在淘捡。
總結(jié)
現(xiàn)實(shí)情況紛繁復(fù)雜藕各,統(tǒng)一的方法往往并不存在。但是心智模型和一定的規(guī)律案淋、思路還是存在的座韵。本文聚焦于通過(guò)缺陷分析進(jìn)行學(xué)習(xí)险绘。
通過(guò)適當(dāng)?shù)姆椒ㄌ呔梢栽诳煽氐臅r(shí)間投入下,為組織積累寶貴的財(cái)富宦棺,并且在未來(lái)的開(kāi)發(fā)中得到數(shù)倍瓣距、數(shù)十倍上百倍的回報(bào)。忙碌不是理由代咸,在未來(lái)少掉一個(gè)新 bug蹈丸,就賺回來(lái)了。
通過(guò)缺陷分析呐芥,我們可以形成如下的產(chǎn)出:
- 建立團(tuán)隊(duì)關(guān)于需求分析逻杖、軟件設(shè)計(jì)、編程思瘟、測(cè)試荸百、運(yùn)維等方面的共同心智
- 形成常見(jiàn)問(wèn)題的檢查單
- 采用或者開(kāi)發(fā)新的工具
- 改進(jìn)既有流程
- 形成針對(duì)特定問(wèn)題的行動(dòng)計(jì)劃
- 最最重要的,通過(guò)消除各種盲點(diǎn)滨攻,我們的能力也就越來(lái)越強(qiáng)够话,開(kāi)發(fā)也就越來(lái)越順暢蓝翰,距離零缺陷的目標(biāo),就越來(lái)越近了女嘲。
文章引自 阿里技術(shù)