当前位置: 首页 > 科技观察

程序员最喜欢的9个不良编程习惯

时间:2023-03-21 12:01:07 科技观察

我们以前都做过:趁妈妈不注意偷偷吃糖果,结果导致蛀牙。同样,我们都违反了一些基本的编程规则,并且我们都坚决声明这种行为是不可取的。但是我们只是偷偷地爱上了这些不良的编程习惯。我们对所谓的编程规则嗤之以鼻,输出的代码也很糟糕——但我们还活着。编程之神没有用闪电击中我们,我们的电脑也没有爆炸。事实上,只要我们能编译出代码,客户似乎就很高兴了。那是因为糟糕的编程并不像安装电路或触摸老虎屁股那样直接有害。它也适用于大部分时间。规则通常作为格式的指导或建议,没有必须遵守的硬性规定,也不会导致代码立即死亡。当然,你的代码可能会被嘲笑,人们甚至可能会公开嘲笑你,但这种挑战惯例的行为可以增添一点点颠覆性的快感,哪怕是不经意间。为了使事情变得更加复杂,有时最好打破规则。(我不会告诉一般人!)生成的代码会更清晰,甚至可能更快更简单。规则通常显得过于宽泛,熟练的程序员可以通过打破规则来改进代码。不要告诉你的老板,这对你的编程生涯有很大帮助。以下9种编码习惯,虽然在编程规则中被驳斥,但我们中的许多人还是情不自禁地使用它们。编程习惯一:使用goto使用goto的禁令可以追溯到许多结构化编程工具可用之前的日子。如果程序员想要创建一个循环或跳转到程序的另一部分,他们需要键入goto后跟行号。几年后,编译器团队让程序员使用字符串标签而不是行号。这在当时被认为是一个热门的新功能。有些人认为这会导致“意大利面条代码”。代码变得不可读,也变得难以理解代码的执行路径。丝丝纷乱,缠绵到天涯海角。EdsgerDijkstra多次表示应该禁止该命令。他有一篇妙趣横生的手稿,名为《Goto语句害人不浅》。但绝对分支没问题。这让人纠结。通常,聪明的break和return语句提供了一个非常清晰的语句,说明当时代码在做什么。有时将goto添加到case语句中比更合适的多层嵌套if-then-else块更容易理解。也有反例。AppleSSL堆栈中的“gotofail”安全漏洞就是最好的例子之一。但是,如果我们能够小心地避免case语句和循环的一些尴尬问题,那么我们就可以嵌入良好的绝对转换,使阅读代码的人更容易理解正在发生的事情。我们可以插入break和return语句,让每个人都更干净、更愉快——也许goto的反对者除外。编程习惯2:成功地避免文档我的一个朋友有一个非常精明的老板,他从未写过任何代码,但认为每个特性都必须被文档化。任何不提供评论的程序员都会受到惩罚。于是,我朋友在他的编辑器里接了一个人工智能之类的东西,于是他的每一个功能都有几行“文档”。我的朋友逃脱了,因为精明的老板不够聪明,无法理解这些评论毫无意义。他的代码经常被用作正式文档。我觉得他应该很快就升职了!许多函数方法甚至一些类或多或少都是自文档化的。名称为insertReservation或cancelReservation或deleteAll的函数无需过多解释它们的作用。为函数选择正确的名称通常就足够了。事实上,这比写一个长注释要好,因为函数名可以出现在代码的其他地方。而文件只能静静地留在角落里。自我记录的函数名称改进了它们出现的每个文件。在某些情况下,编写文档甚至会使事情变得更糟。例如,当代码快速变化并且团队疯狂重构时,文档就会出现分歧。代码是这样写的,但是文档还是说明了四五个版本前的情况。这种“过时”的文档通常位于代码的顶部,有人会在此处对代码应该发生的情况进行很好的总结。因此,即使重构团队仔细修改了相关评论,文件顶部的这个“很好的总结”仍然缺失。当代码和文本出现分歧时,注释就毫无价值,甚至会产生误导。在这种情况下,良好的自文档化代码显然会胜出。编程习惯三:一行写太多代码老板在慌乱中突然给团队发了一封恶毒的邮件:为了执行非常严格的风格规定,我们都必须重写我们的代码。最神奇的要求是:每个动作或步骤或子句必须独占一行。您不能使用点语法连续调用函数。分支语句中不能有两个或多个返回布尔值的子句。如果要定义变量,则另起一行。如果您正在进行复杂的计算,则不要使用括号。每个片段也独占一行。他认为他的法令将使调试更容易。就像您单步执行代码一样,调试器会一个接一个地推进操作。这样你就不会卡在某条线上。而且更容易执行。但是这样一来,键盘上的回车键就很烦人了,因为我需要不断地插入行。而且我相信老板可以四处吹嘘他的团队可以编写多少行代码。las,有时在同一行上声明一堆变量会更容易;有时将所有布尔子句放在一起更容易——一切都可以变得更紧凑。这也意味着,我们无需滚动即可在屏幕上看到更多逻辑。更容易阅读意味着更快理解。这就是简单的本质。编程习惯四:不声明类型那些热爱类型化语言的人认为,如果他们为每个变量添加显式数据类型声明,他们可以编写出更好、无错误的代码。花点时间拼写类型可以帮助编译器在代码开始运行之前标记愚蠢的错误。这可能很痛苦,但很有帮助。这是一种主动阻止编程错误的方法。但时代变了。许多较新的编译器非常智能,只需查看代码即可推断出类型。他们来回遍历代码,直到他们确定变量是字符串、整数还是其他东西。如果正在查看的类型没有排队,错误标志将被点亮。所以我们不再需要输入变量的类型。这意味着我们现在可以在代码中省略一些最简单的声明。代码更简洁,读者会猜测for循环中名为i的变量代表一个整数。编程习惯5:不确定的代码有些程序员在编写代码时特别优柔寡断和犹豫不决。值首先存储为字符串,然后解析为整数。然后将其转换回字符串。这是非常低效的,你甚至可以感觉到CPU在咆哮这种浪费负载的行为。聪明的程序员编码速度很快,因为他们预先设计架构以尽量减少转换。他们的代码运行得更快,因为他们有一个好的计划。但是,信不信由你,这种摇摆不定的代码有时是有道理的。比方说,你有一个很棒的库,它在其专有的黑盒子里做着无数聪明的事情。如果库需要字符串数据,您就给它字符串,即使您只是将数据转换为整数。当然,您可以重写所有代码以尽量减少转换,但这需要时间。此外,有时让代码多花一点时间运行也无妨,因为重写代码会占用我们更多的时间。有时,承担此类技术债务比一开始就正确构建它的成本要低。有时,库不是专有代码,而是您以前自己编写的所有代码对您来说是独一无二的。有时再次转换数据比重写库中的所有代码更快。所以,顺其自然,让代码摇摆不定。编程习惯6:编写自己的数据结构有一条标准规则是,程序员不应在完成数据结构课程的第二年编写用于存储数据的代码。基本上我们需要的数据结构都已经写好了,而且代码也经过了很多年的反复测试。它与语言捆绑在一起,而且通常是免费的。您的代码只会产生错误。但是有时候你会发现数据结构库有点慢。有时他们会强迫我们使用标准但错误的代码结构。有时图书馆会迫使我们在使用结构之前重新配置数据。有时库中会包含一些线程锁等所谓的保护功能,但实际上我们的代码并不需要。如果是这种情况,那么我们应该开始编写自己的数据结构。这可能会让你做得更快,做得更多。而且代码会更简洁,因为我们不会包含格式化数据以执行某些功能的冗余代码。编程习惯七:在中间打破循环一个规则制定小组声明每个循环都应该有一个“常量”,这意味着当逻辑语句为真时,循环将一直执行。当常量不能为真时,循环将结束。这是考虑复杂循环的好方法,但它会导致愚蠢的禁令——例如禁止我们在循环中间使用return和break语句。这也包含在禁止goto语句的规则中。理论很好,但通常会导致更复杂的代码。请看下面的简单案例,遍历数组,将找到的元素传给测试函数,返回元素:while(i