编码规范?呵……可能只是一块遮羞的破布而已

李肖遥 2021-08-15 22:10


据说,赵国的首都邯郸的人走路的姿态很好看,动作非常优雅、轻快。
燕国有一个少年听到这个传说,非常羡慕邯郸人,就走了很远的路去赵国,想学习邯郸人走路的方法。刚开始,他整天站在街头,仔细研究每个人走路的姿态,再慢慢模仿他们,可是都没有成功。后来,他想可能是受到过去走路习惯的影响,所以,他决定要忘掉以前走路的方法。从那时候起,他更专心研究邯郸人走路的姿势,不过,再怎么努力他还是学不会,最后他只好放弃。可是,因为他把以前走路的方法忘得一干二净,已经不知道该怎么走路,只好一路爬着回去。
http://www.hydcd.com/cy/gushi/0236hd.htm


不知不觉间,代码也写了二十余载,我已成精了。借着过来人的身份和语气,有一件事情我一直都特别喜欢吐槽:无论过去多少年,中国的嵌入式软件开发者群体似乎一直对一个叫做“编码规范”的东西趋之若鹜,仿佛是什么了不得的武林秘籍,学会了就可以叱咤武林让让人不敢小觑又亦或是什么内功心法,需要每日研读或与它人细细品读交流,以求它日可以参透其中奥秘,从此内力大增,用心跳就可以虐死对手


君不见,曾几何时《某为编程规范》在网上被广泛传抄,互联网时代虽然无法“洛阳纸贵”,却曾经引得某公司的公关部门到处发函让站长们删帖;时过境迁,虽然某为的编程规范也不至于热度全无,但对冠名于国外大厂大公司的编码规范的追捧却已悄然成为当下的热门——仿佛如果说不出自己使用的规范来自哪个大门派,都不好意思跟人家打招呼



可拉倒吧!

在兄弟们浪费太多时间之前,可曾了解过自己苦苦追寻和模仿的究竟是个什么东西?


【编码规范的本质是什么?】


要理解编码规范的本质,其实并不复杂:

  • 编码规范是在一定范围内强制推行的编码习惯;这里的编码习惯通常来自于对团队有控制力的一个或者少数几个人


这里,你会很容易注意到三个关键字:“一定范围”、“强制推行”和“编码习惯”。抓住这三点,编码规范的本质就像“任意不在同一直线上的三点确定一个平面”一样——没得跑了。


首先来说说这个“编码习惯”,其实很好理解,它就是字面意思——一个人写代码时候的某种习惯,高情商叫风格,低情商叫“我就爱这么干,别问我为啥,我要么不知道,要么等我编个理由告诉你”。总之呢,编码习惯带有强烈的主观性、基本上可以认为缺乏强有力的客观依据,在稳定性和一致性方面其实就是水中花镜中月——不能说完全没有,只能说毫无可信度。


不信么?今天你看了一个大牛的代码,觉得:


“哇!好牛逼”,

“大牛这么做一定有什么深意”


然后不自觉的就学着人家的编码规范来了。过了几天,你可能又碰到了另外的大牛,或者是什么明星开源项目……咋说呢……如果用男女关系来形容兄弟们的行为,那就是妥妥的渣男/渣女——没得洗


你跟我说说,哪儿来的稳定性和一致性?还不如先问问“你是谁的粉”比较靠谱。


很多时候,一个程序员自己的编码习惯可能一辈子都没有鲤鱼跃龙门——成为编码规范的机会;但如果有朝一日,你满足了以下两个条件,你的编码习惯就是妥妥的编码规范了:

  1. 拥有了一个完全由自己掌控的团队或者项目;

  2. 拥有了执行决定的强制力;(比如KPI审核,扣工资之类)


此时,只要你乐意,完全可以在“你控制的范围内”“强制”推行你自己的编码习惯——恭喜你,一个只属于你的编码规范就诞生了。


【编码规范的“原罪”】


搞懂了编码规范诞生的原因,接下来很自然的,就要聊一聊伴随编码规范一起诞生的“原罪”了。

要理解什么是编码规范的原罪,首先必须要讲清楚“编码规范”(或者说“遵守编码规范”)的意义。然而,有些东西你非要向字典一样去从正面解释往往非常抽象,但稍微打个比方,就简单明朗了——实际上:

编码规范的作用几乎完全等效于人类自然语言文字中的书法。


