IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 设计模式相关面试题集合 -> 正文阅读

[Java知识库]设计模式相关面试题集合

1、单例模式

定义:它是java所有设计模式中最简单的一种,它提供了一个创建对象的最佳方法,

那些地方用到了单例模式?

1、网站计数器,一般采用单例模式,否则难以同步
2、应用程序的日志应用一般采用单例模式
3、多线程的线程池一般也是采用单例模式
4、windows中的任务管理器是典型的单例模式,不可以开启两个
5、windows中的回收站也是单例模式

单例模式的创建?

主要是懒汉式和饿汉式
1、饿汉式:类初始化的时候会立刻加载该对象,天生的线程安全,调用效率高。

饿汉式实现的步骤:
1、构造器私有化.
2、类的内部创建一个对象的实例。
3、向外提供一个静态的方法用来获取对象的实例。

优点:在类加载的过程中就创建的实例,避免的线程同步的问题(线程的聚绝对安全)。
缺点:如果从开始的时候就没有使用这个实例,就造成的内存的浪费。

class Singleton{
    //1.私有化构造器
    private Singleton(){
    }
    //类的内部创建一个对象实例
    private  final  static Singleton instance =new Singleton();
    //3.提供一个公有的静态的方法,返回对象的实例
     public static Singleton getInstance(){
         return  instance;
     }
}

 public static void main(String[] args) {
        //测试
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        //调用两个方法获取的对象实例,是相同的
        System.out.println(instance==instance1);
        //获取两个实例的hashcode
        System.out.println(instance.hashCode());
        System.out.println(instance1.hashCode());
    }

true
1956725890
1956725890

2、懒汉式:类初始化的时候,不会初始化该对象,真正使用的时候才会创建该对象,具有懒加载的功能。

实现步骤:
1、私有化构造器
2、向外提供一个静态的方法,用来获取对象的实例。

优点:实现了懒加载的效果,但是只能在单线程的情况下使用。
缺点:如果两个线程同时进入了if条件语句,那么就会创建多个实例(线线程不安全)

class  Singleton{
    //1.私有化构造器
    private Singleton(){
    }
    private static Singleton instance;
    //2.提供一个静态的公有方法,使用该方法创建一个对象的实例
    public static  Singleton getInstance(){
        if(instance ==null){
            instance = new Singleton();
        }
        return instance;
    }
}

 public static void main(String[] args) {
        //测试
        System.out.println("这是懒汉式,线程不安全");
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        //调用两个方法获取的对象实例,是相同的
        System.out.println(instance==instance1);
        //获取两个实例的hashcode
        System.out.println(instance.hashCode());
        System.out.println(instance1.hashCode());
    }
这是懒汉式,线程不安全
true
1956725890
1956725890

3、内部静态类的方法:结合了懒汉式和饿汉式的各自的优点,真正需要对象的时候才会加载,加载类是线程安全的。

class  Singleton {
    private static volatile Singleton instance;
    //1.私有化构造器
    private Singleton() {
    }
    //写一个静态内部类,该类中有一个静态的属性,Singleton
    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }
    //2.提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
    //synchronized关键字
    public static synchronized Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

4、枚举单例:使用枚举实现单例模式,实现简单,调用率高,枚举的本身就是一个单例模式,由JVM从根本上提供保障。

2、工厂模式?

1、它提供了一种创建对象的最佳方式。
2、在工厂模式中通过使用一个共同的接口来指向新创建的对象。实现了创建者和调用者分离。
工厂模式分为简单工厂工厂方法抽象工厂模式
简单工厂 :用来生产同一等级结构中的任意产品。
工厂方法 :用来生产同一等级结构中的固定产品。
抽象工厂 :用来生产不同产品族的全部产品。

优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。

缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则

具体示例:

//首先创建一个图形类的公共接口
public interface Shape {
    void draw();
}
//创建接口的一个具体的实现类,长方形
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}
//正方形类
public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Square::draw() method.");
    }
}
//圆的类
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}
//实现一个创建图形的工厂
public class ShapeFactory {

    //使用 getShape 方法获取形状类型的对象
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        shapeType = shapeType.toLowerCase(); //将字符串所有的大写转换为小写
        switch (shapeType) {
            case "circle":
                return new Circle();
            case "rectangle":
                return new Rectangle();
            case "square":
                return new Square();
            default:
                return null;
        }
    }
}

