C++复习day05

类和对象

1. 面向对象和面向过程的区别是什么?(开放性问题)
1. **抽象级别**:- **面向对象**:以对象(数据和方法的集合)为中心,强调的是数据和行为的封装。- **面向过程**:以过程(函数或子程序)为中心,强调的是步骤和顺序。2. **数据和方法的关系**:- **面向对象**:数据和处理数据的方法封装在对象中,对象可以包含数据和操作数据的方法。- **面向过程**:数据和处理数据的方法是分离的,通常数据结构和处理这些数据的函数是分开的。3. **模块化**:- **面向对象**:通过类和对象来实现模块化,类定义了对象的蓝图。- **面向过程**:通过函数和过程来实现模块化,函数是独立的代码块。4. **代码重用**:- **面向对象**:通过继承和多态性,可以更容易地重用代码。- **面向过程**:代码重用通常通过函数库来实现,但可能不如面向对象那样灵活。5. **维护和扩展**:- **面向对象**:由于封装和模块化,通常更容易维护和扩展。- **面向过程**:随着系统的增长,维护和扩展可能会变得更加困难。6. **设计复杂性**:- **面向对象**:设计可能更复杂,因为需要考虑类之间的关系和继承结构。- **面向过程**:设计可能更直接,因为关注点在于函数的调用和执行。7. **语言支持**:- **面向对象**:许多现代编程语言(如Java、C++、Python、Ruby)天然支持面向对象编程。- **面向过程**:几乎所有编程语言都支持过程化编程,但一些语言(如C)在支持面向对象特性方面可能不如其他语言。8. **性能**:- **面向对象**:可能会有额外的开销,因为需要处理对象的创建和方法调用。- **面向过程**:通常在性能上更高效,因为直接调用函数通常比创建对象和调用方法更快。
2.类大小的计算

这里同样是和结构体的内存对齐做法相同,需要注意的是空类的大小是1(主要是为了在地址空间中占位,表示存在这个类)

3.class和struct的区别
  1. struct 一般用于描述一个数据结构集合,而 class 是对一个对象数据的封装;
  2. struct 中默认的访问控制权限是 public 的,而 class 中默认的访问控制权限是 private 的,例如:
struct A{
int iNum; // 默认访问控制权限是 public
}
class B{
int iNum; // 默认访问控制权限是 private
}
  1. 在继承关系中,struct 默认是公有继承,而 class 是私有继承;
  2. class 关键字可以用于定义模板参数,就像 typename,而 struct 不能用于定义模板参数,例如:
template<typename T, typename Y> // 可以把typename 换成 class
int Func(const T& t, const Y& y) {
//TODO
}
3.this指针
1)this指针存放在哪里?

this指针是在栈上的,因为他是一个形参,当然有时候在会存在于寄存器上。因为有时候需要频繁的使用this指针,所以放到了寄存器,便于更加快速的使用this指针

2)this指针可以为空嘛?

this指针通常不能为nullptr,因为他是当前对象的地址,然而有一些特殊的情况

1. 静态成员函数:在静态成员函数中,this指针是不可用的,因为静态成员函数不依赖于任何特定的实例。
2 .如果是去调用成员函数,由于成员函数并不在对象中,this不会进行解引用,所以即使this是空指针,也不会崩溃。
3. 如果this指针是空,还访问了成员变量,那么成员就会崩溃,原因是对空指针进行了解引用。

4.八个默认成员函数

首先先整体清点一下是哪八个成员函数
构造函数,析构函数,拷贝构造函数,赋值运算符重载,取地址操作符重载,const成员函数,移动构造,移动赋值

1)构造函数
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。虽然名称叫构造,但是构造函数的主要任
务并不是开空间创建对象,而是初始化对象

特性:

1. 函数名与类名相同。
2. 无返回值。
3. 对象实例化时编译器自动调用对应的构造函数。
4. 构造函数可以重载。

问: 关于编译器生成的默认成员函数,很多童鞋会有疑惑:不实现构造函数的情况下,编译器会生成默认的构造函数。但是看起来默认构造函数又没什么用?d对象调用了编译器生成的默认构造函数,但是d对象_year/_month/_day,依旧是随机值。也就说在这里编译器生成的
默认构造函数并没有什么用??
答: C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如int/char…,自定义类型就是我们使用class/struct/union等自己定义的类型,看看下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员函数。

class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本类型(内置类型)int _year;int _month;int _day;// 自定义类型Time _t;
};
int main()
{Date d;return 0;
}

注意:C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。

