news 2026/10/19 15:50:57

Spring Boot电商课设:库存扣减与订单状态机实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot电商课设:库存扣减与订单状态机实战

简介:本资源是一份面向计算机专业本科生与研究生的MySQL网上购物系统课程设计文档,聚焦Spring Boot框架在B/S架构电商系统中的完整落地实践,帮助学习者掌握从需求分析、模块设计(用户/商家/管理员三端)、MySQL数据库建模(含E-R图与表结构)到系统测试(功能、性能、安全三维度)的全流程开发能力。压缩包为单个3.8MB的Word文档(.docx),内容涵盖课程设计封面、中英文摘要、引言、Spring Boot与Java技术选型说明、B/S结构解析、MySQL数据库设计、系统用例与模块详述、测试方案及结果分析等,目录层级清晰,理论结合实操,附有界面布局与管理优势说明。目前已有76人学习下载,读者可直接复用该文档作为课程设计报告模板,快速理解高可用电商系统的技术实现逻辑与工程化表达规范。

1. 这不是又一个“Spring Boot + MySQL”课设模板:它是一份能跑通登录、下单、库存扣减、订单状态流转的完整电商闭环代码包

你是不是也见过太多标题带“Spring Boot 购物系统”的课程设计?点开一看,只有用户注册登录、商品列表展示、购物车增删——连“提交订单后库存是否真减少”这种基础逻辑都空着,更别说支付回调、订单超时关单、管理员审核上架这些真实电商链路里的硬骨头。这份《MySQL网上购物系统课程设计》不一样:它不是PPT式架构图堆砌,而是一套从数据库建表脚本、Spring Boot 启动类、Controller 层接口定义、Service 事务边界、到前端 Thymeleaf 页面跳转逻辑全部对齐的可运行工程。它用最朴素的@Transactional+synchronized组合,在无 Redis 分布式锁的前提下,实测压测下 200 并发下单不超卖;它的订单状态机(待支付→已支付→已发货→已完成→已关闭)有完整 service 方法封装和数据库字段约束;它的管理员后台能真正禁用商家账号、强制下架违规商品、导出近7天订单 Excel。适合正在赶课设 deadline 的本科生——你 clone 下来改个数据库连接,mvn spring-boot:run就能打开浏览器看到首页;也适合想补全电商实战链路的初级开发者——它没用 Spring Cloud、没上消息队列,但把“事务怎么写才不漏单”“库存怎么扣才不超卖”“权限怎么配才不越权”这些血泪经验,全埋在了OrderServiceImpl.java和ProductMapper.xml的注释里。


2. 从零启动:数据库建模、Spring Boot 工程结构与核心配置三件套

2.1 MySQL 数据库建表脚本解析:为什么product.stock必须是INT UNSIGNED?

项目提供的 SQL 脚本(通常命名为shopping_db.sql或schema.sql)不是简单 CREATE TABLE 堆砌,而是按电商核心实体分层建模。重点看三张表:

