当前位置: 首页 > news >正文

21.多态

一、多态概念

多种形态。

静态多态:编译时多态。(函数重载)

动态多态:运行时多态。(继承关系下,调用父类指针或引用,对于不同的对象有不同的行为)

二、多态的定义及实现

1)多态的构成条件

多态时一个继承关系下的类对象,去调用同一函数,产生了不同的行为。

实现多态的两个必须条件:

1.必须是父类的指针或引用调用虚函数。

2.被调用的函数必须是虚函数,子类必须对父类的虚函数重写/覆盖。

2)虚函数

易错点1:

virtual关键字只在声明时加上,在类外实现时不能加

易错点2:

static和virtual是不能同时使用的。

原因:static成员函数没有this指针,且virtual成员函数依赖于this指针来实现动态绑定。

 易错点3:

重定义就是隐藏。

虚函数:类成员函数前加virtual修饰。

注:非成员函数不能加virtual修饰。

虚函数的重写/覆盖:子类中有一个和父类完全相同的虚函数(参数列表,函数名,返回值)

例如:

#include <iostream>
using namespace std;class Person
{
public:virtual void BuyTicket(){}
};class Teacher :public Person
{
public:virtual void BuyTicket(){cout << "老师,买全票" << endl;}
};class Student :public Person
{
public:virtual void BuyTicket(){cout << "学生,优惠买票" << endl;}
};void Buy(Person* ptr)
{ptr->BuyTicket();
}int main()
{Student s;Teacher t;Buy(&s);Buy(&t);return 0;
}

其中,满足了多态,和ptr的类型无关,与ptr指向的对象有关。

注意:重写父类虚函数时,子类的虚函数可以不加virtual,也构成重写。

原因:继承后父类的虚函数被继承下来了在子类中保持虚函数属性,但这种写法不规范。

面试题:

 以下程序输出结果是什么()
A: A->0 B: B->1 C: A->1 D: B->0 E: 编译出错 F: 以上都不正确

class A
{
public:virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }virtual void test() { func(); }
};
class B : public A
{
public:void func(int val = 0) { std::cout << "B->" << val << std::endl; }
};
int main(int argc, char* argv[])
{B* p = new B;p->test();return 0;
}

答案是B,输出结果为:B->1

分析:A类的func和B类的func构成重写,因为参数列表,返回值,函数名都一致,其中参数列表是否不同和缺省值具体是多少无关,B类中即使没加virtual,也没有问题,因为继承后父类的虚函数被继承下来在子类中仍旧保持虚函数属性

编译器对于重写的函数的处理:

3)虚函数重写的一些其他问题

协变:

概念:子类重写父类虚函数时,与父类虚函数返回值类型不同。

不同指必须是:父类返回值返回父类的指针和引用,子类返回值返回子类的指针和引用。

可以是自身的继承关系,也可以是其他的继承关系。

测试代码:

#include <iostream>
using namespace std;class A
{};
class B :public A
{};class Person
{
public:virtual A* func(){cout << "Person::func()" << endl;return nullptr;}
};
class Student :public Person
{
public:virtual B* func(){cout << "Student::func()" << endl;return nullptr;}
};
class Teacher :public Person
{
public:virtual B* func(){cout << "Teacher::func()" << endl;return nullptr;}
};
void f(Person* ptr)
{ptr->func();
}int main()
{Person p;Student s;Teacher t;f(&p);f(&s);f(&t);return 0;
}

 可以看到,用其他类的继承关系实现协变也可。

析构函数的重写

父类的析构函数为虚函数,此时子类析构函数只要定义,无论是否加virtual,都构成重写。

原因:编译器对析构函数的名称特殊处理,编译后析构函数的名称统⼀处理成destructor
为什么父类的析构函数建议设计成虚函数?
测试代码:
#include <iostream>
using namespace std;class A
{
public:~A(){cout << "~A()" << endl;}
protected:int _a;
};
class B :public A
{
public:~B(){delete[] _b;cout << "~B()" << endl;}
private:int* _b = new int[10];
};int main()
{B* b = new B;A* a = new B;delete b;delete a;return 0;
}
结果为:可以明确看到,若A* a = new B; 这种情况,如果B类不重写A类的析构函数,那么就会导致delete a; 时,只调用了父类A的析构函数,没有调用子类B的析构函数,导致内存泄漏。
解决方法:重写父类A的析构函数。

4)重载/重写/隐藏的比较(同名函数的关系)

重载:

1.两个函数在同一作用域

2.函数名相同,参数不同(参数列表不同),返回值不限

重写/覆盖:

1.两个函数分别在继承体系的父类和子类作用域

2.函数名,参数,返回值必须相同,协变例外

3.两个函数必须都是虚函数

隐藏:

1.两个函数分别在继承体系的父类和子类作用域

2.函数名相同

3.父子类的成员变量名相同(成员变量方面) 

 三、纯虚函数和抽象类

定义方式:在纯虚函数后面加上=0。

class A
{
public:virtual void func() = 0;
};

不需要定义实现(但在语法上可以实现,没有必要),只要声明即可。

抽象类:包含纯虚函数的类。

抽象类不能实例化出对象。

子类继承父类,若没有重写父类的纯虚函数,那么子类也是抽象类。(间接强制重写纯虚函数,不重写实例化不出对象)

四、多态的原理

下面编译为32位程序的运行结果是什么()
A. 编译报错 B. 运行报错 C. 8  D. 12

class Base
{
public:virtual void Func1(){std::cout << "Func1()" << endl;}
protected:int _b = 1;char _ch = 'x';
};
int main()
{Base b;cout << sizeof(b) << endl;return 0;
}

答案是D,sizeof(b)是12字节。

原因,b对象中有_vfptr,虚函数表的指针,存在对象的起始位置,类型为void**,在32位环境下是指针是4字节,根据内存对齐规则,对齐后为12字节。

多态原理分析: 

测试代码:

#include <iostream>
using namespace std;class Person
{
public:virtual void func(){cout << "Person::func()" << endl;}
protected:string _name;
};
class Student :public Person
{
public:virtual void func(){cout << "Student::func()" << endl;}
private:int _sid;
};
class Teacher :public Person
{
public:virtual void func(){cout << "Teacher::func()" << endl;}
private:int _tid;
};
void f(Person* ptr)
{ptr->func();
}int main()
{Person p;Student s;Teacher t;f(&p);f(&s);f(&t);return 0;
}

通过监视窗口可以看到,p,s,t对象各有一个虚函数表指针_vfptr(virtual function table 虚函数表指针),且指针的值不同,说明指向不同的空间,而且指向的内容函数指针不同,p对象为它的Person::func的函数指针,重写的s和t对象为各自重写的函数指针。

逻辑结构如图:

指向谁调用谁,运行时,到指向对象的虚函数表中找到对应虚函数的地址,进行调用,达到多态。

动态绑定和静态绑定

静态绑定:对不满足多态条件(指针或引用调用虚函数)在编译时确定,编译时确定调用函数的地址。

动态绑定:满足多态条件的函数调用是在运行时绑定,也就是运行时到指定对象的虚函数表中找到调用函数的地址。

虚函数表

易错点1:

虚函数表是在编译时生成的。

易错点2:

#include<iostream>
using namespace std;class A
{
public:virtual void f(){cout << "A::f()" << endl;}
};
class B : public A
{
private:virtual void f(){cout << "B::f()" << endl;}
};int main()
{A* pa = (A*)new B;pa->f();return 0;
}

输出:B::f() 。
原因:即使B中重写的f()函数是私有的,但是已经构成重写了,把虚函数表中原有的A的f()函数指针覆盖了,最终调用的位置不变,只是执行函数发生变化访问权限的检查是基于指针的类型A而不是指向的对象实际类型B

易错点3:

