MySQL介绍及使用

news2025/4/7 20:43:49

1. 安装、启动、配置 MySQL

1. 安装 MySQL

更新软件包索引
sudo apt update
安装 MySQL 服务器
sudo apt install mysql-server

安装过程中可能会提示你设置 root 用户密码。如果没有提示,可以跳过,后续可以手动设置。


2. 配置 MySQL

运行安全脚本

安装完成后,运行以下命令以提高 MySQL 的安全性:

sudo mysql_secure_installation

按照提示进行操作:

  • 设置 root 用户密码(如果之前未设置)。

  • 移除匿名用户(建议选择 Y)。

  • 禁止 root 用户远程登录(如果不需要远程访问,建议选择 Y)。

  • 删除测试数据库(建议选择 Y)。

  • 重新加载权限表(选择 Y)。


3. 设置 MySQL 用户密码

如果在安装过程中没有设置密码,或者需要更改密码,可以通过以下步骤设置密码。

登录到 MySQL
sudo mysql -uroot -p

如果之前没有设置密码,直接按回车键即可登录。

设置密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';

新密码 替换为你想要设置的密码。

FLUSH PRIVILEGES;
退出 MySQL
exit;

4. 配置远程访问(可选)

如果你需要从其他计算机远程访问 MySQL 数据库,可以按照以下步骤配置。

登录到 MySQL
sudo mysql -uroot -p
创建远程用户并授予权限
CREATE USER 'root'@'%' IDENTIFIED BY '新密码';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
  • CREATE USER 创建一个允许从任何 IP 地址访问的 root 用户。

  • GRANT ALL PRIVILEGES 授予该用户所有数据库和表的完全访问权限。

刷新权限
FLUSH PRIVILEGES;
退出 MySQL
exit;

5. 配置 MySQL 服务:实现所有IP都能访问

编辑 MySQL 配置文件
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
修改 bind-address
bind-address = 127.0.0.1
bind-address = 0.0.0.0
保存并退出

保存文件并退出编辑器。

重启 MySQL 服务
sudo systemctl restart mysql

6. 测试远程访问(可选)

在另一台计算机上,使用以下命令测试远程访问:

mysql -uroot -h[MySQL服务器IP] -p

输入你设置的密码,如果能够成功连接,说明配置成功。


7. 安装 MySQL 客户端(可选)

如果你需要从其他计算机连接到 MySQL 数据库,可以在客户端计算机上安装 MySQL 客户端。

安装 MySQL 客户端
sudo apt install mysql-client

2.MySQL介绍 

MySQL 是一个 关系型数据库管理系统(RDBMS),使用 结构化查询语言(SQL) 来管理和操作数据。

“关系”在这里指的是二维表格(表 / table),每张表由行(row)列(column) 组成,数据以结构化形式存储。

名称说明
数据库(Database)数据的集合,一个数据库中可以有多张表
表(Table)类似 Excel 表格,用来存储结构化数据
行(Row)表中的一条记录,例如一个用户信息
列(Column)数据的字段,比如姓名、年龄、邮箱等
主键(Primary Key)每行的唯一标识,不可重复
外键(Foreign Key)引用其他表的主键,用于建立表之间的关系

1.数值类型

1. 整数类型
数据类型存储大小(字节)范围(有符号)范围(无符号)
TINYINT1-128 到 1270 到 255
SMALLINT2-32768 到 327670 到 65535
MEDIUMINT3-8388608 到 83886070 到 16777215
INT 或 INTEGER4-2147483648 到 21474836470 到 4294967295
BIGINT8-9223372036854775808 到 9223372036854775807
2. 浮点数类型
数据类型存储大小(字节)范围
FLOAT4依赖于精度
DOUBLE8依赖于精度

2、字符串类型

