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

Linux嵌入式系统SQlite3数据库学习笔记

前言

SQlite3是一个轻量级、嵌入式的关系型数据库管理系统,其中具有的核心特点:

1:嵌入式数据库:无需独立服务器进程,数据库直接嵌入到应用程序中。

2:单文件存储:整个数据库存储为单个文件(.db或.sqlite后缀),便于移植和备份。

3:跨平台:支持 Windows、Linux、macOS、iOS、Android 等系统。

相比于MySQl/PostgreSQL等数据库具有轻量级操作简单的优点。

一、数据库安装

可以直接使用命令安装

# 更新软件源
sudo apt update# 安装 SQLite3 命令行工具和库
sudo apt install sqlite3# 可选:安装开发头文件(用于编程开发)
sudo apt install libsqlite3-dev

也可以直接去下载对应的安装包本地编译

wget https://www.sqlite.org/2024/sqlite-autoconf-3440200.tar.gz
tar xvfz sqlite-autoconf-*.tar.gz
cd sqlite-autoconf-*/# 编译安装
./configure
make
sudo make install

安装的话是比较简单的,毕竟是轻量级的数据库。

二、数据库使用方法

1:创建数据库

sqlite3 xxxx.db //创建数据库

创建完数据库后进入数据库后开头就是sqlite>这样的

然后对数据库的操作的相关指令

.open filename -- 打开文件
.show -- 显示SQKite命令提示符的默认设置
.q -- 退出
.databases -- 显示数据库
.help -- 帮助
.dump --导入导出数据库
.tables -- 查看表

2.数据类型

Sqlite3的主要数据类型

除了这些主要的数据类型之外还有别的数据类型

3.创建表

前面已经创建了数据库和知道了有那些数据类型,那么接下来就该进行数据库的核心操作“增删改查”。

创建表的话有两种方式一种是使用标准的SQL语句另外一种是使用对应的API接口函数,我看了很多文章很多博主是分开进行介绍的其本质还是一样的。

标准SQL语句

CREATE TABLE Filename (列名 数据类型 ...)

API接口函数

对于SQlite3数据库的基本使用的话就三个核心API接口函数

1:打开数据库

函数原型:

SQLITE_API int sqlite3_open(const char *filename,   /* Database filename (UTF-8) */sqlite3 **ppDb          /* OUT: SQLite db handle */
);

参数说明:

const char *filename:指向要打开的数据库文件名的字符串,可以带路径。

sqlite3 **ppDb:是一个指向SQlite的结构体的二级指针

函数返回值:

  1. 成功开发返回SQLITE_OK(0)。
  2. 失败返回错误码

补充说明:

SQLITE_API int sqlite3_open16(const void *filename,   /* Database filename (UTF-16) */sqlite3 **ppDb          /* OUT: SQLite db handle */
);
SQLITE_API int sqlite3_open_v2(const char *filename,   /* Database filename (UTF-8) */sqlite3 **ppDb,         /* OUT: SQLite db handle */int flags,              /* Flags */const char *zVfs        /* Name of VFS module to use */
);

2:SQL语句执行函数

函数原型:

SQLITE_API int sqlite3_exec(sqlite3*,                                  /* An open database */const char *sql,                           /* SQL to be evaluated */int (*callback)(void*,int,char**,char**),  /* Callback function */void *,                                    /* 1st argument to callback */char **errmsg                              /* Error msg written here */
);

函数参数:

sqlite3*:一个打开的数据库连接指针。

const char *sql:要执行的 SQL 语句字符串。可以是单个 SQL 语句或多个 SQL 语句的序列,以分号分隔。

int (*callback)(void*,int,char**,char**):回调函数,每当执行一个查询语句并返回结果时,这个回调函数会被调用。如果不需要处理查询结果,可以设置为 NULL。

void *:用户提供的指针,可以在回调函数中使用,通常用于传递上下文信息。

char **errmsg:如果发生错误,这个指针将被设置为指向一个包含错误信息的字符串。

函数返回值:

  1. 成功返回SQLITE_OK(0)。
  2. 失败返回错误码

3:关闭数据库

SQLITE_API int sqlite3_close(sqlite3*);

函数参数:

数据库链接指针。

这三个函数就是SQLite3的基本API接口函数。可以直接使用SQL语句来进行相关的表操作,其本质与直接使用SQl语句操作数据库是一样的。除此之外还有一些高级用法。

创建表格的基础用法程序示例:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>//打开数据库函数示例
int main(int argc,char * argv[])
{sqlite3 *db;char *mang = 0;int rc;char *err_msg = 0;//1:连接数据库rc = sqlite3_open("./test.db",&db);//打开当前目录下的数据库if(rc){//非0表示打开失败fprintf(stderr,"Can't open database: %s\n",sqlite3_errmsg(db));}else{//打开成功fprintf(stderr,"Opened database successfully\n");}//2:创建表/*构建SQLstatement创建一个名为files的表一共三列分别为:FILENAME DATE SIZE数据类型分别为:文本字符串 文本字符串 无符号整形*/// 创建表的 SQL 语句const char *sql = "CREATE TABLE IF NOT EXISTS files (""FILENAME TEXT PRIMARY KEY,""DATE TEXT NOT NULL,""SIZE INTEGER NOT NULL);";//执行SQL命令创建表rc = sqlite3_exec(db,sql,0,0,&err_msg);if( rc != SQLITE_OK ){fprintf(stderr, "SQL error: %s\n", err_msg);sqlite3_free(err_msg);}else{fprintf(stdout, "Table created successfully\n");}sqlite3_close(db);//关闭数据库return 0;
}

查看上面的SQL语句做一下解释说明:

观察上面的写法可以看到其中处理规范中的内容多了一些:PRIMARY KEY、NOT NULL。

这些在sqlite3数据库中叫做约束,表中的每一列都有一些限制属性,这些限制属性就叫做约束。

这些约束在表中根据具体情况来使用。

4:插入数据

上面介绍的示例使用的SQL语句使用法,在表中插入数据当然也可以使用这个方法,

语法一:insert into 表名 (字段名称) values (值名称)。

例如:insert into user (id,age) values (1,10)。

语法二:insert into 表名 values(值 1,值 2,...)。

例如:insert into user values(3,"wang",11)。

经过我的学习中发现了另外的一种的用法为占位符使用

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>//使用预处理语句添加元素
int main(int argc,char * argv[])
{sqlite3 *db;char *mang = 0;int rc;char *err_msg = 0;//1:连接数据库rc = sqlite3_open("./test.db",&db);//打开当前目录下的数据库if(rc){//非0表示打开失败fprintf(stderr,"Can't open database: %s\n",sqlite3_errmsg(db));}else{//打开成功fprintf(stderr,"Opened database successfully\n");}// 插入数据的SQL语句(使用占为符?)const char *sql = "INSERT INTO files (FILENAME,DATE,SIZE)VALUES(?,?,?);";sqlite3_stmt *stmt;rc = sqlite3_prepare_v2(db,sql,-1,&stmt,NULL);if (rc != SQLITE_OK) {fprintf(stderr, "准备语句失败: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}//绑定参数(索引从1开始)sqlite3_bind_text(stmt,1,"flie4.mp4",-1,SQLITE_STATIC);// FILENAMEsqlite3_bind_text(stmt,2,"2025-04-21",-1,SQLITE_STATIC);//DATEsqlite3_bind_int(stmt,3,4096);//SIZE//执行插入rc = sqlite3_step(stmt);if(rc != SQLITE_DONE){fprintf(stderr, "插入失败: %s\n", sqlite3_errmsg(db));sqlite3_finalize(stmt);sqlite3_close(db);return 1;}// 释放预处理语句资源sqlite3_finalize(stmt);printf("数据插入成功!\n");sqlite3_close(db);//关闭数据库return 0;
}
SQLITE_API int sqlite3_prepare_v2(sqlite3 *db,            /* Database handle */const char *zSql,       /* SQL statement, UTF-8 encoded */int nByte,              /* Maximum length of zSql in bytes. */sqlite3_stmt **ppStmt,  /* OUT: Statement handle */const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);

参数绑定函数后很多种,区别就在于对应的数据类型

函数数据类型
sqlite3_bind_int()整数
sqlite3_bind_double()浮点数
sqlite3_bind_text()字符串
sqlite3_bind_blob()二进制数据
sqlite3_bind_null()NULL 值
SQLITE_API int sqlite3_step(sqlite3_stmt*);//插入函数

插入一条语句的话这样使用是没有问题的,那既然插入一条语句是这样的那么插入多条语句应该怎么实现。那就引出来一个全新的概念那就是事务。

对于事务这个概念就要引出ACID特性

特性描述
​原子性​​ (Atomicity)事务内的操作要么全部成功,要么全部回滚(不可分割的最小单元)
一致性​​ (Consistency)事务执行后数据库必须保持有效状态(满足约束、触发器等规则)
隔离性​​ (Isolation)并发事务之间互不干扰(通过锁机制实现)
持久性​​ (Durability)事务提交后,修改永久保存(即使系统崩溃)

在SQLite3中的事务用法

命令作用
BEGIN TRANSACTION开启事务(默认进入 DEFERRED 模式,首次读操作时获取锁)
COMMIT提交事务(持久化更改)
ROLLBACK回滚事务(撤销所有未提交的操作)
SAVEPOINT name创建保存点(支持嵌套事务)
RELEASE SAVEPOINT name释放保存点(提交到该点的操作)
ROLLBACK TO name回滚到指定保存点

使用示例:

