总结:工作 + 学习 (2019年)

1、关于对象结合JVM

  写功能代码时,尽量在一个方法里少创建对象,因为并发量高的时候,频繁的创建和销毁大量对象,会对 JVM 产生巨大压力,可能会崩溃。

2、关于 JVM 参数设置

  在实际开发中,可以工具测试一个对象占多少内存,计算下并发量假如1000的时候,对象一共会占用多少内存。再结合新生代、老年代的垃圾清除思想,来设置新

生代中三区、老年代的内存大小。

3、关于对象

  在实际业务代码里,一般加了@Service @Controllere 的对象,都是创建一次,一直使用,所以会在创建后,经过 MinorGC 进入到老年代。

  我们在接口,方法里面的局部变量,都是使用一次后基本就不再使用(除非方法逃逸),所以对象在新生代里,很快就会回收,不会进入老年代。

  我们实际写业务代码,就尽量考虑到创建对象的时候,不要在一个方法里大量创建对象,避免频繁出发 MinorGC。(结合第一条心得)

4、关于常量类和数据字典

  如果只是单纯的 key ,就可以用常量类 - 静态变量来定义;

  如果是不可变 key + value 格式,可以用枚举来定义;

  如果是不可变的 key 和可变的 value,那可变的 value 就从持久化的地方获取,例如 mysql。 key 的话就可以用常量类 - 静态变量来定义。

5、关于如何分析 JVM 优化

  分析一个项目,1秒钟会产生多少对象,新声代的 Eden 区 和 Survivor 区有多大。多少秒后会发生一次 YGC。发生 YGC 时,如果有空间担保规则,老年代的剩余大小是否大于新生代每次回收存活对象平均内存大小。如果老年代放的下,则发生 YGC,如果老年代放不下,则发生 FullGC。

  如果新生代的 Eden 区回收垃圾,存活的对象大于 Survivor 区的大小,则这些存活对象会直接存到老年代中,会使老年代迅速的存满对象。

  所以优化,就是先分析上述情况。然后针对性的,调大堆大小以及 Survivor 区的大小,使对象从 Eden 区存活,会复制到 Survivor 区。

  并且如果是大内存的机器,面向外网网友访问的,应该将垃圾回收器设置为 G1 垃圾回收器。

  防止频繁 FullGC:禁止动态年龄判断,以及确保每次 MinorGC 后存活的对象,能放在 Survivor,不会直接移动到老年代。(让进入老年代的对象尽量少)

6、关于写代码

  要按照规范来,让自己的代码具有规范性,可读性,简洁性,可用性。

7、关于 MySQL 建表

  一个备用字段,几个字段能合并就尽量合并为一个。要考虑到后期扩展。字段名不用包含表名,例如rule表的名称直接name,不需要rule_name 。

8、关于 web 层代码

  要对关键性参数做校验,例如非空检验。以及打印日志。可以在报错的时候,迅速定位到是哪里出现Bug。

9、关于写代码

  尽量按照规范,或阿里规范或公司规范来进行命名,领域模型等来完成功能。

10、关于全局异常

  先自定义一个异常,在代码逻辑里自己做的一些逻辑的失败处理就可以 return new 自定义异常。然后写一个全局异常,可以捕获自定义异常和 exception ,并且处理。(不用像之前笔记和小说项目,每个方法都 try catch)

11、关于打印日志

  打印日志时,打印的类信息,有些字段有值,有些字段没有值,就的用 JsonObject 格式化。

JSONObject.toJSONString(arriveWarnRuleVO);

12、关于设计VO(字段太多,分属不同的类型)

  设计VO时,如果涉及到多个类型,每个类型显示不同的详情,例如商品类型显示商品详情,订单类型显示订单详情。则可以每个类型的具体详情设计一个实体类,把该实体性的对象作为VO的字段。(对代码的可读性和整洁性的提高)

13、关于联表查询和分表查询

  考虑到联表查询的IO次数少些,但是数据量大的时候,或者没有正确的索引,查询时间长些。

  以及综合业务考虑,是否联表一次性查出来、一次性查询出来的数据量的多少、以及查询字段的多少、以及SQL是否太庞大。

  我自己的习惯是,如果查询总数少,例如一次性只查1条或者20条,并且只能联表查询,那就联表查询。

  如果业务不复杂,可以依次单表查询,那就单表查询。在代码里面组装数据。(代码的可读性,维护性更高。数据量不是很大的时候,联表和单表查询的耗时以及资源都相差不大)

14、关于Service 和 Dao 层的调用

  除了本业务,例如 UserService 和 UserDao,service 直接调用 dao 层外,如 User 涉及 Product 表,则应该 UserService 调用 ProductService ,而不应调 ProductDao。

  如果涉及到简单业务和复杂业务,都是一个类型功能,方法可以重载。例如在 ProductService 中可以将方法重载,不同的参数和不同的返回值。 (重载的思想)

 

15、当多线程、多人、多端口修改一条数据(乐观锁)

 

  如何保证一致性:将修改之前的旧唯一值(修改必定会修改的字段 - 可以为时间、状态),将旧的值作为修改操作的条件,符合的时候才修改,不符合的话,update 操作会返回一个 int 值为0。

 

CAS操作。

 

  返回值为0,代表未修改成

 

16、参数校验

 

  用注解@validate(value={}) Object object,抛出MethodArgumentNotValidException异常(参数通不过校验),在全局异常里面捕获,处理返回提示信息。

 

value= 的表示分组,分组信息是在实体类的字段上注明,并且可以设置一个变量值。在一个地方统一返回信息,可以增加该变量值,可以做到返回信息的精细。

 

posted @ 2019-08-09 09:00  几近虚年  阅读(209)  评论(0编辑  收藏  举报