C++Mysql8.0数据库跨平台编程实战(下)

news2024/11/16 21:47:48

C++Mysql8.0数据库跨平台编程实战(下)

  • 第六章 跨平台中文乱码问题和mysql锁
    • 1、MySQLAPIC++封装策略和方法说明
    • windows上字符集gbk和utf8互转
      • 开始写代码把测试框架搭起来
    • linux上字符集GBK和UTF8互转
    • ZPMysql库添加字符集转换函数并测试GBK
      • 插入utf-8的数据
        • 我们把代码在linux运行看看
      • 插入gbk的数据
    • 简易获取数据的接口GetResult实现
    • mysql的表锁和行锁代码示例购票竞争
  • 第七章 日志审计系统项目实战和课程总结
    • 日志审计系统项目模块分析
    • 日志审计系统Agent模块项目
    • 日志审计系统Center模块项目
      • Center模块安装配置和数据初始化
      • Center审计策略表安装和策略添加
      • 完成Center的添加设备
      • Center主循环获取到Agent发送的最新事件


第六章 跨平台中文乱码问题和mysql锁

1、MySQLAPIC++封装策略和方法说明

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我们希望一套代码到处编译,所以这里我们选择了系统的API,系统API也比较简单:
在这里插入图片描述

windows上字符集gbk和utf8互转

我们先说明一下我们怎么测这个案例,就是每次你做一个案例,就要想怎么测。

  • UTF-8到GBK的转换
    第一个就是UTF-8转GBK的话,GBK可以直接在控制台显示,这个跟系统有关,我们系统控制台默认是GBK,所以说UTF-8转GBK很简单,我们直接cout打印就行了;
    那么UTF-8这种编码的字符串从哪里来呢?我们直接把这个代码字符串前面加一个u8就可以了,但这样呢还是会有问题的,并不是说很兼容;我们直接把代码文件设成utf-8的,但是有的机器上这样设置后,当编译成字符串的时候还是GBK,也就是说它编译的时候做了转换;
    所以这个时候,我们比较靠谱的方法就是说,在字符串前面加一个u8,例如u8"我这个是utf-8的字符串",告诉编译器我们要把所标识的这个字符串转成utf-8,就跟你在linux当中编译的时候指定这个代码用什么编译一样。

  • GBK到UTF-8的转换
    我们默认的就是GBK,你不加u8,并且把代码转成GBK的,把我们的代码文件转成GBK的,然后再把把转化成UTF-8的;
    而UTF-8怎么测呢,打印是输出不了的,在Linux当中可以输出(linux默认输出是utf-8的),在windows当中不行,那怎么办呢?几个方案:
    (1)把UTF-8写到文件里面去;
    (2)我们前面不是做了UTF-8转GBK么,我们再转一遍把它输出就可以了。

开始写代码把测试框架搭起来

在这里插入图片描述

在这里插入图片描述

我们可以看到控制台默认是GBK的。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

有的vs版本(例如vs2017)的默认编码是UTF-8的,可以从上图看到,我们这里的vs2019默认编码是GBK的。

当然你可以基于其他的工具(例如notepad++、UltraEdit推荐):
在这里插入图片描述

我们把代码换成ANSI编码的话,代码里面的中文注释都成乱码了:
在这里插入图片描述

我们可以点击下面的菜单:转为ANSI编码,就可以把代码转为ANSI编码格式了。

// test_gbk_utf8.cpp
//

#include <iostream>
#include <string>
#include <windows.h>

using namespace std;