//插入多条语句
int main() {sqlite3 *db;char *err_msg = NULL;int rc;// 打开数据库rc = sqlite3_open("test.db", &db);if (rc != SQLITE_OK) {fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));return 1;}// 开启事务(大幅提升批量插入速度)rc = sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, &err_msg);if (rc != SQLITE_OK) {fprintf(stderr, "事务开启失败: %s\n", err_msg);sqlite3_free(err_msg);sqlite3_close(db);return 1;}// 准备插入语句const char *sql = "INSERT INTO files (FILENAME, DATE, SIZE) VALUES (?, ?, ?);";sqlite3_stmt *stmt;rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);if (rc != SQLITE_OK) {fprintf(stderr, "预处理失败: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 示例数据(假设从数组或文件读取)const char *filenames[] = {"file1.txt", "file2.pdf", "file3.jpg","flie4.mp4"};const char *dates[] = {"2023-10-05", "2023-10-06", "2023-10-07","2023-10-07"};const int sizes[] = {1024, 2048, 3072,4096};// 插入多条数据for (int i = 0; i < 3; i++) {// 绑定参数sqlite3_bind_text(stmt, 1, filenames[i], -1, SQLITE_STATIC); // FILENAMEsqlite3_bind_text(stmt, 2, dates[i], -1, SQLITE_STATIC);     // DATEsqlite3_bind_int(stmt, 3, sizes[i]);                         // SIZE// 执行插入rc = sqlite3_step(stmt);if (rc != SQLITE_DONE) {fprintf(stderr, "插入失败: %s\n", sqlite3_errmsg(db));sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL); // 回滚事务sqlite3_finalize(stmt);sqlite3_close(db);return 1;}// 重置语句(不清除绑定)sqlite3_reset(stmt);}// 提交事务rc = sqlite3_exec(db, "COMMIT;", NULL, NULL, &err_msg);if (rc != SQLITE_OK) {fprintf(stderr, "提交失败: %s\n", err_msg);sqlite3_free(err_msg);}// 释放资源sqlite3_finalize(stmt);sqlite3_close(db);printf("成功插入 %d 条数据!\n", 3);return 0;
}

5:删除表数据

删除表中数据:

语法:delete from 表名 [满足条件]。

例如:

delete from user(删除表中所有数据)。

delete from user where id = 1(删除id=1的数据)。

删除表中的内容除了可以一次删除一条语句之外还可以一下删除具有相同的名字的所有数据。

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
//删除表内容
/*** 删除表中数据(按文件名或日期)* @param db        数据库句柄* @param condition 条件类型:"filename" 或 "date"* @param value     条件值(如文件名或日期字符串)* @return          1: 成功, 0: 失败*/
int delete_records(sqlite3 *db, const char *condition, const char *value) {sqlite3_stmt *stmt = NULL;char *err_msg = NULL;int rc;// 根据条件类型生成 SQL 语句const char *sql;if (strcmp(condition, "filename") == 0) {sql = "DELETE FROM files WHERE FILENAME = ?;";} else if (strcmp(condition, "date") == 0) {sql = "DELETE FROM files WHERE DATE = ?;";} else {fprintf(stderr, "无效的条件类型: 仅支持 'filename' 或 'date'\n");return 0;}// 准备预处理语句rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);if (rc != SQLITE_OK) {fprintf(stderr, "预处理失败: %s\n", sqlite3_errmsg(db));return 0;}// 绑定参数(索引从 1 开始)sqlite3_bind_text(stmt, 1, value, -1, SQLITE_STATIC);// 执行删除操作rc = sqlite3_step(stmt);if (rc != SQLITE_DONE) {fprintf(stderr, "删除失败: %s\n", sqlite3_errmsg(db));sqlite3_finalize(stmt);return 0;}// 获取删除的行数int rows_affected = sqlite3_changes(db);printf("成功删除 %d 条数据\n", rows_affected);// 释放资源sqlite3_finalize(stmt);return 1;
}
int main(int argc,char * argv[])
{sqlite3 *db;int rc;//1:连接数据库rc = sqlite3_open("./test.db",&db);//打开当前目录下的数据库if(rc){//非0表示打开失败fprintf(stderr,"Can't open database: %s\n",sqlite3_errmsg(db));}else{//打开成功fprintf(stderr,"Opened database successfully\n");}// // 示例 1:按文件名删除(删除 file1.txt)// if (!delete_records(db, "filename", "file1.txt")) {//     sqlite3_close(db);//     return 1;// }//示例 2:按日期删除(删除所有日期为 2025-04-21 的记录)if (!delete_records(db, "date", "2025-04-21")) {sqlite3_close(db);return 1;}// 关闭数据库sqlite3_close(db);return 0;
}

6:修改表数据

修改表中数据:

语法:update 表名 set 表字段 = 值 [满足条件]。

例如:

update user set id = 1 where name = 'li'。

update user set id = 1 where name = "li" and passwd = "123"。

update user set id = 2 where name = "li" or name = "zhao"。

使用示例:

