C/C++ 通过SQLiteSDK增删改查

SQLite,作为一款嵌入式关系型数据库管理系统,一直以其轻量级、零配置以及跨平台等特性而备受青睐。不同于传统的数据库系统,SQLite是一个库,直接与应用程序一同编译和链接,无需单独的数据库服务器进程,实现了数据库的零配置管理。这种设计理念使得SQLite成为许多嵌入式系统、移动应用和小型项目中的首选数据库引擎。

SQLite的特点包括:

  1. 嵌入式数据库引擎: SQLite 是一个嵌入式数据库引擎,意味着它是一个库,与应用程序一同编译和链接,而不是作为独立的进程运行。
  2. 零配置: 无需配置或管理。SQLite 不需要一个独立的数据库服务器进程,所有的操作都是直接在存储在文件中的数据库上执行。
  3. 轻量级: SQLite 是一个轻量级的数据库,相对于一些其他数据库管理系统来说,它的内存占用和资源消耗相对较小。
  4. 支持 SQL: SQLite 支持大部分标准的 SQL 语法,并提供了事务支持,包括隔离级别和回滚。
  5. 跨平台: SQLite 可以在各种操作系统上运行,包括 Windows、Linux、macOS 和其他嵌入式系统。
  6. 自给自足: SQLite 数据库是一个单一的磁盘文件,整个数据库被存储在一个文件中,这使得备份、复制或传输数据库变得非常容易。
  7. 开源: SQLite 是一个开源项目,采用公共领域授权(Public Domain License),可以在商业和非商业项目中免费使用。

SQLite 数据库以其独特的自给自足特性脱颖而出,整个数据库被存储在一个单一的磁盘文件中,使得备份、复制或传输数据库变得异常简单。而作为一款开源项目,SQLite采用了公共领域授权,可以在商业和非商业项目中免费使用。

  • SQLiteSDK下载:https://download.csdn.net/download/lyshark_csdn/88568197

由于该数据库的小巧和简洁所以在使用上也非常容易,当读者下载好附件以后会看到如下图所示的文件;

使用时只需要将sqlite3.hsqlite3.c文件导入到项目中并使用#include "sqlite3.h"即可,无需做其他配置,图中的sqlite3.dll是动态库,sqlite3.exe则是一个命令行版本的数据库可在测试时使用它。

打开与关闭库

sqlite3_open 用于打开或创建一个 SQLite 数据库文件。该函数的原型如下:

int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
  • filename: 要打开或创建的 SQLite 数据库文件的路径。如果文件不存在,将会创建一个新的数据库文件。
  • ppDb: 用于存储 SQLite 数据库句柄(handle)的指针。SQLite 数据库句柄是与一个打开的数据库关联的结构,它在后续的 SQLite 操作中用作标识。

该函数返回一个整数值,代表函数的执行状态。如果函数成功执行,返回 SQLITE_OK。如果有错误发生,返回一个表示错误代码的整数值。可以通过 sqlite3_errmsg 函数获取更详细的错误信息。

sqlite3_close 用于关闭数据库连接的函数。其原型如下:

int sqlite3_close(sqlite3*);
  • sqlite3: 要关闭的 SQLite 数据库连接的句柄。

该函数返回一个整数值,用于表示函数的执行状态。如果函数成功执行,返回 SQLITE_OK。如果有错误发生,返回一个表示错误代码的整数值。

使用 sqlite3_close 函数可以释放与数据库连接相关的资源,并确保数据库文件被正确关闭。在关闭数据库连接之前,应该确保已经完成了所有需要执行的 SQL 语句,并在需要的情况下检查执行结果。

// 打开数据库并返回句柄
sqlite3* open_database(std::string database_name)
{
  int ref =-1;
  sqlite3 *db = 0;

  ref = sqlite3_open(database_name.c_str(), &db);
  if (ref == SQLITE_OK)
    return db;
  return false;
}

// 关闭数据库
bool close_database(sqlite3 *db)
{
  int ref = sqlite3_close(db);
  if (ref == SQLITE_OK)
    return true;
  return false;
}

执行查询语句

sqlite3_exec 用于执行 SQL 语句的高级接口函数。它的原型如下:

int sqlite3_exec(
  sqlite3* db,                    /* Database handle */
  const char* sql,                /* SQL statement, UTF-8 encoded */
  int (*callback)(                /* Callback function */
    void*,                        /* Callback parameter */
    int,                          /* Number of columns in the result set */
    char**,                       /* Array of column values */
    char**                        /* Array of column names */
  ),
  void* callback_param,           /* 1st argument to callback function */
  char** errmsg                   /* Error msg written here */
);
  • db: SQLite 数据库连接的句柄。
  • sql: 要执行的 SQL 语句,以 UTF-8 编码。
  • callback: 回调函数,用于处理查询结果的每一行数据。
  • callback_param: 传递给回调函数的参数。
  • errmsg: 用于存储错误消息的指针。

sqlite3_exec 函数执行一个或多个 SQL 语句,并对每一条语句的执行结果调用指定的回调函数。回调函数的原型如下:

int callback(
  void* callback_param, /* 参数,由 sqlite3_exec 传递给回调函数 */
  int num_columns,      /* 结果集中的列数 */
  char** column_values,  /* 指向结果集中当前行的列值的数组 */
  char** column_names    /* 指向结果集中列名的数组 */
);
  • callback_param: 回调函数的参数,由 sqlite3_exec 传递给回调函数。
  • num_columns: 结果集中的列数。
  • column_values: 指向结果集中当前行的列值的数组。
  • column_names: 指向结果集中列名的数组。

回调函数返回一个整数,用于指示是否继续执行后续的 SQL 语句。如果回调函数返回非零值,sqlite3_exec 将停止执行 SQL,并立即返回。

sqlite3_prepare_v2 用于准备 SQL 语句的接口函数。它的原型如下:

int sqlite3_prepare_v2(
  sqlite3* db,            /* Database handle */
  const char* sql,        /* SQL statement, UTF-8 encoded */
  int sql_len,            /* Length of SQL statement in bytes, or -1 for zero-terminated */
  sqlite3_stmt** stmt,    /* OUT: Statement handle */
  const char** tail       /* OUT: Pointer to unused portion of SQL statement */
);
  • db: SQLite 数据库连接的句柄。
  • sql: 要准备的 SQL 语句,以 UTF-8 编码。
  • sql_len: SQL 语句的长度,如果为 -1,则表示 SQL 语句以 null 结尾。
  • stmt: 用于存储准备好的语句句柄的指针。
  • tail: 用于存储未使用的 SQL 语句的指针。

sqlite3_prepare_v2 函数用于将 SQL 语句编译成一个 SQLite 语句对象(prepared statement)。这个对象可以被多次执行,每次执行时可以绑定不同的参数。stmt 参数将用于存储编译后的语句的句柄,以供后续的操作。

sqlite3_step 执行预编译 SQL 语句的接口函数。它的原型如下:

int sqlite3_step(sqlite3_stmt*);
  • sqlite3_stmt*: 由 sqlite3_prepare_v2 预编译的 SQL 语句的句柄。

sqlite3_step 函数用于执行由 sqlite3_prepare_v2 预编译的 SQL 语句。在执行过程中,可以通过不断调用 sqlite3_step 来逐行获取查询结果,直到结果集结束。对于非查询语句(如 INSERTUPDATEDELETE),sqlite3_step 函数执行一次即可完成操作。

该函数的返回值表示执行的结果,可能的返回值包括:

  • SQLITE_ROW: 成功获取一行数据。
  • SQLITE_DONE: 执行完成,没有更多的数据可用(用于非查询语句)。
  • 其他错误码,表示执行过程中出现了错误。

sqlite3_column_text 用于获取查询结果集中某一列的文本值。其原型为:

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
  • sqlite3_stmt*: 由 sqlite3_prepare_v2 预编译的 SQL 语句的句柄。
  • int iCol: 列的索引,从0开始。

该函数返回指向字符串值的指针,该字符串值是查询结果集中指定列的文本表示。需要注意的是,返回的指针指向 SQLite 内部的存储区,应该在使用完之后尽早释放资源。

sqlite3_column_int 用于获取查询结果集中某一列的整数值。其原型为:

