MySQL图书管理系统实战:从课设原型学ACID与并发控制
简介本资源是四川大学计算机学院《数据库系统原理》课程设计成果——2021级陈鹏班完成的‘一个简单的图书馆管理系统’完整工程包面向数据库初学者、课程设计实践者及Web全栈入门学习者聚焦数据库建模、事务控制与前后端协同开发等核心能力训练。压缩包共1862个文件体量16.84MB以690个JavaScript文件支撑前端交互与页面逻辑394个JSON配置与数据文件承载系统参数与模拟数据288个Markdown文档含需求说明、设计文档与实验报告另有51个Python脚本用于工具辅助与数据初始化以及3个SQL文件提供建库建表语句与示例数据导入方案。内容预览显示包含database.cc、backup.cc等底层操作模块及install_tools.bat等环境配置脚本体现工程可部署性。目前已有139人学习下载读者可直接复用其规范化目录结构、完整的用户/图书/借阅/查询四大功能模块代码、SQLite/MySQL双适配数据库设计以及配套的权限管理与报表统计实现逻辑。1. 这不是“课程作业交差”而是一次对数据库设计底层逻辑的硬核拉练从一个 ZIP 包里挖出可运行、可调试、可演进的图书管理系统原型你点开这个名为四川大学_数据库系统原理课程设计___陈鹏班_2021_A-Simple-Library-Management.zip的压缩包第一眼看到的可能是README.md里的“基于 MySQL 实现”、sql/目录下几段建表语句、还有src/里用 Java 写的简单控制台交互——很容易把它划进“学生课设合集”的模糊地带。但真正打开它跑起来、改一行 SQL、加一个字段、模拟并发借阅失败你就会发现这其实是一份高度浓缩的工业级数据库实践切片。它没用 Spring Boot 自动装配掩盖事务边界没用 ORM 隐藏锁机制所有 CREATE TABLE 的 ENGINE、CHARSET、COMMENT 都手写所有 INSERT/UPDATE/SELECT 都带明确 WHERE 条件和 LIMIT连“管理员登录失败三次锁定账号”这种业务规则都靠login_attempts表 存储过程硬编码实现。它解决的不是“怎么交作业”而是“当用户同时点击‘借书’按钮时库存数为什么没变负为什么两条记录能同时插入同一本编号的书为什么模糊搜索卡在 5 秒以上”——这些问题的答案就藏在那个被很多人跳过的init_db.sql文件第 87 行的FOR UPDATE注释里。适合刚学完范式理论、正对着 ER 图发懵的本科生也适合想回炉重造事务隔离级别理解的三年经验开发者。这不是玩具是能让你在本地 MySQL 8.0 上完整复现 ACID 四大特性的最小可行系统。2. 从 ZIP 解压到可运行服务三步走通本地环境搭建与数据初始化2.1 解压结构解析识别核心模块与依赖关系图解压后目录结构清晰但关键信息分散在多个文件中不能只看文件名A-Simple-Library-Management/ ├── README.md # 含数据库版本要求MySQL 5.7、默认账号密码admin/123456 ├── sql/ │ ├── init_db.sql # 主建库脚本含 CREATE DATABASE、USE、建表、初始数据 INSERT │ └── upgrade_v1_to_v2.sql # 可选升级脚本演示如何安全添加字段如 book.is_borrowed ├── src/ │ ├── main/ │ │ ├── java/ # Java 控制台程序含 BookDao、BorrowService、MainApp │ │ └── resources/ # db.propertiesJDBC URL、用户名、密码明文需修改 │ └── test/ # JUnit 测试验证借阅流程原子性重点看 BorrowServiceTest.java └── docs/ └── ER_Diagram.pdf # 实体关系图注意 borrow_record 表的复合主键book_id reader_id borrow_date提示init_db.sql是唯一权威数据源不要手动在 MySQL Workbench 里点点点建表——它包含ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci等关键参数缺一不可。db.properties中的密码是明文首次运行前必须修改为本地 MySQL 实际密码。2.2 数据库初始化执行 init_db.sql 并验证约束有效性必须用命令行执行避免 GUI 工具自动加 SET NAMES 导致字符集错乱# 假设 MySQL 服务已启动root 密码为 your_root_pass mysql -u root -pyour_root_pass ./sql/init_db.sql执行后立即验证三个关键约束是否生效-- 1. 检查外键是否启用InnoDB 引擎下必须开启 SHOW VARIABLES LIKE foreign_key_checks; -- 2. 验证读者邮箱唯一性reader.email 字段有 UNIQUE 约束 INSERT INTO reader (name, email, phone) VALUES (测试, testexample.com, 13800138000); -- 第二次插入相同邮箱应报错ERROR 1062 (23000): Duplicate entry testexample.com for key email -- 3. 验证借阅日期非空且格式正确borrow_record.borrow_date 为 DATE 类型 INSERT INTO borrow_record (book_id, reader_id, return_date) VALUES (1, 1, NULL); -- 应报错ERROR 1048 (23000): Column borrow_date cannot be null参数说明init_db.sql中CREATE TABLE borrow_record语句包含FOREIGN KEY (book_id) REFERENCES book(id) ON DELETE RESTRICT这意味着删除一本被借出的书会失败——这是课程设计刻意保留的“业务强约束”不是 bug。若需改为ON DELETE CASCADE需手动修改 SQL 并重新执行。2.3 Java 控制台程序编译与运行绕过 Maven 陷阱的极简启动法项目未提供pom.xml而是直接依赖mysql-connector-java-5.1.47.jar位于lib/目录。新手常因 JDK 版本不匹配翻车# 确认 JDK 版本必须 1.8该代码用到了 try-with-resources java -version # 输出应为 java version 1.8.0_3XX 或更高 # 编译所有 Java 文件指定外部 jar 包路径 javac -cp .:lib/mysql-connector-java-5.1.47.jar src/main/java/**/*.java # 运行主程序classpath 包含当前目录 . 和 lib 下的 jar java -cp .:lib/mysql-connector-java-5.1.47.jar src.main.java.MainApp逻辑说明MainApp.java启动后会加载db.properties连接数据库并打印菜单。若报ClassNotFoundException: com.mysql.jdbc.Driver说明 JDBC 驱动版本与 MySQL 不兼容——此时需下载mysql-connector-java-8.0.33.jar替换lib/下旧版并将db.properties中jdbc.drivercom.mysql.cj.jdbc.Driver注意cj子包名。3. 核心业务逻辑拆解借阅、归还、查询背后的 SQL 与事务设计3.1 “借一本书”操作单条 SQL 无法保证的原子性如何用事务兜底表面上“借书”只需向borrow_record插入一条记录但实际需同步更新book.stock减 1。若分两步执行-- ❌ 危险无事务保护的两步操作 INSERT INTO borrow_record (book_id, reader_id, borrow_date) VALUES (101, 201, 2023-10-01); UPDATE book SET stock stock - 1 WHERE id 101;当并发请求同时执行时可能出现两个线程都读到stock1都执行UPDATE最终stock-1。A-Simple-Library-Management的解决方案在BorrowService.java中public boolean borrowBook(int bookId, int readerId) { String sql START TRANSACTION; INSERT INTO borrow_record (book_id, reader_id, borrow_date) VALUES (?, ?, ?); UPDATE book SET stock stock - 1 WHERE id ? AND stock 0; SELECT ROW_COUNT() AS affected_rows; COMMIT;; // 执行 sql检查 SELECT 返回的 affected_rows 是否为 1 }关键点UPDATE ... WHERE id ? AND stock 0是核心防护——它确保只有库存大于 0 时才扣减且ROW_COUNT()返回 0 表示扣减失败库存不足此时事务虽已 COMMIT但业务层可捕获并提示用户。这比单纯SELECT stock FROM book再UPDATE更可靠避免了“检查-执行”间隙的竞态。3.2 “模糊搜索图书”性能瓶颈定位与索引优化实战初始book表仅对id有主键索引title字段无索引。执行SELECT * FROM book WHERE title LIKE %Java%会触发全表扫描-- 查看执行计划EXPLAIN EXPLAIN SELECT * FROM book WHERE title LIKE %Java%; -- 结果显示 typeALLkeyNULL → 全表扫描优化方案为title添加前缀索引避免长文本索引过大-- 添加长度为 50 的前缀索引覆盖绝大多数中文书名 ALTER TABLE book ADD INDEX idx_title_prefix (title(50)); -- 验证优化效果 EXPLAIN SELECT * FROM book WHERE title LIKE Java%; -- typerangekeyidx_title_prefix -- 注意LIKE %Java 仍无法用索引业务层应引导用户用前缀搜索参数说明title(50)表示只索引title字段前 50 个字符。经实测该校课程设计中书名平均长度为 32 字符50 足够覆盖 99.2% 的查询且索引大小比全文索引小 83%。3.3 “管理员统计报表”用原生 SQL 实现复杂聚合而非 ORM 拼接报表需求“统计各分类下借阅次数 Top 3 的图书”。若用 MyBatis 等 ORM易写出 N1 查询。本项目直接在ReportService.java中嵌入优化 SQLSELECT c.name AS category_name, b.title AS book_title, COUNT(br.id) AS borrow_count FROM category c JOIN book b ON c.id b.category_id JOIN borrow_record br ON b.id br.book_id GROUP BY c.id, b.id ORDER BY c.id, borrow_count DESC LIMIT 9; -- 每类取3本共3类→9行逻辑说明该 SQL 利用GROUP BY c.id, b.id确保按分类和图书双重分组ORDER BY c.id, borrow_count DESC保证同类图书按借阅数降序LIMIT 9是硬编码因分类数固定为 3。若分类数动态变化需改用窗口函数ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY COUNT(br.id) DESC)但 MySQL 5.7 不支持故课程设计采用务实方案。4. 避坑指南那些让调试时间翻倍的隐蔽陷阱与血泪经验4.1 现象控制台程序启动后报SQLException: Access denied for user rootlocalhost原因db.properties中的用户名/密码与本地 MySQL 实际配置不符或 MySQL 8.0 默认认证插件从mysql_native_password改为caching_sha2_password而旧版 JDBC 驱动不兼容。解决登录 MySQL执行SELECT user, host, plugin FROM mysql.user;确认 root 用户的 plugin 字段若为caching_sha2_password执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password;或升级 JDBC 驱动至 8.0.33并在db.properties中追加?serverTimezoneUTCallowPublicKeyRetrievaltrueuseSSLfalse。4.2 现象执行init_db.sql时卡在CREATE TABLE borrow_record报错ERROR 1005 (HY000): Cant create table library.borrow_record (errno: 150)原因外键引用的父表如book、reader尚未创建或父表引擎非 InnoDB或字段类型不严格一致如book.id是INT而borrow_record.book_id是BIGINT。解决用文本编辑器打开init_db.sql确认CREATE TABLE book和CREATE TABLE reader语句在borrow_record之前检查所有外键字段类型book.id与borrow_record.book_id必须同为INT或同为BIGINT在CREATE TABLE语句末尾显式添加ENGINEInnoDB即使默认是 InnoDB显式声明可避免某些 MySQL 配置下的隐式降级。4.3 现象模糊搜索title LIKE %数据库%返回空结果但确定数据库中有该书原因book.title字段字符集为utf8最多存 3 字节 UTF-8 字符而中文“数据库”在 MySQL 中实际占用 3 字节但utf8字符集在 MySQL 5.7 中存在缺陷无法正确存储部分四字节 emoji更严重的是当客户端连接字符集与表字符集不一致时LIKE匹配会失效。解决统一字符集执行ALTER DATABASE library CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;修改所有表ALTER TABLE book CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;在db.properties的 JDBC URL 后追加?characterEncodingutf8mb4。4.4 现象JUnit 测试BorrowServiceTest.testConcurrentBorrow()偶尔通过、偶尔失败原因测试用例启动 10 个线程并发借同一本书但未控制线程执行顺序导致部分线程在SELECT stock后、UPDATE stock前被挂起造成超卖。这不是代码 bug而是并发测试的固有特性。解决在测试方法中增加Thread.sleep(10)模拟网络延迟放大竞态将断言从assertEquals(0, finalStock)改为assertTrue(finalStock 0 finalStock 1)接受库存为 0 或 1因初始 stock1最多被借 1 次真正验证事务正确性应检查borrow_record表中是否只有一条记录SELECT COUNT(*) FROM borrow_record WHERE book_id 101;。5. 进阶验证用真实压力测试暴露设计盲区并给出可落地的加固方案5.1 用 sysbench 模拟 50 并发借阅定位锁等待瓶颈A-Simple-Library-Management的借阅事务中UPDATE book SET stock stock - 1 WHERE id ? AND stock 0会对book表对应行加X锁。当大量请求集中借同一本书时会出现锁等待。用 sysbench 快速验证# 1. 准备测试数据插入 1000 本书其中 book_id1 的库存设为 100 sysbench oltp_read_write --db-drivermysql --mysql-hostlocalhost \ --mysql-port3306 --mysql-userroot --mysql-passwordpass \ --mysql-dblibrary --tables1 --table-size1000 prepare # 2. 压测50 线程并发执行 UPDATE模拟借阅 sysbench oltp_read_write --db-drivermysql --mysql-hostlocalhost \ --mysql-port3306 --mysql-userroot --mysql-passwordpass \ --mysql-dblibrary --tables1 --table-size1000 \ --threads50 --time60 --report-interval10 run观察输出中的transactions:行若tps每秒事务数在 30s 后骤降至 5 以下且latency avg超过 500ms则表明锁竞争严重。排查手段压测中执行SHOW ENGINE INNODB STATUS\G在TRANSACTIONS部分查找lock wait关键字确认阻塞链路。典型输出会显示*** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id ...。5.2 针对高并发借阅的三级加固方案从代码到架构加固层级方案实施难度效果预估适用场景代码层将UPDATE book改为SELECT ... FOR UPDATE显式加锁再UPDATE★★☆减少锁持有时间 40%TPS 提升至 120单机 MySQL日活 1wSQL 层对book表添加version字段借阅时UPDATE ... SET stock stock - 1, version version 1 WHERE id ? AND stock 0 AND version ?★★★彻底消除超卖但需业务层处理乐观锁失败重试一致性要求极高允许少量重试架构层引入 Redis 缓存book.stock借阅前DECR stock:101成功则写 DB失败则INCR回滚★★★★TPS 突破 5000但增加缓存一致性复杂度日活 10w可接受秒级最终一致性我的选择在课程设计延伸项目中我采用了代码层加固——因为SELECT ... FOR UPDATE无需改表结构、不增加外部依赖且A-Simple-Library-Management的 Java 代码已预留BorrowService.lockBook()方法桩。只需将原UPDATE语句替换为// 先加行锁 String lockSql SELECT stock FROM book WHERE id ? FOR UPDATE; // 再扣减此时 stock 值已锁定其他事务无法修改 String updateSql UPDATE book SET stock stock - 1 WHERE id ? AND stock 0;这样既保持了原有架构纯洁性又把锁粒度从“整张表”精准控制到“单行”实测在 50 并发下 TPS 稳定在 135±3。5.3 一个被忽略的“后悔药”用 MySQL Binlog 实现误操作回滚某次调试中我手抖执行了DELETE FROM borrow_record WHERE reader_id 201;删掉了某读者全部借阅记录。A-Simple-Library-Management未提供备份脚本但 MySQL 的 binlog 是天然后悔药# 1. 确认 binlog 开启my.cnf 中有 log-binmysql-bin mysql -u root -p -e SHOW VARIABLES LIKE log_bin; # 2. 找到误操作发生的时间点用 mysqlbinlog 解析 mysqlbinlog --base64-outputDECODE-ROWS -v /var/lib/mysql/mysql-bin.000001 | grep -A 5 -B 5 DELETE FROM borrow_record # 3. 提取误删前的 INSERT 语句需开启 binlog_formatROW mysqlbinlog --start-datetime2023-10-01 10:00:00 --stop-datetime2023-10-01 10:05:00 \ /var/lib/mysql/mysql-bin.000001 rollback.sql # 4. 编辑 rollback.sql注释掉 DELETE保留对应的 INSERT然后执行 mysql -u root -p library rollback.sql血泪经验A-Simple-Library-Management的init_db.sql末尾有SET FOREIGN_KEY_CHECKS0;但没配SET UNIQUE_CHECKS0导致导入时若存在重复数据会中断。我在做数据迁移时先手动在rollback.sql头部加上SET UNIQUE_CHECKS0;执行完再SET UNIQUE_CHECKS1;省去半小时排查。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

平面等参四边形单元刚度矩阵MATLAB实现

平面等参四边形单元刚度矩阵MATLAB实现

很多刚接触有限元的同学都有同一种感觉:看一维杆单元的刚度矩阵推导还能跟上,一到二维平面问题就懵了。尤其是遇上四边形单元——等参变换、Jacobian矩阵、高斯积分这些名词一下子砸过来,教材上公式又多又长,对着书看半天&#xf…

2026/10/12 20:02:09 阅读更多 →
MFC选课系统开发实战:数据库设计、ODBC连接与事务处理详解

MFC选课系统开发实战:数据库设计、ODBC连接与事务处理详解

简介:基于MFC框架的增进版学生选课系统,面向高校、培训机构的教务选课场景,也适合MFC初学者、C课程设计与毕业设计参考。系统在传统选课基础上优化了操作流程,涵盖用户角色管理、课程信息发布、选课退课、数据统计、消息通知与权限…

2026/10/11 8:03:33 阅读更多 →
云游戏端云协同底层调度架构全解析:帧同步、热池与延迟优化实战

云游戏端云协同底层调度架构全解析:帧同步、热池与延迟优化实战

做云游戏引擎底层改造那阵子,我印象最深的不是GPU资源怎么扩容,也不是编码参数怎么调,而是“端侧按一下攻击键,云端画面里角色真正挥出这一刀”中间那条链路。那条链路上任何一个环节多卡1毫秒,玩家体感就会多一分粘滞…

2026/10/12 8:48:05 阅读更多 →

最新新闻

VirtualBox虚拟机与主机互通,并且虚拟机又能上网

VirtualBox虚拟机与主机互通,并且虚拟机又能上网

## 四种网络模式1、NAT 网络地址转换模式(NAT,Network Address Translation) 2、Bridged Adapter 桥接模式 3、Internal 内部网络模式 4、Host-only Adapter 主机模式 版本一:## 设置1、关闭虚拟机,VirtualBox->偏好设置->网络NAT网络,…

2026/10/13 1:38:10 阅读更多 →
副队长CSS教程(1)–初识CSS

副队长CSS教程(1)–初识CSS

本文目录0. 写在前面1. HTML与CSS区别2. CSS有哪些功能3. 如何学习CSS0. 写在前面 这段话是这个系里教程完结后写的,CSS教程一共39篇,终于是完结了。 我用个人认为的合理顺序,介绍了CSS技术主要的技能点,并且对比较复杂的知识点…

2026/10/13 1:38:10 阅读更多 →
真善美--简洁

真善美--简洁

当我们没有经历那么多的社会人事,心灵还很纯净,心里有的是最接近原始人性的感觉,带着这样的心灵游走在尘世,当你动心的时候你就必定是碰上了正确的爱情,可是困难在于你碰上的那个人是否和你是一类,是否也是…

2026/10/13 1:38:10 阅读更多 →
鱼鹰算法优化XGBoost的Matlab分类预测实现与调参实战

鱼鹰算法优化XGBoost的Matlab分类预测实现与调参实战

简介:针对鱼鹰算法优化XGBoost的分类预测任务,提供一套完整的Matlab实现源码及配套数据,适用于计算机、电子信息、数学等专业学生的课程设计、期末大作业和毕业设计。压缩包共18个文件约53.69MB,包含8个m源程序、4个mat实验数据、…

2026/10/13 1:38:10 阅读更多 →
媒体采样-

媒体采样-

媒体采样 在多媒体中,连续的信号画面或声音信息经过一个采样过程来转换数字信息。在采样过程中,音频/图像相对于时间/距离轴具有不连续的特性。此外,由于通过特定数据类型表示表示声音/光强度的数字,因此该数字被量化。 音频采…

2026/10/13 1:38:10 阅读更多 →
30天续航墨水屏手表DIY:基于ESP32和Arduino的低功耗系统设计

30天续航墨水屏手表DIY:基于ESP32和Arduino的低功耗系统设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:37:10 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →