Java技术专家面试专题系列(七):设计模式与代码优化

设计模式和代码优化是Java技术专家的重要技能,直接影响代码的可维护性、可扩展性和性能。本篇将从常用设计模式、SOLID原则到高性能编码实践,系统讲解如何编写优雅高效的代码,助你在面试中展现设计思维和优化能力。

1. 常用设计模式

设计模式是解决常见问题的模板,以下是几种典型模式。

  • 单例模式(Singleton)

    • 确保类只有一个实例。
    • 实现:懒汉式、饿汉式、双重检查锁。
  • 工厂模式(Factory)

    • 封装对象创建,解耦客户端与具体类。
  • 观察者模式(Observer)

    • 定义一对多依赖,对象状态变化通知观察者。

示例: 双重检查锁单例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {
        // 防止反射创建
        if (instance != null) {
            throw new RuntimeException("Instance already exists");
        }
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1 == s2); // 输出: true
    }
}

面试问题:

  • 问题: 单例模式如何防止多线程问题?
  • 答案: 使用volatile防止指令重排序,双重检查锁确保线程安全。

2. SOLID原则

SOLID是面向对象设计的五大原则,提升代码质量。

  • 单一职责(SRP): 一个类只负责一项职责。
  • 开闭原则(OCP): 对扩展开放,对修改关闭。
  • 里氏替换(LSP): 子类可替换父类,不改变行为。
  • 接口隔离(ISP): 客户端只依赖需要的接口。
  • 依赖倒置(DIP): 高层模块依赖抽象,而非实现。

示例: 开闭原则实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
interface Shape {
    double calculateArea();
}

class Circle implements Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle implements Shape {
    private double width, height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double calculateArea() {
        return width * height;
    }
}

class AreaCalculator {
    public double calculate(Shape shape) {
        return shape.calculateArea(); // 扩展新形状无需修改
    }
}

public class OCPDemo {
    public static void main(String[] args) {
        AreaCalculator calculator = new AreaCalculator();
        System.out.println(calculator.calculate(new Circle(5))); // 输出: 78.54...
        System.out.println(calculator.calculate(new Rectangle(4, 6))); // 输出: 24.0
    }
}

面试问题:

  • 问题: 如何理解开闭原则?
  • 答案: 通过抽象(如接口)定义行为,新增功能只需实现新类,无需改动现有代码。

3. 高性能编码实践

优化代码性能是技术专家的关键能力。

  • 减少IO操作

    • 使用缓冲流(如BufferedReader)。
  • 缓存优化

    • 复用对象,避免重复创建。
  • 集合性能

    • 根据场景选择:ArrayList(随机访问快)、LinkedList(插入删除快)。

示例: StringBuilder优化字符串拼接

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class StringOptimization {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            sb.append(i).append(",");
        }
        System.out.println("Time: " + (System.currentTimeMillis() - start) + "ms");
        // 对比: String拼接耗时更长
    }
}

面试问题:

  • 问题: 如何优化List遍历性能?
  • 答案: 对于ArrayList,用普通for循环(索引访问快);避免在循环中频繁修改大小。

4. 代码重构要点

重构提升代码可读性和可维护性。

  • 提取方法: 将复杂逻辑拆分为小方法。
  • 消除魔法值: 用常量替代硬编码。
  • 减少嵌套: 使用提前返回(Guard Clause)。

示例: 重构嵌套代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 未重构
public String process(int value) {
    String result = "";
    if (value > 0) {
        if (value < 100) {
            result = "Valid range";
        } else {
            result = "Too large";
        }
    } else {
        result = "Negative";
    }
    return result;
}

// 重构后
public String processRefactored(int value) {
    if (value <= 0) return "Negative";
    if (value >= 100) return "Too large";
    return "Valid range";
}

面试问题:

  • 问题: 重构的目的是什么?
  • 答案: 提高代码可读性、可维护性和扩展性,同时保持功能不变。

5. 代码审查要点

代码审查确保质量,以下是关注点:

  • 一致性: 命名规范、代码风格。
  • 异常处理: 是否合理捕获和记录。
  • 性能: 是否有明显瓶颈(如嵌套循环)。
  • 安全性: 输入校验、SQL注入防护。

示例: 安全的数据库查询

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import java.sql.PreparedStatement;
import java.sql.Connection;

public class SecureQueryDemo {
    public void queryUser(Connection conn, String id) throws Exception {
        String sql = "SELECT * FROM users WHERE id = ?";
        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setString(1, id); // 防SQL注入
            stmt.executeQuery();
        }
    }
}

面试问题:

  • 问题: 代码审查中最关注什么?
  • 答案: 关注功能正确性、性能瓶颈和安全漏洞,如未释放资源或未校验输入。

6. 学习与面试建议

  • 实践: 实现23种设计模式,优化现有代码。
  • 深入: 阅读《设计模式》和《重构》经典书籍。
  • 表达: 用UML图或代码实例解释设计思路。

结语

设计模式与代码优化是技术专家的软实力,掌握这些技能能让你编写优雅高效的代码,在面试中脱颖而出。下一专题将探讨综合实战与项目经验,敬请期待!

updatedupdated2025-03-312025-03-31