news 2026/10/17 21:26:43

GreatSQL数据库原理实验:部署、建表、查询与避坑全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GreatSQL数据库原理实验:部署、建表、查询与避坑全流程

简介:郑州大学计算机与人工智能学院《数据库系统原理》课程实验报告,适合数据库初学者、正在完成同类实验的高校学生及复习备考者。报告完整记录了数据库原理实验的关键环节,重点展示万里数据库GreatSQL在CentOS虚拟机中的安装、配置与使用流程,包括关闭SELinux和防火墙的原因与命令、依赖包安装、二进制包下载解压、mysql系统用户及系统服务创建、启动与状态检查等,并配有进程、TCP连接、数据库文件等截图和命令说明。内容还覆盖数据库系统逻辑组件(基本表、视图、触发器、存储过程、约束)与物理组件的理解,以及实验报告撰写规范,如截图需带编号图题、表格需编号表名等,可帮助读者规范完成课程实验。压缩包仅含1个docx文档,大小3.69MB,结构紧凑便于阅读;已有509人学习,特别适合作为课程实验的环境搭建参考和排错思路借鉴。

1. 说到数据库原理实验报告,这套 GreatSQL 实验的练习远不止交差

数据库原理课程的实验报告,很多人的第一反应是“把教材上的 SQL 跑一遍,截图贴上去”。但这套实验包的价值比交差要大不少:它把环境配置、建库建表、索引管理、交互式查询和报告排版全部串成了一条可复现的路线。前三个实验从安装一个基于 MySQL 8.0 内核的国产数据库发行版起步,再到创建 STUDENTS、COURSES、SC 三张表,最后把 WHERE、IN、BETWEEN 这些查询条件逐条跑通;报告规范里还专门强调了截图编号、表格编号和书面语表达。对于正在赶实验报告、不想在命令行里来回翻车的同学,这套资料的命令可以直接抄;对于想脱离图形界面、通过终端理解数据库管理系统的初学者,它也是一份从零到查询的完整走查记录。

2. 环境搭建:为什么要关 SELinux,以及数据库二进制包的正确安装方式

2.1 安全策略的取舍:SELinux 和 firewalld 为什么必须处理

安装文档的一开始就出现了setenforce=0和systemctl stop firewalld两条命令。很多第一次接触 Linux 数据库部署的人会疑惑:数据库运行和安全策略冲突吗?答案是会冲突,尤其在 CentOS 7 这种默认开启 SELinux 的系统上。

SELinux 是强制访问控制机制,它给文件、进程、端口都打上了安全标签。数据库服务启动时要读取/etc/my.cnf、写入/var/lib/mysql、绑定 3306 端口,这些操作如果和 SELinux 的进程域不匹配,mysqld就可能出现权限拒绝。表现五花八门:有时候是启动后立即退出,有时候是能启动但无法创建 socket 文件。关闭 SELinux 不见得是最优解,但在教学环境里,它能把变量控制到最小,让后续实验的精力集中在 SQL 本身。防火墙同理——默认的 firewalld 区域不会放行 3306 端口,如果后面要使用图形化客户端做远程连接,端口不通会让人误判为服务没起来。

这里要特别提醒:setenforce=0只对当前运行状态生效,重启系统后 SELinux 会回到 enforcing。真正要永久关闭,必须修改/etc/selinux/config。实验报告里给的那条sed命令就是做这个的,它把配置文件中以SELINUX=开头的行整体替换成了SELINUX=disabled。

setenforce=0 sed -i '/^SELINUX=/c'SELINUX=disabled /etc/selinux/config systemctl disable firewalld systemctl stop firewalld

命令说明:第一行立刻把 SELinux 切换到 permissive 模式,相当于临时放开限制;第二行持久化修改配置,防止重启后失效;第三行disable让 firewalld 不再开机自启;第四行stop立即关闭防火墙。实际工作中如果只是想临时测一下,只执行第一和第四行就够了,但在实验环境里两条都要写,否则下次开机又会被安全策略拦住。

2.2 依赖包清单与二进制解压:每个参数都在解决什么问题

