每日最新頭條.有趣資訊

不是程序員的程序員

作者丨賈彥民

程序員如何看軟體管理?從寫代碼的程序員到做管理的程序員,作者從程序員的視角講述了軟體開發實踐中溝通和流程的理解和第一手體驗。作者認為,靈活,簡單,直接,清楚是有效(effective)且高效(efficient)的溝通和流程的不二法門。

從 2009 年公司成立算下來,已有八九年的光景了,雖然時間不算很短了,但總體上公司還是以起步的模式運營。我加入公司轉眼間也過了五個年頭,從寫程序的程序員開始,逐步過渡到了現在的俗稱所謂的“管理”崗位。嚴格地講,公司對我的職責範圍並沒有清楚的界定。

根據我的經驗,在起步公司做事情,職責範圍基本上是自己測試出來的。一件事情做完了,順風順水,上下歡喜,雖名份所關,亦當仁不讓;另一件事情忙 (盲) 著去做了,吃力不討好,天怒人怨,雖僥幸得成,亦下不為例。

我的這個角色有一點兒尷尬,甚至沒有一個明確的名稱,所以,我戲稱這個不知道名字的角色是“不是程序員的程序員”。原因在於,雖然沒有太多機會生產加入到產品中的代碼了,但是在工作中還是在用程序員的腦子來思考和解決大大小小的各種問題。

公司的情況有些特殊,總部位於美國的矽谷。大部分的產品、銷售和市場團隊都在美國;而所有的工程師團隊在北京這邊。我的工作內容可用繁和雜兩個字來概括:負責產品的發布,保證新版本的內容和質量;作為北京工程師團隊和美國產品團隊的一個聯結點,組織兩邊的溝通和討論,包括需求,問題,設計,實現,以及項目的優先級和進度;而在北京工程師團隊這邊,協調突破需要跨團隊合作的項目;參與討論產品的新功能的設計、實現和測試,審核相關的文檔。另外,凡是和項目及產品相關的,而所有的開發工程師和測試工程師不大會關注的事情,比如管理 git 的開發分支,監管重要分支上的代碼提交,甚至於作為替補,幫忙合並和編譯代碼。救火隊長的即成的事實讓習慣成自然,雖欲懈怠,奚可焉?!

因此,溝通 (communication) 是我日常最重要的事情。和不同角色的人們包括開發工程師,測試工程師,支持工程師,架構師,產品經理,市場銷售通過交談、文檔 、會議、郵件弄明白和講清楚生產線兩頭的故事。

一頭是用戶的故事,即需求和問題;一頭是代碼的故事,即設計和實現;中間穿插著項目的優先級和進度。幫助大家了解這些故事,是我對公司的主要價值。在一個忙碌的工作日上午,從 9 點到辦公室到 11 點半去吃午餐,我參加了三個會議,仔細閱讀了 20+ 個郵件,大致瀏覽了 30+ 個郵件,寫了 14 個郵件,我私下開玩笑說這個上午很對得起公司付我的薪水了。

偉大的藝術作品是人世間和自然界的美的反映,這裡所說的美並不是我們平常所說的美麗的那種美,而是在 Clive Bell 的著作《Art》中所描述的哲學意義上的終極真實 (Ultimate Reality) 的那種美,即有意味的形式(Significant Form)。

藝術家從藝術的角度發現並理解了這種美,並把它表達在畫布上和音樂裡。因此,藝術家的能力一方面表現在對美的發現和理解;另一方面表現在對美的表達。因此,我認為,發現,理解和表達便是藝術創造力的全部。同樣地,高質量的軟體產品是目標用戶的真實意願在自身中的映射。這種意願常常是微妙的,模糊的,難以描述的。甚至連用戶自己都不真正知道想要的究竟是什麽,有時看到產品時,用戶才發覺和實際的使用場景南轅北轍。發現和理解用戶的真實需求,是產品經理的創造力;將需求表達在程序的設計上和代碼的實現裡,是程序員兼架構師的創造力;驗證代碼和需求的契合程度,即代碼的正確性,是測試工程師的創造力。

因此,理解,表達和驗證是軟體創造力的魔幻三傑的組合,而理解是這個組合的基礎和前提。不妨拿修改一個 BUG 為例,首要的問題是:有穩定的重現步驟嗎?根本原因是什麽?解決的辦法是什麽?是否有其他的解決辦法?

知道導致問題的根本原因,代碼的修改才不會對其他正確的功能產生副作用,避免質量的倒退 (Quality Regression);有穩定的重現步驟,BUG 修改後,才有相應的驗證方法。這樣,最終才能夠有信心把新的版本交付給用戶。因此,對一個 BUG 的理解包含在解決它的過程中,即可重現,知道根本原因和解決方法,修改後可驗證。

