- bool falg类型的数据与0作比较时应为:if(flag) if(!flag)
- float x与0值做比较,浮点变量不能用“==”“!=”与数字作比较,要转换成 “>=””<=”的形式:const float ESPINON=0.00001,if(x>=-ESPINON)&&if(x<=ESPINON)
- Char *p与0值做比较时:if(NULL==p) if(p!=NULL)
- c/c++中的struct的主要区别是c中struct不可以含有成员函数,c++中struct可以,c++中struct和class的主要区别在于默认的存取权限不同,struct默认是public,class默认是private
- 数组:数据顺序存储,大小固定。链表:数据可以随机存储,大小可以动态改变
- Sizeof和初不初始化无关,strlen和初不初始化有关
- 子函数中malloc申请的动态空间不能传递到主函数中
- 使用malloc申请的内存要主动调用free,new申请的内存要调用delete,否则会导致内存泄漏
- <>编译器会从标准库路径开始搜索,“”编译器会从用户的工作路径开始搜索
- const的用途:1.可以定义const常量2.const可以修饰函数的参数、返回值和定义体,被const修饰的东西会受到强制保护
- static的用途:1.修饰局部变量延长局部变量的生命周期2.修饰全局变量限制全局变量的作用域3.修饰函数限制函数的作用域
- 堆栈溢出一般是因为没有回收垃圾资源,也可能是由于循环的递归引起的,或者由于分配了过大的局部变量
- Heap是堆,stack是栈,stack的空间是由操作系统自动分配和释放,Heap的空间可以手动分配和释放,stack空间有限,Heap是很大的自由存储区
- -:普通文件 d:目录文件 c:字符设备文件 b:块设备文件
l:软连接文件 p:管道文件 s:套接字文件
- gcc的编译过程:1.预处理,将C源文件编译成C文件,只做头文件的展开,宏替换掉,注释去掉,不做语法检查(代码有错时在这一步检测不出来) gcc -E test.c -o test.i; 2.编译,将上一步生成的C文件编译成汇编文件 gcc -S test.i -o test.s; 3.汇编,将上一步生成的汇编文件编译成机器文件(OBJ格式)gcc -c test.s -o test.o; 4.链接,将所有机器文件共同参与链接,生成一个可执行文件
- 有符号数:有符号位,最高位为0代表正数,为1负数
无符号为:没有符号位
Char:1字节
有符号位:signed char (1000 0000~0111 1111)-128~127
无符号位:unsinged char (0000 0000~1111 1111)0~255
Short:2字节
有符号位:signed short (-2^15-2^15-1)
无符号位:unsigned short (0-2^16-1)
Int :4字节
有符号位:signed int (-2^31-2^31-1)
无符号位:unsigned int (0-2^32-1)
- 指针在32OS下占4字节,64OS下占8字节
- 关键字volatile:提示编译器对象的值可能在编译器未监测到的情况下改变
- static函数在内存中只有一份,普通函数在每个调用中维持一份拷贝
- static把局部变量改变为静态变量后改变了存储方式即改变了生命周期,把全局变量改变为静态变量后没有改变存储方式,只限制了作用域
- 局部变量存储在栈(stack)中,全局变量存储在静态存储区,动态申请的变量存储在堆(Heap)区
- 顺序表的特点:(1)顺序且连续存储,大小固定(2)访问方便(3)插入、删除要移动元素,不方便
- 链表的特点:(1)申请的空间可以不连续(2)访问不方便(3)插入、删除不用移动元素
- 程序是静态的,是一些存储在磁盘上的指令的有序集合,没有执行的概念;进程是动态的,是程序执行的过程,进程是程序执行和资源管理的最小单位
- 每个进程都有独立的资源空间,当进程创建时OS会为进程分配4G的空间(1G内核空间和3G用户空间,内核空间是进程共享的)
- 守护进程的特点:始终在后台运行,系统启动时运行,系统关闭时结束,始终独立于任何终端,周期性的执行一些任务
28.(1)创建和销毁较频繁使用线程,应为创建进程的花销大
(2)需要传输大量数据使用线程,因为多线程切换速度快,不需要跨越进程边界
(3)安全稳定选进程,频繁快速选线程
29.线程中全局变量和堆区的数据是共享的
30.线程使轻量级进程
31.多进程优点:
(1)每个进程相互独立,不影响主程序的稳定性,子进程崩溃没关系
(2)通过增加cpu就可以扩充性能
(3)可以尽量减少线程加锁/解锁的影响,极大提高性能,就算是线程运行的模块算法效率低也没关系
(4)每个子进程都有2GB的地址空间和相关资源,总体能够达到的性能上限非常大
多进程缺点:
- 逻辑控制复杂,需要和主程序交互
- 需要跨进程边界,如果要传输大量数据就不太好,适合小量数据的传输和密集运算
- 多进程调度开销大
多线程的优点:
- 无需跨进程边界
- 程序逻辑和控制方式简单
- 所有线程可以共享内存和变量
- 线程消耗的资源比进程少
多线程的缺点:
- 每个线程和主程序共用地址空间,受限于2GB的地址空间
- 线程之间的控制和加锁比较麻烦
- 一个线程的崩溃可能会影响整个程序的稳定性
- 线程能提高的性能有限,会消耗更多的CPU
33.子进程所有资源都继承与父进程,得到父进程资源的副本。区别是进程的ID号不同、父进程的锁子进程不继承fork的返回值不同
34.理论上,一个进程可用虚拟空间是2GB,线程的栈的大小是1MB,理论上可以创建2048个线程,一个进程可以创建的线程数由进程的虚拟空间和线程的栈的大小共同决定
35.红黑树是一种自平衡二叉查找树
36.平衡二叉树是一个空树,或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是平衡二叉树
37.流量控制就是让发送方的发送速率不要太快,让接收方来得及接收。对于成块数据流,TCP采用滑动窗口机制实现流量的控制,对于交互数据流,TCP采用捎带ACK和Nagle算法实现流量控制
38.多线程,多进程的优缺点:
(1)一个进程死亡不会影响到其他进程,但一个线程死亡可能会影响到它本身所处的整个进程
(2)创建多进程的系统开销比多线程大
(3)多进程要跨越进程边界,不适合传输大量数据,多线程不需要跨越进程边界,适合传输大量数据,并且多线程可以共享同一进程的共享内存和变量
39.进程是资源分配的基本单位,线程是程序执行的最小单位
40.创建和销毁频繁用线程,因为创建进程的花销大
需要大量数据传送用线程,因为多线程不需要跨越进程边界,切换速度快
安全稳定选进程,快速频繁选线程
41.进程间的同步(通讯):有名/无名管道,信号量,信号,共享内存,消息队列,socket
42.线程间通讯(锁):信号量,读写锁,条件变量,互斥锁,自旋锁
43.父进程调用fork()后克隆一个子进程,子进程和父进程拥有相同内容的代码段,数据段和用户堆栈,父子进程的执行顺序不一定,一般设置父进程等待子进程执行完
44.进程上下文:当内核切换到另一个进程时,它会保存当前进程的所有状态(CPU的所有寄存器中的值,进程的状态以及堆栈中的内容),以便再次执行该进程时能够恢复切换时的状态,继续运行
中断上下文:由于触发信号,导致CPU中断当前进程,转而去执行另外的程序,保存当前进程的所有资源后去执行中断处理函数,快速执行完中断后返回并恢复上一个进程的资源,继续执行
45.malloc和free是C/C++的库函数,需要头文件的支持,new和delete是C++的关键字,不需要头文件,要编译器的支持
使用new申请空间时不需要指定空间的大小,使用malloc申请空间的时候需要指定空间的大小
用new申请内存成功时返回的是对象类型的指针,不需要进行类型的转换,用malloc申请内存成功时返回的是void *,需要进行强制转换成我们需要的指针类型
New内存分配失败时会抛出bad_alloc异常,malloc内存分配失败时返回NULL
46.应用程序通过malloc函数向程序的虚拟空间申请一片虚拟地址空间,与物理内存没有直接关系,得到的是虚拟地址空间中的地址,程序运行提供的物理内存由操作系统完成
47.strcpy不会做任何的检查,不会判断拷贝的大小,不会判断目的地址内存是否够用
Strncpy计算了拷贝的大小,但没有判断目标边界
Memcpy可以拷贝任意类型的数据,把资源内存的内容拷贝到目标内存中,有一个size变量控制拷贝的字节数,strcpy只能拷贝字符串
48.dynamic_cast的作用:实现安全的向上转换,如果转换不成功,就会把被赋值的指针赋值为nullptr
父类转成子类,dynamic_cast要求父类中必须要有虚函数
Static_cast的作用:将expression类型强制转换为type-name类型
可以把原本只允许单向转换的场景变成允许双向转换
49.static修饰局部变量:使其变为静态存储方式,局部变量在函数执行完后不会被释放,继续保留在内存中
Static修饰全局变量:使其只在本文件内有效,限制其作用域其他文件不能连接和引用该变量
Static修饰函数:对函数的连接方式产生影响,使函数只在本文件内有效,对其他文件不可见,这样的函数又叫静态函数,静态函数的好处是不用担心其他文件内的同名函数产生干扰,对函数本身也是一种保护机制
50.const修饰常量:定义时就初始化,以后不能更改、
Const修饰形参:该形参不能在函数内不能改变
Const修饰类成员函数:该函数只能对成员变量进行读操作,被const修饰的都受到强制保护,预防意外变动提高程序的健壮性
51.一个定义为volatile的变量说明这个变量可能随时都会被更改,优化器在使用这个值时会到内存中调用这个值,而不是使用保存在寄存器中的备份
52.#define定义的常量没有类型,所给出的是一个立即数,在预处理阶段进行替换
53.sizeof是操作符,也是关键字,strlen是函数
53.引入inline修饰符,表述为内联函数,内链是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,提高函数的执行效率
54.TCP—传输控制协议,提供的是面向连接、可靠的字节流服务,在客户端和服务端通信之前必须先建立TCP连接
UDP—用户数据报协议,是面向数据报的运输层协议,不保证可靠性,只是把应用程序传给IP层的数据报发送出去,不能确保能够准确的到达目的地
(1)TCP面向连接,UDP不面向连接
(2)UDP程序结构较简单
(3)TCP面向字节流,UDP基于数据报
(4)TCP保证数据的准确性,UDP可能会丢包
(5)TCP保证数据顺序到达,UDP不保证
55.TCP可靠是因为TCP在传输数据之前会有三次握手来建立连接,数据传输完成后会断开连接节约系统资源
56.TCP的缺点:传输速度慢、效率低,占用系统资源多,容易受到攻击。在传输数据之前要先建立连接,并且还有确认机制、重传机制、拥塞机制,会消耗大量的时间。要在每一台设备上维护所有的传输连接,每个连接都会占用系统CPU、内存等硬件设备,而且正是因为TCP有确认机制和三次握手机制,会被利用遭受攻击
57.UDP比TCP传输速度要快,也更安全。因为UDP没有这些协议,是一种无状态的传输协议
58.因为UDP没有TCP的机制,传数据的时候如果网络质量不好很容易出现丢包,造成数据缺失
59.TCP、UDP适用场景
TCP:传输一些对信号完整性、信号质量有要求的信息
UDP:对网络质量要求不高,要求传输速度要快的场景