int sqlite3_column_int(sqlite3_stmt*, int iCol);
  • sqlite3_stmt*: 由 sqlite3_prepare_v2 预编译的 SQL 语句的句柄。
  • int iCol: 列的索引,从0开始。

该函数返回查询结果集中指定列的整数表示。需要注意的是,如果该列不是整数类型,或者包含的数据无法转换为整数,那么返回的结果可能不是有效的整数值。

sqlite3_finalize 用于释放一个预备语句对象(prepared statement)。在使用 sqlite3_prepare_v2 函数准备 SQL 语句后,需要使用 sqlite3_finalize 来释放相应的语句对象。

该函数的原型为:

int sqlite3_finalize(sqlite3_stmt *pStmt);
  • sqlite3_stmt *pStmt: 指向要释放的语句对象的指针。

该函数返回 SQLITE_OK 表示成功,返回其他错误码表示失败。

// 执行SQL语句
bool exec_sql(sqlite3 *db, char *sql)
{
  char *error_code = 0;
  int ref = sqlite3_exec(db, sql, 0, 0, &error_code);
  if (ref == SQLITE_OK)
  {
    return true;
  }
  return false;
}

// 插入数据
bool insert_data(sqlite3 *db, char *sql)
{
  sqlite3_stmt *stmt = 0;

  // 插入前检查语句合法性, -1自动计算SQL长度
  int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
  if (ref == SQLITE_OK)
  {
    sqlite3_step(stmt);       // 执行语句
    sqlite3_finalize(stmt);   // 清理语句句柄
    return true;
  }
  sqlite3_finalize(stmt);
  return false;
}

// 查询数据集
bool select_data(sqlite3 *db, char *sql)
{
  sqlite3_stmt *stmt = 0;

  int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
  if (ref == SQLITE_OK)
  {
    // 每调一次sqlite3_step()函数,stmt就会指向下一条记录
    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
      // 取出第1列字段的值
      const unsigned char *name = sqlite3_column_text(stmt, 1);
      
      // 取出第2列字段的值
      int age = sqlite3_column_int(stmt, 2);
      std::cout << "姓名: " << name << " 年龄: " << age << std::endl;
    }
  }
  else
  {
    sqlite3_finalize(stmt);
    return false;
  }
  sqlite3_finalize(stmt);
  return true;
}

调用查询语句

创建数据库

首先打开了名为 "database.db" 的 SQLite 数据库,并创建了一个名为 "LySharkDB" 的表,该表格包含了id、name、agemsg四个字段。随后,通过执行 SQL 语句创建了这个表格。最后,关闭了数据库连接。这段代码主要用于数据库初始化操作,确保了数据库中包含了指定的表格结构。

int main(int argc, char *argv[])
{
  sqlite3* open_db = open_database("database.db");
  if (open_db != false)
  {
    bool create_table_ref;

    std::string sql = 
      "create table LySharkDB("
      "id int auto_increment primary key,"
      "name char(30) not null," 
      "age int not null,"
      "msg text default null"
      ")";

    // 运行创建表操作
    char run_sql[1024] = { 0 };
    strcpy(run_sql, sql.c_str());
    create_table_ref = exec_sql(open_db, run_sql);
  }

  close_database(open_db);
  std::system("pause");
  return 0;
}

上述代码运行后则可以创建一个数据库database.db表名为LySharkDB读者可以使用数据库工具打开该表,其结构如下所示;

插入数据测试

创建数据库后,接着就是插入数据测试,插入时可以使用insert_data,如下代码项数据库中插入5条记录;

int main(int argc, char *argv[])
{
  sqlite3* open_db = open_database("./database.db");
  if (open_db != false)
  {
    bool create_table_ref;

    // 运行插入记录
    if (create_table_ref == true)
    {
      bool insert_ref = 0;
      insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(1,'lyshark',1,'hello lyshark');");
      insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(2,'guest',2,'hello guest');");
      insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(3,'admin',3,'hello admin');");
      insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(4,'wang',4,'hello wang');");
      insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(5,'sqlite',5,'hello sql');");
      if (insert_ref == true)
      {
        std::cout << "插入完成" << std::endl;
      }
    }
  }
  close_database(open_db);
  std::system("pause");
  return 0;
}