最糟糕的情形莫過於此:BUG 不能清楚的描述,不知道重現的步驟,或者似乎可以重現,也不確定是否和應用場景相同。程序員可以修改一個知道不知道什麽 (Known Unknown) 或知道要知道什麽 (Known Known) 的 BUG,可怎樣解決一個不知道不知道什麽 (Unknown Unknown) 的 BUG 呢?僅憑臆測猜著去修改一個似有若無的 BUG,其結果不問可知了。

藝術作品的創作大都是一個人獨立完成,所以藝術家是孤僻的,默默的去發現,理解和表達心中那身份獨特的不為人知的美。而大型軟體系統的開發卻熱鬧多了,是產品經理、架構師、程序員、測試工程師這些不同角色的人們共同合作的勞動成果,若要把所有參與到軟體實踐中的人們的創造力 (發現,理解和表達) 正確地貫徹到最終的產品中,需要有效且高效的溝通。

尊重和信任是良好溝通的開始和第一要義。公司研發的是專業性很強的網絡交換機的作業系統軟體,在網絡工業界,只有經過長時間的經驗積累,才有可能成為某個方面的專家。正如沒有包治百病的全能醫生一樣,也很少有這樣的全才,對設備軟硬體的方方面面的所有細節都了如指掌。

所以,我常常提醒自己,要以謙卑的學習的態度,充分地相信和尊重每個工程師在其所熟悉的領域的專業和技能。事實上,在溝通的過程中,我學到了太多太多的專業知識。老實講,像我這種只是紙上談兵的人對有實戰經驗的網絡工程師懷有真誠的敬意。

溝通是雙向的,一方面是聽的明白,一方面是講的清楚。而我的主要任務是傾聽和提問,目的是理解。長期的作為程序員的計算思維的訓練,我最深刻的體會是程序員之間的對話要用程序員的語言:一方面聽要聽得出問題的關鍵和本質,腦子要清醒,不要像《天龍八部》裡面的包二先生,深陷於表面的細枝末節而纏夾不清;另一方面問要以具體的用例問具體的問題,具體的用例和具體的問題才能讓討論不斷引向深入。

對於不了解的事情,不可能一上手就門兒清,問出專業水準的具體的問題。通過聽和問的互動,剝絲抽繭,由淺入深,事情的真相就會逐漸浮出水面。這個過程有點兒象用 google 搜索一個完全不了解的問題的答案,開始時只有一個模糊的概念,連準確的關鍵詞都不知道,只能得到一些相關的中間結果,慢慢地從這些中間結果中得到和問題越來越接近的關鍵詞,最終檢索到想要的答案。

講的清楚靠的不是伶牙俐齒和能說會道,仿佛兮若口懸黃河,滔滔不絕,實際上卻離題萬裡,不知所雲。講的清楚是言必有中,說到點子上,用最簡單和最直接的方式傳遞最準確的信息。一件事情表達不到位,多半是因為了解地不夠,想不明白當然就講不清楚。程序員常常借助於軟體的層次結構進行系統地思考和論述,低層的基礎設施向上層的功能應用提供接口,當前層隱藏了所有低層的實現細節,給出了更高級別的抽象。

有的工程師工作在軟體的更低層,比如開發驅動代碼的系統工程師;有的工程師工作在軟體的較高層,比如測試工程師的工作基於最高級別的抽象層次,即暴露給用戶的接口如 CLI(Command Line Interface) 或 GUI(Graphic User Interface)。

在我看來,無論是開發工程師還是測試工程師都是工作在不同抽象層次上的程序員,應有共同的語言和思維方式。眉毛鬍子一把抓必然導致混淆,思考的方向有效地聚焦在特定功能的特定的軟體層次上才容易把問題想明白講清楚。關注的抽象層次或高 (淺) 或低 (深),功能的範圍或大 (寬) 或小 (窄),重要的是厘清針對該功能的該層次的相關的接口的細節,去除似是而非的模糊猜想,有啥問題不能搞懂呢?!看問題看得深,看得準,看得透,功夫常在詩外,日常少一些蹭熱度,少一些刷存在感,多一些專研業務,胸中有點兒墨,庶幾可侍矣!

無論說還是問都必須建立在事實即數據和邏輯的基礎上,不能以虛擬的事實和臆測的邏輯主導討論的方向,以新的混淆堆疊到老的混淆之上,在極度的挫敗與沮喪的氣氛中消斫著彼此的信任。

