本年进入我作业的第四个年头, 三年多的时刻里, 算上实习, 经历过3家公司. 见过了林林总总的同事, 也算见过林林总总的代码. 这篇文章主要是想共享一下一个java后端三年的一些感悟, 关于编程上的, 作业上的, 和同事相处上的.

一: 关于开发

我把关于编程的写在最前面, 我觉得关于开发人员来讲, 编程才能才是混饭的手工, 它也一定程度上也决议了你的钱包和取得作业的筹码.

1. 勇于和长于运用package

关于Java后端开发来讲, 在长时刻的web开发中. 咱们现已了解了MVC架构, 也被这套结构所束缚. 导致创立出来的包也一向都是controller, manager, service, dao. 也将林林总总的类文件都放入其间. 这并不是一种好的做法.

其实咱们能够斗胆的创立相关的package, 只需让结构更合理, 可读性更高.

比如能够把对接前端的类写到request, response包; 把一些处理器提取出来放到handler中, 把一些定时任务放到schedule包; 把参数结构相关的放到generator; 把校验相关的放到validator下等等. 

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

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

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();
  }
} 

3. 合理的办法命名和办法界说

办法名的界说很令人苦恼, 常常左思右想想不到好名字. 我曾经由于办法命名不好, 被张狂的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) {
}

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

我一向觉得, 好的代码读起来应该像故事一样, 有前因, 有结果, 中间娓娓道来.  简略举个比如, 咱们或许会遇到在办法中去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
  }
}

5. 不知道的常识能够去问问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");

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

慢恳求的剖析, 或许不需求要先去看有没有复杂的相关查询, 或许是不是数据库查询有没有射中索引, 而是先去看是不是有大哥在for循环去恳求数据库和dubbo接口. 循环了1w次. 我曾经遇到过屡次恳求超时都是由于有人在代码里for循环去select , update. 

关于这种问题的处理, 将循环调用改成单次的批量接口就能够处理问题. 关于mysql的化in操作就能够处理, 关于外部系统对接的, 两边供给批量接口就能够了.

7. 没有意义的注释不要写

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

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

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

8. 不要忽视UnitTest

写过单元测试的会发现, 编写完善的单元测试会占用大量的时刻, 一般都会超过需求的开发时刻, 但是我仍是以为单元测试是有必要且重要的. 由于作为研制人员, 才是最了解代码中哪里容易出问题的. 更容易写出发现问题的测试用例. 而且代码迭代或许修改后, 也能更快速的发现问题, 将问题停留在研制阶段去处理, 进步全体的进展.

9.长于运用AI编程东西

在我运用了Github copilot和ChatGPT半年后, 我发现我的摸鱼时刻变多了… 由于AI编程东西帮我完结了一定量的作业. 例如最常用的代码补全, 代码主动生成, 主动生成单元测试等等

在当今, 熟练掌握AI编程东西, 是进步自己作业效率的极佳的办法. 在未来, AI也一定会替代掉一部分程序员的作业.
1b48670f07e84e188917094af9f05120~tplv-k3u1fbpfcp-watermark.png

10. 运用IDE的东西来完结代码和优化代码

  1. IDEA自带功用扫描代码无用引证, 重复代码等坏滋味 : Code → Inspect Code
  2. SonarLint
  3. MyBatis Plus
  4. Lombok
  5. Alibaba Java Coding Guidelines
  6. CheckStyle-IDEA

11. 拥抱新技能

  或许随着作业的时刻变长, 咱们对新鲜技能的兴趣并不像之前感兴趣. 或许以为现在的技能足够, 远不会过期, 即便过期了, 也会有公司运用.

  技能是不断迭代更新的, 运用技能的人也要随之更新. 当咱们都去开端了解和运用云服务, 容器化, 运用JDK 17的新特性, 开端用云原生框架去替换现有技能时, 咱总不能一向玩转jdk 1.8吧.

  了解一些新技能并不是什么值得炫耀的, 不知道也不一定影响你作业和挣钱, 但是当互联网盈利现已逐步褪去, 内卷在越来越重的今天, 时机也变得弥足珍贵. 更好的常识储备, 也能让你能取得下一份作业, 在人才市场取得更多喜爱.

  我也一向以为, 开发对许多人来说不光是作业, 也有着一份热爱.

二. 关于处理作业和人际联系