插入后,打开数据库管理软件,可看到插入后的记录;

查询与删除数据

而查询删除与增加记录,我们这里直接使用exec_sql()函数,通过传入不同的SQL语句实现。

int main(int argc, char *argv[])
{
  sqlite3* open_db = open_database("./database.db");
  if (open_db != false)
  {
    // 删除记录
    bool delete_ref = exec_sql(open_db, "delete from LySharkDB where id = 5;");
    if (delete_ref == true)
    {
      std::cout << "删除完成." << std::endl;
    }

    // 更新记录
    bool update_ref = exec_sql(open_db, "update LySharkDB set name='lyshark' where id = 4;");
    if (update_ref == true)
    {
      std::cout << "更新完成." << std::endl;
    }

    // 查询数据
    bool select_ref = select_data(open_db, "select * from LySharkDB;");
    if (select_ref == true)
    {
      std::cout << "查询完毕." << std::endl;
    }
  }
  close_database(open_db);
  std::system("pause");
  return 0;
}

执行更新后的表记录如下所示;

查询区间数据

首先创建一些数据集,这里通过循环生成并插入数据,如下代码中新建一个TimeDB数据表,其中有三个字段uid,host_time,cpu_value

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <time.h>
#include "sqlite3.h"

#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>

using namespace std;
using namespace boost;

// 获取本地时间日期
std::string get_local_datetime()
{
	char ct[80];
	time_t  tt;
	struct tm *tblock;

	tt = time(NULL);
	tblock = localtime(&tt);

	strftime(ct, sizeof(ct), "%Y-%m-%d %H:%M:%S", tblock);
	return ct;
}

// 初始化创建表结构
void Init_Database()
{
	sqlite3* open_db = open_database("./database.db");
	if (open_db != false)
	{
		bool create_table_ref;
		std::string sql =
			"create table TimeDB("
			"uid primary key,"
			"host_time char(128) not null,"
			"cpu_value int not null"
			");";
		char run_sql[1024] = { 0 };
		strcpy(run_sql, sql.c_str());
		exec_sql(open_db, run_sql);
	}
	close_database(open_db);
}

// 批量生成时间字符串并插入数据表
void Insert_Test()
{
	sqlite3* open_db = open_database("./database.db");
	for (int x = 0; x < 1000; x++)
	{
		// 获取本地日期时间
		std::string local_times = get_local_datetime();
		std::string format_string = boost::str(boost::format("insert into TimeDB(uid,host_time,cpu_value) values(%d,'%s',%d);") % x %local_times %x);

		std::cout << "执行SQL: " << format_string << std::endl;

		char run_sql[1024] = { 0 };
		strcpy(run_sql, format_string.c_str());
		insert_data(open_db, run_sql);
		_sleep(1000);
	}
	close_database(open_db);
}

int main(int argc, char *argv[])
{
	sqlite3* open_db = open_database("./database.db");
	Init_Database();
	Insert_Test();

	std::system("pause");
	return 0;
}

如下是五分钟的模拟数据;

当有了数据则再查询,代码中Select_Time_List函数演示了如何通过时间查询一个区间的数据,并返回一个容器列表给被调用者使用,查询代码如下所示;

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <time.h>
#include "sqlite3.h"

#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>

using namespace std;
using namespace boost;

// 打开数据库并返回句柄
sqlite3* open_database(std::string database_name)
{
	int ref = -1;
	sqlite3 *db = 0;

	ref = sqlite3_open(database_name.c_str(), &db);
	if (ref == SQLITE_OK)
		return db;
	return false;
}

// 关闭数据库
bool close_database(sqlite3 *db)
{
	int ref = sqlite3_close(db);
	if (ref == SQLITE_OK)
		return true;
	return false;
}

// 执行SQL语句
bool exec_sql(sqlite3 *db, char *sql)
{
	char *error_code = 0;
	int ref = sqlite3_exec(db, sql, 0, 0, &error_code);
	if (ref == SQLITE_OK)
	{
		return true;
	}
	return false;
}

