设计模式面试专题

文章目录

  • 请列举出在 JDK 中几个常用的设计模式?
  • 什么是设计模式?
  • Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
  • 在 Java 中,什么叫观察者设计模式(observer design pattern)?
  • 使用工厂模式最主要的好处是什么?在哪里使用?
  • 举一个用 Java 实现的装饰模式(decorator design pattern)?它是作用于对象层次还是类层次?
  • 在 Java 中,为什么不允许从静态方法中访问非静态变量?
  • 设计一个 ATM 机,请说出你的设计思路?
  • 在 Java 中,什么时候用重载,什么时候用重写?
  • 举例说明什么情况下会更倾向于使用抽象类而不是接口?


请列举出在 JDK 中几个常用的设计模式?

  1. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。在 JDK 中,Runtime 类就是一个典型的单例模式的应用,通过 Runtime.getRuntime() 方法获取运行时对象的唯一实例。

  2. 工厂模式(Factory Pattern):定义一个用于创建对象的接口,但由子类决定实例化哪个类。在 JDK 中,例如 Boolean.valueOf(boolean) 方法就是一个工厂方法,根据传入的参数返回 Boolean 类的实例。

  3. 观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在 JDK 中,Swing 中的事件监听机制就是观察者模式的一个典型应用。

  4. 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就扩展功能而言,装饰器模式比继承更为灵活。在 JDK 中,java.io 包中的很多类(如 BufferedInputStreamBufferedOutputStream 等)就使用了装饰器模式来增强 I/O 功能。

什么是设计模式?

设计模式是解决特定问题的经过反复验证的通用解决方案。它们提供了一种标准的方法来解决常见的设计问题,帮助开发人员编写更加模块化、可维护和可扩展的代码。

Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

单例设计模式确保某个类只有一个实例,并提供一个全局访问点。这种模式通常用于管理共享资源,或者需要限制某个类的实例个数的情况。

以下是一个使用枚举实现的线程安全的单例模式示例:

public enum Singleton {INSTANCE;// 可以在这里添加单例的其他属性和方法// 示例方法public void showMessage() {System.out.println("Hello, World!");}
}// 在其他类中使用单例
// Singleton.INSTANCE.showMessage();

使用枚举实现的单例模式具有以下优点:

  1. 线程安全:枚举类的实例是在类加载时创建的,由 JVM 保证线程安全。
  2. 简洁明了:代码简洁,无需手动实现双重检查锁等复杂的线程安全机制。
  3. 序列化安全:枚举类默认实现了 Serializable 接口,并且保证在反序列化时仍然是单例的。

因此,在现代 Java 应用中,推荐使用枚举实现单例模式。

在 Java 中,什么叫观察者设计模式(observer design pattern)?

