知识点复习2

结构体和类的区别

结构体默认继承是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字

. - 力扣(LeetCode)

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;
}

类的拷贝赋值函数

【C++】类的拷贝赋值函数_c++ 拷贝赋值-CSDN博客

赋值函数则是把一个新的对象赋值给一个原有的对象,所以如果原来的对象中有内存分配要先把内存释放掉,而且还要检察一下两个对象是不是同一个对象,如果是,不做任何操作,直接返回。

值传递和引用传递的区别

 

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

可以很方便的让我们随手定义一个函数 并可以把函数当作参数给别的函数调用,使代码很简洁 读起来也很直观,不用在代码中跳来跳去

捕获列表:

按值捕获 可以修改外部变量的值 按引用捕获 不可以修改外部变量的值

深入浅出 C++ Lambda表达式:语法、特点和应用-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值