軟件工程師是用腦子解決問題的人

源自:?賈彥民?InfoQ時間:2018-01-09次數:1

         陪女兒看動畫片《米奇妙妙屋》,米奇有一句口頭禪:我們是用腦子解決問題的人。從女兒的表情判斷,這句話似乎并沒有給她留下不一樣的印象,三歲半的女兒畢竟還太年輕。但我在想:工程師才最應該是用腦子解決問題的人啊。原始人區別于動物的地方是漸漸地有了思考的能力,但這種思考能力水平很低,缺乏系統性和邏輯性。比如餓了,出去打獵;吃飽的時候,就無所事事,而不是繼續工作,儲存食物以備不時之需。這樣長遠的打算遠遠超出了他的思考能力。就好像小孩子一樣,在我們農村老家,冬天很冷,到了這個季節,有的小孩子特別喜歡尿褲子,那是因為尿的溫度使孩子感覺很溫暖,卻全不考慮熱尿變涼之后的痛苦,于是,上一次的尿涼了,就只好努力再來上一泡。

 到了新石器時代,人類開始耕種和馴養動物時,才真正有了系統性的思考。即使對于現代的人們,系統的邏輯的思考能力依然是寶貴的稀有資源,并非想當然的人人都可以自然地輕易擁有。很多人大多數時候都是情緒的宣泄,不過是所謂的感情用事,這和原始人及小孩子并沒有太大的區別。

  測試工程師和開發工程師都是軟件工程師,請注意在這里工程師才是重點,工程師尤其是和程序打交道的軟件工程師的一個重要特質就是知道如何用科學的方法論來解決問題。

  所謂科學的方法論,簡單地講,即數據和邏輯的組合,數據表述事實,邏輯用于推理,一言以蔽之,就是基于數據事實的邏輯推理。計算機科學專業的課程中的數據結構和算法從本質上講也可以說是軟件工程師的方法論。數據結構用來無歧義地有組織地抽象出問題域中的實體和對象,而算法描述了計算過程的邏輯的確定性和正確性以及計算的其他性質如時間復雜度和空間復雜度。

 軟件工程師面對問題時,首先要把問題的事實即數據無歧義地有組織地清清楚楚地表示出來,然后,利用邏輯的分析、歸納和推理找出問題的癥結之所在,最后根據軟件設計與開發的原則和最佳實踐得到問題的解決方案。

四個例子

 

例子 一:

 有測試工程師抱怨開發工程師不停地改變命令行的字符串,導致她的測試腳本不能穩定運行,每次命令行字符串的改變都浪費了她大量的時間去修改測試的腳本。軟件開發中隨時隨地要面對各種各樣的變化,不讓開發工程師修改這些字符串顯然是不可能的和不合理的。問題的事實是在測試的腳本中處理經常改變的命令行字符串需要大量的時間,原因是她把這些字符串硬編碼到測試的腳本中。

在程序設計的方法中,一個重要的原則是把需要經常變化的部分隔離開來,這樣有利于更容易地管理這些變化。所以,可能的解決方案就是把這些字符串隔離出來,定義為全局變量,在測試腳本中引用這些變量就可以了。這樣,當開發工程師修改了這些字符串時,測試工程師只要修改這些變量的定義就好了。

例子二:

 常常聽到測試團隊和開發團隊抱怨產品的性能如何糟糕,但抱怨僅僅只是抱怨,問題依然還是問題。解決性能問題,首先要知道怎樣量化地定義性能。對程序而言,性能可概括為兩個參數,即吞吐量(Throughput)和響應時間(Responding Time)。令人沮喪的并不在于有些工程師不知道性能的定義,而是根本沒有想到要知道性能的定義。追本溯源,多半是從來沒有使用數據與邏輯的科學方法的意識和習慣,不知道用什么樣的方法來解決問題,剩下的當然只有抱怨了。

        所以,工程師尤其是測試工程師最不應該抱怨產品的性能,正確的做法應該是找到一個應用案例(Use Case),給出具體的可重現的配置操作步驟,得到相應的吞吐量或響應時間,和期望的結果做比較,指出其中的差距。有了應用案例,開發工程師就可以用一些工具做性能的profiling了,根據profiling的數據,找出性能的瓶頸是什么,帕累托原理告指出往往是局部的區域貢獻了大部分的問題,比如一個拙笨的函數,導致響應時間增加80%。以這些數據做基礎,開發工程師更容易的做出有針對性的解決方案,我們當然有理由對這樣的解決方案對于改進性能抱有更大的信心。

 最后,當然還是要用測試的數據來證明解決方案的有效性。這是改善產品性能最專業的做法。我們是做交換機系統軟件的公司,利用這種方法,在CPU占用率基本不變的情況下,CPU處理協議包(protocol packet)的吞吐量提高了一倍。