在下载二进制包之前,先要解决依赖库。数据库发行版虽然自带大部分运行库,但 glibc 环境下的部分扩展库还需要系统提供。实验里给出的依赖安装命令是这样的:

yum install -y pkg-config perl libaio-devel numactl-devel numactl-libs net-tools openssl openssl-devel jemalloc jemalloc-devel perl-Data-Dumper perl-Digest-MD5 python2 perl-JSON perl-Test-Simple

这里几个包值得单独说。libaio-devel是异步 I/O 的开发库,InnoDB 存储引擎的读写操作会用到它,缺失时可能导致初始化失败;jemalloc是内存分配器,官方二进制包推荐用它提升内存分配效率;numactl-devel和numactl-libs用于 NUMA 架构下的 CPU 内存绑定,多核服务器上对性能有影响;perl-Data-Dumper和perl-JSON是数据库自带运维脚本的运行依赖。如果是最小化安装的 CentOS,yum源里可能没有这些包,需要先执行yum install -y epel-release扩展软件源。

依赖装完后,进入下载和解压阶段。实验选择的是官方预编译二进制包,而不是源码编译。二进制包的好处是解压即用,不需要经历漫长的cmake和make过程,缺点是对系统环境敏感,所以前面那串依赖必须装齐。

cd /usr/local wget https://product.greatdb.com/GreatSQL-8.0.32-25/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz tar xf GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal.tar.xz

下载链接指向的是 8.0.32-25 版本的 minimal 最小化安装包。冠以 glibc2.17 表示它可以在 CentOS 7 的默认 glibc 版本下运行。tar xf不需要加-z,因为.xz解压由xz工具处理,CentOS 7 默认已经自带了。解压完成后,/usr/local/下会出现对应版本的目录,后面启动服务就是指向这个目录里的bin/mysqld。

接着是创建 mysql 系统用户和数据目录。数据库服务不允许直接以 root 身份运行,这是安全底线。mysql用户不分配登录 shell,只用于运行守护进程:

/sbin/groupadd mysql /sbin/useradd -g mysql mysql -d /dev/null -s /sbin/nologin mkdir /var/lib/mysql/ chown -R mysql:mysql /var/lib/mysql/ /var/log /usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal

chown -R将数据目录、日志目录和安装目录都归属给 mysql 用户。如果漏掉这一步,mysqld启动时无法在/var/lib/mysql下创建系统表文件,会直接报 “Permission denied”。这类错误非常隐蔽,因为命令执行时本身不会提示。

2.3 服务注册到 systemd:启动、状态检查和常见失败定位

二进制包不会自动生成 systemd 服务文件,需要手动创建一个。这个文件把数据库进程交给 systemd 托管,之后就能用systemctl start/stop/status来管理,不需要每次手敲mysqld_safe。

vim /lib/systemd/system/greatsql.service

服务文件的核心内容如下:

[Unit] Description=GDB Server After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/GreatSQL-8.0.32-25-Linux-glibc2.17-x86_64-minimal/bin/mysqld LimitNOFILE=65535 [Install] WantedBy=multi-user.target

User=mysql和Group=mysql指定进程以哪个身份运行,和前面创建的用户对应。After=network.target表示网络服务就绪后再启动数据库,避免监听端口时网络还没准备好。LimitNOFILE=65535把文件描述符上限调大,数据库并发连接高时会创建大量 socket 和文件句柄,默认 1024 的限制很容易触顶。

写完服务文件后必须执行systemctl daemon-reload,systemd 才会重新读取配置文件。之后启动数据库:

systemctl start greatsql systemctl status greatsql ps -ef | grep mysqld ss -lntp | grep mysqld ls /var/lib/mysql

systemctl status能看到服务是否处于 active 状态、进程 PID 以及最近的日志输出。ps -ef | grep mysqld检查进程是否真实存在,如果只显示 grep 自身,说明服务启动后崩了。ss -lntp | grep mysqld确认 3306 端口在监听。最后列一下/var/lib/mysql数据目录,如果里面有mysql.ibd、ibdata1这些初始化文件,说明首次启动已经完成了系统库初始化。

