突破编程_C++_基础教程(类的基础知识)

1 面向对象

面向对象( Object-Oriented ,简称 OO )是一种编程思想,它使用对象的理念来设计软件和构建程序。面向对象编程( Object-Oriented Programming ,简称 OOP )是这种思想的具体实现方式。在面向对象编程中,程序把对象作为基本单元,对象包含了数据(属性)和操作数据的函数(方法),通过对象之间的交互以及消息传递完成了程序的运行。

1.1 面向对象编程的三大基本特性

面向对象编程的三大基本特性是:封装( Encapsulation )、继承( Inheritance )和多态( Polymorphism )。
(1)封装(Encapsulation)
封装是指将对象的属性和方法隐藏在其内部,只通过有限的接口与外部进行交互。这样可以防止外部代码随意访问和修改对象的内部数据,从而提高代码的安全性和可维护性。
(2)继承(Inheritance)
继承是指一个类(子类)可以继承另一个类(父类)的属性和方法,从而实现代码的重用。子类可以继承父类的所有非私有属性和方法,并可以添加或覆盖父类的方法。 C++ 支持三种类型的继承:公有继承( public )、保护继承( protected )和私有继承( private )。其中,公有继承是最常用的继承方式。
(3)多态(Polymorphism)
多态是指允许一个成员函数被多种数据类型实现(重载),或者一个成员函数在不同场景下有不同实现方式(重写)。多态性允许使用基类的指针或引用来调用派生类中的成员函数,在运行时根据实际对象的类型来确定调用哪个函数,从而增强了程序的灵活性和可扩展性。

1.2 面向对象编程的主要优点

(1)通过继承增强代码的可重用性:可以很方便地重用父类的属性与方法。
(2)通过封装增强代码的可维护性:可以隐藏对象的内部实现细节,只通过有限的接口与外部进行交互,从而降低代码的耦合度,提高代码的可维护性。
(3)通过多态增强代码的可扩展性:可以在不修改现有代码的情况下,增加新的功能或重构现有功能的行为。

1.3 面向过程编程与面向对象编程的区别

(1)设计思路
面向过程以算法为核心,通过分析问题,确定程序流程和模块化的分解。面向对象以对象为核心,通过封装、继承和多态等特性实现代码复用和扩展。它要解决的问题分解成各个对象,各个对象之间交互,完成事件,解决问题。
(2)数据与方法
在面向过程编程中,数据和对数据的操作通常是分开的。而在面向对象编程中,数据和相关的操作被封装在一起形成对象。
(3)实现方式
面向过程编程采用函数调用的方式实现功能。具体来说,它采用模块化、流程化的编程方式,具体步骤和每个步骤需要完成的任务明确清晰,在开发之前基本考虑了实现方式和最终结果,便于节点分析。而面向对象采用对象的方式实现功能。它通过将控制权转移到数据上,实现了数据控制代码的访问。
(4)适用场景
面向过程编程以函数为基本单位,结构化,适用于需要高性能和明确流程的程序开发。面向对象编程以类和对象为基本单位,提供了抽象、封装、继承和多态等好处(比较消耗资源),适用于大型程序开发。

2 类的概念与基本用法

类( Class )是一种用户自定义的数据类型,它允许程序员定义自己的数据类型,并封装数据和方法(即函数)在一起。类提供了数据抽象、封装、继承和多态等面向对象的特性,有助于创建更加模块化和可重用的代码。

2.1 类的语法结构

类的语法结构通常包括类名、访问修饰符( public 、 private 、 protected )、成员变量和成员函数(包括构造函数以及析构函数):
(1)成员变量:也称为属性或字段,用于存储对象的状态或数据。
(2)成员函数:也称为方法或行为,定义了对象可以执行的操作。
(3)构造函数:一种特殊的成员函数,当创建类的对象时自动调用。通常用于初始化对象的属性。
(4)析构函数:一种特殊的成员函数,在对象被销毁之前调用,用于执行清理操作。
(5)访问修饰符:包括 public 、private 、 protected ,用于定义成员变量的可见性和成员函数的访问权限。
下面是一个简单的类的语法结构示例:

class MyClass 		// 类名
{
// 构造函数与析构函数
public:				// 访问修饰符:公有成员(默认情况下,如果不指定访问修饰符,则成员是私有的)  MyClass() {};	// 构造函数~MyClass() {};	// 析构函数// 公共成员函数与成员变量
public:void publicFunc() {}	// 公共成员函数int m_publicVal;		// 公共成员变量// 保护成员函数与成员变量
protected:void protectedFunc() {}	// 保护成员函数int m_protectedVal;		// 保护成员变量// 私有成员函数与成员变量
private:void privateFunc() {}	// 私有成员函数int m_privateVal;		// 私有成员变量
};

2.2 类的基本用法

根据 " 2.1 类的语法结构 "介绍的语法规则,可以创建如下的一个类:

class Animal
{	
public:Animal(string name):m_name(name) {};~Animal() {};public:void eat(){printf("eat something");}string getName(){return m_name;}private:string m_name;
};

在上面中,Animal 是一个类,它有两个成员函数 eat 以及 getName ,有一个属性 m_name 。在定义这个类之后就可以创建该类的一个实例:

Animal animal("aa");
animal.eat();

在创建该类的实例后,即可使用点操作符调用该对象的成员函数。C++11 引入了列表初始化(也称为统一初始化),它提供了一种更直观、更灵活的方式来初始化对象。列表初始化可以使用花括号 {} 来包围初始化值:

Animal animal{ "aa" };

还可以使用 new 关键字在堆上动态地创建对象。这种方式创建的对象在生命周期结束时需要使用 delete 关键字来释放内存:

Animal* animal = new Animal("aa");
animal->eat();

注意:使用 new 关键字在堆上动态地创建对象需要使用箭头操作符调用该对象的成员函数。

3 类访问修饰符

类访问修饰符用于控制类成员的访问权限,即确定哪些成员可以在类的对象外部访问,哪些只能在类的内部访问。C++提供了三种访问修饰符:public、private和protected。

3.1 public 访问修饰符

使用 public 修饰符声明的成员函数与成员变量是公开的。当创建一个类的对象时,可以直接访问 public 修饰符修饰的成员:

class Animal
{	
public:Animal() {};~Animal() {};public:void eat(){printf("eat something");}public:string name;
};Animal animal;  
animal.eat(); 		// OK:可以访问公有成员函数  
eat.name = "aa"; 	// OK:可以访问公有成员变量  

public 访问修饰符主要用于定义那些可以从类的外部访问的成员(包括成员变量和成员函数)。使用 public 访问修饰符可以使类的某些部分对外部代码可见,从而实现类的功能与外部对象的交互。
以下是一些 public 访问修饰符的应用场景:
(1)接口定义
当定义一个类作为接口时,通常会将成员函数声明为 public,以便其子类可以实现这些接口。接口中的成员函数通常是纯虚函数,没有实现,但它们定义了类与外部对象的交互方式。
(2)访问器( getter )和修改器( setter )方法
在面向对象编程中,为了封装数据并控制对数据的访问,通常会使用 public 访问修饰符来声明访问器( getter )和修改器( setter )方法。这些方法允许外部代码读取或修改类的私有数据成员,同时保持对数据的完整性和安全性的控制。
(3)构造函数和析构函数
通常情况下,构造函数和析构函数也会被声明为 public,以便外部代码可以创建和销毁类的对象。如果构造函数或析构函数被声明为 private 或 protected,则外部代码将无法直接创建或销毁类的对象。
(4)操作符重载
当需要对类的操作符进行重载时,这些重载的操作符函数通常也会被声明为 public。这样,外部代码就可以使用这些操作符与类的对象进行交互。
(5)公共工具函数
类中可能包含一些公共工具函数,这些函数不直接操作类的状态,但提供了与类相关的有用功能。这些函数通常也会被声明为 public,以便外部代码可以使用它们。
(6)继承中的可见性
在类的继承关系中,如果基类的成员函数或数据成员被声明为 public,则它们在派生类中也将是可见的,并且可以通过派生类的对象进行访问。这使得派生类可以继承和重用基类的功能。

3.2 private 访问修饰符

使用 private 修饰符声明的成员函数与成员变量是私有的。当将类的成员标记为 private 时,这意味着这个成员只能在它所属的类内部被访问,而不能从类的外部直接访问:

class Animal
{	
public:Animal() {};~Animal() {};private:void eat(){printf("eat something");}private:string name;
};Animal animal;  
animal.eat(); 		// 错误:不可以访问私有成员函数   
eat.name = "aa"; 	// 错误:不可以访问私有成员变量