class A
{
public:A ():m_iVal(0){test();}virtual void func() { std::cout<<m_iVal<<‘ ’;}void test(){func();}
public:int m_iVal;
};class B : public A
{
public:B(){test();}virtual void func(){++m_iVal;std::cout<<m_iVal<<‘ ’;}
};int main(int argc ,char* argv[])
{A*p = new B;p->test();return 0;
}

输出结果为:0 1 2

分析:最开始,new B,开内存,调用B的构造,由于B继承A,初始化列表调用A的默认构造,初始化列表m_iVal被初始化成0,然后调用test(),由于此时还处于父类对象构造阶段,多态机制还没有生效,调用的是父类A的func(),打印0 。然后借着就是B的构造,调用test(),此时父类已经构造好了,func也实现了重写,满足多态机制,调用重写后的func,打印1 。然后A* p调用test(),符合多态机制,调用重写后的func,打印2 。

1)父类对象的虚函数表中存放所有虚函数的地址。

同类型对象共用一张虚表,不同类型对象有各自独立的虚表,因此子类和父类有各自虚表。

2)子类由两部分构成,继承下来的父类和自己的成员。一般情况下,继承下来的父类中有虚函数表指针,自己就不会再生成虚函数表指针。

3)子类重写的父类的虚函数,子类的虚函数表中对应的虚函数就会被覆盖成子类重写的虚函数地址。

测试代码:

#include <iostream>
using namespace std;class A
{
public:virtual void print(){cout << "A::print()" << endl;}virtual void funcA(){cout << "A::funcA()" << endl;}
private:int _a;
};class B :public A
{
public:virtual void print(){cout << "B::print()" << endl;}virtual void funcB(){cout << "B::funcB()" << endl;}
private:int _b;
};class C :public B
{
public:virtual void print(){cout << "C::print()" << endl;}virtual void funcC(){cout << "C::funcC()" << endl;}
private:int _c;
};int main()
{C c;c.funcB();return 0;
}

可以看到,在纯单继承体系中,只有一张虚函数表,存放所有继承体系的虚函数地址,其中被重写的虚函数只存放最终版(之前的都被覆盖了)。

4)子类的虚函数表中包含,父类的虚函数地址,子类重写(覆盖的虚函数地址),子类自己的虚函数地址。

测试代码:

#include <iostream>
using namespace std;class A
{
public:virtual void func1(){}
};class B
{
public:virtual void func2(){}
};class C :public A, public B
{
public:virtual void func3(){}
};typedef void(C::* P)();
int main()
{A a;B b;C c;P p = &C::func3;int n = 0;return 0;
}

可以看到,多继承,C同时继承A和B,A和B各自独立有一个虚函数表指针,C自身的虚函数指针存放在第一个继承的类A的虚函数指针表中。
5)虚函数表本质是⼀个存虚函数指针的指针数组,一般情况这个数组最后面放了⼀个0x00000000标记。(这个C++并没有进行规定,各个编译器自行定义的,vs系列编译器会再后面放个0x00000000标记,g++系列编译器不会放)

6)虚函数和普通函数一样,存放在代码段的,编译后是一段指令,只是虚函数的地址又存到虚函数表中。

7)虚函数表存在哪里?C++没有规定,以下是一个测试程序,来测试虚函数表存在哪里。

测试代码:

#include <iostream>
using namespace std;class Base {
public:virtual void func1() { cout << "Base::func1" << endl; }virtual void func2() { cout << "Base::func2" << endl; }void func5() { cout << "Base::func5" << endl; }
protected:int a = 1;
};
class Derive : public Base
{
public:// 重写基类的func1virtual void func1() { cout << "Derive::func1" << endl; }virtual void func3() { cout << "Derive::func1" << endl; }void func4() { cout << "Derive::func4" << endl; }
protected:int b = 2;
};int main()
{int i = 0;static int j = 1;int* p1 = new int;const char* p2 = "xxxxxxxx";printf("栈:%p\n", &i);printf("静态区:%p\n", &j);printf("堆:%p\n", p1);printf("常量区:%p\n", p2);Base b;Derive d;Base* p3 = &b;Derive* p4 = &d;printf("Person虚表地址:%p\n", *(int*)p3);printf("Student虚表地址:%p\n", *(int*)p4);printf("虚函数地址:%p\n", &Base::func1);printf("普通函数地址:%p\n", &Base::func5);return 0;
}