#include <stdio.h>
#include <sqlite3.h>/*** 安全更新数据项(原子化操作)* @param db_name    数据库文件名* @param table_name 表名* @param old_value  旧数据值(需存在)* @param new_value  新数据值(需唯一)* @return           1: 成功, 0: 失败*/
int update_data_item(const char* db_name,const char* table_name,const char* old_value,const char* new_value) 
{sqlite3 *db = NULL;sqlite3_stmt *stmt = NULL;char *sql = NULL;int rc, ret = 0;// 打开数据库if (sqlite3_open(db_name, &db) != SQLITE_OK) {fprintf(stderr, "数据库连接失败: %s\n", sqlite3_errmsg(db));return 0;}// 开启事务if (sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL) != SQLITE_OK) {fprintf(stderr, "事务开启失败: %s\n", sqlite3_errmsg(db));goto cleanup;}// ------------------- 检查新值是否唯一 -------------------sql = sqlite3_mprintf("SELECT COUNT(*) FROM %w WHERE FILENAME=?;", table_name);rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);sqlite3_free(sql);if (rc != SQLITE_OK) {fprintf(stderr, "唯一性检查预处理失败: %s\n", sqlite3_errmsg(db));goto rollback;}sqlite3_bind_text(stmt, 1, new_value, -1, SQLITE_STATIC);if (sqlite3_step(stmt) != SQLITE_ROW) {fprintf(stderr, "唯一性检查执行失败\n");goto rollback;}if (sqlite3_column_int(stmt, 0) > 0) {fprintf(stderr, "错误: 新值 '%s' 已存在\n", new_value);goto rollback;}sqlite3_finalize(stmt);stmt = NULL;// ------------------- 执行更新操作 -------------------sql = sqlite3_mprintf("UPDATE %w SET FILENAME=? WHERE FILENAME=?;", table_name);rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);sqlite3_free(sql);if (rc != SQLITE_OK) {fprintf(stderr, "更新预处理失败: %s\n", sqlite3_errmsg(db));goto rollback;}sqlite3_bind_text(stmt, 1, new_value, -1, SQLITE_STATIC);sqlite3_bind_text(stmt, 2, old_value, -1, SQLITE_STATIC);if (sqlite3_step(stmt) != SQLITE_DONE) {fprintf(stderr, "更新执行失败: %s\n", sqlite3_errmsg(db));goto rollback;}// 验证实际更新行数if (sqlite3_changes(db) == 0) {fprintf(stderr, "错误: 旧值 '%s' 不存在\n", old_value);goto rollback;}// 提交事务if (sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL) != SQLITE_OK) {fprintf(stderr, "提交失败: %s\n", sqlite3_errmsg(db));goto rollback;}ret = 1; // 成功标志printf("[%s] %s → %s\n", table_name, old_value, new_value);rollback:if (!ret) sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
cleanup:if (stmt) sqlite3_finalize(stmt);sqlite3_close(db);return ret;
}// 示例用法
int main() {// 将 test.db 数据库 files 表中 "file3.jpg" 改为 "video.mp4"int success = update_data_item("test.db", "files", "video.mp4", "会议室1上午关键记录.mp4");printf("操作结果: %s\n", success ? "成功" : "失败");return 0;
}

7:查找数据

//查表
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
//SQL语句用法
//使用查表操作主要是sqlite3_exec()的回调函数
typedef int (*sqlite3_callback)(void*,    /* Data provided in the 4th argument of sqlite3_exec() */int,      /* The number of columns in row */char**,   /* An array of strings representing fields in the row */char**    /* An array of strings representing column names */);
// 第一个参数:即第四个参数传入的数据
// 第二个参数:行中的列数
// 第三个参数:表示行中字段的字符串数组,即各行中的数据
// 第四个参数:表示列名的字符串数组,创建链表时设置的
// 执行流程:查表,是否还有符合条件数据。有,执行sqlite3_callback()函数;没有,退出
// 回调函数
int callback(void *data, int argc, char **argv, char **azColName)
{int i;//fprintf(stderr, "%s ", (const char*)data);for(i=0; i<argc; i++){printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");}printf("\n");return 0;
}
int main(int argc,char* argv[])
{sqlite3 *db;char *mang = 0;int rc;char *err_msg = 0;const char* data = "Table";//1:连接数据库rc = sqlite3_open("./test.db",&db);//打开当前目录下的数据库if(rc){//非0表示打开失败fprintf(stderr,"Can't open database: %s\n",sqlite3_errmsg(db));}else{//打开成功fprintf(stderr,"Opened database successfully\n");}// 创建表查询表的SQL语句const char *sql = "SELECT * FROM files";//执行SQL命令创建表rc = sqlite3_exec(db,sql,callback,(void *)data,&err_msg);if( rc != SQLITE_OK ){fprintf(stderr, "SQL error: %s\n", err_msg);sqlite3_free(err_msg);}else{fprintf(stdout, "Operation done successfully\n");}sqlite3_close(db);//关闭数据库return 0;
}
//占位符用法
int main() {sqlite3 *db;sqlite3_stmt *stmt = NULL;char *err_msg = NULL;int rc;// 打开数据库rc = sqlite3_open("test.db", &db);if (rc != SQLITE_OK) {fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));return 1;}// 准备查询语句(示例:查询所有数据)const char *sql = "SELECT FILENAME, DATE, SIZE FROM files;";rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);if (rc != SQLITE_OK) {fprintf(stderr, "预处理失败: %s\n", sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 遍历结果集printf("文件列表:\n");printf("----------------------------------\n");while (sqlite3_step(stmt) == SQLITE_ROW) {// 提取各列数据(列索引从 0 开始)const char *filename = sqlite3_column_text(stmt, 0);  // 第0列:FILENAMEconst char *date = sqlite3_column_text(stmt, 1);      // 第1列:DATEint size = sqlite3_column_int(stmt, 2);               // 第2列:SIZEprintf("文件名: %-12s  日期: %-10s  大小: %d字节\n", filename, date, size);}printf("----------------------------------\n");// 检查是否因错误退出循环if (sqlite3_errcode(db) != SQLITE_DONE) {fprintf(stderr, "查询未完整执行: %s\n", sqlite3_errmsg(db));}// 释放资源sqlite3_finalize(stmt);sqlite3_close(db);return 0;
}

