豆瓣图书数据采集与可视化分析(二)- 豆瓣图书数据清洗与处理

文章目录

  • 前言
  • 一、查看数据基本信息
  • 二、拆分pub列
  • 三、日期列处理
  • 四、价格列处理
  • 五、出版社列处理
  • 六、评价人数列处理
  • 七、缺失值处理
  • 八、重复数据处理
  • 九、异常值处理
  • 十、完整代码
  • 十一、清洗与处理后的数据集展示


前言

豆瓣作为国内知名的文化社区,拥有庞大且丰富的图书数据资源。这些数据涵盖了图书的分类、标签、详细信息以及用户的评价等多个维度,为我们深入了解图书世界提供了宝贵的素材。然而,原始的豆瓣图书数据往往存在格式不规范、信息缺失、数据重复以及异常值等问题,这些问题会严重影响数据的质量和后续的分析与应用。
为了充分挖掘豆瓣图书数据的价值,我们需要对其进行一系列的清洗和处理工作。通过对数据的全面检查和针对性处理,我们可以解决数据中存在的各种问题,使数据更加完整、准确和一致。本项目围绕豆瓣图书数据集展开,详细阐述了从数据的初步查看、各列数据的处理(包括拆分、格式转换、异常值处理等),到缺失值和重复值的处理,以及最终将处理后的数据保存到数据库的整个过程。


一、查看数据基本信息

def data_info(data):"""打印数据的前几行、列名和基本信息。:param data: 待分析的DataFrame数据"""print("数据前几行:")print(data.head().to_csv(sep='\t', na_rep='nan'))  # 使用制表符分隔,方便查看,缺失值用nan表示print("数据列名:")print(data.columns)print("数据基本信息:")data.info()

数据前几行如下所示:

数据前几行:category_name	url	img_url	name	pub	rating	rating_count	plot	buy_info
0	J.K.罗琳	https://book.douban.com/subject/35671734/	https://img9.doubanio.com/view/subject/s/public/s34048686.jpg	哈利·波特与死亡圣器	J.K. 罗琳 / 中国图书进出口总公司 / 2016-8-1 / 30.00元	9.6	(310人评价)	「“把哈利·波特交出来,”伏地魔的声音说,“你们谁也不会受伤。把哈利·波特交出来,我会让学校安然无恙。把哈利·波特交出来,你们会得到奖赏。”」当哈利·波特攀...	nan
1	J.K.罗琳	https://book.douban.com/subject/27625554/	https://img3.doubanio.com/view/subject/s/public/s33973792.jpg	神奇动物在哪里(插图版)	[英]纽特·斯卡曼德 / 一目、马爱农 / 人民文学出版社 / 2018-3 / 45.00	8.5	(483人评价)	《神奇动物在哪里》是“哈利·波特”系列*著名的官方衍生书。它是哈利·波特在霍格沃茨魔法学校的指定教材,由J.K.罗琳(化名纽特·斯卡曼德)撰写。 这一全新的...	纸质版 25.00元
2	J.K.罗琳	https://book.douban.com/subject/27594566/	https://img1.doubanio.com/view/subject/s/public/s32311010.jpg	诗翁彼豆故事集(插图版)	[英]J.K.罗琳 / 马爱农 / 人民文学出版社 / 2018-3	8.9	(721人评价)	《诗翁彼豆故事集》是“哈利·波特”系列的官方衍生书。它是魔法世界家喻户晓的床边故事集,也是邓布利多留给赫敏·格兰杰的礼物。书中故事均由J.K.罗琳撰写。 这...	纸质版 25.00元
3	J.K.罗琳	https://book.douban.com/subject/35909174/	https://img1.doubanio.com/view/subject/s/public/s34330260.jpg	哈利·波特与被诅咒的孩子	[英] J.K.罗琳、[英] 约翰·蒂法尼、[英] 杰克·索恩 / 马爱农 / 人民文学出版社 / 2022-6 / 69.00元	7.0	(84人评价)	第八个故事。 十九年后。 十九年前,哈利·波特、罗恩·韦斯莱和赫敏·格兰杰携手拯救了魔法世界;如今,他们再次踏上了一场非同寻常的冒险旅程。这次与他们同行的,...	纸质版 40.40元
4	J.K.罗琳	https://book.douban.com/subject/26984868/	https://img9.doubanio.com/view/subject/s/public/s29443244.jpg	神奇动物在哪里	[英] J. K. 罗琳 / 马爱农、马珈 / 人民文学出版社 / 2017-4 / 58	8.3	(1346人评价)	读懂“哈利·波特”,从前传开始 《神奇动物在哪里》 J.K.罗琳首次挑战电影编剧 纽特·斯卡曼德邀请你一同探索魔法世界新纪元! 冒险家、神奇动物学家纽特·...	纸质版 32.00元

