设计模式和代码优化是Java技术专家的重要技能,直接影响代码的可维护性、可扩展性和性能。本篇将从常用设计模式、SOLID原则到高性能编码实践,系统讲解如何编写优雅高效的代码,助你在面试中展现设计思维和优化能力。
设计模式是解决常见问题的模板,以下是几种典型模式。
单例模式(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
防止指令重排序,双重检查锁确保线程安全。
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
}
}
|
面试问题:
- 问题: 如何理解开闭原则?
- 答案: 通过抽象(如接口)定义行为,新增功能只需实现新类,无需改动现有代码。
优化代码性能是技术专家的关键能力。
减少IO操作
缓存优化
集合性能
- 根据场景选择:
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循环(索引访问快);避免在循环中频繁修改大小。
重构提升代码可读性和可维护性。
- 提取方法: 将复杂逻辑拆分为小方法。
- 消除魔法值: 用常量替代硬编码。
- 减少嵌套: 使用提前返回(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";
}
|
面试问题:
- 问题: 重构的目的是什么?
- 答案: 提高代码可读性、可维护性和扩展性,同时保持功能不变。
代码审查确保质量,以下是关注点:
- 一致性: 命名规范、代码风格。
- 异常处理: 是否合理捕获和记录。
- 性能: 是否有明显瓶颈(如嵌套循环)。
- 安全性: 输入校验、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();
}
}
}
|
面试问题:
- 问题: 代码审查中最关注什么?
- 答案: 关注功能正确性、性能瓶颈和安全漏洞,如未释放资源或未校验输入。
- 实践: 实现23种设计模式,优化现有代码。
- 深入: 阅读《设计模式》和《重构》经典书籍。
- 表达: 用UML图或代码实例解释设计思路。
设计模式与代码优化是技术专家的软实力,掌握这些技能能让你编写优雅高效的代码,在面试中脱颖而出。下一专题将探讨综合实战与项目经验,敬请期待!