启动之前还应该检查/etc/my.cnf是否存在。如果文件缺失,mysqld会使用编译时默认配置,数据目录可能指向/var/lib/mysql以外的位置。常见的做法是最少写上三段配置:

[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock port=3306 character-set-server=utf8mb4

character-set-server=utf8mb4这一行非常关键。默认字符集在旧版本里可能是latin1,插入中文时命令行显示会变成乱码,排序规则也会受影响。实验环境里如果一开始没配,后面建表时每个字段都得手动指定字符集,非常麻烦。如果服务启动失败,第一件事是执行journalctl -u greatsql -n 50看日志,不要盲目重启。常见的失败原因就三类:数据目录权限不对、配置文件里的路径不存在、依赖库缺失。

3. 建库建表建索引:从逻辑设计到物理文件都要讲清楚

3.1 创建数据库 DB,以及数据页、表空间这些物理概念

实验二的第一步是创建一个名为 DB 的数据库。这个操作在原理上很简单,但它带出了一个值得深挖的问题:数据库文件到底存在哪里?

CREATE DATABASE DB; SHOW DATABASES; USE DB;

在 MySQL 系列的存储引擎里,CREATE DATABASE做的事情是在数据目录下创建一个同名子目录。默认数据目录由/etc/my.cnf里的datadir指定,通常是/var/lib/mysql。执行完上面三条命令后,可以到系统里确认一下:

ls /var/lib/mysql | grep -i db

如果能看到一个名为db的目录,说明数据库创建成功。这个目录在初始化时是空的,后续创建的表会以独立文件的形式出现在这里。InnoDB 引擎的表会同时生成.ibd文件存放数据行和索引,表结构则记录在数据字典中。

物理存储的单位是数据页,默认大小通常是 16384 字节。数据页是 InnoDB 从磁盘读取和写入的最小单位,一页里可能存放多行数据,也可能一个表有几百个页。理解数据页的意义在于:为什么查询走索引比全表扫描快,本质上就是减少了需要读取的数据页数量。实验报告里如果能写一句“数据以数据页存储,表对应一个或多个页文件”,这部分的得分点基本就拿到了。

3.2 STUDENTS、COURSES、SC 三张表:字段类型为什么这么选

建表的第一个版本非常简单,id int primary key这种结构适合快速演示,但不符合教材的语义需求。实验里从简版改成正式版,这一步是理解字段类型的好机会。

CREATE TABLE STUDENTS( Sno char(9) PRIMARY KEY, Sname char(10) NOT NULL, Sex char(2), Birthday DATE, Speciality char(20), Dno char(4) ); CREATE TABLE Courses( Cno char(5) PRIMARY KEY, Cname char(20) NOT NULL, Period int, Credit int ); CREATE TABLE SC( Sno char(9), Cno char(5), Grade int, PRIMARY KEY (Sno, Cno) );

参数说明:学号 Sno 用char(9)而不是int,是因为学号是编号而非数值,它不需要参与加减乘除,而且用字符类型可以保留前导零,以后如果出现类似“001”的编号也不会丢失信息。Sname 加NOT NULL,姓名不应该为空。Sex 用char(2),教材里的取值只有“男”和“女”两个汉字。Birthday 用DATE类型,而不是字符串,这样后续可以使用日期函数做年龄计算。SC 表的主键是(Sno, Cno)复合主键,因为一个学生选一门课的成绩记录,需要学生和课程两个维度才能唯一确定。

在正式创建三张表之前,实验里先演示了删除操作:

DROP TABLE students CASCADE; DROP TABLE courses CASCADE; DROP TABLE sc CASCADE;

实际上 MySQL 的DROP TABLE并不支持CASCADE关键字,这是 Oracle 数据库的写法。如果直接复制到命令行里执行,会报语法错误。正确写法是直接DROP TABLE 表名。这个问题也提醒了一件事:教材里的 SQL 不能无脑照抄,需要根据具体的数据库产品调整。

填充数据是建表后的必做步骤。这里要注意插入顺序——先插入父表,再插入子表:

INSERT INTO STUDENTS VALUES ('201705001', '张华', '男', '1999-12-16', '计算机', 'CS'), ('201705002', '张晓霞', '女', '1999-01-01', '软件工程', 'SE'), ('201706001', '李玉', '女', '1999-10-17', '数学', 'MA'); INSERT INTO COURSES VALUES ('CS101', '计算机科学导论', 2, 1), ('CS102', '数据库系统', 4, 4), ('CS103', '操作系统', 4, 3); INSERT INTO SC VALUES ('201705001', 'CS101', 89), ('201705002', 'CS102', 92), ('201705003', 'CS101', 88);

这段插入脚本隐藏着一个坑。SC 表里出现了201705003,但 STUDENTS 表的插入数据里只有201705001、201705002和201706001,没有201705003。如果在创建 SC 表时同时定义了外键约束,这条插入就会直接违反外键约束,返回Cannot add or update a child row。教材数据里这种不一致很常见,实验时要么把 STUDENTS 表补上对应学号,要么去掉外键约束再插入。这个细节后面避坑章节还会展开。

3.3 索引:普通索引、唯一索引与删除操作

索引是数据库原理实验的必考内容。实验要求在 Students 表的 Dno 字段上创建普通索引,在 Courses 表的 Cno 字段上创建唯一索引:

CREATE INDEX Student_Dept ON Students (Dno); CREATE UNIQUE INDEX Course_Cno ON Courses (Cno);

普通索引声明的语义是“允许重复值”,它只加速查询,不约束数据。Dno 是院系编号,一个系有多个学生,所以这里用普通索引合适。唯一索引的语义是“字段值不能重复”,Cno 本来就是主键,主键本身已经隐含唯一索引,这里再创建一个唯一索引属于锦上添花,主要演示UNIQUE关键字。

删除索引的语法和 Oracle 不同,MySQL 使用DROP INDEX 索引名 ON 表名:

DROP INDEX Course_Cno ON Courses;

删除后可以再次执行SHOW INDEX FROM Courses;验证索引是否移除。这里有一个设计上的问题值得思考:主键和唯一索引都能保证唯一性,为什么还需要主键?主键是表的逻辑标识,每行数据必须有且只有一个;唯一索引只是业务约束,不一定是行的身份标识。索引不是越多越好,每个索引在加速查询的同时都会拖慢插入和更新操作,因为写入数据时,所有索引都需要同步维护。这种“读写权衡”的观念,实验报告的分析部分可以写进去。

最后处理表间约束。SC 表中的 Sno、Cno 分别引用 Students 和 Courses,正确做法是在建表后用ALTER TABLE补上外键:

ALTER TABLE SC ADD CONSTRAINT fk_sc_sno FOREIGN KEY (Sno) REFERENCES Students(Sno); ALTER TABLE SC ADD CONSTRAINT fk_sc_cno FOREIGN KEY (Cno) REFERENCES Courses(Cno);

但这里有个执行前提:SC 表里的 Sno 和 Cno 值,在父表里必须已经存在。如果上面插入的 SC 数据里有201705003,而这个学号在 Students 表里不存在,这条ALTER TABLE会直接失败。所以遇到外键约束添加失败,不要怀疑语法,先查数据完整性。

4. 交互式 SQL 查询:把教材上的 WHERE、IN、BETWEEN 跑成自己的数据

4.1 全部查询与计算字段:不带 WHERE 的简单场景

实验三的第一步是先建好完整的数据表,再开始各种查询。不带 WHERE 的查询最简单,但里面也藏着一个小知识点——计算字段。

SELECT * FROM Courses; SELECT Sname, 2024 - YEAR(Birthday) AS Age FROM Students;

第一条查询返回 Courses 表的全部列,没有任何过滤条件,执行计划里走的是全表扫描。第二条查询里YEAR(Birthday)从日期字段中提取出生年份,然后用当前年份减去它得到年龄。这里有个隐患:如果系统当前时间不是 2024 年,算出来的年龄就是错的。更严谨的做法是用TIMESTAMPDIFF(YEAR, Birthday, CURDATE()),它会自动根据当前时间计算精确年龄。

SELECT Sname, TIMESTAMPDIFF(YEAR, Birthday, CURDATE()) AS Age FROM Students;

TIMESTAMPDIFF是 MySQL 系列的日期差函数,第一个参数指定单位,第二个参数是起始日期,第三个参数是结束日期。这个函数的好处是不用硬编码年份,每年的结果都正确。实验报告里如果写“计算字段可以用 YEAR 函数,也可以用 TIMESTAMPDIFF 更严谨”,体现的思路会让报告加分。

4.2 条件查询:等于、小于、范围与 NOT 的组合

带 WHERE 的查询是交互式 SQL 的核心。实验里要求按教材完成多个查询实例,这里挑几个典型写法拆解:

SELECT Tname, Sex FROM Teachers WHERE Title = '讲师'; SELECT DISTINCT Sno FROM SC WHERE Grade < 60; SELECT Sname, Speciality FROM Students WHERE YEAR(Birthday) BETWEEN 1997 AND 1999; SELECT Sname, Speciality FROM Students WHERE YEAR(Birthday) NOT BETWEEN 1997 AND 1999;

第一条WHERE Title = '讲师'用了字符串等值比较。中文引号会导致语法错误,这里必须用 ASCII 单引号。第二个查询用DISTINCT去重,查出所有考试不及格的学生学号;如果不加DISTINCT,同一个学号挂科多门课会出现多行。对于实践报告,提醒"不及格课程多门时用DISTINCT"很实用。

第三和第四条是范围查询。BETWEEN 1997 AND 1999是闭区间,等价于>= 1997 AND <= 1999;NOT BETWEEN取反。这个写法比手写两个比较条件更清晰。注意YEAR(Birthday)函数把日期转成年份再做比较,这是对字段套函数,如果 Birthday 列上有索引,套函数会导致索引失效,全表扫描。数据量小无所谓,但如果到了几十万行的场景,应该改成Birthday >= '1997-01-01' AND Birthday < '2000-01-01',让索引能发挥作用。

接下来是 IN 条件:

SELECT Sno, Sname FROM Students WHERE Speciality IN ('计算机', '软件工程'); SELECT Sno, Sname FROM Students WHERE Speciality NOT IN ('计算机', '软件工程');

IN 列表本质是多个 OR 条件的简写。NOT IN需要注意 null 陷阱——如果被比较列里有 NULL 值,NOT IN的结果可能不符合直觉,它会对 NULL 返回 UNKNOWN,导致整行被过滤掉。在实验数据较少时不容易暴露,但在真实数据里很容易让人困惑。

4.3 更新操作:插入、修改、删除时容易被忽略的细节

教材的更新操作分三类:插入、修改、删除。实验报告要求关注标准 SQL 和 M 系数据库 SQL 的差异。这里有一个最重要的差异,就是前面提到的DROP TABLE ... CASCADE,标准 SQL 支持,而 M 系数据库不支持。

UPDATE Students SET Sname = '张华' WHERE Sno = '201705001'; DELETE FROM SC WHERE Grade < 60; INSERT INTO Students(Sno, Sname, Sex, Birthday, Speciality, Dno) VALUES ('201705004', '王芳', '女', '2000-03-15', '计算机', 'CS');

UPDATE 语句必须带上 WHERE,否则会更新整张表的全部行,这是最容易翻车的操作。经验做法是先写 WHERE,再回头补 SET,确保过滤条件明确。DELETE 同理,不带 WHERE 会清空整张表,而且这个操作不可回滚——除非事务里已经执行了START TRANSACTION。插入语句列出字段名比不列字段名更清晰,也更能避免字段顺序变化导致的数据错位。

5. 实验过程中的避坑清单:五个真实报错与对应解法

5.1 现象:服务启动失败且日志提示权限不足

执行systemctl start greatsql后,服务一直是 failed 状态。journalctl -u greatsql -n 50里出现Permission denied或Can't open file /var/lib/mysql/ibdata1。

原因:只执行了setenforce=0,没有在/etc/selinux/config里把 SELINUX 改为 disabled。第一次启动时 SELinux 被临时关闭,一切正常;重启系统后 SELinux 恢复 enforcing,数据目录写入被安全策略拦截。另一个可能原因是mysql用户没有数据目录的写权限,因为chown -R那步被跳过了。

解决:检查/etc/selinux/config是否真的是SELINUX=disabled,检查/var/lib/mysql的属主是否为 mysql:mysql。两个条件都满足后再systemctl start greatsql。从那以后我每次装数据库都会先跑一次getenforce确认状态,而不是想当然以为关过了。

5.2 现象:日期数据插入后查询不到结果

插入 Birthday 字段时用了1999_12_16这种下划线分隔的格式,INSERT 成功了,但WHERE Birthday = '1999-12-16'查不到。

原因:M 系列数据库默认启用了严格模式,日期字符串必须符合YYYY-MM-DD格式。下划线格式在某些版本里会被解析为 0 值日期,或者直接报Incorrect date value错误。这条记录很可能根本没插入,或者被存成了全零日期。

解决:统一使用1999-12-16这种标准格式。如果表里已经混入了全零日期,先执行SELECT * FROM Students WHERE Birthday = '0000-00-00'定位数据,再手动修复或删除。

5.3 现象:学号字段用了 int 导致输出不符合预期

建表时把 Sno 定义成int,插入201705001后查询结果变成了201705001,看起来没问题,但如果学号是0001这种前导零格式,存储后直接丢失了 0,变成 1。

原因:int 是数值类型,它只保存数值大小,不保存格式。前导零不是数值的一部分,所以必丢。学号、身份证号、电话号码这类“看起来像数字”但不需要计算的字段,都应该用 char 或 varchar。

解决:把 Sno 改成char(9),已经建表的执行ALTER TABLE STUDENTS MODIFY Sno char(9);。这个坑在实验二里就会遇到,建议建表时直接按正式版结构来,不要偷懒用 int 简化。

5.4 现象:SQL 一直报语法错误但看起来没问题

复制教材或 Word 文档里的 SQL 执行,返回1064 - You have an error in your SQL syntax,检查半天发现引号用的是中文全角'和'。

原因:很多教材 PDF 或网页里的引号会被排版软件自动转成全角。数据库只认 ASCII 单引号,全角引号直接导致语法解析失败。

解决:写 SQL 时统一在终端或编辑器中输入,不要直接复制带格式的文档内容。如果已经报错,把引号替换成英文单引号。这个坑非常隐蔽,新手排查语法问题往往在括号和关键词上折腾半天,实际只是引号字符的问题。

5.5 现象:外键约束阻止数据插入或 ALTER TABLE 失败

插入 SC 表的201705003时,报错Cannot add or update a child row: a foreign key constraint fails。或在执行ALTER TABLE SC ADD FOREIGN KEY...时卡住。

原因:SC 表的 Sno 字段里存在父表 Students 中没有的学号。外键约束要求子表的所有引用值都必须在父表主键中存在,否则约束无法通过验证。

解决:先检查不一致数据,执行SELECT SC.Sno FROM SC LEFT JOIN Students ON SC.Sno = Students.Sno WHERE Students.Sno IS NULL;,找出孤立记录后,要么在父表补插入对应学生,要么删除这些子表记录,然后重新执行 ALTER TABLE。这个顺序问题是数据库设计里的经典场景,所有外键约束的添加顺序都应该是先父后子。

6. 把实验过程变成一份规范报告:编号、截图和表题的固定套路

6.1 截图下方必须有图编号和图题

实验报告的要求里反复出现一条:截图下方需要有图的编号和图题。这听起来很简单,但很多人交上去的报告里只有“图1”“结果如下”这种敷衍写法。规范的格式是“图1 创建数据库结果”,图编号用阿拉伯数字按顺序排,图题应该概括这张图表的内容,而不是写“运行截图”。截图要裁剪干净,只保留和当前操作相关的窗口区域,不要整张桌面糊上去。

6.2 表格上方那行“表1 学生表”不是可选项

报告里如果有数据展示,比如 SC 表的部分数据,应该在表格上方写“表1 选课成绩表”,下面才是属性行和数据行。属性行就是列名 Sno、Cno、Grade,数据行是具体记录。表格编号和图编号分开计,不要混用“图 1”“表 1”的时候编号串在一起。这个格式要求看似是排版细节,数据库课程设计里往往是很容易被扣分的一项。

6.3 报告正文里的“过程→问题→更正→分析”顺序

写实验报告最容易犯的毛病是只贴一段 SQL 加一张截图,完全没有过程描述。规范的做法是:先用一到两句话说明本步要做什么,再贴出核心命令,然后写执行过程中遇到的问题、如何排查和更正,最后写出结果并分析原因。比如在安装数据库的环节,报告里可以写“关闭 SELinux 和防火墙是为了避免安全策略限制数据库端口监听”,而不是光写两行命令。

我的习惯是每次实验过程中开一个临时目录,把每一步的关键报错截图和纠正命令单独存下来,写报告时照着这个素材库整理。这样既不会漏掉过程,也不会在截图编号上翻车。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 21:14:56

滑块验证码动态参数cb定位方法:前端JS分析与断点调试完整思路

做前端分析的人&#xff0c;迟早会遇到滑块验证码。前两年我刚开始接触这类问题时&#xff0c;也是一头雾水&#xff0c;尤其看到请求里那个神秘的cb参数&#xff0c;长度不一、每次都在变&#xff0c;根本不知道它是从哪儿冒出来的。后来跟着请求链路一步步往下查&#xff0c;…

作者头像 李华
网站建设 2026/10/17 21:13:11

AstronRPA开源平台:融合AI Agent的企业级RPA部署与实战指南

我最初想找类似影刀那种商业工具的替代品&#xff0c;看到AstronRPA时确实愣了一下——科大讯飞把一个企业级RPA AI Agent平台给开源了。这篇我会从项目架构拆起&#xff0c;再带大家把控制台、执行器都跑起来&#xff0c;最后聊聊和影刀、n8n这种工具的横向差异&#xff0c;以…

作者头像 李华
网站建设 2026/10/17 21:12:52

深度学习100道选择题:从题库设计到能力评估的落地路径

简介&#xff1a;这是一份面向深度学习初学者与备考人群的专项练习资料&#xff0c;以100道选择题的形式覆盖机器学习与深度学习的核心知识点&#xff0c;帮助学习者在刷题中检验理论掌握程度、查漏补缺。题目涉及监督与无监督学习、梯度下降、交叉验证、准确率与F1分数等评估指…

作者头像 李华
网站建设 2026/10/17 21:10:07

Capsule Networks原理与实战:动态路由与姿态矩阵详解

1. 项目概述&#xff1a;为什么Capsule Networks不是“又一个新网络”&#xff0c;而是对神经网络底层逻辑的一次重审Capsule Networks胶囊网络&#xff08;二&#xff09;——这个标题里藏着一个被多数人忽略的关键信号&#xff1a;“&#xff08;二&#xff09;”。它不是孤立…

作者头像 李华
网站建设 2026/10/17 21:07:29

Unity游戏数据管理:Excel转SQLite实战指南

1. 为什么非得把Excel塞进Unity的SQLite里&#xff1f;——一个被低估的数据管理真相很多人第一次听说“Excel转SQLite再进Unity”&#xff0c;第一反应是&#xff1a;这不折腾吗&#xff1f;Excel双击就开&#xff0c;Unity里写个CSV读取几行代码完事&#xff0c;何必绕这么大…

作者头像 李华
网站建设 2026/10/17 20:56:27

MUSIC多普勒速度谱实战指南:从协方差矩阵到子空间稳定

1. 这不是“加个滤波器”就能出图的事&#xff1a;MUSIC算法求解多普勒速度谱的真实门槛在哪里你是不是也见过这类描述&#xff1a;“用MUSIC算法画出多普勒速度谱&#xff0c;分辨率比FFT高多了”&#xff1f;——听起来很美&#xff0c;但真动手时&#xff0c;信号还没进算法…

作者头像 李华