来源(知乎)

From: https://www.zhihu.com/question/28135660

为什么感觉国外的程序员更专业?

初入行,小菜鸟。现在还在小公司打怪升级。

编程学习过程中,一直有一种感觉,那就是国外的程序员比国内的码农要更专业一些。

专业性不仅仅体现在code上面,也包括代码一致性,文档齐全度,注释风格等等。

包括整个国家的编程学习环境,氛围上。甚至包括对自己的称谓上。国外应该没有码农,码畜,大神,跪舔,程序猿对应的翻译吧~呵呵~

浏览博客过程中也深感如此,很多老外程序员的博客都非常精致,不仅仅是内容,整个博客的风格一看就是倾注了不少心血。

而国内的主流编程博客CSDN,博客园,品质也良莠不齐不等,能坚持更新的很少,大部分也是某个计算机专业的学生为了找工作随便粘贴了一些东西,更谈不上技术深度了。

曾经也想做好一个博客,但是坚持一段时间后发现,时间是个问题。平时白天在公司写业务逻辑已经很累了,是在拿不出时间来经营一个博客。国外的专业程序员是怎么平衡公司业务和自我提升的呢?

请问觉得国外程序员更专业是一种偏见吗?

如果不是,那么如何在国内这种大环境下做一个专业的程序员呢?

16 条评论 157 个回答

----------

知乎用户 网络设备从业者,对于互联网创新持续关注…

266 人赞同

身边有一个程序员,姑且叫他老 S 吧,英国人,在现在的公司工作10年,已经做到了 Director,每天仍旧奋战在第一线,在故障跟踪库中,遇到疑难问题大家一筹莫展时,老S飘然而至,洋洋洒洒数段文字,点出问题所在,然后飘然而去;在Q&A 论坛中,老 S 的回答总是最详尽和最易理解的;在代码 Review 库中,老 S 总是最为严格的给出很多代码改进的建设性意见;老 S 编写和维护着公司最核心的一个基础代码库,同时还亲自维护着3个最核心的模块;老 S 的代码,总是大家在寻找代码参考时的首选;老 S 的手下还管理着30多号人,整天被骚扰请教各种技术问题,还要经常参加各种决策和讨论。经常在感叹老 S 的三头六臂,用“专业”来形容老 S ,绝不为过。

曾经仔细思考过老 S 为何如此专业,总结出如下几点:

追求极致。为啥在某些领域国外的业余运动员水平比国内专业运动员水平还高(乒乓球除外),在国外的氛围是,一旦兴趣使然,就会不断的练习,练习,练习~,直到无法再提高为止。国外的程序员也一样,以兴趣为导向,真正喜欢的东西,往往能玩到极致。

追求深度。国外的教育体系,前期注重广度,后期注重深度,而广度到深度的转变,取决于个人的选择和兴趣,一旦确定专业方向,这里的深度往往远超乎想象。

追求展现和表达。从老 S 的身上,我就可以深切的感受到这一点,老 S 在代码中的注释,有时比专业文档写得还好,在Q&A 论坛中只是表达一下自己的观点和见解,绝少看到老 S 寥寥数语, 往往都是三段论。个人感觉,国外教育体系培养的都是销售,国内教育体系培养的都是工程师。通过培养销售体系中出来的程序员,自然在表达上有得天独厚的优势,加上本身具有的深度理解和逻辑思维,在博客上能够得到淋漓尽致的体现。

坚持再坚持。老 S 编写的公司最核心的基础代码库,第一个版本是2007年完成的,8年的时间,从代码日志上可以看到老 S 对这个基础代码库不断精益求精的进行打磨,根据标准和协议的变化不断的演进。在这个过程中,老 S 的技术能力不断的得到锤炼和提升。

国外的大环境。在国外,程序员之间其实也是“文人相轻”的,一个程序员是否被其他程序员在内心中尊敬,和他以前写过的代码和项目直接相关,和他现在所在的位置关系不大。从职业发展上,某些资深的程序员,待遇会和VP 不相上下。正是因为有这些保证,老 S 身为Director,仍旧可以每天奋斗在代码的第一线;Google 的Sanjay Ghemawat和Jeff Dean,可以没有任何管理头衔,继续在技术上探索,而且继续被大家所崇拜。

所以说国外程序员更专业其实并不是一种偏见,而是事实。

