zoukankan      html  css  js  c++  java
  • 记录一次bug解决过程:可维护性和性能优化

    一、总结

    1. 使用某些变量的地方在2次以上的,强烈建议使用枚举值来维护变量,日后方便扩展。
    2. 查数据库的方法调用,能合并就净量去合并。

    二、Bug描述

    枚举变量的维护以及方法使用:

    public class UsedOnce {
        public static enum ruleDetailsEnum {
            SOURCEREGIN("原区域"), TARGETREGIN("目的区域"), SOURCECITY("原城市"), TARGETCITY("目的城市"), SOURCESITE("原机房"),
            TARGETSITE("目的机房"), DEVICETYPE("设备类型");
            private final String strValue;
            private ruleDetailsEnum(String strValue){
                this.strValue = strValue;
            }
            public String getStrValue() {
                return strValue;
            }
            public static String getStrValueByName(String name) {
                for (ruleDetailsEnum orderDeviceType : ruleDetailsEnum.values()) {
                    if (name.equals(orderDeviceType.name())) {
                        return orderDeviceType.getStrValue();
                    }
                }
                return null;
            }
        }
    
        public static void main(String[] args) {
            UsedOnce.ruleDetailsEnum e = UsedOnce.ruleDetailsEnum.valueOf("DEVICETYPE");
            switch (e.ordinal()) {
                case 0:
                    System.out.println("原区域");
                    break;
                case 6:
                    System.out.println("设备类型");
                    break;
                default:
                    System.out.println("没有匹配到");
            }
        }
    }
    // 结果输出:设备类型

    查询数据库合并性能优化:

    JVM堆中缓存当天的数据性能优化:

    private Map<String, String> getAssignRates() {
        Date start = DateUtil.removeDays(new Date(), 1);
        String startTm = DateUtil.toString(start, DateUtil.DATE_FORMAT);
        String endTm = DateUtil.toString(DateUtil.removeDays(start, 90), DateUtil.DATE_FORMAT);
        List<LogisticsAtomic> list = new ArrayList<LogisticsAtomic>();
    
        /* 缓存入JVM堆中;减少哈希碰撞;且只维护一个数据 */
        String now = DateUtil.toString(new Date(), DateUtil.DATE_FORMAT);
        Map<String, List<LogisticsAtomic>> oneDayData = WorkOrderCst.ONEDAYDATA;if (oneDayData.keySet().contains(now)) {
            list = oneDayData.get(now);
        } else {
            list = logisticsWorkOrderBo.getLogisticsList90DaysBefore(startTm, endTm);
            oneDayData.clear();
            oneDayData.put(now, list);
        }
        Map<String, String> map = new HashMap<String, String>();
        for (LogisticsAtomic bean : list) {
            if (null != bean.getSpId()) {
                map.put(bean.getSpId().toString(), bean.getAssetCounts().toString());
            }
        }
        return map;
    }
    //带null的数据:JSONUtils.toJSONString(map);
    //不带null的数据:JSON.toJSONString(map);

    注意:存放在JVM堆中的map要放在枚举变量中。放在方法中,每次new一个Map不正确。此外,JVM的单例必须限定在一个JVM中,就像是JVM只会存在一个实例,这句话也是限定在一个 JVM 中的,如果是多个 JVM 就会每个 JVM 存在一个实例。java语言层面的单例说的是同一个jvm里面,集群没办法搞。如果你想设置的单例目的是为了数据共享,那数据存数据库或是redis之类的地方。故放在*BoImpl层中,或维护在枚举值变量中,而我们的项目又是部署在集群之上的,故无法保证集群上共享的是同一个Map。

    public class WorkOrderCst {
        // 维护一天的数据
        public static Map<String, List<LogisticsAtomic>> ONEDAYDATA = new ConcurrentHashMap<String, List<LogisticsAtomic>>();
        // 拆单时机房分隔符
        public static final String SiteSplit = "#@#";
    }

    那么可以做到保证在一个集群机器上,只保存一个静态变量ONEDAYDATA。因为类的静态变量是此类的所有实例化对象全局共享的。即指向同一块内存,只要一个对象更改了静态变量,其他对象读到的都是更改后的静态变量。因此从设计上而言,也很容易理解,静态变量也称之为类变量,可以直接使用类名访问而不需要通过类对象访问。这要看你的业务需求,原则上是尽量减少不必要的静态变量。故此处设置为静态变量,可以保证集群的一台机器上,只维护一个静态变量

    //#JVM内存总体四部分:(stack segment、heap segment、code segment、data segment)
    
    //当我们在程序中,申明一个局部变量的时候,此变量就存放在了 stack segment(栈)当中; 
    //当new 一个对象的时候,此对象放在了heap segment(堆)当中; 
    //而static的变量或者字符串常量 则存在在 data segment(数据区)中; 
    //那么类中方法的话,是存在在 code segment(代码区)中了。

    mapper层传入一个参数,筛选出最近三个月的数据:

    SELECT
        COUNT(1)
    FROM
        idc_work_order_main
    WHERE
        gmt_create < CONCAT('2016-08-03','23:59:59')
    AND gmt_create > date_sub('2016-08-03 00:00:00', INTERVAL 3 MONTH)

    一行代码初始化ArrayList:

    //ArrayList<String> list_01 = new ArrayList<String>(){{add("1");add("2");add("3");}};
    //ArrayList<String> list_02 = new ArrayList<String>(Arrays.asList("1","2","3")); 

    如何在Navicat中查看一条SQL语句的执行时间:

    关于走索引的主键id和不走索引的in查询速度哪个快的情况,结果in比主键索引快,讨论如下:

    1. navicat中如何查看执行一条SQL语句的耗时
    2. 根据主键查询两次那个效率高?

    完结。

  • 相关阅读:
    Asp.net 弹出对话框基类 (输出alet警告框)
    Request.ServerVariables获取环境变量
    Asp.net 字符串操作基类(安全,替换,分解等)
    asp.net 取得远程的IP地址和浏览器类型
    存储过程得到三个值
    弹出无边框网页的Javscrpt代码
    .net打包自动安装数据库!
    精妙Sql语句
    关于跨语言站点搜索结果非预期的问题
    SharePoint服务器场环境安装升级补丁的详细步骤
  • 原文地址:https://www.cnblogs.com/RunForLove/p/5734114.html
Copyright © 2011-2022 走看看