观察者设计模式(Observer Design Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象状态发生变化时,所有的观察者都会得到通知并自动更新。

在观察者模式中,有以下几个核心角色:

  1. 主题(Subject): 也称为被观察者或可观察者,它是被观察的对象。当其状态发生变化时,会通知所有注册的观察者。
  2. 观察者(Observer): 也称为订阅者或监听者,它是接收主题状态变化通知的对象,以便进行相应的操作。
  3. 具体主题(Concrete Subject): 实现了主题接口,负责维护一组观察者,并在自身状态发生变化时通知观察者。
  4. 具体观察者(Concrete Observer): 实现了观察者接口,定义了收到通知后所需执行的操作。

观察者模式在实际应用中具有广泛的应用,例如:

  • GUI 程序中的事件处理机制。
  • 订阅-发布系统中,发布者是主题,订阅者是观察者。
  • 观察者模式也被广泛应用于 Java 中的事件监听器(Listener)机制、Swing 中的 MVC 架构等。

使用观察者模式可以实现松耦合的对象间交互,提高系统的灵活性和可扩展性。

使用工厂模式最主要的好处是什么?在哪里使用?

工厂模式的主要好处包括:

  1. 封装创建过程: 工厂模式将对象的创建过程封装在工厂类中,客户端代码只需要通过工厂类来获取所需对象,而无需了解对象创建的具体细节和逻辑。这样可以降低客户端与具体产品类之间的耦合度。

  2. 简化客户端代码: 客户端只需关注所需对象的接口或抽象类,而不需要关心具体的实现类。这样使得客户端代码更加简洁清晰。

  3. 提高代码的可维护性和扩展性: 当需要添加新的产品类时,只需创建相应的产品类和工厂类即可,无需修改现有客户端代码,符合开闭原则。

  4. 隐藏产品类的实现细节: 客户端无需了解产品类的具体实现细节,只需要知道如何使用产品对象即可。这样可以有效地隐藏产品类的实现细节,提高了系统的安全性和稳定性。

工厂模式通常在以下情况下使用:

  • 当一个类不知道它所必须创建的对象的类时。
  • 当一个类希望它的子类来指定它所创建的对象时。
  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望能够将哪一个帮助子类是代理决策者。

工厂模式是一种常见的设计模式,被广泛应用于软件开发中,特别是在需要根据不同条件创建不同类型对象实例的场景中。

举一个用 Java 实现的装饰模式(decorator design pattern)?它是作用于对象层次还是类层次?

装饰模式增加强了单个对象的能力。Java IO 到处都使用了装饰模式,典型例子就是
Buffered 系列类如 BufferedReader 和 BufferedWriter,它们增强了 Reader 和 Writer 对象,
以实现提升性能的 Buffer 层次的读取和写入。

以下是一个简单的示例,演示了如何使用装饰模式实现一个咖啡店的咖啡订单系统:

// 定义咖啡接口
interface Coffee {String getDescription();double getCost();
}// 实现基础咖啡类
class BasicCoffee implements Coffee {@Overridepublic String getDescription() {return "Basic Coffee";}@Overridepublic double getCost() {return 2.0;}
}// 定义装饰器抽象类
abstract class CoffeeDecorator implements Coffee {protected Coffee decoratedCoffee;public CoffeeDecorator(Coffee decoratedCoffee) {this.decoratedCoffee = decoratedCoffee;}@Overridepublic String getDescription() {return decoratedCoffee.getDescription();}@Overridepublic double getCost() {return decoratedCoffee.getCost();}
}// 具体的装饰器类:加奶
class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee decoratedCoffee) {super(decoratedCoffee);}@Overridepublic String getDescription() {return super.getDescription() + " + Milk";}@Overridepublic double getCost() {return super.getCost() + 0.5; // 加奶价格}
}// 具体的装饰器类:加糖
class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee decoratedCoffee) {super(decoratedCoffee);}@Overridepublic String getDescription() {return super.getDescription() + " + Sugar";}@Overridepublic double getCost() {return super.getCost() + 0.3; // 加糖价格}
}// 客户端代码
public class Main {public static void main(String[] args) {// 创建基础咖啡对象Coffee basicCoffee = new BasicCoffee();// 使用装饰器逐步装饰咖啡Coffee milkCoffee = new MilkDecorator(basicCoffee);Coffee sugarMilkCoffee = new SugarDecorator(milkCoffee);// 输出最终咖啡的描述和价格System.out.println("Description: " + sugarMilkCoffee.getDescription());System.out.println("Cost: $" + sugarMilkCoffee.getCost());}
}

在这个示例中,Coffee 接口定义了咖啡对象的基本行为,BasicCoffee 类是一个具体的咖啡实现。CoffeeDecorator 抽象类实现了 Coffee 接口,并持有一个 Coffee 对象作为成员变量,它是装饰器的基类。具体的装饰器类 MilkDecoratorSugarDecorator 继承自 CoffeeDecorator,并在原有的基础上添加了额外的功能。通过装饰器模式,可以动态地组合各种功能来创建不同的咖啡对象,而且可以灵活地添加或删除装饰器,而不影响原有的对象结构。

在 Java 中,为什么不允许从静态方法中访问非静态变量?

在 Java 中,静态方法属于类而不是对象实例,它们在类加载时就被加载到内存中,并且可以直接通过类名调用,而不需要创建类的实例。由于静态方法没有随着对象的创建而创建,因此在静态方法中无法直接访问非静态的成员变量,因为非静态变量是与对象实例相关联的,而静态方法在调用时可能并不存在任何对象实例。

如果静态方法需要访问非静态成员变量,通常需要满足以下两种方式之一:

  1. 将非静态变量也声明为静态变量,使其与类相关联而不是对象实例。这样静态方法就可以直接访问它们。
  2. 在静态方法中通过参数传递对象实例的引用,并通过该引用访问对象的非静态成员变量。

总之,静态方法在设计时应该尽量避免依赖于对象实例的状态,而应该专注于与类相关的操作。

设计一个 ATM 机,请说出你的设计思路?

设计一个ATM机可以包括以下几个方面的考虑:

  1. 用户认证和授权:用户需要提供有效的身份验证信息,如银行卡号和密码,以便ATM机能够确认其身份并授权其进行交易。

  2. 用户界面:ATM机需要提供友好的用户界面,包括屏幕显示、按键输入和语音提示等功能,以便用户能够方便地操作。

  3. 交易处理:ATM机需要支持各种交易类型,如取款、存款、转账、查询余额等,并且需要保证交易的安全性和可靠性。

  4. 硬件设备:ATM机需要包括各种硬件设备,如卡片读取器、键盘、屏幕、打印机、钞箱等,以支持各种交易需求。

  5. 安全性:ATM机需要具有高度的安全性,包括物理安全和逻辑安全,以防止各种安全威胁,如盗窃、欺诈和黑客攻击等。

  6. 日志和监控:ATM机需要记录所有的交易操作并生成相应的日志,以便进行交易追踪和监控,并且需要实时监控ATM机的状态和运行情况。

  7. 网络连接:ATM机需要与银行系统进行实时通讯,以便进行交易处理和账户信息更新等操作。

综上所述,设计一个ATM机需要综合考虑用户需求、系统安全性、硬件设备、网络通讯等多个方面,以确保ATM机能够稳定可靠地运行,并为用户提供良好的交易体验。

在 Java 中,什么时候用重载,什么时候用重写?

在 Java 中,当需要在同一个类中为相同的方法提供不同的实现时,可以使用方法的重载(overloading)。方法的重载是指在同一个类中定义多个方法,它们具有相同的名称但参数列表不同的特性。通过方法的重载,可以根据方法的参数类型、个数或顺序来决定调用哪个方法。

而当需要子类继承父类的方法并提供不同的实现时,可以使用方法的重写(overriding)。方法的重写是指子类定义一个与父类方法签名相同的方法,从而覆盖父类的方法实现。在重写中,子类可以重新定义方法的实现逻辑,以满足自己的特定需求。在重写时,子类方法的访问修饰符不能比父类方法的更严格,并且不能抛出比父类方法更多的异常。

总的来说,重载是在同一个类中为同一个方法提供不同的版本,而重写是子类继承父类方法并提供新的实现。重载用于方法名相同但参数不同的情况,而重写用于继承和多态的实现。

举例说明什么情况下会更倾向于使用抽象类而不是接口?

以下情况下可能更倾向于使用抽象类而不是接口:

