1、面向对象三大特性,并且具体举例说明
封装、继承和多态。
封装:
定义:数据和代码捆绑在⼀起,避免外界⼲扰和不确定性访问。
功能:把客观事物封装成抽象的类,并且类可以把⾃⼰的数据和⽅法只让可信的类或者对象操作,对不可信的进⾏信息隐藏,例如:将公共的数据或⽅法使⽤public修饰,⽽不希望被访问的数据或⽅法采⽤private修饰。
继承:
定义:让某种类型对象获得另⼀个类型对象的属性和⽅法。
功能:它可以使⽤现有类的所有功能,并在⽆需重新编写原来的类的情况下对这些功能进⾏扩展。
常⻅的继承有三种⽅式:
1、实现继承:指使⽤基类的属性和⽅法⽽⽆需额外编码的能⼒
2、接⼝继承:指仅使⽤属性和⽅法的名称、但是⼦类必须提供实现的能⼒
3、可视继承:指⼦窗体(类)使⽤基窗体(类)的外观和实现代码的能⼒
例如:
将⼈定义为⼀个抽象类,拥有姓名、性别、年龄等公共属性,吃饭、睡觉等公共⽅法,在定义⼀个具体的⼈时,就可以继承这个抽象类,既保留了公共属性和⽅法,也可以在此基础上扩展跳舞、唱歌等特有⽅法。
多态:
定义:
同⼀事物表现出不同事物的能⼒,即向不同对象发送同⼀消息,不同的对象在接收时会产⽣不同的⾏为(重载实现编译时多态,虚函数实现运⾏时多态)。
功能:
多态性是允许你将⽗对象设置成为和⼀个或更多的他的⼦对象相等的技术,赋值之后,⽗对象就可以根据当前赋值给它的⼦对象的特性以不同的⽅式运作。
简单⼀句话:允许将⼦类类型的指针赋值给⽗类类型的指针。
例如:
基类是⼀个抽象对象–⼈,那学⽣、运动员也是⼈,⽽使⽤这个抽象对象既可以表示学⽣、也可以表示运动员。
2、多态如何实现
实现多态有两种⽅式:
3、堆和栈的区别
在C++中,内存分为5个区:堆、栈、自由存储区、全局/静态存储区、常量存储区
栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区。通常存放局部变量、函数参数等。
堆:是由new分配的内存块,由程序员释放(编译器不需要操作),一般一个new与一个delete对应,一个new[]与一个delete[]对应。如果程序员没有释放掉,资源将由操作系统在程序结束后自动回收。
自由存储区:是由malloc等分配的内存块,和堆十分相似,用free来释放。
全局/静态存储区:全局变量和静态变量被分配到同一块内存中(在C语言中,全局变量又分为初始化的和未初始化的,C++中没有这一区分)。
常量存储区:这是一块特殊存储区,里边存放常量,不允许修改。
堆和栈的区别:
4、 什么是对齐,以及为什么要对齐:
4.1 概念
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
4.2 对齐的作用及原因:
各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况, 但是最常见的是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为 32位)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低 字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。
4.3 对齐的原则
有效对齐值N是最终用来决定数据存放地址方式的值,最重要。有效对齐N,就是表示“对齐在N上”,也就是说该数据的"存放起始址%N=0"。
数据结构中的数据变量都是按照定义的顺序来排放的,第⼀个数据变量的起始地址就是数据结构的起始地址。
结构体本身也要根据⾃身的有效对齐值取整(结构体成员变量占用总长度,要满足是结构体有效对齐值的整数倍)
总结:
各变量要对齐 + 结构体整体也要对齐。
5、指针和引用的区别
6、C++中struct和class的区别
相同点:
不同点:
引申:C++和C的struct区别
1、OSI七层模型和四层模型,四层模型每一层的具体功能。
2、TCP与UDP的区别
操作系统:
1、
Linux:
1、
设计模式
1、单例模式
确保⼀个类只有⼀个实例,并提供该实例的全局访问点。
优点:
有些实例,全局只需要⼀个就够了,使⽤单例模式就可以避免⼀个全局使⽤的类,频繁的创建与销毁,耗费系统资源。
设计要素:
⼀个私有构造函数(确保只能单例类⾃⼰创建实例)
⼀个私有静态变ᰁ(确保只有⼀个实例)
⼀个公有静态函数(给使⽤者提供调⽤⽅法)
简单来说就是,单例类的构造⽅不让其他⼈修改和使⽤;并且单例类⾃⼰只创建⼀个实例,这个实例,其他⼈也⽆法修改和直接使⽤;然后单例类提供⼀个调⽤⽅法,想⽤这个实例,只能调⽤。这样就确保了全局只创建了⼀个实例。
单例模型6种实现及各实现的优缺点
1、懒汉式(线程不安全)
说明:
先不创建实例,当第⼀次被调⽤时,在创建实例,所以被称为懒汉式。
优点:
延迟了实例化,如果不需要使⽤该类,就不会被实例化,节约了系统资源。
缺点:
线程不安全,多线程环境下,如果多个线程同时进⼊了 if (uniqueInstance == null) ,若此时还
未实例化,也就是uniqueInstance == null,那么就会有多个线程执⾏ uniqueInstance = new
Singleton(); ,就会实例化多个实例;
2、饿汉式(线程安全)
说明:
先不管需不需要使⽤这个实例,直接先实例化好实例(饿死⻤⼀样,所以称为饿汉式),然后
当需要使⽤的时候,直接调⽅法就可以使⽤了
优点:
提起实例化好了⼀个实例,避免了线程不安全问题的出现,
缺点:
直接实例化了实例,不再延迟实例化;若系统没有使⽤这个实例,或者系统运⾏很久之后才需
要使⽤这个实例,都会使操作系统的资源浪费。
3、懒汉式(线程安全)
说明:
实现和线程不安全的懒汉式 ⼏乎⼀样,唯⼀不同的点是,在get⽅法上 加了⼀把锁。如此⼀
来,多个线程访问,每次只有拿到锁的的线程能够进⼊该⽅法,避免了多线程不安全问题的出
现。
优点:
延迟实例化,节约了资源,并且是线程安全的。
缺点:
虽然解决了线程安全问题,但是性能降低了。因为,即使实例已经实例化了,既后续不会再出
现线程安全问题了,但是锁还在,每次还是只能拿到锁的线程进⼊该⽅***使线程阻塞,等待时
间过⻓。
4、双重检查锁实现(线程安全)
说明:
双᯿检查数相当于是改进了线程安全的懒汉式。线程安全的懒汉式的缺点是性能降低了,造成
的原因是因为即使实例已经实例化,依然每次都会有锁。
⽽现在,我们将锁的位置变了,并且多加了⼀个检查。也就是,先判断实例是否已经存在,若
已经存在了,则不会执⾏判断⽅法内的有锁⽅法了。 ⽽如果,还没有实例化的时候,多个线
程进去了,也没有事,因为⾥⾯的⽅法有锁,只会让⼀个线程进⼊最内层⽅法并实例化实例。
如此⼀来,最多最多,也就是第⼀次实例化的时候,会有线程阻塞的情况,后续便不会再有线
程阻塞的问题。
为什么使⽤ volatile 关键字修饰了 uniqueInstance 实例变ᰁ?
uniqueInstance = new Singleton();
这段代码执⾏时分为三步:
项目问题: