cpu架构
https://www.51cto.com/article/747063.html
x86
X86采用CISC复杂指令集计算机
X86则是主要应用于Intel,AMD等PC机
arm
ARM采用的是RISC精简指令集计算机
ARM主要应用于移动终端之中,类如手机,平板
https://www.51cto.com/article/747063.html
X86采用CISC复杂指令集计算机
X86则是主要应用于Intel,AMD等PC机
ARM采用的是RISC精简指令集计算机
ARM主要应用于移动终端之中,类如手机,平板
https://developer.aliyun.com/article/343804
内存泄露:就是内存持续上涨的现象
内存溢出:内存不够用了
1.内存碎片
2.手动申请的内存没有释放
1 tcmalloc
2 jemalloc
把jemalloc 编到包里
生成map 转成svg
对比变化
3 asan
4 valgrind
内存峰值
常驻内存
valgrind 分析内存
pahole 分析内存
https://blog.csdn.net/zju_fish1996/article/details/108858577
https://blog.csdn.net/weixin_41055260/article/details/118586493
https://blog.csdn.net/u013554213/article/details/95959598
https://www.cnblogs.com/fanblogs/p/12658860.html
当程序发生崩溃时 系统会core dump
1.系统开启core dump
2.查询core dump文件路径
3.修改core文件的路径
https://c-cpp.com/c/program/SIG_types
1.指针二次释放
2.并发问题
3.内存访问越界
4.除0
5.野指针
1 有core文件
gdb 带符号表的包 core文件
bt
2 日志打印调用栈
minidump
3 没有core文件,日志也没有打印调用栈
1.计算地址偏移
需要日志dump出来core的函数地址和首地址
地址偏移=core的函数地址-首地址
2.根据地址偏移确定core函数
gdb
addr2line
addr2line -e 带符号表的包 地址偏移 -f -C
进程对比线程
并发对比并行
多进程多线程是并发还是并行取决于硬件资源
并发问题:因为多线程引发的问题
线程安全:一个方法或者实例在多线程环境下稳定运行
并发问题如下:
一个线程改了另外一个线程用的值
同时修改一个容器
atomic
线程安全的变量
互斥锁
lock
当前线程lock 只有两种结果 1 true的话 阻塞别的线程(别的线程也用这个锁) 2 false 被别的线程阻塞了
unlock
构造函数lock
析构函数unlock
线程之间的交互通信
wait
wait_for
notify_one
notify_all
1.创建线程池
2.申请线程执行
3.主线程等待子线程执行完
可以在子线程里面创造线程,此时子线程对于新创建的线程就是相对主线程
ide debug可以选线程,gdb也可以
注意线程的生命周期,线程之间的关系
https://blog.csdn.net/m0_45861545/article/details/120835738
https://juejin.cn/post/6920784699493187591
F12 -> network
https://refactoringguru.cn/design-patterns
https://zhuanlan.zhihu.com/p/37469260
https://blog.csdn.net/justloveyou_/article/details/64127789
一个类仅有一个实例
饿汉模式
实例在程序运行时被立即执行初始化
懒汉模式
实例在第一次被使用时才进行初始化
注意
new的单例的指针 不能用非单例的对象管理 会core
new的非单例的指针 不要在单例对象管理 会内存泄露
qps p95
qps p95 为例
分为客户端 服务端 端到端
https://blog.csdn.net/xiaonuo911teamo/article/details/133521457
https://zhuanlan.zhihu.com/p/486301255
https://zhuanlan.zhihu.com/p/335091866
怎么看
火焰图
https://zhuanlan.zhihu.com/p/402188023
用perf工具
1.采样
perf.data
2.可视化
.data-> .unfold -> .folded -> .svg
https://www.cnblogs.com/xuanyuan/p/13524351.html
https://blog.csdn.net/m0_37251750/article/details/125159533
https://www.runoob.com/w3cnote/cpp-header.html
类似python的包
1 | /* math.h */ |
1 | /* math.cpp */ |
1 | /* main.cpp */ |
1 预编译
include 的作用就是把每一个它出现的地方,替换成它后面所写的那个文件的内容。简单的文本替换,别无其他
main.cpp首先include “math.h”,就是把math.h的东西全部替换过来
2 编译
main.cpp f1,f2的声明 变 符号表
3 链接
根据符号表就可以在math.cpp找到f1,f2的实现
.h文件中能包含:
不能包含:
https://blog.csdn.net/cnds123/article/details/132038160
首先要加载库文件
然后include
https://bbs.huaweicloud.com/blogs/292599
变量
声明:告诉编译器变量的名称和类型,而不分配内存
定义:给变量分配内存,可以为变量赋初值
函数
函数只要有实现即为定义,否则为声明
注意
声明要在使用前面 否则报错
1 变量
只能在定义时初始化,以后不行 如果没有显式初始化,会被程序自动初始化为0 静态成员变量必须类外初始化
生命周期和全局变量一样 程序结束才释放
就一个 公用
作用域:
静态成员变量:类内
静态全局变量:本文件
静态局部变量:函数内
2 函数
静态成员函数:和类绑定 和对象没有关系
静态函数:只能在本文件用
https://www.51cto.com/article/768503.html
https://blog.csdn.net/w2865673691/article/details/13018563
https://blog.csdn.net/xingjiarong/article/details/47656339
extern
原理:就是先声明 告诉编译器定义在别的地方
作用:在本文件使用别的文件的变量和函数 和include类似
extern “c”
表示按照c语言的方式去编译
类名后加final
1.禁止被继承,但是可以继承别人
if(likely(condition)), if(unlikely(condition)), if(condition)功能逻辑上一样
差别就是likely,unlikely编译器上有优化,likely告诉编译器大概率会走这里,unlikely告诉编译器大概率不走这
https://cloud.tencent.com/developer/article/1400469
继承的时候
子类函数声明的时候后面 + override 此时没有重写就会报错
自动匹配类型
声明指针类型时,用auto和auto *没有任何区别
https://www.runoob.com/w3cnote/cpp-const-keyword.html
1.成员函数
不能修改非静态成员变量
2.函数返回值
3.auto const vs const auto
auto const 是一个常量
const auto 是一个变量 但是值不能改
4.不能移动赋值 移动初始化
5.成员变量
和成员变量引用类似
https://zhuanlan.zhihu.com/p/156155959
使用默认实现
只能作用于类内的某些特殊函数 比如构造 析构
https://blog.csdn.net/fengbingchun/article/details/51168728
起别名
将左值转化为右值
https://www.runoob.com/cplusplus/cpp-namespaces.html
区分同名变量和函数
https://zhuanlan.zhihu.com/p/161039484
引用的对象可能是左值 也可能是右值 但是引用变量是左值 引用变量加上forward就可以得到之前的状态
声明
1 | return_type function_name( parameter list ); |
函数参数
1 本质
double& setValues(int& i)
int & i = 传入的变量
2 传值 传指针 传引用
3 参数的默认值
函数声明或者函数实现有一个地方有默认值就可以
4 可变参数
函数返回值
https://blog.csdn.net/jmh1996/article/details/78384083
1 本质
int fun(int a){
return a*a;
}
int result = fun(4);
a.值给临时变量
int tmp = a*a
b.临时变量值给外面变量
int result = tmp
= 0
没有函数体
= default
默认实现
https://www.runoob.com/cplusplus/cpp-functions.html
https://zhuanlan.zhihu.com/p/375828786
好处:效率
坏处:代码膨胀
when
当变量的内存要释放的时候,会自动调用析构函数
注意引用 (左值引用 右值引用) 当最后一个标签的生命周期结束时候才会析构
作用
不是用来释放内存的 是在释放内存前用来做一些清理工作的
析构顺序
原则就是先构造后析构 刚好和构造函数的顺序反一下
先调用子类的析构函数 -> 析构子类成员变量 从下往上 -> 调用父类的析构函数 -> 析构父类成员变量 从下往上
默认的
不写 就有默认的
写了 就覆盖
虚析构
就是父类的析构函数+ virtual
1 多态
不加:只析构父类 内存泄露
加:先析构子类 然后析构父类
原理??
2 没有多态
无所谓
when
申请内存的时候
作用
初始化
初始化列表
https://blog.csdn.net/hzhsan/article/details/55187877
构造函数有两个阶段
1.初始化
初始化列表就是显示初始化
不写初始化列表就是隐性初始化
2.赋值
函数体里面
普通构造函数
有默认的
拷贝构造
有默认的
浅拷贝 深拷贝
https://blog.csdn.net/weixin_44788542/article/details/126234533
移动构造
有默认的
参数左值引用就是拷贝 右值引用就是移动
转移所有权
https://blog.csdn.net/weixin_44788542/article/details/126284429
和赋值运算符的区别
初始化就是调用构造函数 非初始化就是调用赋值运算符
数组名就是指向第一个元素的地址
数组作为函数返回值 返回指针
数组作为函数参数 传指针
指针值就是地址 指针类型决定可以访问的内存大小
指针本身也是一种数据类型 占用内存
调用普通函数没事
调用虚函数会core
https://zhuanlan.zhihu.com/p/337060273
p
*p
p[0]=*p
p+1 地址值+p的类型字节数
int *ptr[MAX];
在这里,把 ptr 声明为一个数组,由 MAX 个整数指针组成
1 | int **var; |
1 非new的系统自动释放
2 new的必须手动释放
delete p
p = nullptr 防止野指针
delete nullptr 不会报错
函数名,函数名取地址,函数名取值结果一样
https://www.runoob.com/cprogramming/c-fun-pointer-callback.html
本质
在普通指针外包一层
和普通指针区别 new出来的 普通指针要手动释放 智能指针会自动释放
指向数组
https://blog.csdn.net/weixin_43705457/article/details/97617676
操作
1 reset
p.reset(q) // 释放p原来指向的内存,然后重新指向q
p.reset() // 重置为nullptr,等于手动释放
2 get
p.get() // 获取指针地址
3 release
q=p.release() // 返回原来指向的地址,p变为nullptr,其实就是释放对指针的管理权
4 unique_ptr
不能拷贝
只能移动或者引用
5 shard_ptr
可以拷贝
当引用计数为0 才会释放管理的内存
值:new的地址值,或者是当前对象的地址值
类型:就是当前类的类型
类内的函数调用 本质是this.funcname 不写的话默认有this
说白了就是new出来的指针 谁来delete
不要忘记delete 不要重复delete
https://www.cnblogs.com/david-china/p/17080072.html
区分左值还是右值 取决于 能否取地址
&
引用左值
本质就是贴标签
省时 省内存
引用右值
加const
延长了右值的生命周期
贴标签
哪些要引用哪些不要
原则是大的要 小的不要 比如说
要:字符串 对象
不要:指针 数字
函数返回值
当返回一个引用时,要注意被引用的对象不能超出作用域
成员变量是引用
https://blog.csdn.net/lazyq7/article/details/48186291
&&
引用右值
延长了右值的生命周期
贴标签
引用左值
move(左值) -> 右值
贴标签
https://www.cnblogs.com/yinheyi/p/14853787.html#%E5%BC%95%E7%94%A8%E6%8A%98%E5%8F%A0
template < typename T> void MyFunc(T&& value) { }
上面就是万能引用 既可以用于左值引用 又可以用于右值引用
因为引用折叠特性,才有了万能引用
局部作用域:在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁。
对象作用域
类作用域:static
全局作用域:在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁。
void *
void指针 无类型指针
(void)变量
https://blog.csdn.net/qq_33611327/article/details/77770144
FLT_EPSILON
https://blog.csdn.net/Hodors/article/details/136497256
https://blog.csdn.net/weixin_38293850/article/details/80191242
友元函数
友元类
{}把代码括起来
限制变量的生命周期
https://www.runoob.com/cplusplus/cpp-overloading.html
1 | 返回值 operator 符号 (参数列表); |
拷贝
移动
https://blog.csdn.net/zhaominyong/article/details/126268983
1.首先按照优先级
2.优先级一样 按照结合性
指针符号和自增符号结合 6种情况
https://blog.csdn.net/xingjiarong/article/details/47071225
1.::
域操作符
2.&
取地址
引用
位运算
3.*
乘法
注释
指针
4 …
可变参数
5 单引号 双引号
单引号表示字符
双引号表示字符串
返回字符串首地址
重载
一个类的多个函数
重写
派生类 对 基类
本质
作用域
3种方式
调用
1.有什么
就是本质里面的图
变量值决定
2.能访问什么
变量类型决定能访问什么
3.选最近的
单继承
多继承
从左往右
继承链
从上往下
条件
1.继承
2.virtual+重写
3.父类指针或者引用指向子类对象
本质
没有vitual 不会调用子类
加上vitual 调用子类
https://www.runoob.com/cplusplus/cpp-switch.html
1 | for ( init; condition; increment ) |
普通变量
自定义对象
调用普通的构造函数
classname instancename= {参数列表}
const classname instancename= {参数列表}
const classname& instancename= {参数列表} 和上面区别??
classname instancename {参数列表}
单行 //
多行 / /
https://blog.csdn.net/shuzfan/article/details/77338366
直接来
( )
static_cast
dynamic_cast
const_cast
reinterpret_cast
基类 -> 派生
派生 -> 基类
就是变量类型不确定
1 函数模板
2 类模板
https://blog.csdn.net/lanchunhui/article/details/49634077
就是值不确定
1 函数模板
2 类模板
https://blog.csdn.net/qq_62390970/article/details/131277193
参数数量可变的 函数模板和类模板
枚举数据类型
https://blog.csdn.net/bytxl/article/details/48340691
各变量互斥
至少有一个纯虚函数
有纯虚函数的类不能实例化
https://www.cnblogs.com/challenger-vip/p/3386819.html
作用
预处理阶段 做 简单替换
define add(x,y) (x+y)
2 add(1,2) -> 2 (x+y)
符号介绍
无参
有参
嵌套
https://blog.csdn.net/weixin_44378800/article/details/115210731
封装函数
然后调用
https://www.runoob.com/cplusplus/cpp-class-access-modifiers.html
public:类内类外都可以访问
private:类内,友元
protected:和private类似,区别是protected派生类可以访问
1.
.cpp-> .h
include .h
2.
extern