例子三:

 做產品級的功能。和例子二一樣,我們總是感覺公司的產品的某些地方不太像產品的樣子,但到底是哪些地方由于什么問題讓我們產生這樣的感覺呢?說不清楚。這就如同某人到公司之后給大家留下了很邋遢的印象,可誰會去細想是因為他今天沒有刮胡子還是沒有洗頭發的緣故呢?更有人認為,像我們這樣的起步公司,對功能的質量不能過于苛求,最好也就做成這樣了。于是,妄自菲薄變成了怠于思考的口實。

 解決這個問題,首先還是應該從事實和數據著手,即產品的哪些地方出了什么問題。方法是把問題具體化,以某個具體的功能作為例子,和同類的頂級的產品做對比研究。

        結果表明:針對該項功能,在大的方面,比如設計目標、應用場景、部署的網絡拓撲、甚至于實現的技術路線,我們的產品和參照的產品并沒有顯著的差異。真正的差距體現在用戶體驗(UX, User eXperience)設計的細節上。比如我們在CLi(Command Line)中呈現給用戶的信息沒有進行精心的過濾和組織,使用了晦澀混淆的術語,并且包含了一些對用戶而言毫無意義的數據,使得整個產品看起來粗糙丑陋,不夠專業。

 結論是:技術總是簡單,而設計無限。假設我們做新的功能時,從用戶的角度出發,真正花些心思在UX的設計上,產品的質量一定會有大的改善。在這個案例中,如果能夠得到用戶的反饋信息,做綜合的分析,那就更加完美了。最后,由于公司保密政策的考慮,我不能列出做對比的兩個產品的名稱,也不能給出那個功能的具體的細節。

例子四:

 和Regression Bug開戰。Regression Bug指的是工程師在修改一個Bug或開發一項功能時將原來好的功能破壞了。如果一個產品開發周期發現了大量的Regression Bug,意味著產品質量的倒退和開發團隊的不專業,這真的是一件令人萬分沮喪的事兒。如果Regression Bug留到了用戶那里,可能會是災難性的后果。因此,產品新的版本發布前,都要進行嚴格的Regression測試。

        我們沒有辦法和Regression Bug永遠說再見,因為任何人在任何時候和任何環節可能有任何錯誤,這也是產品開發中最大的不確定的風險,能夠做的是盡量避免。還是老的方法,把Regression Bug收集起來,針對其中的每一個,分析產生的原因和可能避免的辦法。

 我們發現,有趣的是,越是嚴重的Regression Bug,背后的原因越是簡單。比如系統崩潰是因為某個變量使用前沒有初始化,忘記for語句的循環變量遞加導致系統卡死掛起。所以,小問題引起了大麻煩。這樣的信息反饋給開發工程師,就能夠激發TA有針對性地提升自己的專業水平。

總結

 

  人類是情感和理性交織的動物,偶爾的情感宣泄難以避免,重要的是,無論什么時候,都不要忘記了理性的思考,這是唯一的可以幫助我們解決問題的力量。因此,一個測試工程師如果不了解不運用科學的方法,即使積累了再多的領域知識,最多也就是一個操作員;一個開發工程師如果不了解不運用科學的方法,即使積累了再多的編程經驗,最多也就是一個編碼員。

福利视频(午夜)