<div id="paeqo"></div>
<div id="paeqo"></div>
<dl id="paeqo"><ins id="paeqo"></ins></dl>
  • <menuitem id="paeqo"></menuitem>
  • <li id="paeqo"><s id="paeqo"></s></li>
    <dl id="paeqo"></dl>
    <dl id="paeqo"><ins id="paeqo"><small id="paeqo"></small></ins></dl>

    新闻中心

    EEPW首页 > 牛人业话 > 写代码要小心地盘 阴沟里也能翻了船

    写代码要小心地盘 阴沟里也能翻了船

    作者?#21917;?#26151;道人时间:2019-06-21来源:电子产品世界收藏

    笔者的同事阳春君春节期间喝大了,乐极生悲摔伤了手。在做完手术后的复健阶段,医生让他盘核桃,帮助恢复肌腱。

    本文引用地址:http://www.9113521.com/article/201906/401791.htm

    可是,阳春君的手既?#26159;?#23567;,普通大小的核桃抓一个绰绰有余,抓两个就颇有些力不从心。而且,“盘”核桃这活儿大有技术含量,揉、捏、捻、撸、搓,各种手法,各有各的门道。所以,这只平时敲键盘、写的手刚开?#32908;?#30424;”核桃?#20445;?#21160;作生硬,毫无?#36335;ā?/p>

    玩家们盘上一段时间的核桃,就会变得既红且圆润。可核桃到了他的手里,过了一段时间,就好像受了十大酷?#26691;话悖?#20307;无完肤,斑驳丑陋。让人奇怪的是,虽然盘核?#21307;?#20108;连三地失败,他的手竟而渐渐好了起来,又能噼里啪啦地敲了。

    这段盘核桃的经历在阳春君的身上打下了深深的烙印。他经常把我拉过去,帮着一起?#20197;?#34892;出错的中的bug。看着他那纵横交错的代码,我经常提醒他把代码再重构一下,这样方便找问题。每?#31354;饈保?#20182;就会盯着屏幕上的代码,对着?#24674;?#34255;在何处的bug咬牙切齿地说:盘它!

    timg (1).jpg

    1

    万物皆可盘,核桃如是,代码亦然。

    核桃自不必待言,浑然天成的疙疙瘩瘩,自然而言的天然丑,一副迫切求“盘”的样子,求仁得仁,不盘它盘谁?

    u=3566979592,4253186926&fm=26&gp=0.jpg

    代码呢?基督说,在神面前,人生而不完美。人猿同祖同宗,不完美的程序“猿”写出来的代码自然也不会尽善尽美了,?#35782;?#21516;样存在被“盘”的需求。

    在被盘的过?#35752;校?#26680;桃被千般揉捏,万般搓捻,终于洗尽铅华,文艺气息尽显。代码则被一次次地重构,抽筋换骨,改头换面,最终臻于稳定可靠、好?#26149;?#29992;。

    盘核桃的过程是美妙的。十全老人曾作诗表达对盘核桃的喜爱:掌上旋日月,时光欲倒流。周身气血涌,?#25991;?#26159;白头。盘得如痴如醉,忘了岁月之忧。

    盘代码的过程却?#24378;?#20048;夹杂的。倘若小心翼翼,技术精湛,代码温顺如牛,在自己的手下一步步变得完美、和?#24120;?#30721;农一样可以乐而忘忧。可如果粗心大意,或盘功很烂,搞得代码犹如脱?#31181;?#39532;,携bug之威只是发出那冷笑,码农就只能周身气血涌,早日白了头了。

    ?#24515;敲醇复危?#31508;者就因为不小心,代码没有好好地盘,在阴沟里翻了船。

    2

    这个世界上最遥远的距离,不是相隔千山万里,而是你站在我的面前,我就是搞不懂你。

    对于代码,对于程序,我经常生出这种“你为什么就是不懂我?!”的哀怨。

    1.jpg

    比如我曾经写过下面这句代码:

    Ev_ia=Can_bms.ial+(uint16_t)Can_bms.iah<<8;

    背景很简单,就是根据BMS(电池管理系统)这个CAN节点发来的电流高字节(iah)、低字节(ial)计算出当前电动汽车的电流大小。计算方法为:高字节左移8位,再和低字节相?#21360;?/p>

    看,计算多么简单,简?#31508;?#25226;心?#35745;?#24320;了给你看。但是,岁月剑拔弩?#29275;?#36825;世界并非你想的那样。

    调试过?#35752;校?#38169;误在第一时间就跳了出来,因为我发现,BMS送来的低字节电流为0x64,高字节电流为0?#20445;?#36816;算结果居然成了0x6400。

    错误是显然的,原因也是简单的。我立马敏锐地意识到是“运算符的优先级”问题。查表一看,果然如此。

    左移运算符(<<)的优先级低于相加运算符(+),?#35782;?#22312;计算机的世界中,真正的运算过程为:

    0x64+(uint16_t)0 = 0x64;0x64 << 8 = 0x6400

    而不是自己心中的想当然:0x64 + (0 << 8)=0x64

    细究起来,这可以被认为是人-机之间存在误会,而误会无处不在。

    宇宙黑暗森林中的各个文明之间充满了猜疑,随时准备发起黑暗打击。地球文明中的超级大国美国和中国之间充满了猜忌,贸易战打得如火如荼。就是朝朝暮暮的情侣之间也各种误会,随时捕?#38454;?#23545;方的不信任。

    码农和他钟爱的程序之间?#29275;?#20063;被这宿命般的误会搞得不能你侬我侬,地久天长到那山无棱。

    3

    上面这个bug还算是有情可原,毕竟世间之事千般万种,被世事搞得体力虚弱、脑力孱弱的码农们,很难在编程语言的语法上掌握地非常全面。

    世道艰难,人生无常,程序猿过得很累,我们要原谅他。

    但是还有?#24674;?#26412;来不该出现的bug,它不仅出现了,竟然还长时间地呆在那里,直到你把它?#38454;呤保?#25165;会发觉这种bug出现得多么不可理喻。

    笔者就在一款产品的小批量试产阶段发现了一个本不该出现、出现后也不该活过半天的bug。这只bug通过了功能确认,扛过了车厂的路试,活到了小批量试产阶段。

    这款产品中有个车速检测功能,通过ABS发来的两个字节的车速数据计算出当前车速,根据车速的变化自动对车门上锁。

    两个高低字节经过移位、相加得到一个双字节数据,似曾相识吧。没错,和上面那个计算电动车当前消耗电流的方法一样。

    吃一堑长?#24674;?#30340;笔者肯定不会犯同样的错误,这一次,洒家犯了新的错误。

    2.jpg

    我居?#35805;?#23384;放一个中间车速的变量定义成了8位单字节类型!把一个本该是16位双字节类型的数字塞到单字节里,你可以想象那是怎样?#24674;只?#21776;的bug。

    uint16_t Speed_abs;

    //Uint8_t Speed_abs;//错误就在这里!!!

    Speed_abs=can_ABS330.msg_data.sig.vehicle_speed_l+ (can_ABS330.msg_data.sig.vehicle_speed_h << 8);

    if(Speed_abs <= 0x12c0){

    Speed_quant = Speed_abs;

    CheckSpeed();

    }

    出现这种错误,当然是不可原谅的,但是,人有失算,马有失蹄,?#32423;源?#30701;路,似乎也无法全然避免。事情的诡异当然不在这里,它的神奇之处在于,这种低级别的bug居然一路通关,活到了最后。

    事后想来,整件事都透露着神奇和诡异。

    人生充满了阴差阳错,各种说不清道不明的东西,会让我们陷入莫名其妙的?#36710;亍?#36825;个神奇的bug活了这么久,将这种阴差阳错?#25925;?#22320;淋漓尽致。

    4

    这段错误的代码是在产品开发的最后阶段引入的。最后阶段的主要工作是查缺补漏,尽可能地堵住各种可能的隐?#32908;?/p>

    本来的车速计算和判断程序里没有和最高有效值0x12c0的判断,直接从ABS数据计算出当前车速,赋值给Speed_quant。?#24674;?#24590;么的,我觉得最好是在这里加上对最高有效值的判断,于是就定义了一个中间变量Speed_abs,当它小于等于0x12c0?#20445;?#20877;把它赋值给Speed_quant。

    没用的好心,结果却变成了坏事。本来取值区间在0-0x12c0之间的车速值,被硬生生地限制在了单字节的取值区间(0-0xff)里。想一下吧,有一个神力把三维的你给拍扁了,放进了二维的画里面,憋屈不憋屈?

    本来,这样的bug不该活过半分钟,结果,因为我们这个产品是在车厂的试验车上进行验证,试验车的油箱基本上空了,车厂工作人员也不允许我?#24378;?#36215;车来跑,于是,这个判断车速、赋值车速、根据车速自动闭锁的程序分支?#24674;?#27809;有得到验证。Bug就这样活过了第一关。

    尽管如此,在路试阶段,由于这个bug的存在,加速闭锁功能就失效了。?#25970;矗?#36305;车的路试员怎么竟而没有发现这么明显的错误呢?

    难道路试员?#30475;?#24320;车之前,都会先中控闭锁一下?或者我们的合作伙伴给车厂送的样件里?#31456;?#30340;居然不是我给他们的最后?#35805;?#31243;序?

    实情如何,已无历史可考了,这桩事件终于成了令我百思不得其解的悬案。只有它的诡异,时常浮现在我的心头,让我在敲代码?#22791;?#23384;了一分小心翼翼和战战兢兢。

    战战兢兢,如履薄冰,如此,君子可不立于危地。

    5

    对于一个原始状态的代码,一位好的码农会耐心地在之上精耕细作,仔细地捉虫,耐心地施肥,小心地呵护,务求尽善尽美,这样子,才能搞出健壮、耐看的果实来,这样子盘出来的代码才能经受住时间的考验。

    相反,有的码农写了一段代码后就把它扔在那里,就好像只管生不管养的无?#20960;改?#19968;样,?#34987;?#28779;地又去写下一段代码。没有对代码的耐心呵护,缺乏?#36816;?#30340;修剪、完善,最终,搞出的程序总是既不稳定,又不耐看。

    u=3790028067,1002618127&fm=26&gp=0.jpg

    不愿意耐心找bug改代码的人,?#23548;?#19978;犯的是贪功冒进的错误,总以为量变才能?#26102;洌?#22810;写代码才能把水平提升上去。其实这种认识非常片面,这?#22336;?#24335;也很不可取,对自我能力的提升非常不利。

    因为,只有在一次次的量变中有小的?#26102;洌?#25165;能最终练成编码神功。?#30475;?#37117;马马虎虎,这样的编码经历就像掰玉米的狗熊一样,一边得到,一边丢弃,?#38454;?#21518;其实剩不下多少有用的东西。

    不愿意下功夫盘代码,也是?#24674;?#25042;惰。好逸恶劳是人之通病,所以好的程序猿总是难寻。

    ?#28304;?#20195;码,需要确立不求尽善尽美、但求问心无愧的心态。要仔细地盘,耐心地盘。

    想必,我的经历也能给大家一些启发:代码一定要耐心地盘,阴沟里也能翻了船!



    关键?#21097;? 汽车电子 代码

    评论


    相关推荐

    技术专区

    关闭
    陕西11选5玩法
    <div id="paeqo"></div>
    <div id="paeqo"></div>
    <dl id="paeqo"><ins id="paeqo"></ins></dl>
  • <menuitem id="paeqo"></menuitem>
  • <li id="paeqo"><s id="paeqo"></s></li>
    <dl id="paeqo"></dl>
    <dl id="paeqo"><ins id="paeqo"><small id="paeqo"></small></ins></dl>
    <div id="paeqo"></div>
    <div id="paeqo"></div>
    <dl id="paeqo"><ins id="paeqo"></ins></dl>
  • <menuitem id="paeqo"></menuitem>
  • <li id="paeqo"><s id="paeqo"></s></li>
    <dl id="paeqo"></dl>
    <dl id="paeqo"><ins id="paeqo"><small id="paeqo"></small></ins></dl>
    3d试机号走势图带线专业版 河北麻将下载免费版麻将来了 猜猜乐教案视频 传奇霸业怎样赚钱 2011年f1摩纳哥 沃特福德迪尼 玉皇大帝客服 北京pk赛车人工1期计划 双色球守号中大奖图片 千斤顶或更好100手电子游戏