对于数据库的使用我觉得其核心功能是对数据的处理也就是经典四字真言“增删改查”;当掌握其中的使用方法后就基本会使用这个数据库的方法了。

相关文章:

Linux嵌入式系统SQlite3数据库学习笔记

前言 SQlite3是一个轻量级、嵌入式的关系型数据库管理系统&#xff0c;其中具有的核心特点&#xff1a; 1&#xff1a;嵌入式数据库&#xff1a;无需独立服务器进程&#xff0c;数据库直接嵌入到应用程序中。 2&#xff1a;单文件存储&#xff1a;整个数据库存储为单个文件&…...

【教程】安装 iterm2 打造漂亮且高性能的 mac 终端

【教程】安装 iterm2 打造漂亮且高性能的 mac 终端_mac 安装iterm2-CSDN博客 安装myzh 参考文章&#xff1a;https://blog.csdn.net/qq_44741467/article/details/135727124 下载地址&#xff1a;GitCode - 全球开发者的开源社区,开源代码托管平台 1、下载到本地 2、进入下载的…...

C++IO流

CIO流 IO: 向设备输入数据和输出数据 C的IO流设备: 文件、控制台、特定的数据类型(stringstream) c中,必须通过特定的已经定义好的类, 来处理IO(输入输出) 读写文件&#xff1a;文件流 文件流: 对文件进行读写操作 头文件: <fstream> 类库: ifstream 对文件输入&am…...

Swoole-添加自定义路由实现控制器访问

swoole本身不支持路由功能&#xff0c;默认情况我们实现路由访问可能要这样 $path $request->server[request_uri]switch ($path){case /favicon.ico:$response->status(404);$response->end(Not Found);break;case /abc/def/gg:$response->end("/abc/def/gg…...

Win10 关闭自动更新、关闭自动更新并重启

Windows 专业版及企业版用户可以通过组策略禁用或延迟更新。操作步骤如下&#xff1a; 按 Win R&#xff0c;输入 gpedit.msc 打开组策略编辑器。 导航到&#xff1a;计算机配置 > 管理模板 > Windows 组件 > Windows 更新。 修改以下设置&#xff1a; • 配置自…...

鸿道Intewell操作系统助力工业机器人控制系统自主可控

工业机器人与人形机器人的爆发式增长&#xff0c;正成为东土科技鸿道Intewell系统实现跨越式发展的核心引擎。从技术适配到生态重构&#xff0c;东土科技的三大核心能力与两大机器人赛道形成深度共振&#xff0c;其市场空间和产业地位将迎来指数级跃升。 一、工业机器人&…...

第十一届机械工程、材料和自动化技术国际会议(MMEAT 2025)

重要信息 官网&#xff1a;www.mmeat.net 时间&#xff1a;2025年06月23-25日 地点&#xff1a;中国-深圳 部分展示 征稿主题 智能制造和工业自动化 复合材料与高性能材料先进制造技术 自动化机器人系统 云制造与物联网集成 精密制造技术 智能生产线优化 实时数据分析与过…...

go语言八股文

1.go语言的接口是怎么实现 接口&#xff08;interface&#xff09;是一种类型&#xff0c;它定义了一组方法的集合。任何类型只要实现了接口中定义的所有方法&#xff0c;就被认为实现了该接口。 代码的实现 package mainimport "fmt"// 定义接口 type Shape inte…...

短视频广告创意策划简历模板

模板信息 简历范文名称&#xff1a;短视频广告创意策划简历模板&#xff0c;所属行业&#xff1a;其他 | 职位&#xff0c;模板编号&#xff1a;A4I63M 专业的个人简历模板&#xff0c;逻辑清晰&#xff0c;排版简洁美观&#xff0c;让你的个人简历显得更专业&#xff0c;找到…...

2.Spring MVC与WebFlux响应式编程

目录 一、Spring MVC核心机制与工作原理 • 请求处理流程&#xff1a;DispatcherServlet分发机制、HandlerMapping与HandlerAdapter • 核心组件&#xff1a;ViewResolver、ModelAndView、拦截器&#xff08;Interceptor&#xff09; • 注解驱动开发&#xff1a;Controller、…...

【重走C++学习之路】16、AVL树

目录 一、概念 二、AVL树的模拟实现 2.1 AVL树节点定义 2.2 AVL树的基本结构 2.3 AVL树的插入 1. 插入步骤 2. 调节平衡因子 3. 旋转处理 4. 开始插入 2.4 AVL树的查找 2.5 AVL树的删除 1. 删除步骤 2. 调节平衡因子 3. 旋转处理 4. 开始删除 结语 一、概念 …...

蓝桥杯 19.合根植物

合根植物 原题目链接 题目描述 W 星球的一个种植园被分成 m n 个小格子&#xff08;东西方向 m 行&#xff0c;南北方向 n 列&#xff09;。每个格子里种了一株合根植物。 这种植物有个特点&#xff0c;它的根可能会沿着南北或东西方向伸展&#xff0c;从而与另一个格子的…...

爆改 toxml 组件 支持数据双向绑定 解决数据刷新问题

GGGGGGGGGGGGGGGGGithub地址自行研究 sbfkcel/towxml: 微信小程序HTML、Markdown渲染库https://github.com/sbfkcel/towxml原组件是以导入数据渲染信息为目的、本文以AI数据返回小程序为模拟效果演示 默认情况只在ready 环节进行渲染静态资源 1、对传入数据容器的位置做处理 …...

6.分布式数据库与分库分表

目录 一、分库分表核心概念 • 核心目标&#xff1a;突破单库性能瓶颈&#xff0c;应对海量数据与高并发 • ​​垂直拆分​​&#xff1a;按业务模块拆分&#xff08;用户库、订单库、商品库&#xff09; • ​​水平拆分​​&#xff1a;单表数据分片&#xff08;用户ID取模…...

基于javaweb的SSM+Maven小区失物招领系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

Kubernetes finalize | namespace卡Terminatingfinalizers删除失败

目录 1、为什么会卡住&#xff1f;2、强制删除卡住的 Namespace&#xff1a;操作步骤1&#xff1a;导出当前 namespace 信息2&#xff1a;启动代理&#xff08;另一个终端&#xff09;以便使用 Kubernetes API Server3&#xff1a;使用 curl 强制删除 finalize 3、进阶排查&…...

Java数组

目录 一、定义 二、使用 2.1遍历数组 2.2获取数组长度 三、Arrays类 3.1数组填充 3.2数组排序 3.3数组转为字符串 3.4数组比较 3.5二分搜索 3.6数组复制 二维数组 一、定义 数组表示一个相同类型元素的集合 对于一个数组&#xff0c;可以有以下几种定义方法 int[…...

高级java每日一道面试题-2025年4月22日-基础篇[反射篇]-如何通过反射创建一个对象实例?

如果有遗漏,评论区告诉我进行补充 面试官: 如何通过反射创建一个对象实例&#xff1f; 我回答: 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的工具&#xff0c;允许程序在运行时检查和操作类、接口、字段和方法。反射不仅用于检查类的结构&#…...

Spring开发系列教程(26)——异步处理

在Servlet模型中&#xff0c;每个请求都是由某个线程处理&#xff0c;然后&#xff0c;将响应写入IO流&#xff0c;发送给客户端。从开始处理请求&#xff0c;到写入响应完成&#xff0c;都是在同一个线程中处理的。 实现Servlet容器的时候&#xff0c;只要每处理一个请求&…...

【2025最新Java面试八股】如何理解MySQL的MVCC机制?

面试回答要点 当面试官问及MySQL的MVCC机制时&#xff0c;可以这样组织回答&#xff1a; "MVCC(Multi-Version Concurrency Control&#xff0c;多版本并发控制)是MySQL实现高并发事务的一种重要机制&#xff0c;它通过保存数据在某个时间点的快照来实现非阻塞读操作。I…...

使用FreeRTOS解决单片机串口异步打印

单片机串口异步打印 文章目录 单片机串口异步打印前言设计思路准备队列创建完整代码 总结 前言 &#x1f30a;在单片机开发中串口的异步打印异步打印允许单片机在执行其他任务的同时进行打印操作&#xff0c;无需等待打印完成后再继续执行后续代码&#xff0c;避免了在多处调用…...

飞算 JavaAI 与 Spring Boot:如何实现微服务开发效率翻倍?

微服务架构凭借其高内聚、低耦合的特性&#xff0c;成为企业构建复杂应用系统的首选方案。然而&#xff0c;传统微服务开发流程中&#xff0c;从服务拆分、接口设计到代码编写、调试部署&#xff0c;往往需要耗费大量时间与人力成本。Spring Boot 作为 Java 领域最受欢迎的微服…...

Python 列表与元组深度解析:从基础概念到函数实现全攻略

在 Python 编程的广袤天地中&#xff0c;列表&#xff08;List&#xff09;和元组&#xff08;Tuple&#xff09;是两种不可或缺的数据结构。它们如同程序员手中的瑞士军刀&#xff0c;能高效地处理各类数据。从简单的数值存储到复杂的数据组织&#xff0c;列表和元组都发挥着关…...

vue 修改路由动态选择路由 改文件位置

vue 修改路由动态选择路由 改文件位置 main.jspermission.js...