那么如何在国内这种大环境下做一个专业的程序员呢?

在回答这个问题之前,先谈谈国内的大环境,国内的程序员,代码写的好的,往往技而优则管,从此陷入管理的日常性事务,在专业上就无法继续精进了。曾经思考过这个问题,个人总结原因如下:国内的开发节奏,需要大量的可以加班和熬夜的程序员不断的滚动迭代开发,通过快速的迭代,来弥补软件本身质量上的缺憾,最终输出满足用户各种需求的产品。在这种开发节奏中,“专业”和“资深”的程序员显得非常的不合时宜:往往有家庭的牵绊,无法大量的加班;输出的软件虽然质量有保证,但是并不一定能满足项目激进的进度要求;一般薪水还较高,不如招毕业生新手培养来的划算。而新手需要培养和指导,“专业”和“资深”的管理者变得非常紧缺,其中很重要的一个来源,就是可怜的“专业”而“资深”的程序员。国内有很多公司有所谓的管理和技术双线,但是往往管理线上所能得到的资源和收益,要远远大于技术线。逼迫大部分的优秀程序员,不得不或者心甘情愿地走上管理的岗位,否则会落得“屌丝程序猿,死时爬键盘”。

那这个问题是否有答案呢?其实答案就是两个字:坚持,包括技术上和时间上的坚持。在现实的条件下,不妨去做管理,但是切不可放弃对技术本身的理解和日常的编码,这是技术上的坚持。坚持到有一天,程序猿变成程序员,在薪资上真正的被尊重;在开发节奏上,再也无法使用大量廉价劳动力滚动开发,“专业”的程序员价值被真正的认可和尊重;国内的程序员群体随着岁月也经历50,60,70,80岁;全社会对程序员这个职业有了更加深刻的认识,看到白发苍苍还在一线写代码的程序员时,没有人再认为她或他是 Loser,而是心生敬意。坚持到这一天,才能真真正正的安心做一个专业的程序员,这是时间上的坚持。

最后记起了以前读到的一个故事,真假不太确定:腾讯广研所一次在探讨一个微信需求的具体实现方案,大家争执不下,总觉得太难于实现,这时参与讨论的张小龙踱回办公室,许久后出来,手里拿着代码,轻描淡写的说:大家看看这样实现如何?方案遂定~。如果故事属实,我猜想张小龙的心底一定是有这份坚持的;如果故事不属实,我也猜想张小龙的心底一定是有这份坚持的。

编辑于 2015-07-13 32 条评论

黄逸尘 信息搜集狂,知识面一公里宽一毫米深。。…

2305 人赞同

中国码农不是不专业,而是“浮躁”,写代码从来不是职业,只是通往更高职位的阶梯而已。

在中国任何一个角落,码代码的都会告诉你,35岁之后就会码不动了,招聘广告也会写明,20~35岁,你35之前不从代码转管理,你死定了等等等等。听我混互联网行业的兄弟说,干过2年以上可以算得上高级程序员,5年以上就可以上到技术经理,再往上最好到30之前就爬到技术总监。说得仿佛人生必须在40岁之前完结一样。包括我自己,前几天和同事开完玩笑之后也郁闷了好久,“现在的我可以轻松搞定3个毕业生的工作量,但是老板觉得我2.5倍毕业生的工资还是高了。呵呵。。。” 刚刚有点专业的样子就不得不脱离岗位了,怎么破?

想换个行当,面试告诉你,你年纪大了,可塑性不行,我靠,我在这行混了10年了小到MCU大到服务器,asp写到django,C语言写到PLSQL,从Qt玩到oracle form builder,做过消费品写过erp,从将棋可以陪你聊到会计财务,来来来,咱俩唠唠,你觉得啥我学不会。

作为还有4年可用寿命的码渣,到现在还没脱离第一线工作,喜欢写代码的成就感,可惜天天被人教育一定要往上爬,做业务,别做技术。天天被人鄙视说是不求上进,麻辣隔壁的你们烦不烦?码程序是我爱好,爱好!

到时候真没人要开专车养家糊口,我一样会在家里折腾电脑的。就酱。

编辑于 2015-07-05 262 条评论

----------

vczh 《C++Primer 5th》强势审校

110 人赞同