string UTF8ToGBK(const char* data)
{
	string gbk = "";

	// 1. UTF-8转为unicode		其实unicode对windows来说呢就是utf-16,就是用宽字节来存储的
	
	// 1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_UTF8,	// 转换的格式
						0,			// 默认的转换方式
						data,		// 输入的字节数据
						-1,			// 输入的字符串大小 -1就是找\0结束
						nullptr,	// 输出
						0// 输出的空间大小
		);
	if (len <= 0)
		return gbk;
	wstring udata;
	udata.resize(len);
	// 转换为unidoce了
	MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);

	// 2. unicode转GBK
	// 2.1 统计转换后的字节数
	len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, nullptr, 0, 
		nullptr,	// 失败默认替代字符集,0的话我们就把它截断掉了,因为我们的字符串都是以\0结尾的
		0		// 是否使用默认替代
	);
	if (len <= 0)
		return gbk;
	gbk.resize(len);
	WideCharToMultiByte(CP_ACP, 0, (LPWSTR)udata.data(), -1, (char*)gbk.data(), len, nullptr, 0);

	return gbk;
}

string GBKToUTF8(const char* data)
{
	string utf8 = "";

	// GBK转unicode
	// 1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_ACP,	// 转换的格式
		0,			// 默认的转换方式
		data,		// 输入的字节数据
		-1,			// 输入的字符串大小 -1就是找\0结束
		nullptr,	// 输出
		0// 输出的空间大小
	);
	if (len <= 0)
		return utf8;
	wstring udata;
	udata.resize(len);
	// 转换为unidoce了
	MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);

	// 2. unicode转UTF-8
	// 2.1 统计转换后的字节数
	len = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, nullptr, 0,
		nullptr,	// 失败默认替代字符集,0的话我们就把它截断掉了,因为我们的字符串都是以\0结尾的
		0		// 是否使用默认替代
	);
	if (len <= 0)
		return utf8;
	utf8.resize(len);
	WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)udata.data(), -1, (char*)utf8.data(), len, nullptr, 0);

	return utf8;
}

int main()
{
	// 为了保证下面的测试正确,先确保我们的代码是GBK或者ANSI的
	std::cout << "Hello World 测试!\n";

	// 1、测试UTF-8转GBK
	cout << UTF8ToGBK(u8"测试UTF-8转GBK") << endl;

	// 2、测试GBK到UTF-8的转换
	string utf8 = GBKToUTF8("测试GBK转UTF-8再转为GBK");
	cout << "luan ma : utf8 = " << utf8 << endl;
	cout << "GBK = " << UTF8ToGBK(utf8.c_str()) << endl;

	return 0;
}

linux上字符集GBK和UTF8互转

在这里插入图片描述

我们用UE把代码转成UTF-8格式:
在这里插入图片描述
在windows下要选择utf-8(有BOM)。

// test_gbk_utf8_linux makefile

test:test_gbk_utf8_linux.cpp
	g++ $^ -o $@
// test_gbk_utf8.cpp
//

#include <iostream>
#include <string>

#ifdef _WIN32
#include <windows.h>
#else
#include <iconv.h>
#include <string.h>
#endif
using namespace std;

#ifndef _WIN32
static size_t Convert(char* from_cha, char* to_cha, char* in, size_t inLen, char* out, size_t outLen)
{
	// 转换上下文
	iconv_t cd;
	cd = iconv_open(to_cha, from_cha);
	if(cd == 0)
		return -1;	// 如果字符编码打开失败,直接返回-1
	memset(out, 0, outlen);
	char** pin = &in;
	char** pout = &out;
	cout << "in = " << in << endl;
	cout << "inLen = " << inLen << endl;
	cout << "outLen = " << outLen << endl;
	// 返回转换字节的数量,但是转GBK时经常不正确 >=0就成功
	size_t re = iconv(cd, pin, &inLen, pout, &outLen);
	if(re < 0)
	{
		cout << "iconv failed! re = " << (int)re << endl;
		return -1;
	}
	cout << "iconv success! re = " << (int)re << endl;

	if(cd != 0)
		iconv_close(cd);
	return re;
}
#endif

