第29周 面试题精讲(4)

ops/2025/3/19 9:18:54/

Java面试题详解

一、简单工厂和工厂方法到底有哪些不同?

问题:简单工厂和工厂方法有哪些区别?

答案

  • 简单工厂
    • 通过一个工厂类实现对象创建,隐藏创建细节。
    • 所有对象创建基于一个方法,通过参数不同返回不同对象。
    • 客户端直接通过工厂方法获取对象,与工厂类解耦。
    • 新增产品时需修改工厂类代码,违反开闭原则。
  • 工厂方法
    • 提供抽象工厂接口,每种产品对应具体工厂。
    • 工厂接口定义创建方法,具体工厂实现该方法创建对应产品。
    • 客户端面对具体工厂实例化后调用方法获取对象。
    • 新增产品只需新增对应工厂和产品,不修改现有代码,符合开闭原则。

示例

java">// 简单工厂
public class SimpleFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ProductA();} else if ("B".equals(type)) {return new ProductB();}return null;}
}// 工厂方法
public interface Factory {Product createProduct();
}public class FactoryA implements Factory {@Overridepublic Product createProduct() {return new ProductA();}
}public class FactoryB implements Factory {@Overridepublic Product createProduct() {return new ProductB();}
}

二、请介绍观察者模式,以及它的使用场景

问题:什么是观察者模式,它的应用场景有哪些?

答案

  • 定义:定义对象间一对多依赖关系,当一个对象状态改变时,所有依赖对象自动更新。
  • 角色
    • 目标(Subject):被观察对象,维护观察者列表,提供注册、移除、通知方法。
    • 观察者(Observer):抽象角色,定义更新接口。
    • 具体目标:实现目标类,维护自身状态,状态变化时通知观察者。
    • 具体观察者:实现观察者接口,维护指向目标的引用,实现更新逻辑。
  • 使用场景
    • 界面交互(如按钮点击事件)。
    • 数据变化联动(如在线拍卖新出价通知其他出价者)。
    • 消息订阅与发布(如群消息通知)。

示例

java">// 目标类
public class Subject {private List<Observer> observers = new ArrayList<>();public void addObserver(Observer observer) {observers.add(observer);}public void removeObserver(Observer observer) {observers.remove(observer);}public void notifyObservers() {for (Observer observer : observers) {observer.update(this);}}// 模拟状态变化public void setState(String state) {// 状态改变逻辑notifyObservers();}
}// 观察者接口
public interface Observer {void update(Subject subject);
}// 具体观察者
public class ConcreteObserver implements Observer {@Overridepublic void update(Subject subject) {// 更新逻辑}
}

三、静态代理与动态代理有什么区别?

问题:静态代理与动态代理的区别是什么?

答案

  • 静态代理
    • 手动创建代理类,实现与目标类相同接口。
    • 代理类持有目标类实例,通过代理类方法调用目标类方法,并在前后增加扩展逻辑。
    • 灵活性差,每新增一个目标类需创建对应代理类。
  • 动态代理
    • 使用反射机制或字节码增强技术动态生成代理类。
    • JDK动态代理基于接口,利用反射生成代理类,通过InvocationHandler处理方法调用。
    • CGlib动态代理基于目标类字节码生成子类,重写方法增加扩展逻辑。
    • 灵活性高,无需手动创建代理类,尤其适用于大量目标类的场景。

示例

java">// 静态代理
public interface Service {void doSomething();
}public class RealService implements Service {@Overridepublic void doSomething() {// 目标方法}
}public class ProxyService implements Service {private Service realService;public ProxyService(Service realService) {this.realService = realService;}@Overridepublic void doSomething() {// 前置处理realService.doSomething();// 后置处理}
}// 动态代理
public class DynamicProxy implements InvocationHandler {private Object target;public DynamicProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 前置处理Object result = method.invoke(target, args);// 后置处理return result;}
}// 使用动态代理
Service service = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(),new Class[]{Service.class},new DynamicProxy(new RealService())
);

四、请说明适配器模式的作用

问题:适配器模式的作用是什么?

答案

  • 定义:将两个不兼容的接口进行衔接,使它们能够互联互通。
  • 应用场景
    • 系统迁移,上游接口变化,下游调用者需适配新接口。
    • 旧对象在新系统中运行,通过适配器完成接口转换。
  • 实现方式
    • 适配器实现目标接口。
    • 适配器持有目标对象。
    • 适配器重写目标接口方法,完成数据或接口转换。

示例

java">// 目标接口
public interface TargetInterface {void operation();
}// 需要适配的类
public class Adaptee {public void specificOperation() {// 特定操作}
}// 适配器
public class Adapter implements TargetInterface {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void operation() {adaptee.specificOperation();}
}

http://www.ppmy.cn/ops/166994.html

相关文章

轨迹优化 | 基于梯度下降的路径规划算法(附ROS C++/Python仿真)

目录 0 专栏介绍1 梯度下降路径规划2 代价势场生成方法3 算法仿真3.1 ROS C仿真3.2 Python仿真 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及更高阶的运动规划算法轨迹优化实战&#xff0c;包括&#xff1a;曲线生成、碰撞检测、安全…

微软 LIDA 库:基于大模型的自动化数据分析与可视化

微软 LIDA 库&#xff1a;基于大模型的自动化数据分析与可视化 一、核心架构与 LLM 交互流程 #mermaid-svg-UzSwZNKPlgrJUpej {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UzSwZNKPlgrJUpej .error-icon{fill:#5…

【原创】使用ElasticSearch存储向量实现大模型RAG

一、概述 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;已成为大型语言模型&#xff08;LLM&#xff09;应用的重要架构&#xff0c;通过结合外部知识库来增强模型的回答能力&#xff0c;特别是在处理专业领域知识、最新信息或企业私有数…

再学:函数可见性、特殊函数、修饰符

目录 1.可见性 2.合约特殊函数 constructor && getter 3. receive && fallback 4.view && pure 5.payable 6.自定义函数修饰符 modifier 1.可见性 public&#xff1a;内外部 private&#xff1a;内部 external&#xff1a;外部访问 internal&…

贪心算法——c#

贪心算法通俗解释 贪心算法是一种"每一步都选择当前最优解"的算法策略。它不关心全局是否最优&#xff0c;而是通过局部最优的累积来逼近最终解。优点是简单高效&#xff0c;缺点是可能无法得到全局最优解。 一句话秒懂 自动售货机找零钱&#xff1a;用最少数量的…

代码随想录算法训练营第六十五天| 图论10

Bellman_ford 队列优化算法&#xff08;又名SPFA&#xff09; 代码随想录 import collectionsdef main():n, m map(int, input().strip().split())edges [[] for _ in range(n 1)]for _ in range(m):src, dest, weight map(int, input().strip().split())edges[src].append…

进程间通信--匿名管道

进程间通信介绍 进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某种事件&…

网络安全运维应急响应与溯源分析实战案例

在日常运维过程中&#xff0c;网络安全事件时有发生&#xff0c;快速响应和精准溯源是保障业务稳定运行的关键。本文将通过一个实际案例&#xff0c;详细解析从发现问题到溯源定位&#xff0c;再到最终解决的完整流程。 目录 一、事件背景 二、事件发现 1. 监控告警触发 2…