工作三年后, 我作为Java后端开发的一些心得

这篇具有很好参考价值的文章主要介绍了工作三年后, 我作为Java后端开发的一些心得。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

工作三年后, 我作为Java后端开发的一些心得

关于开发

敢于和善于使用package

  • 对于Java后端开发来讲, 在长时间的web开发中. 大家已经熟悉了MVC架构, 也被这套结构所束缚. 导致创建出来的包也一直都是controller, manager, service, dao. 也将各种各样的类文件都放入其中. 这并不是一种好的做法.
  • 其实我们可以大胆的创建相关的package, 只要让结构更合理, 可读性更高.
  • 比如可以把对接前端的类写到request, response包; 把一些处理器提取出来放到handler中, 把一些定时任务放到schedule包; 把参数构造相关的放到generator; 把校验相关的放到validator下等等.

合理的提取业务逻辑, 让方法只做和它相关的事情.

  • 不知道大家是否看到过下面这种代码. 例如在一个单据的创建方法中, 做一系列的事情, 比如一坨校验参数逻辑, 一堆取价逻辑, 一堆扣减库存逻辑, 再加上创建单据本身的逻辑. 写下来一个方法上百行不止.

  • public class OrderManager {
    
      @Autowired 
      private OrderService orderService;
    
      public String createOrder(Request request){
        // 1. 检查单据创建参数是否合法
        if(Objects.isNull(request)) {
          throw ....;
        }
        if(CollectionUtils.isEmpty(request.getGoodsList())){
          throw ...;
        }
        ... 
    
        // 获取商品的价格
        List<Goods> goodsList = request.getGoods();
        goodsList.forEach(goods -> {
          // 查询商品价格
    
          // 校验价格
          
          // 对价格进行填充
          
        });
         
        // 构造单据逻辑
        
        // 创建单据
    
        return orderCode;
      }
    } 
    
  • 这个方法里做的事, 没有多余的事情, 但是没有合理的进行业务逻辑的提取. 导致代码看起来非常的杂乱.我们可以对一些业务逻辑做提取封装. 来的到更好的可读性和解耦. 这只是一个简单的例子, 在复杂的业务逻辑里更需要合理提取, 否则屎山就出现了.

  • public class OrderManager {
    
      @Autowired 
      private OrderService orderService;
    
      @Autowired
      private OrderValidator orderValidator;
    
      @Autowired
      private OrderGenerator orderGenerator;
      
      @Autowired
      private PriceService priceService;
    
      @Autowired
      private InventoryService inventoryService;
    
      public String createOrder(Request request){
        // 1. 检查单据创建参数是否合法
        this.orderValidator(request);
    
        // 获取商品的价格
        this.priceService(request.getGoods());
         
        // 构造单据逻辑
        Order order = this.orderGenerator.generator(request);
        
        // 创建单据
        this.orderService.create(order);
        return order.getOrderCode();
      }
    } 
    

合理的方法命名和方法定义

  • 方法名的定义很令人苦恼, 常常思前想后想不到好名字. 我曾经因为方法命名不好, 被疯狂的comments

  • 方法命名的好坏受个人主观影响, 所以只说几个共同点:

    1. 言简意赅 准确表达方法内容
    2. 方法名与方法内容匹配
    3. 尽量别生僻单词…
  • 对于方法的参数, 参数过多的时候, 对方法进行拆解或者抽象出对象去传参:

  • // 错误的案例
    public int setParam(int xxx, String xxx, String xxx, String xxx, String xxx, int xxx, String xxx, String xxx){
      ... 
    }
    
    // 合理的写法
    public int setParam(XxxRequest request) {
    
    }
    

控制方法的圈复杂度, 让代码更有层次感

  • 我一直觉得, 好的代码读起来应该像故事一样, 有前因, 有后果, 中间娓娓道来. 简单举个例子, 我们可能会遇到在方法中去for循环处理数据的情况. 比如在一个方法中, 套了三层循环.

  • List<String> orderCodeList = request.getOrderCodes();
    
    // 第一层循环
    for(String orderCode : orderCodeList){
    
      // 查询单号对应的单据明细
      List<OrderItem> items = this.orderItemService.getByCode(orderCode);
      // 第二层循环
      for(OrderItem item : items) {
        // 执行操作1
        // 执行操作2
        // 执行操作3
        
        // 第三层循环
        for()
      }
    }
    
  • 可以把每一层for循环都提取出来, 成为单独的一个方法, 来降低圈复杂度, 提高可读性

  • List<String> orderCodeList = request.getOrderCodes();
    
    // 第一层循环
    for(String orderCode : orderCodeList){
      this.processSingleOrder(orderCode);
    }
    
    public void processSingleOrder(String orderCode){
      // 查询单号对应的单据明细
      List<OrderItem> items = this.orderItemService.getByCode(orderCode);
      this.processItemsData(items);
    }
    
    public void processItemsData(){
      for(OrderItem item : items) {
        // 执行操作1
        // 执行操作2
        // 执行操作3
      }
    }
    