数据列名如下所示:

数据列名:
Index(['category_name', 'url', 'img_url', 'name', 'pub', 'rating','rating_count', 'plot', 'buy_info'],dtype='object')

数据基本信息如下所示:

数据基本信息:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 129839 entries, 0 to 129838
Data columns (total 9 columns):#   Column         Non-Null Count   Dtype  
---  ------         --------------   -----  0   category_name  129839 non-null  object 1   url            129839 non-null  object 2   img_url        129839 non-null  object 3   name           129827 non-null  object 4   pub            129436 non-null  object 5   rating         111810 non-null  float646   rating_count   129839 non-null  object 7   plot           119919 non-null  object 8   buy_info       93330 non-null   object 
dtypes: float64(1), object(8)
memory usage: 8.9+ MB

二、拆分pub列

# 拆分pub列的函数
def split_pub(pub):"""拆分pub列,根据不同的分隔符和格式提取作者、译者、出版社、出版日期和价格信息。:param pub: pub列的单个值:return: 包含提取信息的Series"""if pd.isna(pub):return pd.Series([None, None, None, None, None],index=['author', 'translator', 'publisher', 'publish_date', 'price'])author = translator = publisher = publish_date = price = Noneif '/' in pub:parts = pub.split('/')if len(parts) == 5:author, translator, publisher, publish_date, price = partselif len(parts) == 4:if '.' in pub:author, publisher, publish_date, price = partselse:author, translator, publisher, publish_date = partselif len(parts) == 3:if '.' in pub:author, publish_date, price = partselse:author, publisher, publish_date = partselif len(parts) == 2:if '-' in pub and '.' in pub:publish_date, price = partselse:publisher, publish_date = partselse:if '-' in pub:publish_date = pubelif '出版社' in pub:publisher = pubelse:price = pubreturn pd.Series([author, translator, publisher, publish_date, price],index=['author', 'translator', 'publisher', 'publish_date', 'price'])

三、日期列处理

此函数用于处理日期列,将日期字符串转换为有效的图书发布年份。会对输入的日期字符串进行格式检查,提取年份部分,并验证年份是否处于合理范围(1900 - 2025),若不符合要求则返回 None。

def process_date(date_str):"""处理日期列,提取年份并进行有效性检查。:param date_str: 日期字符串:return: 有效的年份或None"""if pd.notna(date_str):date_str = date_str.strip()try:year_str = date_str[:4]if len(year_str.strip()) != 4:return Noneyear = int(year_str)if 1900 <= year <= 2025:  # 检查年份范围return yearexcept ValueError:passreturn None

四、价格列处理

此函数的作用是处理包含价格信息的字符串,从其中提取有效的价格,并对提取出的价格进行有效性检查。 包含价格信息的字符串,通常是类似 “纸质版 39.8 元” 这样的格式。若字符串中包含有效的价格信息且价格在合理范围内,返回该价格(浮点数类型);若价格超出合理范围,返回设定的上限价格 2000;若字符串为空值、格式不符合要求或在处理过程中出现错误,返回 None。

def process_buy_info(buy_info_str):"""处理价格信息,提取价格并进行有效性检查。:param buy_info_str: 包含价格信息的字符串:return: 有效的价格或None"""if pd.notna(buy_info_str):buy_info_str = buy_info_str.strip()try:price_str = buy_info_str.split(' ')[1].split('元')[0]price = float(price_str)if price <= 2000:  # 检查价格范围return pricereturn 2000except (IndexError, ValueError):passreturn None

五、出版社列处理