可以看出Person虚表地址和Student虚表地址和常量区非常接近,可以推断出vs2022的虚表是存在常量区的。

可以看出Person和Student虚表地址和常量区最接近,可以推断出g++4.8.5的虚表存在常量区。

相关文章:

21.多态

一、多态概念 多种形态。 静态多态&#xff1a;编译时多态。&#xff08;函数重载&#xff09; 动态多态&#xff1a;运行时多态。&#xff08;继承关系下&#xff0c;调用父类指针或引用&#xff0c;对于不同的对象有不同的行为&#xff09; 二、多态的定义及实现 1&#xff…...

无再暴露源站!群联AI云防护IP隐匿方案+防绕过实战

一、IP隐藏的核心原理 群联AI云防护通过三层架构实现源站IP深度隐藏&#xff1a; 流量入口层&#xff1a;用户访问域名解析至高防CNAME节点&#xff08;如ai-protect.example.com&#xff09;智能调度层&#xff1a;基于AI模型动态分配清洗节点&#xff0c;实时更新节点IP池回…...

新版AndroidStudio / IDEA上传项目到Gitee

目录 1.Gitee创建仓库 2.填写仓库的信息 3.创建成功后复制仓库的地址 4.检查AndroidStudio是否配置Git 5.点击测试 6.之后Create Git Repository 7.添加到本地仓库 8.提交项目 9.添加上传仓库的地址 10.上传成功 11.去Gitee上刷新检查 1.Gitee创建仓库 2.填写仓库的…...

学习threejs,使用MeshFaceMaterial面材质容器

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.MeshFaceMaterial 二…...

python微分方程求解,分别用显式欧拉方法、梯形法、改进欧拉方法、二阶龙格库塔方法、四阶龙格库塔方法求解微分方程

微分方程在自然科学、工程技术、社会科学等多个领域都有着广泛而重要的应用。而求解微分方程是数学与应用数据领域一大难题&#xff0c;对于一些复杂的微分方程无法通过计算推导计算其精确的方程表达式与 结果&#xff0c;因此&#xff0c;我们通过数学理论。迭代&#xff0c;微…...

【ubuntu】——wsl中使用windows中的adb

一、引言 在 Windows Subsystem for Linux&#xff08;WSL&#xff09;环境下工作时&#xff0c;有时需要使用 Android Debug Bridge&#xff08;ADB&#xff09;工具与 Android 设备进行交互。通过特定设置&#xff0c;能够在 WSL 中便捷地调用 Windows 系统中已安装的 ADB&a…...

Git 常用命令完全指南:从入门到高效协作

文章需要结构清晰&#xff0c;涵盖从入门到进阶的常用命令&#xff0c;结合实例和注意事项&#xff0c;帮助用户快速掌握Git的核心功能&#xff0c;并应用到实际项目中 一、仓库初始化与基础操作 1. 创建与克隆仓库 # 初始化本地仓库 git init# 克隆远程仓库&#xff08;SSH方…...

学习单片机需要多长时间才能进行简单的项目开发?

之前有老铁问我&#xff0c;学单片机到底要多久&#xff0c;才能进行简单的项目开发&#xff1f;是三个月速成&#xff0c;还是三年磨一剑&#xff1f; 今天咱们就来聊聊这个话题&#xff0c;我不是什么高高在上的专家&#xff0c;就是个踩过无数坑、烧过几块板子的“技术老友”…...

面试系列|蚂蚁金服技术面【3】