class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;
};
int main()
{Date d;return 0;
}
2) 析构函数
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由
编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

析构函数是特殊的成员函数,其特征如下:

  1. 析构函数名是在类名前加上字符 ~。
  2. 无参数无返回值类型。
  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
    函数不能重载
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数
  5. 关于编译器自动生成的析构函数,是否会完成一些事情呢?下面的程序我们会看到,编译器生成的默认析构函数,对自定类型成员调用它的析构函数。
  6. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。
3) 拷贝构造

拷贝构造函数也是特殊的成员函数,其特征如下

  1. 拷贝构造函数是构造函数的一个重载形式
  2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用
  3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
  4. . 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?当然像日期类这样的类是没必要的。那么下面的类呢?验证一下试试?
// 这里会发现下面的程序会崩溃掉?这里就需要我们以后讲的深拷贝去解决。
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");return;}size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:DataType* _array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0;
}

这种情况是会崩溃的,因为同一块空间被释放了两次

4)运算符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其
返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)

注意:

  • 不能通过连接其他符号来创建新的操作符:比如operator@
  • 重载操作符必须有一个类类型参数
  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  • .* :: sizeof ?: .这五类运算符是不能够被重载的,这个在笔试题中会经常性的出现
    比如我们重载一下Date类的==和<<,代码大概就像这样:
#include <iostream>using namespace std;class Date
{friend ostream& operator << (ostream& out, const Date& d);friend bool operator==(const Date& d1, const Date& d2);
public:Date(int year, int month, int day) :_year(year),_month(month),_day(day){ }~Date(){cout << "~Date()" << endl;}private:int _year;int _month;int _day;
};
bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;
}
ostream& operator << (ostream & out, const Date& d)
{out << d._year << d._month << d._day;return out;
}
int main()
{Date d1(1, 1, 1),d2(2,2,2);cout << (d1 == d2) << endl;;cout << d1 << endl;return 0;
}

赋值运算符重载格式:

  • 参数类型:const T&,传递引用可以提高传参效率
  • 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
  • 检测是否自己给自己赋值
  • 返回*this :要复合连续赋值的含义
#include <iostream>using namespace std;class Date
{friend ostream& operator << (ostream& out, const Date& d);friend bool operator==(const Date& d1, const Date& d2);
public:Date(int year, int month, int day) :_year(year),_month(month),_day(day){ }Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}~Date(){cout << "~Date()" << endl;}const Date& operator=(const Date& d){_year = d._year;_month = d._month;_day = d._day;return *this;}
private:int _year;int _month;int _day;
};
bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;
}
ostream& operator << (ostream & out, const Date& d)
{out << d._year << d._month << d._day;return out;
}
int main()
{Date d1(1, 1, 1),d2(2,2,2);cout << (d1 == d2) << endl;d1 = d2 = Date(3,3,3);cout << (d1 == d2) << endl;return 0;
}

注意:

赋值运算符只能重载成类的成员函数不能重载成全局函数
用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符
重载完成赋值。

这里提一嘴关于前置++和后置++的实现(–也是同理的)

#include <iostream>using namespace std;class Date
{friend ostream& operator << (ostream& out, const Date& d);friend bool operator==(const Date& d1, const Date& d2);
public:Date(int year, int month, int day) :_year(year),_month(month),_day(day){ }Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}Date& operator++()// 前置++{_day += 1; //这里为例简便,我就不考虑什么月份,天数什么的了}Date operator++(int) //后置++{Date temp(*this);_day += 1;return temp;}~Date(){cout << "~Date()" << endl;}const Date& operator=(const Date& d){_year = d._year;_month = d._month;_day = d._day;return *this;}
private:int _year;int _month;int _day;
};
bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;
}
ostream& operator << (ostream & out, const Date& d)
{out << d._year << d._month << d._day;return out;
}
int main()
{Date d1(1, 1, 1),d2(2,2,2);cout << (d1 == d2) << endl;d1 = d2 = Date(3,3,3);cout << (d1 == d2) << endl;return 0;
}
5)const成员
将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

请思考下面的几个问题:

  1. const对象可以调用非const成员函数吗?
  2. 非const对象可以调用const成员函数吗?
  3. const成员函数内可以调用其它的非const成员函数吗?
  4. 非const成员函数内可以调用其它的const成员函数吗?
const对象不可以调用非const成员函数,非const对象可以调用const成员函数。
const成员函数不可以调用其他的非const成员函数,非const成员函数可以调用const成员函数
6)取地址操作符重载

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需
要重载,比如想让别人获取到指定的内容!

7/8) 移动构造和移动赋值

(这两个成员函数放到一起进行讨论)
首先来介绍一下什么叫做左值引用,什么叫做右值引用,以及他们的区别是什么

传统的C++语法中就有引用的语法,而C++11中新增了的右值引用语法特性,所以从现在开始我们之前学习的引用就叫做左值引用。无论左值引用还是右值引用,都是给对象取别名。
什么是左值?什么是左值引用?
左值是一个表示数据的表达式(如变量名或解引用的指针),我们可以获取它的地址+可以对它赋值,左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引用就是给左值的引用,给左值取别名。
#include <iostream>
using namespace std;int main()
{int*p = new int(0);int b = 1;const int c = 2;int*&rp = p;int&pb = b;const int&pc = c;int&pvalue = *p;return 0;
}
什么是右值?什么是右值引用?
右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。右值引用就是对右值的引用,给右值取别名。
int main()
{
double x = 1.1, y = 2.2;
// 以下几个都是常见的右值
10;
x + y;
fmin(x, y);
// 以下几个都是对右值的右值引用
int&& rr1 = 10;
double&& rr2 = x + y;
double&& rr3 = fmin(x, y);
// 这里编译会报错:error C2106: “=”: 左操作数必须为左值
10 = 1;
x + y = 1;
fmin(x, y) = 1;
return 0;
}
需要注意的是右值是不能取地址的,但是给右值取别名后,会导致右值被存储到特定位置,且可以取到该位置的地址,也就是说例如:不能取字面量10的地址,但是rr1引用后,可以对rr1取地址,也可以修改rr1。如果不想rr1被修改,可以用const int&& rr1 去引用,是不是感觉很神奇,这个了解一下实际中右值引用的使用场景并不在于此,这个特性也不重要。
int main()
{double x = 1.1, y = 2.2;int&& rr1 = 10;const double&& rr2 = x + y;rr1 = 20;rr2 = 5.5;  // 报错return 0;
}

左值引用与右值引用比较
左值引用总结:

  1. 左值引用只能引用左值,不能引用右值。
  2. 但是const左值引用既可引用左值,也可引用右值。(临时常量具有常性)
#include <iostream>
using namespace std;int main()
{//int&a = 10;//这种是错误的const int&a = 10;//这种是正确的return 0;
}

右值引用总结:

  1. 右值引用只能右值,不能引用左值。
  2. 但是右值引用可以move以后的左值。

来看看右值引用使用场景和意义
前面我们可以看到左值引用既可以引用左值和又可以引用右值,那为什么C++11还要提出右值引
用呢?是不是化蛇添足呢?下面我们来看看左值引用的短板,右值引用是如何补齐这个短板的!

namespace bit
{class string{public:typedef char *iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}string(const char *str = ""): _size(strlen(str)), _capacity(_size){// cout << "string(char* str)" << endl;_str = new char[_capacity + 1];strcpy(_str, str);}// s1.swap(s2)void swap(string &s){::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);}// 拷贝构造string(const string &s): _str(nullptr){cout << "string(const string& s) -- 深拷贝" << endl;string tmp(s._str);swap(tmp);}// 赋值重载string &operator=(const string &s){cout << "string& operator=(string s) -- 深拷贝" << endl;string tmp(s);swap(tmp);return *this;}// 移动构造string(string &&s): _str(nullptr), _size(0), _capacity(0){cout << "string(string&& s) -- 移动语义" << endl;swap(s);}// 移动赋值string &operator=(string &&s){cout << "string& operator=(string&& s) -- 移动语义" << endl;swap(s);return *this;}~string(){delete[] _str;_str = nullptr;}char &operator[](size_t pos){assert(pos < _size);return _str[pos];}void reserve(size_t n){if (n > _capacity){char *tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void push_back(char ch){if (_size >= _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;++_size;_str[_size] = '\0';}// string operator+=(char ch)string &operator+=(char ch){push_back(ch);return *this;}const char *c_str() const{return _str;}private:char *_str;size_t _size;size_t _capacity; // 不包含最后做标识的\0};
}

不妨先看看左值引用的应用场景:

void func1(bit::string s)
{}
void func2(const bit::string& s)
{}
int main()
{bit::string s1("hello world");// func1和func2的调用我们可以看到左值引用做参数减少了拷贝,提高效率的使用场景和价值func1(s1);func2(s1);// string operator+=(char ch) 传值返回存在深拷贝// string& operator+=(char ch) 传左值引用没有拷贝提高了效率s1 += '!';return 0;
}

问:左值引用的短板是什么?

但是当函数返回对象是一个局部变量,出了函数作用域就不存在了,就不能使用左值引用返回,只能传值返回。例如:bit::string to_string(int value)函数中可以看到,这里只能使用传值返回,传值返回会导致至少1次拷贝构造(如果是一些旧一点的编译器可能是两次拷贝构造)。

也就是说,只要是局部的对象需要返回,左值引用就是失去了作用,因为出作用域之后局部对象就会被销毁,当时候指向的就是一片位置的区域。
那么如果解决这个问题呢?

右值引用和移动语义解决上述问题:
在bit::string中增加移动构造,移动构造本质是将参数右值的资源窃取过来,占位已有,那么就不
用做深拷贝了,所以它叫做移动构造,就是窃取别人的资源来构造自己(偷梁换柱)。

来看看怎么实现

// 移动构造
string(string&& s):_str(nullptr),_size(0),_capacity(0)
{cout << "string(string&& s) -- 移动语义" << endl;swap(s);
}
不仅仅有移动构造,还有移动赋值:
在bit::string类中增加移动赋值函数,再去调用bit::to_string(1234),不过这次是将
bit::to_string(1234)返回的右值对象赋值给ret1对象,这时调用的是移动构造。
// 移动赋值
string& operator=(string&& s)
{
cout << "string& operator=(string&& s) -- 移动语义" << endl;
swap(s);
return *this;
}
int main()
{bit::string ret1;ret1 = bit::to_string(1234);return 0;
}
// 运行结果:
// string(string&& s) -- 移动语义
// string& operator=(string&& s) -- 移动语义

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/878909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爆改YOLOv8|利用图像分割网络UNetV2改进yolov8主干-即插即用

1&#xff0c;本文介绍 U-Net v2 通过引入创新的跳跃连接设计来提升医学图像分割的精度。这一版本专注于更有效地融合不同层级的特征&#xff0c;包括高级特征中的语义信息和低级特征中的细节信息。通过这种优化&#xff0c;U-Net v2 能够在低级特征中注入丰富的语义&#xff…

AI 与大模型:物流行业的变革力量

一、物流行业的现状与挑战 物流行业在现代经济中扮演着至关重要的角色&#xff0c;但目前也面临着诸多挑战。 在效率方面&#xff0c;交通拥堵是一个突出问题。许多城市道路容量不足&#xff0c;无法满足日益增长的货物运输需求&#xff0c;导致运输时间延长。例如&#xff0…

使用3DUNet训练自己的数据集(pytorch)— 医疗影像分割

代码:lee-zq/3DUNet-Pytorch: 3DUNet implemented with pytorch (github.com) 文章<cicek16miccai.pdf (uni-freiburg.de)3D U-Net: Learning Dense Volumetric Segmentation

高清4K短视频素材网站有哪些?推荐8个高清4K短视频素材网站

是不是还在为找不到合适的4K高清素材而苦恼&#xff1f;别急&#xff01;今天我为大家精心挑选了8个超级优秀的4K高清短视频素材网站&#xff0c;不仅能让你的视频质量爆表&#xff0c;还能大大提高账号的互动率和曝光度&#xff01;每一个推荐都是精心筛选过的&#xff0c;每一…

[物理专题]经典浮力题目的Fh图像绘制

这段代码用于绘制物体在液体中受到的浮力变化的图像&#xff0c;它有多个好处&#xff1a; 直观展示数据&#xff1a;通过图形化展示&#xff0c;可以直观地看到物体在液体中浸入深度与受到的浮力之间的关系。 教育和学习工具&#xff1a;这种类型的图像常用于教育目的&#x…

基于canal的Redis缓存双写

canal地址&#xff1a;alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 (github.com)https://github.com/alibaba/canal 1. 准备 1.1 MySQL 查看主机二进制日志 show master status 查看binlog是否开启 show variables like log_bin 授权canal连接MySQL账号 …

【OpenCV3】图像的翻转、图像的旋转、仿射变换之图像平移、仿射变换之获取变换矩阵、透视变换

1 图像的放大与缩小 2 图像的翻转 3 图像的旋转 4 仿射变换之图像平移 5 仿射变换之获取变换矩阵 6 透视变换 1 图像的放大与缩小 resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) src: 要缩放的图片dsize: 缩放之后的图片大小, 元组和列表表示均可.dst: 可选参数, 缩…

【无标题】XSS安全防护:responseBody (输入流可重复读) 配置