// 插入数据
bool insert_data(sqlite3 *db, char *sql)
{
	sqlite3_stmt *stmt = 0;

	// 插入前检查语句合法性, -1自动计算SQL长度
	int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
	if (ref == SQLITE_OK)
	{
		sqlite3_step(stmt);       // 执行语句
		sqlite3_finalize(stmt);   // 清理语句句柄
		return true;
	}
	sqlite3_finalize(stmt);
	return false;
}

// 查询数据集
bool select_data(sqlite3 *db, char *sql)
{
	sqlite3_stmt *stmt = 0;

	int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
	if (ref == SQLITE_OK)
	{
		// 每调一次sqlite3_step()函数,stmt就会指向下一条记录
		while (sqlite3_step(stmt) == SQLITE_ROW)
		{
			// 取出第1列字段的值
			const unsigned char *name = sqlite3_column_text(stmt, 1);

			// 取出第2列字段的值
			int age = sqlite3_column_int(stmt, 2);
			std::cout << "姓名: " << name << " 年龄: " << age << std::endl;
		}
	}
	else
	{
		sqlite3_finalize(stmt);
		return false;
	}
	sqlite3_finalize(stmt);
	return true;
}

// 获取本地时间日期
std::string get_local_datetime()
{
	char ct[80];
	time_t  tt;
	struct tm *tblock;

	tt = time(NULL);
	tblock = localtime(&tt);

	strftime(ct, sizeof(ct), "%Y-%m-%d %H:%M:%S", tblock);
	return ct;
}

// 初始化创建表结构
void Init_Database()
{
	sqlite3* open_db = open_database("./database.db");
	if (open_db != false)
	{
		bool create_table_ref;
		std::string sql =
			"create table TimeDB("
			"uid primary key,"
			"host_time char(128) not null,"
			"cpu_value int not null"
			");";
		char run_sql[1024] = { 0 };
		strcpy(run_sql, sql.c_str());
		exec_sql(open_db, run_sql);
	}
	close_database(open_db);
}

// 批量生成时间字符串并插入数据表
void Insert_Test()
{
	sqlite3* open_db = open_database("./database.db");
	for (int x = 0; x < 1000; x++)
	{
		// 获取本地日期时间
		std::string local_times = get_local_datetime();
		std::string format_string = boost::str(boost::format("insert into TimeDB(uid,host_time,cpu_value) values(%d,'%s',%d);") % x %local_times %x);

		std::cout << "执行SQL: " << format_string << std::endl;

		char run_sql[1024] = { 0 };
		strcpy(run_sql, format_string.c_str());
		insert_data(open_db, run_sql);
		_sleep(1000);
	}
	close_database(open_db);
}

// 查询时间区间并返回 传入开始时间与结束时间,过滤出特定的记录
bool Select_Time_List(sqlite3 *db, std::vector<std::map<std::string, int>> &time_ref, std::string start_time, std::string end_time)
{
	sqlite3_stmt *stmt = 0;
	std::string format_string = boost::str(boost::format("select * from TimeDB where host_time >= '%s' and host_time <= '%s';") % start_time %end_time);

	char run_sql[1024] = { 0 };
	strcpy(run_sql, format_string.c_str());

	int ref = sqlite3_prepare_v2(db, run_sql, -1, &stmt, 0);
	if (ref == SQLITE_OK)
	{
		while (sqlite3_step(stmt) == SQLITE_ROW)
		{
			std::map < std::string, int > ptr;

			// 取出第一个和第二个字段
			const unsigned char *time_text = sqlite3_column_text(stmt, 1);
			const int cpu_value = sqlite3_column_int(stmt, 2);

			// 放入一个map容器中
			ptr[boost::lexical_cast<std::string>(time_text)] = cpu_value;
			time_ref.push_back(ptr);
		}
		sqlite3_finalize(stmt);
		return true;
	}
	sqlite3_finalize(stmt);
	return false;
}

int main(int argc, char *argv[])
{
	sqlite3* open_db = open_database("./database.db");
	//Init_Database();
	//Insert_Test();

	// 查询 2023-11-25 19:52:31 - 2023-11-25 19:53:35 区间内的所有的负载情况
	std::vector<std::map<std::string, int>> db_time;
	bool is_true = Select_Time_List(open_db, db_time, "2023-11-25 19:52:31", "2023-11-25 19:53:35");
	if (is_true == true)
	{
		for (int x = 0; x < db_time.size(); x++)
		{
			// 输出该区间内的数据
			std::map < std::string, int>::iterator ptr;
			for (ptr = db_time[x].begin(); ptr != db_time[x].end(); ptr++)
			{
				std::cout << "时间区间: " << ptr->first << " CPU利用率: " << ptr->second << std::endl;
			}
		}
	}
	std::system("pause");
	return 0;
}

