设计模式面试题
001什么是单例模式?
单例设计模式(singleton)最常用、最简单的设计模式。单例模式的目的是保证在整个应用中某一个类有且只有一个实例(一个类在堆内存只存在一个对象)。怎么样让一个类一个类有且只有一个实例呢?最核心的就是一句话就是构造方法私有化。单例模式的编写有很多种写法。比如饿汉式、懒汉式、双重加锁机制静态内部类、枚举。
002单例模式中的饿汉式是什么?
饿汉式,从名字上理解像是有个人很容易饿,所以他每次不管自己饿不饿,没事就提前把要吃的东西先准备出来,也就是 “比较勤”,所以实例在初始化的时候就已经建好了,不管你有没有用到,都先建好了再说。
003饿汉式如何实现?
[1] 构造方法私有化,防止外界通过构造器创建新的工具类对象;
[2] 必须在该类中,自己先创建出一个对象;
[3] 向外暴露一个公共的静态方法用于返回自身的对象;
注意:我们知道,类加载的方式是按需加载,且加载一次。因此,在上述单例类被加载时,就会实例化一个对象并交给自己的引用,供系统使用;而且,由于这个类在整个生命周期中只会被加载一次,因此只会创建一个实例,即能够充分保证单例。
004饿汉模式的优缺点?
005什么是单例的懒汉式?
懒汉式,顾名思义就像一个人比较懒,平时不爱动,事情火烧眉毛了才迫不得已去做,“比较懒”,用的时候才去检查有没有实例,如果有则返回,没有则新建。有线程安全和线程不安全两种写法,区别就是synchronized关键字。
006线程不安全懒汉式实现方式?
[1] 构造方法私有化,防止外界通过构造器创建新的工具类对象
[2] 事先创建好当前类的一个私有静态对象
[3] 向外暴露一个公共的静态方法用于返回自身的对象
讯享网
注意:我们从懒汉式单例可以看到,单例实例被延迟加载,即只有在真正使用的时候才会实例化一个对象并交给自己的引用。
007线程不安全懒汉式优缺点?
优缺点:这种写法起到了Lazy Loading(懒加载)的效果,但是只能在单线程下使用。如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。
008线程安全懒汉式实现方法?
为了解决上面的问题,最简单的方法是将整个 getInstance() 方法设为同步(synchronized)。
注意:虽然做到了线程安全,并且解决了多实例的问题,但是它并不高效。因为同步操作只需要在第一次调用时才被需要,即第一次创建单例实例对象时,也就是if条件判断里面的内容。这就引出了双重检验锁。
009单例中的双重加锁机制是什么?
双重检验锁,又叫双重校验锁,综合了懒汉式和饿汉式两者的优缺点整合而成。看上面代码实现中,特点是在synchronized关键字内外都加了一层 if 条件判断,这样既保证了线程安全,又比直接上锁提高了执行效率,还节省了内存空间。
讯享网
010静态内部类如何实现单例?
注意:这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖 JDK 版本。
011用枚举如何实现单例?
使用:我们可以通过EasySingleton.INSTANCE.工具方法() 的方式来访问实例,这比调用getInstance()方法简单多了。创建枚举默认就是线程安全的,所以不需要担心double checked locking,而且还能防止反序列化导致重新创建新的对象。
012那些地方用到了单例模式?
1)网站的计数器,一般也是采用单例模式实现,否则难以同步。
2)应用程序的日志应用,一般都是单例模式实现,只有一个实例去操作才好,否则内容不好追加显示。
3)多线程的线程池的设计一般也是采用单例模式,因为线程池要方便对池中的线程进行控制
4)Windows的(任务管理器)就是很典型的单例模式,他不能打开俩个
5)windows的(回收站)也是典型的单例应用。在整个系统运行过程中,回收站只维护一个实例。
013什么是工厂设计模式?
工厂模式提供了一种创建对象的**方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。实现了创建者和调用者分离,工厂模式分为简单工厂、工厂方法、抽象工厂模式。
014什么是简单工厂模式?
简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)现实生活中,工厂是负责生产产品的;同样在设计模式中,简单工厂模式我们可以理解为负责生产对象的一个类,称为“工厂类”。
015简单工厂模式解决的问题?
将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。即使用者可直接消费产品而不需要知道其生产的细节
016简单工厂设计模式的实现。
简单工厂模式:把对象的创建放到一个工厂类中,通过参数来创建不同的对象。
017简单工厂模式的优点?
018简单工厂模式的缺点?
1)工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
2)违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
3)简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
019简单工厂模式的应用场景?
020什么是工厂方法模式?
工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
021工厂方法模式的具体实现。
工厂方法模式: 每种产品由一种工厂来创建,一个工厂处理一个对象。
角色组成
1. 抽象工厂: 定义工厂类所具有的基本的操作
2. 具体工厂:该类必须继承抽象工厂,实现抽象工厂定义的方法,返回一个对象
3. 抽象产品:定义了抽象产品具有的基本操作
4. 产品实现类:实现抽象产品类对定义的抽象方法,和具体工厂一一对应;