Nginx openresty web服务 与 Go 原生web服务性能对比

1 概述 Nginx采用的是IO复用模型&#xff0c;能处理超高并发。 Go语言采用协程&#xff0c;能轻量级的处理超高并发。 那么在不考虑业务逻辑复杂的前提下&#xff0c;即假如将Nginx和Go都提供一个/test接口&#xff0c;并在接口逻辑中都只是让其做20毫秒的耗时操作&#xff0c…...

【音视频】FFmpeg解封装

解封装 复用器&#xff0c;比如MP4/FLV 解复用器&#xff0c;MP4/FLV 封装格式相关函数 avformat_alloc_context(); 负责申请一个AVFormatContext结构的内存,并进行简单初始化avformat_free_context(); 释放该结构里的所有东西以及该结构本身avformat_close_input();关闭解复…...

autohue.js - 基于 JavaScript 开发的图片背景色提取开源库,能让图片和背景融为一体

图片提取主题色的工具库&#xff0c;可以实现一些酷炫的界面效果。 本文不是 AI 生成&#xff0c;大部分文字都是我自己敲键盘&#xff0c;部分文字摘自 autohue.js 作者主页&#xff0c;请各位放心舒适阅读。 autohue.js 是一个图片背景色提取库&#xff0c;基于提出来的颜色…...

bgp实验.包括联盟,隧道相关,以及一个低级错误

实验拓扑 低级错误 在配置隧道时,目标的单词是destination,我自动补全为description了,这个问题花了我40分钟 划分ip AS2内骨干网,一个网段需要两个地址,主机位2位,掩码30 需要6个 172.16.0.000000 00 172.16.0.0/30 172.16.0.000001 00 172.16.0.4/30 172.16.0.000010 00 1…...

科普动画短视频制作:角色塑造的魅力法则

宝子们&#xff0c;在科普动画短视频的世界里&#xff0c;角色塑造可是让作品出彩的关键&#xff01;今天就来和大家唠唠那些超实用的角色塑造法则&#xff0c;还会给大家推荐一款超好用的工具哦~ 一、独特外形&#xff0c;吸睛第一步 在科普动画短视频制作中&#xff0c;角色…...

【飞渡科技数字孪生虚拟环境部署与集成教程 - CloudMaster实战指南】

飞渡科技数字孪生虚拟环境部署与集成教程 - CloudMaster实战指南 前言 本教程详细记录了飞渡科技的数字孪生平台CloudMaster的配置过程&#xff0c;以及如何将三维数字孪生场景集成到前端项目中。数字孪生技术能够在虚拟环境中精确复现物理实体的数据、特性和行为&#xff0c…...

MongoDB 集合名称映射问题

项目场景 在使用 Spring Data MongoDB 进行开发时&#xff0c;定义了一个名为 CompetitionSignUpLog 的实体类&#xff0c;并创建了对应的 Repository 接口。需要明确该实体类在 MongoDB 中实际对应的集合名称是 CompetitionSignUpLog 还是 competitionSignUpLog。 问题描述 …...

禁止ubuntu自动更新

由于ubuntu server和desktop版本都默认 启动了&#xff0c;自动更新内核的操作。这对于生 产环境来说是不友好的。容易导致亿赛通 无法启动 默认开启了内核自动更新所以我们关闭自 动内核更新。 1.禁止更新执行 sudo apt-mark hold linux-image-generic linux-headers-generic…...

【C++】——入门基础(一)

前言 这是我C的第一篇文章&#xff0c;如果你想从事入门C行业&#xff0c;可以看看这幅漫画 当然&#xff0c;这只是一个玩笑&#xff0c;但如过你真的想学习C&#xff0c;和我一起学习吧 本人其他博客;恋风诗 本文出现的代码见gitte:mozhengy 这里写目录标题 前言1. C发展历史…...

[原创](现代Delphi 12指南):[macOS 64bit App开发]:在Mac App Store外创建、部署与公证

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...

美乐迪电玩客户端打包与资源替换实战教程

本篇为《美乐迪电玩全套系统搭建》系列的第二篇&#xff0c;聚焦客户端层的实战操作&#xff0c;主要面向前端开发者、美术资源替换人员及整体项目的打包部署人员。教程将涵盖安卓客户端的构建、资源目录说明、动画素材替换方式及常见适配问题处理等。 一、客户端项目结构说明&…...

多态以及多态底层的实现原理

本章目标 1.多态的概念 2.多态的定义实现 3.虚函数 4.多态的原理 1.多态的概念 多态作为面对三大特性之一,它所指代的和它的名字一样,多种形态.但是这个多种形态更多的指代是函数的多种形态. 多态分为静态多态和动态多态. 静态多态在前面已经学习过了,就是函数重载以及模板,…...

描述城市出行需求模式的复杂网络视角:大规模起点-目的地需求网络的图论分析

描述城市出行需求模式的复杂网络视角&#xff1a;大规模起点-目的地需求网络的图论分析 原文&#xff1a; A complex network perspective for characterizing urban travel demand patterns: graph theoretical analysis of large-scale origin–destination demand networks…...