1. 字符类型
数据类型存储大小用途
CHAR固定长度存储固定长度的字符串,如电话号码
VARCHAR可变长度存储可变长度的字符串,如用户名
2. 二进制字符串类型
数据类型存储大小用途
BINARY固定长度存储固定长度的二进制字符串
VARBINARY可变长度存储可变长度的二进制字符串
3. 文本类型
数据类型存储大小用途
TINYTEXT最大 255 字节存储较短的文本
TEXT最大 65535 字节存储中等长度的文本
MEDIUMTEXT最大 16777215 字节存储较长的文本
LONGTEXT最大 4294967295 字节存储非常长的文本

3.MySQL使用

SQL(结构化查询语言) 是操作关系型数据库的标准语言,包括:

  • SELECT:查询数据

  • INSERT:插入数据

  • UPDATE:更新数据

  • DELETE:删除数据

  • CREATE / DROP:创建或删除表和数据库

  • JOIN:多表联查

1.SQL

1. 登录 MySQL

在终端中输入以下命令登录 MySQL:

mysql -u root -p
  • -u root 表示以管理员用户登录(root 是 MySQL 的默认管理员账号)。

  • -p 表示提示输入密码。输入你在安装过程中设置的 MySQL 管理员密码。

如果密码正确,你会看到 MySQL 的命令行提示符,类似如下:

mysql>

2. 查看数据库

登录后,查看当前数据库列表:

SHOW DATABASES;

你会看到类似以下输出:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

这些是 MySQL 系统自带的数据库。你可以创建自己的数据库。

3. 创建数据库

创建一个新的数据库,例如 mydatabase

CREATE DATABASE mydatabase;

4. 切换到新创建的数据库

USE mydatabase;

5. 创建表

mydatabase 数据库中创建一个表,例如 students

CREATE TABLE students (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    age INT,
    grade VARCHAR(10)
);
  • id 是主键,自动递增。

  • name 是字符串类型,最大长度为 50,不能为空。

  • age 是整数类型。

  • grade 是字符串类型,最大长度为 10。

6. 插入数据

students 表中插入数据:

INSERT INTO students (name, age, grade) VALUES ('Alice', 20, 'A');
INSERT INTO students (name, age, grade) VALUES ('Bob', 22, 'B');

7. 查询数据

查询 students 表中的所有数据:

SELECT * FROM students;
+----+-------+-----+-------+
| id | name  | age | grade |
+----+-------+-----+-------+
|  1 | Alice |  20 | A     |
|  2 | Bob   |  22 | B     |
+----+-------+-----+-------+

8. 更新数据

更新表中的数据,例如将 Alice 的年龄改为 21:

UPDATE students SET age = 21 WHERE name = 'Alice';

9. 删除数据

删除表中的数据,例如删除 Bob 的记录:

sql复制

DELETE FROM students WHERE name = 'Bob';

再次查询数据,确认删除是否成功:

sql复制

SELECT * FROM students;

10. 退出 MySQL

EXIT;

11. 其他常用操作

  • 查看表结构

    DESCRIBE students;
  • 删除表

    DROP TABLE students;
  • 删除数据库

    DROP DATABASE mydatabase;

2.列的完整性约束

1. 主键约束(Primary Key)

  • 作用:唯一标识表中的每条记录。

  • 特点:值必须唯一且不能为空。

  • 示例

    sql复制

    CREATE TABLE students (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50)
    );

2. 外键约束(Foreign Key)

  • 作用:建立表与表之间的关系。

  • 特点:值必须是另一个表的主键值,或者为空。

  • 示例

    sql复制

    CREATE TABLE enrollments (
        student_id INT,
        FOREIGN KEY (student_id) REFERENCES students(id)
    );

3. 唯一约束(Unique)

  • 作用:确保列中的值是唯一的。

  • 特点:允许空值,但每个值必须唯一。

  • 示例

    sql复制

    CREATE TABLE users (
        email VARCHAR(100) UNIQUE
    );

