【Java开发岗面试】八股文—设计模式

声明:

  1. 背景:本人为24届双非硕校招生,已经完整经历了一次秋招,拿到了三个offer。
  2. 本专题旨在分享自己的一些Java开发岗面试经验(主要是校招),包括我自己总结的八股文、算法、项目介绍、HR面和面试技巧等等,如有建议,可以友好指出,感谢,我也会不断完善。
  3. 想了解我个人情况的,可以关注我的B站账号:东瓜Lee
  1. 设计模式是什么?

    1. 设计模式通常是对于某一类软件设计问题的可重用解决方案,将设计模式引入软件设计和开发过程,目的主要是重用软件开发经验。
    2. 它一般用来解决同一问题的不同表相。
    3. 设计模式的两大主题是系统复用和系统扩展。
  2. 在项目中应用设计模式有什么好处?如果不用的话有什么坏处?

    1. 可维护性:
      1. 设计模式通常提供了一种结构化的方式来组织代码,使得代码更易于维护。模块化的结构使得修改、扩展或替换某个功能更加容易,因为每个设计模式都有特定的责任,变更只需要在特定的地方进行。
      2. 如果不用设计模式的话,没有明确定义的结构可能导致代码冗余和不一致性,增加了维护的难度。
    2. 扩展性:
      1. 设计模式强调松耦合和可扩展性,使得系统更容易适应变化。新的功能或需求可以通过添加新的模块或修改现有模块的方式来实现,而不影响整体系统的稳定性。
      2. 如果不用设计模式的话,紧密耦合的代码可能导致一个小的变化影响到整个系统,增加了引入新功能或进行改变时的风险。
    3. 可读性:
      1. 设计模式提供了一种常见的语言和结构,其他开发者更容易理解和维护这样的代码。熟悉设计模式的开发者能够更快速地理解代码逻辑。
      2. 如果不用设计模式的话,没有一致性的结构可能使代码难以阅读和理解,尤其是对于新加入的团队成员。
    4. 复用性:
      1. 许多设计模式都强调封装和复用,可以在不同的项目中应用相同的设计思想,提高代码的可复用性。
      2. 如果不用设计模式的话, 缺乏通用的设计原则可能导致代码片段难以在其他项目中复用。
    5. 问题解决能力:
      1. 一些设计模式是为了解决特定类型的问题而设计的,使用这些模式可以提高解决相应问题的效率。
      2. 如果不用设计模式的话,开发者可能需要花更多时间去思考和实现解决方案,而且这些解决方案可能没有经过充分的验证和实践。
  3. 常见的设计模式及其应用场景有什么?

    设计模式总共有23种,可以分为创建型模式、结构性模式、行为型模式,具体来说比如有:

    1. 单例模式:

      单例模式是一种创建型设计模式,它可以保证一个类只有一个实例,并提供全局访问。根据实现方式可以分为:

      1. 饿汉式单例模式是指在类加载时就创建了单例对象,因此在调用时不需要再创建对象,直接使用即可。
      2. 懒汉式单例模式是指在调用时才创建单例对象,这种实现方式避免了资源浪费,但是要用的时候就需要new对象,就要慢一些,而且也有线程安全问题。
      3. 双重检查锁单例模式是指在懒汉式单例模式的基础上加入了双重检查锁机制,可以保证线程安全,同时也避免了资源浪费。
      4. 静态内部类单例模式是指将单例对象作为静态内部类的一个静态变量,这种实现方式可以保证线程安全,同时也可以避免资源浪费。
      5. 枚举单例模式指将单例对象定义为一个枚举类型,这种实现方式可以保证线程安全,同时也可以防止反射和序列化攻击。
    2. 适配器模式:

      1. 适配器模式用于使不同接口的类能够一起工作
      2. 在项目中,可能需要将旧版本的接口适配成新版本,以保持系统的兼容性。
      3. 将一个接口转换成客户希望的另一个接口,这是适配器模式
    3. 装饰器模式:

      1. 装饰器模式允许动态地给对象添加额外的职责。
      2. 在实际应用中,可以用装饰器模式来扩展某个对象的功能,而不必修改其结构。
    4. 享元模式:

      1. 享元模式用于减少对象的数量,通过共享相似对象来减小内存占用。
      2. 在项目中,可以用享元模式来共享大量相似的对象,比如在游戏中共享相同图形的多个实例。
      3. 很多网络设备都是可以共享的,比如交换器、集线器等等,还比如多台终端计算机连接一台网络设备,这也是设备的共享,就可以使用享元模式来模拟。
    5. 外观模式:

      1. 外观模式提供了一个简化接口,用于访问子系统中的一群接口。
      2. 在实际项目中,可以用外观模式隐藏复杂系统的实现细节,提供一个更简单的接口供客户端使用。
      3. 假设一个电源总开关可以控制多个子开关,要实现总开关同时控制多个子开关,就可以使用外观模式来模拟。
    6. 备忘录模式:

      1. 备忘录模式用于捕获对象的内部状态,并在不破坏封装性的前提下将其保存,以便后续恢复到之前的状态。
      2. 比如文档编辑软件都有撤销的功能,快捷键一般都是Ctrl+Z。这就可以使用备忘录模式模式来实现。
    7. 建造者模式:

      1. 建造者模式用于将一个复杂对象的构建过程分离出来,使得相同的构建过程可以创建不同的表示。
      2. 在项目中,可以用建造者模式创建一个具有不同配置选项的对象,比如构建一个包含多个组件的电脑。
      3. 比如一份套餐可以包含多个组成部分,不同的套餐有不同的组成部分一步一步装配这些组成部分,构造一份完整的套餐,就可以使用建造者模式来描述。
    8. 观察者模式:

      1. 观察者模式定义了对象之间的一对多依赖,使得一个对象的状态改变会通知所有依赖它的对象。
      2. 常见场景包括事件处理系统或消息发布订阅系统。
    9. 策略模式:

      1. 策略模式定义了一系列算法,将它们封装起来,并使它们可以相互替换。
      2. 在实际业务中,可以用策略模式实现不同的支付方式,如支付宝支付、微信支付等。
    10. 工厂模式:

    工厂模式用于创建对象,通过定义一个接口或抽象类,让子类决定实例化哪个类。比如在实际项目中,可以用工厂模式创建不同类型的数据库连接对象。

    工厂模式的目的就是用来解耦,降低耦合度,实现松耦合

      1. 简单工厂模式:所有的产品共用一个工厂
      2. 工厂方法模式:每种产品都有一个对应的工厂,让工厂专门负责对应产品的生产,一般项目中用的最多的
      3. 抽象工厂模式:工厂的工厂,很少使用
    
  4. 单例模式怎么保证线程安全?

    单例模式只有一个实例对象,如果在多线程环境下,可能会有线程安全问题,就可以采用特定的单例模式来保证线程安全。

    1. 双重检查锁单例模式:

      // 双重检查锁定
      public class Singleton {
          private static volatile Singleton instance;
      
          private Singleton() {}
      
          public static Singleton getInstance() {
              if (instance == null) {
                  synchronized (Singleton.class) {
                      if (instance == null) {
                          instance = new Singleton();
                      }
                  }
              }
              return instance;
          }
      }
      
    2. 静态内部类单例模式:

      // 静态内部类
      public class Singleton {
          private Singleton() {}
      
          private static class SingletonHolder {
              private static final Singleton INSTANCE = new Singleton();
          }
      
          public static Singleton getInstance() {
              return SingletonHolder.INSTANCE;
          }
      }
      
  5. 反射和序列化对单例模式有什么影响?

    反射和序列化可能破坏单例模式,可以通过在构造方法中添加判断,防止多次实例化,或者通过实现readResolve方法来控制序列化过程中的实例创建。

    // 防止反射多次实例化
    public class Singleton {
        private static volatile Singleton instance;
    
        private Singleton() {
            if (instance != null) {
                throw new RuntimeException("Use getInstance() method to get the single instance.");
            }
        }
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    // 控制序列化过程中的实例创建
    public class Singleton implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private Singleton() {}
    
        private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
    
        public static Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    
        protected Object readResolve() {
            return getInstance();
        }
    }
    
  6. Spring框架中用到了哪些设计模式?

    1. 单例设计模式 : Spring 中的 Bean 默认都是单例的。
    2. 工厂设计模式 : Spring 使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
    3. 代理设计模式 : Spring AOP 底层的实现(jdk动态代理、cglib动态代理)。
    4. 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
    5. 观察者模式:Spring 事件驱动模型就是观察者模式很经典的一个应用。
    6. 适配器模式 : Spring AOP 的增强或通知(Advice)使用到了适配器模式,Spring MVC 中也是用到了适配器模式适配Controller。
    7. MyBatis 中的 SQLSessionFactoryBuilder 使用了建造者模式来构建 SQLSessionFactory。

【后续继续补充,敬请期待】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值