简单说,编码习惯就是关于“你如何写字的”,而编码规范就是“一群人所遵守的书法风格”。这么一比方,也许你立马注意到了:

  • 无论是编码规范还是编码习惯,都只跟描述“你写字丑不丑”、“漂不漂亮”的一个“主观性非常强的”、甚至还带有“艺术性玄学”的评价标准有关;


  • 我们日常写代码其实可以类比为写文章,这意味着:

    • 你可以用非常漂亮的手写体写出狗屁不通的文章;

    • 你也可以在赶时间的情况下,用一种只有自己看得懂的方式,快速而高效的写出优秀的作品;

    • 书法除了草书,往往暗示着——费时间;何况草书往往暗示着,除了那几个评论家,普通人基本看不懂。

    • 书法好坏和写文章所需的遣词造句的技法,以及文章整体的修辞、结构安排完全无关。


说的再直白一点:当你在追求“如何写出精修文章时”,追求“书法”,是浅薄的,而且毫无意义的当你在追求如何写出好的程序时,你需要的是数据结构、算法、操作系统、软件工程、设计模式、开发思维之类的知识,而不是关于如何把代码写的多么漂亮,多么“规范”的书法——或者说表面功夫。认真说起来,连这里“怎样算作代码写的规范”,从一开始就只是某几个人的主观概念罢了。

正如景秀文章往往也是用赏心悦目的书法写出来的;注重表面的编码规范也并非是什么大罪大恶需要我们弃之如粪土。要知道这其中区别,就必须要谈一谈编码规范的原罪。

  • 原罪1:肤浅引战的导火索



正如我在之前一篇文章《真刀真枪模块化(1)——一本糊涂账》所提到的那样:

……读懂一段程序,实际上就是要通过死的代码逻辑去反推模块构作者的思维,这是一个逆向过程,这是一个人与人之间用代码进行间接交流的过程,当逻辑本身较为复杂时,显然比将自己的思维直接翻译成程序(重新开发一个)更为困难。

傻孩子,公众号:裸机思维真刀真枪模块化(1)——一本糊涂账

这里,我提到了一个关键的事实——阅读他人代码是非常耗时和困难的。这样的事情无时无刻不在发生:当我们拿到一段代码时,想通过了解它的内容来判断好坏几乎是不可能的——这不光意味着你要花费时间去阅读它,可能你根本不想去阅读,或者根本没有这样的时间去阅读。此时,要想判断一段代码的好坏就只能通过非常表面的东西来进行了——是的,就是看你写的字漂不漂亮。

如果明确知道这是“名人大家”的作品,或是出自某个大厂的作品,事情就变得非常简单:只要学习历来文人是如何在同行面前显示自己学识渊博的方式——花式吹就行了。

如果要评价的对象是同辈的作品,或是某个来源不明的作品,大家就一下开始“审慎起来”,仿佛瞬间化身为严肃的艺术评论家——在严肃而充满理性的批判声中,自己“高超水平”和“恨铁不成钢的惋惜”跃然纸上。


呜呼哀哉,文人相轻,这味儿太冲了。


  • 原罪2:似是而非



前面我们说过,编码规范的本质是编码习惯,编码习惯拥有非常强的主观性,因而缺乏客观标准。然而,这话只说了一半,事实上,并不矛盾的一点是,如果某个编码习惯出自于“较为严谨认真”的人之手,这样的编码习惯也便“主观的”拥有了一定的客观性——这完全是由提出的人的特性而决定的——因此依然是主观的。
这可就头疼了。因为这些“严谨认真”的人,他们在养成编码习惯时,往往的确会有理性的思考,不光能说出所以然,而且似乎可以说服很多人,让大家觉得

“这样做很有道理”
甚至
“不这么做就是错的”

的判断。问题是:
  • 这些“严谨大佬”们做出思考的背景是不同,而人们讨论和传播编码规范的时候往往会丢弃这些背景信息而将其“泛化”——或者说无限制的扩大适用范围;

  • 很多作为某一编码规范规则在背后的支撑逻辑,我们可以说它是“正确的”,但遗憾的是,它的正确“并不意味着其它做法是错的”——事实上,有很多规则所服务的逻辑实际上存在很多“同样正确、且平等的正确的竞争者”。

         