private 访问修饰符在编程中有多种应用场景,它主要用于限制类成员的访问权限,以确保数据的安全性和封装性。
以下是一些 private 访问修饰符的应用场景:
(1)封装数据
private 修饰符常用于封装类的内部数据。通过将数据成员声明为私有,可以确保只有类自身的方法能够直接访问和修改这些数据,从而防止外部代码对数据的非法访问和修改。
(2)控制访问
使用 private 修饰符可以控制对类成员的访问,从而实现对数据的保护和访问控制。只有类内部的方法可以访问私有成员,而外部代码则需要通过类提供的公共方法来间接访问和操作这些私有成员。
(3)隐藏实现细节
通过将类的实现细节声明为私有,可以隐藏类的内部实现细节,使得类的使用者只关心类的功能和接口,而不需要了解类的具体实现。这有助于保持类的清晰性和可维护性。

3.3 protected 访问修饰符

protected 访问修饰符在设计继承层次结构时特别有用。它允许派生类访问基类的实现细节,同时仍然保持对这些细节的封装和隐藏。这有助于实现更灵活和可维护的代码结构。
注意 protected 和 private 的区别:
如果其他类从该类派生(无论是公开派生还是私有派生),那么派生类中的成员函数可以访问基类中的protected成员。这是 protected 与private 的区别,因为private成员在派生类中是不可访问的。