4. 非空约束(NOT NULL)

  • 作用:确保列中的值不能为空。

  • 特点:插入或更新时必须提供值。

  • 示例

    sql复制

    CREATE TABLE employees (
        name VARCHAR(50) NOT NULL
    );

5. 默认值约束(DEFAULT)

  • 作用:为列指定默认值。

  • 特点:插入记录时未指定值时自动使用默认值。

  • 示例

    sql复制

    CREATE TABLE orders (
        order_date DATE DEFAULT CURRENT_DATE
    );

6. 检查约束(CHECK)

  • 作用:限制列的值必须满足某些条件。

  • 特点:确保数据符合特定规则。

  • 示例

    sql复制

    CREATE TABLE products (
        price DECIMAL(10, 2) CHECK (price > 0)
    );

7. 添加和删除约束

  • 添加约束

    sql复制

    ALTER TABLE table_name ADD CONSTRAINT constraint_name constraint_type;
  • 删除约束

    sql复制

    ALTER TABLE table_name DROP CONSTRAINT constraint_name;

 4.操作 MySQL 的三种主流 C/C++ 接口/库

名称语言说明
libmysqlclient-devC最底层、官方提供的 C API
libmysql++C++C++ 封装库,封装了上面的 C API
MySQL Connector/C++C++Oracle 官方维护的 C++ 驱动,现代化设计

1️⃣ libmysqlclient-dev - 最底层的 C API(推荐了解)

  • 作用:提供最基础的 C API 来操作 MySQL。

  • 包管理器名(Debian/Ubuntu)

    sudo apt install libmysqlclient-dev

  • 常用头文件#include <mysql/mysql.h>

  • 使用方式

    • 初始化连接

    • 发送 SQL 查询

    • 获取结果集

  • 适合:底层开发、嵌入式开发、对性能控制要求高的场景。

    #include <mysql++/mysql++.h>
    
    mysqlpp::Connection conn(false);
    conn.connect("testdb", "localhost", "root", "password");
    
    mysqlpp::Query query = conn.query("SELECT * FROM users");
    mysqlpp::StoreQueryResult res = query.store();
    

✅ 优点:轻量、速度快、控制力强
❌ 缺点:接口是 C 风格,写起来繁琐、类型安全差、易出错


2️⃣ libmysql++ - 对 C API 的 C++ 封装(较旧但简单)

  • 作用:基于 libmysqlclient 封装,提供更易用的 C++ 接口。

  • 安装方式(Ubuntu)

    sudo apt install libmysql++-dev

  • 项目地址:http://tangentsoft.com/mysql++/

#include <mysql++/mysql++.h>

mysqlpp::Connection conn(false);
conn.connect("testdb", "localhost", "root", "password");

mysqlpp::Query query = conn.query("SELECT * FROM users");
mysqlpp::StoreQueryResult res = query.store();

✅ 优点:写起来比 C API 简洁
❌ 缺点:项目已经多年未更新,缺乏现代 C++ 特性(比如 smart pointer, exception 安全等)


3️⃣ MySQL Connector/C++ - Oracle 官方的现代 C++ 驱动(推荐)

  • 作用:Oracle 提供的官方 C++ 库,支持 C++11/14 风格编程,模块化、支持连接池等。

  • 安装方式(Ubuntu)

    sudo apt install libmysqlcppconn-dev

  • 头文件<mysql_driver.h><mysql_connection.h>

#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/prepared_statement.h>

sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
std::unique_ptr<sql::Connection> con(driver->connect("tcp://127.0.0.1:3306", "root", "pwd"));
con->setSchema("testdb");

std::unique_ptr<sql::PreparedStatement> stmt(
    con->prepareStatement("INSERT INTO users(name) VALUES(?)"));
stmt->setString(1, "Alice");
stmt->execute();

✅ 优点:

  • 支持 prepared statements(防注入)

  • 面向对象

  • 官方维护,现代设计

❌ 缺点:比 C API 慢一点,依赖较多


✅ 总结:我该选哪个?