接上文:配置XSS过滤器 XXS 安全防护:拦截器+注解实现校验-CSDN博客XSS(跨站脚本)攻击是一种网络安全威胁,允许攻击者注入恶意脚本到看似安全的网站。当用户浏览这些被注入恶意代码的网页时,恶意脚本会在用户的浏览器环境中执行,这可能导致多种安全问题,如窃取敏感数据、…

将添加功能的抽屉剥离,在父组件调用思路

一、新建组件 新建AddRoleEditerDrawer.vue<template><div><el-drawer v-model"dialog" title"添加角色" :before-close"handleClose" direction"rtl" colse"cancelForm"class"demo-drawer" moda…

「数学::质数」试除法 / Luogu P5736(C++)

概述 在质数的第一节我们来讲解试除法。 质数是指在大于1的自然数中只能被1和它自己整除的数。 我们可以利用这一除法性质对质数进行判定。 Luogu P5736&#xff1a; 输入 n 个不大于 10^5 的正整数。要求全部储存在数组中&#xff0c;去除掉不是质数的数字&#xff0c;依…

LLM Attention and Rotary Position Embedding(旋转位置编码)

旋转位置编码&#xff08;Rotary Position Embedding&#xff0c;RoPE&#xff09;是一种能够将相对位置信息依赖集成Attention计算里的方法。就是在做词表映射的时候不是单一的进行一个embedding计算&#xff0c;还考虑位置信息。 一些资料 [1] https://arxiv.org/pdf/2104.0…

面对养老困局我心安若素

“2025年&#xff0c;我们需要注意什么&#xff1f;是复杂的国际环境么&#xff1f;明年对于我国70岁以上的老年人来说这可不是主要关心的问题。反而有这两件事情需要他们来关注&#xff0c;如果70岁老人不提前做好准备&#xff0c;可能会有非常严重的后果......”这是昨天发表…

鸿蒙轻内核M核源码分析系列十五 CPU使用率CPUP

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 轻内核M核源码分析系列一 数据结构-双向循环链表 轻内核M核源码分析系列二 数据结构-任务就绪队列 鸿蒙轻内核M核源码分析系列三 数据结构-任务排序链表 轻…

国产脑机全面超越马斯克Nearlink

&#x1f4a5;&#x1f4a5;&#x1f4a5;刚刚&#xff0c;世界首富马斯克同学已经是完全懵逼了&#xff0c;心态都崩了&#xff01;因为今天爆出来了一个轰动了全世界科技界的大新闻&#xff0c;国产脑机在多个维度上全面超越了马斯克的Nearlink&#xff01; &#x1f4a5;&am…

SpringBoot2:请求处理原理分析-RESTFUL风格接口

一、RESTFUL简介 Rest风格支持&#xff08;使用HTTP请求方式&#xff0c;动词来表示对资源的操作&#xff09; 以前&#xff1a;/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户 现在&#xff1a; /user GET-获取用户 DELETE-删除用户 PUT-修改…

数据仓库技术选型方案文档

关联博客&#xff1a; 数据仓库技术选型方案文档 Flink CDC MySQL数据同步到Doris表同步配置生成工具类 新版报表系统&#xff08;明细报表、看板、数据大屏&#xff09;方案&介绍 文章目录 数据仓库技术选型背景现状现状架构目标架构业务反馈&痛点问题&#xff1a;原因…

随手记:小程序体积超出2M包大小如何优化

小程序的包体积限制是2M&#xff0c;超出包大小如何优化 先简单列出&#xff0c;最近比较忙&#xff0c;后续优化明细&#xff0c;有着急的先留言踢我 1.分包 留几个主要的页面体积小的&#xff0c;剩下的在page.json中拆到subpackages中&#xff0c;简单举个例子 "page…

多维动态规划-面试高频!-最长公共子序列和最长公共子串、回文串-c++实现和详解

1143. 最长公共子序列 中等 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删…

力扣1049-最后一块石头的重量II(Java详细题解)

题目链接&#xff1a;1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 最近刚学完01背包&#xff0c;所以现在的题解都是以01背包问题为基础再来写的。 如果大家不懂…

FPGA实现串口升级及MultiBoot(二)FPGA启动流程

这个系列开篇肯定要先了解FPGA的启动流程&#xff0c;试想一下&#xff1a;我想实现MultiBoot&#xff0c;那么我应该在什么时候开始升级&#xff0c;升级失败后FPGA进行了哪些操作&#xff0c;以及怎么回到Golden区&#xff1f; 还有一个问题&#xff0c;就是我硬件打板回来&a…