程序员如何做事更细致?

最近在工作中老是犯一些小错误,哦,当然也不是最近了,其实我一直是个马虎的人,我很讨厌做一些细活,因为这会让我反复改动多次在会成功,而平时的代码由于有debug,即便出错了,再改回来即可,但是,很多时候并没有我们想的那么容易,趁着周末,我写下了这篇总结,希望也能帮助到大家。

文章目录

  • 1. 需求有没有问清楚?
    • 1.1 多做记录
  • 2. 反复太多
    • 2.1 单元测试
    • 2.2 自测-交叉验证
  • 3. 基础不牢
    • 3.1 常见错误
  • 4. 不守规矩
    • 4.1 事故
  • 5. 慢就是快

1. 需求有没有问清楚?

我们在开发过程中,一个大忌就是需求都没搞清楚,为了能够更快的完成任务,直接上手写代码,没准写到一半发现需求有问题,或者是之前自己没理解好,导致最终出了问题。
在这里插入图片描述

1.1 多做记录

我的建议是,养成记录工作的好习惯,我一般是以导图的形式做一个梳理,比如下图这样子,里面也包含了我周末想做的事,重点关注最后一条即可。

在这里插入图片描述

  • 需求地址:方便我们快速定位到这个需求具体要我们做什么。
  • 思路:大致写下思路,如果你的思路不清晰,写代码一定会被卡住。
  • 伪代码:先用伪代码的形式写一遍,很多东西可以精简下,这样的好处是,会提前碰到那些我们没考虑到的地方。
  • 问题:开发一定会遇到问题,可以在这里做个记录。
  • 代码位置:这是为了便于我们后期有了bug快速定位。
  • 接口请求:可以和下面的测试用例一起用,可以快速debug。
  • 提交记录:为了更快的追踪之前提交的记录,建议复制版本号,因为在idea中如果出现分支合并,很容易找不到提交的记录。

这里不仅包含了写代码前的一些准备工作,也包含了一些开发的小技巧,思路,总的来说就是多记录,当事物繁多时就能体会到好处了。

2. 反复太多

2.1 单元测试

这里的反复是指,明明开发完成了,测试或者上线又出bug了,我们自我测试是必不可少的,推荐自己的代码使用单元测试跑一下,但我知道很多情况下是做不到的,因为公司代码太繁杂了,测试不一定好跑,所以只是做个小小的推荐,这里推荐使用mocktio框架,它可以以插桩的形式将某些service注入进来,完成虚假的调用,我们只需关注自己想关注的部分即可。
在这里插入图片描述

代码示例如下。

service代码

