跳到主要内容

天融信一面

1. 抽象类

对抽象类的理解

在 Java 中,抽象类(abstract class) 是一种 不能被实例化 的类,用于被其他类继承,定义通用行为并约束子类实现特定方法。 它既可以包含抽象方法(没有方法体),也可以包含具体方法(有方法体)

特点说明
不能实例化只能被继承,不能 new 创建对象
可包含构造方法用于子类初始化
可包含成员变量和具体方法子类可以继承或重写
包含抽象方法子类必须实现所有抽象方法(除非子类也是抽象类)
支持多层继承抽象类可以继承另一个抽象类

如何使用抽象类

✅ 抽象类定义:

public abstract class Animal {
protected String name;

public Animal(String name) {
this.name = name;
}

// 抽象方法:强制子类实现
public abstract void makeSound();

// 具体方法:子类可以直接继承
public void sleep() {
System.out.println(name + " is sleeping...");
}
}

✅ 子类实现抽象类:

java复制编辑public class Dog extends Animal {

public Dog(String name) {
super(name);
}

@Override
public void makeSound() {
System.out.println(name + " says: Woof!");
}
}

✅ 调用:

java复制编辑public class TestAbstract {
public static void main(String[] args) {
Animal dog = new Dog("Buddy");
dog.makeSound(); // Buddy says: Woof!
dog.sleep(); // Buddy is sleeping...
}
}

抽象类 vs 接口的区别(常见面试点)

对比点抽象类接口(interface)
方法类型可包含抽象方法和具体方法Java 8 起可包含默认方法和静态方法
成员变量可包含成员变量只能是 public static final 常量
构造器有构造函数无构造函数
多继承支持单继承支持多继承(实现多个接口)
使用场景表示“是什么”(is-a)表示“能做什么”(can-do)

应用场景举例:

场景使用理由
模板方法模式抽象类定义模板方法,子类扩展实现
通用实体类抽象类定义通用字段,如 BaseEntity
多个子类有共同特征抽象类封装共同代码,避免重复

✅ 总结

  • 抽象类是实现 继承共性代码强制子类实现特定方法 的重要机制。
  • 抽象类不能实例化,只能作为子类的模板。
  • 实际开发中常与设计模式(如模板方法模式)结合使用。

2. 设计模式

策略模式

策略模式用于封装一系列可互换的算法或行为,让它们可以在运行时自由切换,避免冗长的 if-else 或 switch 语句

使用场景

  • 多种支付方式(微信、支付宝、银联)
  • 多种排序算法或优惠计算方式
  • 登录认证方式切换(账号密码、短信、第三方登录)
// 抽象策略
public interface PayStrategy {
void pay(double amount);
}

// 具体策略
public class WeChatPay implements PayStrategy {
public void pay(double amount) {
System.out.println("使用微信支付:" + amount + "元");
}
}

public class AliPay implements PayStrategy {
public void pay(double amount) {
System.out.println("使用支付宝支付:" + amount + "元");
}
}

// 上下文类
public class PayContext {
private PayStrategy strategy;

public PayContext(PayStrategy strategy) {
this.strategy = strategy;
}

public void execute(double amount) {
strategy.pay(amount);
}
}

// 调用方式
public class StrategyTest {
public static void main(String[] args) {
PayContext context = new PayContext(new WeChatPay());
context.execute(100.0); // 输出:使用微信支付:100.0元
}
}

工厂方法模式

工厂方法模式用于将对象的创建延迟到子类中,父类提供一个抽象方法,由子类来决定具体实例化哪个产品。

使用场景

  • 日志框架中 Logger 工厂
  • JDBC 中 DriverManager 获取连接
  • 根据配置创建不同类型对象(例如:导出 PDF、Excel)
// 产品接口
public interface Product {
void show();
}

// 具体产品
public class Phone implements Product {
public void show() {
System.out.println("我是手机产品");
}
}

public class Laptop implements Product {
public void show() {
System.out.println("我是笔记本产品");
}
}

// 工厂接口
public interface ProductFactory {
Product createProduct();
}

// 具体工厂
public class PhoneFactory implements ProductFactory {
public Product createProduct() {
return new Phone();
}
}

public class LaptopFactory implements ProductFactory {
public Product createProduct() {
return new Laptop();
}
}

// 测试
public class FactoryTest {
public static void main(String[] args) {
ProductFactory factory = new PhoneFactory();
Product product = factory.createProduct();
product.show(); // 输出:我是手机产品
}
}

责任链模式

责任链模式将多个处理器(Handler)连接成一条链,每个处理器自行决定是否处理请求或传递给下一个处理器,适用于请求可由多个对象处理但具体处理者不明确的情况

使用场景

  • Java Servlet 过滤器链
  • Spring Security 过滤器链
  • OA 审批流程、异常处理链