如果你是...推荐选择理由
新手/想快速开发MySQL Connector/C++ (libmysqlcppconn-dev)现代 C++ 风格、易用、安全
想学底层 / 嵌入式libmysqlclient-dev学会底层原理,便于扩展
想用老项目代码libmysql++有些老代码仍然使用它,但新项目建议不要用了

5.C/C++ 使用 MySQL API 操作 数据库

// include/db.hpp

#pragma once
#include <string>
#include <vector>

struct FileMeta {
  std::string filename;
  std::string filepath;
  std::string user;
  long size;
};

bool init_db();
void close_db();
bool insert_file(const FileMeta &file);
std::vector<FileMeta> query_files_by_path(const std::string &path);
// src/db.cpp

#include "db.hpp"
#include <iostream>
#include <mysql/mysql.h>

MYSQL *conn = nullptr;

bool init_db() {
  // 1.初始化一个 MySQL 连接句柄
  conn = mysql_init(nullptr);
  if (!conn) {
    std::cerr << "mysql_init failed\n";
    return false;
  }

  // 2.建立与 MySQL 数据库
  if (!mysql_real_connect(conn, "127.0.0.1", "root", "123456", "metadb", 3306,
                          nullptr, 0)) {
    std::cerr << "mysql_real_connect failed: " << mysql_error(conn) << "\n";
    return false;
  }

  return true;
}

void close_db() {
  if (conn) {
    //关闭与MySQL数据库的连接
    mysql_close(conn);
    conn = nullptr;
  }
}

// 向数据库插入文件元数据
bool insert_file(const FileMeta &file) {
  // 1.SQL 插入语句格式化到 query 数组
  char query[1024];
  snprintf(query, sizeof(query),
           "INSERT INTO file_metadata (filename, filepath, user, size) VALUES "
           "('%s', '%s', '%s', %ld)",
           file.filename.c_str(), file.filepath.c_str(), file.user.c_str(),
           file.size);

  // 2.mysql_query 函数执行 SQL 查询语句
  if (mysql_query(conn, query)) {
    std::cerr << "Insert failed: " << mysql_error(conn) << "\n";
    return false;
  }
  return true;
}

std::vector<FileMeta> query_files_by_path(const std::string &path) {
  std::vector<FileMeta> results;
  std::string query = "SELECT filename, filepath, user, size FROM "
                      "file_metadata WHERE filepath = '" +
                      path + "'";

  if (mysql_query(conn, query.c_str())) {
    std::cerr << "Query failed: " << mysql_error(conn) << "\n";
    return results;
  }

  // 3.mysql_store_result 函数获取查询结果。
  MYSQL_RES *res = mysql_store_result(conn);
  if (!res) {
    std::cerr << "mysql_store_result failed\n";
    return results;
  }

  // 4.mysql_fetch_row 函数逐行获取查询结果
  MYSQL_ROW row;
  while ((row = mysql_fetch_row(res))) {
    FileMeta file;
    file.filename = row[0];
    file.filepath = row[1];
    file.user = row[2];
    file.size = std::stol(row[3]);
    results.push_back(file);
  }

  mysql_free_result(res);
  return results;
}

//src/main.cpp
#include "db.hpp"
#include <iostream>

int main() {
  if (!init_db()) {
    return 1;
  }

  FileMeta file = {"report.docx", "/home/user/docs", "alice", 5120};
  insert_file(file);

  auto files = query_files_by_path("/home/user/docs");
  for (const auto &f : files) {
    std::cout << f.filename << " (" << f.size << " bytes) - " << f.user << "\n";
  }

  close_db();
  return 0;
}
cmake_minimum_required(VERSION 3.10)
project(MetaFS_C_API)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 设置头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)

# 设置源文件
file(GLOB SOURCES
    ${PROJECT_SOURCE_DIR}/src/*.cpp
)

# 生成可执行文件
add_executable(meta_fs ${SOURCES})

# 链接 MySQL client 库
target_link_libraries(meta_fs mysqlclient)

——————————————————————————————————————————

#pragma once
#include <string>
#include <vector>

struct FileMeta {
  std::string filename;
  std::string filepath;
  std::string user;
  long size;
};

bool init_db();
bool insert_file(const FileMeta &file);
std::vector<FileMeta> list_files(const std::string &path);
#include "db.hpp"
#include <cppconn/prepared_statement.h> //SQL执行
#include <cppconn/resultset.h>          //查询结果
#include <fstream>
#include <mysql_connection.h> //链接数据库
#include <mysql_driver.h>     //驱动
#include <nlohmann/json.hpp>

using json = nlohmann::json;
static sql::Connection *conn = nullptr;

bool init_db() {
  std::ifstream file("config/db_config.json");
  json cfg;
  file >> cfg;

  // 1.创建 MySQL 驱动对象,初始化驱动
  sql::mysql::MySQL_Driver *driver = sql::mysql::get_mysql_driver_instance();

  // 2. 建立连接
  conn = driver->connect(cfg["host"], cfg["user"], cfg["password"]);

  // 3. 选择数据库
  conn->setSchema(cfg["database"]);
  return true;
}

// 将文件元数据插入到数据库中
bool insert_file(const FileMeta &file) {
  // 1.准备SQL语句
  sql::PreparedStatement *stmt =
      conn->prepareStatement("INSERT INTO file_metadata(filename, filepath, "
                             "user, size) VALUES (?, ?, ?, ?)");

  // 2.设置参数
  stmt->setString(1, file.filename);
  stmt->setString(2, file.filepath);
  stmt->setString(3, file.user);
  stmt->setInt64(4, file.size);

  // 3.执行SQL语句
  stmt->execute();

  // 4.释放PreparedStatement对象,避免内存泄漏
  delete stmt;
  return true;
}

//从数据库中查询指定路径下的所有文件元数据,并将结果存储到一个std::vector<FileMeta>
//中返回
std::vector<FileMeta> list_files(const std::string &path) {
  std::vector<FileMeta> files;
  sql::PreparedStatement *stmt =
      conn->prepareStatement("SELECT filename, filepath, user, size FROM "
                             "file_metadata WHERE filepath = ?");
  stmt->setString(1, path);

  // 3.执行查询
  sql::ResultSet *res = stmt->executeQuery();

  // 4.处理查询结果
  while (res->next()) {
    files.push_back({res->getString("filename"), res->getString("filepath"),
                     res->getString("user"), res->getInt64("size")});
  }
  delete res;
  delete stmt;
  return files;
}
#include "db.hpp"
#include <iostream>

int main() {
  if (!init_db()) {
    std::cerr << "DB init failed\n";
    return 1;
  }

  FileMeta f1 = {"data.txt", "/home/user/docs", "alice", 2048};
  insert_file(f1);

  auto files = list_files("/home/user/docs");
  for (const auto &f : files) {
    std::cout << f.filename << " (" << f.size << " bytes) - " << f.user << "\n";
  }

  return 0;
}
-- sql/init.sql

CREATE DATABASE IF NOT EXISTS metadb;

USE metadb;

CREATE TABLE IF NOT EXISTS file_metadata (
    id INT AUTO_INCREMENT PRIMARY KEY,
    filename VARCHAR(255) NOT NULL,
    filepath VARCHAR(255) NOT NULL,
    user VARCHAR(64),
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    size BIGINT
);
cmake_minimum_required(VERSION 3.10)
project(MiniMetaFS)

set(CMAKE_CXX_STANDARD 17)

include_directories(include)

add_executable(minifs src/main.cpp src/db.cpp)

find_package(MySQL REQUIRED)
target_link_libraries(minifs mysqlcppconn)

# 使用 nlohmann/json(假设你用的是头文件方式)

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

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

相关文章

java后端开发day34--脑子空空如何无痛想起所有知识点--概念拟人化

1.上半部学习思考 1.1反思–浮躁–二倍速 刚开始算半个小白吧&#xff0c;从最基础的知识点开始学习&#xff0c;到后面学习整个项目的布局和功能。可能是后面慢慢懂得多了&#xff0c;每次打代码搞项目啊什么的&#xff0c;就能明显感觉到自己很浮躁&#xff1a;脑子里已经明…

fastGPT—前端开发获取api密钥调用机器人对话接口(HTML实现)

官网文档链接&#xff1a;OpenAPI 介绍 | FastGPT 首先按照文档说明创建api密钥 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…

解决 PDF 难题:批量处理、文档清理与自由拆分合并

软件介绍 在日常办公与学习中&#xff0c;处理 PDF 文件常常让人头疼不已&#xff0c;不过别担心&#xff0c;今天有一款堪称神器的国产老牌 PDF 工具要分享给大家。它就是 PDF 补丁丁&#xff0c;凭借其强大功能&#xff0c;为大家排忧解难。 界面体验 初次打开 PDF 补丁丁&…

使用pycharm社区版调试DIFY后端python代码

目录 背景 前置条件 DIFY使用的框架 API服务调试配置步骤&#xff08;基于tag为0.15.3的版本&#xff09; 1.配置.env文件 2.关闭docker里面的docker-api-1服务 3.使用DOCKER启动本地环境需要用到的中间件&#xff0c;并暴露端口 注意事项一&#xff1a; 注意事项二&#xff1a…

量子计算与人工智能的结合:未来科技的双重革命

引言 在过去几十年里&#xff0c;人工智能&#xff08;AI&#xff09;和计算能力的提升一直是推动科技进步的重要力量。然而&#xff0c;随着深度学习和大规模数据处理的发展&#xff0c;传统计算架构的算力瓶颈逐渐显现&#xff0c;人工智能的训练和推理效率受到了限制。在此背…

关于存储的笔记

存储简介 名称适用场景常见运用网络环境备注块存储高性能、低延迟数据库局域网专业文件存储数据共享共享文件夹、非结构化数据局域网通用对象存储大数据、云存储网盘、网络媒体公网&#xff08;断点续传、去重&#xff09;海量 存储协议 名称协议块存储FC-SAN或IP-SAN承载的…

JWT认证服务

JSON Web Token&#xff08;JWT&#xff09;是一种用于在网络应用间安全地传递信息的紧凑、自包含的方式。以下是关于 JWT 认证服务器更详细的介绍&#xff0c;包括其意义、作用、工作原理、组成部分、时效性相关内容、搭建条件以及代码案例。 JWT 的意义与作用 意义&#xf…

手机中的type-C是如何防水的呢?

防水类型的type-C座子&#xff1a; 电子产品防水等级的区分&#xff1a; 这里的“IP”是国际防护标准等级&#xff1b;简而言之&#xff0c;IPXX中“XX”两位数字分别代表防尘和防水等级&#xff0c;其中防尘等级从0&#xff5e;6&#xff0c;防水等级则从0&#xff5e;8。 第…

[Redis]Redis学习开篇概述

欢迎来到啾啾的博客&#x1f431;。 这是一个致力于构建完善 Java 程序员知识体系的博客&#x1f4da;。 它记录学习点滴&#xff0c;分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604;。 引言 大家好…

WordPress浮动广告插件+飘动效果客服插件

源码介绍 WordPress浮动广告插件飘动效果客服插件 将源码上传到wordpress的插件根目录下&#xff0c;解压&#xff0c;然后后台启用即可 截图 源码免费获取 WordPress浮动广告插件飘动效果客服插件

Java基础关键_034_网络编程

目 录 一、概述 二、网络编程三要素 1.IP 地址 2.端口号 3.通信协议 &#xff08;1&#xff09;说明 &#xff08;2&#xff09;OSI 七层参考模型 &#xff08;3&#xff09;TCP/IP 四层参考模型 三、网络编程基础类 1.InetAddress 2.URL &#xff08;1&#xff09…

Ubuntu交叉编译器工具链安装

声明 本博客所记录的关于正点原子i.MX6ULL开发板的学习笔记&#xff0c;&#xff08;内容参照正点原子I.MX6U嵌入式linux驱动开发指南&#xff0c;可在正点原子官方获取正点原子Linux开发板 — 正点原子资料下载中心 1.0.0 文档&#xff09;&#xff0c;旨在如实记录我在学校学…

基于Python的招聘推荐数据可视化分析系统

【Python】基于Python的招聘推荐数据可视化分析系统&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 &#x1f680;&#x1f31f; 基于Python的招聘推荐数据可视化分析系统&#xff01;&#x1…

光谱相机在工业中的应用

光谱相机&#xff08;多光谱、高光谱、超光谱成像技术&#xff09;在工业领域通过捕捉物质的光谱特征&#xff08;反射、透射、辐射等&#xff09;&#xff0c;结合化学计量学与人工智能算法&#xff0c;为工业检测、质量控制和工艺优化提供高精度、非接触式的解决方案。以下是…

使用PyQt5绘制水波浪形的柱状显示流量—学习QTimer+QPainterPath

前言&#xff1a;进入学习Python开发上位机界面的第二阶段&#xff0c;学习如何开发自定义控件&#xff0c;从常用的控件入手学习&#xff0c;本期主要学习如何使用PyQt5绘制水波浪形的柱状显示流量。但是最后我放弃了&#xff0c;因为水波的效果达不到我想要的。 1. 明确想要…

C++蓝桥杯实训篇(二)

片头 嗨咯~小伙伴们&#xff01;今天我们来一起学习算法和贪心思维&#xff0c;准备好了吗&#xff1f;咱们开始咯&#xff01; 第1题 数位排序 对于这道题&#xff0c;我们需要自己写一个排序算法&#xff0c;也就是自定义排序&#xff0c;按照数位从小到大进行排序。 举一…

无人驾驶是自动化还是智能化?

这是一个由小米Su-7和人形机器人问题引起的思考&#xff1a;努力决定了下限&#xff0c;认知决定了上限。 一、无人驾驶既涉及自动化&#xff0c;也涉及智能化&#xff0c;这两者在无人驾驶系统中应该是相互融合、相辅相成的1、自动化&#xff08;Automation&#xff09; 自动化…

实操(不可重入函数、volatile、SIGCHLD、线程)Linux

1 不可重入函数 为什么会导致节点丢失内存泄露&#xff1f;main函数在执行insert&#xff0c;但是没执行完就被信号中断了&#xff0c;又进了这个函数里&#xff0c;所以这个insert函数在不同的执行流中&#xff0c;同一个函数被重复进入&#xff0c;如果没有问题&#xff0c;…

【Flask开发】嘿马文学web完整flask项目第2篇:2.用户认证,Json Web Token(JWT)【附代码文档】

教程总体简介&#xff1a;2. 目标 1.1产品与开发 1.2环境配置 1.3 运行方式 1.4目录说明 1.5数据库设计 2.用户认证 Json Web Token(JWT) 3.书架 4.1分类列表 5.搜索 5.3搜索-精准&高匹配&推荐 6.小说 6.4推荐-同类热门推荐 7.浏览记录 8.1配置-阅读偏好 8.配置 9.1项目…

Ubuntu 下搭建 MCU 开发环境全流程指南(以 STM32 为例)

在嵌入式开发中,许多工程师都习惯于在 Windows 平台使用 Keil、IAR 等 IDE。然而,随着对自动化、可定制性以及开放工具链的需求增长,越来越多的开发者开始尝试在 Linux 环境下进行 MCU 开发。 本篇文章将以 STM32F1 系列 为例,手把手带你在 Ubuntu 下搭建一个完整的 MCU 开…