Java面试题(含答案)9.设计模式类型篇

news/2024/6/20 21:24:26/文章来源:https://blog.csdn.net/pythontxt/article/details/137182132

1. 什么是设计模式?为什么我们需要设计模式?

答案:
设计模式是在软件开发中解决特定问题的最佳实践。它们是在长期软件开发中积累的经验的总结,可以帮助我们更高效地编写可维护、可扩展和可重用的代码。设计模式使代码结构更加清晰,提高了代码的可读性和可维护性,同时也有助于开发人员之间的沟通和协作。

2. 请解释单例模式,并给出一个Java实现示例

答案:
单例模式确保一个类仅有一个实例,并提供一个全局访问点。

public class Singleton {  private static Singleton instance;  private Singleton() {} // 私有构造方法,防止外部实例化  public static synchronized Singleton getInstance() {  if (instance == null) {  instance = new Singleton();  }  return instance;  }  
}

注意:上面的实现是线程安全的,但性能较差。在实际应用中,通常会使用双重检查锁定或静态内部类等方式来实现线程安全且高效的单例。

3. 请解释工厂模式,并给出一个Java实现示例

答案:
工厂模式用于封装对象的创建过程,将对象的创建与使用分离。

public interface Car {  void drive();  
}  public class BMW implements Car {  @Override  public void drive() {  System.out.println("Driving BMW");  }  
}  public class CarFactory {  public static Car createCar() {  return new BMW(); // 可以根据需要返回不同的Car实现  }  
}

4. 请解释观察者模式,并给出一个Java实现示例

答案:
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,它的所有依赖者(观察者)都会自动收到通知并更新。

import java.util.ArrayList;  
import java.util.List;  public interface Observer {  void update(String message);  
}  public class Subject {  private List<Observer> observers = new ArrayList<>();  private String message;  public void attach(Observer observer) {  observers.add(observer);  }  public void detach(Observer observer) {  observers.remove(observer);  }  public void notifyObservers() {  for (Observer observer : observers) {  observer.update(message);  }  }  public void setMessage(String message) {  this.message = message;  notifyObservers();  }  
}

然后你可以创建实现了Observer接口的类,并将其附加到Subject上,以便在主题状态变化时接收通知。

5. 请解释建造者模式,并给出一个Java实现示例

答案:
建造者模式将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

public class Computer {  private String ram;  private String hdd;  private String cpu;  private Computer(Builder builder) {  this.ram = builder.ram;  this.hdd = builder.hdd;  this.cpu = builder.cpu;  }  public static class Builder {  private String ram;  private String hdd;  private String cpu;  public Builder setRam(String ram) {  this.ram = ram;  return this;  }  public Builder setHdd(String hdd) {  this.hdd = hdd;  return this;  }  public Builder setCpu(String cpu) {  this.cpu = cpu;  return this;  }  public Computer build() {  return new Computer(this);  }  }  
}

使用建造者模式创建Computer对象:

Computer computer = new Computer.Builder()  .setRam("8GB")  .setHdd("500GB")  .setCpu("Intel Core i7")  .build();

6. 请解释适配器模式,并给出一个Java实现示例

答案:
适配器模式将一个类的接口转换成客户端所期望的另一种接口,使得原本由于接口不兼容而无法一起工作的类能够一起工作。

public interface Target {  void request();  
}  public class Adaptee {  public void specificRequest() {  System.out.println("Called specificRequest()");  }  
}  public class Adapter implements Target {  private Adaptee adaptee;  public Adapter(Adaptee adaptee) {  this.adaptee = adaptee;  }  @Override  public void request() {  adaptee.specificRequest();  }  
}

7. 请解释原型模式,并给出一个Java实现示例

答案:
原型模式用于创建重复的对象,同时又能保证性能。这种模式涉及将一个对象用作创建新对象的原型,然后复制这个原型对象来创建更多相同类型的对象。

public class Prototype implements Cloneable {  private String name;  public Prototype(String name) {  this.name = name;  }  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  @Override  protected Object clone() throws CloneNotSupportedException {  return super.clone();  }  
}

使用原型模式创建对象:

Prototype prototype = new Prototype("Original");  
Prototype clonedPrototype;  try {  clonedPrototype = (Prototype) prototype.clone();  clonedPrototype.setName("Cloned");  
} catch (CloneNotSupportedException e) {  e.printStackTrace();  
}

8. 请解释模板方法模式,并给出一个Java实现示例

答案:
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。

public abstract class AbstractClass {  public final void templateMethod() {  specificMethod1();  specificMethod2();  }  protected abstract void specificMethod1();  protected abstract void specificMethod2();  
}  public class ConcreteClass extends AbstractClass {  @Override  protected void specificMethod1() {  System.out.println("ConcreteClass specificMethod1");  }  @Override  protected void specificMethod2() {  System.out.println("ConcreteClass specificMethod2");  }  
}

使用模板方法模式:

AbstractClass abstractClass = new ConcreteClass();  
abstractClass.templateMethod(); // 输出:ConcreteClass specificMethod1, ConcreteClass specificMethod2

9. 请解释策略模式,并给出一个Java实现示例

答案:
策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端变化。

public interface Strategy {  int doOperation(int num1, int num2);  
}  public class OperationAdd implements Strategy {  @Override  public int doOperation(int num1, int num2) {  return num1 + num2;  }  
}  public class OperationSubtract implements Strategy {  @Override  public int doOperation(int num1, int num2) {  return num1 - num2;  }  
}  public class Context {  private Strategy strategy;  public Context(Strategy strategy) {  this.strategy = strategy;  }  public int executeStrategy(int num1, int num2) {  return strategy.doOperation(num1, num2);  }  
}

使用策略模式:

Context context = new Context(new OperationAdd());  
System.out.println("10 + 5 = " + context.executeStrategy(10, 5)); // 输出:10 + 5 = 15  context = new Context(new OperationSubtract());  
System.out.println("10 - 5 = " + context.executeStrategy(10, 5)); // 输出:10 - 5 = 5

10. 请谈谈你对建造者模式的理解,并给出一个使用场景

答案:
建造者模式将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。建造者模式通常包含建造者接口、具体建造者类和产品类。

使用场景:在需要生成具有多个选项或配置的产品对象时,可以使用建造者模式。例如,在配置一个复杂的订单系统时,订单可能包含多个产品,每个产品又有多种可选配置,如颜色、尺寸、数量等。通过建造者模式,我们可以逐步构建一个订单对象,同时保持构建过程的灵活性和可读性。

11. 观察者模式是什么?请给出一个实际应用的例子

答案:
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生改变时,它的所有依赖者(观察者)都会自动收到通知并更新。

实际应用例子:在GUI编程中,观察者模式常用于实现事件处理机制。例如,当用户点击一个按钮时,按钮(主题对象)会发出一个点击事件,所有注册了该事件的监听器(观察者)都会收到通知并执行相应的操作,如更新界面、执行命令等。

12. 请描述单例模式的实现方式,并讨论其线程安全性问题

答案:
单例模式确保一个类仅有一个实例,并提供一个全局访问点。常见的实现方式包括饿汉式、懒汉式(双重检查锁定、静态内部类等)。

线程安全性问题:在多线程环境下,懒汉式实现可能会因为多个线程同时访问并创建实例而导致产生多个实例。为了确保线程安全,可以使用同步块或双重检查锁定等技术。双重检查锁定虽然可以提高性能,但需要注意正确实现以避免出现内存可见性和指令重排序问题。静态内部类方式是一种线程安全的单例实现方式,它利用了JVM的类加载机制来确保只创建一个实例。

13. 工厂方法和抽象工厂模式有何区别?

答案:
工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。而抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

区别:工厂方法模式关注的是单个对象的创建,而抽象工厂模式关注的是一系列相关或依赖对象的创建。工厂方法模式通常只有一个抽象产品类,而抽象工厂模式可能有多个抽象产品类。因此,抽象工厂模式具有更高的灵活性和扩展性,但实现起来也更复杂。

14. 请谈谈你对装饰器模式的理解,并给出一个使用场景

答案:
装饰器模式动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。装饰器模式是一种用于代替继承的技术,它通过一种无须修改已有类的方式来增加新功能。

使用场景:当需要动态地给一个对象增加功能,且这些功能可以动态地撤销时,可以使用装饰器模式。例如,在I/O流的设计中,Java的IO库使用了装饰器模式为基本的输入输出流类添加各种功能,如缓冲、同步等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1034963.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编译好的C++应用程序拷贝到其它电脑,提示dll未找到依赖项的解决方法。

编译好的C++应用程序拷贝到其它电脑上,运行时出现提示dll未找到依赖项。 由于dll依赖于其它dll,在开发用电脑上的环境不能完全与其它电脑相同。 解决办法是找到调用到的dll依赖的所有dll,拷贝到运行目录下。 在开发电脑上: 1、开始菜单--》所有应用--》Visual Studio 2…

QT网络调试助手

QT网络调试助手 1.开发流程 2.QTtcp服务器   1.1 服务端数据读取   1.2 服务端发送数据-所有客户端   1.3 服务端自动刷新ip地址   1.4 服务端检测客户端断开状态   1.5 服务端发送数据-指定特定客户端发送数据   1.6 服务端停止监听和断开 3.QTtcp客户端 1…

MinIO基础及面经

MinIO基础及面经 Minio是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟化镜像等&#xff0c;而一个对象文件可以是任意大小&a…

Thales SafeNet Sentinel HASP LDK本地提权漏洞(CVE-2024-0197)分析与复现

漏洞描述 Thales SafeNet Sentinel HASP LDK是一个软件保护和许可管理解决方案&#xff0c;用于帮助软件开发者保护其应用程序免受盗版和未经授权使用&#xff0c;由Thales SafeNet公司开发并提供支持。 该工具的msi安装程序在执行修复模式/fa时&#xff0c;存在DLL劫持漏洞。导…

【随笔】Git 高级篇 -- 分离 HEAD(十一)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

SpringBoot实现邮箱验证

目录 1、开启邮箱IMAP/SMTP服务&#xff0c;获取授权码 2、相关代码 1、使用配置Redis&#xff08;用于存储验证码&#xff0c;具有时效性&#xff09; 2、邮箱依赖和hutool&#xff08;用于随机生成验证码&#xff09; 3、配置Redis和邮箱信息 4、开启Redis服务 5、编写发送…

《QT实用小工具·四》屏幕拾色器

1、概述 源码放在文章末尾 该项目实现了屏幕拾色器的功能&#xff0c;可以根据鼠标指定的位置识别当前位置的颜色 项目功能包含&#xff1a; 鼠标按下实时采集鼠标处的颜色。 实时显示颜色值。 支持16进制格式和rgb格式。 实时显示预览颜色。 根据背景色自动计算合适的前景色…

1,static 关键字.Java

目录 1.概述 2.定义格式和使用 2.1 静态变量及其访问 2.2 实例变量及其访问 2.3 静态方法及其访问 2.4 实例方法及其访问 3.小结 1.概述 static表示静态&#xff0c;是Java中的一个修饰符&#xff0c;可以修饰成员方法&#xff0c;成员变量。被static修饰后的&#xff…

(八)Gateway服务网关

Gateway服务网关 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关&#xff0c;它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。…

openGauss学习笔记-254 openGauss性能调优-使用Plan Hint进行调优-子链接块名的hint

文章目录 openGauss学习笔记-254 openGauss性能调优-使用Plan Hint进行调优-子链接块名的hint254.1 功能描述254.2 语法格式254.3 参数说明254.4 示例 openGauss学习笔记-254 openGauss性能调优-使用Plan Hint进行调优-子链接块名的hint 254.1 功能描述 指明子链接块的名称。…

设计模式20--迭代器模式

定义 案例一 案例二 优缺点

C++的静态绑定和动态绑定、虚函数表的理解

C的静态绑定和动态绑定、虚函数表的理解 概念 在C中&#xff0c;静态绑定&#xff08;Static Binding&#xff09;和动态绑定&#xff08;Dynamic Binding&#xff09;是两种不同的函数调用机制&#xff0c;主要涉及到如何根据对象的类型来选择执行哪个函数的决定过程。这两种…

电商技术揭秘五:电商平台的个性化营销与数据分析

文章目录 引言1. 个性化营销的概念与价值1.1 个性化营销的定义1.1.1 个性化营销的基本概念1.1.2 个性化营销在电商领域的重要性 1.2 个性化营销的核心价值1.2.1 提升用户体验1.2.2 增加转化率和客户忠诚度1.2.3 优化营销资源配置 2. 用户画像与行为分析2.1 用户画像的构建2.1.1…

本地项目上传到GitHub

本文档因使用实际项目提交做为案例&#xff0c;故使用xxx等字符进行脱敏&#xff0c;同时隐藏了部分输出&#xff0c;已实际项目和命令行输出为准 0、 Git 安装与GitHub注册 1&#xff09; 在下述地址下载Git&#xff0c;安装一路默认下一步即可。安装完成后&#xff0c;随便…

道本科技智慧合规助力企业转型升级

在当今这个快速变化的商业世界里&#xff0c;企业合规管理已经从一项基本的监管要求转变为推动企业持续发展的关键动力。合规不仅是避免法律麻烦的盾牌&#xff0c;它还充当着引领企业向更高效、更可靠和更可持续方向发展的催化剂。而在实现这一目标的过程中&#xff0c;智慧合…

Linux中如何修改界面为中文, 设置中文输入法

目录 修改界面为中文方法一方法二方法三(kali中)方法四方法五(kali中) 切换为中文/英文输入法方法一方法二(kali中) 待续、更新中 修改界面为中文 方法一 查看当前系统拥有的中文语言包 locale -a | grep CN zh_CN.utf8 : 简体中文语言包 打开文件locale.conf vi /etc/lo…

完整部署一套k8s-v.1.28.0版本的集群

一、系统情况 虚拟机版本&#xff1a;esxi 6.7 系统版本&#xff1a;centos7.9_2009_x86 配置&#xff1a;4核8G&#xff08;官网最低要求2核2G&#xff09; 192.168.0.137 master节点 192.168.0.139 node2节点 192.168.0.138 node1节点&#xff08;节点扩容练习&#xf…

5.C++:string常用函数及模拟实现

一、resize() void test7() {string s("hello world");s.resize(5); //改变长度s.resize(20,x); //改变空间大小 } int main() {test7();return 0; } 二、string常用函数接口 1.打印 2.、push_back、append 3.迭代器&#xff0c;读写&#xff1b;s.begin()、s.…

Linux虚拟机环境搭建spark

Linux环境搭建Spark分为两个版本&#xff0c;分别是Scala版本和Python版本。 一、 安装Pyspark 本环境以 Python 环境为例。 1、下载spark 下载网址&#xff1a;https://archive.apache.org/dist/spark 下载安装包&#xff1a;根据自己环境选择合适版本&#xff0c;本环境…

爱上数据结构:栈和队列的概念及使用

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;数据结构 ​ 一、栈 1.栈的基本概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;…