簡介: 缺陷分析作得好,bug 寫得少。阿里資深技術專家和你分享如何進行高質量的缺陷分析,總結了 5 個要點,經過缺陷分析消除開發中的各類盲點,打造一個學習型的團隊。編程
軟件開發中的缺陷隱含着極高的價值,可是許多組織都僅僅忍受了缺陷帶來的成本和後果,卻讓價值白白溜掉了。運維
缺陷的價值是其觸發的學習和成長的機會。把握缺陷帶來的學習機會,能夠快速提升組織的能力,將來的缺陷更少,成本更低,更容易成功。但同時,有效的缺陷分析和跟蹤行動須要有效的方法和相應的組織的支持。工具
最近咱們作了一次關於缺陷分析的工做坊。學習
「發生缺陷是一件好事嗎?」 在工做坊開始的時候,我這麼問參與的同窗。
「那固然是一件壞事了。」
「無論是否是好事,它就在那兒。我以爲無所謂好很差,這是一件正常的事情。」
「這麼說好像也對,可是缺陷很麻煩,我無法喜歡缺陷。」測試
是的,沒有人喜歡缺陷,它消耗研發成本,影響開發週期,但同時,缺陷又和軟件開發如影隨形,不管多少,始終都在。這是爲何呢?編碼
看下面的這張圖:spa
軟件開發和工業生產徹底不一樣。工業生產經過消除過程當中的各類可變性,可以逐步逼近零缺陷的目標。因此,六西格瑪方法在工業生產中很是行之有效。設計
軟件開發的過程則偏偏相反。每一次開發,都是不肯定的,咱們每每都是在項目臨近結束的時候,對整個項目的各類問題和細節才變得清晰。在這種假設下,與其追求零缺陷,倒不如說是咱們應該追求下降缺陷的影響,好比,在缺陷產生的第一時間(注入時間甚至注入以前)就發現缺陷——由於這時候缺陷的成本幾乎爲零,這也就能夠等價爲「零缺陷」了吧。code
若是說工業生產中的六西格瑪方法來自於對生產系統的打造,那麼,在軟件開發中,「零缺陷」對應的系統是什麼呢?它固然包含軟件研發的流程和工具,可是,在我看來,最重要的,應該是打造軟件的核心主體——人。經過缺陷分析來持續學習,才能不浪費缺陷所消耗的成本。blog
有很多團隊是有缺陷緣由分析的。我曾經仔細分析過一個團隊的缺陷緣由分析,發現了下面這些缺陷緣由的高頻詞:
我相信,寫下上述緣由分析的同窗,心裏必定是很真誠的,也是真心以爲本身當時代碼寫的不夠好,業務場景分析的不全面,代碼評審不夠充分。可是,這個分析帶來的行動,卻每每是不可達成的。是真的想的不仔細嗎,仍是就是想不到?此次評審作的很差,下次就確定能作好了嗎?此次場景分析不全,那麼怎麼才能更全呢?
這種緣由分析過於寬泛了,以致於很難產生實際有效的改進行動,下次每每仍是會在一樣的地方跌倒——你們只要看一下在既往的緣由分析中,有多少次相似的答案?每一次重複,就是一次新的踩坑。
還有一類緣由分析,偏偏相反,又過於具體化了,具體化到了沒有學習價值的層面上。例如,這是當時設計的不對,A 服務就不應調用 B 服務,A 服務應該考慮到B服務調用中的異常場景,等等。好吧,缺陷如今已經修復了,A 服務調用 B 服務出現的異常場景已經固化在代碼中了,下一次若是是 C 服務調用 D 服務的異常場景應該怎麼辦呢?
最合適的缺陷緣由應該基於這樣的標準:這些緣由須要造成系統化的可行動的結果。這個標準的檢驗方式是:下一次若是發生某某場景,咱們的應對方案是否有效?
在實踐中,咱們總結了 5 個要點,來最大化出於學習目的的缺陷分析的實踐操做。它們是:
「缺陷分析很重要,可是研發同窗都太忙了,咱們兩個月集中作一次怎麼樣?」
別那麼緊張——及時纔是最節約的方式。要從忙碌中解放出來,每次花 15 分鐘,作一次有效的缺陷分析,時間已經妥妥的啦。
缺陷分析的最好時間是缺陷修復完成的時間。此時記憶最新鮮、也能早收益。若是一個缺陷已通過去了兩個月,那麼缺陷分析的成本就變高了,得找回原來的記憶和當時的上下文,這個記憶準確不許確仍是另外一回事。
怎樣才能保證及時地作,從而保證這些重要而不緊急的事情發生呢?一個比較有效的方式,是設置流程中的卡點:當缺陷被設定爲已修復狀態、或者設定爲已關閉狀態時,強制把缺陷分析設定爲一個流程卡點,這樣就能造成比較好的驅動。
誰來負責缺陷分析?是讓具體這個缺陷的同窗來作,仍是召集整個團隊一塊兒?
召集整個團隊來作缺陷分析,有時候代價過於高昂。即便僅僅分析比較後期的線上問題,即便每一個缺陷僅僅分析 15 分鐘:100 個缺陷,每一個團隊 8 我的,乘積就是 12,000分鐘,合 200 個小時,也是一個驚人的數字,投入產出不成比例。
解決缺陷的同窗確實是對這個缺陷理解最好。可是,這會不會造成「單點問題」,下降問題分析的有效性?
咱們的方案是:
把結對分析做爲制度
讓解決缺陷的同窗擔任負責人,搭配上一個小夥伴。結對既造成了知識方面的互補,必定程度上消除了思惟盲點,也經過結對造成了更深刻的討論,也提早進行結果的「驗收」,提升分析的質量。若是有必要,結對的小組能夠自主決定是否引入其餘人蔘與。
團隊按期討論學習
團隊按期對重要的缺陷分析結果進行討論,既是對小組成果的驗收,更有利於在團隊成員間造成傳播,互相學習。
缺陷分析的目的是提高,因此,重在解決那些「未知的未知」的問題。顯然不是每一個缺陷都應該深刻分析。可是,若是咱們針對每一個缺陷都定義它該不應分析,又會致使決策成本太高,並且質量也不可靠。因此,咱們的作法是在默認全量的基礎上,使用負面清單進行過濾。凡是負面清單不存在的,都進行缺陷分析。負面清單是團隊級別的。每一個團隊都應該維護本身的列表,例如:
這個事情和淘金有些相似,明確不要什麼,能更高效地避免那些真正值得作的事情不被淹沒。事實上,每次缺陷分析都會擴充負面清單的長度,所需的缺陷分析數量將愈來愈少,問題愈來愈聚焦,時間也愈來愈節省。
缺陷分析應該產生有價值的洞見,足夠的深度是重點。在如何產生深度洞見方面已經有很是多成熟的方法,最典型的是 5 Whys,此外還有魚骨圖等著名工具可用。爲了控制篇幅,本文略去對這些方法的介紹,只經過一個實例來講明在實際的缺陷分析中,咱們是如何產生深度洞見的。
某缺陷描述了以下的場景(該實例在不影響問題說明的狀況下作了適度抽象):
用戶持有某個虛擬設備,該設備有一些附屬資源,當用戶刪除設備時,該設備的附屬資源應該被釋放。可是,發如今一種特殊場景下,這個附屬資源並無獲得釋放。
代碼以下:
void releaseResources (resoure_id){ if (failedOfHardwareResourceRelease(resource_id)){ writeLog("resource release failed"); } }
下面是關於這個問題的對話:
「緣由是什麼?」
「咱們沒有在需求分析階段考慮到這種釋放不成功的場景。」
「OK。需求分析是問題,這是一個改進點。——可是更重要的:最後發現這個問題的最直接的機會點是哪一個時間點?」
「寫代碼的時候。」
「寫代碼的時候咱們注意到這個問題了嗎?」
「注意到了啊,因此寫了 log,可是沒仔細想應該怎麼處理。這說明咱們對這段代碼的職責定義不清晰。」
「也許咱們能夠在編程規範中加入一條:出現異常場景時不該該只記錄 log,而應該和負責人澄清場景和處理方案。在將來,當出現了僅僅出現寫錯誤 log,可是沒有其餘處理的時候,咱們就能注意到這一點。」
檢驗分析深度是否足夠,最直接的指標就是產生的結果是不是「可行動的」。若是一個結果是不可行動的,每每意味着深度或者抽象不夠。
學習型組織並不老是容易創建。除了上述心智模型和操做方法以外,組織機制每每是成功的重點。咱們總結了以下幾點:
這幾點彷佛都毋需多言。可是關於智力資產,仍是要多強調一下:分析結果最後可能會是流程改進、編程習慣和編程規範、代碼評審的檢查單、設計能力的提高、引入某些新的工程實踐如實例化需求等,不外乎有兩類:
短時間的行動
例如引入實例化需求實踐、 建設自動化測試機制等。對於這類具體行動,要定義責任人和結束日期,而且把它們和管理需求等工做項同等管理起來,確保其發生。
長期的規則
這類是須要持續關注的東西,例如代碼評審的常見問題列表、採納某種設計思想如契約式設計、防護式編程等。對於這類問題,因爲須要持續關注,須要維護它們,並把它們做爲團隊資產的一部分。固然了,若是技術上可行,仍是要把其中的一部分儘早作成工具,減小記憶負擔,提高可操做性。
這種資產維護的越多,就會發現將來須要繼續分析的缺陷越少——固然了,這也是一切資產的共性所在。
現實狀況紛繁複雜,統一的方法每每並不存在。可是心智模型和必定的規律、思路仍是存在的。本文聚焦於經過缺陷分析進行學習。
經過適當的方法,它能夠在可控的時間投入下,爲組織積累寶貴的財富,而且在將來的開發中獲得數倍、數十倍上百倍的回報。忙碌不是理由,在將來少掉一個新 bug,就賺回來了。
經過缺陷分析,咱們能夠造成以下的產出:
最最重要的,經過消除各類盲點,咱們的能力也就愈來愈強,開發也就愈來愈順暢,距離零缺陷的目標,就愈來愈近了。