文件操作函数

本文是小编巩固自身而作&#xff0c;如有错误&#xff0c;欢迎指出&#xff01; 1.使用文件的原因 我们编写的程序都是有生命周期的&#xff0c;储存在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就会丢失&#xff0c;等程序再次运行&#xf…...

Java高频面试之并发编程-05

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;线程有哪些调度方法&#xff1f; 在Java中&#xff0c;线程的调用方法主要包括以下几种方式&#xff0c;每种方式适用于…...

LeetCode 1292 元素和小于等于阈值的正方形的最大边长

最大正方形边长问题详解 一、问题描述 给定一个大小为 mn 的矩阵 mat 和一个整数阈值 threshold&#xff0c;要求返回元素总和小于或等于阈值的正方形区域的最大边长&#xff1b;如果没有这样的正方形区域&#xff0c;则返回 0。 二、解题思路 前缀和矩阵的概念与构建 前缀…...

测试开发 - Java 自动化测试核心函数详解

目录 1. 元素定位 1.1 By.xpath 1.1.1 //* 1.1.2 //[指定节点] 1.1.3 / 1.1.4 /.. 1.1.5 [...] 1.1.6 指定索引获取对应元素 1.2 By.cssSelector 1.2.1 # 1.2.2 . 1.2.3 > 1.2.4 标签名:nth-child(n) 2. 获取元素 2.1 findElement 2.2 findElements 3. 操…...

【HarmonyOS】ArKUI框架

目录 概述 声明式开发范式 基于ArKUI的项目 • 1&#xff0e;创建资源文件 • 2&#xff0e;引用资源 • 3&#xff0e;引用系统资源&#xff1a; • 系统资源有哪些 • 4. 在配置和资源中引用资源 声明式语法 UI描述规范 UI组件概述 组件化 组件渲染控制语法 修改…...

【MQ篇】RabbitMQ之简单模式!

目录 引言一、 初识 RabbitMQ 与工作模式二、 简单模式 (Simple Queue) 详解&#xff1a;最直接的“点对点快递” &#x1f4ee;三、 Java (Spring Boot) 代码实战&#xff1a;让小兔子跑起来&#xff01; &#x1f430;&#x1f3c3;‍♂️四、 深入理解&#xff1a;简单模式的…...

K8S节点出现Evicted状态“被驱逐”

在Kubernetes集群中&#xff0c;Pod状态为“被驱逐&#xff08;evicted&#xff09;”表示Pod无法在当前节点上继续运行&#xff0c;已被集群从节点上移除。 问题分析&#xff1a; 节点磁盘空间不足 &#xff0c;使用df -h查看磁盘使用情况 可以看到根目录 / 已100%满&#x…...

NumPyro:概率编程的现代Python框架深度解析

引言 概率编程作为统计学与机器学习的交叉领域&#xff0c;正在重塑我们构建不确定性模型的方式。在众多概率编程语言&#xff08;PPL&#xff09;中&#xff0c;NumPyro凭借其简洁的语法、强大的性能和与PyTorch生态系统的无缝集成&#xff0c;已经成为研究者和数据科学家的首…...

java进阶之git

git git介绍git常用命令代码回滚操作 git 介绍 工作区 改动&#xff08;增删文件和内容&#xff09;暂存区 输入命令&#xff1a;git add改动的文件名&#xff0c;此次改动就放到了"暂存区“本地仓库 输入命令&#xff1a;git commit 此次修改的描述&#xff0c;此次改动…...

负载阻尼效应及其作用解析

负载阻尼效应是指负载&#xff08;如电路、机械系统或控制系统中连接的设备&#xff09;对系统动态变化&#xff08;如电压波动、机械振动等&#xff09;产生的抑制或衰减作用。 其核心是通过消耗或吸收能量&#xff0c;减少系统中的振荡、波动或瞬态响应&#xff0c;从而提高…...

面向组织的网络安全措施

一、安全措施概述 在一个组织中&#xff0c;技术人员可以利用一系列强大的网络安全工具进行安全检测和防范&#xff0c;以保护组织的网络基础设施、数据和资产免受各种威胁。这些工具通常涵盖了从主动防御、威胁检测、漏洞管理到事件响应和安全分析的各个方面。 以下是一些关…...

Unity 跳转资源商店,并打开特定应用

需求&#xff1a; 打开资源商店&#xff0c;并定位到特定应用. 代码&#xff1a; #if UNITY_ANDROIDApplication.OpenURL("market://details?idcom.tencent.mm"); #elif UNITY_IPHONEApplication.OpenURL(“itms-apps://apps.apple.com/app/id333903271”); #end…...

2025年五大ETL数据集成工具推荐

ETL工具作为打通数据孤岛的核心引擎&#xff0c;直接影响着企业的决策效率与业务敏捷性。本文精选五款实战型ETL解决方案&#xff0c;从零门槛的国产免费工具到国际大厂企业级平台&#xff0c;助您找到最适合的数据集成利器。 一、谷云科技ETLCloud&#xff1a;国产数据集成工…...