题主说的事情都是不存在的,正确的解答是,国内的公司不鼓励程序员追求质量,所以你在这个地方生存当然也只能这样了。如果你跑到外面去,你会发现无论是中国人还是外国人,都变得更有追求了。

最近感觉很明显,跟一个Excel的人谈合作,要弄一个事情。尽管是在让他们migrate到我做的新的开发工具上,人家不会一股脑把所有的工作都推给我,只要是他们改对Excel的长远未来会更好,他们就改。想起之前跟在阿三的阿三谈事情的时候,简直就是天跟地的区别(逃

编辑于 2017-02-02 22 条评论

----------

欲三更 人生政委

119 人赞同

有一个因素,前面的答案都没说到。就是中国程序员的个人品牌意识还不算太强。

几年前我在做 windows 开发的时候,常常要借助两个网站,一个是外国的 codeproject,一个是中国的 csdn。csdn 当时口碑就不算好,大家都说太水。其实在 csdn 上也常能找到干货,很多文章并不缺乏技术含量,但是整体观感上,却要差 cp 很多。造成这种差距的,主要是细节,比如行文语句不通顺,文章太简略没解释清楚问题,轻率地转载,错别字,张贴的代码编译通不过,demo 代码不规范,排版不友好等等。

我认为这就是一种意识上的差距,cp 上的作者,往往是以自媒体(尽管那时还没这个词)或者自我品牌建设的定位来运营博客的,而当时绝大部分 csdn 用户,把博客当成了备忘录,写的内容根本不是给外人看的,更没有想过通过博客给自己加码(这其实就是轮子哥常说的 promote)。

这种理念的差距反应到工作中、代码上,就是很多程序员写代码是给机器看的,而不是给同事和领导看的。这其实是一种短视,同事可能变成领导,领导可能会跳槽,而你展现给他们的代码,很有可能意味着新的工作机会。

值得庆幸的是,随着互联网公司招聘看博客和 github 的风潮兴起,这种情况正在改变。现在开源代码和技术文章,几乎已经成了中高级程序员简历的一部分,知乎和掘金上的国产技术文,越来越有“专业”味道了。为了能吸引读者以及彰显实力,大家开始普遍思考“写有营养的东西”,而不是“先记下来别回头忘了”,那种打开一个技术网站满屏初学者笔记的情况,好了不少(尽管仍然存在)。

我相信随着个人品牌意识的普及,中国程序员的专业性,至少看上去的专业性,还能大幅提高一个档次。毕竟中国程序员质量并不算差。这一点有过统计研究,但是相关地址我找不到了。个人观感来说,要比基础的,比如印度人吧,印度的软件外包算是行业标杆,我跟印度外包公司的研发打过交道,我并没感觉的同级别的印度外包程序员比中国外包(就是软通、文思等)程序员专业在哪里。比时髦的,现在国内的开源项目也不少了,只要是搞出点名堂的项目,质量和规范性和国外项目也没有多大区别。

ps:

但是在行业软件领域,依我所见,从产品质量,到代码质量,再到人才质量,真的和国外差距很大。

打个比方,如果你有机会去观察一下国外的行业软件,你会觉得它们和你平时用的 office、photoshop,是差不多的东西,但是同行业的国产软件,具体的差距就不说了,你常常能感觉到,它们和你平时用的软件不像同一种东西。

这说的是产品,程序员也是这样的感觉。我之前做安防的时候,接触过 milestone(后来被佳能收购了)、genetech、sony,以及几个欧洲知名厂商的研发。这些人水平和 title 有高有低,但总体上,他们和你在网上看到的互联网程序员没有什么不同,不管是 email 还是代码,还是面对面交流,都显示出他们是毫无疑问的专业 coder。而同行业国内公司的研发……总感觉哪儿不对劲,不像程序员……倒不是说水平一定不高,只是常会发生一些诸如发 email 使用口语,私人信箱传代码,文档用 word 写,安装包用 rar 压缩,安装包里有静态库,术语听不懂,目录写死在代码里,变量名拼写错误,定制版程序出问题却找不到符号文件之类的事情。

大约就是那种“不专业”的感觉。

编辑于 2017-02-12 33 条评论

----------

知乎用户 http://sujitech.com

325 人赞同

因为写程序好的都变成外国人了

发布于 2015-02-12 22 条评论

----------

Megan Lee 从教育转战IT~ 女娃子也能编程~

73 人赞同

硅谷刚入行小兵一枚,从实习和观察来看,可能以下几个方面能说明点问题

1. 教育方式

读cs系,这里更注重的是实战教育。举例,在上ditributed system时候 要自己看懂paper并且实现一个简单的mapreduce + gfs框架. 全程过中 教授会code review,会和你讨论你的设计方案,会规范你的代码风格和构架方式。会要求你自己写test,会组建seminar让全系其他年纪的人来听你的project 整个过程模拟了工作中需要的各种技能,结果你发现真正工作遇到的问题并没有学校的难(当然只是对entry level来说,仍在努力练级中)

2. 分享精神和行业氛围

在一个以充满技术氛围的地方,周围高手云集 又谦逊近人 整个硅谷充满导师文化。这种氛围下,一个人的姿态不自觉的就会谦逊,把自己放得很低,周围人不是把技术当成职业 而是一种信仰 一种热爱 一项魔术。这种热忱回不自觉的感染到新进码农。在怀着热忱为社会创建更多影响力的使命的驱动下,有一种内在力量 会不断把你推向完美!

但是周围接触到的华人工程师也是非常厉害的!中国的人口基数造就了独一无二的高负荷大型分布式的网站,用户基数在全世界范围都是独一无二的。

眼见为心中所想,无需观测外在,只需专注于让自己和自己接触到的人不断提升!

编辑于 2015-02-12 8 条评论

----------

贺利湘 拥有腹肌的攻城狮

70 人赞同

提主,你是不是应该要从国情出发?市场决定经济,经济决定心态。

1.中国互联网主要靠什么方式挣钱?坑,对,就是坑用户,如果答主不是干互联网这块那就体验不到。举个几个栗子:一个小栗子,上一家老板是90后的他最开始从一个小站长开始做,主要是导流量卖伟哥挣了第一桶金,想象一下一个技术员累死累活的搞了一个网页一个月才几千块钱,而你就在他的网页上放一条连接,每个人点一下一个月下来就挣了几十万。让你选择你怎么办?

最近的一个项目叫一元购,老板经常拿着用户的钱干脆不给了用户了,总的来说去年挣了1000W。

举一个大一点的例子:诺基亚、MOTO、Sony等为什么落的如此下场(他们的主要市场基本在中国)?这几个厂家之所以落的如此下场难道他们的技术不行了,难道小米的技术就是一流了?在小米等国内厂家刚要兴起来的时候,当时是怎么忽悠用户的?号外:大内存和多核。对,主要是这个。提主,我拿4个崩腾换你一个i7行不行?相对于国外用户就会更理智的选择,于是乎不会出现抢苹果、小米。所以你要知道一个不争的事实:中国的互联网虽然是以技术为主导,但绝对玩的不是技术。

2.中国的技术太廉价了。举个栗子,前年我在安防行业工作(主要用户是相关部门),你一个技术员累死累活的解决一个又一个问题,然后没有销售关系,公司的产品不会卖出一个,只要销售的人际关系搞得好,再垃圾的产品也会相关部门买单,你这时候就会明白中国是个特色的关系国家。还有没有人这个技术自然有人顶上来,产品做的再烂总会有相关部门买单。

3.编码员的地位太低了。XX公司加班又死了一个人,什么?又死了。不管哪一个互联网公司你会发现最忙的永远是那几个编码员,然而薪水低的离谱。举个栗子:第一点的时候提到过上家公司老板挣了1000W,当时在年会说拿出20%出来分红(忘了,居然说进入公司半年起才会有年底双薪,我当时是8月初进去的,那就没有了),今年3月份的时候分红还没有下来,坑爹。3月初的时候移动端全部走了,后来我也走了,再后来听说有渠道推广的人拿了60W,呵呵,这也是人脉广。

-----------

你让编码员怎么不浮躁

发布于 2015-07-08 16 条评论

----------

赵劼 知乎“温赵轮”三大软狗之一。

1068 人赞同

为什么你觉得国外的书质量高?因为质量差的书是不会引进到国内来的。你觉得老外牛逼,不过是因为你见到的外国人太少代码太少博客太少,中国人良莠不齐你每天都看在眼里,而老外你只见得到够亮的那些。

编辑于 2015-02-12 117 条评论

----------

毛草 前软件工程师/MBA在读/大概还是动漫宅/不…

197 人赞同

最底层原因是不注重知识产权。这有两方面,一个是社会不关心公司产品的产权,另一个是老板不关心员工的知识产权。

社会嘛,这么说吧,扔在国外企鹅这种网吧公司早就被告到死了……现在好了,国产大旗

360这种流氓公司扔在国外早就被法院起诉死了……现在也是创业者的楷模

我们就讲究说原始积累时候要心狠手辣,可是就没有人意识到十年磨一剑的重要性。当然磨剑的大部分在磨的过程中就被社会碾死了,这是另一方面。

这样的社会大环境带来的结果就是,对于公司而言,“能用”比起“好”重要的太多太多

换言之,用10个廉价劳力,比起用1个顶50个的高手,更容易进行风险控制

所以这样导致的生产模式就是,一旦你不再是廉价劳力,那么使用你的风险就会大幅上升,于是公司就不想用了

当然另一方面求职者本身的心态也是大问题。国内只看到了硅谷的创业潮(而且是疯狂的宣传着硅谷的创业潮),却没有看见硅谷和硅谷以外,几十倍乃至与几百倍的技术高手只是在心甘情愿的做一份朝九晚五的工作。他们可能技术都非常非常非常牛逼(我个人见过的不要太多),但是他们并不想创业。

但是中国你不创业就是没上进心,而且好像你手下不管着多少个人你就是个废物一样。没有人关心你的技术如何。

可是大家就忽略了,本质上,人本来就分为喜欢管理他人,和不喜欢管理他人的两类人。比如我就是一个天生极端讨厌管理人的人。我只喜欢处理具体事务,而且说真的我根本就不care其他人在干什么,或者其他人怎么看我。

但我这样的人扔在国内就是个完全没有上进心的failure。可是在国外就不是。

我相信我不是唯一这样的人。可是正如“30岁不结婚的女人就死定了”一样,“35岁还做技术不转管理的男人就完蛋了”也成为了社会的共识。

结果就是,老板不想用技术好的人,因为他看不到技术好带来的效益,而只看到了技术好带来的不好管控。

程序员则是因此分化,一类因此失去研究技术的动力,于是就等着靠人事能力和业务能力升职去做纯管理;另一类则是眼界奇高,就想着技术牛逼了去做个CXO,结果话里话外都体现出一种天大地大老子最大的傲气,让人不敢用。

结果就是踏实搞技术的那一小部分人死球。

还有一个因素就是,国内90%以上的大学本科计算机教育简直像屎一样。这是致命的,因为走程序员这条路的发展如何,90%取决于你本科学的怎么样。

我们学校(在加拿大)计算机专业本科,每年录取200人,但能毕业出来不超过50人。剩下的要不然转专业要不然退学了。据我所知其他学校类似这个比例。

我们大二讲编译原理和大三讲操作系统时候,学生都必须亲手写编译器和微型操作系统。然后没有标准答案,只有测试。测试过了满分,不过零分。当然还有建立在词法和语法分析基础上的反作弊软件——抄袭超过5行就能抓住,抓住本课直接零分,两次抓住直接劝退,没有商量。最后教授没有毕业率要求卡着,他不开心了把你们全体挂科也无所谓,没人管他。

所以这样学出来,你对各种编程语言的掌握和学习能力就不是国内一般学校比得了的。

然后基础的差别会让你以后的学习速度出现决定性的差别。更何况很多人是干了多少年见多识广的人。

几个因素加在一起,国内的大环境短期内是看不到翻身的可能的。

当然,我同样也遇到过许多打破了这些所谓“常理”的那些少数精英。那些人可能会嘲笑我说的这些都是狗屁,我尊重他们的看法,而且我也同意这是狗屁。

但是对于我遇到的大多数人而言,这些都没错。

如果你问一个人他为什么不去改变,得到的回答九成都会是“哎,大环境如此,没办法,你不懂”

所以不懂的就都出国了

然后国外就比国内技术水平强了

就这样

EDIT:关于国内怎么变成更专业的程序员:

这个我只能从我在国内认识的一些比较厉害的人身上来发掘共性,毕竟大环境这个问题不好说

英语要学好,一定要学好。这个是最最关键的东西。学好英语你可以直接上StackOverflow和各种国外博客,可以直接和人交流/学习所谓“第一手”的东西,而不是抱着CSDN上被“大牛”们咀嚼消化过的内容来学。

如果还在大学,离散数学相关的东西一定要非常认真的学。然后编译原理和操作系统尽可能的搞明白。搞不明白的话,能把C的指针彻底搞明白也行。方法就是多写,多试,多问,多讨论。

一定要有对任何技术细节都打破沙锅问到底的精神。如果遇到大牛(或者不用大牛,只要是个你认为比你强的人就行)写的程序中某个细节不明白,那一定要尽可能搞明白,无论这个地方看起来多小。不要怕丢面子也不要怕别人嫌你烦(当然你要讲究方法,而且要机灵点)。这种东西只能靠平时的积累。而且这是唯一能提高你debug能力的办法。除此之外没什么捷径。

多和人交流,相互促进。既然你已经进入编程行业了,那相信你找到一个喜欢编程而且喜欢讨论的人应该不难。那么你每次学到新东西的时候不妨找这(几)个人一起讨论。每个人知道的东西都不一样,讨论多了也许就会碰撞出你想象不到的火花。

除了程序以外,尽可能多去了解你所在行业的业务流程。大多数情况下,程序经常改来改去很大程度上是因为对用户需求分析的不够明确。如果在你动手写程序之前就能指出需求不完善的地方,那么有可能PM拿回去确认后你就不用写了,当然也就更不用改了。

敢于提意见,但是提之前尽量站在他人角度思考,同时多听别人从其他角度提出的意见。比如上边说的,PM给的需求如果不合理,一定要尽早指出。但是指出的方式要和对方关心的方式有关——比如对PM,你可以说“做这个功能需要很多天,而且有很大的不确定性。如果改的话工作量也很大,这样的话很可能会导致你要求我们做的其他功能做不完”,等等。要用对方能理解的角度解释。或者比如你可以说“这个功能现在我不确定能不能做出来,你能不能给我一天时间做个原型验证一下,如果一天后技术不可行那我们赶紧想别的办法”之类。总之,管理者角度而言,如果你做不出来,他们希望越早知道越好,最好是你做之前就知道。

具体技术方面,一定要掌握所有测试相关的知识。特别是如果学习一个新语言的话,争取尽快掌握其中的一个做单元测试的框架,然后尽早给你开发的所有主要功能全部写出单元测试。要知道问题发现的越早,修复的越快。同一个问题在单元测试发现,和在客户手里发现,造成的问题完全不是一个数量级,即便问题完全一样。

上边那些都做好,有余力的时候,争取多看看程序的新发展方向,和新兴的技术。和大多数其他人的观点不同,我个人觉得这条是这些里边最不重要的。原因是人要先站稳了才能跳,先会走再学跑。首先你要有一门掌握的非常过硬的语言,然后才有必要学新的。样样通样样松的人只能做管理(笑),但管理一般要不然是样样通样样精的巨牛,要不然是空降的亲戚。你能跟哪边比呢(笑)。

以上

编辑于 2015-07-09 26 条评论

----------

李黄河 继续修炼

2 人赞同

大环境如此,除了少数互联网知名企业的开发。

其他公司的程序员不受重视,从上到下,从里到外都在告诉你写代码没前途。

发布于 2015-07-08 添加评论 感谢

----------

知乎用户 铲屎上将

44 人赞同

我想优雅敲代码,没事重构下让代码更优雅

结果呢

2星期一小版3星期一大版注重发版效率轻视程序稳定

加班就不提了

闲下来就想歇歇

发布于 2015-02-12 11 条评论

----------

萧井陌 微信公众号:炼瓜研究所 技术社区 …

160 人赞同

你不过把自己不努力学习的因素归于国内大环境不好罢了。

来份日本、美国的例子,是丰田车的渣代码杀人事件。

【年度巨献】从外行的视角尝试讲解为什么这回丰田栽了【全文完】【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):后记部分增加为何没找到直接证据的技术原因。