不知道的知识可以去问问Google, 不要自己编

  • 不知道标题是否贴切, 但是大家看了例子就会明白我的意思.

  • 其中最为典型的例子我认为 是对Obejct和集合的判空 和 创建集合

  • // 对于判断, 很多人喜欢这样写
    if( list == null || list.size == 0) 
    或者 
    if(order == null)
    
    // 对于创建集合, 去创建空集合, 再添加
    List<String> list = new ArrList();
    list.add("xxx");
    list.add("bbb");
    
  • 其实只要我们Google以下, Java下如何对集合判空, 就能看到apache.commons 或者google.common等很多类库已经包含这些内容, 并且实现的更严谨, 更优美. 要请善于使用搜索引擎去填补自己不了解的知识.

  • CollectionUtils.isEmpty(list);
    
    List<String> list = Lists.newArrayList("xxx", "bbb");
    

不要for循环请求数据库和外部系统接口

  • 慢请求的分析, 可能不需要要先去看有没有复杂的关联查询, 或者是不是数据库查询有没有命中索引, 而是先去看是不是有大哥在for循环去请求数据库和dubbo接口. 循环了1w次. 我曾经遇到过多次请求超时都是因为有人在代码里for循环去select , update.
  • 对于这种问题的解决, 将循环调用改成单次的批量接口就可以解决问题. 对于mysql的化in操作就可以解决, 对于外部系统对接的, 双方提供批量接口就可以了.

没有意义的注释不要写

  • 我很反感在类上要先写上 @Author @Date @Description 一大串内容表明这是你的杰作, 这不是JDK 也不是什么开源项目!!! 除了你和你的同事没人去看.

  • 再或者像下面这样在方法上直白翻译了一堆废话, 注释不是这么用的…

  • /**
     * 查询用户名称
     *
     * @Param name:用户名
     * @Return 用户
     */
    public User getByName(String name);
    

不要忽视UnitTest

  • 写过单元测试的会发现, 编写完善的单元测试会占用大量的时间, 一般都会超过需求的开发时间, 但是我还是认为单元测试是必须且重要的. 因为作为研发人员, 才是最了解代码中哪里容易出问题的. 更容易写出发现问题的测试用例. 并且代码迭代或者修改后, 也能更快速的发现问题, 将问题停留在研发阶段去解决, 提高整体的进度.

善于使用AI编程工具

  • 在我使用了Github copilot和ChatGPT半年后, 我发现我的摸鱼时间变多了… 因为AI编程工具帮我完成了一定量的工作. 例如最常用的代码补全, 代码自动生成, 自动生成单元测试等等
  • 在当今, 熟练掌握AI编程工具, 是提高自己工作效率的极佳的方法. 在未来, AI也一定会代替掉一部分程序员的工作.
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ONbgJ6nV-1690847312973)(C:\Users\quyanliang\AppData\Roaming\Typora\typora-user-images\1690847111862.png)]

利用IDE的工具来完成代码和优化代码

  • IDEA自带功能扫描代码无用引用, 重复代码等坏味道 : Code → Inspect Code

    SonarLint

    MyBatis Plus

    Lombok

    Alibaba Java Coding Guidelines

    CheckStyle-IDEA

    文章来源地址https://www.toymoban.com/news/detail-638275.html

拥抱新技术

  • 可能随着工作的时间变长, 大家对新鲜技术的兴趣并不像之前感兴趣. 或者认为目前的技术足够, 远不会过时, 即使过时了, 也会有公司使用.
  • 技术是不断迭代更新的, 使用技术的人也要随之更新. 当大家都去开始了解和使用云服务, 容器化, 使用JDK 17的新特性, 开始用云原生框架去替换现有技术时, 咱总不能一直玩转jdk 1.8吧.
  • 了解一些新技术并不是什么值得炫耀的, 不知道也不一定影响你工作和赚钱, 但是当互联网红利已经逐渐褪去, 内卷在越来越重的今天, 机会也变得弥足珍贵. 更好的知识储备, 也能让你能获得下一份工作, 在人才市场获得更多青睐.
  • 我也一直认为, 开发对很多人来说不光是工作, 也有着一份热爱.