今天继续分享一下蚂蚁金服的 Java 后端开发岗位真实社招面经&#xff0c;复盘面试过程中踩过的坑&#xff0c;整理面试过程中提到的知识点&#xff0c;希望能给正在准备面试的你一些参考和启发&#xff0c;希望对你有帮助&#xff0c;愿你能够获得心仪的 offer ! 第二轮面试之…...

Spring Boot项目中成功集成了JWT

JWT 原理解释 什么是 JWT&#xff1f; JSON Web Token&#xff08;JWT&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应用环境间安全地将信息作为JSON对象传输。JWT通常用于身份验证和信息交换。 JWT 的结构 JWT由三部分组成&#xff…...

《Java SQL 操作指南:深入理解 Statement 用法与优化》

在 Java 数据库编程中&#xff0c;Statement 是用于执行 SQL 语句的接口&#xff0c;允许程序与数据库进行交互。本文将详细介绍 Statement 的基本概念、常见用法以及 PreparedStatement 和 CallableStatement 等相关接口。 1. Statement 基本介绍 Statement 接口继承了 AutoC…...

element ui设置结束时间为23:59:59

开始时间为00:00:00结束时间为23:59:59 在请求接口前&#xff0c;用substring取结束时间的年月日&#xff0c;并替换时间值即可 <el-formref"searchForm":model"searchForm":inline"true"size"mini"keyup.enter.native"getDa…...

Matlab 舰载机自动着舰控制系统研究

1、内容简介 Matlab 188-舰载机自动着舰控制系统研究 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...

数据集格式转换——json2txt、xml2txt、txt2json【复制就能用】

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏地址:YOLO11入门 + 改进涨点——点击即可跳转 欢迎订阅 目录 json2txt脚本 xml2txt txt2json...

MySQL 横向衍生表(Lateral Derived Tables)

前面我们介绍过MySQL中的衍生表&#xff08;From子句中的子查询&#xff09;和它的局限性&#xff0c;MySQL8.0.14引入了横向衍生表&#xff0c;可以在子查询中引用前面出现的表&#xff0c;即根据外部查询的每一行动态生成数据&#xff0c;这个特性在衍生表非常大而最终结果集…...

基于llama.cpp的QwQ32B模型推理

基于llama.cpp的QwQ32B模型推理 llama.cpp项目主页&#xff1a; https://github.com/ggml-org/llama.cpp# llama.cpp源码下载 cd /root/lanyun-tmpgit clone https://github.com/ggml-org/llama.cpp#llama.cpp编译 llama.cpp是个C语言项目&#xff0c;实际调用过程需要先构建项…...

【Jmeter】使用教程

下载及安装 参考链接: JMeter下载及安装&#xff08;附插件及中文包超详细&#xff09; 参考链接: 【Jmeter】win 10 / win 11&#xff1a;Jmeter 下载、安装、汉化、新机迁移、版本更新&#xff08;Jmeter 4 以上版本均适用&#xff09; 分辨率的调整 参考链接: Jmeter5.3字…...

黑马商城完成随笔

完结撒花 &#x1f389; &#x1f389; &#x1f389; 差不多用了两三个星期&#xff1f;终于是完成了。 黑马商城体量应该是全部黑马项目中体量最多&#xff0c;技术栈最复杂的了。 可是仍然存在之前黑马项目的问题&#xff1a;不细致&#xff0c;不完整 很多技术栈的使用仅…...

【Python 算法零基础 1.线性枚举】

我装作漠视一切&#xff0c;以为这样就可以不在乎 —— 25.3.17 一、线性枚举的基本概念 1.时间复杂度 线性枚举的时间复杂度为 O(nm)&#xff0c;其中 n是线性表的长度。m 是每次操作的量级&#xff0c;对于求最大值和求和来说&#xff0c;因为操作比较简单&#xff0c;所以 …...

涨薪技术|Kubernetes(k8s)之Pod端口设置及资源配额

01端口设置 使用以下命令可以可以查看到到ports的子选项 [rootk8s-master01 ~]# kubectl explain pod.spec.containers.portsKIND: PodVERSION: v1RESOURCE: ports <[]Object>FIELDS:name <string> # 端口名称&#xff0c;如果指定&#xff0c;必须保证name在pod…...

七大常用智能家居协议对比

如果您不知道在项目中使用哪种智能家居通信协议&#xff0c;那么进入智能家居行业可能会很困难。如果没有合适的协议将其集成到智能家居生态系统中&#xff0c;智能家居设备将无法正常工作。否则&#xff0c;您将面临硬件和软件无法满足最终用户期望的风险。协议选择不当可能会…...

K8S快速部署

前置虚拟机环境正式部署BUG解决 前置虚拟机环境 每个虚拟机配置一次就好 #关闭防火墙 systemctl stop firewalld systemctl disable firewalld #关闭 selinux sed -i s/enforcing/disabled/ /etc/selinux/config # 永久 setenforce 0 # 临时 #关闭 swap swapoff -a # 临时 vi…...

TCP 三次握手四次挥手过程详解

注&#xff1a;本文为 “TCP 的三次握手与四次挥手” 相关文章合辑。 英文引文&#xff0c;机翻未校。 中文引文&#xff0c;未整理去重。 英文引文第二篇&#xff0c;实为国内《稀土掘金技术社区》文章&#xff0c;没检索到原文&#xff0c;此处 “出口转内销” 。 如有内…...

如何利用 Zeabur 实现 OceanBase 的一键部署

引言 Zeabur 是一个功能强大且即开即用的自动化部署平台&#xff0c;它不仅能迅速部署多种应用&#xff0c;还支持一键安装 MySQL、PostgreSQL 等数据库服务。 Zeabur 拥有众多国内外用户&#xff0c;如 AFFiNE、Bytebase 等企业客户&#xff0c;以及大量全栈和独立开发者。将…...

基于Springboot+服务器磁盘的本地文件存储方案

[local-file-system]基于服务器磁盘的本地文件存储方案 仅提供后端方案 github 环境 JDK11linux/windows/mac 应用场景 适用于ToB业务&#xff0c;中小企业的单体服务&#xff0c;仅使用磁盘存储文件的解决方案 仅使用服务器磁盘存储 与业务实体相结合的文件存储方案&…...

基于FPGA的3U机箱模拟量高速采样板ADI板卡,应用于轨道交通/电力储能等

板卡简介&#xff1a; 本板为模拟量高速采样板&#xff08;ADI&#xff09;&#xff0c;主要用于电机转速和相电流检测&#xff0c;以实现电机闭环控制。 性能规格&#xff1a; 电源&#xff1a;DC5V&#xff0c;DC3.3V&#xff0c;DC15V&#xff0c;DC24V FPGA&#xff1a;…...

泰勒·斯威夫特(Taylor Swift)的音乐影响力与商业版图深度研究

泰勒斯威夫特的音乐影响力与商业版图深度研究 简介 泰勒斯威夫特&#xff08;Taylor Swift&#xff09;是当今流行音乐领域最具影响力的全球巨星之一。自少年时期出道以来&#xff0c;她在音乐风格、形象和商业战略上不断演变&#xff0c;从乡村音乐新人成长为引领流行文化的…...

神经网络微调技术解析

神经网络微调技术 微调&#xff08;Fine-tuning&#xff09;是迁移学习的核心技术&#xff0c;通过在预训练模型基础上调整参数&#xff0c;使其适应特定任务或领域。以下从传统方法、参数高效微调&#xff08;PEFT&#xff09;、新兴技术三个维度展开&#xff0c;覆盖主流技术…...

鸿蒙路由 HMRouter 配置及使用 三 全局拦截器使用

1、前期准备 简单封装一个用户首选项的工具类 import { preferences } from "kit.ArkData";// 用户首选项方法封装 export class Preferences {private myPreferences: preferences.Preferences | null null;// 初始化init(context: Context, options: preference…...