string UTF8ToGBK(const char* data)
{
	string re = "";

	// 1. UTF-8转为unicode		其实unicode对windows来说呢就是utf-16,就是用宽字节来存储的
#ifdef _WIN32	
	// 1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_UTF8,	// 转换的格式
						0,			// 默认的转换方式
						data,		// 输入的字节数据
						-1,			// 输入的字符串大小 -1就是找\0结束
						nullptr,	// 输出
						0// 输出的空间大小
		);
	if (len <= 0)
		return re;
	wstring udata;
	udata.resize(len);
	// 转换为unidoce了
	MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len);

	// 2. unicode转GBK
	// 2.1 统计转换后的字节数
	len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, nullptr, 0, 
		nullptr,	// 失败默认替代字符集,0的话我们就把它截断掉了,因为我们的字符串都是以\0结尾的
		0		// 是否使用默认替代
	);
	if (len <= 0)
		return re;
	re.resize(len);
	WideCharToMultiByte(CP_ACP, 0, (LPWSTR)udata.data(), -1, (char*)re.data(), len, nullptr, 0);
#else
	// linux部分
	re.resize(1024);
	int inLen = strlen(data);
	Convert((char*)"utf-8", (char*)"gbk", (char*)data, inLen, (char*)re.data(), re.size());
	int outLen = strlen(re.data());
	re.resize(outLen);
#endif
	return re;
}

string GBKToUTF8(const char* data)
{
	string re = "";
#ifdef _WIN32
	// GBK转unicode
	// 1.1 统计转换后的字节数
	int len = MultiByteToWideChar(CP_ACP,	// 转换的格式
		0,			// 默认的转换方式
		data,		// 输入的字节数据
		-1,			// 输入的字符串大小 -1就是找\0结束
		nullptr,	// 输出
		0// 输出的空间大小
	);
	if (len <= 0)
		return re;
	wstring udata;
	udata.resize(len);
	// 转换为unidoce了
	MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len);

	// 2. unicode转UTF-8
	// 2.1 统计转换后的字节数
	len = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, nullptr, 0,
		nullptr,	// 失败默认替代字符集,0的话我们就把它截断掉了,因为我们的字符串都是以\0结尾的
		0		// 是否使用默认替代
	);
	if (len <= 0)
		return re;
	re.resize(len);
	WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)udata.data(), -1, (char*)re.data(), len, nullptr, 0);
#else
	// linux部分
	re.resize(1024);
	int inLen = strlen(data);
	Convert((char*)"gbk", (char*)"utf-8", (char*)data, inLen, (char*)re.data(), re.size());
	int outLen = strlen(re.data());
	re.resize(outLen);
#endif
	return re;
}

int main()
{
	// 为了保证下面的测试正确,先确保我们的代码是GBK或者ANSI的
	std::cout << "Hello World 测试!\n";

	// 1、测试UTF-8转GBK
	//string gbk = UTF8ToGBK(u8"测试UTF-8转GBK");
	//cout << "gbk = " << gbk << endl;
	//cout << GBKToUTF8(gbk.c_str()) << endl;

	string ascii_string = "测试UTF-8转GBK";
	string utf8_string = GBKToUTF8(ascii_string.c_str());
	cout << "输入 utf = " << utf8_string << endl;
	string gbk = UTF8ToGBK(utf8_string.c_str());
	cout << "gbk = " << gbk << endl;
	cout << GBKToUTF8(gbk.c_str()) << endl;

	// 2、测试GBK到UTF-8的转换
	//string utf8 = GBKToUTF8("测试GBK转UTF-8再转为GBK");
	//cout << "luan ma : utf8 = " << utf8 << endl;
	//cout << "GBK = " << UTF8ToGBK(utf8.c_str()) << endl;

	system("pause");

	return 0;
}

ZPMysql库添加字符集转换函数并测试GBK

我们这边字符集转换主要涉及两方面的内容:插入和读取。

插入utf-8的数据

在这里插入图片描述

我们把代码在linux运行看看

// ZPMysql makefile

testZPMysql:test_ZPMysql.cpp libZPMysql.so
	g++ test_ZPMysql.cpp -L./ -lZPMysql -o $@ -g
libZPMysql.so:ZPData.cpp ZPMysql.cpp ZPData.h ZPMysql.h
	g++ -fPIC -shared -g $^ -I/usr/include/mysql/ -lmysqlclient -o $@
run:
	./testZPMysql
install:
	@cp libZPMysql.so /usr/lib/
	@echo "install libZPMysql.so success!"
uninstall:
	@rm -rf /usr/lib/libZPMysql.so
	@echo "uninstall libZPMysql.so success!"
clean:clear
	@echo "clear project success!"
clear:
	@rm -rf *.o *.so testZPMysql
	@echo "clear project success!"

上述makefile执行输出:
g++ -fPIC -shared ZPData.cpp ZPMysql.cpp ZPMysql.h ZPData.h -o libZPMysql.so -I/usr/include/mysql -lmysqlclient
g++ ./test_ZPMysql/test_ZPMysql.cpp -o test_ZPMysql -I./ -lZPMysql -L./
cp libZPMysql.so /usr/lib
install libZPMysql.so success!
./test_ZPMysql

在linux当中我们也测试成功,这样的话,我们同一份代码在两个系统都已经插入成功。

插入gbk的数据

utf8在各个平台通用,但是gbk数据在linux当中就没有了(无法正常显示);
这里我们先插入,等有问题了再来解决。
在这里插入图片描述

在linux当中我们测试发现是乱码,因为linux这边是当做utf-8的,要插入的字段name是gbk的,你把utf-8插进去肯定是乱码;
所以在linux当中我们要做个转换,把utf-8转换成gbk。

在这里插入图片描述

在ZPData.cpp中,把前面我们写的UTF8ToGBK和GBKToUTF8这两个函数的代码粘贴过来:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我们查询数据库发现显示没问题。

我们来编写从数据库中获取数据的代码:
在这里插入图片描述

在linux当中因为name字段存的是gbk的,所以获取后不能正常显示。

我们修改代码,可以判断是否是在linux当中,如果在linux当中我们要做个转换才能正常输出:
在这里插入图片描述

这样在windows和linux当中测试都没有问题。

在这里插入图片描述

我们可以看到在控制台中的utf8输出是乱码,这是因为控制台的编码是GBK的,所以我们在windows当中的时候需要转换,而在linux当中就不需要转换了,因为linux是直接支持utf-8显示的。
在这里插入图片描述

在这里插入图片描述

这样我们就完成了对于中文字符的UTF-8和GBK之间的互相转换,插入和读取功能就做完了。

简易获取数据的接口GetResult实现

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

经测试我们发现没有输出BLOG,说明我们FetchRow的时候没有把类型保存起来(为了性能的话可以在StoreResult里面保存)。

在这里插入图片描述

在这里插入图片描述

mysql的表锁和行锁代码示例购票竞争

mysql的锁一般只是针对我们做事务的时候才会用到,最常见的用法,比方说订票,就是你不能保证你这次操作是原子操作,因为订票是两个操作的,第一步先查这个票有没有售完,第二步把这张票标识为已售完。

在这里插入图片描述

