Skip to content

Latest commit

 

History

History
215 lines (156 loc) · 5.67 KB

代码优化.md

File metadata and controls

215 lines (156 loc) · 5.67 KB

[TOC]

代码优化

使用select 具体字段,代替 select *

  • 节省资源,减少网络开销
  • 可能用到覆盖索引,减少回表,提高查询效率

复杂的if条件,可以调整条件的顺序

初始化集合,指定容量

方法参数超过3个,使用DTO封装

使用缓冲流,减少IO操作

不要使用魔法值

  • 代码中直接出现数值

注意Arrays.asList的几个坑

  • 「基本类型不能作为 Arrays.asList方法的参数,否则会被当做一个参数。」
public class ArrayAsListTest {
    public static void main(String[] args) {
        int[] array = {1, 2, 3};
        List list = Arrays.asList(array);
        System.out.println(list.size());
    }
}
//运行结果
1
  • 「Arrays.asList 返回的 List 不支持增删操作。」
public class ArrayAsListTest {
    public static void main(String[] args) {
        String[] array = {"1", "2", "3"};
        List list = Arrays.asList(array);
        list.add("5");
        System.out.println(list.size());
    }
}

// 运行结果
Exception in thread "main" java.lang.UnsupportedOperationException
 at java.util.AbstractList.add(AbstractList.java:148)
 at java.util.AbstractList.add(AbstractList.java:108)
 at object.ArrayAsListTest.main(ArrayAsListTest.java:11)

Arrays.asList 返回的 List 并不是我们期望的 java.util.ArrayList,而是 Arrays 的内部类ArrayList。内部类的ArrayList没有实现add方法,而是父类的add方法的实现,是会抛出异常的呢。

  • 「使用Arrays.asList的时候,对原始数组的修改会影响到我们获得的那个List」
public class ArrayAsListTest {
    public static void main(String[] args) {
        String[] arr = {"1", "2", "3"};
        List list = Arrays.asList(arr);
        arr[1] = "4";
        System.out.println("原始数组"+Arrays.toString(arr));
        System.out.println("list数组" + list);
    }
}

//运行结果
原始数组[1, 4, 3]
list数组[1, 4, 3]

尽量减少对变量的重复计算

  • 对方法的调用,即使是只有一个语句,也是有有消耗的,比如创建栈帧。如果list比较大时,多次调用list.size也是会有资源消耗的。

尽量不在循环里远程调用、或者数据库操作,优先考虑批量进行

多线程异步优先考虑恰当的线程池,而不是new thread,同时考虑线程池是否隔离

优化程序结构,尽量减少方法的重复调用

「反例:」

    public static void listDetail(List<UserInfo> userInfoList) {
        for (int i = 0; i < userInfoList.size(); i++) {
            //重复调用userList.size()方法了
        }
    }

「正例:」

 public static void listDetail(List<UserInfo> userInfoList) {
        int length = userInfoList.size();
        for (int i = 0; i < length; i++) {
            //减少调用userList.size()方法,只在length变量调了一次。
        }
    }

批量查询

批量查询优化

代码美观

代码美观

直接大文件或者一次性从数据库读取太多数据到内存,可能导致OOM问题

调用第三方接口,需要考虑异常处理,安全性,超时重试这几个点

批量调用第三方接口

对于复杂的代码逻辑,添加清楚的注释

  • 好的方法变量命名就是最好的注释
  • 业务逻辑很复杂的代码,真的非常有必要写清楚注释

对于行数比较多的函数,建议划分小函数,增强可读性

策略模式+工厂方法优化冗余的if else

「反例:」

    String medalType = "guest";
    if ("guest".equals(medalType)) {
        System.out.println("嘉宾勋章");
     } else if ("vip".equals(medalType)) {
        System.out.println("会员勋章");
    } else if ("guard".equals(medalType)) {
        System.out.println("展示守护勋章");
    }
    ...

首先,我们把每个条件逻辑代码块,抽象成一个公共的接口,我们根据每个逻辑条件,定义相对应的策略实现类,可得以下代码:

//勋章接口
public interface IMedalService {
    void showMedal();
}

//守护勋章策略实现类
public class GuardMedalServiceImpl implements IMedalService {
    @Override
    public void showMedal() {
        System.out.println("展示守护勋章");
    }
}
//嘉宾勋章策略实现类
public class GuestMedalServiceImpl implements IMedalService {
    @Override
    public void showMedal() {
        System.out.println("嘉宾勋章");
    }
}
//VIP勋章策略实现类
public class VipMedalServiceImpl implements IMedalService {
    @Override
    public void showMedal() {
        System.out.println("会员勋章");
    }
}

接下来,我们再定义策略工厂类,用来管理这些勋章实现策略类,如下:

//勋章服务工产类
public class MedalServicesFactory {

    private static final Map<String, IMedalService> map = new HashMap<>();
    static {
        map.put("guard", new GuardMedalServiceImpl());
        map.put("vip", new VipMedalServiceImpl());
        map.put("guest", new GuestMedalServiceImpl());
    }
    public static IMedalService getMedalService(String medalType) {
        return map.get(medalType);
    }
}

优化后,正例如下:

ublic class Test {
    public static void main(String[] args) {
        String medalType = "guest";
        IMedalService medalService = MedalServicesFactory.getMedalService(medalType);
        medalService.showMedal();
    }
}