例如代码中我们查询2023-11-25 19:52:31 - 2023-11-25 19:53:35这个区间内的数据信息,并返回一个map容器给被调用者,运行效果如下所示;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[LaTex]arXiv投稿攻略——jpg/png转pdf

一、将图片复制进ppt&#xff0c;右键单击图片选择设置图片格式&#xff0c;获取图片高度和宽度 二、选择“设计-幻灯片大小-自定义幻灯片大小” 三、设置幻灯片大小为图片大小 四、 选择“最大化” 五、 检查幻灯片大小是否与图像大小一致 六、导出为PDF

Doris单机部署——2.0.1.1版本

目录 一、前期准备工作 1.设置系统最大文件打开句柄数 2.时钟同步 3.关闭每台机器的交换分区 4.下载安装包 二、单节点部署安装Doris (一)安装fe 1.解压改名 2.修改配置文件 3.创建元数据目录 4.启动fe 5.访问fe的webUI (二)安装be 1.进入be目录下&#xff0c;修…

紫光展锐 展讯芯片 展讯处理器解锁BL 各分区结构 ROM 分区列表代表什么 bin img 表示什么意思

是展锐 Android 10.0、Android 9.0 平台 ROM 空间划分情况以及分区格式、分区大小和分区功能的 初步描述。 prodnv 开机后系统中的 productinfo 分区&#xff0c;保 存 adc 校准参数、eng.db 数据库。 Miscdata 保存 ota、recovery 时的一些数据 recovery 存放 recovery.i…

【数据中台】开源项目(1)-LarkMidTable

LarkMidTable 是一站式开源的数据中台&#xff0c;实现中台的 基础建设&#xff0c;数据治理&#xff0c;数据开发&#xff0c;监控告警&#xff0c;数据服务&#xff0c;数据的可视化&#xff0c;实现高效赋能数据前台并提供数据服务的产品。 系统演示地址 &#xff1a; www.l…

Simulink 的代数环

代数环, 就是由于模型的输出反馈到模块或子系统先的某个输入端, 如果这个输入是直接馈入的, 那么二者在同一个采样点内需得到求解, 但又互相依赖, 哪一方都不能完成求解过程, 使得解算器无法解算导致错误产生, 这样的情况称为代数环。 一旦 Simulink 遇到代数环, 将根据 Confi…

交换机配置与管理

文档以国产迈普交换机为例&#xff0c;各厂家交换机配置有少许不同&#xff0c;仅供参考。 交换机命令行模式&#xff1a; 普通用户模式Hostname>&#xff08;&#xff09; exit 输入enable命令 特权用户模式Hostname#&#xff08;&#xff09; exit 输入configu…

BrokerChain

BrokerChain: A Cross-Shard Blockchain Protocol for Account/Balance-based State Sharding 我总感觉这篇文章不完整&#xff0c;缺少一些东西。或者说有些地方并没有详细说。比如状态图的构建&#xff0c;网络重分片的的配置过程。都直接忽略了。 Motivation 1 跨片交易不…

Adversarial Attack on Graph Structured Data(2018 PMLR)

Adversarial Attack on Graph Structured Data----《图结构数据的对抗攻击》 摘要 基于图结构的深度学习已经在各种应用中显示出令人兴奋的结果。然而&#xff0c;与图像或文本对抗攻击和防御的大量研究工作相比&#xff0c;此类模型的鲁棒性却很少受到关注。在本文中&#xf…

【漏洞复现】Array VPN任意文件读取漏洞

漏洞描述 华耀(中国)科技有限公司(简称:Array)于2003年创建于北京,是优秀的网络功能平台解决方案提供商,也是应用交付解决方案、移动应用接入(SSL VPN)解决方案的全球领导者。华耀现有员工200余人,其中研发团队占到100余人,总部位于北京。并在北京、上海、广州、杭…