class Animal
{	
public:Animal() {};~Animal() {};protected:void eat(){printf("eat something");}protected:string name;
};class Dog : public Animal
{	
public:Dog() {};~Dog() {};public:void dogEat(){   eat(); 				// OK:派生类中可以直接访问基类的 protected 成员函数  name = "aa"; 		// OK:派生类中可以直接访问基类的 protected 成员变量   }protected:string name;
};Dog dog;  
dog.eat(); 			// 错误:不可以访问 protected 成员函数
dog.name = "aa"; 	// 错误:不可以访问 protected 成员变量

protected 访问修饰符的应用场景主要涉及到继承和多层次的对象关系:
(1)封装类层次结构中的状态
如果需要在类层次结构中的多个层次之间共享某些状态信息,但又不想让这些状态信息暴露给类的外部。在这种情况下,可以将这些状态信息声明为 protected,这样它们就可以在类层次结构中的任何层次中被访问和修改。
(2)实现受保护的接口
如果需要定义一个受保护的接口,只有派生类可以实现它。在这种情况下,可以将接口中的方法声明为 protected,这样只有派生类可以覆盖这些方法。
(3)控制数据成员的访问
与 private 修饰符相比, protected 修饰符提供了更灵活的数据成员访问控制。有时,可能需要派生类能够直接访问或修改数据成员,但又不想让类的外部代码这样做。在这种情况下,可以将数据成员声明为 protected 。

3.4 访问修饰符权限总结

本类继承类其他
private××
protected×
public

4 类的构造函数与析构函数

C++ 类的构造函数和析构函数是特殊的成员函数,它们在创建和销毁类的对象时自动执行。

4.1 构造函数

根据构造函数的参数列表和特性,可以将构造函数分为几种不同的类型。以下是 C++ 中常见的构造函数:

4.1.1 默认构造函数

默认构造函数是一种没有参数的构造函数。如果类中没有定义任何构造函数,编译器会自动生成一个默认构造函数。如果类定义了其他构造函数,但没有定义默认构造函数,编译器就不会自动生成默认构造函数,如下为样例代码:

class Animal1
{
};class Animal2
{
public:Animal2(string name) {}
};Animal1 animal1;		// OK:类中没有定义任何构造函数,编译器会自动生成一个默认构造函数 Animal2 animal2;		// 错误:类定义了其他构造函数( Animal2(string name) ),但没有定义默认构造函数,编译器就不会自动生成默认构造函数 
Animal2 animal2("aa");	// OK:

4.1.2 参数化构造函数

参数化构造函数是带有参数的构造函数。它可以有一个或多个参数,用于在创建对象时初始化对象的成员变量。如下为样例代码:

class Animal
{
public:Animal(string name) {}
};Animal animal("aa");	// OK:

4.1.3 拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它使用一个已存在的对象来初始化新创建的对象。它的参数是对同类型对象的常量引用。如果类没有显式定义拷贝构造函数,编译器会提供一个默认的拷贝构造函数。如下为样例代码:

#include <iostream>  
#include <string>  using namespace std;class Animal
{
public:Animal() {printf("call Animal()\n");}Animal(const Animal& animal){printf("call Animal(const Animal& animal)\n");}
};int main() {Animal animal1;				// 调用无参数的构造函数Animal animal2(animal1);	// 调用拷贝构造函数return 0;
}

上面代码的输出为:

call Animal()
call Animal(const Animal& animal)

4.1.4 列表初始化构造函数

列表初始化构造函数使用成员初始化列表来初始化对象的数据成员,C++11 的列表初始化特性需要该种类型构造函数的支持。如下为样例代码:

#include <iostream>  
#include <string>  using namespace std;class Animal
{
public:Animal(const string& name) : m_name(name){printf("call Animal(const string& name) : m_name(name)\n");}private:string m_name;
};int main() {		Animal animal{"aa"};	// 调用列表初始化构造函数return 0;
}

上面代码的输出为:

call Animal(const string& name) : m_name(name)

4.1.5 委托构造函数

委托构造函数是一种特殊的构造函数,它调用同类的另一个构造函数来执行初始化。这可以通过使用类名并跟随参数列表来实现。C++11 及以后的版本支持委托构造函数。如下为样例代码:

#include <iostream>  
#include <string>  using namespace std;class Animal
{
public:Animal() : Animal("default"){printf("Animal() : Animal(\"default\")\n");}Animal(const string& name) : m_name(name){printf("call Animal(const string& name) : m_name(name)\n");}private:string m_name;
};int main() {		Animal animal;return 0;
}

上面代码的输出为:

call Animal(const string& name) : m_name(name)
Animal() : Animal("default")

注意:先调用的是委托构造函数。

4.1.6 移动构造函数

移动构造函数是一种特殊的构造函数,它使用右值引用参数将资源从一个对象移动到另一个对象,而不是复制。这通常用于优化性能,特别是在处理如 vector 、 string 等可能包含动态分配资源的类型时。如下为样例代码:

#include <iostream>  
#include <string>  using namespace std;class Animal
{
public:Animal(){printf("call Animal()\n");}Animal(const Animal& animal){printf("call Animal(const Animal& animal)\n");}Animal(Animal&& other) noexcept		//移动构造函数{printf("call Animal(Animal&& other)\n");}
};int main() {		Animal animal1;					// 调用无参数构造函数Animal animal2 = animal1;		// 调用拷贝构造函数Animal animal3 = move(animal1); // 调用移动构造函数return 0;
}

上面代码的输出为:

call Animal()
call Animal(const Animal& animal)
call Animal(Animal&& other)

4.2 析构函数

析构函数是一种特殊的成员函数,它在每次删除所创建的对象时执行。析构函数的名称是在类名前加上一个波浪符( ~ )。析构函数用于执行任何必要的清理任务,如释放对象可能拥有的动态内存或关闭打开的文件等。
析构函数没有返回类型,也没有参数。一个类只能有一个析构函数,并且它不能被重载。当对象的生命周期结束时,析构函数会自动被调用:

#include <iostream>  class Animal
{
public:~Animal()						// 析构函数{printf("call ~Animal()\n");}
};int main() {	{Animal animal;}		// 作用域结束后,在销毁 animal 时自动调用其析构函数return 0;
}

上面代码的输出为:

call ~Animal()

注意,析构函数不应该抛出异常
如果析构函数抛出异常且没有被捕获,程序将调用 std::terminate 并终止执行。这是因为析构函数在对象生命周期结束时被调用,此时对象可能已经不再处于有效状态,因此处理异常可能不安全。

4.3 构造函数与析构函数在 RAII 中的作用

RAII( Resource Acquisition Is Initialization ,资源获取即初始化)是 C++ 语言中的一种管理资源、避免泄漏的惯用法。其核心理念是将资源的获取和释放与对象的构造和析构绑定在一起。这意味着,当一个对象被创建时,它的构造函数会自动获取所需的资源,并在对象被销毁时,其析构函数会自动释放所占用的资源。
首先,构造函数在 RAII 中的作用是在对象创建时获取所需的资源。这通常包括分配内存、打开文件、建立数据库连接等。构造函数的调用是在对象创建时自动发生的,因此它是确保资源正确获取的关键环节。如果资源获取失败,构造函数可以抛出异常来指示错误。
接着,析构函数在RAII中的作用是在对象销毁时释放所占用的资源。这包括释放内存、关闭文件、销毁数据库连接等。与构造函数类似,析构函数的调用也是在对象生命周期结束时自动发生的,这确保了资源的正确释放,从而避免了资源泄漏的问题。析构函数应该仔细管理资源的释放过程,确保不会出现任何错误,并且不应该抛出异常。
通过将资源的获取和释放与对象的构造和析构绑定在一起, RAII 提供了一种简洁、安全、实时的资源管理方式。

5 this 指针

this 是一个特殊的指针,它代表对象自身。this 指针是隐式传递给每个成员函数的,它允许成员函数访问和修改调用它的对象的成员。this 指针在成员函数内部是自动可用的,不需要显式声明。它通常用于区分成员变量和参数名称相同的情况,或者在函数内部引用当前对象的其他成员:

class Animal
{
public:Animal(string name){//name = name;		// 如果这里不使用 this ,则无法分别这个变量 name 是入参还是成员变量this->name = name;}public:string getName(){return this->name;	// 此处的 this 可以用也可以不用}private:string name;
};

在上面的代码中,构造函数 Animal(string name) 和成员函数 getName() 都使用了 this 指针。在构造函数 Animal(string name) 中,this->name表示对象的 name 成员变量,而构造函数的入参也是 name 。使用了 this 指针可以使得代码更加清晰,尤其是在成员变量和参数名称相同或相似的情况下。
需要注意的是,在大多数情况下,this 指针的使用是隐式的,编译器会自动处理。只有在需要区分成员变量和函数参数,或者需要在成员函数中显式引用当前对象时,才需要显式地使用 this 指针。

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

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

相关文章

LeetCode1365之切披萨的方案数(相关话题:二维前缀和,动态规划)

题目描述 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; A &#xff08;表示苹果&#xff09;和 . &#xff08;表示空白格子&#xff09;。你需要切披萨 k-1 次&#xff0c;得到 k 块披萨并送给别人。 切披萨的每一刀&#xf…

vscode开发FPGA(0)--windows平台搭建

一、从官网下载安装VScode Download Visual Studio Code - Mac, Linux, Windows 二、安装配置插件 1. 安装Chinese&#xff08;simplified&#xff09;中文汉化包 2.安装Verilog-HDL/systemVerilog插件(支持verilog语法) 3.配置CTags Support插件(支持代码跳转) 1)在github下…

MySQL篇之定位与优化MySQL慢查询

一、如何定位慢查询 1.方案一&#xff1a;开源工具 调试工具&#xff1a;Arthas。 运维工具&#xff1a;Prometheus 、Skywalking。 2.方案二&#xff1a;MySQL自带慢日志 慢查询日志记录了所有执行时间超过指定参数&#xff08;long_query_time&#xff0c;单位&#xff1a;…

Backtrader 文档学习- Plotting -Plotting on the same axis

Backtrader 文档学习- Plotting -Plotting on the same axis 1.概述 在同一轴上绘图&#xff0c;绘图是在同一空间上绘制原始数据和稍微(随机)修改的数据&#xff0c;但不是在同一轴上。 核心代码&#xff0c;data数据正负50点。 # The filter which changes the close pri…

(50)矩阵对角线元素的和

文章目录 每日一言题目解题思路法一&#xff1a;法二&#xff1a; 代码法一&#xff1a;法二&#xff1a; 结语 每日一言 高山之巅&#xff0c;方见大河奔涌&#xff1b;于群峰之上&#xff0c;更觉长风浩荡。 题目 题目链接&#xff1a;矩阵对角线元素的和 给你一个正方形矩…

力扣热门100题 - 5.最长回文子串

力扣热门100题 - 5.最长回文子串 题目描述&#xff1a;示例&#xff1a;提示&#xff1a;解题思路&#xff1a;&#xff08;动态规划&#xff09;代码&#xff1a; 题目链接&#xff1a;5. 最长回文子串 题目描述&#xff1a; 给你一个字符串 s&#xff0c;找到 s 中最长的回…

[day0] 借着“ai春晚”开个场

1 文思ai笔记-新的开始 今天是2024年2月29日&#xff0c;也是传统农历的除夕夜。早起在ai圈看到一个比较新奇的消息&#xff0c;ai春晚今日举办&#xff0c;竟然有一点小小的激动。这些年确实好久没看过春晚了&#xff0c;自己对于春晚的映像还停留在“白云黑土”、“今天&…

Sklearn、TensorFlow 与 Keras 机器学习实用指南第三版(六)

原文&#xff1a;Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十四章&#xff1a;使用卷积神经网络进行深度计算机视觉 尽管 IBM 的 Deep Blue 超级计算机在 1996 年击败了国际象棋世界冠军…

【51单片机】烧写教程:将代码下载到单片机中(图示&解析)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 这是LCD基本实验中的一部分&#xff0c;完整实验传送门如下&#xff1a;传送门 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是…

初始web服务器(并基于idea来实现无需下载的tomcat)

前言 前面学习了对应的http协议&#xff0c;我们知道了他是在网络层进行数据传输的协议&#xff0c;负责相应数据以及接收数据的规则&#xff0c;但是在人员开发后端的时候不仅仅需要你写io流进行数据传输&#xff0c;还需要你进行对应的tcp协议来进行数据打包发送http协议-CSD…

MySQL运维实战(6)用户认证插件caching_sha2_password

作者&#xff1a;俊达 用户认证及连接错误解决 MySQL用户认证可以使用几种不同的方式&#xff0c;创建用户时可以制定认证方式&#xff1a; create user username% identified with auth_plugin by passwordauth_plugin: mysql_native_password sha256_password caching_sh…

横扫Spark之 - 22个常见的转换算子

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 1. map()2. flatMap()3. filter()4. mapPartitions()5. mapPartitionsWithIndex()6. groupBy()7. distinct()8. coalesce()9. repartition()10. sortBy()11. intersection()12.union()13.…

IT行业有哪些证书含金量高呢?

目录 引言&#xff1a; 一、 计算机网络类证书 二、 数据库管理类证书 三、 安全与信息技术管理类证书 四、 编程与开发类证书 五、 数据科学与人工智能类证书 六、结论&#xff1a; 悟已往之不谏&#xff0c;知来者犹可追 …

c#安全-nativeAOT

文章目录 前记AOT测试反序列化Emit 前记 JIT\AOT JIT编译器&#xff08;Just-in-Time Complier&#xff09;,AOT编译器&#xff08;Ahead-of-Time Complier&#xff09;。 AOT测试 首先编译一段普通代码 using System; using System.Runtime.InteropServices; namespace co…

全栈光量子计算系统公司ORCA宣布收购GXC的集成光子学部门

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨慕一 编译/排版丨沛贤 深度好文&#xff1a;1000字丨8分钟阅读 2024年1月30日&#xff0c;全栈光量子计算系统公司ORCA Computing宣布收购总部位于奥斯汀的GXC集成光子学部门。该部门主…

阿里云服务器租用价格表_2024一年_1个月_1小时收费价格表

2024年阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核4G服…

Flink on k8s之historyServer

1.Flink HistoryServer用途 HistoryServer可以在Flink 作业终止运行&#xff08;Flink集群关闭&#xff09;之后&#xff0c;还可以查询已完成作业的统计信息。此外&#xff0c;它对外提供了 REST API&#xff0c;它接受 HTTP 请求并使用 JSON 数据进行响应。Flink 任务停止后&…

探索设计模式的魅力:代理模式揭秘-软件世界的“幕后黑手”

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 引言 一、魔法世界 1.1 定义与核心思想 1.2 静态代理 1.3 动态代理 1.4 虚拟代理 1.5 代理模式结构图 1.6 实例展示如何工作&#xff08;场景案例&#xff09; 不使用模式实现 有何问题 使用模式重构示例 二、…

STM32 适合人群

STM32 适合各种需要进行嵌入式系统开发的人群&#xff0c;具体如下&#xff1a; 嵌入式系统工程师&#xff1a;嵌入式系统工程师可以使用 STM32 进行系统设计、硬件和软件编程、测试和部署等工作。学生和研究人员&#xff1a;学生和研究人员可以使用 STM32 进行实验、学习和研…

【Java万花筒】实时洞察与智能分析:构建成熟的Java应用程序监控与日志处理方案

全方位监控与可视化&#xff1a;JMX、Spring Boot Admin和Kibana的强大功能与实践技巧 欢迎订阅专栏&#xff1a;Java万花筒 文章目录 全方位监控与可视化&#xff1a;JMX、Spring Boot Admin和Kibana的强大功能与实践技巧前言1. JMX&#xff08;Java Management Extensions&a…