很多时候,为了赶项目进度,或是没有合适的代码review机制,再是每个程序员的水平高低各不相同。以下几点就是最近优化接口时做的一些调整。
- 如果使用循环不停地去操作数据库,请把这个循环放在service层中,并且使用
@Transactional
,这样,就保证多次的数据库操作在一个事务中,不会不断地开启提交事务。不建议要放在controller层或action层中。 举例代码如下:
@Transactional @Override public ListcollectContents(Set contentIds) { if (contentIds.isEmpty()) { return new ArrayList<>(); } Integer[] ids = contentIds.stream() .map(id -> Integer.parseInt(id)) .collect(Collectors.toList()) .toArray(new Integer[contentIds.size()]); return dao.queryContentsInOne(ids); }
- 如果需要获取redis的多个keys或批量操作时,推荐使用pipeline,减少网络通讯开销。 举例代码如下:
Pipeline pipeline = jedis.pipelined(); ListuIds = new LinkedList<>(followingUsers); for(String userId : uIds) { pipeline.exists(getFormatKeyStr(USER_CONTENT_ZSET, userId)); }
Pipeline zaddPipeline = jedis.pipelined(); if(Objects.nonNull(followingUpUserContents) && followingUpUserContents.size() > 0) { followingUpUserContents.forEach(content -> { zaddPipeline.zadd(getFormatKeyStr(USER_CONTENT_ZSET, content.getUser().getId()), content.getSortDate().getTime(), String.valueOf(content.getId())); }); zaddPipeline.sync(); }
熟悉数据表的定义结构,每个字段的类型和长度,以及建立了哪些索引,哪些索引是必需的,哪些是可以去掉的,再是使用explain命令,来查看你要编写的sql语句是否使用了索引。
在项目中遇到了OOM溢出,原因是原来Hibernate使用redis作为二级缓存,后因为redis需要大量的网络通信,后更换为Ehcache,结果就OOM了。其原因是Ehcache需要大量内存缓存查询结果,一开始分配的内存并不多。解决办法,增加内存。
时刻记得null和为空的情况,可以使用Optional来解决。
举例代码如下:
package crazy;import java.util.Optional;class Company { private String name; private Optionaloffice; public Company(String name, Optional office) { this.name = name; this.office = office; } public String getName() { return name; } public Optional getOffice() { return office; }}class Office { private String id; private Optional address; public Office(String id, Optional address) { this.id = id; this.address = address; } public String getId() { return id; } public Optional getAddress() { return address; }}class Address { private Optional street; private Optional city; public Address(Optional street, Optional city) { this.street = street; this.city = city; } public Optional getStreet() { return street; } public Optional getCity() { return city; }}public class OptionalDemo1 { public static void main(String[] args) { Optional address1 = Optional.of(new Address(Optional.ofNullable(null), Optional.of("New York"))); Optional office1 = Optional.of(new Office("OF1", address1)); Optional company1 = Optional.of(new Company("Door Never Closed", office1)); // What is the street address of company1? // In which city company1 is located? Optional maybeOffice = company1.flatMap(Company::getOffice); Optional maybeAddress = office1.flatMap(Office::getAddress); Optional maybeStreet = address1.flatMap(Address::getStreet); maybeStreet.ifPresent(System.out::println); if (maybeStreet.isPresent()) { System.out.println(maybeStreet.get()); } else { System.out.println("Street not found."); } // shorter way String city = company1.flatMap(Company::getOffice) .flatMap(Office::getAddress) .flatMap(Address::getStreet) .orElse("City is not found."); System.out.println("City: " + city); // only print if city is not null company1.flatMap(Company::getOffice) .flatMap(Office::getAddress) .flatMap(Address::getCity) .ifPresent(System.out::println); }}
- 如果常见的优化手段并不明显,可以考虑使用临时表。
最重要的一点是:
写代码的时候,不要只盯着代码,要想你写的代码在内存或是在程序中是如何执行的。