您的位置 首页 培训

写代码要当心地盘 暗沟里也能翻了船

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

笔者的搭档阳春君新年期间喝大了,乐极生悲摔伤了手。在做完手术后的复健阶段,医师让他盘核桃,协助康复肌腱。

可是,阳春君的手既肥且小,一般巨细的核桃抓一个捉襟见肘,抓两个就颇有些无能为力。并且,“盘”核桃这活儿大有技能含量,揉、捏、捻、撸、搓,各种办法,各有各的门路。所以,这只平常敲键盘、写代码的手刚开始“盘”核桃时,动作僵硬,毫无规矩。

玩家们盘上一段时刻的核桃,就会变得既红且圆润。可核桃到了他的手里,过了一段时刻,就好像受了十大酷刑一般,遍体鳞伤,斑斓丑恶。让人奇怪的是,尽管盘核桃接二连三地失利,他的手竟而逐渐好了起来,又能噼里啪啦地敲代码了。

这段盘核桃的阅历在阳春君的身上打下了深深的痕迹。他常常把我拉过去,帮着一同找运转犯错的代码中的bug。看着他那犬牙交错的代码,我常常提示他把代码再重构一下,这样便利找问题。常常这时,他就会盯着屏幕上的代码,对着不知藏在何处的bug咬牙切齿地说:盘它!

timg (1).jpg

1

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

核桃自不用待言,浑然天成的疙疙瘩瘩,天然而言的天然丑,一副火急求“盘”的姿态,求仁得仁,不盘它盘谁?

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

代码呢?基督说,在神面前,人生而不完美。人猿同祖同宗,不完美的程序“猿”写出来的代码天然也不会一无是处了,故而相同存在被“盘”的需求。

在被盘的进程中,核桃被千般揉捏,千般搓捻,总算洗尽铅华,文艺气味尽显。代码则被一次次地重构,抽筋换骨,面目一新,终究臻于安稳牢靠、美观好用。

盘核桃的进程是美好的。十全白叟曾作诗表达对盘核桃的喜欢:掌上旋日月,韶光欲倒流。周身气血涌,何年是白头。盘得如痴如醉,忘了年月之忧。

盘代码的进程却是苦乐搀杂的。假使小心谨慎,技能精深,代码温柔如牛,在自己的手下一步步变得完美、调和,码农相同能够乐而忘忧。可假如粗枝大叶,或盘功很烂,搞得代码犹如脱缰之马,携bug之威仅仅宣布那冷笑,码农就只能周身气血涌,提前白了头了。

有那么几回,笔者就由于不小心,代码没有好好地盘,在暗沟里翻了船。

2

这个国际上最悠远的间隔,不是相隔千山万里,而是你站在我的面前,我便是搞不明白你。

关于代码,关于程序,我常常生出这种“你为什么便是不明白我?!”的哀怨。

1.jpg

比方我从前写过下面这句代码:

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

布景很简略,便是依据BMS(电池办理体系)这个CAN节点发来的电流高字节(iah)、低字节(ial)核算出当时电动汽车的电流巨细。核算办法为:高字节左移8位,再和低字节相加。

看,核算多么简略,简直是把心都剖开了给你看。可是,年月一触即发,这国际并非你想的那样。

调试进程中,过错在第一时刻就跳了出来,由于我发现,BMS送来的低字节电流为0x64,高字节电流为0时,运算成果竟然成了0x6400。

过错是显着的,原因也是简略的。我立马敏锐地意识到是“运算符的优先级”问题。查表一看,不出所料。

左移运算符(<<)的优先级低于相加运算符(+),故而,在核算机的国际中,真实的运算进程为:

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

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

细究起来,这能够被认为是人-机之间存在误解,而误解无处不在。

世界漆黑森林中的各个文明之间充满了猜疑,随时预备建议漆黑冲击。地球文明中的超级大国美国和我国之间充满了猜疑,贸易战打得如火如荼。便是朝朝暮暮的情侣之间也各种误解,随时捕捉着对方的不信任。

码农和他宠爱的程序之间呐,也被这宿命般的误解搞得不能你侬我侬,地久天长到那山无棱。

3

上面这个bug还算是有情可原,究竟人间之事千般万种,被世事搞得膂力衰弱、脑力懦弱的码农们,很难在编程言语的语法上把握地十分全面。