討論一旦陷入這種癡人囈語的夢境,再繼續下去,不過是浪費時間。這種情形下,多說無益,不如去做。研究代碼,查閱資料,收集新的數據,然後,再來決定何去何從。畢竟都是程序員,最好一竿子插到底,拿出代碼來看,那才是熟悉的味道。借助於數學語言,可以減少許多表達上的歧義。比如,使用二維以至於多維的矩陣表呈現不同類型多種情況的組合,往往達到事半功倍的效果。

建設性的討論和溝通的焦點常常集中地放在具體的問題、具體的案例和具體的需求上,大家保持在同一個頻道,彼此的啟發和知識的互補有助於理解事物的本質。盡量避免天馬行空般的哲學爭辯,比如,事實還沒有完全澄清,便迅速的轉向與討論的對象毫不相乾的抽象的流程和方法論,弄了半天,還不知道正題是什麽。

“坐議立談,無人能及,隨機應變,百無一能。”那些雍容華貴的清談,看似高雅,其實不過是窮嚼蛆的無稽之談,除了誤國然而並沒有什麽卵用,吾深恨之。

在任何情況下,都必須講真實的故事。比如在發布產品的新版本時,哪些已知的問題尚未解決,哪些測試的案例沒有覆蓋,使用上有哪些限制,都必須有一說一地在文檔(如 Release Notes)中一一指明。有基於此才可能有效地管理用戶對發布版本的期望。面臨用戶緊急需求的時間壓力時,不能以犧牲產品的質量來追求效率,更不能草率地答應不切實際的時間表,儘管過度承諾(over commit)時說 OK 的那一刻大家都很興奮,上下“充滿了快活的空氣”。當逾期不能交付或由於趕時間交付了質量糟糕的版本時,一時的快意於用戶造成了永久的長痛,進退失據之間,又何以挽回與用戶雙輸的殘局呢?!

事無巨細,尤其是工作中的那些瑣碎的雜務 (miscellaneous),唯有耐煩些,以勤謹自勉。為此,我大概是辦公室走路最多的人。多數工程師隻關注自己負責的領域,個人自掃門前雪。其實也沒有什麽不好,專業的人做專業的事兒,這樣更有利於專注於一點並做到極致。

如下圖所示,每個人的工作相互之間不可避免地會有少許重疊的交集,與此同時,也不可避免地會留下一些無人理會的空白。這些空白多半是些細枝末節的“髒活兒”,看似無關緊要,然而,細節常常決定一切,發布新版本時,忘記更新版本號就可能造成極大的困擾。因此,總要有人多操一份心,來填補這些空白的部分。

總而言之,一方面要小心謹慎,有責任心,臨事以懼;另一方面,更重要的是,要有能力,有辦法,好謀而成。盡量用技術的手段保證不出差錯,可以由程序完成的任務絕不用人工來做。對任何一件事情,程序員的方法是把它看做開發一項新的功能,事先準備一個類似於測試計劃的檢查列表 (checklist);事後一一對照檢查,測試驗證完畢,哪裡還有意外發生?!

多操一些大家都不操的心,當然是極好的事兒。需要注意的是,千萬不要討人嫌,亂操別人家的閑心。一定要耐得住寂寞,知道克制。成功不必在我,任何一個進展順利的項目,最好是做一個觀棋不語的真君子,只要知趣地在旁邊默默地看著就好。需要幫助,人家自然會過來找你。大概人性使然,揮斥方遒,指點江山,是多少人的夢想?!談笑間神州大定,權力帶來的快感達到了高潮,爽之極矣,誰不想?據稱川普曾半當真地半開玩笑地打起了閱兵的主意,莫非他想在山呼海嘯般的“首長好”中過把總統癮?美國的總統畢竟“配不上”閱兵的禮遇,結果在山呼海嘯般的罵聲中,未曾出師便黯然收兵了。聰明的程序員總是知道什麽時候做什麽事兒,何須別人瞎指揮?不懂裝懂,輕率地指點別人的江山,常常自取其辱而於事無補。

流程是一個常常引起爭論的話題。同樣的情形,事情搞砸了,或歸罪於糟糕的流程束縛了大家的手腳,這是大公司的通病;或歸罪於沒有流程或只有形同虛設的流程,這是小公司的鄙陋。

我認為,《創新者的窘境》對流程的概念做了最好的詮釋,即有效的流程是可複製的成功。流程是可變的,而不是僵化的;流程是靈活的,而不是教條的。我們把在軟體開發實踐中那些行之有效的做法,固定下來,即是流程。比如開始一個新的重要的項目,我們常常由對項目最懂的工程師領銜,臨時組織一個跨開發與測試的動態小組 (Dynamic Team),根據項目需要,隨時加入新的成員,而完成任務的成員及時退出,項目做完後,小組全部解散。正是這種臨時拚湊的貌似雜牌軍的動態開發小組機甲狂潮出了無與倫比的戰鬥力和創造力,常常高效快速地完成不可能的艱難任務。

