Java面试题(二)设计模式系列

1.面向对象的六原则一法则

  • 职责单一原则:一个类只做它该做的事。

  • 开闭原则:软件实体应当对扩展开放,对修改关闭。

  • 依赖倒转原则:面向接口。声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不使用具体类型,因为抽象类型可以被其任意子类所替代。

  • 里氏替换原则:任何时候都可以用子类型替换掉父类型。

  • 接口隔离原则:接口应该小而专,不应该大而全。

  • 合成聚合复用原则:应当多使用聚合或合成关系复用代码。

  • 迪米特法则:最少知识原则,一个对象应当对其他对象尽可能少的了解。

2.简述设计模式

设计模式其实就是一个设计思想和理念,就是一套被反复使用的代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。多用接口/抽象类,从而增加代码的可扩展性(减少修改代码)。降低模块间的依赖和联系。 体现了OOP的模块化、可扩展性等特征。

3.说出5种设计模式和应用

  • 原型模式:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象
  • 单例模式:一个类只有一个实例对象
  • 工厂模式:只需要知道接口方法,不需要知道具体如何实现
  • 代理模式:给目标对象提供一个代理,由代理对象控制对目标对象的引用
  • 适配器模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作

4.用代码写懒汉式/饿汉式单例

懒汉式单例:类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例。如果是多线程程序,则不要删除上例代码中的关键字 volatile 和 synchronized,否则将存在线程非安全的问题。如果不删除这两个关键字就能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。

public class LazySingleton {
	//保证 instance 在所有线程中同步
    private static volatile LazySingleton instance = null;    
    //private 避免类在外部被实例化
    private LazySingleton(){}    
    public static synchronized LazySingleton getInstance()
    {
        //getInstance 方法前加同步
        if(instance == null){
            instance = new LazySingleton();
        }
        return instance;
    }
}

饿汉式单例:类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的,可以直接用于多线程而不会出现问题。

public class HungrySingleton {
    private static final HungrySingleton instance = new HungrySingleton();
    private HungrySingleton(){}
    public static HungrySingleton getInstance(){
        return instance;
    }
}

5.写一个双重检查锁单例

public static synchronized Singleton getInstance() {
  if(singleton == null) {
     synchronized(Singleton.class) {
       if(singleton == null) {
         singleton = new Singleton();
       }
    }
  }
  return singleton;
}

6.Spring 框架中常用的设计模式有哪些

  • 工厂设计模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
  • 代理设计模式 : Spring AOP 功能的实现。
  • 单例设计模式 : Spring 中的 Bean 默认都是单例的。
  • 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  • 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
  • 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
  • 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。

7.说一说DAO设计模式

DAO (数据访问对象) 模式用于将低级数据访问API或操作与高级业务服务隔离开来。下面是DAO模式中的组件。

  • 数据存取对象接口,DAO接口描述要在模型对象上执行的标准操作。

  • 数据访问对象的具体类,该类实现一个DAO接口。该类负责从数据源(可以是Xml/数据库或任何其他存储机制)获取数据。

  • 模型对象或值对象,这个对象是一个普通的旧java对象,包含用于存储使用DAO类检索的数据的get/set方法。

8.说一说DAO,DTO,VO,PO,Entity

  • Entity 对应数据库字段对象,他和PO(persistant object) 持久对象是一个意思
  • DAO(Data Access Object数据访问对象):持久层操作,数据库操作
  • DTO(Data Transfer Object 数据传输对象):持久层转化到业务层时,需要个中间对象来转化
  • VO(值对象)业务层对象,用于想web前端展示,传给页面数据

9.接口和抽象类的应用场景

  • 抽象类中不一定都是抽象的方法,也可以有具体实现的方法,这样就可以把大家公用的方法提升到抽象类中,然后具体的方法可以留给子类自己实现(此处经典的应用,模板方法设计模式)。所以抽象类可以更好的实现代码的复用

  • 接口和抽象类的概念不一样。可以理解为:抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。

举例:
有男人类,女人类,他们都属于人类,那么就可以做一个人类的抽象类。那么男人和女人一些共同的方法就可以写到抽象类里面,例如吃饭睡觉,可以把吃饭睡觉做成接口。一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭,睡觉接口)。当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。

你可能感兴趣的:(面试题)