// 抽象处理器
public abstract class Handler {
protected Handler next;

public void setNext(Handler next) {
this.next = next;
}

public abstract void handleRequest(int level);
}

// 具体处理器
public class Manager extends Handler {
public void handleRequest(int level) {
if (level <= 1) {
System.out.println("经理处理了请求");
} else if (next != null) {
next.handleRequest(level);
}
}
}

public class Director extends Handler {
public void handleRequest(int level) {
if (level <= 2) {
System.out.println("主管处理了请求");
} else if (next != null) {
next.handleRequest(level);
}
}
}

// 测试
public class ChainTest {
public static void main(String[] args) {
Handler manager = new Manager();
Handler director = new Director();
manager.setNext(director);

manager.handleRequest(1); // 输出:经理处理了请求
manager.handleRequest(2); // 输出:主管处理了请求
}
}

Springboot中用到了哪些设计模式?

3. AOP

对AOP的理解

AOP 是一种编程思想,用来将横切关注点(cross-cutting concerns)从业务逻辑中分离出来。

在实际开发中,日志记录、权限校验、事务管理、安全控制、异常处理等,往往散布在多个模块中,如果都写在业务逻辑里会造成代码重复和耦合性高。

AOP 就是为了解决这个问题: 它在 不修改原有代码逻辑 的前提下,将这些通用功能抽离出来并统一管理

AOP实现记录日志

定义切面类

@Aspect
@Component
public class LogAspect {

@Pointcut("execution(* com.example.service..*(..))")
public void logPointcut() {}

@Before("logPointcut()")
public void before(JoinPoint joinPoint) {
System.out.println("方法开始执行:" + joinPoint.getSignature());
}

@AfterReturning(pointcut = "logPointcut()", returning = "result")
public void afterReturn(JoinPoint joinPoint, Object result) {
System.out.println("方法执行结束:" + joinPoint.getSignature() + " 返回值:" + result);
}

@AfterThrowing(pointcut = "logPointcut()", throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
System.out.println("方法异常:" + joinPoint.getSignature() + " 异常信息:" + ex.getMessage());
}
}
  • @Aspect:声明当前类为切面类。
  • @Pointcut:定义切点表达式,拦截哪些方法。
  • @Before@AfterReturning@AfterThrowing:定义增强逻辑,在方法调用前后、抛异常时插入日志逻辑。

AOP使用到什么设计模式

设计模式作用描述
代理模式 (Proxy Pattern)AOP 的底层就是通过代理对象增强目标方法的功能(Spring AOP 默认基于 JDK 动态代理或 CGLIB)
策略模式 (Strategy Pattern)Spring AOP 中,Advice 的执行策略是可配置的,比如执行顺序、异常处理策略等
责任链模式 (Chain of Responsibility)多个 Advice(通知)按顺序执行,构成一个调用链条

AOP实现机制

项目实现方式
基于接口使用 JDK 动态代理,接口为目标对象的父类
基于类使用 CGLIB 字节码生成代理子类(无接口时)

4. 数据库表一对多和多对多的区别

一对多

一个表中的一条记录对应另一个表中的多条记录。

假设有两个实体:

  • 用户表(user)
  • 订单表(order)

一个用户可以有多个订单,但一个订单只能属于一个用户。

-- 用户表
CREATE TABLE user (
id INT PRIMARY KEY,
username VARCHAR(50)
);

-- 订单表(外键指向用户表)
CREATE TABLE orders (
id INT PRIMARY KEY,
order_no VARCHAR(50),
user_id INT,
FOREIGN KEY (user_id) REFERENCES user(id)
);

特点:

  • 外键通常存在于“多”的那一方(上例中是 orders 表)。
  • 数据查询相对简单,可以用 JOIN 关联查询。

多对多

一个表中的多条记录可以对应另一个表中的多条记录,反之亦然。

假设有两个实体:

  • 学生表(student)
  • 课程表(course)

一个学生可以选多门课程,一门课程也可以被多个学生选。

需要一个**中间表(关联表)**来维护这种多对多关系:

-- 学生表
CREATE TABLE student (
id INT PRIMARY KEY,
name VARCHAR(50)
);

-- 课程表
CREATE TABLE course (
id INT PRIMARY KEY,
name VARCHAR(50)
);

-- 学生课程关联表
CREATE TABLE student_course (
student_id INT,
course_id INT,
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES student(id),
FOREIGN KEY (course_id) REFERENCES course(id)
);

特点:

  • 必须引入中间关联表
  • 查询时需要用两个 JOIN 才能得到关联数据(例如:查一个学生选了哪些课程)。
  • 常用于社交关系、标签系统、收藏等功能。
比较项一对多多对多
定义一条记录对应多条记录多条记录对应多条记录
表结构外键在“多”方表中引入第三张“关联表”
举例用户和订单、分类和文章学生和课程、用户和角色
查询复杂度相对简单稍复杂,需使用中间表
数据维护简单需要同步维护中间表记录