该函数用于处理数据集中的出版社列信息,对传入的出版社信息字符串进行检查,去除其中包含无效信息的部分,筛选出有效的出版社信息。出版社信息的字符串可能是正确的出版社名称,也可能包含如日期等无效信息。若字符串是有效的出版社信息,则返回该字符串;若字符串为缺失值或者包含无效信息(如“年”或“-”),则返回 None。

def process_publish(publish_str):"""处理出版社列,去除无效信息。:param publish_str: 出版社信息字符串:return: 有效的出版社信息或None"""if pd.notna(publish_str):publish_str = publish_str.strip()if '年' not in publish_str and '-' not in publish_str:return publish_strreturn None

六、评价人数列处理

该函数的主要作用是处理包含评价人数信息的字符串,将不同格式的评价人数描述转换为对应的整数形式,以便后续的数据处理和分析。如果输入的字符串为空值或者无法正确转换为整数,则返回 None。

def process_rating_count(rating_count_str):"""处理评价人数列,将不同格式的评价人数转换为整数。:param rating_count_str: 评价人数信息字符串:return: 评价人数的整数表示或None"""if pd.notna(rating_count_str):rating_count_str = rating_count_str.strip()if rating_count_str == '(少于10人评价)':return 10elif rating_count_str == '(目前无人评价)':return 0try:rating_count = int(rating_count_str.split('(')[1].split('人')[0])return rating_countexcept (IndexError, ValueError):passreturn None

七、缺失值处理

该函数的主要功能是处理输入的DataFrame数据中的缺失值。针对数据中的不同列,采用不同的策略来处理缺失值,以提高数据的质量和可用性。

缺失值统计情况如下:

缺失值情况:
category_name        0
url                  0
img_url              0
name                12
rating           18029
rating_count         0
plot              9920
author            3842
translator       63390
publisher        15669
publish_year     15801
price            36509
dtype: int64

对于图书名称列的缺失值,使用dropna方法,指定subset为[‘name’],即删除’name’列中值为缺失值的行。

对于作者列的缺失值,首先使用replace方法,利用正则表达式r’^\s*$'匹配空字符串(包括只包含空白字符的字符串),将其替换为pd.NA(表示缺失值)。然后再使用dropna方法,删除’author’列中值为缺失值的行。

对于评分列的缺失值,使用groupby方法按’category_name’分组,然后对每个组内的’rating’列进行操作。通过transform方法,对每个组内的缺失值使用该组的评分均值(保留一位小数)进行填充。

对于情节简介列的缺失值,使用fillna方法,将’plot’列中的缺失值填充为字符串’未知’。

对于译者列的缺失值,先使用replace方法,将空字符串(包括只包含空白字符的字符串)替换为pd.NA。然后使用fillna方法,将缺失值填充为字符串’无译者’。最后使用apply方法,对每一个译者字符串应用lambda函数,去除字符串前后的空格。

对于出版社列的缺失值,类似作者列的处理方式,先将空字符串替换为pd.NA,然后删除该列中值为缺失值的行。

对于出版年份列的缺失值,按’category_name’分组,对每个组内的’publish_year’列的缺失值使用该组的中位数进行填充。

对于价格列的缺失值,按’category_name’分组,对每个组内的’price’列的缺失值使用该组的均值(保留两位小数)进行填充。

缺失值统计及处理代码如下:

def process_null_data(data):"""处理数据中的缺失值,根据不同列采用不同的处理方法。:param data: 待处理的DataFrame数据"""# data_info(data)  # 查看处理前的数据信息print("缺失值情况:")print(data.isnull().sum())# 处理各列的缺失值data.dropna(subset=['name'], inplace=True)  # 删除图书名称缺失的行data['author'] = data['author'].replace(r'^\s*$', pd.NA, regex=True)data.dropna(subset=['author'], inplace=True)  # 删除作者缺失的行data['rating'] = data.groupby('category_name')['rating'].transform(lambda x: x.fillna(x.mean().round(1)))  # 按类别填充评分缺失值data['plot'].fillna('未知', inplace=True)  # 填充情节简介缺失值data['translator'] = data['translator'].replace(r'^\s*$', pd.NA, regex=True)data['translator'].fillna('无译者', inplace=True)data['translator'] = data['translator'].apply(lambda x: x.strip())  # 去除译者前后空格data['publisher'] = data['publisher'].replace(r'^\s*$', pd.NA, regex=True)data.dropna(subset=['publisher'], inplace=True)  # 删除出版社缺失的行data['publish_year'] = data.groupby('category_name')['publish_year'].transform(lambda x: x.fillna(x.median()))  # 按类别填充出版年份缺失值data['price'] = data.groupby('category_name')['price'].transform(lambda x: x.fillna(x.mean().round(2)))  # 按类别填充价格缺失值print("处理后缺失值情况:")print(data.isnull().sum())