国科大——计网(0812)——考试真题

前沿&#xff1a; 此篇文章记录了国科大秋季学期计网&#xff08;0812&#xff09;课程的一些考试真题&#xff0c;某些题目的答案仅供参考&#xff0c;还请自行辨别。 备注&#xff1a; 计网的考试题一般都会多一道&#xff0c;每道题的分值相同&#xff0c;例如&#xff1a;…...

Feedback-Guided Autonomous Driving

Feedback-Guided Autonomous Driving idea 问题设定&#xff1a;基于 CARLA 的目标驱动导航任务&#xff0c;通过知识蒸馏&#xff0c;利用特权智能体的丰富监督信息训练学生传感器运动策略函数 基于 LLM 的端到端驱动模型&#xff1a;采用 LLaVA 架构并添加航点预测头&#…...

超参数优化算法:scikit-opt库、Scikit-Optimize库

1 scikit-opt库&#xff1a;https://www.cnblogs.com/luohenyueji/p/18333387 https://blog.csdn.net/weixin_45750972/article/details/124683402 a 差分进化算法 (Differential Evolution)&#xff1a;一种基于群体搜索的优化算法&#xff0c;通过模拟生物进化的过程来寻找最…...

我与DeepSeek读《大型网站技术架构》- 大型网站架构技术一览与Web开发技术发展历程

文章目录 大型网站架构技术一览1. 前端架构2. 应用层架构3. 服务层架构4. 存储层架构5. 后台架构6. 数据采集与监控7. 安全架构8. 数据中心机房架构 Web开发技术发展历程一、静态HTML阶段二、CGI脚本模式阶段三、服务器页面模式阶段 大型网站架构技术一览 1. 前端架构 浏览器…...

解决QT_Debug 调试信息不输出问题

方式1 &#xff1a;手动通过添加环境变量解决 ->使用命令&#xff1a; QT_LOGGING_TO_CONSOLE1 qtcreator启动 ->如若还未输出qDebug调试信息 则在程序中引<QLoggingCategory>包 #include <QLoggingCategory> ->在程序入口添加 QLoggingCategory::defa…...

NebulaGraph3.3.0部署与配置

系统参数 8g 2核参考文档: https://docs.nebula-graph.com.cn/3.8.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/2.install-nebula-graph-by-rpm-or-deb/静态IP配置 # 修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33# 修改文件内容…...

oracle 基础知识之 多表查询

多表查询定义&#xff1a;当查询的数据并不是来源一个表时&#xff0c;需要使用多表连接操作完成查询。多表连接查询通过表之间的关联字段&#xff0c;一次查询出多个表的数据。多表查询包括了等值连接、左连接、右连接、完全连接。 1.等值连接 等值连接也称为简单连接&#xf…...

《论分布式系统架构设计及其应用》架构师论文

【摘要】 2022年3月&#xff0c;我参与了某金融科技公司“智能风控云平台”项目的研发工作&#xff0c;担任系统架构师职务&#xff0c;负责分布式系统架构设计与核心技术选型。该平台旨在为银行、保险等金融机构提供实时风险评估、反欺诈及数据服务&#xff0c;需支撑每秒十万…...

Matlab 汽车主动悬架LQR控制器设计与仿真

1、内容简介 Matlab 182-汽车主动悬架LQR控制器设计与仿真 可以交流、咨询、答疑 2、内容说明 略 1、研究背景 汽车悬架系统由弹性元件、导向元件和减振器组成,是车身与车轴之间连接的所有组合体零件的总称,也是车架(或承载式车身)与车桥(或车轮)之间一切力传递装置的总称,…...

JMeter 参数化工作原理说明

一、核心目标&#xff1a;让每条请求都能用不同数据 参数化的本质是让 JMeter 在发送请求时&#xff0c;自动替换变量为不同的值。例如&#xff1a; 模拟 100 个用户登录 → 每个用户使用不同的账号密码。模拟搜索不同关键词 → 每次请求自动更换关键词。 二、参数化如何工作…...