关于处理工作和人际关系

开发并不只是开发

  • 这个标题就是字面意思, 指的并不是光顾忌自己的开发任务. 同时也要关注公司的运营和公司业务或者说自己负责的项目的业务.
  • 我见过一些程序员只是单纯的根据产品的文档写需求, 你需求怎么写, 我功能就怎么写. 但是研发在看待需求时, 应该持有自己的见解, 观点和建议. 这也就是需求评审的目的.
  • 不要觉得需求是产品提的, 和研发没有任何关系. 但是你需要考虑到, 当需求存在问题, 后续的需求优化, bug修复, 甚至数据处理, 可都是要由研发来做的. 简单来说, 错在产品, 但引发问题由你处理.
  • 而公司的运营, 关系到了你在公司的生存和发展, 所以关注着公司的运营情况, 也大概你知道你明年的涨薪是否有希望, 年终奖是否能按时发放, 以及你是否应该考虑换一个公司去继续搬砖.

合理的分配和安排自己的工作

  • 拿到需求不要急于开发, 不要急于开发, 不要急于开发.
  • 我见过一些开发, 在拿到需求后会马不停蹄的开始Coding, 然后就出现边写边改, 再写又发现哪里存在问题, 最后发现写不通, 推翻了之前的结构再写.
  • 这个可能并不适合所有人, 但是我认为在开始Coding之前, 是需要构思一下再着手的. 花一些时间分析一下这个需求, 考虑下设计到的各个部分, 构思下自己的开发思路, 设想下其中可能遇到的问题, 当思路清晰后, 再去着手开发, 这样会让你能够流畅的完成开发工作, 并且让你的代码质量更高.

对自己的工作要有Owner意识, 答应的事情要尽力去做到

  • 什么是工作的Owner意识, 简单来说, 就是这个工作分配给你, 你就是第一负责人.
  • 对于分配到自己手里的工作, 首先要有一个正确的评估. 可以简单的分为: 这个工作你能不能做, 能不能按时做完, 要怎么做, 最后能做到什么效果.
  • 如果因为种种原因做不到, 需要提前预报风险, 不要等到最后一刻告诉大家, 你没做到. 任务分配给你, 是因为这是你的工作, 也有一部分信任在, 是相信你可以做好, 别去辜负别人的信任, 信任可能因为一件事就确立起来, 也可能因为一件事情就毁掉.

我不管别人摸鱼, 但不要影响到我的工作

  • 工作难免偷懒, 大家都有想休息放松的时候. 我对这个事情的看法就是, 摸鱼可以, 但是不要影响别人的工作.
  • 在整个项目或者需求的流程里, 产品, 后端开发, 前端开发, 测试人员都只是其中的一环. 对于各个环节的人员来说, 都是这样, 可以适当摸鱼, 但是不要压缩了别人安排好的时间.

自己的问题勇于承认, 但不是我的锅我不背

  • 承认自己的问题并不是一个可耻的事情, 但是不承认被别人扒出来可是非常尴尬的.
  • 如果你不能按时完成开发任务, 可以说明你的原因, 尽快的提出来, 别等到最后到了Deadline你说你做不完.
  • 或者因为你的bug导致了线上事故, 也没必要遮遮掩掩. 快速的定位问题, 解决问题, 在会议上复盘问题, 最好下次发生同样的状况就好, 也没必要因此给自己很大的心理压力和负担. 常在河边走, 哪有不湿鞋.
  • 但是, 对于甩锅这种问题, 没有人不反感. 我不去讨论什么叫甩锅, 我只去讨论怎么避免甩锅这种事情的发生.
    • 在对于需求, 会议, 形成良好的书面文档, 各方进行确认
    • 有问题避免天知地知你知我知, 有问题大家一起沟通, 沟通后形成相关的书面文档
    • 当出现这种问题的时候, 拿出自己的证据来证明自己, 不是老子的锅老子不背

摆正自己和领导的位置

  • 对于领导, 你是他的下属, 不管你们是酒友还是烟友或者是pao友, 你对他最重要的是工作的能力和处理问题的能力. 认真对待分配的任务, 做好自己的分内工作, 让他看到你对他在工作上的价值, 才是建立你们工作关系的基础.

合理的看待别人的反对和批评

  • 可能每一个参加工作的人都被批评过或者吐槽, 被领导也好, 被同事也好. 在面对批评时, 不要急于反驳. 大家作为成年人, 很少会有人毫无原因和根据的前提下去吐槽你的问题.
  • 他提出的问题, 可能就是你切实存在的问题, 他不说, 下一个人也会说, 尽早了解自己的问题并及时改掉不是坏事. 不能不在意, 也不要太在意.

