设计模式

https://refactoringguru.cn/design-patterns

单例

https://zhuanlan.zhihu.com/p/37469260

https://blog.csdn.net/justloveyou_/article/details/64127789

一个类仅有一个实例

饿汉模式

实例在程序运行时被立即执行初始化

懒汉模式

实例在第一次被使用时才进行初始化

注意

new的单例的指针 不能用非单例的对象管理 会core

new的非单例的指针 不要在单例对象管理 会内存泄露

性能优化

1 性能指标

qps p95

2 性能压测

qps p95 为例

分为客户端 服务端 端到端

3 性能瓶颈

https://blog.csdn.net/xiaonuo911teamo/article/details/133521457

https://zhuanlan.zhihu.com/p/486301255

https://zhuanlan.zhihu.com/p/335091866

io

cpu

怎么看

火焰图

https://zhuanlan.zhihu.com/p/402188023

用perf工具

1.采样

perf.data

2.可视化

.data-> .unfold -> .folded -> .svg

网络

4 常见优化技术

https://www.cnblogs.com/xuanyuan/p/13524351.html

问题

语法

c++ 版本

https://blog.csdn.net/m0_37251750/article/details/125159533

头文件

https://www.runoob.com/w3cnote/cpp-header.html

作用

类似python的包

原理

1
2
3
4
/* math.h */
double f1();
double f2(double);
/* end of math.h */
1
2
3
4
5
6
7
8
9
10
11
12
/* math.cpp */
double f1()
{
//do something here....
return;
}
double f2(double a)
{
//do something here...
return a * a;
}
/* end of math.cpp */
1
2
3
4
5
6
7
8
/* main.cpp */
#include "math.h"
main()
{
int number1 = f1();
int number2 = f2(number1);
}
/* end of main.cpp */

1 预编译

include 的作用就是把每一个它出现的地方,替换成它后面所写的那个文件的内容。简单的文本替换,别无其他

main.cpp首先include “math.h”,就是把math.h的东西全部替换过来

2 编译

main.cpp f1,f2的声明 变 符号表

3 链接

根据符号表就可以在math.cpp找到f1,f2的实现

怎么写头文件

.h文件中能包含:

  • 类成员数据的声明,但不能赋值
  • 类静态数据成员的定义和赋值,但不建议,只是个声明就好。
  • 类的成员函数的声明
  • 非类成员函数的声明
  • 常数的定义:如:constint a=5;
  • 静态函数的定义
  • 类的内联函数的定义

不能包含:

  • 1.所有非静态变量(不是类的数据成员)的声明
  • 2.默认命名空间声明不要放在头文件,using namespace std;等应放在.cpp中,在 .h 文件中使用 std::string

怎么使用

https://blog.csdn.net/cnds123/article/details/132038160

首先要加载库文件

然后include

声明 定义

https://bbs.huaweicloud.com/blogs/292599

变量

声明:告诉编译器变量的名称和类型,而不分配内存

定义:给变量分配内存,可以为变量赋初值

函数

函数只要有实现即为定义,否则为声明

注意

声明要在使用前面 否则报错

关键字

static

1 变量

只能在定义时初始化,以后不行 如果没有显式初始化,会被程序自动初始化为0 静态成员变量必须类外初始化

生命周期和全局变量一样 程序结束才释放

就一个 公用

作用域:

​ 静态成员变量:类内

​ 静态全局变量:本文件

​ 静态局部变量:函数内

2 函数

静态成员函数:和类绑定 和对象没有关系

静态函数:只能在本文件用

extern

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

类名后加final

1.禁止被继承,但是可以继承别人

likely unlikely

if(likely(condition)), if(unlikely(condition)), if(condition)功能逻辑上一样

差别就是likely,unlikely编译器上有优化,likely告诉编译器大概率会走这里,unlikely告诉编译器大概率不走这

__attribute__

https://cloud.tencent.com/developer/article/1400469

override

继承的时候

子类函数声明的时候后面 + override 此时没有重写就会报错

auto

自动匹配类型

声明指针类型时,用auto和auto *没有任何区别

const

https://www.runoob.com/w3cnote/cpp-const-keyword.html

1.成员函数

不能修改非静态成员变量

2.函数返回值

3.auto const vs const auto

auto const 是一个常量

const auto 是一个变量 但是值不能改

4.不能移动赋值 移动初始化

5.成员变量

和成员变量引用类似

using

https://zhuanlan.zhihu.com/p/156155959

default

使用默认实现

只能作用于类内的某些特殊函数 比如构造 析构

thread_local

explicit