处理后缺失值情况如下,可以看到已经没有缺失值。

处理后缺失值情况:
category_name    0
url              0
img_url          0
name             0
rating           0
rating_count     0
plot             0
author           0
translator       0
publisher        0
publish_year     0
price            0
dtype: int64

八、重复数据处理

def process_repeat_data(data):"""处理数据中的重复值,删除重复行。:param data: 待处理的DataFrame数据:return: 处理后的DataFrame数据"""print("重复值情况:")count = data.duplicated().sum()print(count)if count > 0:data.drop_duplicates(inplace=True)return data

九、异常值处理

def process_outliers(data):"""处理数据中的异常值,对评分进行范围限制。:param data: 待处理的DataFrame数据"""print("异常值情况:")print(data.describe())data['rating'] = data['rating'].clip(0, 10)  # 限制评分范围在0-10之间

十、完整代码

豆瓣图书数据清洗与处理的完整代码如下:

import pandas as pd
from sqlalchemy import create_engine# 查看数据基本信息的函数
def data_info(data):"""打印数据的前几行、列名和基本信息。:param data: 待分析的DataFrame数据"""print("数据前几行:")print(data.head().to_csv(sep='\t', na_rep='nan'))  # 使用制表符分隔,方便查看,缺失值用nan表示print("数据列名:")print(data.columns)print("数据基本信息:")data.info()# 拆分pub列的函数
def split_pub(pub):"""拆分pub列,根据不同的分隔符和格式提取作者、译者、出版社、出版日期和价格信息。:param pub: pub列的单个值:return: 包含提取信息的Series"""if pd.isna(pub):return pd.Series([None, None, None, None, None],index=['author', 'translator', 'publisher', 'publish_date', 'price'])author = translator = publisher = publish_date = price = Noneif '/' in pub:parts = pub.split('/')if len(parts) == 5:author, translator, publisher, publish_date, price = partselif len(parts) == 4:if '.' in pub:author, publisher, publish_date, price = partselse:author, translator, publisher, publish_date = partselif len(parts) == 3:if '.' in pub:author, publish_date, price = partselse:author, publisher, publish_date = partselif len(parts) == 2:if '-' in pub and '.' in pub:publish_date, price = partselse:publisher, publish_date = partselse:if '-' in pub:publish_date = pubelif '出版社' in pub:publisher = pubelse:price = pubreturn pd.Series([author, translator, publisher, publish_date, price],index=['author', 'translator', 'publisher', 'publish_date', 'price'])# 日期列处理函数
def process_date(date_str):"""处理日期列,提取年份并进行有效性检查。:param date_str: 日期字符串:return: 有效的年份或None"""if pd.notna(date_str):date_str = date_str.strip()try:year_str = date_str[:4]if len(year_str.strip()) != 4:return Noneyear = int(year_str)if 1900 <= year <= 2025:  # 检查年份范围return yearexcept ValueError:passreturn None# 价格列处理函数
def process_buy_info(buy_info_str):"""处理价格信息,提取价格并进行有效性检查。:param buy_info_str: 包含价格信息的字符串:return: 有效的价格或None"""if pd.notna(buy_info_str):buy_info_str = buy_info_str.strip()try:price_str = buy_info_str.split(' ')[1].split('元')[0]price = float(price_str)if price <= 2000:  # 检查价格范围return pricereturn 2000except (IndexError, ValueError):passreturn None# 出版社列处理函数
def process_publish(publish_str):"""处理出版社列,去除无效信息。:param publish_str: 出版社信息字符串:return: 有效的出版社信息或None"""if pd.notna(publish_str):publish_str = publish_str.strip()if '年' not in publish_str and '-' not in publish_str:return publish_strreturn None# 评价人数列处理函数
def process_rating_count(rating_count_str):"""处理评价人数列,将不同格式的评价人数转换为整数。:param rating_count_str: 评价人数信息字符串:return: 评价人数的整数表示或None"""if pd.notna(rating_count_str):rating_count_str = rating_count_str.strip()if rating_count_str == '(少于10人评价)':return 10elif rating_count_str == '(目前无人评价)':return 0try:rating_count = int(rating_count_str.split('(')[1].split('人')[0])return rating_countexcept (IndexError, ValueError):passreturn None# 空值处理函数
def process_null_data(data):"""处理数据中的缺失值,根据不同列采用不同的处理方法。:param data: 待处理的DataFrame数据"""# data_info(data)  # 查看处理前的数据信息print("缺失值情况:")print(data.isnull().sum())# 处理各列的缺失值data.dropna(subset=['name'], inplace=True)  # 删除图书名称缺失的行data['author'] = data['author'].replace(r'^\s*$', pd.NA, regex=True)data.dropna(subset=['author'], inplace=True)  # 删除作者缺失的行data['rating'] = data.groupby('category_name')['rating'].transform(lambda x: x.fillna(x.mean().round(1)))  # 按类别填充评分缺失值data['plot'].fillna('未知', inplace=True)  # 填充情节简介缺失值data['translator'] = data['translator'].replace(r'^\s*$', pd.NA, regex=True)data['translator'].fillna('无译者', inplace=True)data['translator'] = data['translator'].apply(lambda x: x.strip())  # 去除译者前后空格data['publisher'] = data['publisher'].replace(r'^\s*$', pd.NA, regex=True)data.dropna(subset=['publisher'], inplace=True)  # 删除出版社缺失的行data['publish_year'] = data.groupby('category_name')['publish_year'].transform(lambda x: x.fillna(x.median()))  # 按类别填充出版年份缺失值data['price'] = data.groupby('category_name')['price'].transform(lambda x: x.fillna(x.mean().round(2)))  # 按类别填充价格缺失值print("处理后缺失值情况:")print(data.isnull().sum())# 重复数据处理函数
def process_repeat_data(data):"""处理数据中的重复值,删除重复行。:param data: 待处理的DataFrame数据:return: 处理后的DataFrame数据"""print("重复值情况:")count = data.duplicated().sum()print(count)if count > 0:data.drop_duplicates(inplace=True)return data# 异常值处理函数
def process_outliers(data):"""处理数据中的异常值,对评分进行范围限制。:param data: 待处理的DataFrame数据"""print("异常值情况:")print(data.describe())data['rating'] = data['rating'].clip(0, 10)  # 限制评分范围在0-10之间# 保存数据到MySQL数据库的函数
def save_to_mysql(data, table_name):"""将处理后的数据保存到MySQL数据库。:param data: 待保存的DataFrame数据:param table_name: 数据库表名"""engine = create_engine(f'mysql+mysqlconnector://root:zxcvbq@127.0.0.1:3306/douban')try:data.to_sql(table_name, con=engine, index=False, if_exists='replace')print(f'清洗后的数据已保存到 {table_name} 表')except Exception as e:print(f"保存数据到数据库时出错: {e}")if __name__ == '__main__':# 读取数据data = pd.read_csv('./原始数据层/豆瓣图书数据集.csv')# 查看数据基本信息data_info(data)# 拆分pub列data[['author', 'translator', 'publisher', 'publish_date', 'price']] = data['pub'].apply(split_pub)data.drop(['pub'], axis=1, inplace=True)data.drop(['price'], axis=1, inplace=True)data.to_csv('./中间处理层/拆分列后的豆瓣图书数据集.csv', index=False)data = pd.read_csv('./中间处理层/拆分列后的豆瓣图书数据集.csv')# 日期列处理data['publish_date'] = data['publish_date'].apply(process_date)data.rename(columns={'publish_date': 'publish_year'}, inplace=True)# 价格列处理data['price'] = data['buy_info'].apply(process_buy_info)data.drop(['buy_info'], axis=1, inplace=True)# 出版社列处理data['publisher'] = data['publisher'].apply(process_publish)# 评价人数列处理data['rating_count'] = data['rating_count'].apply(process_rating_count)# 空值处理process_null_data(data)# 重复数据处理data = process_repeat_data(data)# 异常值处理process_outliers(data)# 保存处理后的数据data.to_csv('./中间处理层/清洗后的豆瓣图书数据集.csv', index=False, encoding='utf-8-sig')# 保存分析后的数据到MySQL数据库save_to_mysql(data, '清洗后的豆瓣图书数据集')