关于这点,其实并不难理解,比如,假设我们想解决一个问题A,那么可能有1,2,3,……很多个解决方案,这些方案中可能会存在一些“同样正确且各有优缺点的”。
从另外一个角度来看,对于一个已知的“规则或者行为”,你往往可以找到不止一种原因和动机去解释它。
所以,结合以上两个方向的例子,我们要明白,很多事情都不是“非黑即白”的,尤其是编码规则的好坏、成因、收益这种极端主观的事情。


  • 编码规范的信徒们,往往视其它规范(甚至是某一个规范的变种)为异端,定要除之而后快,表现为与他人进行无意义的论战、不说服他人加入自己的阵营就决不罢休,甚至上升到人身攻击等等……


  • 原罪3:遮羞布



正因为评价它人代码的阅读代价太高,而凭借“眼缘”去评价它人“字太丑”简单且可行,因此,对很多人来说,追求“书法”而不是具体的“写作文能力”就成了“快速提高代码质量”的捷径——这里的代码质量,很多时候也仅仅只是“是否好看”了……


【C语言编码规范的“甜”和“咸”】


如果书法大家云集流派众多,C语言的编码规范也是有“门派”的,比如大家熟悉的Linux派、微软派……(此处省略1W字)。然而,无论门派多寡,其实都可以在一个“编码规范光谱”中为其找到一席之地。

在光谱的最左边是名为“纯粹追求美观”的极点、在光谱的最右边是名为“纯粹追求功能性”的另一极。实际上如今你所熟悉的编码规范,基本都位于两级中的某一位置。

  • “纯粹追求美观”,顾名思义,代码写出来要眼睛看着舒服。需要特别强调的是,这里的看着舒服与“代码的可读性”完全是两回事。


    纯粹追求美观的杰出代表是Linux编码规范——它所追求的是纯粹小写所带来的那种和谐而统一的美;它基本不对函数、变量名、类型名做任何的区别(甚至是非常数的宏);为了解决小写单词缺乏“节奏”的问题,而在单词与单词之间简单的引入“_”完事。

    这种美学就好比最优质的牛排,只需要辅以简单的海盐,进行简单的烹饪就能发挥牛排最原始的美味;这就好比,新鲜的生蚝,只需要挤上几瓣柠檬就可以释放出最大的鲜甜……


    正是由于Linux这种纯粹追求视觉上的和谐而不“诡辩”自己有如何功能上的便利,受到众多“返璞归真”老鸟的狂热追捧——我要的就是简洁的美,其它都在我心间


  • 纯粹追求功能性”,顾名思义,就是以牺牲一定程度的“美感”而换取某种功能上的便利。实际上,完全牺牲美感的编码规范几乎没有,但很多商用协议栈的编码规范或多或少都有着明确的功能追求。


    典型的是匈牙利变量命名法,它的特点是为每一个变量追加必要的类型信息,从而提高变量名的信息携带量——最终尝试提高代码的可读性。在Linux玩家的眼里,匈牙利是真的丑;同时作为一个如入鲍鱼之肤久而不闻其臭的匈牙利变量命名法玩家,我也只是“习惯了”这种用法,你要说我觉得它有多美,那也绝对是扯淡。有意思的是,匈牙利变量命名法往往会与驼峰命名法搅和在一起,这让纯粹的驼峰信徒颇为不爽——因为驼峰可以说是“美的”,但你非要粘上一些类型标签——就好比在布丁的蜂蜜浇头上发现了苍蝇一样恶心。

    公平的说,匈牙利所附加的信息的确有助于提升代码的可读性。至于美不美,可以完全抛在脑后。


    另外一类“追求功能性”的编码规范就是各类DSP、视频、音频、数学相关的协议栈,它们纯粹为了方便API的使用,尝试在变量、函数以及类型名称上附加大量的信息,以描述API的参数类型、函数所代表的的运算功能、以及其它相关专业方向才会理解的特性属性等等——这样的信息追加,造就了犹如喀斯特地貌一样的奇观——用是好用,美不美,就不好说了。这类协议栈的典型是鼎鼎大名的Dolby的音频库。



对普通人来说,一般我们使用的编码习惯都处于这两级的中间地带,这不光因为很多时候我们同时会有“看着顺眼”和“提供额外信息”这两种追求,更主要的原因是:编码规范的本质是书法,对我们所使用的书法起决定作用的是“审美”,而每个人不同阶段的审美很难保持一成不变。当我们因为工作关系游走于不同的团队而被迫服从的编码规范时,久而久之……如邯郸学步,自己的“初心”可能早就被染成了“别人的颜色”……


【编码规范,怎么做才对?】


