心口如一,犹不失为光明磊落丈夫之行也。——梁启超
文章目录
- :smirk:1. 语言基础
- 内存分配
- 指针参数传递和引用参数传递
- 四种强制转换
- 面向对象的三大特性并举例
- #define 和别名 typedef 的区别
- :blush:2. 标准库
- STL介绍
- 频繁调⽤ push_back() 的影响
- ++i 和 i++ 的区别
- ⼤端⼩端模式
- 回调函数的作⽤
- :satisfied:3. 四件套
- TCP三次握⼿和挥⼿
- 线程⽐进程具有哪些优势
- :satisfied:4.有目的的刻意练习
😏1. 语言基础
内存分配
代码区:存放程序的二进制代码
常量存储区:存储常量,一般不能改
全局/静态存储区:分为初始化和未初始化的两个相邻区域
堆:开发者管理,需要手动 new malloc delete free 进行内存分配与回收,可能会出现内存泄漏和空闲碎片的情况
指针参数传递和引用参数传递
指针参数传递本质是值传递,传递一个地址值;而引用传递传递的是实参变量的地址
指针传递可以改变其指向的对象,而引用对象不能被修改
四种强制转换
包括:static_cast, dynamic_cast, const_cast, reinterpret_cast
面向对象的三大特性并举例
封装:就是把客观事物封装成抽象的类,并且类可以把⾃⼰的数据和⽅法只让信任的类或者对象操作,对不可信的进⾏信息隐藏。⼀个类就是⼀个封装了数据以及操作这些数据的代码的逻辑实体。在⼀个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种⽅式,对象对内部数据提供了不同级别的保护,以防⽌程序中⽆关的部分意外的改变或错误的使⽤了对象的私有部分。
继承:是指可以让某个类型的对象获得另⼀个类型的对象的属性的⽅法。它⽀持按级分类的概念。继承是指这样⼀种能⼒:它可以使⽤现有类的所有功能,并在⽆需重新编写原来的类的情况下对这些功能进⾏扩展。通过继承创建的新类称为“⼦类”或者“派⽣类”,被继承的类称为“基类”、“⽗类”或“超类”。继承的过程,就是从⼀般到特殊的过程。要实现继承,可以通过“继承”和“组合”来实现。
继承概念的实现⽅式有两类:
实现继承:实现继承是指直接使⽤基类的属性和⽅法⽽⽆需额外编码的能⼒。
接⼝继承:接⼝继承是指仅使⽤属性和⽅法的名称、但是⼦类必需提供实现的能⼒。
多态:就是向不同的对象发送同⼀个消息,不同对象在接收时会产⽣不同的⾏为(即⽅法)。即⼀个接⼝,可以实现多种⽅法。
多态与⾮多态的实质区别就是函数地址是早绑定还是晚绑定的。如果函数的调⽤,在编译器编译期间就可以确定函数的调⽤地址,并产⽣代码,则是静态的,即地址早绑定。⽽如果函数调⽤的地址不能在编译器期间确定,需要在运⾏时才确定,这就属于晚绑定
#define 和别名 typedef 的区别
执⾏时间不同, typedef 在编译阶段有效, typedef 有类型检查的功能;#define是宏定义,发⽣在预处理阶段,不进⾏类型检查;功能差异, typedef ⽤来定义类型的别名,定义与平台⽆关的数据类型,与 struct的结合使⽤等。
#define 不只是可以为类型取别名,还可以定义常量、变量、编译开关等。 作⽤域不同,#define 没有作⽤域的限制,只要是之前预定义过的宏,在以后的程序中都可以使⽤。 ⽽ typedef 有⾃⼰的作⽤域。
😊2. 标准库
STL介绍
STL ⼀共提供六⼤组件,包括容器,算法,迭代器,仿函数,配接器和配置器,彼此可以组合
套⽤。容器通过配置器取得数据存储空间,算法通过迭代器存取容器内容,仿函数可以协助算 法完成不同的策略变化,配接器可以应⽤于容器、
仿函数和迭代器。 容器: 各种数据结构,如 vector, list, deque, set, map,⽤来存放数据, 从实现的⻆度来
讲是⼀种类模板。 算法: 各种常⽤的算法,如 sort(插⼊,快排,堆排序), search(⼆分查找), 从实现的
⻆度来讲是⼀种⽅法模板。 迭代器: 从实现的⻆度来看,迭代器是⼀种将 operator*,operator->,operator++,
operator–等 指针相关操作赋予重载的类模板,所有的 STL 容器都有⾃⼰的迭代器。 仿函数:从实现的⻆度看,仿函数是⼀种重载了
operator()的类或者类模板。 可以帮助算法实 现不同的策略。 配接器:⼀种⽤来修饰容器或者仿函数或迭代器接⼝的东⻄。
配置器:负责空间配置与管理,从实现的⻆度讲,配置器是⼀个实现了动态空间配置、空间管 理,空间释放的类模板。
频繁调⽤ push_back() 的影响
向 vector 的尾部添加元素,很有可能引起整个对象 存储空间的重新分配,重新分配更⼤的内 存,再将原数据拷⻉到新空间中,再释
放原有内存,这个过程是耗时耗⼒的,频繁对 vector 调⽤ push_back()会导致性能的下降。 在 C++11 之后, vector
容器中添加了新的⽅法: emplace_back() ,和 push_back() ⼀样的是都是在容器末尾添加⼀个新的元素进去,不同的是
emplace_back() 在效率上相⽐ 较于 push_back() 有了⼀定的提升。 emplace_back() 函数在原理上⽐
push_back() 有了⼀定的改进,包括在内存优化⽅⾯和
运⾏效率⽅⾯。内存优化主要体现在使⽤了就地构造(直接在容器内构造对象,不⽤拷⻉⼀个 复制品再使⽤)
+强制类型转换的⽅法来实现,在运⾏效率⽅⾯,由于省去了拷⻉构造过程, 因此也有⼀定的提升。
++i 和 i++ 的区别
前置加加不会产⽣临时对象,后置加加必须产⽣临时对象,临时对象会导致效率降低。
++i实现:
int& int::operator++ (){
*this +=1;
return *this;
}
i++实现:
const int int::operator(int) {
int oldValue = *this;
++(*this);
return oldValue;
}
⼤端⼩端模式
⼤端模式:是指数据的⾼字节保存在内存的低地址中,⽽数据的低字节保存在内存的⾼地址端。
⼩端模式,是指数据的⾼字节保存在内存的⾼地址中,低位字节保存在内存的低地址端。
直接读取存放在内存中的⼗六进制数值,取低位进⾏值判断:
int a = 0x12345678;
int *c = &a;
c[0] == 0x12 ⼤端模式
c[0] == 0x78 ⼩段模式
回调函数的作⽤
当发⽣某种事件时,系统或其他函数将会⾃动调⽤你定义的⼀段函数。
回调函数就相当于⼀个中断处理函数,由系统在符合你设定的条件时⾃动调⽤。为此,你需要
做三件事:1、声明;2、定义;3、设置触发条件,就是在你的函数中把你的回调函数名称转 化为地址作为⼀个参数,以便于系统调⽤。
😆3. 四件套
TCP三次握⼿和挥⼿
三次握⼿过程:
第⼀次:客户端发含SYN位, SEQ_NUM = S的包到服务器。(客-> SYN_SEND)
第⼆次:服务器发含ACK,SYN位且ACK_NUM = S + 1, SEQ_NUM = P的包到客户机。(服-> SYN_RECV)
第三次:客户机发送含ACK位, ACK_NUM = P + 1的包到服务器。(客 -> ESTABLISH,服 -> ESTABLISH)
四次挥⼿过程:
第⼀次:客户机发含FIN位, SEQ = Q的包到服务器。(客 -> FIN_WAIT_1)
第⼆次:服务器发送含ACK且ACK_NUM = Q + 1的包到服务器。(服-> CLOSE_WAIT,客-> FIN_WAIT_2)此处有等待
第三次:服务器发送含FIN且SEQ_NUM = R的包到客户机。(服-> LAST_ACK,客-> TIME_WAIT)此处有等待
第四次:客户机发送最后⼀个含有ACK位且ACK_NUM = R + 1的包到客户机。(服-> CLOSED)
线程⽐进程具有哪些优势
1)线程在程序中是独⽴的,并发的执⾏流,但是,进程中的线程之间的隔离程度要⼩;
2)线程⽐进程更具有更⾼的性能,这是由于同⼀个进程中的线程都有共性:多个线程将共享同⼀个进程虚拟空间;
3)当操作系统创建⼀个进程时,必须为进程分配独⽴的内存空间,并分配⼤量相关资源;
😆4.有目的的刻意练习
- 定义明确的目标
- 练习过程保持专注(归类整理、思考迁移)
- 获取反馈(无论是正的还是负的)
- 走出舒适区,在实际场景中验证知识或能力(学以致用)
以上。