  1. 当你需要在类的继承层次结构中提供一组通用行为,并且这些行为具有某种默认实现时,可以使用抽象类。抽象类可以为一些方法提供默认实现,而子类可以选择性地覆盖这些方法以满足特定需求。这样可以避免在每个子类中重复编写相同的代码。
abstract class Shape {// 抽象方法abstract double area();abstract double perimeter();// 默认实现void display() {System.out.println("This is a shape.");}
}
  1. 当你希望将一些相关的类组织在一起,并且它们共享某些通用特征时,可以使用抽象类。通过将这些类放在同一个抽象类的继承层次结构中,可以更清晰地表达它们之间的关系。
abstract class Animal {abstract void makeSound();
}class Dog extends Animal {void makeSound() {System.out.println("Woof");}
}class Cat extends Animal {void makeSound() {System.out.println("Meow");}
}
  1. 当你需要在类中定义一些非抽象方法,并且希望子类共享这些方法时,可以使用抽象类。抽象类可以包含非抽象方法的实现,这些方法可以直接在子类中使用,而无需重新实现。
abstract class Vehicle {void startEngine() {System.out.println("Engine started");}abstract void accelerate();
}class Car extends Vehicle {void accelerate() {System.out.println("Car is accelerating");}
}

总的来说,抽象类适合于在类的继承层次结构中提供通用行为和共享特征,以及需要为子类提供一些默认实现的情况。

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

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

相关文章

富格林:可信要领戒备虚假套路

富格林指出,为避免遭遇虚假套路而造成巨大亏损,投资者需灵活地采用一些可信的交易技巧作为抵抗风险的重要手段。投资者进入市场后,需要的系统学习正规做单技巧,树立正规做单的意识规避虚假套路,提高做单盈利。接下来总…

位运算符与位移运算符

按位与& 两个二进制数字都是1 取1否则取0 按位或I 两个二进制数字都是0取0否则取1 按位取反~如果该位为0则1 &#xff0c;为1取0 按位异或 ^ 相同为零相反为1 移位运算符 有三个: <<, >> ,>>>&#xff0c;都是二元运算符&#xff0c;且都是按…

iPhone 15 Pro LiDAR Module模组逆向(2024.3.23)

iPhone15 Pro出来后,基本上国内所有的模组厂包括舜宇,丘钛等都已经逆向了LiDAR模组,并同时测试了电学,光学,BOM成本等一系列测试。当然市面上最具备影响力的是YOLE的商业评估报告,我这边同时具有这些报告,也有一些自己的见解,当然本篇讲解可能会同时涉及到几个模组厂和…

Python爬虫-批量爬取星巴克全国门店

前言 本文是该专栏的第22篇,后面会持续分享python爬虫干货知识,记得关注。 本文笔者以星巴克为例,通过Python实现批量爬取目标城市的门店数据以及全国的门店数据。 具体的详细思路以及代码实现逻辑,跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM…

【前端寻宝之路】JavaScript初学之旅

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-azUa9yH16cRXQUxE {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

解读EPO电梯行业数智化平台功能模块,开启电梯行业智能之旅

在当今的电梯行业中&#xff0c;数字化和智能化已经成为提升运营效率和服务质量的关键。EPO电梯行业数智化运营平台凭借其出色的功能模块&#xff0c;为行业带来了创新和变革。那么我们今天就来讲讲国辰智企的EPO电梯行业数智化运营平台的功能吧。 1、EOS土建出图&#xff1a;这…

【STK】手把手教你利用STK进行导弹和反导仿真02 - STK/MMT模块01 导弹任务分析工具概述

导弹任务分析工具 Missile Mission Toolbox MMT包括4个部分,分别是 导弹设计工具 Missile Design Tool MDT 导弹飞行工具 Missile Flight Tool MFT 拦截飞行工具 Interceptor Flight Tool MCT 导弹转换工具 Missile Conversion Tool MCT 可以用于 创建高保真弹道 评估导弹系统…

贝尔曼最优方程【BOE】

强化学习笔记 主要基于b站西湖大学赵世钰老师的【强化学习的数学原理】课程&#xff0c;个人觉得赵老师的课件深入浅出&#xff0c;很适合入门. 第一章 强化学习基本概念 第二章 贝尔曼方程 第三章 贝尔曼最优方程 文章目录 强化学习笔记一、最优策略二、贝尔曼最优方程(BOE)三…

【linux】进程1 -- 属性

文章目录 进程PCBlinux查看进程 进程属性task_struct结构体一、进程标识符父子进程 二、进程状态磁盘睡眠 -- D 暂停和跟踪暂停 -- T和t僵尸进程 -- Z孤儿进程 三、进程优先级 进程 课本概念&#xff1a;程序的一个执行实例&#xff0c;正在执行的程序&#xff0c;操作系统进行…

反序列化漏洞简单知识

目录&#xff1a; 一、概念&#xff1a; 二、反序列化漏洞原因 三、序列化漏洞的魔术方法&#xff1a; 四、反序列化漏洞防御&#xff1a; 一、概念&#xff1a; 序列化&#xff1a; Web服务器将HttpSession对象保存到文件系统或数据库中&#xff0c;需要采用序列化的…

nodejs+vue反诈科普平台的设计与实现pythonflask-django-php

相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低反诈科普平台的运营人员成本&#xff0c;实现了反诈科普平台的标准化、制度化、程序化的管理&#xff0c;有效地防止了反诈科普平台的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够…

AIGC、3D模型、轻量化、格式转换、可视化、数字孪生引擎...

老子云3D可视化快速开发平台&#xff0c;集云压缩、云烘焙、云存储云展示于一体&#xff0c;使3D模型资源自动输出至移动端PC端、Web端&#xff0c;能在多设备、全平台进行展示和交互&#xff0c;是全球领先、自主可控的自动化3D云引擎。 平台架构 平台特性 基于 HTML5 和 Web…

IP 报头和以太网报头

IP 报头和以太网报头是计算机网络中两个重要的报头&#xff0c;它们分别用于网络层和数据链路层。虽然它们都包含用于路由和寻址信息&#xff0c;但它们在功能和结构上存在着一些关键差异。 IP 报头 IP 报头是网络层协议&#xff0c;它负责在网络上路由数据包。它包含以下信息…

微信小程序实现多张照片上传

hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;code袁 &#x1f4a5; 所属专栏&…

springboot+vue导出excel并下载

引入easyexcel依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>编写接口 /*** 批量导出** param ids* return*/PostMapping("/export"…

​如何下载virtualbox的旧版本​

1. 打开VirtualBox官网&#xff1a;https://www.virtualbox.org/wiki/Download_Old_Builds 2. 在页面上找到“VirtualBox 5.2.x”或者“VirtualBox 6.0.x”等旧版本的链接&#xff0c;点击进入。 3. 在页面上找到对应操作系统的下载链接&#xff0c;点击下载。 4. 下载完成后…

Linux 进程通信:命名管道、共享内存

目录 一、命名管道 1、概念 2、特点 3、原理 4、创建 5、匿名管道与命名管道的区别 6、命名管道的打开规则 二、命名管道—实现客户端和服务器之间的通信 1、Makefile 2、comm.hpp 3、Log.hpp 4、server.cxx 5、client.cxx 运行测试&#xff1a; 三、system V…

java泛型详解

java泛型详解 目录 一、泛型类 二、泛型方法 三、类型变量限定 四、类型擦除 4.1与4.2&#xff1a;虚拟机中没有泛型 4.3&#xff1a;翻译泛型表达式 五、继承规则&#xff08;通配符的上下限&#xff09; 捕获通配符。 六、约束与局限性 大部分的泛型文章只涉及到泛…

Matlab进阶绘图第47期—气泡分组蝴蝶图

气泡分组蝴蝶图是分组蝴蝶图与气泡图的组合——在分组蝴蝶图每组柱子上方添加大小不同的气泡&#xff0c;用于表示另外一个数据变量&#xff08;如每组柱子值的和&#xff09;的大小。 本文利用自己制作的BubbleButterfly工具&#xff0c;进行气泡分组蝴蝶图的绘制&#xff0c…

Docker 入门使用说明

Docker 入门使用说明 Docker 安装 Docker 官网&#xff1a;Docker Docker 安装说明&#xff1a;Docker 安装说明 这里由于 Docker 在实时更新&#xff0c;所以每次安装 Docker 用来导入 key 的链接可能会有变化&#xff0c;这里就参考官方的安装方法即可 Docker 常用命令说…