【C++】——类和对象
目录
- 面向过程和面向对象的初步认识
- 类的引入
- 类的定义
- 类的访问限定符及封装
- 类的作用域
- 类的实例化
- this指针
- 类的6个默认成员函数
- 构造函数
- 析构函数
面向过程和面向对象的初步认识
C语言是面向过程的,关注的是过程,分析求解问题的步骤,通过函数调用逐步解决问题
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成
C++不是纯面向对象的
类的引入
C语言中,结构体内只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。(C++兼容C语言,结构体的用法可以继续使用,同时struct也升级成了类)
struct Stack
{//成员函数void Init(){a = nullptr;top = capacity = 0;}//成员变量int* a;int top;int capacity;
};
void StackInit(struct Stack* ps)
{//....
}
int main()
{struct Stack st1;StackInit(&st1);Stack st2;st2.Init();return 0;
}
类的定义
class className
{//类体:由成员函数和成员变量组成};//注意分号
struct和class最主要的区别就是访问限定符
1、类可以做声明和定义分离:
Test.cpp:
Func.cpp:
Func.h:
2、类的两种定义方式:
1、声明和定义全部放在类体中,需要注意:成员函数如果在类中定义,编译器可以能会将其当成内联函数处理。函数不进入符号表。
2、类的声明放在.h文件当中,成员函数定义放在.cpp文件当中,注意:成员函数之前需要加类名。
类的访问限定符及封装
1、访问限定符:public protected private
C++实现封装的方式:用类将对象的属性和方法结合在一起,让对象更加完善,荣光访问权限选择性的将其接口提供给外部的用户使用。
1、public 修饰的成员在类外可以直接被访问
2、protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
3、访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现为止
4、如果后面没有访问限定符,作用域到 } 结束
5、class的默认访问权限是private,struct为public(因为struct要兼容C)
#include <iostream>
using namespace std;
class Stack
{
public ://成员函数void Init(){a = nullptr;top = capacity = 0;}void push(int x){if (top == capacity){int newcapacity = capacity == 0 ? 4 : 2 * capacity;a = (int*)realloc(a, sizeof(int) * newcapacity);capacity = newcapacity;}a[top++] = x;}int Top(){return a[top - 1];}
private://成员变量int* a;int top;int capacity;
};
int main()
{Stack st;st.Init();st.push(1);st.push(2);st.push(3);cout << st.Top() << endl;return 0;
}
2、C++中struct和class的区别是什么?
C++需要兼容C语言,所以C++中struct可以当成结构体使用,另外C++中struct还可以用来定义类。和class定义类是一样的。区别是:struct定义类的默认访问权限是public,class定义的类默认访问权限是private。
类的作用域
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域
类的实例化
1、 用类类型创建对象的过程,称为类的实例化
2、类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个类,来描述具体学生信息。
3、 一个类可以实例化出多个对象,类实例化出的对象占用实际的物理空间,类不占用实际的物理空间,存储类成员量。
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month; //是类的声明不是类的定义int _day;
};
int main()
{Date d;//实例化,开实际的物理空间d.Init(2023, 7, 21);return 0;
}
类在内存当中不占内存的空间,占文件系统的空间
类不能存储数据,类实例化的对象存储数据
对象存储方式:
计算类的大小:
类中既有成员变量,又有成员函数
class A1 {
public:void f1() {} //4
private:int _a;
};
类中仅有成员函数
class A2 {
public:void f2() {} //1
};
类中什么都没有—空类
class A3 //1
{};
分配1字节,不存储数据,只是占位,表示对象存在过
结构体内存对齐规则:
- 第一个成员在与结构体偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8- 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
this指针
class Date
{
public:void Init(int year, int month, int day){cout << this << endl;_year = year;_month = month;_day = day;}void Print(){cout << this << endl;cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year; int _month;int _day;
};
int main()
{Date d1, d2;d1.Init(2022, 1, 11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}
此段代码中还隐含了this指针,在编译器中,编译器会默认给代码加上隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
上述程序代码中,两个成员函数的指针并不是同一个,更准确的来说,是看this指针指向哪个对象,如何指向的是d1对象,那么调用两个成员函数的地址就是相同的。如果同时调用两个对象所指向的成员函数,那么this指针的地址就是不同的。
this指针指向当前调用的对象,是临时变量,函数调用结束后就销毁了
练习题1:
class A
{
public:
void Print()
{
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}
运行成功,打印Print( ),该函数存放在公共代码区,不存到成员变量中,所以p指针不解引用,运行成功
练习题2:
class A
{
public:void PrintA(){cout<<_a<<endl;}
private:
int _a;
};
int main()
{A* p = nullptr;p->PrintA();return 0;
}
运行崩溃,此处有空指针的解引用,因为函数存放在公共代码区,p指针不解引用是空,同时this指针也是空,导致程序运行崩溃
this指针存放在哪?
this指针是一个形参,一般存在栈栈帧中。VS下面一般会用ecx寄存器直接传递
this指针的特性
- this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。
- 只能在“成员函数”的内部使用
- this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
- this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递
类的6个默认成员函数
如果一个类当中什么都没有,那么这个类就是空类,但是空类在什么都不写的情况下会自动生成以下6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
默认构造函数的特点:不传参就可以调用的构造就是默认构造
class classmate
{};
构造函数
特性:构造函数是特殊的成员函数,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。
特性:
1、函数名与类名相同
2、无返回值 (也不需要写void)
3、对象实例化时编译器自动调用对应的构造函数
4、构造函数可以重载 (可以写多个构造函数,提供多种初始化方式)
class Date
{
public:Date()//无参构造函数{_year = 1;_month = 1;_day = 1;}Date(int year, int month, int day)//有参构造函数{_year = year;_month = month;_day = day;}void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
上述构造函数也可以合并写成参数全缺省形式
class Date
{
public://Date()//无参构造函数//{// _year = 1;// _month = 1;// _day = 1;//}//Date(int year, int month, int day)//有参构造函数//{// _year = year;// _month = month;// _day = day;//}Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;d1.Print();Date d2(2023,7,28);d2.Print();Date d3(2023, 7);d3.Print();/*d1.Init(2022, 7, 5);d1.Print();Date d2;d2.Init(2022, 7, 6);d2.Print();*/return 0;
}
C++实现栈:
#include <assert.h>class Stack
{
public:/*Stack(){a = nullptr;top = capacity = 0;}*/Stack(size_t n = 4){if (n == 0){a = nullptr;top = capacity = 0;}else{a = (int*)malloc(sizeof(int) * n);if(a == nullptr){perror("realloc fail");exit(-1);}top = 0;capacity = n;}}// 成员函数//void Init()//{// a = nullptr;// top = capacity = 0;//}void Push(int x){if (top == capacity){size_t newcapacity = capacity == 0 ? 4 : capacity * 2;int* tmp = (int*)realloc(a, sizeof(int) * newcapacity);if (tmp == nullptr){perror("realloc fail");exit(-1);//程序以异常的方式退出}if (tmp == a){cout << capacity << "原地扩容" << endl;}else{cout << capacity << "异地扩容" << endl;}a = tmp;capacity = newcapacity;}a[top++] = x;}int Top(){return a[top - 1];}void Pop(){assert(top > 0);--top;}void Destroy(){free(a);a = nullptr;top = capacity = 0;}bool Empty(){return top == 0;}
private:// 成员变量int* a;int top;int capacity;
};int main()
{Stack st1;st1.Push(1);st1.Push(2);st1.Push(3);st1.Push(4);while (!st1.Empty()){cout << st1.Top() << " ";st1.Pop();}cout << endl;st1.Destroy();//Stack st2(1000);Stack st2;for (size_t i = 0; i < 1000; i++){st2.Push(i);}while (!st2.Empty()){cout << st2.Top() << " ";st2.Pop();}cout << endl;st2.Destroy();
}
推荐在一个类当中使用全缺省构造函数
构造函数,也是默认成员函数,我们不写,编译器会自动生成
编译生成的构造函数的特点:
1、我们不写才会自动生成,我们写了就不会自动生成了
2、内置类型(基本类型 int double)成员不会处理,(C++11,声明支持给缺省值)
3、对于自定义类型的成员才会处理,会去调用这个成员的默认构造函数
如果类中没有显示定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显示定义编译器将不再生成。
无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个(多个并存会存在调用的二义性)。
注意:无参构造函数,全缺省构造函数,我们没有写编译器默认生成的构造函数,都可以认为时默认构造函数(不传参就可以调用的)。
一般情况下都需要我们自己写构造函数,决定初始化方式
class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};
int main()
{//MyQueue mq;Time t;return 0;
}
举例:
class A
{
public:A(int a){cout << "A(int a)" << endl;}
private:int _a;
};
class Date
{
public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;A _aa;};
int main()
{Date d1;//Date d2(2023, 7, 29);return 0;
}
运行报错:
错误原因:类A中不存在默认构造函数,默认构造函数:无参的构造函数和全缺省的构造函数。
代码更正:将类A中的构造函数写成参数全缺省形式
class A
{
public:A(int a=1){cout << "A(int a)" << endl;}
private:int _a;
};
class Date
{
public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;A _aa;};
int main()
{Date d1;//Date d2(2023, 7, 29);return 0;
}
析构函数
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
特性:
1、析构函数名是在类名前加上字符“~”
2、无参数无返回值类型
3、一个类只能有一个析构函数,若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
4、对象生命周期结束时,C++编译系统自动调用析构函数
默认的析构函数:
对内置类型成员不做处理
自定义类型的成员会去调用他的析构函数
class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}~Time(){cout << "~Time()" << endl;}
private:int _hour;int _minute;int _second;
};
int main()
{Time t;return 0;
}
栈需要显式的写析构函数
class Stack
{
public://构造函数Stack(size_t n = 4)//unsigned int{if (n == 0){a = nullptr;top = capacity = 0;}else{a = (int*)malloc(sizeof(int) * n);if (a == nullptr){perror("malloc fail");exit(-1);//异常}top = 0;capacity = n;}}int Top(){return a[top - 1];}void Pop(){assert(top > 0);top--;}void Push(int x){if (top == capacity){size_t newcapacity = capacity == 0 ? 4 : capacity * 2;int* tmp = (int*)realloc(a, sizeof(int) * newcapacity);if (tmp == nullptr){perror("realloc fail");exit(-1);}if (tmp == a){cout << capacity << "原地" << endl;}else{cout << capacity << "异地" << endl;}a = tmp;capacity = newcapacity;}a[top++] = x;}~Stack(){cout << "~Stack()" << endl;free(a);a = nullptr;top = 0;capacity = 0;}bool Empty(){return top == 0;}
private:int* a;int top;int capacity;
};
int main()
{Stack st1(1000);st1.Push(1);st1.Push(2);while (!st1.Empty()){cout << st1.Top() << endl;st1.Pop();}return 0;
}
默认析构函数:
1、内置类型成员不会处理
2、自定义类型成员会调用这个成员的析构函数
C++实现括号匹配
#include <iostream>
#include <assert.h>
using namespace std;class Stack
{
public:Stack(size_t n = 4)//构造函数{cout << "Stack(size_t n = 4)" << endl;if (n == 0){a = nullptr;top = capacity = 0;}else{a = (int*)malloc(sizeof(int) * n);if (a == nullptr){perror("realloc fail");exit(-1);}top = 0;capacity = n;}}~Stack()//析构函数{cout << "~Stack()" << endl;free(a);a = nullptr;top = capacity = 0;}void Push(int x){if (top == capacity){size_t newcapacity = capacity == 0 ? 4 : capacity * 2;int* tmp = (int*)realloc(a, sizeof(int) * newcapacity);if (tmp == nullptr){perror("realloc fail");exit(-1);}if (tmp == a){cout << capacity << "原地扩容" << endl;}else{cout << capacity << "异地扩容" << endl;}a = tmp;capacity = newcapacity;}a[top++] = x;}int Top(){return a[top - 1];}void Pop(){assert(top > 0);--top;}void Destroy(){free(a);a = nullptr;top = capacity = 0;}bool Empty(){return top == 0;}
private:// 成员变量int* a;int top;int capacity;
};
bool isValid(const char* s) {Stack st;while (*s){if (*s == '[' || *s == '(' || *s == '{'){st.Push(*s);++s;}else{// 不匹配if (st.Empty())return false;char top = st.Top();st.Pop();// 不匹配if ((*s == ']' && top != '[')|| (*s == ')' && top != '(')|| (*s == '}' && top == '{')){return false;}++s;}}return st.Empty();
}int main()
{// 后定义,先析构Stack st1;Stack st2;cout << isValid("[[]]()()") << endl;cout << isValid("[[]]]") << endl;return 0;
}
相关文章:

【C++】——类和对象
目录 面向过程和面向对象的初步认识类的引入类的定义类的访问限定符及封装类的作用域类的实例化this指针类的6个默认成员函数构造函数析构函数 面向过程和面向对象的初步认识 C语言是面向过程的,关注的是过程,分析求解问题的步骤,通过函数调用…...

【Docker】使用docker-maven-plugin插件构建发布推镜像到私有仓库
文章目录 1. 用docker-maven-plugin插件推送项目到私服docker1.1. 构建镜像 v1.01.2. 构建镜像 v2.01.3. 推送到镜像仓库 2. 拉取私服docker镜像运行3. 参考资料 本文描述了在Spring Boot项目中通过docker-maven-plugin插件把项目推送到私有docker仓库中,随后拉取仓…...

区块链学习笔记
区块链技术与应用 数组 列表 二叉树 哈希函数 BTC中的密码学原理 cryptographic hash function collsion resistance(碰撞抵抗) 碰撞指的是找到两个不同的输入值,使得它们的哈希值相同。也就是说,如果存在任意两个输入x和y,满足x ≠ y…...

实用上位机--QT
实用上位机–QT 通信协议如下 上位机设计界面 #------------------------------------------------- # # Project created by QtCreator 2023-07-29T21:22:32 # #-------------------------------------------------QT += core gui serialportgreaterThan(QT_MAJOR_V…...
os.signal golang中的信号处理
在程序进行重启等操作时,我们需要让程序完成一些重要的任务之后,优雅地退出,Golang为我们提供了signal包,实现信号处理机制,允许Go 程序与传入的信号进行交互。 Go语言标准库中signal包的核心功能主要包含以下几个方面…...

Python源码:Tkinter组件布局管理的3种方式
Tkinter组件布局管理可以使用pack()方法、grid()方法和place()方法。pack()方法将组件放置在窗口中,grid()方法将组件放置在网格布局中,place()方法将组件放置在指定位置。 01使用pack()方法布局: 在Tkinter中,pack方法用于将控…...

网络防御之VPN
配置IKE 第一阶段 [r1]ike proposal 1 [r1-ike-proposal-1]encryption-algorithm aes-cbc-128 [r1-ike-proposal-1]authentication-algorithm sha1 [r1-ike-proposal-1]dh group2 [r1-ike-proposal-1]authentication-method pre-share[r1]ike peer aaa v1 [r1-ike-peer-aaa…...

VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题
参考:https://www.codetd.com/article/15219743 安装 // 安装 docxtemplater npm install docxtemplater pizzip --save // 安装 jszip-utils npm install jszip-utils --save // 安装 jszip npm install jszip --save // 安装 FileSaver npm install file-save…...
ubuntu 安装 Pycharm社区版
在Ubuntu中安装pycharm社区版_上玄下纁的博客-CSDN博客 里面可以创建快捷方式,蛮好用的...

IP 监控软件
IP 监控软件可帮助管理员主动监控网络资源。随着各种设备连接到网络,监控设备和接口可能很复杂,为管理员提供这些设备的IP监控,了解其各种性能指标和问题。 使用有效的 IP 监控软件的优势 使用有效的 IP 监控系统和一套全面的 IP 监控工具&…...

C#实现读写CSV文件的方法详解
目录 CSV文件标准 文件示例RFC 4180简化标准读写CSV文件 使用CsvHelper使用自定义方法总结 项目中经常遇到CSV文件的读写需求,其中的难点主要是CSV文件的解析。本文会介绍CsvHelper、TextFieldParser、正则表达式三种解析CSV文件的方法,顺带也会介绍一…...

04 http连接处理(上)
基础知识:epoll、http报文格式、状态码和有限状态机 代码:对服务端处理http请求的全部流程进行简要介绍,然后结合代码对http类及请求接收进行详细分析。 epoll epoll_create函数 #include <sys/epoll.h> int epoll_create(int size)…...

c++(强生成关键字+可变参数模板+emplace)[26]
强制生成 不生成 在C中,可以通过一些方式来控制编译器是否生成某些特殊成员函数(如默认构造函数、拷贝构造函数、拷贝赋值运算符、析构函数等)。 默认生成:如果你没有显式地定义这些特殊成员函数,编译器会自动生成它们…...

Mysql 数据库开发及企业级应用
文章目录 1、Mysql 数据库开发及企业级应用1.1、为什么要使用数据库1.1.1、数据库概念(Database)1.1.2、为什么需要数据库 1.2、程序员为什么要学习数据库1.3、数据库的选择1.3.1、主流数据库简介1.3.2、使用 MySQL 的优势1.3.3、版本选择 1.4、Windows …...

【数据结构】_6.队列
目录 1.概念 2.队列的使用 3.队列模拟实现 4.循环队列 5.双端队列 6.OJ题 6.1 用队列实现栈 6.2 用栈实现队列 1.概念 (1)队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表; (2&am…...

7 网络通信(上)
文章目录 网络通信概述ip地址ip的作用ip地址的分类私有ip 掩码和广播地址 linux 命令(ping ifconfig)查看或配置网卡信息:ifconfig(widows 用ipconfig)测试远程主机连通性:ping路由查看 端口端口是怎样分配的知名端口动态端口 查看…...
MFC图表控件high-speed-charting的使用
high-speed-charting是MFC上的开源图表库,Teechart的替代品。 high-speed-charting的下载地址 https://www.codeproject.com/Articles/14075/High-speed-Charting-Control 特性 High-speed drawing (when axis is fixed) which allows fast plotting of dataUnlimited number …...
Unity中常用方法
1.基础 //初始化引入 [RequireComponent(typeof(BoxCollider2D))] [RequireComponent(typeof(Rigidbody2D))]//游戏帧率设置 60帧Application.targetFrameRate 60;//获取物体对象 //获取到当前物体(根据名称,也可以根据路径)GameObject go GameObject.Find("…...

【监控系统】可视化工具Grafana简介及容器化部署实战
1.什么是Grafana 官网地址:https://grafana.com/ Grafana用Go语言开发的开源数据可视化工具,可以做数据监控和数据统计,带有告警功能。支持快速灵活的客户端图表,面板插件有许多不同方式的可视化指标和日志,官方库中…...

VUE之VueRouter页面跳转
参考资料: 参考视频 参考demo及视频资料 VUE之基本部署及VScode常用插件 VUE之基本组成和使用 VUE之Bootstrap和Element-UI的使用 VUE之axios使用,跨域问题,拦截器添加Token Vue Router官网 Vue Router说明: 说明…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...

自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...