1. 开发并不仅仅开发

  这个标题便是字面意思, 指的并不是光顾忌自己的开发任务. 同时也要重视公司的运营和公司事务或许说自己负责的项意图事务.

  我见过一些程序员仅仅单纯的根据产品的文档写需求, 你需求怎样写, 我功用就怎样写. 但是研制在看待需求时, 应该持有自己的见地, 观点和建议. 这也便是需求评定的意图.

  不要觉得需求是产品提的, 和研制没有任何联系. 但是你需求考虑到, 当需求存在问题,  后续的需求优化, bug修正, 乃至数据处理, 可都是要由研制来做的. 简略来说, 错在产品, 但引发问题由你处理.

  而公司的运营, 联系到了你在公司的生计和开展, 所以重视着公司的运营状况, 也大概你知道你明年的涨薪是否有期望, 年终奖是否能准时发放, 以及你是否应该考虑换一个公司去持续搬砖.

2. 合理的分配和安排自己的作业

  拿到需求不要急于开发, 不要急于开发, 不要急于开发.

  我见过一些开发, 在拿到需求后会再接再励的开端Coding,  然后就呈现边写边改, 再写又发现哪里存在问题, 最终发现写不通,  推翻了之前的结构再写. 

  这个或许并不合适所有人, 但是我以为在开端Coding之前, 是需求构思一下再着手的. 花一些时刻剖析一下这个需求, 考虑下规划到的各个部分, 构思下自己的开发思路, 设想下其间或许遇到的问题, 当思路清晰后, 再去着手开发, 这样会让你能够流通的完结开发作业, 而且让你的代码质量更高.

3. 对自己的作业要有Owner认识, 答应的作业要尽力去做到

  什么是作业的Owner认识,  简略来说, 便是这个作业分配给你, 你便是第一负责人.

  关于分配到自己手里的作业, 首要要有一个正确的评价. 能够简略的分为: 这个作业你能不能做, 能不能准时做完, 要怎样做, 最终能做到什么作用.    

  假如由于种种原因做不到, 需求提早预报危险, 不要比及最终一刻告知咱们, 你没做到. 任务分配给你, 是由于这是你的作业, 也有一部分信赖在, 是相信你能够做好, 别去孤负他人的信赖,  信赖或许由于一件事就建立起来, 也或许由于一件作业就销毁.

4. 我不论他人摸鱼, 但不要影响到我的作业

  作业不免偷懒, 咱们都有想歇息放松的时分. 我对这个作业的看法便是, 摸鱼能够, 但是不要影响他人的作业. 

  在整个项目或许需求的流程里, 产品, 后端开发, 前端开发, 测试人员都仅仅其间的一环. 关于各个环节的人员来说, 都是这样, 能够恰当摸鱼, 但是不要紧缩了他人安排好的时刻.

5. 自己的问题勇于供认, 但不是我的锅我不背

  供认自己的问题并不是一个可耻的作业, 但是不供认被他人扒出来但是非常为难的. 

  假如你不能准时完结开发任务, 能够阐明你的原因, 尽快的提出来, 别比及最终到了Deadline你说你做不完. 

  或许由于你的bug导致了线上事端, 也没必要遮遮掩掩. 快速的定位问题, 处理问题, 在会议上复盘问题, 最好下次发生同样的状况就好, 也没必要因而给自己很大的心理压力和担负. 常在河边走, 哪有不湿鞋. 

但是, 关于甩锅这种问题, 没有人不反感. 我不去评论什么叫甩锅, 我只去评论怎样防止甩锅这种作业的发生. 

  • 在关于需求, 会议, 构成良好的书面文档, 各方进行确认

  • 有问题防止天知地知你知我知, 有问题咱们一同交流, 交流后构成相关的书面文档

  • 当呈现这种问题的时分, 拿出自己的证据来证明自己, 不是老子的锅老子不背

6. 摆正自己和领导的位置

  关于领导, 你是他的部属, 不论你们是酒友仍是烟友或许是pao友, 你对他最重要的是作业的才能和处理问题的才能. 认真对待分配的任务, 做好自己的本分作业, 让他看到你对他在作业上的价值, 才是建立你们作业联系的根底.

7. 合理的看待他人的反对和批判

  或许每一个参加作业的人都被批判过或许吐槽, 被领导也好, 被同事也好. 在面对批判时, 不要急于反驳. 咱们作为成年人, 很少会有人毫无原因和根据的条件下去吐槽你的问题.     

  他提出的问题, 或许便是你实在存在的问题, 他不说, 下一个人也会说, 尽早了解自己的问题并及时改掉不是坏事. 不能不在意, 也不要太在意.

8. 假如你领导或许同事是sb

   能忍忍, 不能忍就滚. 你不能逼迫他人走, 你忍不了, 你自己走.

三: 总结

以上仅仅我个人的一些经历和体会了, 作业三年相比许多大佬来比, 也仅仅个小毛孩. 但是期望能帮助到咱们, 有问题也欢迎咱们积极评论.