為什麼感覺國外的程序員更專業?

初入行,小菜鳥。現在還在小公司打怪升級。
編程學習過程中,一直有一種感覺,那就是國外的程序員比國內的碼農要更專業一些。
專業性不僅僅體現在code上面,也包括代碼一致性,文檔齊全度,注釋風格等等。
包括整個國家的編程學習環境,氛圍上。甚至包括對自己的稱謂上。國外應該沒有碼農,碼畜,大神,跪舔,程序猿對應的翻譯吧~呵呵~
瀏覽博客過程中也深感如此,很多老外程序員的博客都非常精緻,不僅僅是內容,整個博客的風格一看就是傾注了不少心血。
而國內的主流編程博客CSDN,博客園,品質也良莠不齊不等,能堅持更新的很少,大部分也是某個計算機專業的學生為了找工作隨便粘貼了一些東西,更談不上技術深度了。
曾經也想做好一個博客,但是堅持一段時間後發現,時間是個問題。平時白天在公司寫業務邏輯已經很累了,是在拿不出時間來經營一個博客。國外的專業程序員是怎麼平衡公司業務和自我提升的呢?
請問覺得國外程序員更專業是一種偏見嗎?
如果不是,那麼如何在國內這種大環境下做一個專業的程序員呢?


中國碼農不是不專業,而是「浮躁」,寫代碼從來不是職業,只是通往更高職位的階梯而已。
在中國任何一個角落,碼代碼的都會告訴你,35歲之後就會碼不動了,招聘廣告也會寫明,20~35歲,你35之前不從代碼轉管理,你死定了等等等等。聽我混互聯網行業的兄弟說,干過2年以上可以算得上高級程序員,5年以上就可以上到技術經理,再往上最好到30之前就爬到技術總監。說得彷彿人生必須在40歲之前完結一樣。包括我自己,前幾天和同事開完玩笑之後也鬱悶了好久,「現在的我可以輕鬆搞定3個畢業生的工作量,但是老闆覺得我2.5倍畢業生的工資還是高了。呵呵。。。」 剛剛有點專業的樣子就不得不脫離崗位了,怎麼破?

想換個行當,面試告訴你,你年紀大了,可塑性不行,我靠,我在這行混了10年了小到MCU大到伺服器,asp寫到django,C語言寫到PLSQL,從Qt玩到oracle form builder,做過消費品寫過erp,從將棋可以陪你聊到會計財務,來來來,咱倆嘮嘮,你覺得啥我學不會。

作為還有4年可用壽命的碼渣,到現在還沒脫離第一線工作,喜歡寫代碼的成就感,可惜天天被人教育一定要往上爬,做業務,別做技術。天天被人鄙視說是不求上進,麻辣隔壁的你們煩不煩?碼程序是我愛好,愛好!
到時候真沒人要開專車養家糊口,我一樣會在家裡折騰電腦的。就醬。


身邊有一個程序員,姑且叫他老 S 吧,英國人,在現在的公司工作10年,已經做到了 Director,每天仍舊奮戰在第一線,在故障跟蹤庫中,遇到疑難問題大家一籌莫展時,老S飄然而至,洋洋洒洒數段文字,點出問題所在,然後飄然而去;在QA 論壇中,老 S 的回答總是最詳盡和最易理解的;在代碼 Review 庫中,老 S 總是最為嚴格的給出很多代碼改進的建設性意見;老 S 編寫和維護著公司最核心的一個基礎代碼庫,同時還親自維護著3個最核心的模塊;老 S 的代碼,總是大家在尋找代碼參考時的首選;老 S 的手下還管理著30多號人,整天被騷擾請教各種技術問題,還要經常參加各種決策和討論。經常在感嘆老 S 的三頭六臂,用「專業」來形容老 S ,絕不為過。

曾經仔細思考過老 S 為何如此專業,總結出如下幾點:

追求極致。為啥在某些領域國外的業餘運動員水平比國內專業運動員水平還高(乒乓球除外),在國外的氛圍是,一旦興趣使然,就會不斷的練習,練習,練習~,直到無法再提高為止。國外的程序員也一樣,以興趣為導向,真正喜歡的東西,往往能玩到極致。

追求深度。國外的教育體系,前期注重廣度,後期注重深度,而廣度到深度的轉變,取決於個人的選擇和興趣,一旦確定專業方向,這裡的深度往往遠超乎想像。

追求展現和表達。從老 S 的身上,我就可以深切的感受到這一點,老 S 在代碼中的注釋,有時比專業文檔寫得還好,在QA 論壇中只是表達一下自己的觀點和見解,絕少看到老 S 寥寥數語, 往往都是三段論。個人感覺,國外教育體系培養的都是銷售,國內教育體系培養的都是工程師。通過培養銷售體系中出來的程序員,自然在表達上有得天獨厚的優勢,加上本身具有的深度理解和邏輯思維,在博客上能夠得到淋漓盡致的體現。

堅持再堅持。老 S 編寫的公司最核心的基礎代碼庫,第一個版本是2007年完成的,8年的時間,從代碼日誌上可以看到老 S 對這個基礎代碼庫不斷精益求精的進行打磨,根據標準和協議的變化不斷的演進。在這個過程中,老 S 的技術能力不斷的得到錘鍊和提升。

國外的大環境。在國外,程序員之間其實也是「文人相輕」的,一個程序員是否被其他程序員在內心中尊敬,和他以前寫過的代碼和項目直接相關,和他現在所在的位置關係不大。從職業發展上,某些資深的程序員,待遇會和VP 不相上下。正是因為有這些保證,老 S 身為Director,仍舊可以每天奮鬥在代碼的第一線;Google 的Sanjay Ghemawat和Jeff Dean,可以沒有任何管理頭銜,繼續在技術上探索,而且繼續被大家所崇拜。

所以說國外程序員更專業其實並不是一種偏見,而是事實。

那麼如何在國內這種大環境下做一個專業的程序員呢?

在回答這個問題之前,先談談國內的大環境,國內的程序員,代碼寫的好的,往往技而優則管,從此陷入管理的日常性事務,在專業上就無法繼續精進了。曾經思考過這個問題,個人總結原因如下:國內的開發節奏,需要大量的可以加班和熬夜的程序員不斷的滾動迭代開發,通過快速的迭代,來彌補軟體本身質量上的缺憾,最終輸出滿足用戶各種需求的產品。在這種開發節奏中,「專業」和「資深」的程序員顯得非常的不合時宜:往往有家庭的牽絆,無法大量的加班;輸出的軟體雖然質量有保證,但是並不一定能滿足項目激進的進度要求;一般薪水還較高,不如招畢業生新手培養來的划算。而新手需要培養和指導,「專業」和「資深」的管理者變得非常緊缺,其中很重要的一個來源,就是可憐的「專業」而「資深」的程序員。國內有很多公司有所謂的管理和技術雙線,但是往往管理線上所能得到的資源和收益,要遠遠大於技術線。逼迫大部分的優秀程序員,不得不或者心甘情願地走上管理的崗位,否則會落得「屌絲程序猿,死時爬鍵盤」。

那這個問題是否有答案呢?其實答案就是兩個字:堅持,包括技術上和時間上的堅持。在現實的條件下,不妨去做管理,但是切不可放棄對技術本身的理解和日常的編碼,這是技術上的堅持。堅持到有一天,程序猿變成程序員,在薪資上真正的被尊重;在開發節奏上,再也無法使用大量廉價勞動力滾動開發,「專業」的程序員價值被真正的認可和尊重;國內的程序員群體隨著歲月也經歷50,60,70,80歲;全社會對程序員這個職業有了更加深刻的認識,看到白髮蒼蒼還在一線寫代碼的程序員時,沒有人再認為她或他是 Loser,而是心生敬意。堅持到這一天,才能真真正正的安心做一個專業的程序員,這是時間上的堅持。

