0

0

一行代码花了我一个小时来修复

WBOY

WBOY

发布时间:2024-07-11 11:52:16

|

643人浏览过

|

来源于dev.to

转载

https://www.vecteezy.com/vector-art/7591399-inefficiency-time-management-overload-stress-or-burnout-at-work-concept-confused-businessman-and-large-amount-of-work-on-seesaw-comparing-on-seesaw-lying-on-timer-clock

开发者您好。在今天的文章中,我将分享如何花费我一个小时来查找和修复一行代码的故事。让我们开始吧。

该项目最初是在spring boot 2.6.4开发,目前运行在spring boot 3.2.3版本。我将版本升级到了spring boot 3.2.3,因为我遇到了一些问题,这些问题阻碍并延迟了即将推出的功能。我会在另一篇文章中讲述升级之旅。请务必关注以获取有关即将发布的文章的通知。

问题

我在一家新公司开始了我的se之旅,并加入了一个有趣的项目。该项目包含多个调度程序,每个调度程序以不同的时间运行,例如每 10 秒、30 秒、30 分钟等。如果您有此类项目的经验,那么您已经知道发现问题有多么困难。

好吧,让我们直接进入花费我几个小时调试的那行。

public void sendchatrequest(long chatid) {
   chatservice.findchatbyname("demo-chat").orelse(save(new chat("demo-chat")));
   // other codes ommited...
}

你能发现问题吗?

无论聊天是否存在,每次都会调用 save() 方法。这是因为 orelse() 方法急切地求值。另一方面,orelseget() 方法是延迟计算的,只有当optional为空时才会执行。

为了了解它们之间的区别,请在 ide 中执行以下代码并查看日志。

首先,我们将返回空的optional,看看结果会是什么。

public class orelseandorelsegetmethods {

  record chat(string name) {
  }

  class chatservice {
    public optional findchatbyname(string name) {
      return optional.empty();
    }
  }

  private final chatservice chatservice = new chatservice();

  public static void main(string[] args) {
    var main = new orelseandorelsegetmethods();
    main.testorelse();
    system.out.println("*************************");
    main.testorelseget();
  }

  public void testorelse() {
    system.out.println("testing orelse() method");
    chatservice.findchatbyname("demo-chat")
        .orelse(save(new chat("demo-chat")));
  }

  public void testorelseget() {
    system.out.println("testing orelseget() method");
    chatservice.findchatbyname("demo-chat")
        .orelseget(() -> save(new chat("demo-chat")));
  }

  public chat save(chat chat) {
    system.out.println("saving " + chat);
    // saving chat to database
    return chat;
  }
}

上述代码片段的输出如下所示:

testing orelse() method
saving chat[name=demo-chat]
**********
testing orelseget() method
saving chat[name=demo-chat]

正如您在上面看到的,在两个方法(orelse() 和 orelseget())中都执行了 save() 方法。

让我们看看如果optional 不为空会发生什么。

public class orelseandorelsegetmethods {

  record chat(string name) {
  }

  class chatservice {
    public optional findchatbyname(string name) {
      // searching inside db
      var foundedchat = new chat(name);
      return optional.of(foundedchat);
    }
  }

  private final chatservice chatservice = new chatservice();

  public static void main(string[] args) {
    var main = new orelseandorelsegetmethods();
    main.testorelse();
    system.out.println("**********");
    main.testorelseget();
  }

  public void testorelse() {
    system.out.println("testing orelse() method");
    chatservice.findchatbyname("demo-chat")
        .orelse(save(new chat("demo-chat")));
  }

  public void testorelseget() {
    system.out.println("testing orelseget() method");
    chatservice.findchatbyname("demo-chat")
        .orelseget(() -> save(new chat("demo-chat")));
  }

  public chat save(chat chat) {
    system.out.println("saving " + chat);
    // saving chat to database
    return chat;
  }
}

上面的整个代码片段与之前相同,只有第 11 行不同。返回的不是optional.empty(),而是optional.of(foundedchat)。

来看看结果吧