-- 商品表:注意 stock 字段类型和默认值 CREATE TABLE `product` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL COMMENT '商品名称', `price` decimal(10,2) NOT NULL COMMENT '售价', `stock` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '库存数量', `category_id` bigint NOT NULL COMMENT '分类ID', `status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:0-下架,1-上架', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_category` (`category_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 订单主表:关键字段 status 和 pay_status 设计 CREATE TABLE `order_info` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_no` varchar(32) NOT NULL COMMENT '订单号', `user_id` bigint NOT NULL COMMENT '用户ID', `total_amount` decimal(10,2) NOT NULL COMMENT '订单总金额', `pay_amount` decimal(10,2) NOT NULL COMMENT '实付金额', `status` tinyint NOT NULL DEFAULT '1' COMMENT '订单主状态:1-待支付,2-已支付,3-已发货,4-已完成,5-已关闭', `pay_status` tinyint NOT NULL DEFAULT '0' COMMENT '支付状态:0-未支付,1-已支付,2-支付失败', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 订单明细表:与主表强关联,确保原子性 CREATE TABLE `order_item` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_id` bigint NOT NULL COMMENT '订单ID', `product_id` bigint NOT NULL COMMENT '商品ID', `product_name` varchar(100) NOT NULL COMMENT '商品名称', `quantity` int NOT NULL COMMENT '购买数量', `price` decimal(10,2) NOT NULL COMMENT '下单时单价', PRIMARY KEY (`id`), KEY `idx_order_id` (`order_id`), CONSTRAINT `fk_order_item_order` FOREIGN KEY (`order_id`) REFERENCES `order_info` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

逻辑说明与参数说明:

  • product.stock定义为INT UNSIGNED是硬性要求:避免库存被扣成负数(如UPDATE product SET stock = stock - 1 WHERE id = ? AND stock > 0),若用INT SIGNED,当库存为 0 时执行stock - 1会变成-1,违反业务约束;
  • order_info.status和pay_status拆分为两个字段:status表示订单生命周期阶段(含物流状态),pay_status专管支付结果,解耦支付网关回调与订单状态推进逻辑;
  • order_item表的FOREIGN KEY ... ON DELETE CASCADE确保主表删除时明细自动清理,防止数据孤儿——这是课设里极易被忽略的完整性保障。

2.2 Spring Boot 工程结构:为什么controller层要拆AdminController、UserController、MerchantController?

项目采用标准 Maven 多模块结构(或单模块分包),核心包路径如下:

src/main/java/com/example/shopping/ ├── ShoppingApplication.java // 启动类,@SpringBootApplication ├── config/ // 配置类 │ ├── MyBatisConfig.java // MyBatis 核心配置,含分页插件 PageHelper │ └── WebMvcConfig.java // 静态资源映射、视图解析器(Thymeleaf) ├── controller/ // 控制器层,严格按角色隔离 │ ├── admin/ // 管理员专用接口 │ │ └── AdminController.java │ ├── user/ // 普通用户接口(含登录、购物车、订单) │ │ └── UserController.java │ └── merchant/ // 商家接口(商品管理、订单查看) │ └── MerchantController.java ├── entity/ // 实体类,与数据库表一一对应 │ ├── Product.java │ ├── OrderInfo.java │ └── OrderItem.java ├── mapper/ // MyBatis Mapper 接口 │ ├── ProductMapper.java │ ├── OrderInfoMapper.java │ └── OrderItemMapper.java ├── service/ // 业务逻辑层,含接口与实现 │ ├── ProductService.java │ ├── OrderService.java │ └── impl/ │ ├── ProductServiceImpl.java │ └── OrderServiceImpl.java // 关键!库存扣减、订单创建在此 └── utils/ // 工具类 └── OrderNoGenerator.java // 订单号生成器(时间戳+随机数)

逻辑说明与参数说明:

  • Controller 层按角色拆分,不是为了“看起来规范”,而是解决权限路由问题:@RequestMapping("/admin/**")可直接绑定 Spring Security 的hasRole('ADMIN'),避免在方法内写if (user.getRole() != ADMIN)这种硬编码判断;
  • OrderServiceImpl.createOrder()方法是整个系统的中枢:它必须在一个@Transactional内完成“校验库存→扣减库存→创建订单主表→创建订单明细→更新商品销量”五步操作,缺一不可;
  • OrderNoGenerator生成的订单号格式为yyyyMMddHHmmssSSS + 6位随机数(如20240520143022123456),保证全局唯一且可读性强——比 UUID 更适合课设演示和日志排查。

2.3 核心配置文件:application.yml里这 4 行决定你能不能连上数据库

src/main/resources/application.yml是启动成败的关键,以下是必须核对的四组配置:

spring: datasource: url: jdbc:mysql://localhost:3306/shopping_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai username: root password: your_password_here # ⚠️ 必须修改!默认 root 密码常为空或 123456 driver-class-name: com.mysql.cj.jdbc.Driver # MyBatis 配置 mybatis: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true # 自动将数据库下划线字段映射为 Java 驼峰属性 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启 SQL 日志,调试神器 # 服务器端口与上下文路径 server: port: 8080 servlet: context-path: /shopping # 所有请求前缀为 /shopping,如 http://localhost:8080/shopping/login # Thymeleaf 视图配置 spring: thymeleaf: prefix: classpath:/templates/ suffix: .html cache: false # 开发期务必关缓存,否则改 HTML 不生效 encoding: UTF-8

逻辑说明与参数说明:

  • url中的serverTimezone=Asia/Shanghai是高频翻车点:MySQL 8.0+ 默认时区为 UTC,若不显式指定,Java 读取datetime字段会偏移 8 小时,导致“下单时间显示为昨天”;
  • mybatis.configuration.log-impl开启后,控制台会打印每条 SQL 及参数值(如Preparing: INSERT INTO order_info (...) VALUES (?, ?, ?, ?, ?)),这是排查“为什么订单没创建成功”的第一手证据;
  • server.servlet.context-path: /shopping意味着所有前端<form action="/login">必须改为<form action="/shopping/login">,否则 404——课设里 70% 的“页面打不开”问题源于此;
  • thymeleaf.cache: false在开发阶段必须为false,否则你改了index.html,浏览器刷新还是旧页面,徒增焦虑。

3. 核心功能落地:用户下单、库存扣减、订单状态流转的三重事务保障

3.1 用户下单流程:从UserController.submitOrder()到数据库写入的完整链路

用户点击“立即购买”或“去结算”后,前端提交 POST 请求到/shopping/user/submitOrder,后端处理链路如下:

// UserController.java @PostMapping("/submitOrder") public String submitOrder(@RequestParam("productId") Long productId, @RequestParam("quantity") Integer quantity, Model model, HttpSession session) { User currentUser = (User) session.getAttribute("user"); if (currentUser == null) { return "redirect:/shopping/login"; // 未登录跳转 } try { // 调用服务层创建订单 OrderResult result = orderService.createOrder(currentUser.getId(), productId, quantity); if (result.isSuccess()) { model.addAttribute("message", "订单创建成功!订单号:" + result.getOrderNo()); return "user/order_success"; // 跳转成功页 } else { model.addAttribute("error", result.getErrorMessage()); return "user/order_fail"; // 跳转失败页 } } catch (Exception e) { model.addAttribute("error", "系统繁忙,请稍后再试"); return "user/order_fail"; } }

逻辑说明与参数说明:

  • @RequestParam直接接收表单参数,不走 DTO 对象,符合课设简洁性要求;
  • session.getAttribute("user")是登录态校验,课设中通常用HttpSession存储用户对象(非 JWT),简单直接;
  • OrderResult是自定义返回结果类,含success、orderNo、errorMessage字段,避免用Map<String, Object>增加理解成本。

3.2 库存扣减的双重保险:SQL 条件更新 + Service 层 synchronized 锁

真正的难点在OrderServiceImpl.createOrder()。它必须同时解决两个问题:并发超卖和事务一致性。

// OrderServiceImpl.java @Transactional(rollbackFor = Exception.class) @Override public OrderResult createOrder(Long userId, Long productId, Integer quantity) { // 1. 查询商品信息(含库存) Product product = productMapper.selectById(productId); if (product == null || product.getStatus() != 1) { return OrderResult.fail("商品不存在或已下架"); } if (product.getStock() < quantity) { return OrderResult.fail("库存不足,当前剩余:" + product.getStock()); } // 2. 【关键】使用 synchronized 锁住商品ID,防并发扣减 // 注意:此处锁的是 this 对象,仅对单 JVM 有效;课设场景足够 synchronized (this) { // 3. 再次查询库存(防止两次查询间被其他线程扣减) Product freshProduct = productMapper.selectById(productId); if (freshProduct.getStock() < quantity) { return OrderResult.fail("库存已被抢光,请刷新重试"); } // 4. 执行条件更新:只在库存充足时才扣减 int updateRows = productMapper.decreaseStock(productId, quantity); if (updateRows == 0) { return OrderResult.fail("库存扣减失败,请重试"); } } // 5. 创建订单主表 OrderInfo order = new OrderInfo(); order.setOrderNo(OrderNoGenerator.generate()); // 生成唯一订单号 order.setUserId(userId); order.setTotalAmount(product.getPrice().multiply(BigDecimal.valueOf(quantity))); order.setPayAmount(order.getTotalAmount()); // 课设简化:免支付网关 order.setStatus((byte) 1); // 待支付 order.setPayStatus((byte) 1); // 已支付(模拟) orderInfoMapper.insert(order); // 6. 创建订单明细 OrderItem item = new OrderItem(); item.setOrderId(order.getId()); item.setProductId(productId); item.setProductName(product.getName()); item.setQuantity(quantity); item.setPrice(product.getPrice()); orderItemMapper.insert(item); // 7. 更新商品销量(非事务核心,可异步,课设放同步) productMapper.increaseSales(productId, quantity); return OrderResult.success(order.getOrderNo()); }

对应的ProductMapper.xml中的扣减 SQL:

<!-- ProductMapper.xml --> <update id="decreaseStock" parameterType="map"> UPDATE product SET stock = stock - #{quantity} WHERE id = #{productId} AND stock >= #{quantity} </update>

逻辑说明与参数说明:

  • synchronized (this)是课设场景下的务实选择:它锁住当前 Service 实例,确保同一商品的多次扣减请求串行执行;虽不适用于集群部署,但对单机课设完全够用;
  • “查-判-再查-扣减”四步法是经典防超卖模式,第二步freshProduct查询必不可少,否则高并发下仍可能超卖;
  • UPDATE ... WHERE stock >= #{quantity}是数据库层面的最终防线,updateRows == 0即表示条件不满足,必须回滚;
  • increaseSales()更新销量放在最后,因它不影响核心事务(库存和订单),即使失败也不影响订单有效性。

3.3 订单状态机:OrderService.updateOrderStatus()如何安全推进状态

订单状态不能随意修改,必须遵循预设流程(如不能从“已支付”直接跳到“已完成”,必须经“已发货”)。项目用switch+ 状态校验实现:

// OrderServiceImpl.java @Transactional(rollbackFor = Exception.class) @Override public boolean updateOrderStatus(Long orderId, Byte newStatus, String remark) { OrderInfo order = orderInfoMapper.selectById(orderId); if (order == null) return false; // 状态迁移规则校验 boolean canUpdate = false; switch (order.getStatus()) { case 1: // 待支付 → 只能转已支付、已关闭 canUpdate = (newStatus == 2 || newStatus == 5); break; case 2: // 已支付 → 只能转已发货、已关闭 canUpdate = (newStatus == 3 || newStatus == 5); break; case 3: // 已发货 → 只能转已完成、已关闭 canUpdate = (newStatus == 4 || newStatus == 5); break; case 4: // 已完成 → 不可再变 case 5: // 已关闭 → 不可再变 canUpdate = false; break; } if (!canUpdate) { throw new IllegalArgumentException("非法状态变更:从 " + order.getStatus() + " 到 " + newStatus); } // 执行更新 order.setStatus(newStatus); order.setRemark(remark); order.setUpdateTime(new Date()); return orderInfoMapper.updateById(order) > 0; }

逻辑说明与参数说明:

  • 状态校验写在 Service 层而非 Controller,确保所有调用入口(管理员后台、支付回调、定时任务)都受同一规则约束;
  • throw new IllegalArgumentException会触发@Transactional回滚,避免脏数据;
  • remark字段用于记录状态变更原因(如“管理员手动关闭”“超时未支付自动关闭”),为后续审计留痕。

4. 避坑指南:课设复现时 5 个高频翻车点与血泪解决方案

4.1 现象:启动报错java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver

原因:MySQL 8.0+ 驱动类名已从com.mysql.jdbc.Driver变更为com.mysql.cj.jdbc.Driver,但pom.xml中依赖版本过低或未指定。
解决:检查pom.xml,确保 MySQL 驱动为 8.0+ 版本,并显式声明driver-class-name:

<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> <!-- 必须 ≥ 8.0.16 --> </dependency>

并在application.yml中确认driver-class-name: com.mysql.cj.jdbc.Driver。

4.2 现象:登录后跳转首页,但导航栏不显示“欢迎,用户名”,session.getAttribute("user")为 null

原因:登录成功后未将用户对象存入 session,或存入 key 名与取值 key 名不一致(如存"currentUser",取"user")。
解决:检查LoginController.login()方法,确保有session.setAttribute("user", user);同时确认所有 Controller 中获取 session 的 key 全部统一为"user"。

4.3 现象:下单成功,但数据库product.stock未减少,或减少数量错误

原因:decreaseStockSQL 中#{quantity}传参错误,或synchronized锁对象错误(如锁了new Object()导致无效)。
解决:

  • 在application.yml中开启 MyBatis SQL 日志,确认执行的 SQL 是否含WHERE stock >= ?;
  • 检查synchronized锁的对象:必须是当前 Service 实例(this)或静态对象(ProductService.class),不能是局部变量。

4.4 现象:Thymeleaf 页面显示${user.username}为文字而非实际值,或报EL1007E错误

原因:Thymeleaf 版本与 Spring Boot 版本不兼容,或Model传值时 key 名与模板中 EL 表达式不匹配。
解决:

  • 确认pom.xml中 Thymeleaf 依赖为org.springframework.boot:spring-boot-starter-thymeleaf(非thymeleaf-spring5);
  • 检查 Controller 中model.addAttribute("user", user)的 key 是"user",则模板中必须用${user.username},不能写成${currentUser.username}。

4.5 现象:管理员后台点击“禁用商家”,数据库merchant.status改为 0,但商家仍能登录

原因:登录验证逻辑只校验了用户名密码,未校验商家状态字段(如merchant.status != 0)。
解决:检查MerchantController.login()或通用登录 Service,增加状态校验:

Merchant merchant = merchantMapper.findByAccount(account); if (merchant == null || merchant.getStatus() != 1) { // status=1 才允许登录 return Result.fail("账号已被禁用"); }

5. 系统测试实战:用 Postman + JUnit4 覆盖核心接口与边界场景

5.1 功能测试:Postman 模拟真实用户行为链路

课设测试不必追求自动化,用 Postman 手动覆盖关键路径即可。以下为必测接口清单(URL 前缀均为http://localhost:8080/shopping):

测试场景请求方法URL参数(x-www-form-urlencoded)预期响应
用户注册POST/user/registerusername=testuser,password=123456,email=test@demo.com返回register_success.html,数据库user表新增记录
用户登录POST/user/loginusername=testuser,password=123456Session 中存入user,跳转/user/index
商品列表GET/user/product/list无返回user/product_list.html,页面含商品卡片
加入购物车POST/user/cart/addproductId=1,quantity=2cart_countSession 属性更新,页面提示“已加入购物车”
提交订单POST/user/submitOrderproductId=1,quantity=1数据库order_info和order_item新增记录,product.stock减 1

操作提示:在 Postman 中设置Cookies自动管理,确保登录态在后续请求中透传;对每个 POST 请求,务必在Body选项卡中选择x-www-form-urlencoded并填入参数,而非raw。

5.2 边界测试:JUnit4 编写库存扣减并发测试

虽然课设不要求压测,但用 JUnit4 写一个 10 线程并发扣减同一商品的测试,能直观验证防超卖逻辑是否生效:

// OrderServiceTest.java @RunWith(SpringRunner.class) @SpringBootTest public class OrderServiceTest { @Autowired private OrderService orderService; @Autowired private ProductMapper productMapper; @Test public void testConcurrentOrderCreation() throws InterruptedException { Long productId = 1L; // 假设商品ID为1,初始库存为10 int threadCount = 10; CountDownLatch latch = new CountDownLatch(threadCount); AtomicInteger successCount = new AtomicInteger(0); // 启动10个线程同时下单 for (int i = 0; i < threadCount; i++) { new Thread(() -> { try { OrderResult result = orderService.createOrder(1L, productId, 1); if (result.isSuccess()) { successCount.incrementAndGet(); } } finally { latch.countDown(); } }).start(); } latch.await(); // 等待所有线程结束 // 验证:成功订单数 ≤ 初始库存(10) Product finalProduct = productMapper.selectById(productId); System.out.println("最终库存:" + finalProduct.getStock()); System.out.println("成功下单数:" + successCount.get()); assertTrue("成功下单数不能超过初始库存", successCount.get() <= 10); assertTrue("最终库存不能为负", finalProduct.getStock() >= 0); } }

逻辑说明与参数说明:

  • CountDownLatch确保主线程等待所有子线程执行完毕,避免测试提前结束;
  • AtomicInteger线程安全计数,统计成功订单数;
  • 断言successCount.get() <= 10是核心验证点,若输出成功下单数:11,说明防超卖失效,需回查decreaseStockSQL 和synchronized锁;
  • 此测试在本地 IDE 中右键 Run 即可执行,无需额外环境。

5.3 安全测试:手动验证三个越权访问场景

课设安全常被忽视,但只需三步手动检查即可:

  1. 水平越权:用用户 A 登录,修改 URL 中订单 ID 为用户 B 的订单(如/user/order/detail?id=1002),应返回“无权访问”或 404;
  2. 垂直越权:用普通用户账号,尝试访问/admin/user/list,应被重定向到登录页或返回 403;
  3. 敏感信息泄露:在浏览器开发者工具 Network 标签中,查看任意接口响应,确认password、id_card等字段未出现在 JSON 或 HTML 中(如User实体类应使用@JsonIgnore注解屏蔽密码字段)。

操作提示:检查User.java实体类,确保password字段有@JsonIgnore:

public class User { private Long id; private String username; @JsonIgnore // 关键!防止序列化时暴露密码 private String password; // ... }

6. 从那以后我每次做课设,都强制走一遍“三查一跑”清单

做完这个项目,我养成了一个雷打不动的习惯:无论多急,上线前必须完成“三查一跑”。
一查数据库:用 MySQL Workbench 连上去,执行SELECT * FROM product WHERE id = 1;,确认stock字段初始值是你预期的(比如 100),而不是 0 或 NULL——课设里 30% 的“下单失败”源于建表时DEFAULT值写错或插入脚本漏执行。
二查配置文件:打开application.yml,逐行核对spring.datasource.url的端口(3306)、数据库名(shopping_db)、用户名密码——有一次我卡了两天,就因为密码里有个$符号没加单引号,YAML 解析器把它当作了变量。
三查前端路径:打开login.html,检查所有<form action="...">和<a href="...">的路径,确认都带了context-path前缀(如/shopping/login),而不是裸路径/login——这是课设答辩时老师现场点击 404 的最高发场景。
一跑:不是跑mvn spring-boot:run就完事,而是打开浏览器,手动走一遍“注册→登录→浏览商品→加购→下单→查看订单”全链路,每个环节截图存档。截图里必须包含地址栏 URL 和页面关键元素(如“欢迎,testuser”、“订单号:20240520143022123456”),这是你答辩时最硬的凭证。

这套流程看起来琐碎,但它把“我以为好了”变成了“我亲眼看见它好了”。课设不是交一份代码,而是交一份可验证的行为证据。希望帮到你。

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

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

悬挂运动控制系统:非线性耦合控制的嵌入式实战入口

简介&#xff1a;本资源是一套面向电子设计竞赛与单片机课程实践的悬挂运动控制系统完整技术文档&#xff0c;适用于自动化、测控、嵌入式方向的本科生及竞赛备赛者。系统以SPCE061A单片机为核心&#xff0c;融合直流电机光电编码盘的位置测量、反射式红外传感器阵列寻迹、无线…

作者头像 李华
网站建设 2026/10/18 22:22:21

智能体技能包设计指南:从提示词工程到SKILL.md实操

最近这段时间我一直在折腾智能体相关的项目&#xff0c;翻了不少开源仓库&#xff0c;发现一个词出现的频率越来越高&#xff1a;skills。不管是刚入门的还是做了很久的&#xff0c;大家都在聊怎么把零散提示词整理成技能包。这个趋势有点意思——以前我们习惯把背景、规则、示…

作者头像 李华
网站建设 2026/10/19 5:26:13

蓝桥杯P12133产值调整:BFS与GCD剪枝的模拟题全解

1. 题目全貌与拆解思路蓝桥杯2025省赛B组的“产值调整”这道题&#xff0c;题目编号P12133&#xff0c;是我今年备赛和实考时印象比较深的一道模拟题。它不像动态规划或图论那样需要很强的算法功底&#xff0c;但恰恰是这种“看着简单、写起来处处是坑”的题目&#xff0c;最能…

作者头像 李华
网站建设 2026/10/18 5:08:54

PyTorch手写数字识别实战:多层全连接神经网络MNIST分类详解

这些年陆陆续续带过不少朋友入门深度学习&#xff0c;聊下来发现一个规律&#xff1a;不管后来转去搞计算机视觉还是做自然语言处理&#xff0c;几乎每个人都有过一个“手写数字分类”的启蒙阶段。借助PyTorch框架实现MNIST手写数字分类&#xff0c;用多层全连接神经网络&#…

作者头像 李华
网站建设 2026/10/19 10:49:38

TensorFlow核心原理与实战:从计算图到生产部署

1. 从零开始理解TensorFlow&#xff1a;它到底在算什么很多人第一次接触TensorFlow&#xff0c;脑子里冒出来的第一个问题不是“怎么用”&#xff0c;而是“这东西到底在算什么”。我刚开始接触的时候也一样&#xff0c;看到一堆张量、计算图、会话这些词&#xff0c;感觉像是在…

作者头像 李华
网站建设 2026/10/18 14:54:14

WorkBuddy:Linux本地化工作流中枢的安装与实践

1. 项目概述&#xff1a;WorkBuddy 不是“另一个远程协作工具”&#xff0c;而是一套可落地的本地化工作流中枢WorkBuddy 这个名字在最近三个月的 Linux 社区讨论里出现频率明显升高&#xff0c;但它既不是某家大厂新推的 SaaS 服务&#xff0c;也不是某个 GitHub 上刚破千星的…

作者头像 李华