行锁,我们用事务来演示,开两个线程来演示,或者让我们程序运行两遍。


    // 订票模拟(事务) t_tickets(id int, sold int)
    sql = "CREATE TABLE IF NOT EXISTS `t_tickets` \
        (`id` INT AUTO_INCREMENT, \
        `sold` INT, \
        PRIMARY KEY(`id`))";
    my.Query(sql.c_str());
    // 这里不能清空数据(因为我们模拟行锁,要运行两遍程序,两个程序共享这张表)
    //my.Query("TRUNCATE `t_tickets`");

    {
        XDATA data;
        data["sold"] = "0";     // 0是未售出
        my.Insert(data, "t_tickets");   // id=1
    
	// 取这张票,并且把这张票的标识添加进来
		my.StartTransaction();
		// 我们先看不锁的情况
		XROWS rows = my.GetResult("select * from t_tickets where sold=0 order by id");
        string id = rows[0][0].data;
		cout << "Buy ticket id is " << id << endl;

        // 模拟冲突(10秒钟之后我们更新这张票)
        this_thread::sleep_for(10s);
        data["sold"] = "1";
        string where = "where id = ";
        where += id;
        cout << my.Update(data, "t_tickets", where) << endl;
        cout << "Buy ticket id " << id << "success!" << endl;
		//my.GetResult("select * from t_tickets where sold=0 for updata");
		my.Commit();
		my.StopTransaction();

    }

    cout << endl;
    // 清理资源
    my.Close();
    cout << "test_ZPMysql!" << endl;

    getchar();

在这里插入图片描述

我们可以看到,两个人买同一张票都成功了!这就很有问题了,而且第二个人执行Update修改票的状态的时候是失败的(Update输出是0)。

在这里插入图片描述

在这里插入图片描述

我们可以看到第二个人阻塞在那里,就在那里等着,无法查询。

在这里插入图片描述

第一个人购买2号票成功后,第二个人查询的票号是3,第二个人购票成功。

这样的话就使得两者不冲突(判断资源和申请资源不冲突),我们就做了这样一个行锁,锁住这张票,

第七章 日志审计系统项目实战和课程总结

日志审计系统项目模块分析

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

日志审计系统Agent模块项目

// agent makefile

agent:agent.cpp XAgent.cpp XAgent.h
	g++ $^ -o $@ -I ../ZPMysql -lZPMysql
	./$@ 127.0.0.1
// ZPMysql makefile

all:libZPMysql.so test_ZPMysql install
	#./test_ZPMysql
libZPMysql.so:ZPData.cpp ZPMysql.cpp ZPData.h ZPMysql.h
	g++ -fPIC -shared $^ -o $@ -I/usr/include/mysql/ -lmysqlclient 
test_ZPMysql:../test_ZPMysql/test_ZPMysql.cpp
	g++ $^ -o $@ -I./ -lZPMysql -L./
install:
	cp libZPMysql.so /usr/lib/
	@echo "install libZPMysql.so success!"
uninstall:
	rm -rf /usr/lib/libZPMysql.so
	@echo "uninstall libZPMysql.so success!"
clean:
	rm -rf *.o *.so test_ZPMysql
	rm -rf /usr/lib/libZPMysql.so
	@echo "clear project success!"

日志审计系统Center模块项目

Center模块安装配置和数据初始化

// center makefile

center:center.cpp XCenter.cpp XCenter.h
	g++ $^ -o $@ -I ../ZPMysql -lZPMysql
	./$@ install 127.0.0.1
clean:
	rm -rf *.o
	rm -rf center

在linux下用makefile的时候,如果你的程序某个函数返回-1的话,make就会认为你的程序出错了,makefile可能会停止,所以我们这里测试的时候还是返回0吧。

Center审计策略表安装和策略添加

在这里插入图片描述

完成Center的添加设备

// center makefile

center:center.cpp XCenter.cpp XCenter.h
	g++ $^ -o $@ -I ../ZPMysql -lZPMysql
	./$@ install 127.0.0.1
	./$@ add 192.168.0.202 fileserver1
	./$@ add 192.168.0.201 fileserver2
clean:
	rm -rf *.o
	rm -rf center

Center主循环获取到Agent发送的最新事件

// center makefile

center:center.cpp XCenter.cpp XCenter.h
	g++ $^ -o $@ -I ../ZPMysql -lZPMysql
	#./$@ install 127.0.0.1
	#./$@ add 192.168.0.202 fileserver1
	#./$@ add 192.168.0.201 fileserver2
	./$@