十一、清洗与处理后的数据集展示

清洗与处理后的数据集部分数据如下图所示:

在这里插入图片描述

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

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

相关文章

Wasm -WebAssembly简介

WebAssembly 是什么&#xff1f; WebAssembly/wasm WebAssembly 或者 wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式 WebAssembly&#xff08;简称 Wasm&#xff09;是一种二进制指令格式&#xff0c;设计用于在现代 Web 浏览器中高效运行程序。它可以被认为是一…

驱动开发硬核特训 · Day 15:电源管理核心知识与实战解析

在嵌入式系统中&#xff0c;电源管理&#xff08;Power Management&#xff09;并不是“可选项”&#xff0c;而是实际部署中影响系统稳定性、功耗、安全性的重要一环。今天我们将以 Linux 电源管理框架 为基础&#xff0c;从理论结构、内核架构&#xff0c;再到典型驱动实战&a…

【SpringBoot】99、SpringBoot中整合RabbitMQ实现重试功能

最近在做一个项目,需要使用 MQ 实现重试功能,在这里给各位分享一下。 1、整合 RabbitMQ <!-- rabbitmq消息队列 --> <dependency><groupId>org.springframework.boot</groupId><

AI 中的 CoT 是什么?一文详解思维链

文章目录 CoT 的组成CoT 的作用CoT 的推理结构变体CoT 的特点CoT 的适用场景总结 在人工智能领域&#xff0c;尤其是自然语言处理和机器学习中&#xff0c;有一种名为思维链&#xff08;Chain of Thought&#xff0c;CoT&#xff09;的技术&#xff0c;它正逐渐改变着我们对 AI…