https://blog.csdn.net/fengbingchun/article/details/51168728

typedef

起别名

move

将左值转化为右值

namespace

https://www.runoob.com/cplusplus/cpp-namespaces.html

区分同名变量和函数

forward

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

image-20240310170013989

好处:效率

坏处:代码膨胀

析构函数

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

和赋值运算符的区别

初始化就是调用构造函数 非初始化就是调用赋值运算符

数组

数组名就是指向第一个元素的地址

数组作为函数返回值 返回指针

数组作为函数参数 传指针

指针

1 裸指针

本质

指针值就是地址 指针类型决定可以访问的内存大小

指针本身也是一种数据类型 占用内存

nullptr

调用普通函数没事

调用虚函数会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 不会报错

2 函数指针

函数名,函数名取地址,函数名取值结果一样

https://www.runoob.com/cprogramming/c-fun-pointer-callback.html

3 智能指针

本质

在普通指针外包一层

和普通指针区别 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 才会释放管理的内存

4 this指针

值:new的地址值,或者是当前对象的地址值

类型:就是当前类的类型

类内的函数调用 本质是this.funcname 不写的话默认有this

5 指针管理

说白了就是new出来的指针 谁来delete

不要忘记delete 不要重复delete

引用

https://www.cnblogs.com/david-china/p/17080072.html

左值 右值

区分左值还是右值 取决于 能否取地址

左值引用

&

引用左值

本质就是贴标签

省时 省内存

引用右值

加const

延长了右值的生命周期

贴标签

哪些要引用哪些不要

原则是大的要 小的不要 比如说

要:字符串 对象

不要:指针 数字

函数返回值

当返回一个引用时,要注意被引用的对象不能超出作用域

https://mesywang.github.io/2019/09/10/C++%E4%B8%AD%E5%BC%95%E7%94%A8%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC/

成员变量是引用

https://blog.csdn.net/lazyq7/article/details/48186291

右值引用

&&

引用右值

延长了右值的生命周期

贴标签

引用左值

move(左值) -> 右值

贴标签

万能引用

https://theonegis.github.io/cxx/C-%E4%B8%AD%E7%9A%84%E4%B8%87%E8%83%BD%E5%BC%95%E7%94%A8%E5%92%8C%E5%AE%8C%E7%BE%8E%E8%BD%AC%E5%8F%91/#%E5%BC%95%E7%94%A8%E6%8A%98%E5%8F%A0%EF%BC%88Universal-Collapse%EF%BC%89

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指针 无类型指针