public class UserRepository {public User findUserById(String userId) {// 数据库逻辑,这里为了简单省略return null;}
}public class UserService {private UserRepository userRepository;public UserService(UserRepository userRepository) {this.userRepository = userRepository;}public User getUserById(String userId) {return userRepository.findUserById(userId);}
}

测试代码

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;public class UserServiceTest {@Testpublic void testGetUserById() {// 创建模拟对象UserRepository mockRepository = mock(UserRepository.class);// 设置模拟行为when(mockRepository.findUserById("123")).thenReturn(new User("123", "Test User"));// 使用模拟对象创建UserService实例UserService userService = new UserService(mockRepository);// 调用UserService的方法并断言结果User result = userService.getUserById("123");assertNotNull(result);assertEquals("123", result.getId());assertEquals("Test User", result.getName());// 验证模拟对象的方法是否被调用verify(mockRepository).findUserById("123");}
}

2.2 自测-交叉验证

上面的例子很简单,但很多情况下我们求快或者实在搞不了单元测试,那么只能自测了,如果之前写了伪代码,那么将会减少出错的可能性,但这还不够。

这里我是从吴军老师那学到的方法,就是交叉验证,即便我们debug跑下觉得没什么问题,我们也还是应该掌握逆向思维,通过结果,反推值,看是否没问题。

3. 基础不牢

很多时候我们犯错,其实是因为基础不牢导致的,比如下面一些例子,我们就应该警惕。

在这里插入图片描述

3.1 常见错误

  1. 空指针异常(NullPointerException):
    当试图使用一个未初始化(null)的对象时,就会抛出空指针异常。例如,尝试调用一个未实例化对象的方法或访问其属性。

  2. BigDecimal使用浮点数构造器:
    使用new BigDecimal(double)构造函数时,可能不会得到预期的精确值,因为double本身可能无法精确表示。正确的做法是使用字符串构造器,如new BigDecimal("0.1")

  3. 数组越界(ArrayIndexOutOfBoundsException):
    尝试访问数组中不存在的索引时,会抛出数组越界异常。例如,访问长度为5的数组的第6个元素。

  4. 类转换异常(ClassCastException):
    将对象强制类型转换为不兼容类型时,将抛出类转换异常。

  5. 并发修改异常(ConcurrentModificationException):
    在迭代集合时(如使用for-each循环),如果同时对集合进行结构性修改(添加、删除元素),则可能抛出此异常。

  6. String比较使用
    使用
    来比较字符串,这实际上比较的是对象引用,而不是字符串的内容。应该使用.equals()方法来比较字符串的内容。

  7. 忽视了基本类型和包装类之间的区别:
    例如,int和Integer的区别,其中Integer是可以为null的,而int是有默认值0的基本类型。

  8. 不正确的异常处理:
    异常处理不当,如使用空的catch块或仅打印堆栈跟踪而不进行适当处理。

  9. 忽视了Java集合框架中的线程安全问题:
    如在多线程环境下使用非线程安全的集合,如ArrayList和HashMap,而不是线程安全的版本,如Vector或ConcurrentHashMap。

  10. 资源泄露:
    在使用资源(如流、数据库连接等)后没有正确关闭,可能导致资源泄露。

4. 不守规矩

我们会因为自己的熟练,而过度自信,导致一些代码觉得太简单了,肯定不会出问题,最终出现了bug。
或者是自我觉得经验还可以,不听他人的劝告,做一些自认为对的事情,但最终却发现自己走入了一个误区,一开始自己想错了。

这里主要是想给大家提个醒,我们在深入专业的同时,也要保留一份怀疑,开放的态度去听取,挖掘更多的可能性。 下面是一些因为编程不规范导致的事故。

4.1 事故

在这里插入图片描述

  1. Knight Capital Group的交易系统故障(2012年):
    Knight Capital Group由于软件部署错误,导致其交易算法失控。一个旧的、未使用的软件功能被意外地激活,导致公司在不到一小时内损失了约4.4亿美元。这个事件突显了代码管理和部署过程中严格遵守规范的重要性。

  2. Ariane 5 Flight 501失败(1996年):
    欧洲空间局的Ariane 5火箭在首次飞行中因为软件异常而解体。问题源自于64位浮点数在转换为16位整数时未能适当处理溢出。这个错误表明了代码重用时需要考虑上下文的重要性,以及进行充分测试的必要性。

  3. Heartbleed漏洞(2014年):
    OpenSSL的一个严重漏洞,由于未正确检查网络输入的长度,导致攻击者可以读取内存中的敏感数据。这个漏洞凸显了输入验证的重要性以及在安全相关代码中遵守最佳实践的必要性。

  4. Therac-25事故(1985-1987年):
    Therac-25是一台辐射治疗机,由于软件错误,导致至少六名患者接受了过量的辐射。软件的设计和编码错误,包括竞争条件和不充分的安全检查,是导致这些事故的主要原因。

5. 慢就是快

这也是最近才感悟到的东西,很多需求急着上线,但因为没有经过充分的测试,或者是因为时间太赶,代码滥竽充数,cv大法,只为了完成某个功能,看似进度很快,后期又是不停的改bug。

另外一点是最近学习的感悟,我们很容易夸下海口,说我要在一个月完成什么什么事,比如学习完某个课程,或者在新一年的目标中,定下了许许多多想要完成的事,但大多都不了了之。

在这里插入图片描述

为什么会这样呢?

首先一点就是贪,人总是想要事情做的又快又好,想要知识到了我们脑中就能立刻转化为经验,技能,赚到钱。

但现实不是游戏,很多生活中的大改变往往是每日里的点滴努力汇聚而成的,所以不要有急于求成的心态,只想着每天做一点小改变,就像我前面导图中写到的,周末学一节操作系统,不需要多,平时忙的花就花个10分钟看下视频,即便是躺在床上也能完成,稍微做下笔记。

只要这件事情的进度在往前,那么总能够完成的,如果觉得事情太困难了,不仿切割成一个个的子任务,日积月累,总能够有所成效的。

生命中这些不经意的时刻,最后你付出的点点努力,就像遗失在生命中各个角落的弹珠,有一天突然来了一根线,这些弹珠都被连了起来,你突然发现原来它们不是散落的,它们是一条真正的银河。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/197576.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于STC12C5A60S2系列1T 8051单片的模数芯片ADC0809实现模数转换应用

基于STC12C5A60S2系列1T 8051单片的模数芯片ADC0809实现模数转换应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍模数芯片ADC0809介绍通过模数芯片ADC0809把电压模…

Java Swing商品信息查询系统

内容要求 1) 本次程序设计是专门针对 Java 课程的,要求使用 Java 语言进行具有一定代码量的程序开发。程序的设计要结合一定的算法,在进行代码编写前要能够设计好自己的算法。 2)本次程序设计涉及到 Java 的基本语法,即课堂上所…

