这16个好习惯,可以减少80%非业务的bug!(上)

发表于:2021-3-10 09:22

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Zmmzzz    来源:CSDN

  前言:
  每一个好习惯都是一笔财富,本文整理了写代码的16个好习惯,每个都很经典,养成这些习惯,可以规避多数非业务的bug!希望对大家有帮助哈,谢谢阅读,加油哦~
  1. 修改完代码,记得自测一下
  「改完代码,自测一下」 是每位程序员必备的基本素养。尤其不要抱有这种侥幸「心理:我只是改了一个变量或者我只改了一行配置代码,不用自测了」。改完代码,尽量要求自己都去测试一下哈,可以规避很多不必要bug的。
  2. 方法入参尽量都检验
  入参校验也是每个程序员必备的基本素养。你的方法处理,「必须先校验参数」。比如入参是否允许为空,入参长度是否符合你的预期长度。这个尽量养成习惯吧,很多「低级bug」都是「不校验参数」导致的。
  3. 修改老接口的时候,思考接口的兼容性。
  很多bug都是因为修改了对外老接口,但是却「不做兼容导致」的。关键这个问题多数是比较严重的,可能直接导致系统发版失败的。新手程序员很容易犯这个错误哦~
  所以,如果你的需求是在原来接口上修改,,尤其这个接口是对外提供服务的话,一定要考虑接口兼容。举个例子吧,比如dubbo接口,原本是只接收A,B参数,现在你加了一个参数C,就可以考虑这样处理。
  //老接口
  void oldService(A,B);{
    //兼容新接口,传个null代替C
    newService(A,B,null);
  }
  //新接口,暂时不能删掉老接口,需要做兼容。
  void newService(A,B,C);
  4.对于复杂的代码逻辑,添加清楚的注释
  写代码的时候,是没有必要写太多的注释的,好的方法变量命名就是最好的注释。但是,如果是「业务逻辑很复杂的代码」,真的非常有必要写「清楚注释」。清楚的注释,更有利于后面的维护。
  5. 使用完IO资源流,需要关闭
  应该大家都有过这样的经历,windows系统桌面如果「打开太多文件」或者系统软件,就会觉得电脑很卡。当然,我们linux服务器也一样,平时操作文件,或者数据库连接,IO资源流如果没关闭,那么这个IO资源就会被它占着,这样别人就没有办法用了,这就造成「资源浪费」!
  所以使用完IO流,可以使用finally关闭哈~
  FileInputStream fdIn = null;
  try {
      fdIn = new FileInputStream(new File("/jay.txt"));
  } catch (FileNotFoundException e) {
      log.error(e);
  } catch (IOException e) {
      log.error(e);
  }finally {
      try {
          if (fdIn != null) {
              fdIn.close();
          }
      } catch (IOException e) {
          log.error(e);
      }
  }
  JDK 7 之后还有更帅的关闭流写法,「try-with-resource」。
  try (FileInputStream inputStream = new FileInputStream(new File("jay.txt")) {
      // use resources   
  } catch (FileNotFoundException e) {
      log.error(e);
  } catch (IOException e) {
      log.error(e);
  }
  6.代码采取措施避免运行时错误(如数组边界溢出,被零除等)
  日常开发中,我们需要采取措施规避「数组边界溢出,被零整除,空指针」等运行时错误。
  类似代码比较常见:
  String name = list.get(1).getName(); //list可能越界,因为不一定有2个元素哈
  所以,应该「采取措施,预防一下数组边界溢出」,正例:
  if(CollectionsUtil.isNotEmpty(list)&& list.size()>1){
    String name = list.get(1).getName(); 
  }
  7.尽量不在循环里远程调用、或者数据库操作,优先考虑批量进行。
  远程操作或者数据库操作都是「比较耗网络、IO资源」的,所以尽量不在循环里远程调用、不在循环里操作数据库,能「批量一次性查回来尽量不要循环多次去查」。(但是呢,也不要一次性查太多数据哈,要分批500一次酱紫)。
  正例:
  remoteBatchQuery(param);
  反例:
  for(int i=0;i<n;i++){
    remoteSingleQuery(param)
  }
  8.写完代码,脑洞一下多线程执行会怎样,注意并发一致性问题
  我们经常见的一些业务场景,就是先查下有没有记录,再进行对应的操作(比如修改)。但是呢,(查询+修改)合在一起不是原子操作哦,脑洞下多线程,就会发现有问题了。
  反例如下:
  if(isAvailable(ticketId){ 
      1、给现金增加操作 
      2、deleteTicketById(ticketId) 
  }else{ 
      return "没有可用现金券";
  }
  为了更容易理解它,看这个流程图吧:
  1.线程A加现金
  2.线程B加现金
  3.线程A删除票标志
  4.线程B删除票标志
  显然这样存在「并发问题」,正例应该「利用数据库删除操作的原子性」,如下:
  if(deleteAvailableTicketById(ticketId) == 1){ 
      1、给现金增加操作 
  }else{ 
      return “没有可用现金券” 
  }
  因此,这个习惯也是要有的,「写完代码,自己想下多线程执行,是否会存在并发一致性问题」。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号