(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

友元函数

友元类

代码块

{}把代码括起来

限制变量的生命周期

符号

1 重载

https://www.runoob.com/cplusplus/cpp-overloading.html

1
返回值 operator 符号 (参数列表);

1赋值运算符

拷贝

移动

2 顺序

https://blog.csdn.net/zhaominyong/article/details/126268983

1.首先按照优先级

2.优先级一样 按照结合性

指针符号和自增符号结合 6种情况

https://blog.csdn.net/xingjiarong/article/details/47071225

3 常见符号

1.::

域操作符

2.&

取地址

引用

位运算

3.*

乘法

注释

指针

4 …

可变参数

5 单引号 双引号

单引号表示字符

双引号表示字符串

string

c_str()

返回字符串首地址

重载 重写

重载

一个类的多个函数

重写

派生类 对 基类

继承

本质

作用域

3种方式

调用

1.有什么

就是本质里面的图

变量值决定

2.能访问什么

变量类型决定能访问什么

3.选最近的

单继承

多继承

从左往右

继承链

从上往下

多态

条件

1.继承

2.virtual+重写

3.父类指针或者引用指向子类对象

本质

没有vitual 不会调用子类

加上vitual 调用子类

switch语句

https://www.runoob.com/cplusplus/cpp-switch.html

for循环

1
2
for ( init; condition; increment )
for (auto &x : my_array)

初始化

1.{}

普通变量

自定义对象

调用普通的构造函数

classname instancename= {参数列表}

const classname instancename= {参数列表}

const classname& instancename= {参数列表} 和上面区别??

classname instancename {参数列表}

注释

单行 //

多行 / /

类型转换

https://blog.csdn.net/shuzfan/article/details/77338366

1.隐式

直接来

2.显示

( )

static_cast

dynamic_cast

const_cast

reinterpret_cast

3 向上 向下

基类 -> 派生

派生 -> 基类

模板

类型模板参数

就是变量类型不确定

1 函数模板

2 类模板

非类型模板参数

https://blog.csdn.net/lanchunhui/article/details/49634077

就是值不确定

1 函数模板

2 类模板

可变参数模板

https://blog.csdn.net/qq_62390970/article/details/131277193

参数数量可变的 函数模板和类模板

enum

枚举数据类型

特殊的类

struct

https://blog.csdn.net/bytxl/article/details/48340691

union

各变量互斥

抽象类/接口

至少有一个纯虚函数

有纯虚函数的类不能实例化

宏定义

ifndef define endif

https://www.cnblogs.com/challenger-vip/p/3386819.html

define

作用

预处理阶段 做 简单替换

define add(x,y) (x+y)

2 add(1,2) -> 2 (x+y)

符号介绍

无参

有参

嵌套

function,bind

https://blog.csdn.net/weixin_44378800/article/details/115210731

封装函数

然后调用

类访问修饰符

https://www.runoob.com/cplusplus/cpp-class-access-modifiers.html

public:类内类外都可以访问

private:类内,友元

protected:和private类似,区别是protected派生类可以访问

使用cpp文件的东西

1.

.cpp-> .h

include .h

2.

extern

编译

1 原理

编译器分类

gcc:c

g++:c++

静态库 动态库 静态链接 动态链接

https://www.runoob.com/w3cnote/cpp-static-library-and-dynamic-library.html

1 静态库 动态库

库是写好的现有的,成熟的,可以复用的代码 和python的 包一样

可以编译生成静态库和动态库

静态库.a(linux) , .lib(win) 动态库.so(linux) , .dll(win)

2 静态链接 动态链接

静态链接:静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,因此体积较大。

动态链接:动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在,因此代码体积较小.不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。带来好处的同时,也会有问题!如经典的DLL Hell问题,关于如何规避动态库管理问题

编译过程

https://developer.aliyun.com/article/1154672

可执行文件有main

so没有main

2 命令行编译

3 构建工具

1 为什么要构建工具呢?

当你的程序只有一个源文件时,直接就可以用gcc命令编译它。但是当你的程序包含很多个源文件时,用gcc命令逐个去编译时,你就很容易混乱而且工作量大,为什么呢?
因为各个文件之间还涉及到互相访问与链接,错综复杂的关系一个一个处理很麻烦,很容易出错,素衣需要一个工具来制定一个很好的编译规则,这就是make的作用了

2 vs(Visual Studio)为什么可以直接编译一个工程?

因为vs创建的工程,所有添加的文件都有链接管理

1 cmake

2 bazel

1 build文件

1 哪些文件要写

所有用到的文件都需要

2 怎么写

比如某个cpp

deps: 当前cpp 需要用到某个头文件,那这个头文件就要写到这

2 bazel clean

3 编译可执行文件

bazel build -c opt //opt/data:test

生成路径:bazel-bin/opt/data/test

4 编译.so

https://blog.csdn.net/zyq880625/article/details/131393651

5 编译选项

—strip=always

—copt=”-g”

6 交叉编译

https://zhuanlan.zhihu.com/p/422055988

https://blog.csdn.net/pengfei240/article/details/52912833

问题

异常处理

try-exception-finally

1
2
3
4
5
6
try:
XXX
exception XXX:
XXXXX
finally:
XXXX

raise

https://blog.csdn.net/qq_35541155/article/details/108809130

一般代码错误会触发特定异常

某些场景,代码没有错误,也可以人工触发特定异常,借助raise

1
2
3
4
5
6
7
8
9
10
11
12
13
try:
try:
raise ValueError(123)
except Exception as e:
print(e)
raise ValueError(456)

except Exception as e1:
print(e1)




1
2
3
123
456

变量

本质

https://zhuanlan.zhihu.com/p/331732504

1.对象:python里一切皆对象

对象的本质是:对象是分配的一块内存,有足够的空间去表示它们所代表的值。—— 《Learning Python》

对象具有三要素:标识(identity)、类型(type)、值(value)

img

可变对象,不可变对象

img

2.变量:是对象的一个临时标签

1
2
3
x = 666
y = x
x = x + 1

执行以上三句,在 python 中意味着什么, 实际发生了什么?

  1. x = 666会在内存中创建一个整型对象666,然后变量x相当于一个标签,贴在此对象上,注意666是对象,x是变量
  2. y = xy也作为这个整型对象666的标签,而不是重新在内存中创建一个对象。
  3. x = x+1x的值加 1,然后在内存中创建另一个整型对象667,将x贴在这个对象上,而不是原来的 666 上。

变量作用域范围

作用域从小到大 LEGB

  • local
  • enclosed 闭包
  • global 全局变量
  • built in 内置的
  

:D 一言句子获取中...