redis高级案列case

案列一 双写一致性 案例二 双锁策略 package com.redis.redis01.service;import com.redis.redis01.bean.RedisBs; import com.redis.redis01.mapper.RedisBsMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; imp…

基于STC12C5A60S2系列1T 8051单片机的模数芯片ADC0832实现模数转换应用

基于STC12C5A60S2系列1T 8051单片的模数芯片ADC0832实现模数转换应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍模数芯片ADC0832介绍通过模数芯片ADC0832把电压模…

【python】OpenCV—Rectangle, Circle, Selective Search(1.2)

文章目录 1 画框画圈1.1 画矩形框1.2 画圆 / 点1.3 椭圆 2 Selective Search3 Resize 1 画框画圈 1.1 画矩形框 # Copy the image img_rgb_copy img_rgb.copy()# Draw a rectangle cv2.rectangle(img_rgb_copy, pt1 (405, 90), pt2 (740, 510),color (255, 0, 0), thickne…

4种经典的限流算法

0、基础知识 1000毫秒内,允许2个请求,其他请求全部拒绝。 不拒绝就可能往db打请求,把db干爆~ interval 1000 rate 2; 一、固定窗口限流 固定窗口限流算法(Fixed Window Rate Limiting Algorithm)是…

文件传输客户端 SecureFX mac中文版支持多种协议

SecureFX mac是一款功能强大的文件传输客户端,可在 Mac 操作系统上使用。它由 VanDyke Software 公司开发,旨在为用户提供安全、可靠、高效的文件传输服务。 SecureFX 支持多种协议,包括 SFTP、SCP、FTP、FTP over SSL/TLS 和 HTTP/S。它使用…

支持4KHz回报还能无线充电,简约不简单的雷柏VT3S游戏鼠标上手

这两年国产鼠标的表现很让人惊喜,不仅外观做工越来越精细,配置也越来越强大,当然价格依然亲民。现在很容易找到一款搭载高端传感器、响应速度快、电池续航时间长,并且还支持无线充电的全能型鼠标。 我之前用雷柏的鼠标比较多&…

Transformer ZOO

Natural Language Processing Transformer:Attention is all you need URL(46589)2017.6 提出Attention机制可以替代卷积框架。引入Position Encoding,用来为序列添加前后文关系。注意力机制中包含了全局信息自注意力机制在建模序列数据中的长期依赖关系方面表现出…

vue项目本地开发完成后部署到服务器后报404