1、代理模式

1.1静态代理

  • 静态代理:由程序员创建,也就是在编译时就将接口、被代理类、代理类等确定下来,在程序运行之前,代理类.class文件以及生成。
  • 它主要就是有一个公共的接口、一个被代理类,以及一个代理类,这两个类都实现了这个接口,这个公共的接口定义了被代理类的一个行为规范,代理类持有被代理类的具体实现方法,而且代理类还可以在执行被代理类的方法之前添加额外的行为,这就是代理模式的一个很大的优点,体现最直白的地方就是SpringAOP(面向切面编程),我们可以在切点之前和之后都添加一些操作,而这些切点就是一些方法,而这些方法所在的类就是被代理的,这也是面向编程的主要思想。
  • 示例:
/**
 * 创建Person接口公共接口
 */
public interface Person {
    //上交班费
    void giveMoney();
}
//学术类实现了Person接口,实现类具体的方法
public class Student implements Person {
    private String name;
    public Student(String name) {
        this.name = name;
    }
    @Override
    public void giveMoney() {
       System.out.println(name + "上交班费50元");
    }
}
/**
 * 学生代理类,也实现了Person接口,保存一个学生实体,这样既可以代理学生产生行为
 * @author Gonjan
 *
 */
public class StudentsProxy implements Person{
    //被代理的学生
    Student stu;
    
    public StudentsProxy(Person stu) {
        // 只代理学生对象
        if(stu.getClass() == Student.class) {
            this.stu = (Student)stu;
        }
    }
    
    //代理上交班费,调用被代理学生的上交班费行为
    public void giveMoney() {
        stu.giveMoney();
    }
}
//客户端的操作与行为
public class StaticProxyTest {
    public static void main(String[] args) {
        //被代理的学生张三,他的班费上交有代理对象monitor(班长)完成
        Person zhangsan = new Student("张三");
        //生成代理对象,并将张三传给代理对象
        Person monitor = new StudentsProxy(zhangsan);
        //班长代理上交班费
        monitor.giveMoney();
    }
}

1.2动态代理

3、观察者模式

  • 对象之间存在着一对多的关系,那就使用观察者模式,比如当一个对象被修改的时候,可以自动通知它依赖的对象做出相对应的更新修改。
  • 一般来说观察者模式主要有三各类,Subject(主题类),Observe抽象类(观察类),Cilent(客户端),Subject类主要实现存储观察者的一个ArrayList,将观察者添加到观察列表中的方法attach(),以及通知所有观察者的方法notifyAllObserve()方法。以及状态的修改方法setStatue()。
  • 示例:
public class Subject {
       //首先是一个添加观察者的列表
    private List<Observer> observers = new ArrayList<>();
      //一个状态值,状态改变那么就通知其他的观察者改变
    private int state;
    
    public int getState() {
        return state;
    }
    public void setState(int state) {
        this.state = state;
        notifyAllObservers();
    }
    //添加到观察者列表之中
    public void attach(Observer observer) {
        observers.add(observer);
    }
    //通知所有的观察者去自动更新
    public void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

//抽象的观察者方法,以便于观察者实现
public abstract class Observer {

    protected Subject subject;

    public abstract void update();

}
//创建多个实体类观察者,实现更新方法
public class BinaryObserver extends Observer {

    public BinaryObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("Binary String: "
                + Integer.toBinaryString(subject.getState()));
    }
}

public class OctalObserver extends Observer {

    public OctalObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Octal String: "
                + Integer.toOctalString( subject.getState() ) );
    }

}
public class HexaObserver extends Observer {

    public HexaObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Hex String: "
                + Integer.toHexString( subject.getState() ).toUpperCase() );
    }

}
public class ObserverPatternDemo {

    public static void main(String[] args) {
        Subject subject = new Subject();

        new BinaryObserver(subject);
        new HexaObserver(subject);
        new OctalObserver(subject);

        System.out.println("First state change: 15");
        subject.setState(15);
        System.out.println();

        System.out.println("Second state change: 10");
        subject.setState(10);
    }
}
First state change: 15
Binary String: 1111
Hex String: F
Octal String: 17

Second state change: 10
Binary String: 1010
Hex String: A
Octal String: 12

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-30 11:48:08  更:2021-09-30 11:50:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:16:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码