面试题答案
一键面试1. 建造者模式在电商订单领域模型中的应用
- 定义产品类 - 订单类
public class Order {
private List<Product> productList;
private User user;
private DeliveryInfo deliveryInfo;
// 省略getter和setter方法
public void setProductList(List<Product> productList) {
this.productList = productList;
}
public void setUser(User user) {
this.user = user;
}
public void setDeliveryInfo(DeliveryInfo deliveryInfo) {
this.deliveryInfo = deliveryInfo;
}
}
- 定义商品类
public class Product {
private String category;
private Map<String, String> properties;
// 省略getter和setter方法
public void setCategory(String category) {
this.category = category;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
}
- 定义用户类
public class User {
private String name;
private String contact;
// 省略getter和setter方法
public void setName(String name) {
this.name = name;
}
public void setContact(String contact) {
this.contact = contact;
}
}
- 定义配送信息类
public class DeliveryInfo {
private String address;
private String deliveryMethod;
// 省略getter和setter方法
public void setAddress(String address) {
this.address = address;
}
public void setDeliveryMethod(String deliveryMethod) {
this.deliveryMethod = deliveryMethod;
}
}
- 定义建造者接口
public interface OrderBuilder {
void buildProductList();
void buildUser();
void buildDeliveryInfo();
Order getOrder();
}
- 具体建造者实现
public class ConcreteOrderBuilder implements OrderBuilder {
private Order order = new Order();
@Override
public void buildProductList() {
List<Product> productList = new ArrayList<>();
// 假设从数据库或其他数据源获取商品信息
Product product1 = new Product();
product1.setCategory("Electronics");
Map<String, String> properties1 = new HashMap<>();
properties1.put("brand", "Apple");
properties1.put("model", "iPhone 14");
product1.setProperties(properties1);
productList.add(product1);
order.setProductList(productList);
}
@Override
public void buildUser() {
User user = new User();
user.setName("John Doe");
user.setContact("john@example.com");
order.setUser(user);
}
@Override
public void buildDeliveryInfo() {
DeliveryInfo deliveryInfo = new DeliveryInfo();
deliveryInfo.setAddress("123 Main St");
deliveryInfo.setDeliveryMethod("Express");
order.setDeliveryInfo(deliveryInfo);
}
@Override
public Order getOrder() {
return order;
}
}
- 导演类
public class OrderDirector {
private OrderBuilder orderBuilder;
public OrderDirector(OrderBuilder orderBuilder) {
this.orderBuilder = orderBuilder;
}
public Order constructOrder() {
orderBuilder.buildProductList();
orderBuilder.buildUser();
orderBuilder.buildDeliveryInfo();
return orderBuilder.getOrder();
}
}
- 使用示例
public class Main {
public static void main(String[] args) {
OrderBuilder orderBuilder = new ConcreteOrderBuilder();
OrderDirector orderDirector = new OrderDirector(orderBuilder);
Order order = orderDirector.constructOrder();
}
}
2. 性能问题及优化方案
- 性能问题
- 重复计算:在构建商品列表时,如果每次获取商品信息都从数据库查询,且查询条件不变,会产生重复计算。
- 资源浪费:如果构建过程中有临时对象创建,但这些对象在构建完成后不再使用,会造成资源浪费。例如,在构建商品属性的
Map
对象时,如果构建失败,但已经创建了大量这样的Map
对象。
- 优化方案
- 缓存机制:
- 商品信息缓存:使用缓存框架(如Guava Cache或Redis)来缓存商品信息。在构建商品列表时,先从缓存中获取商品信息,如果缓存中没有,则查询数据库并将结果存入缓存。例如,使用Guava Cache:
- 缓存机制:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class ProductCache {
private static final Cache<String, Product> productCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.build();
public static Product getProductFromCache(String productId) {
return productCache.getIfPresent(productId);
}
public static void putProductToCache(String productId, Product product) {
productCache.put(productId, product);
}
}
在buildProductList
方法中使用缓存:
@Override
public void buildProductList() {
List<Product> productList = new ArrayList<>();
String productId = "123";
Product product = ProductCache.getProductFromCache(productId);
if (product == null) {
// 从数据库查询
product = new Product();
product.setCategory("Electronics");
Map<String, String> properties1 = new HashMap<>();
properties1.put("brand", "Apple");
properties1.put("model", "iPhone 14");
product.setProperties(properties1);
ProductCache.putProductToCache(productId, product);
}
productList.add(product);
order.setProductList(productList);
}
- 对象复用:
- 对象池:对于一些频繁创建和销毁的对象,如数据库连接对象(如果构建过程中需要数据库操作),可以使用对象池技术。例如,使用Apache Commons Pool来管理数据库连接对象。
- 避免不必要的对象创建:在构建过程中,尽量复用已有的对象。例如,如果订单构建过程中需要获取用户信息,且该用户信息在其他地方已经获取并存在内存中,可以直接复用该用户对象,而不是重新创建。
- 构建逻辑优化:
- 减少复杂逻辑中的嵌套:如果构建过程中有复杂的逻辑判断,尽量简化嵌套结构,提高代码的可读性和执行效率。例如,使用策略模式来替代复杂的
if - else
逻辑,将不同的构建策略封装成独立的类。 - 延迟加载:对于一些不是立即需要的组件(如订单中的一些附加信息),可以采用延迟加载的方式,在真正需要时再进行构建。例如,订单中的商品评价信息,在订单构建时可以先不加载,当用户查看订单评价时再进行加载。
- 减少复杂逻辑中的嵌套:如果构建过程中有复杂的逻辑判断,尽量简化嵌套结构,提高代码的可读性和执行效率。例如,使用策略模式来替代复杂的