Vue3集成Element Plus完整指南:从安装到主题定制上

一、Element Plus简介 Element Plus是一套基于Vue 3.0的桌面端组件库&#xff0c;由饿了么前端团队开源维护。它提供了丰富的UI组件&#xff0c;能够帮助开发者快速构建企业级中后台产品。 1. 安装与卸载 bash 复制 下载 # 安装最新版本 npm install element-plus -S# 卸…

Java29:Spring MVC

一&#xff1a;Springmvc简介 1.简介&#xff1a; Spring Web MVC 是基于Servlet API构建的原始Web框架&#xff0c;从一开始就包含在Spring Framework中。正式名称“Spring Web MVC” 来自其源模块名称&#xff08;spring-webmvc&#xff09;但它通常被称为“Spring Mvc” …

VLC搭建本机的rtsp直播推流和拉流

媒体---流---捕获设备&#xff0c;选择摄像头&#xff0c;点击串流 x下一步 选择rtsp&#xff0c;点击添加 看到了端口&#xff0c;并设置路径&#xff1a; 选择Video -H 264 mp3(TS) 点击下一个&#xff0c; 点击流&#xff0c;就开始推流了 拉流&#xff0c;观看端&#x…

云点数据读写

一、常见点云数据格式 LAS/LAZ格式 LAS是点云数据的行业标准格式 LAZ是LAS的压缩版本 支持地理参考信息、颜色、强度等属性 PCD格式(Point Cloud Data) PCL(Point Cloud Library)开发的格式 支持ASCII和二进制存储 包含头部信息和数据部分 PLY格式(Polygon File Format…

[RHEL8] 指定rpm软件包的更高版本模块流

背景&#xff1a;挂载RHEL ISO使用kickstart安装操作系统&#xff0c;安装包未指定安装perl&#xff0c;但是安装完可以查到其版本&#xff0c;且安装的是ISO中多个版本中的最低版本。 原因&#xff1a;&#xff08;1&#xff09;为什么没有装perl&#xff0c;perl -v可以看到版…

Spring 事务管理核心机制与传播行为应用

Spring 事务详解 一、Spring 事务简介 Spring 事务管理基于 AOP&#xff08;面向切面编程&#xff09;实现&#xff0c;通过 声明式事务&#xff08;注解或 XML 配置&#xff09;统一管理数据库操作&#xff0c;确保数据一致性。核心目标&#xff1a;保证多个数据库操作的原子…

JavaScript解密实战指南:从基础到进阶技巧

JavaScript加密技术广泛应用于数据保护、反爬虫和代码混淆&#xff0c;但掌握解密方法能帮助开发者突破技术壁垒。本文结合爬虫实战与安全分析场景&#xff0c;系统梳理JS解密的核心方法与工具。 一、基础解密方法 1. Base64解码 适用于简单编码场景&#xff0c;如Cookie加密…

WEMOS LOLIN32

ESP32是結合Wi-Fi和藍牙的32位元系統單晶片&#xff08;SoC&#xff09;與外接快閃記憶體的模組。許多廠商生產採用ESP32模組的控制板&#xff0c;最基本的ESP控制板包含ESP32模組、直流電壓轉換器和USB序列通訊介面IC。一款名為WEMOS LOLIN32的ESP32控制板具備3.7V鋰電池插座。…

俄罗斯方块-简单开发版

一、需求分析 实现了一个经典的俄罗斯方块小游戏&#xff0c;主要满足以下需求&#xff1a; 1.图形界面 使用 pygame 库创建一个可视化的游戏窗口&#xff0c;展示游戏的各种元素&#xff0c;如游戏区域、方块、分数等信息。 2.游戏逻辑 实现方块的生成、移动、旋转、下落和锁…

使用安全继电器的急停电路设计

使用安全继电器的急停电路设计 一&#xff0c;急停回路的设计1&#xff0c;如何将急停接到线路当中&#xff1f;2&#xff0c;急停开关 如何接到安全继电器中 一&#xff0c;急停回路的设计 急停是每一个设备必不可少的部分&#xff0c;因为关乎安全&#xff0c;所以说所以说他…

【读书笔记·VLSI电路设计方法解密】问题64:什么是芯片的功耗分析

低功耗设计是一种针对VLSI芯片功耗持续攀升问题的设计策略。随着工艺尺寸微缩&#xff0c;单颗芯片可集成更多元件&#xff0c;导致功耗相应增长。更严峻的是&#xff0c;现代芯片工作频率较二十年前大幅提升&#xff0c;而功耗与频率呈正比关系。因此&#xff0c;芯片功耗突破…

在 Debian 10.x 安装和配置 Samba

1. 更新系统 sudo apt update sudo apt upgrade -y2. 安装 Samba sudo apt install samba -y3. 配置 Samba 备份默认配置文件 sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak编辑配置文件 sudo nano /etc/samba/smb.conf示例配置&#xff08;共享目录&#xff09; …

修改PointLIO项目

添加key_frame_info.msg消息 新建.msg文件&#xff0c;内容填写为&#xff1a; # Cloud Info Header header # cloud messages sensor_msgs/PointCloud2 key_frame_cloud_ori sensor_msgs/PointCloud2 key_frame_cloud_transed sensor_msgs/PointCloud2 key_frame_poses其中k…

关于隔离1

1.隔离的目的&#xff1a; 在隔离电源设计中&#xff0c;输入与输出之间没有直接电气连接&#xff0c;提供绝缘高阻态&#xff0c;防止电流回路。这意味着输入与输出之间呈现为绝缘的高阻态&#xff0c;从而确保了无电流回路的形成。 隔离与可靠保护有关。电隔离是一种电路设…

【java实现+4种变体完整例子】排序算法中【插入排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格

以下是插入排序的详细解析&#xff0c;包含基础实现、常见变体的完整代码示例&#xff0c;以及各变体的对比表格&#xff1a; 一、插入排序基础实现 原理 将元素逐个插入到已排序序列的合适位置&#xff0c;逐步构建有序序列。 代码示例 public class InsertionSort {void…

清醒思考的艺术

成为穿越暴风雨后的幸存者 系统性错误是指系统性的偏离理性&#xff0c;偏离最理想的、合乎逻辑的、理智的思考和行为。 “系统”一词很重要&#xff0c;因为我们经常错误地走向同一方向。 幸存偏误 幸存偏误会扭曲概率&#xff0c;系统性的高估了成功概率。一旦混淆选择标准和…