【版权没有,转贴注明出处】

发布于 2015-02-12 31 条评论

----------

匿名用户

12 人赞同

国外虽然没有码农的说法但是有码猴 Code monkey

发布于 2015-02-12 8 条评论

----------

Yorkie http://github.com/yorkie

7 人赞同

那是因为你接触到的外国程序员都是outstanding的 普通的程序员也进不了大家的视野~

发布于 2015-07-09 添加评论 感谢

----------

知乎用户 骑行爱好者

80 人赞同

不要用最好中国程序员的去比其他国家普通的程序员,也不要用国外也存在很烂的程序来否认软件工程水平(而不是技术水平,技术和工程是两回事)低于强国的事实。

为什么呢?书的问题?语言的问题?程序员自己的问题?

作为一个业余程序员来说吧,我觉得都不是!!!

先讲故事。

上个星期,我们项目组开例会,一个组员的PPT有个错别字,我指出来,小朋友回答——“看得懂就行了”,心里一万头草泥马呼啸而过啊!因为UI中有错别字被客户鄙视羞辱的故事我不想讲了。

至于源代码里缩进不一样,同一个系统里显示的日期格式一会儿是yyyy-MM-dd, 一会儿是MM/dd/yyyy, 我就不挑剔了,每次给他们提这种要求他们都用看外星人的眼光看我!