知识点小总结

‘Integer(int)‘ 已经过时了 https://blog.csdn.net/qq_43116031/article/details/127793512 解决Java中的“找不到符号“错误 解决Java中的“找不到符号“错误_java: 找不到符号_很酷的站长的博客-CSDN博客 可右键打开 错误: 编码 UTF-8 的不可映射字符 错误: 编码 UTF-8 …

1603. 整数集合划分(2016年408数据结构算法题)

一、题目 1603. 整数集合划分https://www.acwing.com/problem/content/description/1605/ 二、算法的基本设计思想 由题意知&#xff0c;将最小的 个元素放在 中&#xff0c;其余的元素放在 中&#xff0c;分组结果即可满足题目要求。仿照快速排序的思想&#xff0c;基于枢…

面向对象编程:Rust的面向对象特性

欢迎关注我的公众号lincyang新自媒体&#xff0c;回复关键字【程序员经典书单】&#xff0c;领取程序员的100本经典书单 大家好&#xff01;我是lincyang。 今天我们将深入探讨Rust语言中的面向对象编程&#xff08;OOP&#xff09;特性&#xff0c;并将其与其他流行编程语言进…

C语言之指针知识点总结

C语言之指针知识点总结 文章目录 C语言之指针知识点总结1. 初识指针1.1 取地址操作符 &1.2 指针变量1.3 解引用操作符 *1.4 指针变量1.4.1 大小1.4.2 指针类型的意义 1.5 void*指针1.6 const关键字1.61 const修饰变量1.6.2 const修饰指针变量 1.7 指针的运算1.7.1 指针-整数…

微信小程序便民小工具源码

微信小程序便民小工具源码,包含身材计算&#xff0c;房贷计算器&#xff0c;工资计算器&#xff0c;血型计算器&#xff0c;进制计算器&#xff0c;量角器&#xff0c;计数器等便民工具。 微信扫一扫即可预览 微信扫一扫即可预览 下载链接:https://www.ym4j.com/program/7525

(二) Windows 下 Sublime Text 3 安装离线插件 Anaconda

1 下载 Sublime Text 3 免安装版 Download - Sublime Text 2 下载 Package Control&#xff0c;放到 Sublime Text Build 3211\Data\Installed Packages 目录下。 Installation - Package Control 3 页面搜索 anaconda anaconda - Search - Package Control Anaconda - Pac…

4. 标准 IO 库

4. 标准 IO 库 1. 标准 IO 简介2. FILE 指针3. 标准输入、标准输出和标准错误4. fopen() 和 flose()5. fread() 和 fwrite()6. fseek 定位7. 检查或复位状态7.1 feof()7.2 ferrof()7.3 clearerr() 8. 格式化 IO8.1 格式化输出8. 2 格式化输入 9. IO 缓冲9.1 文件 IO 的内核缓冲…

坚鹏:中国人寿临沂公司当下中国经济形势与寿险业发展机遇培训

中国人寿保险&#xff08;集团&#xff09;公司属国家大型金融保险企业&#xff0c;2016年中国人寿入主广发银行&#xff0c;开启保险、投资、银行三大板块协同发展新格局。2022年&#xff0c;集团公司合并营业收入站稳万亿平台&#xff1b;合并总资产突破6万亿元大关。中国人寿…

数据结构与算法Java版本单元测验题

1.【实验题 2-2】实现以下对单链表的操作&#xff0c;题意和算法描述见《习题解答》图 2-7。 //将单链表 list 逆转&#xff0c;将各结点的 next 指向其前驱。泛型方法&#xff0c;返回值类型前声明类型参数 T public static void reverse(SinglyList list) 【思考题 2-6】实现…

MySQL进阶知识

目录 MySQL的Linux安装 存储引擎 MySQL的体系结构 存储引擎简介 存储引擎特点 InnoDB 逻辑存储结构 MyISAM Memory 对比 存储引擎选择 索引 介绍 索引结构 BTree索引 Hash索引 索引分类 索引语法 SQL性能分析 SQL执行频率 慢查询日志 profile详情 expla…

VUE简易购物车程序

目录 效果预览图 完整代码 效果预览图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…