20170328_C++程序员必备的20个知识点
11、解释下类的三大特性:封装、继承、多态?
(1)C++ 的三大特性是指封装、继承、多态。
(2)对于封装,封装可以把有关联的数据和函数封装在一个对象中,形成一个基本单位,各个对象之间相对独立、互不干扰。同时,封装还可以对外隐藏数据、隐藏函数的实现细节,仅留下少量必须的对外接口,使得代码模块化,安全性更高。
(3)对于继承,它包括 public、protected、private三种继承方式,它是指从基类派生出派生类,该派生类实现了对基类已有代码模块的继承与扩展,封装和继承都是为了代码重用,也就是增加代码的复用性。
(4)对于多态,它包括静态多态性和动态多态性。其中,静态多态性是由函数重载和运算符重载实现的,而动态多态性是通过基类虚函数和基类指针配合使用实现的。总之,多态是指一个接口、多种实现方法的现象。它是为了实现接口重用,增加代码的可扩充性。
12、指针和引用的区别是什么?
(1)指针是一个变量,操作系统需要为指针变量本身分配内存空间,同时,这个变量里面存储的是一个地址,这个地址指向内存中的一个存储单元。引用只是一个变量的别名,操作系统不为它分配存储空间,它和被绑定的变量共用一块内存空间。
(2)指针在使用时需要解引用,使用 * 运算符,对指针的操作包括:对指针本身的操作和对指针所指向的内存的操作。引用在使用时不需要解引用运算符,对引用的操作则是对该引用所绑定的变量的直接操作。
(3)引用,不能为空,在定义时必须要被初始化,而且只能被初始化一次。指针可以为空,在定义时可以初始化、也可以不初始化,另外,它也可以根据需要改变指针的指向。
(4)指针有 const 指针,但是引用没有 const 引用。
(5)sizeof(引用),得到的是所绑定的变量的大小。sizeof(指针),得到的是指针本身的大小。
(6)指针有一级指针、二级指针等多级之说。引用没有。指针的自增、自减运算符的含义和引用的自增、自减运算的符含义是不一样的。
13、什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法?你通常使用哪些方法来避免和减少这类错误的发生?
(1)参考博客:20170327_请说出C++中的内存分区。
(2)内存泄漏,指的是堆内存的泄露。堆内存是程序从堆栈区中分配出来的大小任意的一个内存块,通常是由malloc() 函数和new 运算符动态申请,用完过之后要手动释放,使用的是free() 函数delete 运算符,才能使该内存块回收以留他用。
但是,如果程序员忘记了手动释放,那么便会造成该内存块不能被再次使用,也就是说这块内存泄露了。
(3)方法:使用的时候要记得指针所指数组的长度。动态分配的内存空间在使用完毕之后要记得手动释放。动态分配内存的指针最好不要再次被赋值。对指针进行赋值的时候,要注意这个被赋值指针需不需要被释放。
14、常用的排序算法有哪些?简单描述几个排序算法的优缺点。
(1)参考博客:20170328_请说出各个排序算法的时间复杂度和稳定性。
15、new 和 malloc 的区别?
(1)malloc() 函数和 free() 函数是 C 语言中的标准库函数,它们的功能就是动态申请内存空间、使用完毕之后内存空间再被释放,在 C++ 中新标准中,它们依然存在,只是可以被功能更强大、使用更广泛的 new 运算符和 delete 运算符代替。
(2)对于非基本数据类型而言,比如类,光使用 malloc() 和 free() 是不够的,它无法满足动态对象自身的要求,对象在创建的同时需要自动执行构造函数、在被释放的时候需要自动执行析构函数。
(3)由于malloc() 和 free() 是库函数,不是运算符,因此它们不在编译器的控制范围内,不能够吧执行构造函数和析构函数的任务强加给它们。因此,C++ 需要一个能够完成动态内存分配且进行初始化工作的运算符 new 和一个完成清理与释放内存空间工作的运算符 delete 。
(4)new 可以认为是 malloc() 函数 + 构造函数的执行。new 出来的指针是直接带类型信息的,而 malloc() 函数返回到都是 void * 类型的指针。delete 可以认为是 free() 函数 + 析构函数的执行。
16、TCP通信和UDP通信的差别是什么?什么是IOCP?
(1)TCP 通信 —— UDP 通信:
(1)有无连接、是否可靠、速度快慢:
- TCP ,指的是传输控制协议,提供的是面向有连接的、可靠的服务。这意味着当客户端和服务器之间通过TCP 协议传输数据之前,必须先建立TCP连接,连接之后才能进行数据传输。 (1)其中,建立连接的过程被称之为“握手”,它是通过控制“消息”在客户端和服务器之间来回互换实现的。 (2)提供可靠性传输,这意味着使用TCP 协议发送的消息是保证交付给客户端的。如果消息在传输过程中丢失或者超时,那么它将重发,这就是TCP 提供的重发机制。 (3)也正因为如此,TCP 传输速度比较慢。
- UDP,指的是用户数据报协议,提供的是面向无连接的、不可靠的服务。这意味着UDP 在传输数据报之前不需要在客户端和服务器之间事先建立连接,它只是把应用程序传给 IP 层的数据报发送出去,但是并不能保证它们能够到达目的地,而且它也没有超时重发机制,因此它是不可靠的,但是它的传输速度很快。
(2)流量控制、拥塞控制:
- TCP 提供流量控制和拥塞控制。
- UDP 不提供流量控制和拥塞控制。
(3)首部格式:
- TCP 具有比UDP 更大的首部。一个TCP 首部的大小是20 字节。
- 一个UDP 首部的大小是8 字节。
- TCP 首部和UDP 首部所包含的内容差异很大。
(2)IOCP 是什么:
- IOCP 的全称是 I/O completion port,中文名字是 I/O 完成端口。
- IOCP 是一个异步 I/O 的API,它可以高效的将 I/O 事件通知给应用程序。
- 与使用 select() 或是其它异步方法不同的是:一个套接字 [ socket ] 与一个完成端口关联了起来,然后就可继续进行正常的Winsock操作了。然而,当一个事件发生的时候,此完成端口就将被操作系统加入一个队列当中,然后应用程序可以对核心层进行查询以得到此完成端口。
17、同步 IO 和异步 IO 的区别,你知道么?
(1)同步IO,指的是,线程启动一个IO 操作后,就立即进入等待状态,直到这个 IO 操作完成之后、返回了结果,这个线程才会重新醒来、继续执行后续的操作。
(2)异步IO ,指的是,线程发送一个IO 请求到系统内核,然后接着处理其他的事情,内核完成这个IO 请求后,将会通知这个线程IO 操作完成了,然后这个线程再利用这个调用的返回值继续其他的操作。
(3)如果IO 请求需要大量的执行时间,那么异步IO 方式可以显著提高效率,因为在线程等待的这段时间内,CPU 可以调度其他的线程进行执行。如果没有其他的线程需要执行,则这段时间将会被浪费掉。 但是,如果IO 操作时间很短暂,用异步IO 方式会导致线程与线程之间频繁的交换,反而比较低效率,此时最好使用同步IO 方式。
(4)简单的说就是:同步在编程里,一般是指某个操作执行完毕之后,才可以继续执行后面的操作,拿到IO 上面来说就是,我要完成这个IO 操作之后才继续进行后面的操作。 异步则指的是,我交代给操作系统一个IO 操作,你先执行,它执行的结果我过会来拿,在OS 执行的这段时间内,我还要去干其他的事情。
18、解释下C++ 中的静态函数和静态变量?
(1)参考博客:20170328_C++程序员必备的20个知识点。
(2)类中的静态数据成员,在编译时创建并且初始化:在该类的任何对象建立之前就已经存在了,它不属于某一个具体的对象,它属于整个类的,在内存中只占据一份内存空间,所以每个对象都可以使用它。
类中的非静态数据成员,则是属于某一个具体的类对象的,存在于不同的内存空间中,不同的类对象该数据成员可能不同。
(3)静态的数据成员和成员函数,实现了同类对象之间的信息共享。
(4)静态的数据成员和成员函数,在类外存储,求类的大小时,并不包含在内。
(5)静态成员函数的意义,不在于信息共享、数据沟通,而在于管理静态数据成员、完成对静态数据成员的封装。
(6)静态成员函数只能访问静态数据成员。非静态成员函数即可访问静态数据、也可访问非静态数据。
原因在于:非静态成员函数访问数据时,在调用时 this 指针会被当作参数传进去。而静态成员函数是属于类的,不属于对象,所以它没有this 指针,因此只能访问静态数据成员。
19、说下你对内存的了解?
(1)参考博客:20170327_请说出C++中的内存分区。