别笑我们是小公司才这样,某个微信版本里“请稍后"这三个字不知道现在改过来没有。

写程序能有多难?一群人长期稳定地把事情做好才是真难!特别是对于我们这些什么都讲究“差不多”的炎黄子孙来说。所以要我说吧,咱们天朝几千年的文化,以及深入我们中国人骨子里的东西就导致了我们没法做出精细、专业的工业产品,软件也算工业产品对吧,别跟我扯编程是艺术,也别跟我扯iPhone是中国工人做的。

说结论吧,社会环境导致了我们的工程技术人员很难有条件沉下心去提升自己的专业水平,也很少有客户和老板允许我们精益求精的干活。

”小X, 这个东西你慢慢做,一定要做成精品,UE/UI要像艺术品一样优雅,代码要像处女一样纯洁”。

“小X, 客户(or 老板)已经骂娘了,赶快先搞一个版本上线,有问题再慢慢改”。

知乎程序员多,上面哪句你常听到?

补充一句以免引起误会——处女和非处女都可以是纯洁的。

编辑于 2015-02-13 33 条评论

----------

Belleve编程、JavaScript话题优秀回答者 Type design == 设…

37 人赞同

国内第一台稍为使用广泛点的计算机是啥?DJS-130 系。几年出的?1974 年。用过这台机器的,都是中国计算机界最早的先驱。

然后一年后《人月神话》初版。

懂吗?国内科研机构拿到第一个型号计算机用来研究的时候,人美国的软件工程都发展许多年了,计算机商用不知道多久了。

编辑于 2015-02-12 8 条评论

----------

匿名用户

54 人赞同

我 在上海, 90年代就工作了 。始终专心研究自己的领域,好好工作,我工作基本上一个人抵2~3个人,同时做基础开发,也做公司的产品。 但是由于过分执着,而忽视了别的东西。 到 2010 年,回头一看, 我当年稍微花点心思,买个3套房不就啥都解决了么 ? 然后我付出了很多,得到的只是稍微高一点的工资 和自己的兴趣满足 。 中国的变化太快,很多的不平衡,这样非常容易迷失自己,不容易安安心心的工作。

编辑于 2015-07-07 10 条评论

----------

唐伟诚 编乎,绿乎,玄乎

28 人赞同

自从有了墙,中国就更少专业的了。

发布于 2015-02-12 6 条评论

----------

杨超 不生产代码的搬运工

1.不是感觉 是事实 一国之力敌全世界就不太可能嘛

那些不错的国外blog里面除了有美国 还有希腊的 波兰的 俄罗斯的 巴西的 叙利亚的

2.要是题主指的国内外是地理意义上的 那就更是如此了 去微软 google facebook这些地方面试 面试官不是印度的 就是中国的

3.但是 就个体而言 不要用人家最好的 来跟我们最差的比啊 贴吧里也有非常厉害的大神哪

那些csdn cnblog博客里 也不乏很多质量好的 虽然大多人后来都建了独立博客 难道都被无视了么

当然 用blog来衡量编程能力本身也不合理

发布于 2015-07-11 添加评论 感谢

----------

春哥叨叨 自认全栈工程师。身处互联网。

基本功吧,国内都是快餐

Link: http://www.asm32.net/article_details.aspx?id=7165