知道了编码规范的本质和原罪、讨论了编码规范的两个极端风格,那么我们普通人应该如何对待它呢?

  • 字写的好看,是一种展示“认真态度”的方式;努力写出漂亮的代码无可厚非

  • 切记不可喧宾夺主,在本意是追求“如何写出优秀作文”的时候,注意力过多的被“如何写出漂亮字”的编码规范所抓住,浪费不必要的时间;

  • 不要把编码规范上升成宗教信仰——哪怕你是无意识中这样做的;

  • 记住:优秀的程序员可以在任何编码规范上随意切换——这是你游刃有余的一种表现

  • 如果想讨好一个人,赞扬他的书法;

  • 如果一个群里的人让你讨厌,可以在退群之前,可以故意挑起关于编码规范孰优孰劣的宗教战争——如果碰巧他们都是同一个宗教的信徒,则尝试发起关于“怎样才是正统”的讨论。如果你喜欢一个群,就切记不要这么做。

  • 在自己可控的范围内——比如自己的开源项目里,随意的使用自己的编码规范。如果要跟他人合作,最好写清楚自己的习惯,并且保持包容的心态——因为,请记住:

    • 编码规范的制定者往往会被所有人盯着,等着你的永远是“你自己的规范你自己都没遵守”,而不是“你的规范真好”的赞赏;

    • 对任何你订立的规则,你写下来的只是你心目中的“默认情况”,而没写来的是大量你自己觉得合理的“特殊情况”——在你心中,除了“少数”特殊情况外,我们都应该按照“默认情况”来处理——可惜,这里的“少数”往往超出你的想像;

    • 不要认为别人质疑你的编码规范就是在骂你、质疑你或者找茬——哪怕大部分情况都是这样;

    • 同理,尽可能遵守它人的编码规范,来展示自己对它人的尊重。看到“特例”不妨一笑了之。


  • 干点正事吧!



【说在后面的话】


编码规范展现的是一种“认真的态度”,但它不是“能力和质量”本身。区别你要追求的是“书法的”编码规范,还是“思维的”编码原则。尊重他人从不贬低他人的编码习惯开始;团队合作从严格遵守编码规范开始。不要浪费太多时间,舒服就好。

如果大家感兴趣,后下次我可以简单的介绍一下我所使用的编码习惯,并尝试逐条解释规则背后的原因。


原创不易,

如果你喜欢我的思维、觉得我的文章对你有所启发,

请务必 “点赞、收藏、转发” 三连,这对我很重要!谢谢!


欢迎订阅 裸机思维