clean:
	rm -rf *.o
	rm -rf center

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

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

相关文章

Android之Zygote(下)--- SystemServer详解

SystemServer是由zygote.forkSystemServer函数fork出来的子进程&#xff0c;forkSystemServer是一个native函数&#xff0c; /dalvik/vm/native/dalvik_system_Zygote.c static void Dalvik_dalvik_system_Zygote_forkSystemServer(const u4* args, JValue* pResult) {pid_t …

ABAP学习笔记之——第十章:面向对象ALV

一、ALV ALV 是 ABAP List Viewer 的缩写&#xff0c;是实际业务中查询数据或修改数据时经常使用的程序。 1、ALV的主要功能排序功能 (Ascending/Descending); 过滤设置; 变更列宽; 变更布局; ABC 分析; 下载 Excel及 Word 文档的保存。 2、ALV的类型 Function ALV; …

java计算机毕业设计ssm校园疫情防控系统u3669(附源码、数据库)

java计算机毕业设计ssm校园疫情防控系统u3669&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff0…

Docker安装以及容器使用笔记

我们知道容器是一个打包了应用和相关依赖的盒子,那怎么去操控这个盒子呢? 这一篇我通过一个简单的aspnetcore程序来加深对盒子的理解,使用之前先 安装一下Docker的环境。 一:Docker的安装 官方下载地址:Install Docker Engine on CentOS | Docker Documentation ,跟着文…

深度学习——NiN网络模型(笔记)

网络中的网络&#xff08;NiN&#xff09; 1.全连接层的问题&#xff1a;参数多&#xff0c;容易过拟合。 ①卷积层需要的参数较少 ②卷积层后第一个全连接层参数对比 参数过多带来的问题&#xff1a;1.占内存 2.占用计算的带宽多3.容易过拟合 2.NiN为了解决全连接层参数过多的…

20221208英语学习

今日新词&#xff1a; fragment n.碎片&#xff0c;碎块&#xff0c;破片&#xff1b;片段 cynicism n.愤世嫉俗, 玩世不恭, (古希腊的)犬儒哲学, 冷言冷语, 犬儒学派 slight adj.少量的&#xff1b;轻微的&#xff1b;细小的&#xff1b;纤细的 willing adj.愿意, 乐意, 自…

虚拟存储器

虚拟存储器 文章目录虚拟存储器虚拟存储器概述常规存储器管理方式的特征局部性原理虚拟存储器的定义和特征请求分页存储管理方式请求分页中的硬件支持请求分页中的内存分配页面调入策略页面置换算法最佳(Optimal)置换算法先进先出(FIFO)页面置换算法最近最久未使用(LRU)置换算法…

深度学习下的脑机接口BCI究竟有多远?

BCI | ECoG | 脑机接口 LFP | CMRR | 生物计算 随着生命科学、医药研发、数据分析、数据挖掘、LFP、生物计算、靶点发现、基因测序等技术的快速发展&#xff0c;脑科学逐渐出现在人们的视野中&#xff0c;随之而来的脑机接口技术同时得到快速发展。 脑科学是人类社会面临的…

Word处理控件Aspose.Words功能演示:使用 Java 将 Word 文档转换为 HTML

为了将 Word 文档的内容嵌入到您的应用程序中&#xff0c;您可能需要执行转换。在这种情况下&#xff0c;最广泛选择的转换是 Word 到HTML或 Word 到图像。&#xff0c;Aspose API支持流行文件格式处理&#xff0c;并允许将各类文档导出或转换为固定布局文件格式和最常用的图像…

Ubuntu20.04安装各种库----简洁版

目录Eigen3SophusPangolinCeresg2o建议先装anaconda再装ros, python,opencv啥该有的都有了下面仅仅安装ros没有的库Eigen3 作用:线性代数开源库, 提供了有关线性代数、矩阵和矢量运算、数值分析及相关的算法安裝方法: sudo apt-get install libeigen3-dev使用時注意添加頭文件…

