项目开发经验

一、性能优化:

数据库
  1. 字段优化: 如果需求字段不多的话,不要用findall,可以考虑jpql语句select new的方式,或者新建实体对应数据库表
  2. 条件优化: 是否join过多,or过多,in的元素过多,是否存在无用的筛选条件,如不需要的排序,还有查询范围是否合理等
  3. 索引优化: 关键字段是否有索引,索引字段是否合理,看执行计划是否走索引,能否索引覆盖避免回表,索引字段过多会影响update性能等
  4. 多表关联: 超过三张表关联要考虑需求是否合理,是否可以通过其他的方式解决,如单表查询,内存中拼接结果,如增加冗余字段减少表关联
业务代码
  1. 批量查询: 多次查询的,能否改成批量查询,减少数据库访问,减少远程接口调用
  2. 缓存结果: 大量重复利用的结果或者获取逻辑复杂的结果缓存起来,减少请求次数
  3. 多线程线程池: 各部分数据逻辑关联不强,可考虑多线程,异步多线程,同时处理,也可汇总结果
  4. 消息队列: 通过消息队列解耦,异步处理。大量消息同时处理,发布时,可返回一个软状态,处理中,之后后台慢慢处理
  5. 异步处理: 不需要及时的结果,通过异步节省时间,如主流程触发一些细小分支,不重要可以使用异步,不增加主流程的执行时间
  6. 合理加锁: 不该加锁而加锁,锁的范围太大,锁的粒度太重,锁的类型不清(读写锁)等可能导致性能下降
  7. 事务: 如hibernate查询加只读事务是有优化的,多次相同查询只会执行一次SQL
底层结构
  1. 垂直分表: 表字段太多可考虑垂直分表,查询条件和展示列拆成一个表,其他字段拆成另一个表,已成熟的业务再行拆分,比较复杂,可考虑后面新的业务
  2. 水平分表: 单表数据量比较大可进行水平分库分表,或者对数据进行定期归档
  3. 引入其他搜索引擎: 如引入ES存储商品数据,分布式的实时分析搜索引擎,海量数据下可近秒级响应

二、代码优化:

  1. 算法优化: 运算要考虑时间复杂度,空间复杂度,如常用hash表优化,如果数据比较多,存在多重for循环,可以空间换时间,通过HashSet,HashMap存取,时间复杂度O(1)
  2. 执行顺序: 如调整if else的执行顺序,将最可能命中的结果放到前面,以减少后续判断及逻辑执行;
  3. 设计模式: 对于很多的if else,每段分支都有大段逻辑,可以考虑使用设计模式进行优化,如策略模式;对于使用比较频繁的工具类,可以考虑使用单例模式,减少频繁创建对象等
  4. 单一职责: 尽量避免一个大的,复杂的功能写到一起,对各部分小功能要进行拆分,这样逻辑清晰,也易于维护扩展,提高复用性,代码超80行,看可拆否
  5. 分布式锁: 不要随便加锁,加锁会降低并发性能,只在必要的场景加锁,如防止修改丢失
  6. 代码精简: 要习惯使用如stream流等简洁方式开发,但逻辑也不要过于复杂,不然出现问题,调试麻烦
  7. 规则引擎: 规则引擎内的代码需要编译,所以执行时间比较长,可以进行结果缓存
  8. catch优化: 尽量不要将大块代码放到catch块中去执行,因为jvm很少会对此代码进行优化

