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

C++和Python实现SQL Server数据库导出数据到S3并导入Redshift数据仓库

用C++实现高性能数据处理,Python实现操作Redshift导入数据文件。
在Visual Studio 2022中用C++和ODBC API导出SQL Server数据库中张表中的所有表的数据为CSV文件格式的数据流,用逗号作为分隔符,用双引号包裹每个数据,字符串类型的数据去掉前后的空格,数据中如果包含双引号,则将一个双引号替换为两个双引号,创建gzip压缩文件,输出数据流写入到gzip压缩文件包中的唯一的csv文件中,一张表对应一个gzip压缩文件。用异步编程的方法优化数据库表的读取和写入文件的过程,每个gzip压缩文件包中的csv文件的第一行都是用逗号分割的表头,对应数据库表的字段,程序需要异常处理和日志文件输出,当前路径下唯一的日志文件中包含运行时间戳、数据库名、schema名、表名、导出数据行数、成功或者失败的状态,日志文件不存在则创建。

以下是一个使用C++和ODBC API在Visual Studio 2022中实现将SQL Server数据库表数据导出为CSV文件并进行gzip压缩的示例代码。代码使用异步编程优化数据库读取和文件写入过程,并包含异常处理和日志记录功能。

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <future>
#include <sql.h>
#include <sqlext.h>
#include <zlib.h>
#include <ctime>
#include <iomanip>// 日志记录函数
void logMessage(const std::string& message) {std::ofstream logFile("export_log.txt", std::ios::app);if (logFile.is_open()) {auto now = std::chrono::system_clock::now();std::time_t now_c = std::chrono::system_clock::to_time_t(now);std::tm* now_tm = std::localtime(&now_c);std::ostringstream oss;oss << std::put_time(now_tm, "%Y-%m-%d %H:%M:%S") << " " << message << std::endl;logFile << oss.str();logFile.close();}
}// 处理字符串中的双引号
std::string escapeDoubleQuotes(const std::string& str) {std::string result = str;size_t pos = 0;while ((pos = result.find('"', pos))!= std::string::npos) {result.replace(pos, 1, 2, '"');pos += 2;}return result;
}// 从数据库读取表数据
std::vector<std::vector<std::string>> readTableData(SQLHSTMT hstmt) {std::vector<std::vector<std::string>> data;SQLSMALLINT columnCount = 0;SQLNumResultCols(hstmt, &columnCount);std::vector<SQLCHAR*> columns(columnCount);std::vector<SQLINTEGER> lengths(columnCount);for (SQLSMALLINT i = 0; i < columnCount; ++i) {columns[i] = new SQLCHAR[SQL_MAX_MESSAGE_LENGTH];SQLBindCol(hstmt, i + 1, SQL_C_CHAR, columns[i], SQL_MAX_MESSAGE_LENGTH, &lengths[i]);}while (SQLFetch(hstmt) == SQL_SUCCESS) {std::vector<std::string> row;for (SQLSMALLINT i = 0; i < columnCount; ++i) {std::string value(reinterpret_cast<const char*>(columns[i]));value = escapeDoubleQuotes(value);row.push_back(value);}data.push_back(row);}for (SQLSMALLINT i = 0; i < columnCount; ++i) {delete[] columns[i];}return data;
}// 将数据写入CSV文件
void writeToCSV(const std::vector<std::vector<std::string>>& data, const std::vector<std::string>& headers, const std::string& filename) {std::ofstream csvFile(filename);if (csvFile.is_open()) {// 写入表头for (size_t i = 0; i < headers.size(); ++i) {csvFile << '"' << headers[i] << '"';if (i < headers.size() - 1) csvFile << ',';}csvFile << std::endl;// 写入数据for (const auto& row : data) {for (size_t i = 0; i < row.size(); ++i) {csvFile << '"' << row[i] << '"';if (i < row.size() - 1) csvFile << ',';}csvFile << std::endl;}csvFile.close();} else {throw std::runtime_error("Failed to open CSV file for writing");}
}// 压缩CSV文件为gzip
void compressCSV(const std::string& csvFilename, const std::string& gzipFilename) {std::ifstream csvFile(csvFilename, std::ios::binary);std::ofstream gzipFile(gzipFilename, std::ios::binary);if (csvFile.is_open() && gzipFile.is_open()) {gzFile gzOut = gzopen(gzipFilename.c_str(), "wb");if (gzOut) {char buffer[1024];while (csvFile.read(buffer, sizeof(buffer))) {gzwrite(gzOut, buffer, sizeof(buffer));}gzwrite(gzOut, buffer, csvFile.gcount());gzclose(gzOut);} else {throw std::runtime_error("Failed to open gzip file for writing");}csvFile.close();gzipFile.close();std::remove(csvFilename.c_str());} else {throw std::runtime_error("Failed to open files for compression");}
}// 导出单个表
void exportTable(const std::string& server, const std::string& database, const std::string& schema, const std::string& table) {SQLHENV henv = nullptr;SQLHDBC hdbc = nullptr;SQLHSTMT hstmt = nullptr;try {SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);std::string connectionString = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=" + server + ";DATABASE=" + database + ";UID=your_username;PWD=your_password";SQLRETURN ret = SQLDriverConnect(hdbc, nullptr, (SQLCHAR*)connectionString.c_str(), SQL_NTS, nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT);if (ret!= SQL_SUCCESS && ret!= SQL_SUCCESS_WITH_INFO) {throw std::runtime_error("Failed to connect to database");}std::string query = "SELECT * FROM " + schema + "." + table;SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);ret = SQLExecDirect(hstmt, (SQLCHAR*)query.c_str(), SQL_NTS);if (ret!= SQL_SUCCESS && ret!= SQL_SUCCESS_WITH_INFO) {throw std::runtime_error("Failed to execute query");}std::vector<std::vector<std::string>> data = readTableData(hstmt);std::vector<std::string> headers;SQLSMALLINT columnCount = 0;SQLNumResultCols(hstmt, &columnCount);for (SQLSMALLINT i = 0; i < columnCount; ++i) {SQLCHAR columnName[SQL_MAX_COLUMN_NAME_LEN];SQLSMALLINT nameLen;SQLDescribeCol(hstmt, i + 1, columnName, SQL_MAX_COLUMN_NAME_LEN, &nameLen, nullptr, nullptr, nullptr, nullptr);headers.push_back(reinterpret_cast<const char*>(columnName));}std::string csvFilename = table + ".csv";writeToCSV(data, headers, csvFilename);std::string gzipFilename = table + ".gz";compressCSV(csvFilename, gzipFilename);std::ostringstream oss;oss << "Database: " << database << ", Schema: " << schema << ", Table: " << table << ", Rows Exported: " << data.size() << ", Status: Success";logMessage(oss.str());} catch (const std::exception& e) {std::ostringstream oss;oss << "Database: " << database << ", Schema: " << schema << ", Table: " << table << ", Status: Failed, Error: " << e.what();logMessage(oss.str());} finally {if (hstmt) SQLFreeHandle(SQL_HANDLE_STMT, hstmt);if (hdbc) SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc);if (henv) SQLFreeHandle(SQL_HANDLE_ENV, henv);}
}int main() {std::string server = "<实例名>";std::string database = "<数据库名>";std::string schema = "<Schema名>";std::vector<std::string> tables = {"<表名1>", "<表名2>", "<表名3>"};std::vector<std::future<void>> futures;for (const auto& table : tables) {futures.push_back(std::async(std::launch::async, exportTable, server, database, schema, table));}for (auto& fut : futures) {fut.get();}return 0;
}

代码说明:

日志记录: logMessage 函数用于记录操作日志,包括时间戳、数据库名、schema名、表名、导出数据行数和操作状态。
字符串处理: escapeDoubleQuotes 函数用于处理字符串中的双引号,将其替换为两个双引号。
数据库读取: readTableData 函数使用ODBC API从数据库中读取表数据,并将其存储在二维向量中。
CSV写入: writeToCSV 函数将数据写入CSV文件,包括表头和数据行,并用双引号包裹每个数据,使用逗号作为分隔符。
文件压缩: compressCSV 函数将生成的CSV文件压缩为gzip格式,并删除原始CSV文件。
表导出: exportTable 函数负责连接数据库、执行查询、读取数据、写入CSV文件并压缩。
主函数: main 函数定义了数据库服务器、数据库名、schema名和表名,并使用异步任务并行导出每个表的数据。

用Python删除当前目录下所有功能扩展名为gz文件,接着运行export_sqlserver.exe程序,输出该程序的输出内容并等待它运行完成,然后连接SQL Server数据库和Amazon Redshift数据仓库,从数据库中获取所有表和它们的字段名,然后在Redshift中创建字段名全部相同的同名表,字段长度全部为最长的varchar类型,如果表已经存在则不创建表,自动上传当前目录下所有功能扩展名为gz文件到S3,默认覆盖同名的文件,然后使用COPY INTO将S3上包含csv文件的gz压缩包导入对应创建的Redshift表中,文件数据的第一行是表头,导入所有上传的文件到Redshift表,程序需要异常处理和日志文件输出,当前路径下唯一的日志文件中包含运行时间戳、数据库名、schema名、表名、导入数据行数、成功或者失败的状态,日志文件不存在则创建。

import os
import subprocess
import pyodbc
import redshift_connector
import boto3
import logging
from datetime import datetime# 配置日志记录
logging.basicConfig(filename='operation_log.log', level=logging.INFO,format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')def delete_gz_files():try:for file in os.listdir('.'):if file.endswith('.gz'):os.remove(file)logging.info('所有.gz文件已删除')except Exception as e:logging.error(f'删除.gz文件时出错: {e}')def run_export_sqlserver():try:result = subprocess.run(['export_sqlserver.exe'], capture_output=True, text=True)print(result.stdout)logging.info('export_sqlserver.exe运行成功')except Exception as e:logging.error(f'运行export_sqlserver.exe时出错: {e}')def create_redshift_tables():# SQL Server 连接配置sqlserver_conn_str = 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=your_sqlserver_server;DATABASE=your_database;UID=your_username;PWD=your_password'try:sqlserver_conn = pyodbc.connect(sqlserver_conn_str)sqlserver_cursor = sqlserver_conn.cursor()# Redshift 连接配置redshift_conn = redshift_connector.connect(host='your_redshift_host',database='your_redshift_database',user='your_redshift_user',password='your_redshift_password',port=5439)redshift_cursor = redshift_conn.cursor()sqlserver_cursor.execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'")tables = sqlserver_cursor.fetchall()for table in tables:table_name = table[0]sqlserver_cursor.execute(f"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{table_name}'")columns = sqlserver_cursor.fetchall()column_definitions = ', '.join([f"{column[0]} VARCHAR(MAX)" for column in columns])try:redshift_cursor.execute(f"CREATE TABLE IF NOT EXISTS {table_name} ({column_definitions})")redshift_conn.commit()logging.info(f'在Redshift中成功创建表 {table_name}')except Exception as e:logging.error(f'在Redshift中创建表 {table_name} 时出错: {e}')sqlserver_conn.close()redshift_conn.close()except Exception as e:logging.error(f'连接数据库或创建表时出错: {e}')def upload_gz_files_to_s3():s3 = boto3.client('s3')bucket_name = 'your_bucket_name'try:for file in os.listdir('.'):if file.endswith('.gz'):s3.upload_file(file, bucket_name, file)logging.info(f'成功上传文件 {file} 到S3')except Exception as e:logging.error(f'上传文件到S3时出错: {e}')def copy_data_to_redshift():redshift_conn = redshift_connector.connect(host='your_redshift_host',database='your_redshift_database',user='your_redshift_user',password='your_redshift_password',port=5439)redshift_cursor = redshift_conn.cursor()bucket_name = 'your_bucket_name'try:for file in os.listdir('.'):if file.endswith('.gz') and file.endswith('.csv.gz'):table_name = file.split('.')[0]s3_path = f's3://{bucket_name}/{file}'sql = f"COPY {table_name} FROM '{s3_path}' IAM_ROLE 'your_iam_role' CSV HEADER"try:redshift_cursor.execute(sql)redshift_conn.commit()row_count = redshift_cursor.rowcountlogging.info(f'成功将数据导入表 {table_name},导入行数: {row_count}')except Exception as e:logging.error(f'将数据导入表 {table_name} 时出错: {e}')except Exception as e:logging.error(f'连接Redshift或导入数据时出错: {e}')finally:redshift_conn.close()if __name__ == "__main__":delete_gz_files()run_export_sqlserver()create_redshift_tables()upload_gz_files_to_s3()copy_data_to_redshift()

代码说明:

日志记录:使用 logging 模块配置日志记录,记录操作的时间戳和操作信息到 operation_log.log 文件。
删除.gz文件: delete_gz_files 函数删除当前目录下所有扩展名为 .gz 的文件。
运行export_sqlserver.exe: run_export_sqlserver 函数运行 export_sqlserver.exe 程序并输出其内容。
创建Redshift表: create_redshift_tables 函数连接SQL Server和Redshift数据库,获取SQL Server中所有表和字段名,在Redshift中创建同名表,字段类型为 VARCHAR(MAX) 。
上传.gz文件到S3: upload_gz_files_to_s3 函数上传当前目录下所有扩展名为 .gz 的文件到S3。
将数据从S3导入Redshift: copy_data_to_redshift 函数使用 COPY INTO 语句将S3上的CSV压缩包数据导入对应的Redshift表中。

请根据实际的数据库配置、S3桶名和IAM角色等信息修改代码中的相关参数。

相关文章:

C++和Python实现SQL Server数据库导出数据到S3并导入Redshift数据仓库

用C实现高性能数据处理&#xff0c;Python实现操作Redshift导入数据文件。 在Visual Studio 2022中用C和ODBC API导出SQL Server数据库中张表中的所有表的数据为CSV文件格式的数据流&#xff0c;用逗号作为分隔符&#xff0c;用双引号包裹每个数据&#xff0c;字符串类型的数据…...

AI大模型开发原理篇-5:循环神经网络RNN

神经概率语言模型NPLM也存在一些明显的不足之处:模型结构简单&#xff0c;窗口大小固定&#xff0c;缺乏长距离依赖捕捉&#xff0c;训练效率低&#xff0c;词汇表固定等。为了解决这些问题&#xff0c;研究人员提出了一些更先进的神经网络语言模型&#xff0c;如循环神经网络、…...

4-图像梯度计算

文章目录 4.图像梯度计算(1)Sobel算子(2)梯度计算方法(3)Scharr与Laplacian算子4.图像梯度计算 (1)Sobel算子 图像梯度-Sobel算子 Sobel算子是一种经典的图像边缘检测算子,广泛应用于图像处理和计算机视觉领域。以下是关于Sobel算子的详细介绍: 基本原理 Sobel算子…...

数据结构与算法 —— 常用算法模版

数据结构与算法 —— 常用算法模版 二分查找素数筛最大公约数与最小公倍数 二分查找 人间若有天堂&#xff0c;大马士革必在其中&#xff1b;天堂若在天空&#xff0c;大马士革必与之齐名。 —— 阿拉伯谚语 算法若有排序&#xff0c;二分查找必在其中&#xff1b;排序若要使用…...

DDD - 领域事件_解耦微服务的关键

文章目录 Pre领域事件的核心概念领域事件的作用领域事件的识别领域事件的技术实现领域事件的运行机制案例领域事件驱动的优势 Pre DDD - 微服务设计与领域驱动设计实战(中)_ 解决微服务拆分难题 EDA - Spring Boot构建基于事件驱动的消息系统 领域事件的核心概念 领域事件&a…...

芯片AI深度实战:实战篇之vim chat

利用vim-ollama这个vim插件&#xff0c;可以在vim内和本地大模型聊天。 系列文章&#xff1a; 芯片AI深度实战&#xff1a;基础篇之Ollama-CSDN博客 芯片AI深度实战&#xff1a;基础篇之langchain-CSDN博客 芯片AI深度实战&#xff1a;实战篇之vim chat-CSDN博客 芯片AI深度…...

【产品经理学习案例——AI翻译棒出海业务】

前言&#xff1a; 本文主要讲述了硬件产品在出海过程中&#xff0c;翻译质量、翻译速度和本地化落地策略是硬件产品规划需要考虑的核心因素。针对不同国家&#xff0c;需要优化翻译质量和算法&#xff0c;关注市场需求和文化差异&#xff0c;以便更好地满足当地用户的需求。同…...

解决运行npm时报错

在运行一个Vue项目时报错&#xff0c;产生下面问题 D:\node\npm.cmd run dev npm WARN logfile could not be created: Error: EPERM: operation not permitted, open D:\node\node_cache\_logs\2025-01-31T01_01_58_076Z-debug-0.log npm WARN logfile could not be created:…...

【07-编译工程与导入网表】

这里写自定义目录标题 一丶编译原理图编译默认属性一丶编译项目二丶输出BOM材料报告优化EXCEL-BOM清单 三丶输出PDF原理图给维修人员看 四丶导入网格表查看是否有错误常见错误 其他问题什么是位号(C1)?EXCEL添加序号列和居中显示?位号(序号)与单位(型号)EXCEL设置自动换行 编…...

FireFox | Google Chrome | Microsoft Edge 禁用更新 final版

之前的方式要么失效&#xff0c;要么对设备有要求&#xff0c;这次梳理一下对设备、环境几乎没有要求的通用方式&#xff0c;universal & final 版。 1.Firefox 方式 FireFox火狐浏览器企业策略禁止更新_火狐浏览器禁止更新-CSDN博客 这应该是目前最好用的方式。火狐也…...

conda配置channel

你收到 CondaKeyError: channels: value https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main not present in config 错误是因为该镜像源&#xff08;https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main&#xff09;可能没有被正确添加到 Conda 的配置文件中&…...

【MQ】探索 Kafka

基本概念 主题&#xff1a;Topic。主题是承载消息的逻辑容器&#xff0c;在实际使用中多用来区分具体的业务。 分区&#xff1a;Partition。一个有序不变的消息序列。每个主题下可以有多个分区。消息位移&#xff1a;Offset。表示分区中每条消息的位置信息&#xff0c;是一个…...

Workbench 中的热源仿真

探索使用自定义工具对移动热源进行建模及其在不同行业中的应用。 了解热源动力学 对移动热源进行建模为各种工业过程和应用提供了有价值的见解。激光加热和材料加工使用许多激光束来加热、焊接或切割材料。尽管在某些情况下&#xff0c;热源 &#xff08;q&#xff09; 不是通…...

计算机网络 笔记 网络层 3

IPv6 IPv6 是互联网协议第 6 版&#xff08;Internet Protocol Version 6&#xff09;的缩写&#xff0c;它是下一代互联网协议&#xff0c;旨在解决 IPv4 面临的一些问题&#xff0c;以下是关于 IPv6 的详细介绍&#xff1a; 产生背景&#xff1a; 随着互联网的迅速发展&…...

翼星求生服务器搭建【Icarus Dedicated Server For Linux】

一、前言 本次搭建的服务器为Steam平台一款名为Icarus的沙盒、生存、建造游戏,由于官方只提供了Windows版本服务器导致很多热爱Linux的小伙伴无法释怀,众所周知Linux才是专业服务器的唯一准则。虽然Github上已经有大佬制作了容器版本但是容终究不够完美,毕竟容器无法与原生L…...

ZZNUOJ(C/C++)基础练习1011——1020(详解版)

目录 1011 : 圆柱体表面积 C语言版 C版 1012 : 求绝对值 C语言版 C版 1013 : 求两点间距离 C语言版 C版 1014 : 求三角形的面积 C语言版 C版 1015 : 二次方程的实根 C语言版 C版 1016 : 银行利率 C语言版 C版 1017 : 表面积和体积 C语言版 C版 代码逻辑…...

论文阅读:Realistic Noise Synthesis with Diffusion Models

这篇文章是 2025 AAAI 的一篇工作&#xff0c;主要介绍的是用扩散模型实现对真实噪声的仿真模拟 Abstract 深度去噪模型需要大量来自现实世界的训练数据&#xff0c;而获取这些数据颇具挑战性。当前的噪声合成技术难以准确模拟复杂的噪声分布。我们提出一种新颖的逼真噪声合成…...

复杂场景使用xpath定位元素

在复杂场景下使用XPath定位元素时&#xff0c;可以通过以下高级技巧提高定位准确性和稳定性&#xff1a; 动态属性处理 模糊匹配&#xff1a; //div[contains(id, dynamic-part)] //button[starts-with(name, btn-)] //input[ends-with(class, -input)] (需XPath 2.0)多属性…...

算法基础——存储

引入 基础理论的进步&#xff0c;是推动技术实现重大突破&#xff0c;促使相关领域的技术达成跨越式发展的核心。 在发展日新月异的大数据领域&#xff0c;基础理论的核心无疑是算法。不管是技术设计&#xff0c;还是工程实践&#xff0c;都必须仰仗相关算法的支持&#xff0…...

动态规划 (环形)

在一个圆形操场的四周摆放着n堆石子&#xff0c;现要将石子有次序地合并成一堆。规定每次只能选相邻2堆石子合并成新的一堆&#xff0c;并将新的一堆石子数记为该次合并的得分。试设计一个算法&#xff0c;计算出将n堆石子合并成一堆的最小得分和最大得分。 输入格式: n表示n…...

3小时从零到一:在Linux上搭建macOS虚拟机的完整实战指南

3小时从零到一&#xff1a;在Linux上搭建macOS虚拟机的完整实战指南 【免费下载链接】OneClick-macOS-Simple-KVM Tools to set up a easy, quick macOS VM in QEMU, accelerated by KVM. Works on Linux AND Windows. 项目地址: https://gitcode.com/gh_mirrors/on/OneClick…...

DS1202示波器功能详解与实战操作指南

1. DS1202示波器核心功能解析 第一次拿到DS1202示波器时&#xff0c;面对密密麻麻的按键和接口确实有点懵。但用久了就会发现&#xff0c;它的设计其实非常人性化。咱们先从最常用的垂直控制区说起——这是调节波形高低胖瘦的关键区域。 垂直位移按键就像给波形装了个电梯&…...

手把手教你搭建mPLUG图片问答工具:全本地运行,无需联网

手把手教你搭建mPLUG图片问答工具&#xff1a;全本地运行&#xff0c;无需联网 1. 项目介绍与核心价值 想象一下&#xff0c;你有一张照片但不确定里面有什么&#xff0c;或者需要快速了解图片中的细节信息。传统方法可能需要你手动描述、上网搜索&#xff0c;或者将图片上传…...

C++ Move 构造函数性能影响

C Move构造函数性能影响探析 在现代C编程中&#xff0c;Move构造函数是提升性能的重要工具之一。它通过“窃取”临时对象的资源而非深拷贝&#xff0c;显著减少了不必要的内存分配和数据复制。Move构造函数的性能影响并非总是显而易见&#xff0c;其实际效果取决于多种因素。本…...

能耗优化指南:OpenClaw+GLM-4.7-Flash笔记本续航方案

能耗优化指南&#xff1a;OpenClawGLM-4.7-Flash笔记本续航方案 1. 为什么需要关注OpenClaw的能耗问题 去年夏天的一次出差经历让我深刻意识到这个问题的重要性。当时我正在高铁上用笔记本调试一个OpenClaw自动化流程&#xff0c;结果不到两小时就收到了电量不足的警告。这促…...

用tcpreplay+Wireshark搭建网络攻防实验环境:手把手教你复现渗透测试流量

实战指南&#xff1a;用tcpreplay与Wireshark构建网络攻防实验环境 在网络安全领域&#xff0c;理论知识的掌握固然重要&#xff0c;但真正的技能提升往往来自于实战演练。然而&#xff0c;直接在真实网络环境中进行渗透测试或攻击模拟不仅存在法律风险&#xff0c;还可能对生…...

前端HTML精讲01:别再乱 div 一把抓,吃透语义化标签才是进阶第一步

前端HTML精讲01&#xff1a;别再乱 div 一把抓&#xff0c;吃透语义化标签才是进阶第一步 文章目录前端HTML精讲01&#xff1a;别再乱 div 一把抓&#xff0c;吃透语义化标签才是进阶第一步一、什么是HTML语义化&#xff1f;二、为什么要做HTML语义化&#xff1f;1\. 提升代码可…...

网盘下载加速工具:突破下载限制的直链提取技术详解

网盘下载加速工具&#xff1a;突破下载限制的直链提取技术详解 【免费下载链接】baiduyun 油猴脚本 - 一个免费开源的网盘下载助手 项目地址: https://gitcode.com/gh_mirrors/ba/baiduyun 你是否也曾遇到这样的情况&#xff1a;明明是自己辛苦上传的文件&#xff0c;下…...

Qwen3-Embedding-4B广告过滤应用:恶意内容识别系统实战

Qwen3-Embedding-4B广告过滤应用&#xff1a;恶意内容识别系统实战 1. 引言&#xff1a;当广告变成“牛皮癣”&#xff0c;我们如何反击&#xff1f; 想象一下&#xff0c;你运营着一个用户社区或内容平台。每天&#xff0c;用户都在热情地分享、讨论。但总有一些不速之客&am…...

解密ARM多核调度:从Linux内核源码看SMP负载均衡如何玩转Cortex-A系列

ARM多核调度实战&#xff1a;从Linux内核视角剖析SMP负载均衡的艺术 在移动计算和嵌入式系统领域&#xff0c;ARM架构凭借其出色的能效比已经占据了主导地位。随着Cortex-A系列处理器核心数量的不断增加&#xff0c;如何高效地管理这些计算资源成为系统性能优化的关键。本文将带…...