最後記起了以前讀到的一個故事,真假不太確定:騰訊廣研所一次在探討一個微信需求的具體實現方案,大家爭執不下,總覺得太難於實現,這時參與討論的張小龍踱回辦公室,許久後出來,手裡拿著代碼,輕描淡寫的說:大家看看這樣實現如何?方案遂定~。如果故事屬實,我猜想張小龍的心底一定是有這份堅持的;如果故事不屬實,我也猜想張小龍的心底一定是有這份堅持的。


有一個因素,前面的答案都沒說到。就是中國程序員的個人品牌意識還不算太強。

幾年前我在做 windows 開發的時候,常常要藉助兩個網站,一個是外國的 codeproject,一個是中國的 csdn。csdn 當時口碑就不算好,大家都說太水。其實在 csdn 上也常能找到乾貨,很多文章並不缺乏技術含量,但是整體觀感上,卻要差 cp 很多。造成這種差距的,主要是細節,比如行文語句不通順,文章太簡略沒解釋清楚問題,輕率地轉載,錯別字,張貼的代碼編譯通不過,demo 代碼不規範,排版不友好等等。

我認為這就是一種意識上的差距,cp 上的作者,往往是以自媒體(儘管那時還沒這個詞)或者自我品牌建設的定位來運營博客的,而當時絕大部分 csdn 用戶,把博客當成了備忘錄,寫的內容根本不是給外人看的,更沒有想過通過博客給自己加碼(這其實就是輪子哥常說的 promote)。

這種理念的差距反應到工作中、代碼上,就是很多程序員寫代碼是給機器看的,而不是給同事和領導看的。這其實是一種短視,同事可能變成領導,領導可能會跳槽,而你展現給他們的代碼,很有可能意味著新的工作機會。

值得慶幸的是,隨著互聯網公司招聘看博客和 github 的風潮興起,這種情況正在改變。現在開源代碼和技術文章,幾乎已經成了中高級程序員簡歷的一部分,知乎和掘金上的國產技術文,越來越有「專業」味道了。為了能吸引讀者以及彰顯實力,大家開始普遍思考「寫有營養的東西」,而不是「先記下來別回頭忘了」,那種打開一個技術網站滿屏初學者筆記的情況,好了不少(儘管仍然存在)。

我相信隨著個人品牌意識的普及,中國程序員的專業性,至少看上去的專業性,還能大幅提高一個檔次。畢竟中國程序員質量並不算差。這一點有過統計研究,但是相關地址我找不到了。個人觀感來說,要比基礎的,比如印度人吧,印度的軟體外包算是行業標杆,我跟印度外包公司的研發打過交道,我並沒感覺的同級別的印度外包程序員比中國外包(就是軟通、文思等)程序員專業在哪裡。比時髦的,現在國內的開源項目也不少了,只要是搞出點名堂的項目,質量和規範性和國外項目也沒有多大區別。

ps:
但是在行業軟體領域,依我所見,從產品質量,到代碼質量,再到人才質量,真的和國外差距很大。

打個比方,如果你有機會去觀察一下國外的行業軟體,你會覺得它們和你平時用的 office、photoshop,是差不多的東西,但是同行業的國產軟體,具體的差距就不說了,你常常能感覺到,它們和你平時用的軟體不像同一種東西。

這說的是產品,程序員也是這樣的感覺。我之前做安防的時候,接觸過 milestone(後來被佳能收購了)、genetech、sony,以及幾個歐洲知名廠商的研發。這些人水平和 title 有高有低,但總體上,他們和你在網上看到的互聯網程序員沒有什麼不同,不管是 email 還是代碼,還是面對面交流,都顯示出他們是毫無疑問的專業 coder。而同行業國內公司的研發……總感覺哪兒不對勁,不像程序員……倒不是說水平一定不高,只是常會發生一些諸如發 email 使用口語,私人信箱傳代碼,文檔用 word 寫,安裝包用 rar 壓縮,安裝包里有靜態庫,術語聽不懂,目錄寫死在代碼里,變數名拼寫錯誤,定製版程序出問題卻找不到符號文件之類的事情。

大約就是那種「不專業」的感覺。


因為寫程序好的都變成外國人了


矽谷剛入行小兵一枚,從實習和觀察來看,可能以下幾個方面能說明點問題

1. 教育方式
讀cs系,這裡更注重的是實戰教育。舉例,在上ditributed system時候 要自己看懂paper並且實現一個簡單的mapreduce + gfs框架. 全程過中 教授會code review,會和你討論你的設計方案,會規範你的代碼風格和構架方式。會要求你自己寫test,會組建seminar讓全系其他年紀的人來聽你的project 整個過程模擬了工作中需要的各種技能,結果你發現真正工作遇到的問題並沒有學校的難(當然只是對entry level來說,仍在努力練級中)

2. 分享精神和行業氛圍
在一個以充滿技術氛圍的地方,周圍高手雲集 又謙遜近人 整個矽谷充滿導師文化。這種氛圍下,一個人的姿態不自覺的就會謙遜,把自己放得很低,周圍人不是把技術當成職業 而是一種信仰 一種熱愛 一項魔術。這種熱忱回不自覺的感染到新進碼農。在懷著熱忱為社會創建更多影響力的使命的驅動下,有一種內在力量 會不斷把你推向完美!

但是周圍接觸到的華人工程師也是非常厲害的!中國的人口基數造就了獨一無二的高負荷大型分散式的網站,用戶基數在全世界範圍都是獨一無二的。

眼見為心中所想,無需觀測外在,只需專註於讓自己和自己接觸到的人不斷提升!


為什麼你覺得國外的書質量高?因為質量差的書是不會引進到國內來的。你覺得老外牛逼,不過是因為你見到的外國人太少代碼太少博客太少,中國人良莠不齊你每天都看在眼裡,而老外你只見得到夠亮的那些。


我想優雅敲代碼,沒事重構下讓代碼更優雅
結果呢
2星期一小版3星期一大版注重發版效率輕視程序穩定
加班就不提了
閑下來就想歇歇


題主說的事情都是不存在的,正確的解答是,國內的公司不鼓勵程序員追求質量,所以你在這個地方生存當然也只能這樣了。如果你跑到外面去,你會發現無論是中國人還是外國人,都變得更有追求了。

最近感覺很明顯,跟一個Excel的人談合作,要弄一個事情。儘管是在讓他們migrate到我做的新的開發工具上,人家不會一股腦把所有的工作都推給我,只要是他們改對Excel的長遠未來會更好,他們就改。想起之前跟在阿三的阿三談事情的時候,簡直就是天跟地的區別(逃


最底層原因是不注重知識產權。這有兩方面,一個是社會不關心公司產品的產權,另一個是老闆不關心員工的知識產權。

----------------------

社會嘛,這麼說吧,扔在國外企鵝這種網吧公司早就被告到死了……現在好了,國產大旗
360這種流氓公司扔在國外早就被法院起訴死了……現在也是創業者的楷模

我們就講究說原始積累時候要心狠手辣,可是就沒有人意識到十年磨一劍的重要性。當然磨劍的大部分在磨的過程中就被社會碾死了,這是另一方面。

這樣的社會大環境帶來的結果就是,對於公司而言,「能用」比起「好」重要的太多太多
換言之,用10個廉價勞力,比起用1個頂50個的高手,更容易進行風險控制
所以這樣導致的生產模式就是,一旦你不再是廉價勞力,那麼使用你的風險就會大幅上升,於是公司就不想用了

---------------------

當然另一方面求職者本身的心態也是大問題。國內只看到了矽谷的創業潮(而且是瘋狂的宣傳著矽谷的創業潮),卻沒有看見矽谷和矽谷以外,幾十倍乃至與幾百倍的技術高手只是在心甘情願的做一份朝九晚五的工作。他們可能技術都非常非常非常牛逼(我個人見過的不要太多),但是他們並不想創業。

但是中國你不創業就是沒上進心,而且好像你手下不管著多少個人你就是個廢物一樣。沒有人關心你的技術如何。
可是大家就忽略了,本質上,人本來就分為喜歡管理他人,和不喜歡管理他人的兩類人。比如我就是一個天生極端討厭管理人的人。我只喜歡處理具體事務,而且說真的我根本就不care其他人在幹什麼,或者其他人怎麼看我。
但我這樣的人扔在國內就是個完全沒有上進心的failure。可是在國外就不是。

我相信我不是唯一這樣的人。可是正如「30歲不結婚的女人就死定了」一樣,「35歲還做技術不轉管理的男人就完蛋了」也成為了社會的共識。

-------------------

結果就是,老闆不想用技術好的人,因為他看不到技術好帶來的效益,而只看到了技術好帶來的不好管控。

程序員則是因此分化,一類因此失去研究技術的動力,於是就等著靠人事能力和業務能力升職去做純管理;另一類則是眼界奇高,就想著技術牛逼了去做個CXO,結果話里話外都體現出一種天大地大老子最大的傲氣,讓人不敢用。

結果就是踏實搞技術的那一小部分人死球。

-------------------

還有一個因素就是,國內90%以上的大學本科計算機教育簡直像屎一樣。這是致命的,因為走程序員這條路的發展如何,90%取決於你本科學的怎麼樣。

我們學校(在加拿大)計算機專業本科,每年錄取200人,但能畢業出來不超過50人。剩下的要不然轉專業要不然退學了。據我所知其他學校類似這個比例。
我們大二講編譯原理和大三講操作系統時候,學生都必須親手寫編譯器和微型操作系統。然後沒有標準答案,只有測試。測試過了滿分,不過零分。當然還有建立在詞法和語法分析基礎上的反作弊軟體——抄襲超過5行就能抓住,抓住本課直接零分,兩次抓住直接勸退,沒有商量。最後教授沒有畢業率要求卡著,他不開心了把你們全體掛科也無所謂,沒人管他。

所以這樣學出來,你對各種編程語言的掌握和學習能力就不是國內一般學校比得了的。
然後基礎的差別會讓你以後的學習速度出現決定性的差別。更何況很多人是幹了多少年見多識廣的人。

------------------

幾個因素加在一起,國內的大環境短期內是看不到翻身的可能的。
當然,我同樣也遇到過許多打破了這些所謂「常理」的那些少數精英。那些人可能會嘲笑我說的這些都是狗屁,我尊重他們的看法,而且我也同意這是狗屁。
但是對於我遇到的大多數人而言,這些都沒錯。

如果你問一個人他為什麼不去改變,得到的回答九成都會是「哎,大環境如此,沒辦法,你不懂」
所以不懂的就都出國了
然後國外就比國內技術水平強了
就這樣

-----------------

EDIT:關於國內怎麼變成更專業的程序員
這個我只能從我在國內認識的一些比較厲害的人身上來發掘共性,畢竟大環境這個問題不好說

  1. 英語要學好,一定要學好。這個是最最關鍵的東西。學好英語你可以直接上StackOverflow和各種國外博客,可以直接和人交流/學習所謂「第一手」的東西,而不是抱著CSDN上被「大牛」們咀嚼消化過的內容來學。
  2. 如果還在大學,離散數學相關的東西一定要非常認真的學。然後編譯原理和操作系統儘可能的搞明白。搞不明白的話,能把C的指針徹底搞明白也行。方法就是多寫,多試,多問,多討論。
  3. 一定要有對任何技術細節都打破沙鍋問到底的精神。如果遇到大牛(或者不用大牛,只要是個你認為比你強的人就行)寫的程序中某個細節不明白,那一定要儘可能搞明白,無論這個地方看起來多小。不要怕丟面子也不要怕別人嫌你煩(當然你要講究方法,而且要機靈點)。這種東西只能靠平時的積累。而且這是唯一能提高你debug能力的辦法。除此之外沒什麼捷徑。
  4. 多和人交流,相互促進。既然你已經進入編程行業了,那相信你找到一個喜歡編程而且喜歡討論的人應該不難。那麼你每次學到新東西的時候不妨找這(幾)個人一起討論。每個人知道的東西都不一樣,討論多了也許就會碰撞出你想像不到的火花。
  5. 除了程序以外,儘可能多去了解你所在行業的業務流程。大多數情況下,程序經常改來改去很大程度上是因為對用戶需求分析的不夠明確。如果在你動手寫程序之前就能指出需求不完善的地方,那麼有可能PM拿回去確認後你就不用寫了,當然也就更不用改了。
  6. 敢於提意見,但是提之前盡量站在他人角度思考,同時多聽別人從其他角度提出的意見。比如上邊說的,PM給的需求如果不合理,一定要儘早指出。但是指出的方式要和對方關心的方式有關——比如對PM,你可以說「做這個功能需要很多天,而且有很大的不確定性。如果改的話工作量也很大,這樣的話很可能會導致你要求我們做的其他功能做不完」,等等。要用對方能理解的角度解釋。或者比如你可以說「這個功能現在我不確定能不能做出來,你能不能給我一天時間做個原型驗證一下,如果一天後技術不可行那我們趕緊想別的辦法」之類。總之,管理者角度而言,如果你做不出來,他們希望越早知道越好,最好是你做之前就知道。
  7. 具體技術方面,一定要掌握所有測試相關的知識。特別是如果學習一個新語言的話,爭取儘快掌握其中的一個做單元測試的框架,然後儘早給你開發的所有主要功能全部寫出單元測試。要知道問題發現的越早,修復的越快。同一個問題在單元測試發現,和在客戶手裡發現,造成的問題完全不是一個數量級,即便問題完全一樣。
  8. 上邊那些都做好,有餘力的時候,爭取多看看程序的新發展方向,和新興的技術。和大多數其他人的觀點不同,我個人覺得這條是這些裡邊最不重要的。原因是人要先站穩了才能跳,先會走再學跑。首先你要有一門掌握的非常過硬的語言,然後才有必要學新的。樣樣通樣樣松的人只能做管理(笑),但管理一般要不然是樣樣通樣樣精的巨牛,要不然是空降的親戚。你能跟哪邊比呢(笑)。

以上


你不過把自己不努力學習的因素歸於國內大環境不好罷了。

來份日本、美國的例子,是豐田車的渣代碼殺人事件。

【年度巨獻】從外行的視角嘗試講解為什麼這回豐田栽了【全文完】【v1.01】
【第一部分】背景簡介

前幾年鬧得沸沸揚揚的豐田剎不住事件最近又有新進展。十月底俄克拉荷馬的一次庭審,2007年一輛2005年凱美瑞暴沖(Unintended Acceleration,UA)致一死一傷事件中豐田被判有責。引起廣泛關注的是庭審中主要證人Michael Barr的證詞讓陪審團同意豐田的動力系統軟體存在巨大漏洞可能導致此類事件。這是豐田在同類事件中第一次被判有責。庭審過后豐田馬上同意支付300萬美元進入調解程序。

出於好奇,我漫不經心地下載了Barr的286頁證詞,卻一下子被吸引住了。幾天內讀完,算是對這次事件進行了一次深入了解。下面就從外行角度總結一下這份證詞並嘗試以更簡單的語言解釋裡面提到的暴沖原因以及豐田犯下的錯誤。

Barr的證詞下載自他的個人博客Barr Code,但現在該文已經被刪除。見2樓。

Michael Barr是誰?他是一位擁有20年以上行業經驗的嵌入式系統工程師。在十八個月中,有12位嵌入式系統專家,包Barr,受原告訴訟團所託,被關在馬里蘭州一間高度保安的房間內對豐田動力控制系統軟體(主要是2005年的凱美瑞)源代碼進行深度審查。這房間沒有英特網,沒有手機信號,他們進出不能攜帶任何紙張、記錄甚至皮帶。最後的調查結果被寫入一份800頁,13章的詳細報告。而鑒於保密協議,調查內容一直沒有公布,直至俄克拉荷馬這次庭審才首度部分公開(報告本身似乎還沒公開)。

回到正題。豐田的軟體有沒有缺陷?根據Barr的調查,答案是有。這其實是廢話,任何軟體都會有缺陷,關鍵在於是什麼樣的缺陷。豐田的軟體缺陷分為三類:

  • 非常業餘的結構設計。
    軟體設計的基本要求是模塊盡量簡單化,因為這樣可以一來更易於閱讀二來更易於維護。但豐田的工程師顯然沒有遵循這原則。Barr使用一種工具自動根據代碼的可能分支數量評估函數的複雜度,結果是豐田的軟體中至少有67條函數複雜度超過50,意味著運行這個函數可能出現超過50種不同的執行結果,屬於「非可測」級別。因為為了測試這50個不同的結果,必須準備至少50條不同的測試用例以及相應的文檔,在生產環境中一般是不現實的。作為比較,Barr表示他自己的公司嚴格執行的其中一條規定就是任何代碼複雜度不能超過30,否則不合格。而在這67條函數中還有12條複雜度超過100,達到「非可維護」級別,意味著一旦發現缺陷(Bug)也無法修復,因為實在太複雜,修復缺陷的過程中會產生新的缺陷。其中最複雜的一條函數有超過1300行代碼,146個可能執行路徑——正好用於根據各感測器數值計算節氣門開關角度。
    如果你不知道什麼是節氣門,那麼這裡我稍微解釋一下。為了讓內燃機運行,有三大要素:燃油、空氣和點火時機。空氣和燃油的混合物進入氣缸,被火花塞在正確的時間點燃推動活塞並最終推動曲軸和車輪前進。在電噴技術發明以後直到2002年以前,三大要素的燃油和點火時間是由電子設備控制,節氣門機械連接加速踏板,由司機直接控制。節氣門大致是一個連接加速踏板的「空氣龍頭」——踩下去越多,「龍頭」打開得越大,允許越多的空氣進入發動機輸出更大的動力。2002年以後,豐田引入的「電子油門」讓電子系統掌管了最後一個要素:空氣。加速踏板不再機械連接節氣門,而是連接一些感測器,由行車電腦將這些感測器數值計算成節氣門開啟角度再由馬達控制節氣門。我們稍後會再討論節氣門開合。
    極複雜的代碼帶來的是極複雜的功能。下面說一下被稱為「廚房洗滌盆」的Task X。這裡先解釋一下,豐田的軟體系統和很多別的軟體系統一樣,都是由一個統領程序(稱之為「操作系統」)和若干小程序(稱之為Task)組成。就好比電腦上跑的Windows是統領全局的操作系統,網路瀏覽器和記事本是跑在操作系統上的小程序。豐田的系統里每個Task都有自己的名字,但這些名字非常敏感,敏感到每次被提及的時候律師都要求法庭內的沒有閱讀代碼許可權的人全部清場。為了減少清場次數,Barr將這個最重要的小程序稱為Task X。這個Task X有多重要呢?跟廚房裡的洗滌盆一樣重要。它負責非常多的事情,包括計算節氣門開啟角度、速度監測和保持、定速巡航監測等等。Task X的不正常運行被認為是暴沖事件的元兇。稍後會再繼續討論Task X。
    還有一些別的匪夷所思的發現。比如豐田的軟體包含了超過一萬一千個全局變數。如果你不知道什麼是全局變數,那麼只需要知道軟體設計的一般原則是要盡量少使用全局變數,因為有可能帶來無法預測的結果。這裡的「少」的意思是「盡量接近零」,絕對不會是一萬一千個。
  • 不符合軟體開發規範。
    如同很多行業一樣,汽車行業也有自己的規範。更具體一點,由於汽車的危險性質,汽車控制系統被劃分為「安全關鍵性系統(Safety Critical System)」——說白了就是安全性非常重要,弄不好會死人的。為了達到這一特殊要求,汽車相關軟體開發人員定期舉行會議討論並發布編程規範,稱為MISRA C。該規範的2004年版的感謝列表裡還能看到豐田員工的名字,至少讓外界認為豐田確實也在遵循這些規範。
    真的嗎?根據源代碼來看,答案是否定的。對此之前的NASA報告也有所提及,豐田辯稱他們遵循的不是行業規範,而是豐田內部編程規範。這一規範與行業規範的吻合程度達到50%。但是Barr認為根據他的調查,兩個規範之間吻合度小於10%,甚至有若干規範條目相互衝突。後來發現豐田的代碼甚至沒有遵循豐田內部規範,當然比起別的問題這個已經無關緊要了。
    MISRA C擁有超過100條規範,NASA的調查只使用了到其中35條進行校對,發現超過7000處違規代碼。Barr使用全部條目,對照結果是豐田的程序擁有超過80000處違規代碼。
    這些數字說明了什麼?根據統計,違規數量可以用於預測代碼中暗藏的缺陷(Bug)數量。在之前提到的汽車相關軟體開發人員會議中,有人就這一主題發表過專題演講,提出每30處違規代碼可能包含一個重大缺陷和十個輕微缺陷。諷刺的是這人是豐田員工。
    特別需要指出MISRA C其中一個規則的內容是不得使用遞歸。
    如果你不知道什麼是遞歸,那麼這裡我稍微解釋一下。遞歸是一種計算方法。但一般計算方法要麼是自己算,要麼詢問別的計算模塊索要結果。而遞歸則是通過問一層層問自己的方法完成計算。好處是代碼簡單,壞處是計算層數不固定。可能會2層就出結果了,也可能會是10000層,在設計程序的時候無從得知。
    軟體計算需要消耗存儲器。越繁瑣、越長的計算自然需要佔用越多的存儲器。遞歸的問題在於其嵌套層數無法預測,從而導致可能消耗的存儲器容量無法控制。稍後會再討論存儲器。
  • 對關鍵變數缺乏保護。
    什麼是變數?變數就是存在一段存儲器的0和1的集合。這些變數既可以是一些函數的處理結果,也可以是另一些函數的處理原材料。比方說前面提到有一條程序專門計算節氣門開合角度,比如說是20度,這個20就是一個變數,存在存儲器的一個指定位置。另一個程序專門負責開合節氣門,它知道去那個指定位置讀取這個20,然後把節氣門開啟20度。
    什麼是保護?嵌入式系統,或者任何系統,都會在一定條件下發生硬體或者軟體錯誤。客觀上這是無法避免的。而且汽車作為一個時常在震動、發熱、位移的系統,它的內部環境不能說不惡劣,發生硬體錯誤的可能性甚至更高。什麼樣的硬體錯誤呢?別忘了變數都是0和1的組合,這些0和1由存儲器上的高低電平代表。由於某些不可抗原因,一個電平從高變成低,或者反過來,那麼這個變數就被更改了。這被稱為「位反轉(Bit Flip)」。為了對抗這樣的事情發生,需要對變數進行保護。保護的方法一般是鏡像法。簡單來說就是在兩個不同的地方寫入同一個變數,讀取的時候兩邊都讀,比較是不是一致。如果不一致,那麼可以得知這個變數已經不可靠,需要進行容錯處理。
    豐田的程序總體上對其上萬個變數進行了有效保護,但問題出在操作系統上。前面提到豐田的軟體本質上分為操作系統和Task。Task是由豐田自己開發,但是操作系統則是由晶元供應商提供,固化在晶元里的。豐田在這裡的過失是沒有對供應商提供的代碼進行深度審核,拿到什麼用什麼。
    另一個保護措施是錯誤校驗碼(Error Detective and Correction Codes,EDAC)。這是一個硬體層面的數據保護措施。簡而言之就是給內存中每一個位元組(8比特)後面物理地增加幾比特校驗碼。這樣萬一變數出錯了,可以通過校驗碼得知,甚至可以通過校驗碼修復一些輕微錯誤。這個措施十分簡單有效,但是在2005年款凱美瑞的系統中完全沒有使用,豐田卻告訴NASA他們用了。而在2008年款凱美瑞中使用了3比特長的EDAC。Barr認為是為了節省成本,否則應該使用5比特長。
    還有值得一提的是,汽車相關的軟體行業有那麼幾家操作系統供應商,早已形成了一套成熟標準稱為OSEK。各供應商開發的符合OSEK認證的操作系統至少都能達到一定的質量。但豐田選用的操作系統卻沒有通過認證,讓人不解。

現在我們知道豐田在編寫軟體的時候至少有三種缺陷。那麼重點問題:豐田的這些軟體缺陷是否會導致車輛暴沖?根據Barr的調查,答案是有可能。暴沖的起因需要結合上述三種缺陷來說明。

汽車正常運行需要倚靠若干程序(這裡叫Task)的同時運作。Task有很多,CPU只有一塊,在任何時刻只能處理一個Task,怎麼辦呢?這需要操作系統的統籌規劃,合理分配CPU的任務,讓每個Task都能按時執行。如果出現某種意外,讓某個Task突然不執行了,那麼就稱為這個Task「死亡」。Task死了,自然不能執行它的任務。根據Barr的測試,在某些特定情況下,Task X的死亡可以導致節氣門敞開——因為Task X的其中一個任務就是根據司機的操作計算節氣門開合角度,它死了也就沒法重新計算這個角度,即使司機把腳挪開加速踏板,節氣門也無法關閉。此為暴沖的直接原因。更糟糕的是,節氣門的開合角度這個數值,被Task X算出來以後保存在一個變數中。這個特定的變數正好沒有被保護(缺陷3)。意味著萬一Task X死亡並且停止計算,這個數值有可能因為不可抗原因被改變,而程序無從得知。

那麼Task X為何會死亡呢?一般是因為內存出錯。這個出錯可能是一個小小的位反轉,也可能是內存里的數值被別的程序錯誤覆蓋。同一系統內同時運行了若干程序,這些程序需要共享一塊內存,內存內部必然要被劃分成若干塊。比如第一塊給程序1,第二塊給程序2,等等。如果程序1因為某些原因(比如Bug)寫到第二塊內存上去,就會導致程序2讀取了錯誤的信息。這就是所謂的內存出錯。豐田的系統里,正好有這麼兩塊相鄰的內存塊。第一塊被稱為「堆棧(Stack)」,這是所有Task存儲它們運行狀態的地方,大小為4KB。與之相鄰的地方儲存了操作系統進行任務分配的記錄。那麼可以想像,如果很多Task給堆棧里寫入太多東西,超過4KB,那麼就會錯誤地寫入與之相鄰的任務分配表。這種錯誤被稱為「堆棧溢出」。操作系統拿到了錯誤的任務分配表,就會錯誤地分配任務,造成某些Task多執行幾次,某些Task少執行幾次,某些Task甚至就再也不執行——死了!必須指出的是,程序死亡並不罕見,甚至可以認為是正常現象。稍後解釋處理方法。

那麼堆棧為什麼會溢出呢?顯然是因為要寫入的數據超過了堆棧的容量。在設計程序的時候要計算最壞的情況並且允許冗餘。即使作出了正確的設計,這種錯誤也相對常見,所以NASA在他們的調查中重點排查堆棧溢出的可能性。於是NASA問豐田,豐田的回復是最壞的情況下4KB堆棧只寫入了41%的數據,換句話說發生溢出的可能性非常低。NASA直接取信了這個數字並沒有再深入調查。但Barr他們發現豐田的回答有嚴重低估,實際上最壞的情況會達到94%,而且還不算遞歸。豐田在代碼中使用了遞歸(缺陷2)。因而實際數字有可能超過94%而且無法預計上限,因為遞歸計算的嵌套層數是無法預測的。所以實際情況下堆棧溢出的可能性相當可觀。一旦溢出,相鄰的任務分配表不可避免就會遭到破壞。此為暴沖的根本原因其中之一。之所以說「其中之一」,是因為堆棧溢出僅僅是損壞任務分配表的其中一個原因,別的還有許多可能性並沒有被Barr在法庭上深入解釋。而且任務分配表的損壞也僅僅是導致Task死亡的原因之一。
順便提一句,2005年的凱美瑞的這部分供應商是電裝,沒有搭載堆棧實時監測功能——溢出了也不知道。同年的卡羅拉卻搭載了,因為供應商是通用。

到這裡我小結一下,串鏈子。左邊是原因,右邊是後果。
堆棧溢出→(可能導致)→任務分配表被改寫→(可能導致)→Task X死亡→(可能導致)→節氣門敞開→(導致)→汽車暴沖

必須指出的是,這條鏈子從最左邊一直到Task X死亡,都還算是嵌入式系統的常見故障。雖然程序代碼寫得不好也許導致更容易出錯,客觀上豐田並沒有特別大的過錯。只要處理得當,這些故障都不會導致暴沖。

到此為止還只是前奏而已,接下來我們來看看豐田到底做錯了什麼。

【第二部分】豐田之罪

上面反覆提到,嵌入式系統中內存出錯或者程序死亡其實是一種正常現象——至少從Barr的證詞可以得出這個結論——現在連我們都知道了,嵌入式工程師肯定比我們更清楚才對。確實,為了使系統正常運行不被錯誤干擾,一般的做法是設置若干層防護措施(Failsafe),讓運行中出現的錯誤無法輕易突破,得到妥善處理。豐田的工程師自然也懂得這一點。很可惜,他們搞砸了。

上面那條鏈子應該修改成這樣:
(防護措施0)→堆棧溢出→(防護措施1)→(可能導致)→任務分配表被改寫→(防護措施2)→(可能導致)→Task X死亡→(防護措施3)→(可能導致)→節氣門敞開→(防護措施4)→(導致)→汽車暴沖

可以看到,防護措施不可謂不多。只要處理得當,這鏈條應該是走不通的。現在讓我們從左到右看一個小小的內存錯誤是如何一層層突破防護最終導致汽車暴沖的。

首先防護措施0。這個其實上面提到了,因為設計缺陷低估了最大佔用的存儲容量,並且不符合規範地使用了遞歸,最終可能導致堆棧溢出。

然後到防護措施1。上面也提到了,任務分配表緊鄰堆棧。作為外行我都覺得這是個十分危險的設計——既然堆棧這麼容易溢出,好歹應該將任務分配表放遠一點啊。當然我是外行,可能實際上比想像中複雜很多。這段Barr的證詞中並未特別提到,屬於我的個人理解。

防護措施2。從這裡開始豐田的錯誤越發嚴重。任務表被改寫導致某些Task運行異常,在軟體層應該有若干檢測措施,比方說用特殊的監視Task來監視別的Task是否正常。但豐田是怎麼做的呢?還記得上面的「廚房洗滌盆」Task X嗎?它是如此複雜(缺陷1),除了控制汽車運行的任務之外竟然還兼任大部分的監視任務,比如生成DTC。
DTC(diagnostic trouble codes),是汽車電腦系統會根據情況生成的錯誤代碼。有的車主可能會遇到汽車某報警燈常亮,修車師傅拿個儀器插在行車電腦上得出一個代碼,再查表就知道哪個元件壞了——這就是DTC。除了用於修車,DTC還被用於檢測行車電腦和各感測器的異常狀態。
可以想像,這個既是運動員又是裁判的Task X一旦死亡,軟體層的檢測措施大部分就失效了。

防護措施3。在這裡豐田的錯誤開始到達頂峰。即使設置正確無誤,上面提到的監視Task也只不過是另一個Task而已,與它的監視對象算是平級——監視Task自己同樣有可能出現故障。嵌入式系統的一般做法是在所有程序之上再設置一道屏障,被稱為「看門狗(Watchdog)」。所謂看門狗,是一個優先順序很高的倒計時程序。別的程序需要在運行的時候特意去重置一下這個計時器讓它重新開始倒計時,這個動作被稱為「喂狗」。如果因為程序出問題太長時間不喂狗,倒計時完成,看門狗知道什麼地方卡住了,馬上採取措施,比如重啟整個系統。重啟系統聽起來似乎很嚴重,實際上卻是一件相當普通的事情。嵌入式系統的重啟非常快,時速100公里的汽車中動力系統可以在半米之內完成重啟——車上的人根本覺察不到。
通過閱讀代碼和擬真實驗,Barr驚訝地發現上述嵌入式系統的常識性做法竟然在豐田軟體系統內不存在!豐田的軟體確實有一隻看門狗,但它竟然不是用於監視Task異常,而是用於防止CPU過載。首先這個做法不能說後無來者至少算是前無古人。還記得上面提到的800頁13章的報告嗎?目瞪口呆的Barr將豐田看門狗的分析結果寫入了報告的第一章,因為他實在太震驚。其次,豐田看門狗的防止CPU過載功能也相當蹩腳,在擬真測試發現即使它正常工作,還是會允許CPU過載時間長達1.5秒——時速100公里的車能跑40米以上。CPU一旦過載,就會導致所有的Task進入一種「假死」狀態,無法處理信息,這時司機無法控制汽車動力,十分危險。
另外,豐田的工程師還犯了一個嵌入式課堂上被反覆提到的經典錯誤:使用硬體時鐘中斷喂狗。硬體中斷擁有非常高的優先順序,即使Task卡住(比如出現死循環)也不能阻止硬體中斷——可想而知這樣一來看門狗就等於完全白瞎了。
這裡也提一句,同年的普銳斯卻令人意外地搭載了一隻運作正常的看門狗,反而讓人摸不著頭腦。
還沒完。這一層防護是嵌入式系統的關鍵陣地。前面都是電子系統,後面馬上進入機械運作,足以造成災難了。所以僅僅擁有軟體級別的防護還不足夠,豐田的做法是在主CPU之外單獨設置了一塊監視晶元,從硬體級別對系統的運作進行監視。監視晶元有兩個任務。第一,它運行一種叫做系統衛士(System Guard)的程序,原理上來說是專門用於防止暴沖。主CPU和監視晶元上都會運行系統衛士,可是研究發現Task X一旦死亡,這些系統衛士統統都不起作用了。第二,它運行一個被稱為「剎車回聲檢查(Brake Echo Check)」的程序。這個程序從代碼上來看似乎可以檢測出Task X的死亡,並且採取相應措施:關閉節氣門。聽起來像是好消息,但是同樣有問題:首先這個程序不太可靠,即使正常運行,理論上也有失效的可能。最關鍵的是該程序不會自動運行,需要司機先對剎車踏板有「動作」才會觸發。注意這裡我特意沒用「踩剎車」這個詞,因為根據分析「觸發動作」十分令人困惑。它分兩種情況:如果Task X死亡的那一刻司機的腳不在剎車踏板上,那麼觸發動作是踩剎車。還算可以理解。另一種情況,如果Task X死亡那一刻司機的腳踩在剎車踏板上,那麼觸發動作是完全釋放剎車踏板。沒錯,察覺車子在不正常加速的司機需要停止踩剎車才能讓控制系統關閉節氣門!這種違背人類認知的行為應該不是豐田工程師特意設計的。如果是,他們到底在想什麼啊?
到此為止,上面提到的都算是「戰術層面」的錯誤,都是「小錯」。在講解這塊監視晶元的時候,可以發現豐田犯下最嚴重的「戰略層面」錯誤——基礎設計。Barr認為,如果基礎設計正確,上述那些小錯都完全不會導致汽車暴沖——不管代碼寫得多業餘,不管內存錯誤多嚴重,不管Task死得多頻繁,統統不會致命。讓我們回到2002年以前,沒有電子油門的時候。那時候的拉線油門是由油門踏板機械連接的。當駕駛員的右腳踩下剎車,他的右腳必然不在油門踏板上,節氣門自然而然地被關閉。這個動作如此自然,甚至算不上安全措施,僅僅因為每人只有一隻右腳,不可能同時踩油門和剎車。當豐田設計電子油門的時候,只要稍微有點常識,都應該從設計階段就將這一「自然而然」發生的動作考慮進去。但是很顯然,他們沒這麼做。監視晶元上運行的代碼是用彙編語言(一種更加接近機器執行代碼,遠離人類語言,更加難懂的編程語言)編寫的,運行層次比主CPU的C語言更低。Barr認為如果設計得當,現有的監視晶元完全有能力勝任上述功能,需要的僅僅是幾百行代碼,別的什麼都不用更改——不會提高任何生產成本。很遺憾,他們沒有做到。

防護措施4。現在已經脫離電子系統,節氣門已經敞開,發動機全速運轉,需要使用機械運作來阻止機械運作了。如何讓向前沖的車子停下來?不開車的人都知道,剎車!現代汽車都裝備了剎車助力,助力來自於發動機運轉的時候產生的負壓。我們知道發動機需要吸入空氣,吸入體積等於排氣量乘以轉速。節氣門又是用來阻擋空氣的,那麼節氣門關閉而發動機轉速相對高的時候(比如高速丟油門),發動機的實際空氣吸入量比它能吸入的體積要少,那麼從節氣門到氣缸進氣口之間會形成明顯低氣壓(所謂負壓,比大氣壓力小)。剎車助力就是利用了這個負壓推動氣鼓產生更大的推力帶動剎車片抓緊剎車盤。氣鼓的結構是有兩個封閉的空間,一邊連接低壓端(由發動機負壓或者真空泵帶動的真空罐)另一邊連接高壓端(大氣),兩邊的氣壓差在隔層產生壓力。按理說無處不在的大氣壓強是最容易得到的,但是豐田偏偏將剎車系統的進氣口與發動機進氣口相連。當節氣門敞開,發動機大量吸入空氣的時候,空氣流速大大增加。兩百多年前的伯努力早就發現,流體流速越高,壓強越小。又一個基礎設計失誤!

但是如果節氣門敞開讓空氣隨便進來,低氣壓就不存在了,這時剎車助力大大減弱,剎車效率也大大降低。這就是為什麼暴沖事件當事人都說全油門的時候根本剎不住的重要原因。這個現象稱為「真空損失(Vacuum Loss)」,存在於所有自然吸氣的汽油發動機汽車(柴油和增壓發動機沒影響),不算豐田的錯。但豐田遲遲不搭載剎車優先系統(Brake Override System)允許剎車的同時敞開節氣門,毫無疑問是這個現象的幫凶。
所謂剎車優先系統,指的是保證同時踩下剎車油門兩個踏板的時候無條件關閉節氣門的功能。這麼做很顯然主要是為了降低發動機輸出,同時也保證剎車助力。豐田在2010年的凱美瑞上終於搭載了剎車優先系統,但是別高興得太早。根據Barr的調查,豐田竟然將如此重要的修改「理所當然」地寫入了他們的「廚房洗滌盆」——Task X。我只能「啞然失笑,扼腕嘆息」。

好了,到此為止都還是Barr的一面之詞,而且大部分都是在那間守衛森嚴的房間內進行擬真測試得出的「理論結果」。那麼實車測試情況如何呢?豐田對Barr的證詞如何反駁呢?

先說說實車測試。為了證明理論,他們把2008年和2005年的凱美瑞放在馬力機上,固定車身架起前輪模擬車輛運行情況。他們的做法是首先讓車子運行在時速68英里(110公里),啟動巡航,腳離開油門踏板。然後暫停巡航,速度開始下降。下降到一定程度恢復巡航,速度開始上升。在到達68英里的設定時速以前,用一台連接行車電腦的筆記本「注入」錯誤。所謂注入錯誤,就是人為地反轉一個特定比特——將0改成1,或者反過來——模擬內存損壞。結果完全符合理論,時速超過68英里也不停止加速,直至時速90英里(145公里),測試人員踩下剎車。大約1秒以後節氣門被關閉,Barr認為這是上述「剎車回聲檢查」的功勞。

實車測試證明了Barr的理論,卻並不是全無破綻。豐田辯護律師就兩點提出質疑:

  • 實車測試使用人工注入錯誤的方法,並不能證明現實中這種錯誤就一定會發生。
    對此Barr的回答是測試的局限性。因為測試時間、樣本有限,而待測試的樣本空間無窮大。如果要等待那個特定的錯誤自然出現,可能需要成百萬上億小時的不間斷測試,顯然是不現實的。更何況從科學上而言,沒有辦法對這個錯誤證偽——就好比無法證明宇宙里沒有外星人,最多只能證明火星上找不到而已。但是這個測試足以證明一個小小的位反轉確實可以突破重重障礙最終導致暴沖,足以證明豐田的軟體存在不能容忍的隱患。
  • Bookout女士(本案原告)聲稱,在她駕駛汽車離開高速的時候發現不受控加速,她拚命反覆踩下剎車並且拉起手剎,現場留下了剎車痕迹。但並沒有跡象表明發動機動力中斷——換言之「剎車回聲檢測」沒起作用。暗指Barr的理論站不住。
    對此Barr的回答是首先儘管在實車測試中每次都生效,但代碼分析表明「剎車回聲檢查」這一功能在理論上靠不住。其次這一功能的另外一個觸發動作是要讓腳完完全全離開剎車踏板。試想車子正在不受控地往前沖,任何人都會不由自主地踩剎車,讓人完全不踩剎車踏板根本就是違背認知的。Bookout女士即使如同她所稱反覆踩剎車,很可能只是一直將腳放在踏板上往複運動,從未完全挪開。Barr還引用一位豐田自己的軟體專家的證詞。該專家承認,如果發生暴沖的時刻腳正好接觸到剎車踏板,並且之後一直沒挪開,那麼汽車的暴沖距離「取決於還剩多少汽油」。

最後順帶說一下那份800頁,13章的詳細報告完成後,Barr將其提交給了豐田的軟體部門,等待他們的反駁。最終結果是「非常少(Very little)」,13章中的11章,包括堆棧溢出的部分、代碼混亂的部分、違反開發規範的部分、Task X過於臃腫甚至兼任節氣門控制和防護措施的部分、看門狗形同虛設的部分、無EDAC的部分、重要變數缺乏保護的部分、使用了非標準化操作系統的部分,全部沒受到任何形式的反駁。

【第三部分】後記

寫到這裡,談談人們比較關心的幾點。當然還是外行眼光。

  • NASA / NHTSA怎麼沒發現這些問題?
    NHTSA本身不具備檢驗電子系統的能力,於是委託NASA。NASA檢驗的是整個電控系統,包括電控傳動部分,範圍比較寬,只有很少一部分資源被用於檢驗軟體系統,也沒有投入足夠的人力進行逐行代碼審閱。更何況在很多關鍵問題,比如之前提到的EDAC的使用、堆棧的設計,NASA都直接採信豐田的回復,最終被證明不正確。甚至NASA從來都沒拿到過監視晶元的源代碼,豐田的說法是「他們沒說要啊」。NASA報告雖然沒能找到軟體系統導致暴沖的確切原因,但沒有否定其可能性。與之相比Barr的團隊全部都是嵌入式系統專家,投入上千小時,深入程度甚至超過豐田自身對這個系統的理解(比如豐田沒看過供應商的OS代碼,Barr看了)。
  • 能否100%確定本案就是由軟體錯誤造成的?
    不能。並沒有直接證據。訴訟團認為,軟體錯誤造成該事故的可能性比軟體錯誤沒造成該事故的可能性大(原文:more likely than not)。
    這裡再提一句,2005年款的凱美瑞沒有搭載行車數據記錄器(俗稱「黑盒子」),後來的車款漸漸開始搭載。但是Barr發現這個記錄功能並不可靠,完全有可能記錄錯誤信息。比如司機踩剎車了可能會被記錄成沒踩。
  • 原來檢查半天還是找不到直接證據啊?
    這裡涉及到一些技術層面的原因,列舉如下:
    • 之前提到,2005年款凱美瑞沒搭載黑盒子;
    • 沒有黑盒子的情況下,唯一可以直接證明軟體錯誤的手段只剩下DTC;
    • 但是如同之前提到,很大一部分DTC的生成由Task X負責;
    • 即使其它Task或者操作系統檢測到異常生成了錯誤代碼,而且豐田的代碼中竟然能找到特定的語句專門忽略這些錯誤代碼(MISRA第一版中明確禁止的行為);
    • 即使終於有一些錯誤代碼好不容易被記錄下來,卻被保存在連接電池的易失存儲器(RAM)上——事故發生之後車輛被詳細檢查之前,只要電池因為某種原因斷開,這些信息就丟失了。
  • 本案的意義
    之前雖然豐田賠了不少錢,但是從未在涉及人身傷害的案件上承責。所以本案意義在於開先例。美國的法律又特別注重先例,今后豐田的法務部門要頭疼了。
  • 本案提到的有缺陷軟體涉及了哪些車型?
    全部是美國的車型。Barr的調查重點是2005年款凱美瑞,另外審閱過的包括雷克薩斯ES、Tacoma、卡羅拉和普銳斯等等,生產年份大致在2002年(電子油門元年)與2010年之間。其中凱美瑞、雷克薩斯ES和Tacoma使用的軟體系統大致接近(原文:Substantially similar)。另外根據統計,汽車暴沖投訴中與2004年款以後的凱美瑞有關的案件數量激增400%。
  • 太可怕了,這(豐田)車還能開嗎?
    我認為不必過度驚恐。首先暴沖事故的出現可能性還是相當低的,有許多案例都被證實是司機操作錯誤。再者本案也沒能直接證明軟體缺陷肯定就是暴沖事故原因。萬一真的出現暴沖也不是無法挽救,證詞中提及了駕駛員使用N檔或者P檔成功脫險的案例。但是今後有必要留個心眼,注意一下車的檔位切換,開車時集中精神對路況進行預判,出現情況的時候冷靜應對。要不也可以試試Barr的發現:全部丟掉剎車然後再踩(汗)。

最後的最後,放上本案關鍵證人Michael Barr的獨家訪談:

我:這麼看來似乎手動檔汽車更安全,你怎麼認為?
Barr:很多專家都這麼認為,離合器至少可以物理斷開動力系統。但是我翻閱卷宗,發現其中有個案例是受害者開手動檔凱美瑞載著家人,突然巡航系統失靈,無法取消。他踩下離合,同時試圖躲避前方慢速車輛結果失控衝出路面造成單車事故。幸運的是沒死人。

我:現在我們都知道豐田的軟體很糟糕。可是你對整個汽車行業的軟體水平有什麼看法?豐田的軟體在同行內屬於什麼水平?
Barr:我沒有接觸過豐田以外的軟體代碼。但是請注意,這次發現的最嚴重問題是豐田在設計源頭上沒有考慮安全,軟體質量反倒沒有那麼重要。只要一個安全為先的設計,比如剎車和關閉節氣門的可靠互動、防止節氣門開啟降低剎車效率的機制等等,不管軟體有多差勁也不會造成致命結果。只是我真不知道軟體還能怎麼差。

我:終極問題,你開什麼車?
Barr:我不開豐田。接觸該案以來我沒買過新車。老實說我現在非常害怕買新車。我倒是問過一個與車企鬥爭了三十多年的職業律師同樣的問題,他開寶馬。

【全文完】

【更改歷史】
v1.01(2013-11-06):後記部分增加為何沒找到直接證據的技術原因。

【版權沒有,轉貼註明出處】


我看到的可能有這幾個原因:
*各國的程序員,交流時用的主要還是英語。日本人英語大家都在黑,不過我查到的不少技術博客的博主都是日本人,幾篇裡面就關於程序的內容是英文的。你看到的說不定就是講著英文的中國程序員
*不是所有外語資料都能被翻譯成中文,加上譯者水平良莠不齊,一些資料質量低下。所以,國內的很多教材確實爛…
*牆,很多一手的資料沒法訪問。

碼農碼畜這些叫法我覺得就是因為漢語信息量大所以人們自黑的時候能輕鬆造個詞…說不定歪果仁還說自己是n00b自嘲啊是不是。

至於解決方案…上面三個點,反過來想便是。


國外雖然沒有碼農的說法但是有碼猴 Code monkey


不要用最好中國程序員的去比其他國家普通的程序員,也不要用國外也存在很爛的程序來否認軟體工程水平(而不是技術水平,技術和工程是兩回事)低於強國的事實。

為什麼呢?書的問題?語言的問題?程序員自己的問題?

作為一個業餘程序員來說吧,我覺得都不是!!!
先講故事。
上個星期,我們項目組開例會,一個組員的PPT有個錯別字,我指出來,小朋友回答——「看得懂就行了」,心裡一萬頭草泥馬呼嘯而過啊!因為UI中有錯別字被客戶鄙視羞辱的故事我不想講了。

至於源代碼里縮進不一樣,同一個系統里顯示的日期格式一會兒是yyyy-MM-dd, 一會兒是MM/dd/yyyy, 我就不挑剔了,每次給他們提這種要求他們都用看外星人的眼光看我!

別笑我們是小公司才這樣,某個微信版本里「請稍後"這三個字不知道現在改過來沒有。

寫程序能有多難?一群人長期穩定地把事情做好才是真難!特別是對於我們這些什麼都講究「差不多」的炎黃子孫來說。所以要我說吧,咱們天朝幾千年的文化,以及深入我們中國人骨子裡的東西就導致了我們沒法做出精細、專業的工業產品,軟體也算工業產品對吧,別跟我扯編程是藝術,也別跟我扯iPhone是中國工人做的。

說結論吧,社會環境導致了我們的工程技術人員很難有條件沉下心去提升自己的專業水平,也很少有客戶和老闆允許我們精益求精的幹活。

」小X, 這個東西你慢慢做,一定要做成精品,UE/UI要像藝術品一樣優雅,代碼要像處女一樣純潔」。
「小X, 客戶(or 老闆)已經罵娘了,趕快先搞一個版本上線,有問題再慢慢改」。

知乎程序員多,上面哪句你常聽到?

補充一句以免引起誤會——處女和非處女都可以是純潔的。


那是因為你接觸到的外國程序員都是outstanding的 普通的程序員也進不了大家的視野~


我 在上海, 90年代就工作了 。始終專心研究自己的領域,好好工作,我工作基本上一個人抵2~3個人,同時做基礎開發,也做公司的產品。 但是由於過分執著,而忽視了別的東西。 到 2010 年,回頭一看, 我當年稍微花點心思,買個3套房不就啥都解決了么 ? 然後我付出了很多,得到的只是稍微高一點的工資 和自己的興趣滿足 。 中國的變化太快,很多的不平衡,這樣非常容易迷失自己,不容易安安心心的工作。


自從有了牆,中國就更少專業的了。


因為國內程序員討論Haskell你也看得懂,國外程序員討論Java你也看不懂,看不懂的當然高大上啦


提主,你是不是應該要從國情出發?市場決定經濟,經濟決定心態。

1.中國互聯網主要靠什麼方式掙錢?坑,對,就是坑用戶,如果答主不是干互聯網這塊那就體驗不到。舉個幾個栗子:一個小栗子,上一家老闆是90後的他最開始從一個小站長開始做,主要是導流量賣偉哥掙了第一桶金,想像一下一個技術員累死累活的搞了一個網頁一個月才幾千塊錢,而你就在他的網頁上放一條連接,每個人點一下一個月下來就掙了幾十萬。讓你選擇你怎麼辦?
最近的一個項目叫一元購,老闆經常拿著用戶的錢乾脆不給了用戶了,總的來說去年掙了1000W。
舉一個大一點的例子:諾基亞、MOTO、Sony等為什麼落的如此下場(他們的主要市場基本在中國)?這幾個廠家之所以落的如此下場難道他們的技術不行了,難道小米的技術就是一流了?在小米等國內廠家剛要興起來的時候,當時是怎麼忽悠用戶的?號外:大內存和多核。對,主要是這個。提主,我拿4個崩騰換你一個i7行不行?相對於國外用戶就會更理智的選擇,於是乎不會出現搶蘋果、小米。所以你要知道一個不爭的事實:中國的互聯網雖然是以技術為主導,但絕對玩的不是技術。

2.中國的技術太廉價了。舉個栗子,前年我在安防行業工作(主要用戶是相關部門),你一個技術員累死累活的解決一個又一個問題,然後沒有銷售關係,公司的產品不會賣出一個,只要銷售的人際關係搞得好,再垃圾的產品也會相關部門買單,你這時候就會明白中國是個特色的關係國家。還有沒有人這個技術自然有人頂上來,產品做的再爛總會有相關部門買單。

3.編碼員的地位太低了。XX公司加班又死了一個人,什麼?又死了。不管哪一個互聯網公司你會發現最忙的永遠是那幾個編碼員,然而薪水低的離譜。舉個栗子:第一點的時候提到過上家公司老闆掙了1000W,當時在年會說拿出20%出來分紅(忘了,居然說進入公司半年起才會有年底雙薪,我當時是8月初進去的,那就沒有了),今年3月份的時候分紅還沒有下來,坑爹。3月初的時候移動端全部走了,後來我也走了,再後來聽說有渠道推廣的人拿了60W,呵呵,這也是人脈廣。
-----------你讓編碼員怎麼不浮躁


這年頭國內真正研究技術的會餓死


國內第一台稍為使用廣泛點的計算機是啥?DJS-130 系。幾年出的?1974 年。用過這台機器的,都是中國計算機界最早的先驅。
然後一年後《人月神話》初版。

懂嗎?國內科研機構拿到第一個型號計算機用來研究的時候,人美國的軟體工程都發展許多年了,計算機商用不知道多久了。


推薦閱讀:

程序員真的干到 35 歲就干不動了嗎?
不上網,我們會缺少什麼?又會獲得什麼?
開啟瀏覽器的「Do Not Track」後,會對瀏覽造成什麼影響?
程序員的理想是什麼?
你有哪些「當時我就懵逼了」的經歷?

TAG:互聯網 | 程序員 | 軟體開發 | 編程 | 計算機 |