c++c++面试知识7——第七章 设计模式

Posted 超级无敌陈大佬的跟班

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++c++面试知识7——第七章 设计模式相关的知识,希望对你有一定的参考价值。

目录

第七章 设计模式

7.1 了解哪些设计模式?

7.2 ★什么是单例模式?如何实现?应用场景?

7.3 什么是工厂模式?如何实现?应用场景?

第七章 设计模式

7.1 了解哪些设计模式?

面试高频指数:★★★★☆

《大话设计模式》一书中提到 24 种设计模式,这 24 种设计模式没必要面面俱到,但一定要深入了解其中的几种,最好结合自己在实际开发过程中的例子进行深入的了解。

设计模式有 6 大设计原则:

单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。
开放封闭原则:软件实体可以扩展,但是不可修改。即面对需求,对程序的改动可以通过增加代码来完成,但是不能改动现有的代码。
里氏代换原则:一个软件实体如果使用的是一个基类,那么一定适用于其派生类。即在软件中,把基类替换成派生类,程序的行为没有变化。
依赖倒转原则:抽象不应该依赖细节,细节应该依赖抽象。即针对接口编程,不要对实现编程。
迪米特原则:如果两个类不直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用另一个类的某个方法的话,可以通过第三个类转发这个调用。
接口隔离原则:每个接口中不存在派生类用不到却必须实现的方法,如果不然,就要将接口拆分,使用多个隔离的接口。

设计模式分为三类:

创造型模式:单例模式、工厂模式、建造者模式、原型模式
结构型模式:适配器模式、桥接模式、外观模式、组合模式、装饰模式、享元模式、代理模式
行为型模式:责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

下面介绍常见的几种设计模式:

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
工厂模式:包括简单工厂模式、抽象工厂模式、工厂方法模式

  • 简单工厂模式:主要用于创建对象。用一个工厂来根据输入的条件产生不同的类,然后根据不同类的虚函数得到不同的结果。
  • 工厂方法模式:修正了简单工厂模式中不遵守开放封闭原则。把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。
  • 抽象工厂模式:定义了一个创建一系列相关或相互依赖的接口,而无需指定他们的具体类。

观察者模式:定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,主题对象发生变化时,会通知所有的观察者,使他们能够更新自己。
装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成派生类更为灵活。

 

7.2 ★什么是单例模式?如何实现?应用场景?

面试高频指数:★★★★★

单例模式:保证类的实例化对象仅有一个,并且提供一个访问他的全局访问点。

应用场景:

  • 表示文件系统的类,一个操作系统一定是只有一个文件系统,因此文件系统的类的实例有且仅有一个。
  • 打印机打印程序的实例,一台计算机可以连接好几台打印机,但是计算机上的打印程序只有一个,就可以通过单例模式来避免两个打印作业同时输出到打印机。

实现方式:
单例模式可以通过全局或者静态变量的形式实现,这样比较简单,但是这样会影响封装性,难以保证别的代码不会对全局变量造成影响。

  • 默认的构造函数、拷贝构造函数、赋值构造函数声明为私有的,这样禁止在类的外部创建该对象;
  • 全局访问点也要定义成 静态类型的成员函数,没有参数,返回该类的指针类型。因为使用实例化对象的时候是通过类直接调用该函数,并不是先创建一个该类的对象,通过对象调用。

不安全的实现方式:
原因:考虑当两个线程同时调用 getInstance 方法,并且同时检测到 instance 是 NULL,两个线程会同时实例化对象,不符合单例模式的要求。

 

class Singleton{
private:
    static Singleton * instance;
    Singleton(){}
    Singleton(const Singleton& tmp){}
    Singleton& operator=(const Singleton& tmp){}
public:
    static Singleton* getInstance(){
        if(instance == NULL){
            instance = new Singleton();
        }
        return instance;
    }
};
Singleton* Singleton::instance = NULL;

分类:

  • 懒汉模式:直到第一次用到类的实例时才去实例化,上面是懒汉实现。
  • 饿汉模式:类定义的时候就实例化。

1、线程安全的懒汉模式实现:

  • 方法1:加锁

存在的问题:每次判断实例对象是否为空,都要被锁定,如果是多线程的话,就会造成大量线程阻塞。

class Singleton{
private:
    static pthread_mutex_t mutex;
    static Singleton * instance;
    Singleton(){
        pthread_mutex_init(&mutex, NULL); 
    }
    Singleton(const Singleton& tmp){}
    Singleton& operator=(const Singleton& tmp){}
public:
    static Singleton* getInstance(){
        pthread_mutex_lock(&mutex);    "上锁"
        if(instance == NULL){            
            instance = new Singleton();            
        }
        pthread_mutex_unlock(&mutex);   "解锁"
        return instance;
    }
};
Singleton* Singleton::instance = NULL;
pthread_mutex_t Singleton::mutex;
  • 方法2:内部静态变量,在全局访问点 getInstance 中定义静态实例。
class Singleton{
private:
    static pthread_mutex_t mutex;
    Singleton(){
        pthread_mutex_init(&mutex, NULL);
    }
    Singleton(const Singleton& temp){}
    Singleton& operator=(const Singleton& temp){}
public:
    static Singleton* getInstance(){ "静态变量"
        static Singleton instance;
        return &instance;
    }
};
pthread_mutex_t Singleton::mutex; 

1、线程安全的饿汉模式实现:

  • 饿汉模式本身就是线程安全的不用加锁。
class Singleton{
private:
    static Singleton* instance;
    Singleton(const Singleton& temp){}
    Singleton& operator=(const Singleton& temp){}
protected:
    "构造函数设为保护的属性"
	 Singleton(){} 
public:
    static Singleton* getInstance(){ 
        return instance;    
    }
};
Singleton* Singleton::instance = new Singleton();

7.3 什么是工厂模式?如何实现?应用场景?

面试高频指数:★★★☆☆

工厂模式:包括简单工厂模式、抽象工厂模式、工厂方法模式

  • 简单工厂模式:主要用于创建对象。用一个工厂来根据输入的条件产生不同的类,然后根据不同类的虚函数得到不同的结果。
  • 工厂方法模式:修正了简单工厂模式中不遵守开放封闭原则。把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。
  • 抽象工厂模式:定义了一个创建一系列相关或相互依赖的接口,而无需指定他们的具体类。

1、简单工厂模式

  • 主要用于创建对象。用一个工厂来根据输入的条件产生不同的类,然后根据不同类的虚函数得到不同的结果。

应用场景:

  • 适用于针对不同情况创建不同类时,只需传入工厂类的参数即可,无需了解具体实现方法。例如:计算器中对于同样的输入,执行不同的操作:加、减、乘、除。

 

____________________________________________________________

参考:

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/cpp-interview-highlights/o5v4w6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

以上是关于c++c++面试知识7——第七章 设计模式的主要内容,如果未能解决你的问题,请参考以下文章

网易云课堂程序设计入门--C语言第七周:指针与字符串学习笔记

[C/C++笔试面试题] 程序设计基础 - 位操作函数数组篇

Java核心技术(应对面试)

「C语言」「例题」数组

第七章数组实验报告

C/C++面试知识点总结