三、常见问题:

  1. 异步失效: 同一个类内,调用异步方法,由于没有创建代理对象,异步会失效,可以拆分到不同类下,也可以通过自己注入自己的方式解决
  2. 事务失效: 原因同异步失效,类内调用不会创建代理对象,方法可以拆分到不同类下,也可以通过自己注入自己的方式解决
  3. 修改丢失: 大批量数据修改,最好分段临时读取数据,如定时任务大批量数据执行,执行时间比较长,中间可能发生数据变更,可考虑需要执行的时候在提取数据,校验状态,决定是否执行,防止覆盖他人的更新
  4. 内存溢出: 如同时大批量操作会造成内存压力,可分页分批处理;如线程无限制创建导致内存溢出,可使用线程池,限制线程数,队列数
  5. 内存泄漏: 如线程使用未关闭,建议多线程使用线程池
  6. 避免Executors: 使用Executors创建线程池,要么不限制线程数,要么不限制队列边界,有可能会出现内存溢出等问题,最好用ThreadPoolExecutor,自己去指定线程池的各个参数,这样也会进一步理解线程池的原理
  7. 线程池参数不合理: 对于线程池的重要参数要结合业务内容谨慎设置,如线程数,队列数,拒绝策略等,要知道每一部分参数的涵义
  8. 频繁GC: 如报表导出,报表数据量过大;如大对象使用完成后引用不置空,不释放
  9. 超级回滚: 避免大的事务导致超级回滚,大批量数据更新或逻辑运算成本较高,可考虑进行事务切分,不影响的逻辑数据可单段提交

四、三方对接:

  1. 需求沟通: 叫上业务具体操作人员一起沟通,确保需求不脱离实际
  2. 需求会议: 确保每次会议结果归档,留存
  3. 需求整理: 流程图和设计文档还是必要的,设计好后进行确认,尽量避免返工
  4. 表设计: 数据交互,如数据同步,第三方可能会将多个表数据打包发送给我们,字段可能很多,所以不要用单表,要进行表拆分,可从业务角度或功能角度进行拆分,如查询角度将条件字段及列表字段拆分出来,其他的拆成另一张表
  5. 接口设计: 一定要考虑到超时问题,幂等设计,双方都要考虑;执行逻辑要自己没问题在请求第三方,防止自己有问题回滚,导致第三方脏数据(如单据重复创建)
  6. 模块拆分: 三方对接可能会对接多个平台,每个模块的编写要考虑到它的可扩展性
  7. 设计模式: 多个平台,相同的业务场景可能编写多次,可以考虑使用设计模式进行优化
  8. 测试用例: 编好测试用例,别嫌麻烦,后面出问题,找人联调更麻烦
  9. 字段对应: 可以考虑使用Gson实现第三方字段和本地字段之间的转化
  10. 时间传递: 尽量使用string或者时间戳可以避免很多问题
  11. 异常处理: 调用第三方接口,要捕获异常,尽量展现原有异常,不要过度包装
  12. 日志监控: 和第三方交互,尽量保存短期来往日志,追究问题比较方便,系统问题也更容易发现,维护
  13. 数据传输: 和第三方交互数据,要进行加密处理
  14. 返回值: 一定要约定好一个较好的规范,接口发生问题,要在返回值中有所体现,便于双方查找问题,不要过于含糊

常规注意:

  1. Bigdecimal: 禁止使用double直接构造BigDecimal,会损失精度,初始化使用string构造,减少误差;性能差,不可变,每次会创建一个新的对象

  2. 接口调用: 注意异常处理,不重要的话,不要影响整个功能

  3. get请求: 注意地址栏参数的规范,不确定的话用post,如地址参数传String,可能值里面包含"/"不可知

  4. 接口参数: 接口请求传很多参数的话,尽量不用map, 考虑创建类,传递对象

  5. 异常打印: try catch 需要补充 尽量用log.error打印异常,方便调试

  6. JSON异常: Json字段多于对象字段,要解析json为对象,不要转化为对象

  7. objectUtils: 判断对象空时,认为空格字符串是非空的

  8. JPA修改: 不要忘记加@Modifying注解

  9. 签名生成问题: controller层使用string接收对象时,对象属性中间会有空格,和json生成的字符串不完全一致,因此可以resultStr=JSONObject.toJSONString(JSONObject.parseObject(resultStr));

  10. 重复执行: 考虑使用redis 存储唯一标识(key值设计为业务前缀加+id),由业务执行时间设置过期时间。

  11. 魔法值: 写枚举;静态常量;包装成类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值