這其實是《0bug — C/C++商用工程之道》一書的讀者朋友發給我的信件,這位讀者顯然在公司裡面已經是一個技術骨幹了,擁有較強的實戰經驗,也開始帶新人了,然後,在新人的工作上,他遇到了一點問題,就來向我諮詢。
我本來考慮,直接回復他算了,不過想了一下,還是公開回複比較好,因為我感覺到,他的問題比較有代表性。其實帶出了一個很敏感的話題,就是“新人入職以後,該怎麼做?”
好,我們先看看原文,再來分析。還是那句話,一家之言,歡迎拍磚哈。
原文:
在chinapub上看了樣章,雖然沒有程式碼大全經典(笑,絕對不是砸場子來的),但是我會買一本推薦給新入職的同學閱讀,畢竟CC的厚度就夠嚇人了。
除開前來表示敬仰外,也問點非技術性的問題。
俺是一業內菜鳥,入行一年有餘。目前供職的公司開闢了新領域,而老業務也要維持嘛,於是就招了不少人,於是我就成為這一批入職最早的一位,主要工作是維護老產品。
經過大半年的摧殘,俺終於明白了其實寫程式是在和人打交道的道理,也能夠提出一些意見影響技術主管的決定,雖然經常被他說俺的設計太過書生氣 =。=,比如俺一直宣揚應該儘可能的使用編譯器來約束程式碼的使用者(或程式碼本身的特性),只要是你不期望的(不喜歡的)呼叫方式(或某種特性)就讓他編譯不過是最好的,防止程式碼汙染。
近期不時去關注下新老同學手上的程式碼,考慮怎麼去做重構,怎麼去整理出開發庫。
不看不要緊,一看就鬱悶了。俺是個懶人,一看見有人可能下一個錯誤的決定,並且出了錯還可能拉上我去耗時間就覺得焦慮。一焦慮就會變得很殘暴 T_T
舉個典型的代表,入職大半年的小A,現在手上拿著主要模組之一(該模組從來都沒正式交付給我維護,但該模組產生過的嚴重bug,俺都參與過除錯)。
在新平臺下做測試,發現因為平臺差異,在某handle被關閉後的一些看似無關的呼叫會失敗。於是乎,小A就在這些呼叫前又開啟這個handle,寫了100行左右的程式碼,並引入了一個不算嚴重的bug。
發現bug後,建議他再看看(再測試下),經過1天,bug依舊。於是就指出了bug,然後建議我們是否不應該直接就這樣暴力的把bug解決了,而是先去考慮下,這個時侯某Handle被關閉是設計如此?還是一個隱含的bug?以及觸發這個bug的原理是否徹底搞清楚了。
過了兩天,再一看,還是這麼修改的,再一交流,小A表示bug已經解決了,沒問題,但bug發生的機理依然不能表達清楚(我也不知道小A是否真的搞懂了)。而事實上這個問題是一個隱含的bug,那些呼叫就應該在handle關閉前執行。
這個時候如果是老肖會怎麼做?
我的做法是直接找到技術主管提出自己的看法,然後請來資深的前代維護者,花了5分鐘確認了我的看法,刪除掉那100行程式碼,調整了關閉handle的時機。
事後想起來,我的處理方式是否太粗暴了。是否應該先嚐試用更直接的方式與小A溝通,而不僅僅是建議。但是我又感覺對於小A如果建議了,都依然沒有改觀的話,更直接的方式也不一定有效。與其讓自己焦慮,還不如快刀斬亂麻,要是我也忙其他的東西忘記過問了,豈不是又多一顆定時炸彈。
自省後覺得狀態不太對啊,想聽聽老肖的看法。
我的回答:
這位朋友你好,你的信件我仔細看了,也想了差不多一週左右,確實有點難以回答,我只能儘量。如果答得不好,還請見諒。
我們們還是先挑點簡單的先說吧,有個鋪墊,容我也喘口氣,呵呵。
“比如俺一直宣揚應該儘可能的使用編譯器來約束程式碼的使用者(或程式碼本身的特性),只要是你不期望的(不喜歡的)呼叫方式(或某種特性)就讓他編譯不過是最好的,防止程式碼汙染。”
這句話我明確說,我認為你對,應該發揚。我們知道,其實真正做0bug的程式,有點難,主要原因我認為,我們程式設計師是人,是人就有可能犯錯誤,有思維慣性啊,思維誤區啊,或者根本就是考慮問題不全面,設計時漏想了了一塊,這都可能導致bug。
其實有開發經驗的朋友應該都知道,bug其實不難,只要發現了bug,程式設計師總有辦法修訂,難的是bug的查詢和定位,我們無數次因bug導致的加班,其實更多地是在找bug,而不是改bug。
我在《0bug — C/C++商用工程之道》一書中,提出無錯化程式設計方法,其實主要就是針對這個問題在解決。首先我的基調就是,不相信人,包括我自己,因為我也是人,呵呵。因此,我在書中強調程式設計規範,強調程式易讀性,強調嚴禁變數轉義和一語多義,不但從思想上預防bug,更多的我是在講方法和習慣。即很多實用,用一個規範,用一個習慣解決整整一個方面的bug。
比如說判斷語句,常量寫左邊,if(i==0),如果寫成if(i=0)表示式恆定為假,就錯了,但是,如果我們養成常量寫左邊的習慣,永遠一寫就是if(0==i),當此時我們少寫一個=號時,編譯器立即報錯,因為常量在語法上不可被賦值。類似的例子還有很多,我的記憶體池序號產生器制,就是利用程式自己來統計指標變數的使用情況,一旦發現未釋放指標,立即報警,預防記憶體洩漏。
大家注意沒有,所有這些規範,方法和習慣,我都是想盡辦法,爭取向C的語法規約,或者說編譯器的報錯邊界在靠攏,力圖使錯誤在編譯的第一時間,在程式第一次被執行,就被報出來,並順便幫助程式設計師定位到錯誤處,請問,這種bug還可怕嗎?
還有,我在書中強調匈牙利命名法,就是喜歡它有個嚴格的約定,當把一個成員變數改為全域性變數時,根據命名要求,變數必須要改名,由m_xxx改成g_xxx,這一改,編譯器會找出一堆呼叫錯誤,那麼,是不是在幫助我們,仔細檢查每一個呼叫點,讓我們來判斷,這次改變變數的作用域,是不是合理,以及是不是有隱患。
因此,我這裡明確提示一下年輕的朋友們,請儘量利用好編譯器,它找bug比你準確得多。好的程式,不是一寫出來就沒有bug,而是寫出來第一次編譯一大堆bug,然後我們改,當什麼時候改到編譯器不報錯,我們的程式就徹底沒有bug,那麼,我認為,這就是最理想的0bug程式,同時,這個程式設計師,可以稱之為0bug程式設計師。
好,現在我們來討論第二個問題。
第二個問題,我歸納一下,你看了那位小A的程式碼裡面有明顯的bug,於是有點焦急,溝通效果不好,小A雖然改了,但是沒有改到根子上,bug依舊。這件事情,我直說啊,你做得不到位。
為什麼說你不說小A呢,原因很簡單,你比他資深。我們以前帶團隊,有個原則,同樣的錯誤,如果是團隊犯了,年輕的,剛入職的,不但不罵,還要安慰幾句,資深的就罵,特別是級別高的,越是狠人、牛人罵得越凶,因為這裡面有個原則,“資格=責任”。
比如說火車站候車室,一個人心臟病突發,大家都沒轍,只有一個人是醫生,但是他沒有出手,這個人最後死了。想想看,大家是罵所有人,還是罵那個醫生?肯定是醫生啦,因為他有這個治病的能力和資格,但是他不治,就是不負責任,其他人由於不懂,就沒有責任。
因此,這件事情上,雖然我不是很清楚你們公司的行政職務定位,但只要你比他早來一天,你就有責任。
當然,也不是說這件事情上你有多大的錯誤,但是,我個人建議,你的溝通方法需要改進一點,一般說來,我們做事有個原則,“重大問題,立即開會”。
要知道,在公司裡面,不管是哪個級別的員工,其實都有權利開會的,開會並不是很複雜的事情,不是說只有主管才能開會。哪怕一個才入職1天的小弟,發現問題,我教他們的方法就是,先找我,討論,一旦發現問題很嚴重,通常就是立即開會。我負責去請比我職務更高的主管,一起參與。
開會不是目的,目的是提醒所有人,我們有個問題,重要問題,如果不解決,會影響後續很多工作,因此,這是重要事件,請大家知曉。另外,我們要討論一下,該怎麼做,同時,還要對新員工做出表彰,因為他的這個發現,幫助我們預防了bug,節約了成本。
因此,我覺得你的第二個問題,其實就是一個會議的問題,你可以主動請求你的主管或經理,召開一次專題討論會,就這個問題的根源,解法,做個分析和結論,拿出正確的解決方案,再委託這個小A去實施即可。
正如你舉的例子,這個問題根源是小A沒有理解程式設計的原意,開啟了一個已經關閉的Handle,導致新的bug,那麼,開會時,自然大家可以分析清楚,這個Handle原來為什麼會被設計為關閉,來龍去脈如何,如果要再利用,該怎麼做,其實在會上只要攤開來一說,應該不難的,那麼,知道了來龍去脈,知道了原理,我想,小A的實施,應該不會再有bug了。
之所以採用開會形式,其實是有很多好處的。人都是要臉的,當一個人自己做事時,很容易忽視自己的bug,對自己有點放任自流,即使出現一點問題,也不會仔細思考,但是,當問題一旦暴露在大家面前時,人往往就會打起精神,負起責任來,認真對待,其實這也是幫助小A養成良好的職業操守。
當然,開會有開會的方法,我們曾經規定,兩個人以上在一起討論工作,就叫開會,我們不建議開長會,大會,不允許開無結果的會,每一次開會都要有結論,每一次結論都要有記錄,並且,納入工作日記管理,主管下面要查實施效果的。你能明白嗎?
嗯,我們再來談談第三個問題。
第三個就是你直接向我諮詢,你找主管的做法好不好?
我的回答是,也好也不好,好的是,你找主管,開始爭取團隊的支援,找來前代開發者,並解決了問題。從工作效果上,好。
但是,也有很不好的一面,你發現沒,在這中間,沒小A什麼事,那你想想,他會怎麼想?是不是很沒有面子?他會不會因此感到自卑,或者受到傷害,並因此而消沉,離職?
我們經常說新人離職率高,老闆就罵,現在的年輕人怎麼啦?養不家的豬,主管也跟著罵。其實有時候,反過來想,我們這些主管,自己有沒有責任?是不是我們很多時候沒做好,導致了不可挽回的結果?新人好不好,我的建議是,老闆可以罵,但是,主管最好別罵,因為往往會罵到自己頭上的。
我的建議,最好的做法,你和小A先開小會,討論一下這個設計有沒有潛在的bug,當你們能達成共識,再一起找主管,讓前代作者和小A交代,這個東東的原理是什麼,你和主管旁聽,在中間你適當參與討論,引導小A自己總結問題根源,以及解決方案,讓他自己說出來,大家評判他的解決方案是不是對,當最後他自己都能說對的時候,你認為這個問題的解決,還難嗎?
這樣的好處顯而易見,你們沒有責怪小A,更多的是針對他知識和經驗的不足,在幫他提高,提高到他自己擁有解決問題的實力,並且自己拿出解決方案,最終解決掉這個問題,你說,他是不是很有面子?
一個新人,到了新公司,主管悉心教導,不批評,只培訓,自己不斷提升,並且,能解決很多公司的關鍵問題,自己覺得自己逐漸成長為公司的重要人物和骨幹員工,請問,這個新人會沒事跑路嗎?
這裡提示一點管理方法,“上情不能下達,開會,下情不能上達,私下討論”。這也是我自己總結的一點管理經驗,你這個問題,既有上情不能下達問題,又有下情不能上達問題,建議可以參考我的這個原則,一般說來,你做到這一步,方方面面的顧慮就都考慮差不多了,最後,小A受表揚,你的評價也不會錯。
當然,在這期間,必要的溝通技巧必不可少,溝通技巧,可不是說話客氣就算完,是很多素質的綜合,包括換位思考,包括耐心傾聽,包括引導思維,等等,建議以後可以學習一點溝通方面的知識,會對你的工作很有幫助的。
嗯,從這個問題,我再引申第四個問題,就是站在小A的角度,該怎麼看待這件事。
這其實是換位思考了,我們說完了你這位資深員工,或者說主管朋友,那麼,我們來說說,作為新員工的小A,應該怎麼做,才能更加符合公司的需求。
我在《0 bug —- C/C++商用工程之道》裡面,其實這個問題多次涉及並講解,這裡我再多說一次。
在書中,我講過一個故事,就是以前一個團隊成員,獨立完成一個專案,但是顯然沒有做好,他做的演算法沒有和我們商量,或者是沒有重視我們開會時給他提示的重要演算法關鍵點,自己一個人悶著頭做,一個簡單的資料庫樹形目錄體系解析模組,他做了接近4個月。最後,我們全體同事的模組都完成了,單獨等他等了兩個月。
我沒有辦法,最後在專案deadline之前兩天,正式接手他的工作,我發現他把問題做得太複雜了,寫了整整15000行程式碼,中間繞來繞去,造成了無數的bug,最後無法交工,並不是程式沒有寫完,而是bug太多,無法穩定執行。
我沒有辦法,重構了他的程式碼,中間我引入了一個我發明的“工具類”方法,1200行程式碼,兩天做出來,一次過,0bug。他當時都驚呆了。最後,由於他表現不好,被公司請去喝茶,到另外的公司上班去了。
這個故事我記錄在《0 bug —- C/C++商用工程之道》工具類這一小節中,有興趣的讀者,可以看看。
那我們來看看他的問題是什麼?
這麼多年的程式實戰經驗,我發現新程式設計師入職場,往往會犯兩種錯誤:
1、不喜歡求助,新人並沒有把團隊視為自己的資源,更多的是想表現自己,因此遇到問題,喜歡自己鑽牛角尖,尤其是還有一點面子觀念,怕自己問很傻的問題被人笑話,結果呢,導致自己死K不出來,大家想幫忙幫不上,乾著急,最後事情還沒辦好。
這裡我建議各位同學,當你們第一次入職場的時候,擺正位置,你們就是新人,新人不懂,是正常的,有問題,自己想出瞭解法,可以主動找老員工或者主管談談,你不是去問他,你把你的解決方案說給他聽,讓他們參謀,是不是合理,這一般都沒有人會拒絕,而且,可以獲得很有效的幫助,這比你自己全部去想,效果好的多。
我們不建議新員工事事不動腦子,全部靠別人幫忙,但是,我們強調,新人最好在動腦子的前提下,請主管和資深工程師幫助自己點評一下,幫助自己查漏補缺,這是非常好的習慣,會幫大家少犯很多錯誤的。
2、喜歡玩技巧耍酷。這也是新員工喜歡犯的錯誤,很多新人入職,由於在公司沒有地位,急於想表現自己,這體現在開發中,特別喜歡玩一些比較精深的演算法,以顯示自己很牛,並試圖通過這些表現,讓大家重視,或者尊重自己。這也要不得。
我經常喜歡說一些新員工,“耍酷耍到自殘”,呵呵。敲程式碼,明明有方便的VS2008,不用,非要用vi,好像不用這個,就不能算Linux程式設計師。就看他打字的時候,兩個手像蝴蝶一樣在鍵盤上飛,花枝招展,煞是好看。結果最後一看,他產量最少,筆誤最多。
我寫了n個Linux伺服器了,到現在不用vi,我就是在VS2008裡面編輯,然後,VC編譯,執行,通過,ftp到Linux,make,執行,通過,就好了,VC的編輯環境很好用,我們敲程式碼,每個變數名,函式名,只輸入一次,這裡拷貝一下,那裡用點自動彈出,哪來的筆誤嘛。
這還好,僅僅是習慣問題,最多影響一點產量。有一些朋友更要不得,一個簡單的被動池演算法,又是動態記憶體分配,又是連結串列,又是樹,忙活了半天,最後出來,一堆的bug,好不容易改好bug,QA一測試,程式不可用,重構。原因很簡單,沒有考慮到記憶體碎片的影響,無法滿足7*24小時運營要求。
像我們老工程師呢,看看資料邊界,嗯,最多1024個單元,不多嘛,一個靜態陣列搞定,然後在陣列中做點重用邏輯,根據概率分析,效率不比動態分配的差,程式簡單得多,而且沒有bug,靜態陣列,更不可能有什麼記憶體碎片。完了收工。
大家覺得哪個好?
這些,都是我過去碰到的例項,我也share到《0 bug —- C/C++商用工程之道》一書中,很多時候,不要為了寫程式而寫程式,要聰明點。
我經常開會時勸小弟,“請你們用腦子寫程式,別用手寫程式”,大家能明白什麼意思嗎?
好了,總結一下吧。
目前很多朋友,不好找工作,主要原因是因為學校裡面的知識,不是很合用,企業的需求與我們的實力之間有落差。但這個問題其實在我看來,不難解決,目前有很多好的培訓班,也有很多優秀的培訓機構,我們只要潛心學習一段時間,掌握基本的企業開發技能不難的。
但是,我發現大家討論時,很少討論一個問題,那就是:“進去了以後怎麼辦?”
今天我將就這位朋友的問題,談談主管如何管理新人,也談談新人如何融入企業開發團隊,希望能幫到大家。
其實這些東東並不複雜,說穿了,因為不值幾個錢,但是,請大家關注,就這麼一點點思路,理念和方法的差異,有的人就能在新公司迅速定位,並不斷出成績,最後成長為公司的業務骨幹,獲得重用和高新,但有的人,就是沒有辦法獲得穩定的工作,最後變成跳蚤,到處亂跳,始終無法成就自己的事業。大家願意做哪一種?
其實我寫《0 bug —- C/C++商用工程之道》一書,很多時候我自己都在想,我講的重點是什麼,最開始定位的時候,我是程式設計師,我當然應該寫技術,但是寫到一半想法就有點變了,待書出來,面世,我發現其實我真正寫的,是怎麼做人和做事的原則。
我一直建議大家,程式碼不值錢,別被程式碼迷住了,要跳出程式碼看思想,就是因為我覺得,一個新人走入職場,技術上的問題真的不是什麼大問題,最大的問題,是怎麼找到正確的工作方法,少犯錯誤,爭取轉正和進步。我覺得這才是最重要的。
我可能由於水平有限,寫出來的書,這方面說了一點,但是沒有重點突出,表現上也不夠醒目,只有我這裡多發點帖子,請大家關注這個要點了。
歡迎大家以後就這個問題和我多討論,我希望能幫助儘可能多的朋友,獲得滿意的工作,並且能夠做好,成就自己的一番事業。