结构体和类的区别
结构体默认继承是public。class默认继承是privare
tcp udp区别场景
视频会议为什么不用udp传输?
因为udp的传输不像tcp传输基于流的有序的传输,所以当传输视频或者音频的时候,到达的数据包可能是乱序的,会产生错误,还有可能在传输的过程中产生丢包的问题,所以要进行确认和重传机制,这样就和tcp一样了,所以就使用了tcp进行传输
三大范式
explict
【C++】explicit关键字详解(explicit关键字是什么? 为什么需要explicit关键字? 如何使用explicit 关键字)-CSDN博客
用三个线程分别打印’A’、’B’、’C’,线程1打印A,线程2打印B,线程3打印C,请实现三个线程同时启动并协作始终打印 ABCABCABC
#include <iostream>
#include <pthread.h>
using namespace std;
pthread_cond_t mycond;
pthread_mutex_t mymutex;
int ct = 0;
void* mythread1(void *arg){
while(1){
pthread_mutex_lock(&mymutex);
while(ct % 3 != 0){
pthread_cond_wait(&mycond, &mymutex); //还没轮到,继续等待
}
cout << 'A';
++ct;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
void* mythread2(void *arg2){
while(1){
pthread_mutex_lock(&mymutex);
while(ct % 3 != 1){
pthread_cond_wait(&mycond, &mymutex);
}
cout << 'B';
++ct;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
void* mythread3(void *arg3){
while(1){
pthread_mutex_lock(&mymutex);
while(ct % 3 != 2){
pthread_cond_wait(&mycond, &mymutex);
}
cout << 'C' << endl;
++ct;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
int main(){
pthread_mutex_init(&mymutex, NULL);
pthread_cond_init(&mycond,NULL);
pthread_t t1;
pthread_t t2;
pthread_t t3;
pthread_create(&t1, NULL, mythread1, NULL);
pthread_create(&t2, NULL, mythread2, NULL);
pthread_create(&t3, NULL, mythread3, NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 0;
}
MySQL中SQL生命周期与执行流程_mysql设置表生命周期-CSDN博客
z字
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> result;
if(root==NULL)return result;
queue<TreeNode*> qe;
qe.push(root);
while(!qe.empty()){
vector<int> vec;
int size = qe.size();
while(size--){
TreeNode* tmp=qe.front();
vec.push_back(tmp->val);
qe.pop();
if(tmp->left)qe.push(tmp->left);
if(tmp->right)qe.push(tmp->right);
}
if(result.size()%2==1) reverse(vec.begin(),vec.end());
result.push_back(vec);
}
return result;
}
};
层序遍历 加翻转。二层数组的size是层数大小。。。
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int value;
struct node *pleft;
struct node *pright;
}BinaryRree;
BinaryRree *Createtree()
{
BinaryRree *proot=NULL;
//根
proot=(BinaryRree*)malloc(sizeof(BinaryRree));
proot->value=1;
//左
proot->pleft=(BinaryRree*)malloc(sizeof(BinaryRree));
proot->pleft->value=2;
//左的左
proot->pleft->pleft=(BinaryRree*)malloc(sizeof(BinaryRree));
proot->pleft->pleft->value=4;
proot->pleft->pleft->pleft=NULL;
proot->pleft->pleft->pright=NULL;
//左的右
proot->pleft->pright=(BinaryRree*)malloc(sizeof(BinaryRree));
proot->pleft->pright->value=5;
proot->pleft->pright->pleft=NULL;
proot->pleft->pright->pright=NULL;
//右
proot->pright=(BinaryRree*)malloc(sizeof(BinaryRree));
proot->pright->value=3;
proot->pright->pleft=NULL;
proot->pright->pright=NULL;
return proot;
}
void PreorderTravelsal(BinaryRree *ptree)
{
if(ptree == NULL )return;
//根
printf("%d ",ptree->value);
//左子树
PreorderTravelsal(ptree->pleft);
//右子树
PreorderTravelsal(ptree->pright);
}
int main()
{
BinaryRree *proot=NULL;
proot=Createtree();
PreorderTravelsal(proot);
return 0;
}
实现一个完整的 String 类:构造、拷贝、赋值、移动和析构
让我们一步一步实现一个完整的 String 类:构造、拷贝、赋值、移动和析构_string类的构造函数,析构函数,赋值函数,移动构造-CSDN博客
class String {
public:
// 构造:默认(传参)、拷贝构造、移动构造
String(const char *str = nullptr);
String(const String &other);
String(String &&other);
// 析构
~String();
// 赋值:拷贝赋值、移动赋值
String &operator=(const String &other);
String &operator=(String &&other);
private:
char *m_data;
};
String::String(const char *str)
{
if (str == nullptr) {
m_data = new char[1];
*m_data = '\0';
cout << "Default constructor" << endl;
}
else {
int length = strlen(str);
m_data = new char[length + 1];
strcpy(m_data, str);
cout << "Pass argument constructor" << endl;
}
}
String::String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
cout << "Copy constructor" << endl;
}
String::String(String &&other)
{
m_data = other.m_data;
other.m_data = nullptr;
cout << "Move constructor" << endl;
}
String::~String()
{
delete[] m_data;
cout << "Destructor" << endl;
}
String &String::operator=(const String &other)
{
if (this != &other) {
if (!m_data) delete[] m_data;
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
}
cout << "Copy assignment" << endl;
return *this;
}
String &String::operator=(String &&other)
{
if (this != &other) {
delete[] m_data;
m_data = other.m_data;
other.m_data = nullptr;
}
cout << "Move assignment" << endl;
return *this;
}
class String {
public:
// 构造:默认(传参)、拷贝构造、移动构造
String(const char *str = nullptr);
String(const String &other);
String(String &&other);
// 析构
~String();
// 赋值:拷贝赋值、移动赋值
String &operator=(const String &other);
String &operator=(String &&other);
private:
char *m_data;
};
String::String(const char *str)
{
if (str == nullptr) {
m_data = new char[1];
*m_data = '\0';
cout << "Default constructor" << endl;
}
else {
int length = strlen(str);
m_data = new char[length + 1];
strcpy(m_data, str);
cout << "Pass argument constructor" << endl;
}
}
String::String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
cout << "Copy constructor" << endl;
}
String::String(String &&other)
{
m_data = other.m_data;
other.m_data = nullptr;
cout << "Move constructor" << endl;
}
String::~String()
{
delete[] m_data;
cout << "Destructor" << endl;
}
String &String::operator=(const String &other)
{
if (this != &other) {
if (!m_data) delete[] m_data;
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
}
cout << "Copy assignment" << endl;
return *this;
}
String &String::operator=(String &&other)
{
if (this != &other) {
delete[] m_data;
m_data = other.m_data;
other.m_data = nullptr;
}
cout << "Move assignment" << endl;
return *this;
}
类的拷贝赋值函数
赋值函数则是把一个新的对象赋值给一个原有的对象,所以如果原来的对象中有内存分配要先把内存释放掉,而且还要检察一下两个对象是不是同一个对象,如果是,不做任何操作,直接返回。
值传递和引用传递的区别
strlen 和sizeof 的区别
sizeof 运算符:计算所占的字节大小
strlen函数: 字符串的具体长度即字符个数
sizeof()在编译时计算好了,strlen()在运行时计算
交换机和路由器的区别
用最通俗易懂的话告诉你交换机和路由器的区别_交换机通俗理解-CSDN博客
cmake
最简单的构建过程:
make是读取makefile文件中定义的规则来执行构建的构成
每次都会检查 依赖的源文件是否更新 更新了就会重新编译
先把每个源文件编译成.o文件 最后再把每个.o文件链接成可执行文件 这样写的好处是 当我们修改了其中的一个源文件 只需要重新编译一下这个源文件 然后再链接就可以 不需要把没有修改的源文件进行编译 当项目有多个源文件的时候就会更加高效
加一个clean可以删除编译过程中产生的文件
phony伪目标 防止有同名文件clean make就不会吧clean当作文件来处理了
all 编译多个可执行文件
编写cmake
ping
ping 127.0.0.1 是检测自己主机的网络配置是否正常,也就是检查本机的 tcp/ip 是否正确安装,这一步不需要联网
拔了网线,ping 127.0.0.1
是能ping通的。
其中127 开头的都属于回环地址
性能指标
一文搞懂高并发性能指标:QPS、TPS、RT、并发数、吞吐量 - 知乎 (zhihu.com)
每秒请求数(RPS:Request Per Second)。
C++ Lambda
可以很方便的让我们随手定义一个函数 并可以把函数当作参数给别的函数调用,使代码很简洁 读起来也很直观,不用在代码中跳来跳去
捕获列表:
按值捕获 可以修改外部变量的值 按引用捕获 不可以修改外部变量的值