[免费]直接整篇翻译pdf工具-支持多种语言

<闲来没事写篇博客填补中文知识库漏洞> 如题&#xff0c;[免费][本地]工具基于开源仓库&#xff1a; 工具 是python&#xff01;太好了&#xff0c;所以各个平台都可以&#xff0c;我这里基于windows. 1. 先把github代码下载下来&#xff1a; git clone https://githu…...

Python 鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…...

Unity音乐内存优化

文章目录 音乐下载远程音乐 音乐 音乐文件如果只从工程目录里面读取&#xff0c;那有很多种方法可以优化&#xff0c;比如设置Load Type直接采用流式加载方式&#xff0c;内存直接降最小&#xff08;但是记住&#xff0c;每种优化都是有对应的代价的&#xff0c;优化是一种平衡…...

hubilder打包ios app, 并上传TestFlight

目录 一 前提条件 不是该项目成员解决 1. 直接找到该项目的管理人员去设置你的账号 2. 直接重新生成APPID(一般不建议的&#xff0c;可以查看) 3. 如果是离职人员&#xff0c;可以让他将项目权限转让出来 - 如何转让应用 - DCloud问答 未申请ios证书和描述文件 APP ID 的…...

3个 Vue $set 的应用场景

大家好&#xff0c;我是大澈&#xff01;一个喜欢结交朋友、喜欢编程技术和科技前沿的老程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;&#xff0c;关注我&#xff0c;科技未来或许我能帮到你&#xff01; 在 Vue2 中&#xff0c;由于 Object.defineProperty 的限制&#…...

3ds Max 导入到 After Effects 还原摄像机要注意事项--deepseek

我&#xff1a;dp我这有两个脚本分别是syn软件相机导出到max的和syn软件相机导出到ae的&#xff0c;你能看出差别来吗&#xff1f;如果我想把max里的相机导入到ae里&#xff0c;保持原来的位置方向&#xff0c;该怎么做 dp&#xff1a;从这两个脚本可以看出&#xff0c;3ds Ma…...

从零开始 | C语言基础刷题DAY3

❤个人主页&#xff1a;折枝寄北的博客 目录 1.打印3的倍数的数2.从大到小输出3. 打印素数4.打印闰年5.最大公约数 1.打印3的倍数的数 题目&#xff1a; 写一个代码打印1-100之间所有3的倍数的数字 代码&#xff1a; int main(){int i 0;for (i 1; i < 100; i){if (i % …...

SQL注入第7关

存在注入&#xff0c;需要使用单引号闭合 拥有root权限&#xff0c;secure_file_priv值为空&#xff0c;确定路径 http://127.0.0.1/sqli-labs-master/Less-7/?id1)) union select 1,"<?phpinfo();?>",3 into outfile "D:\\landui\\xp\\phpstudy_pro…...

Git使用和原理(3)

1.远程操作 1.1分布式版本控制系统 我们⽬前所说的所有内容&#xff08;⼯作区&#xff0c;暂存区&#xff0c;版本库等等&#xff09;&#xff0c;都是在本地&#xff01;也就是在你的笔记本或者 计算机上。⽽我们的 Git 其实是分布式版本控制系统&#xff01;什么意思呢&a…...

从零搭建微服务项目Pro(第6-1章——Spring Security+JWT实现用户鉴权访问与token刷新)

前言&#xff1a; 在现代的微服务架构中&#xff0c;用户鉴权和访问控制是非常重要的一部分。Spring Security 是 Spring 生态中用于处理安全性的强大框架&#xff0c;而 JWT&#xff08;JSON Web Token&#xff09;则是一种轻量级的、自包含的令牌机制&#xff0c;广泛用于分…...

LeetCode 124.二叉树中的最大路径和

题目&#xff1a; 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点…...