paint-brush
如何找到代码中有问题的部分 [第 XXXIV 部分]经过@mcsee
725 讀數
725 讀數

如何找到代码中有问题的部分 [第 XXXIV 部分]

经过 Maximiliano Contieri7m2023/04/07
Read on Terminal Reader

太長; 讀書

它闻起来是因为可能有很多情况可以对其进行编辑或改进。大多数这些气味只是一些可能出错的暗示。因此,它们本身不需要修复……(不过你应该研究一下。) 以前的代码味道你可以在这里找到所有以前的代码味道(第一部分 - XXXIII)。
featured image - 如何找到代码中有问题的部分 [第 XXXIV 部分]
Maximiliano Contieri HackerNoon profile picture

它闻起来是因为可能有很多情况可以对其进行编辑或改进。


大多数这些气味只是一些可能出错的暗示。因此,它们本身不需要固定......(不过你应该调查一下。)

以前的代码味道

您可以在此处找到所有以前的代码味道(第一部分 - XXXIII)。


让我们继续...


Code Smell 166 - 用户界面上的低级错误

致命错误:未捕获错误:在 /var/www/html/query-line.php:78 中找不到类“logs_queries_web”


堆栈跟踪:#0 {main} 在第 718 行的 /var/www/html/query-line.php 中抛出


TL;DR:抓住你的错误。甚至那些你意想不到的。

问题

  • 安全


  • 错误处理


  • 错误记录


  • 糟糕的用户体验

解决方案

  1. 使用顶级处理程序。


  2. 避免偏爱返回码的语言。


  3. 预计数据库和低级错误。

语境

即使在 2022 年,我们也可以看到“严肃”的网站向临时用户显示堆栈或调试信息。

示例代码

错误的

<? Fatal error: Uncaught Error: Class 'MyClass' not found in /nstest/src/Container.php:9

正确的

<? // A user-defined exception handler function function myException($exception) { logError($exception->description()) // We don't show Exception to final users } // Set user-defined exception handler function set_exception_handler("myException");

检测

  • [x]自动

我们可以使用突变测试来模拟问题,看看是否正确处理。

标签

  • 安全

结论

我们需要不断成熟。


我们的解决方案不应该马虎。



我们需要提高我们作为严肃软件工程师的声誉。

关系

Code Smell 72 - 返回代码

更多信息

快速失败

免责声明

代码味道只是我的意见

学分

杰西·奥里科Unsplash上拍摄的照片


我 80% 的问题都是简单的逻辑错误。其余问题的 80% 是指针错误。剩下的问题就很难了。

马克唐纳

软件工程名言


Code Smell 167 - 哈希比较

哈希保证两个对象不同。并不是说它们是一样的。


TL;DR:如果你检查散列,你也应该检查是否相等

问题

解决方案

  1. 检查散列(快),然后检查相等性(慢)

语境

2022 年 10 月 7 日,其中一个较大的区块链不得不暂停。


这个消息令人震惊,因为大多数区块链都是去中心化的。


您可以在此处阅读完整文章:

黑客如何利用代码气味窃取 5.66 亿美元

示例代码

错误的

public class Person { public String name; // Public attributes are another smell @Override public boolean equals(Person anotherPerson) { return name.equals(anotherPerson.name); } @Override public int hashCode() { return (int)(Math.random()*256); } // This is just an example of non-correlation // When using HashMaps we can make a mistake // and guess the object is not present in the collection }

正确的

public class Person { public String name; // Public attributes are another smell @Override public boolean equals(Person anotherPerson) { return name.equals(anotherPerson.name); } @Override public int hashCode() { return name.hashCode(); } // This is just an example of non-correlation }

检测

  • [x]半自动

许多 linter 都有哈希和相等性重新定义的规则。


通过突变测试,我们可以使用相同的哈希来为不同的对象播种并检查我们的测试。