022工厂方法模式解决的问题?
工厂方法模式把具体产品的创建推迟到工厂类的子类(具体工厂)中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式在添加新产品的时候就不修改工厂类逻辑而是添加新的工厂子类,符合开放封闭原则,克服了简单工厂模式中缺点。
023工厂方法模式的优点?
1)更符合开-闭原则
新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
简单工厂模式需要修改工厂类的判断逻辑
2)符合单一职责原则
每个具体工厂类只负责创建对应的产品
简单工厂中的工厂类存在复杂的switch逻辑判断
3)不使用静态工厂方法,可以形成基于继承的等级结构。
简单工厂模式的工厂类使用静态工厂方法
总结:工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
024工厂方法模式的缺点?
1)添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
2)由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
3)虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;一个具体工厂只能创建一种具体产品。
025工厂方法模式的应用场景。
1)当一个类不知道它所需要的对象的类时,在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可;
2)当一个类希望通过其子类来指定创建对象时,在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
3)将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
026什么是抽象工厂模式?
抽象工厂模式,即Abstract Factory Pattern,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。 允许使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。
027抽象工厂模式的具体实现。
抽象工厂模式:工厂方法模式的进一步延伸。
角色组成
1. 抽象工厂: 定义工厂类所具有的基本的操作
2. 具体工厂:具体工厂实现了抽象工厂,每个工厂方法返回多个具体对象
3. 抽象类接口:定义了产品具有的基本操作,提供一组所有类都具有的业务方法
4. 抽象类:用于实现抽象接口所定义的业务方法,只做抽象接口,具体由产品实现类处理
5. 产品实现类:实现抽象产品类对定义的抽象方法,和具体工厂一对多;
028抽象工厂模式的优点。
1)降低耦合
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;
2)更符合开-闭原则
新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可
3)符合单一职责原则
每个具体工厂类只负责创建对应的产品
4)不使用静态工厂方法,可以形成基于继承的等级结构。
029抽象工厂模式的缺点。
抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
030抽象工厂模式的应用场景。
1)一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
2)这个系统有多个系列产品,而系统中只消费其中某一系列产品
3)系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。
031工厂模式和抽象工厂模式对比?
032什么是代理模式?
033代理模式的具体实现?
步骤1: 创建抽象对象接口(Subject):声明你(真实对象)需要让代购(代理对象)帮忙做的事(买Mac)
步骤2: 创建真实对象类(RealSubject),即”我“
步骤3:创建代理对象类(Proxy),即”代购“,并通过代理类创建真实对象实例并访问其方法
步骤4:客户端调用
结果输出
买一台Mac
用盒子包装好Mac
034代理模式的优缺点?
优点
协调调用者和被调用者,降低了系统的耦合度
代理对象作为客户端和目标对象之间的中介,起到了保护目标对象的作用
缺点
由于在客户端和真实主题之间增加了代理对象,因此会造成请求的处理速度变慢;
实现代理模式需要额外的工作(有些代理模式的实现非常复杂),从而增加了系统实现的复杂度。
035代理模式应用场景?
036为什么要使用动态代理?
在静态代理模式中一个静态代理只服务一种类型的目标对象,若要服务多类型的目标对象,则需要为每种目标对象都实现一个静态代理对象。在目标对象较多的情况下,若采用静态代理,则会出现 静态代理对象量多、代码量大,从而导致代码复杂的问题。
037什么是动态代理?
038动态代理模式的原理?
039动态代理的优点和缺点?
优点
1)只需要1个动态代理类就可以解决创建多个静态代理的问题,避免重复、多余代码;
2)更强的灵活性;
缺点
1)效率低:相比静态代理中直接调用目标对象方法,动态代理则需要先通过Java反射机制 java如何刷基础题 从而间接调用目标对象方法。
2)应用场景局限:Java 的单继承特性(每个代理类都继承了 Proxy 类),即只能针对接口创建代理类,不能针对类创建代理类。
040动态代理的应用场景。
日志记录、性能统计、安全控制、异常处理等。
041动态代理与静态代理模式的区别?
042JDK动态代理的实现步骤?
1.创建接口,定义目标类需要完成的功能
2.创建目标类,实现接口。
3.创建InvocationHandler接口的实现类。在invoke方法中完成代理类的功能。
目标方法的调用
功能增强
4.使用Proxy类中静态方法Proxy.newProxyInstance完成代理类对象的创建,返回代理对象,并把返回值转为接口类型。
043CGLib代理的实现步骤?
044什么是设计模式(Design pattern)?
设计模式(Design pattern)是一种思想,是一套被反复使用的代码设计经验总结,专门用于解决特定场景的需求。它提供了在软件开发过程中面临的一些问题的**解决方案,使用设计模式是为了提高代码的可重用性、让代码通俗易懂,增加代码可靠性。
045面向对象编程中,都有哪些设计原则?
开闭原则:对扩展开放,对修改关闭。就是如果要修改原有的功能或者是扩展功能,尽量去扩展原有的代码,而不是修改原来已有的代码。
里氏替换原则:任何子类对象都应该可以替换其派生的超类对象 。即,子类可以扩展父类的功能,但不要修改父类原有的功能。 也就是说,当一个子类继承父类后,尽量不要去重写它原有的方法。
依赖转置(依赖倒置)原则:要面向接口编程,不要面向实现编程。两个模块交互时,都访问各自接口,而不是具体的实现类。
单一职责原则:一个对象要专注于一种事情,不要让它担任太多责任。
接口隔离原则:一个接口尽量只包含用户关心的内容。就是一个接口不要太庞大。
迪米特法则:如果两个软件实体之间不是特别必要,尽量不要让他们直接通信。而是找个第三方进行转发,比如使用MQ(消息队列)。
合成复用原则:如果在“组合/聚合”和“继承”之间做抉择时,优先选择“组合/聚合”。
046设计模式的分类?
创建型模式:用于创建对象的设计模式。一般可以简化用户创建对象的过程。其次可以降低耦合度,用户不需要关心对象具体的创建过程。包含:单例模式、原型模型、工厂模式、建造者模式。
结构型模型:组织对象之间的结构。使其易于扩展等。包括:代理模式、适配器模式、桥接模式、装饰器模式、外观模式、享元模式、组合模式。
行为模型:主要用于决定对象如何做出行为包括:模板方法模式、策略模式、命令模式、责任链、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式。
047设计模式的作用?
1)提高代码复用率,降低开发成本和周期;
2)提高代码可维护性、可拓展性;
3)使代码更加优雅、更容易被他人理解。
048举例说明一个符合开闭原则的设计模式的例子?
开闭原则要求你的代码对扩展开放,对修改关闭。这个意思就是说,如果你想增加一个新的功 能,你可以很容易的在不改变已测试过的代码的前提下增加新的代码。有好几个设计模式是基 于开闭原则的,如策略模式,如果你需要一个新的策略,只需要实现接口,增加配置,不需要 改变核心逻辑。一个正在工作的例子是 Collections.sort() 方法,这就是基于策略模式,遵循 开闭原则的,你不需为新的对象修改 sort() 方法,你需要做的仅仅是实现你自己的 Comparator 接口。
049OOP中的组合、聚合和关联有什么区别?
如果两个对象彼此有关系,就说他们是彼此相关联的。组合和聚合是面向对象中的两种形式的 关联。组合是一种比聚合更强力的关联。组合中,一个对象是另一个的拥有者,而聚合则是指 一个对象使用另一个对象。如果对象 A 是由对象 B 组合的,则 A 不存在的话,B一定不存在, 但是如果 A 对象聚合了一个对象 B,则即使 A 不存在了,B 也可以单独存在。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/5688.html