性能测试:数据库性能问题实战分析

接口压测分析 现在我们来压测一个获取用户信息接口&#xff0c;这个接口会涉及到数据库的数据查询。我们的项目是部署正在应用服务器上面的&#xff0c;因此我们需要同时监控应用服务器和数据库服务器。 那么下面我们来看一下tomcat的这台服务器&#xff0c;cpu的使用率并不高&…

linux系统怎么安装宝塔面板

linux系统怎么安装宝塔面板 怎么安装宝塔面板&#xff1f;这个其实很简单接下来跟着我操作&#xff1a;以linux centos7.6 举例 Centos安装脚本&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh i…

JavaScript -- 10. 一文了解DOM对象及常用方法

文章目录1. DOM介绍1.1 什么是DOM1.2 概念1.3 关系1.4 HelloWorld1.5 document对象2. DOM节点2.1 元素节点2.1.1 获取已有的元素节点2.1.1 document.getElementById()2.1.2 document.getElementsByClassName()2.1.3 document.getElementsByTagName()2.1.4 document.getElements…

设计模式之简单工厂模式

simple factory design pattern 简单工厂模式的概念、简单工厂模式的结构、简单工厂模式优缺点、简单工厂模式的使用场景、简单工厂模式的实现示例 注&#xff1a;简单工厂模式没有被收录在 GoF 的二十三种设计模式中。 1、简单工厂的概念 简单工厂模式&#xff0c;与其说是设…

32位PCI转CPCI转接板

功能型号 32位PCI转CPCI转接板&#xff0c;调试卡 支持PICMG 2.0 D3.0规范&#xff1b; 支持33MHz速率&#xff1b; 支持32bit总线&#xff1b; 功能描述 1、沉金工艺&#xff0c;接触更好&#xff1b; 2、四层板设计&#xff0c;抗干扰更好&#xff1b; 3、信号线等长处理&…

【论文精读9】MVSNet系列论文详解-AA-RMVSNet

AA-RMVSNet&#xff0c;论文名为&#xff1a;AA-RMVSNet: Adaptive Aggregation Recurrent Multi-view Stereo Network&#xff0c;CVPR2021&#xff08;CCF A&#xff09; 本文是MVSNet系列的第9篇&#xff0c;建议看过【论文精读1】MVSNet系列论文详解-MVSNet之后再看便于理解…

【Java 快速复习】 Java 内存模型 并发问题本质

【Java 快速复习】 Java 内存模型 & 并发问题本质 在 Java 领域&#xff0c;我们经常会说两个名词大家要有所区分&#xff1a; JVM 内存模型&#xff1a;这个所说的是 JVM 内存的划分规则&#xff0c;如 堆、栈、元空间等Java 内存模型&#xff1a;这个所说的是线程和主内…

【计算机网络】应用层

应用层的许多协议都是基于客户服务器方式。 客户和服务器指通信中所涉及的两个应用进程。客户服务器方式描述的是进程之间服务和被服务的关系。客户是服务请求方&#xff0c;服务器是服务提供方。 P2P模式&#xff1a;整个网络中的传输内容不再被保存在中心服务器中&#xff…

怎么裁剪视频?手把手教你裁剪

这两年&#xff0c;随着网课的不断发展&#xff0c;我们可以很轻松的就在网上找到各种课程视频。可是有时候&#xff0c;一些视频里面的重点内容往往只有那几分钟&#xff0c;当我们回顾的时候&#xff0c;需要不断跳转&#xff0c;这就显得有些麻烦。其实我们可以将重点内容裁…

【代码随想录】二刷-回溯算法

回溯算法 《代码随想录》 什么是回溯算法&#xff1f; 回溯算法也可以叫做回溯搜索法&#xff0c;它是一种搜索方式。回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 回溯法的效率: 回溯法的本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案。(n…