世风困难,人生无常,程序猿过得很累,咱们要宽恕他。

可是还有一种原本不应呈现的bug,它不只呈现了,竟然还长时刻地呆在那里,直到你把它捉走时,才会发觉这种bug呈现得多么不行理喻。

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

这款产品中有个车速检测功用,通过ABS发来的两个字节的车速数据核算出当时车速,依据车速的改变主动对车门上锁。

两个凹凸字节通过移位、相加得到一个双字节数据,似曾相识吧。没错,和上面那个核算电动车当时耗费电流的办法相同。

失败乃成功之母的笔者必定不会犯相同的过错,这一次,洒家犯了新的过错。

2.jpg

我竟然把寄存一个中心车速的变量界说成了8位单字节类型!把一个本该是16位双字节类型的数字塞到单字节里,你能够幻想那是怎样一种荒诞的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();

}

呈现这种过错,当然是不行宽恕的,可是,人有失算,马有失蹄,偶然脑袋短路,好像也无法全然防止。作业的怪异当然不在这儿,它的奇特之处在于,这种初级其他bug竟然一路通关,活到了终究。

过后想来,整件事都透露着奇特和怪异。

人生充满了一差二错,各种说不清道不明的东西,会让咱们堕入不可思议的地步。这个奇特的bug活了这么久,将这种一差二错诠释地酣畅淋漓。

4

这段过错的代码是在产品开发的终究阶段引进的。终究阶段的首要作业是查缺补漏,尽或许地堵住各种或许的危险。

原本的车速核算和判别程序里没有和最高有效值0x12c0的判别,直接从ABS数据核算出当时车速,赋值给Speed_quant。不知怎样的,我觉得最好是在这儿加上对最高有效值的判别,所以就界说了一个中心变量Speed_abs,当它小于等于0x12c0时,再把它赋值给Speed_quant。

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

原本,这样的bug不应活过半分钟,成果,由于咱们这个产品是在车厂的实验车上进行验证,实验车的油箱基本上空了,车厂作业人员也不允许咱们开起车来跑,所以,这个判别车速、赋值车速、依据车速主动闭锁的程序分支一向没有得到验证。Bug就这样活过了第一关。

尽管如此,在路试阶段,由于这个bug的存在,加快闭锁功用就失效了。那么,跑车的路试员怎样竟而没有发现这么显着的过错呢?

难路途试员每次开车之前,都会先中控闭锁一下?或许咱们的合作伙伴给车厂送的样件里烧录的竟然不是我给他们的终究一版程序?

实情怎么,已无前史可考了,这桩事情总算成了令我百思不得其解的悬案。只要它的怪异,经常浮现在我的心头,让我在敲代码时更存了一分小心谨慎和战战兢兢。

战战兢兢,如履薄冰,如此,正人可不立于危地。

5

关于一个原始状况的代码,一位好的码农会耐性肠在之上精耕细作,细心肠捉虫,耐性肠上肥,小心肠呵护,一定一无是处,这姿态,才干搞出强健、耐看的果实来,这姿态盘出来的代码才干饱尝住时刻的检测。

相反,有的码农写了一段代码后就把它扔在那里,就好像只管生不论养的无良爸爸妈妈相同,急火火地又去写下一段代码。没有对代码的耐性呵护,缺少对它的修剪、完善,终究,搞出的程序总是既不安稳,又不耐看。

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

不愿意耐性找bug改代码的人,实际上犯的是贪功冒进的过错,总以为突变才干突变,多写代码才干把水平提高上去。其实这种知道十分片面,这种方法也很不行取,对自我才干的提高十分晦气。

由于,只要在一次次的突变中有小的突变,才干终究练成编码神功。每次都敷衍了事,这样的编码阅历就像掰玉米的狗熊相同,一边得到,一边丢掉,到终究其实剩不下多少有用的东西。

不愿意下功夫盘代码,也是一种懒散。好吃懒做是人之通病,所以好的程序猿总是难寻。

对待代码,需求建立不求一无是处、但求心安理得的心态。要细心肠盘,耐性肠盘。

想必,我的阅历也能给我们一些启示:代码一定要耐性肠盘,暗沟里也能翻了船!

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/peixun/114540.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部