  • 身份
  • 安全

结论

每项性能改进都有其缺点。


缓存和复制是著名的例子。


我们可以(必须)谨慎使用它们。

关系

Code Smell 49 - 缓存

Code Smell 150 - 相等比较

更多信息

平等与哈希

Java 中的哈希码

哈希码与相等

免责声明

代码味道只是我的意见


这会让您的一些读者感到惊讶,但我的主要兴趣不是计算机安全。我主要对编写按预期工作的软件感兴趣。

维茨维内玛

软件工程名言


Code Smell 168 - 未记录的决定

我们需要做一些改变。我们需要弄清楚为什么

TL;DR:对您的设计或实施决策进行声明。

问题

  • 代码注释
  • 缺乏可测试性

解决方案

  1. 明确说明原因。
  2. 将注释转换为方法。

语境

有时我们发现任意规则并不那么容易测试。


如果我们不能编写一个失败的测试,我们需要一个具有出色的声明性名称而不是注释的函数。

示例代码

错误的

// We need to run this process with more memory set_memory("512k) run_process();

正确的

increase_memory_to_avoid_false_positives(); run_process();

检测

  • [x]半自动

这是一种语义气味。


我们可以检测评论并警告我们。

标签

  • 评论

结论

代码是散文。设计决策应该是叙述性的。

关系

Code Smell 05 - 评论滥用者

Code Smell 75 - 方法中的注释

免责声明

代码味道只是我的意见

学分

Goh Rhy YanUnsplash上拍摄的照片


程序和人一样,会变老。我们无法阻止衰老,但我们可以了解其成因、限制其影响并逆转部分损害。

马里奥富斯科

软件工程名言


Code Smell 169 - 粘合方法

不要同时做两件或更多的事情。

TL;DR:尽量在你的方法中保持原子性

问题

  • 耦合代码
  • 更难测试
  • 更难阅读

解决方案

  1. 破解方法

重构

https://maximilianocontieri.com/refactoring-002-extract-method

语境

如果您使用“And”命名一个方法,您可能会错过提取和中断方法的机会。

示例代码

错误的

calculatePrimeFactorsRemoveDuplicatesAndPrintThem() // Three responsibilities

正确的

calculatePrimeFactors(); removeDuplicates(); printNumbers(); // Three different methods // We can test them and reuse them

检测

  • [x]半自动

一些 linters 可以警告我们注意包括术语“和”在内的方法。

标签

  • 耦合

结论

在制定方法时,玩一些橡皮鸭的故事并告诉自己我们做的事情是否正确是非常重要的。

关系

%[ https://maximilianocontieri.com/code-smell-85-and-functions ]

免责声明

代码味道只是我的意见

学分

斯科特·桑克 (Scott Sanker)Unsplash上拍摄的照片


与大多数其他学科一样,学习编程艺术包括首先学习规则,然后学习何时打破规则。

约书亚·布洛赫


Code Smell 170 - 通过功能更改进行重构

发展很棒。重构是惊人的。不要同时做

TL;DR:不要同时进行功能更改和重构。

问题

  • 难以审查解决方案
  • 合并冲突

解决方案

  1. 重构时永远不要改变功能

语境

有时我们检测到需要重构才能进一步开发。


我们是学习专家。


我们应该搁置我们的解决方案。进行重构,并继续我们的解决方案。

示例代码

错误的

getFactorial(n) { return n * getFactorial(n); } // Rename and Change factorial(n) { return n * factorial(n-1); } // This is a very small example // Things go works while dealing with huge code

正确的

getFactorial(n) { return n * getFactorial(n); } // Change getFactorial(n) { return n * getFactorial(n-1); } // Run the tests factorial(n) { return n * factorial(n-1); } // Rename

检测

这是重构的味道。

  • [x]手册

标签

  • 重构

结论

我们应该使用物理令牌。


我们要么处于重构阶段,要么处于开发阶段。

免责声明

代码味道只是我的意见

学分

Dannie JingUnsplash上拍摄的照片


当我研究代码时,重构让我获得更高层次的理解,否则我会错过。那些认为理解式重构是无用的摆弄代码的人并没有意识到他们从来没有看到隐藏在混乱背后的机会。

马丁福勒


即将推出 5 种代码味道……