testing orelse() method
saving chat[name=demo-chat]
**********
testing orelseget() method

正如你在输出中看到的,在执行 orelse() 方法时调用了 save() 方法,但是,这并没有发生在 orelseget() 方法上。

ecshop
ecshop

本版本全面兼容php5.6+,并且修复了许多官方程序的低级代码bug。在apache 2.4.17+php5.6.15环境下测试通过,人格保证无毒无木马,仅仅是一名ecshop热爱者心血来潮之作。ecshop编译更新日志:1、加入最新官方补丁。2、修改数据库连接底层为mysqli, 现在完美无缺了。3、再次对所有代码进行细节修复。4、adminers更新至1.1.2, 在线管理数据库的神器。5、测

下载

为什么要花这么多时间来检测和解决问题?

我没有看到一些意外情况,但 20 分钟后我意识到,数据库上的聊天请求比预期的要多。当时是测试环境,当时我的队友正在服务器上工作。但他们告诉我他们那天没有碰服务器上的任何东西。

调试会话开始了,有两件事让我很挣扎。

调度程序太多了。
缺乏日志记录,尤其是发生更改的方法。
为了解决这个问题,我将方法从 orelse() 更改为 orelseget()。

该问题之后项目的改进

第一个改进是将调度程序数量从 5 个减少到 1 个。我观察并发现这些调度程序几乎具有相同的目的,因此可以将它们合并到一个调度程序操作中。另外,其中一篇已过时并立即删除。

第二个改进是在方法中添加了不言自明的日志语句,以方便调试过程。

该问题之后的经验教训

当问题根源找到时,我意识到我已经看了这个类两次但第一次找不到。这是因为我很着急并试图尽快解决问题。然而,这花了我更多的时间来找出问题所在。

下次遇到这种问题的时候,大声读每一行或者自言自语,这样代码就会变得更清晰。

当你开始将上述策略应用到你的工作中时,你会发现很多问题或写得不好的代码。这将使您有优势找到需要重构的地方。

这是上述示例:

- You: Okay, in the first line of the method, it do null checks
- You: if it is null, then return immediately, otherwise
- You: send the method parameter to method findByName()
- You: and findByName() returns Optional. 

你明白这个想法。当你做到以上的时候,不要着急,否则不会有那么大的影响。要有耐心,慢慢来。

文章到此结束,喜欢文章的话别忘了分享和评论哦

如果您有任何疑问,可以通过 linkedin 联系我。

终于在 github 上提供了代码。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

98

2025.08.06

spring boot框架优点
spring boot框架优点

spring boot框架的优点有简化配置、快速开发、内嵌服务器、微服务支持、自动化测试和生态系统支持。本专题为大家提供spring boot相关的文章、下载、课程内容,供大家免费下载体验。

135

2023.09.05

spring框架有哪些
spring框架有哪些

spring框架有Spring Core、Spring MVC、Spring Data、Spring Security、Spring AOP和Spring Boot。详细介绍:1、Spring Core,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度;2、Spring MVC,提供基于模型-视图-控制器的架构,用于开发灵活和可扩展的Web应用程序等。

384

2023.10.12

Java Spring Boot开发
Java Spring Boot开发

本专题围绕 Java 主流开发框架 Spring Boot 展开,系统讲解依赖注入、配置管理、数据访问、RESTful API、微服务架构与安全认证等核心知识,并通过电商平台、博客系统与企业管理系统等项目实战,帮助学员掌握使用 Spring Boot 快速开发高效、稳定的企业级应用。

61

2025.08.19

Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性
Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性

Spring Boot 是一个基于 Spring 框架的 Java 开发框架,它通过 约定优于配置的原则,大幅简化了 Spring 应用的初始搭建、配置和开发过程,让开发者可以快速构建独立的、生产级别的 Spring 应用,无需繁琐的样板配置,通常集成嵌入式服务器(如 Tomcat),提供“开箱即用”的体验,是构建微服务和 Web 应用的流行工具。

11

2025.12.22

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

101

2025.12.24

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

331

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2068

2023.08.14

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.3万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号