vue项目本地开发完成后部署到服务器后报404是什么原因呢? 一、如何部署 前后端分离开发模式下,前后端是独立布署的,前端只需要将最后的构建物上传至目标服务器的web容器指定的静态目录下即可 我们知道vue项目在构建后,是生成一系…

统信UOS通过源码安装软件提示“configure: error: cannot run C compiled programs.”错误

1. 问题说明 使用源码的方式安装git软件,安装过程中出现两个错误。 编译错误“cannot run C compiled programs” XC:~/Downloads/git-2.42.1$ ./configure --prefix/home/software/git-2.42.1 configure: Setting lib to lib (the default) configure: Will try…

计算机组成原理-双端口RAM和多模块存储器

文章目录 存取周期总览双端口RAM多体并行存储器低地址交叉编址有多少个存储体合适(体号)多模块存储器(多体存储器)总结实际场景 存取周期 总览 双端口RAM RAM:用于主存或高速缓存,断电数据丢失 多体并行…

C++ 运算符重载详解

本篇内容来源于对c课堂上学习内容的记录 通过定义函数实现任意数据类型的运算 假设我们定义了一个复数类&#xff0c;想要实现两个复数的相加肯定不能直接使用“”运算符&#xff0c;我们可以通过自定义一个函数来实现这个功能&#xff1a; #include <iostream> using…

宠物信息服务预约小程序的效果如何

宠物的作用越来越重要&#xff0c;因此铲屎官们对自己爱宠的照顾也是加倍提升&#xff0c;而市场围绕宠物展开的细分服务近些年来逐渐增多&#xff0c;且市场规模快速增长。涉及之广&#xff0c;涵盖宠物衣食住行、医疗、美容、婚丧嫁娶等&#xff0c;各品牌争相抢夺客户及抢占…

代码随想录算法训练营|五十六天

回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; dp含义&#xff1a;表示区间内[i,j]是否有回文子串&#xff0c;有true&#xff0c;没有false。 递推公式&#xff1a;当s[i]和s[j]不相等&#xff0c;false&#xff1b;相等时&#xff0c;情况一&#xff0c;…

中国电影票房排行数据爬取及分析可视化

大家好&#xff0c;我是带我去滑雪&#xff01; 对中国电影票房排行数据的爬取和分析可视化具有多方面的用处&#xff1a;例如了解电影市场的历史趋势&#xff0c;包括不同类型电影的受欢迎程度、票房的季节性波动。识别观众对于不同类型电影的偏好&#xff0c;为电影制片方提供…

高效背单词——单词APP安利

大英赛&#xff0c;CET四六级&#xff0c;以及考研英语&#xff0c;都在不远的未来再度来临&#xff0c;年复一年的考试不曾停息&#xff0c;想要取得好成绩&#xff0c;需要我们的重视并赋予相应的努力。对于应试英语&#xff0c;词汇量是不可忽略的硬性要求。相比于传统默写&…

快速集成Skywalking 9(Windows系统、JavaAgent、Logback)

目录 一、Skywalking简介二、下载Skywalking服务端三、安装Skywalking服务端3.1 解压安装包3.2 启动Skywalking 四、关于Skywalking服务端更多配置五、Java应用集成skywalking-agent.jar5.1 下载SkyWalking Java Agent5.2 集成JavaAgent5.3 Logback集成Skywalking5.4 集成效果 …

flutter web 中嵌入一个html

介绍 flutter web 支持使用 HtmlElementView嵌入html import dart:html; import dart:ui as ui; import package:flutter/cupertino.dart;class WebWidget extends StatelessWidget {const WebWidget({super.key});overrideWidget build(BuildContext context) {DivElement fr…

【diffuser系列】ControlNet

ControlNet: TL;DRControl TypeStableDiffusionControlNetPipeline1. Canny ControlNet1.1 模型与数据加载1.2 模型推理1.3 DreamBooth微调 2. Pose ControlNet2.1 数据和模型加载2.2 模型推理 ControlNet: TL;DR ControlNet 是在 Lvmin Zhang 和 Maneesh Agrawala 的 Adding …