如果你领导或者同事是sb

  • 能忍忍, 不能忍就滚. 你不能强迫别人走, 你忍不了, 你自己走.

到了这里,关于工作三年后, 我作为Java后端开发的一些心得的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java:企业级java后端开发,需要掌握哪些内容

    一、什么是后端开发 后端开发是指开发基于服务器端的软件应用程序,也称为系统的后台或服务器端编程。 后端程序员负责处理网站或应用程序后台的逻辑和功能,包括数据库管理、服务器端脚本编写、API设计、数据安全性、网站性能优化等。 后端开发技术通常包括网络协

    2024年01月24日
    浏览(52)
  • Java后端开发面试题——框架篇

    Spring框架中的bean是单例的吗?Spring框架中的单例bean是线程安全的吗? singleton : bean在每个Spring IOC容器中只有一个实例。 prototype:一个bean的定义可以有多个实例。 Spring bean并没有可变的状态(比如Service类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的 如果在bean中定

    2024年02月12日
    浏览(42)
  • java后端开发环境搭建 mac

    在mac pro上搭建一套java 后端开发环境,主要安装的内容有:jdk、maven、git、tomcat、mysql、navicat、IntelliJ、redis。 本人mac pro的系统为mac OS Monterey 12.6.7,主机的硬件架构为x86_64。 左上角关于本机查看系统版本;终端上输入 查看机器架构: 下载官网:Java Downloads | Oracle 中国 安装步

    2024年02月15日
    浏览(41)
  • Java后端开发面试题——多线程

    创建线程的方式有哪些? 继承Thread类 实现runnable接口 实现Callable接口 线程池创建线程 runnable 和 callable 有什么区别? Runnable 接口run方法没有返回值 Callable接口call方法有返回值,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果 Callable接口的call()方法允许抛出异常

    2024年02月10日
    浏览(34)
  • Java后端开发中Java 8,JVM和JDK的关系

    Java8(也就是Java1.8)是Java编程语言的一个主要版本,正式名称为Java Platform, Standard Edition 8 (Java SE 8)。Java 8在2014年3月发布,引入了许多新特性,如Lambda表达式、新的日期时间API、接口中的默认和静态方法等。Java 8的引入使得Java程序可以更加简洁、易读,同时提高了编程效率。

    2024年04月08日
    浏览(42)
  • Java后端开发面试题——消息中间篇

    RabbitMQ-如何保证消息不丢失 交换机持久化: 队列持久化: 消息持久化 ,SpringAMQP中的的消息默认是持久的,可以通过MessageProperties中的DeliveryMode来指定的  消费者确认 manual:手动ack,需要在业务代码结束后,调用api发送ack。 auto:自动ack,由spring监测listener代码是否出现异常

    2024年02月11日
    浏览(37)
  • 华创云鼎面试:java后端开发

    华创云鼎面试: 1、项目:项目业务介绍、项目人员组成 2、分布式锁用过哪些 基于数据库的锁:可以使用关系型数据库的事务和行级锁来实现分布式锁。通过在数据库中创建一个标志位或特定的锁表来表示资源的锁定状态,其他进程在访问该资源之前需要先获取该锁。这种方法

    2024年02月12日
    浏览(37)
  • 用chatGPT快速开发java后端功能

      需求如图 常规无非是建表接口测试类,最后造数据进行自测。突发奇想,要不用GPT试一下快速写业务代码? 第一步:建表,直接复制excel中内容到GPT中  第二步:要求转为下划线:    第三步:给出条件和想要的结果(下面第一幅图是自己写的,其它代码图都是GPT生成的)

    2024年02月06日
    浏览(30)
  • Java后端开发面试题篇——Redis

    Redis的数据持久化策略有哪些 RDB的执行原理? bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。 fork采用的是copy-on-write技术: 当主进程执行读操作时,访问共享内存; 当主进程执行写操作时,则会拷贝一份数据,执

    2024年02月12日
    浏览(36)
  • mac pro java后端开发环境搭建

        从零开始,在mac pro上搭建一套java 后端开发环境,主要安装的内容有:jdk、maven、git、tomcat、mysql、navicat、IntelliJ、redis。     因为网上有很多很详细的教程,这里主要记录大概的安装过程和本人在安装过程中遇到的问题以及解决办法。     本人mac pro的系统为mac OS

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包