面试题补充
今天有同学问到豆芽一个问题:为什么微信不能像qq一样打开多个。豆芽突然想到看样子还得补充一些面试题。豆芽尽我所能帮助到大家。
对于C++软件求职要求确实是比较高的,《蒋豆芽的秋招打怪之旅》专刊包含近400道高频面试题,今天再补充一些设计模式面试题和场景题。
设计模式面试题
-
说说面对对象中的设计原则
SRP(Single Responsibility Principle):单一职责原则,就是说一个类只提供一种功能和仅有一个引起它变化的因素。
OCP(Open Close Principle):开放封闭原则,就是对一个类来说,对它的内部修改是封闭的,对它的扩展是开放的。
DIP(Dependence Inversion Principle):依赖倒置原则,就是程序依赖于抽象,而不依赖于实现,它的主要目的是为了降低耦合性,它一般通过反射和配置文件来实现的。
LSP(Liskov Substitution Principle):里氏替换原则,就是基类出现的地方,通过它的子类也完全可以实现这个功能
ISP(Interface Segregation Principle):接口隔离原则,建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
CRP(Composite Reuse Principle):合成复用原则,多用组合设计类,少用继承。
-
单一职责原则和接口隔离原则的区别
- 单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。
- 单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节; 而接口隔离原则主要约束接口,主要针对抽象,针对程序整体框架的构建。
-
说说你了解的设计模式
-
单例模式(要求学会手撕)
单例模式只允许创建一个活动的对象(实例),提供了对唯一实例的受控访问。
比如Windows的任务管理器,就是一个很典型的单例模式实现。
单例实现原理是,将能够创建对象的函数都设置为private,通过静态成员返回一个实例。
有两种方式,一个是懒汉式,一个是饿汉式。懒汉式需要考虑加锁。
实现代码如下:
#include <iostream> #include <pthread.h> using namespace std; class singleInstance{ public: static singleInstance* GetsingleInstance(){ if (instance == NULL){ pthread_mutex_lock(&mutex);//mlock.lock(); if (instance == NULL){ instance = new singleInstance(); } pthread_mutex_unlock(&mutex);//mlock.unlock(); } return instance; }; ~singleInstance(){}; static pthread_mutex_t mutex;//mutex mlock; 加锁互斥 private:// 涉及创建对象的函数都设置为private singleInstance(){}; singleInstance(const singleInstance& other){}; singleInstance& operator=(const singleInstance& other){ return *this; }; static singleInstance* instance; }; //懒汉式,静态变量需要定义 singleInstance* singleInstance::instance = nullptr; pthread_mutex_t singleInstance::mutex; int main(){ // 因为没有办法创建对象,就得采用静态成员函数的方法返回静态成员变量 singleInstance *s = singleInstance::GetsingleInstance(); //singleInstance *s1 = new singleInstance(); // 报错 cout << "Hello World"; delete s; // 防止内存泄露 return 0; }
下面是饿汉式:
#include <iostream> #include <pthread.h> using namespace std; class singleInstance{ public: static singleInstance* GetsingleInstance(){ // 饿汉式,直接创建一个对象,不需要加锁 static singleInstance instance; return &instance; }; ~singleInstance(){}; private:// 涉及创建对象的函数都设置为private singleInstance(){}; singleInstance(const singleInstance& other){}; singleInstance& operator=(const singleInstance& other){ return *this; }; }; int main(){ // 因为没有办法创建对象,就得采用静态成员函数的方法返回 singleInstance *s = singleInstance::GetsingleInstance(); //singleInstance *s1 = new singleInstance(); // 报错 cout << "Hello World"; return 0; }
-
工厂模式(要求学会手撕)
就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
#include <iostream> #include <pthread.h> using namespace std; //产品类(抽象类,不能实例化) class Product{ public: Product(){}; virtual void show()=0; //纯虚函数 virtual ~Product(){}; }; class productA:public Product{ public: productA(){}; void show(){ cout << "product A create!" << endl; }; ~productA(){ cout << "product A delete!" << endl; }; }; class productB:public Product{ public: productB(){}; void show(){ cout << "product B create!" << endl; }; ~productB(){ cout << "product B delete!" << endl; }; }; class simpleFactory{ // 工厂类 public: simpleFactory(){}; Product* product(const string str){ if (str == "productA") return (new productA()); if (str == "productB") return (new productB()); return NULL; }; ~simpleFactory(){}; }; int main(){ simpleFactory obj; // 创建工厂 Product* pro; // 创建产品 pro = obj.product("productA"); pro->show(); // product A create! delete pro; pro = obj.product("productB"); pro->show(); // product B create! delete pro; return 0; }
工厂模式为的就是代码解耦,如果我们不采用工厂模式,如果要创建产品A、B,我们通常做法是不是用switch...case语句?那麻烦了,代码耦合程度高,后期添加更多的产品进来,我们不是要添加更多的case吗?这样就太麻烦了,而且不符合设计模式中的开放封闭原则。
为了进一步解耦,在简单工厂的基础上发展出了抽象工厂模式,即连工厂都抽象出来,实现了进一步代码解耦。代码如下:
#include <iostream> #include <pthread.h> using namespace std; //产品类(抽象类,不能实例化) class Product{ public: Product(){} virtual void show()=0; //纯虚函数 virtual ~Product(){} }; //产品A class ProductA:public Product{ public: ProductA(){} void show(){ cout<<"product A create!"<<endl; }; ~ProductA(){ cout<<"product A delete!"<<endl; }; }; //产品B class ProductB:public Product{ public: ProductB(){} void show(){ cout<<"product B create!"<<endl; }; ~ProductB(){ cout<<"Product B delete!"<<endl; }; }; class Factory{//抽象类 public: virtual Product* CreateProduct()=0; ~Factory(){} }; class FactorA:public Factory{//工厂类A,只生产A产品 public: Product* CreateProduct(){ return (new ProductA()); } }; class FactorB:public Factory{//工厂类B,只生产B产品 public: Product* CreateProduct(){ return (new ProductB()); } }; int main(){ Product* _Product = nullptr; auto MyFactoryA = new FactorA(); _Product = MyFactoryA->CreateProduct();// 调用产品A的工厂来生产A产品 _Product->show(); delete _Product; auto MyFactoryB=new FactorB(); _Product=MyFactoryB->CreateProduct();// 调用产品B的工厂来生产B产品 _Product->show(); delete _Product; getchar(); return 0; }
-
观察者模式
观察者模式的作用是:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
比如拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。
代码如下:
#include <iostream> #include <list> using namespace std; class Observer{ // 观察者抽象 public: virtual void Update(int) = 0; }; class Subject{ // 被观察者抽象 public: virtual void Attach(Observer *) = 0; virtual void Detach(Observer *) = 0; virtual void Notify() = 0; }; class ConcreteObserver1:public Observer{ // 第一个观察者 public: ConcreteObserver1(Subject *pSubject):m_pSubject(pSubject){} void Update(int value){ cout << "ConcreteObserver1 get the update. New State:" << value << endl; } private: Subject *m_pSubject; }; class ConcreteObserver2 : public Observer{ // 第二个观察者 public: ConcreteObserver2(Subject *pSubject):m_pSubject(pSubject){} void Update(int value){ cout << "ConcreteObserver2 get the update. New State:" << value << endl; } private: Subject *m_pSubject; }; class ConcreteSubject:public Subject{ // 被观察者 public: void Attach(Observer *pObserver); void Detach(Observer *pObserver); void Notify(); void SetState(int state){ m_iState = state; } private: std::list<Observer *> m_ObserverList; int m_iState; }; void ConcreteSubject::Attach(Observer *pObserver){ // 添加观察者 m_ObserverList.push_back(pObserver); } void ConcreteSubject::Detach(Observer *pObserver){ // 删除观察者 m_ObserverList.remove(pObserver); } void ConcreteSubject::Notify(){ // 通知观察者 std::list<Observer *>::iterator it = m_ObserverList.begin(); while (it != m_ObserverList.end()){ (*it)->Update(m_iState); ++it; } } int main(){ // Create 被观察者 ConcreteSubject *pSubject = new ConcreteSubject(); // Create 观察者 Observer *pObserver1 = new ConcreteObserver1(pSubject); Observer *pObserver2 = new ConcreteObserver2(pSubject); // 改变状态 pSubject->SetState(2); // 注册观察者 pSubject->Attach(pObserver1); pSubject->Attach(pObserver2); pSubject->Notify();// 通知观察者 // 删除观察者 pSubject->Detach(pObserver1);
-