我們的團隊常常同時有好幾個這樣的動態小組工作在不同的項目上。這完全是一個不具文的流程,有的同事在完成任務退出時甚至不知道自己被拉進了一個動態小組。

流程是用來解決問題而不是製造問題,我的意思是說,並非所有的開發實踐都可以套用流程,為了流程而流程,等於自覺地向僵化和教條的鬼蜮伸出了橄欖枝。

記得當年在 IBM 時,我所在的部門照本宣科地模仿所謂的敏捷開發 (Aigile Software Development ) 流程。每天早上,所有的開發和測試小組開始工作前,都要單獨聚在一起開一個長至半個小時的例會 (SCRUM meeting),檢查一下當前的狀態,並協調下一步的任務。聽起來蠻不錯,問題是在我們已有的流程中,每天每周已經有很多類似的會議在不停地同步項目的狀態了,工程師們有無數的機會向大大小小的經理們不斷地報告自己做了什麽,正在做什麽,還有哪些沒做。

在 IBM 的組織架構裡,有管人的人事經理 (People Mamager),有管事的項目經理 (Project Manager),若沒有那麽多的會議,這些經理們充沛的精力又往哪裡釋放呢?印象中 IBM 最吃緊的資源就是會議室。於是,工程師們不得不再把一天中最美好的時光獻給無聊的會議。一日之計在於晨,如果大家在頭腦最好使的時候思考一下當天要解決的問題,不是更有意義嗎?所以,任何流程在執行的過程中,必須保持足夠的靈活性。例如,我們要求提交到主乾分支的代碼必須經過審查和測試。而對於簡單地修改,比如只是更改一個字元串,審查和測試就是多此一舉,這種情況下,只要言語一聲,允許直接把代碼合並到主乾分支。

事事講流程,事事走流程,架屋疊床,常常是向官僚主義發出了邀請函。《後漢書》講到一個很精彩的故事,值得像我們這樣的初創公司借鑒。馬援的同鄉好友公孫述稱帝於蜀,馬援前往投奔,以為見到公孫述後,“既至當握手歡如平生”。沒想到,公孫述並不急於和馬援接談天下大勢,卻擺起了的帝王的臭排場。以盛大的儀式接見他,讓人肉麻的繁文縟節一一表演之後,“欲授援以封侯大將軍印”。可是馬援對公孫述這個沐猴而冠的豬腦殼的底細看得穿而又穿,“如偶人形,妄自尊大,井底蛙爾”。因而辭歸,專意於東方的劉秀。相比之下,馬援一到,劉秀馬上引見於宣德殿,簡易若是。促膝長談,“自夕達旦,開心見誠,無所隱伏,闊達多大節”。在那個“非獨君擇臣,臣亦擇君”的亂世,馬援追隨光武,成就了大功。有志於天下者,矢石交攻之際,千槍萬刃之中,匹馬縱橫,豈有閑心汲汲於縟節耶!

初創公司的處境本就艱辛,程序是一行代碼一行代碼寫出來的,質量是一個用例一個用例測出來的。把好的產品乾出來,或許能夠勉強保持一線生機的希望。說到底,這一切取決於工程師的素質。優秀的工程師一將難求,拿一些不合時宜的流程約束他,羈縻他,限制他,耐煩他,折騰他,非所以謀生存與發展而重人才與技術也。

見怪不怪,有些喜歡生活在安樂窩 (comfort zone) 中的平庸的工程師仿佛得了流程病。言必稱流程,拿流程當作不思進取的擋箭牌。事情弄壞了,流程變成了推諉搪塞的口實。完全不知道責任是什麽,油瓶倒了都不會去扶,為什麽要扶呢?流程裡面並沒有規定我扶啊。凡事都要聽流程,何必要到辦公室上班呢?被送到幼兒園按照老師的指令做個乖寶寶不是更好嗎?

作者簡介

賈彥民,目前就職於 PICA8。本科與研究生就讀於重慶大學,2007 年獲中國科學院軟體研究所計算機軟體與理論博士學位。愛讀書,喜歡爬山與攝影(歷史、文學、數學)。

技術管理不同於普通管理,那多出的“技術”二字既是優勢,卻也是困擾。在技術轉向管理的“旅途”中,除了以上列舉的部分問題,你可能還會遇到大大小小的苦惱。

添加請備注「企業账號」

點個在看少個 bug

獲得更多的PTT最新消息
按讚加入粉絲團