李肖遥 公众号“技术让梦想更伟大”,作者:李肖遥,专注嵌入式,只推荐适合你的博文,干货,技术心得,与君共勉。
评论
  • 本文介绍瑞芯微RK3588主板/开发板Android12系统下,APK签名文件生成方法。触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,该开发板是核心板加底板设计,音视频接口、通信接口等各类接口一应俱全,可帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。工具准备下载Keytool-ImportKeyPair工具在源码:build/target/product/security/系统初始签名文件目录中,将以下三个文件拷贝出来:platform.pem;platform.
    Industio_触觉智能 2024-12-12 10:27 68浏览
  • 全球智能电视时代来临这年头若是消费者想随意地从各个通路中选购电视时,不难发现目前市场上的产品都已是具有智能联网功能的智能电视了,可以宣告智能电视的普及时代已到临!Google从2021年开始大力推广Google TV(即原Android TV的升级版),其他各大品牌商也都跟进推出搭载Google TV操作系统的机种,除了Google TV外,LG、Samsung、Panasonic等大厂牌也开发出自家的智能电视平台,可以看出各家业者都一致地看好这块大饼。智能电视的Wi-Fi连线怎么消失了?智能电
    百佳泰测试实验室 2024-12-12 17:33 56浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-12 10:13 40浏览
  • RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。RK3506核心板主要分为三个型号,各型号间的区别如下图:​图 1  RK3506核心板处理器型号场景1:显示HMIRK3506核心板显示接口支持RGB、MIPI、QSPI输出,且支持2D图形加速,轻松运行QT、LVGL等GUI,最快3S内开
    万象奥科 2024-12-11 15:42 88浏览
  • 铁氧体芯片是一种基于铁氧体磁性材料制成的芯片,在通信、传感器、储能等领域有着广泛的应用。铁氧体磁性材料能够通过外加磁场调控其导电性质和反射性质,因此在信号处理和传感器技术方面有着独特的优势。以下是对半导体划片机在铁氧体划切领域应用的详细阐述: 一、半导体划片机的工作原理与特点半导体划片机是一种使用刀片或通过激光等方式高精度切割被加工物的装置,是半导体后道封测中晶圆切割和WLP切割环节的关键设备。它结合了水气电、空气静压高速主轴、精密机械传动、传感器及自动化控制等先进技术,具有高精度、高
    博捷芯划片机 2024-12-12 09:16 85浏览
  • 时源芯微——RE超标整机定位与解决详细流程一、 初步测量与问题确认使用专业的电磁辐射测量设备,对整机的辐射发射进行精确测量。确认是否存在RE超标问题,并记录超标频段和幅度。二、电缆检查与处理若存在信号电缆:步骤一:拔掉所有信号电缆,仅保留电源线,再次测量整机的辐射发射。若测量合格:判定问题出在信号电缆上,可能是电缆的共模电流导致。逐一连接信号电缆,每次连接后测量,定位具体哪根电缆或接口导致超标。对问题电缆进行处理,如加共模扼流圈、滤波器,或优化电缆布局和屏蔽。重新连接所有电缆,再次测量
    时源芯微 2024-12-11 17:11 109浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-11 17:58 86浏览
  • 一、SAE J1939协议概述SAE J1939协议是由美国汽车工程师协会(SAE,Society of Automotive Engineers)定义的一种用于重型车辆和工业设备中的通信协议,主要应用于车辆和设备之间的实时数据交换。J1939基于CAN(Controller Area Network)总线技术,使用29bit的扩展标识符和扩展数据帧,CAN通信速率为250Kbps,用于车载电子控制单元(ECU)之间的通信和控制。小北同学在之前也对J1939协议做过扫盲科普【科普系列】SAE J
    北汇信息 2024-12-11 15:45 113浏览
  • 应用环境与极具挑战性的测试需求在服务器制造领域里,系统整合测试(System Integration Test;SIT)是确保产品质量和性能的关键步骤。随着服务器系统的复杂性不断提升,包括:多种硬件组件、操作系统、虚拟化平台以及各种应用程序和服务的整合,服务器制造商面临着更有挑战性的测试需求。这些挑战主要体现在以下五个方面:1. 硬件和软件的高度整合:现代服务器通常包括多个处理器、内存模块、储存设备和网络接口。这些硬件组件必须与操作系统及应用软件无缝整合。SIT测试可以帮助制造商确保这些不同组件
    百佳泰测试实验室 2024-12-12 17:45 63浏览
  • 在智能化技术快速发展当下,图像数据的采集与处理逐渐成为自动驾驶、工业等领域的一项关键技术。高质量的图像数据采集与算法集成测试都是确保系统性能和可靠性的关键。随着技术的不断进步,对于图像数据的采集、处理和分析的需求日益增长,这不仅要求我们拥有高性能的相机硬件,还要求我们能够高效地集成和测试各种算法。我们探索了一种多源相机数据采集与算法集成测试方案,能够满足不同应用场景下对图像采集和算法测试的多样化需求,确保数据的准确性和算法的有效性。一、相机组成相机一般由镜头(Lens),图像传感器(Image
    康谋 2024-12-12 09:45 75浏览
  • 天问Block和Mixly是两个不同的编程工具,分别在单片机开发和教育编程领域有各自的应用。以下是对它们的详细比较: 基本定义 天问Block:天问Block是一个基于区块链技术的数字身份验证和数据交换平台。它的目标是为用户提供一个安全、去中心化、可信任的数字身份验证和数据交换解决方案。 Mixly:Mixly是一款由北京师范大学教育学部创客教育实验室开发的图形化编程软件,旨在为初学者提供一个易于学习和使用的Arduino编程环境。 主要功能 天问Block:支持STC全系列8位单片机,32位
    丙丁先生 2024-12-11 13:15 66浏览
  • 首先在gitee上打个广告:ad5d2f3b647444a88b6f7f9555fd681f.mp4 · 丙丁先生/香河英茂工作室中国 - Gitee.com丙丁先生 (mr-bingding) - Gitee.com2024年对我来说是充满挑战和机遇的一年。在这一年里,我不仅进行了多个开发板的测评,还尝试了多种不同的项目和技术。今天,我想分享一下这一年的故事,希望能给大家带来一些启发和乐趣。 年初的时候,我开始对各种开发板进行测评。从STM32WBA55CG到瑞萨、平头哥和平海的开发板,我都
    丙丁先生 2024-12-11 20:14 73浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