JSP+SSM网上购物商城系统实战:从架构设计到部署上线

如果让我挑一个最适合初学 JavaWeb 的完整案例,网上购物商城系统绝对能排进前三。这个基于 JSP 和 SSM(Spring、SpringMVC、MyBatis)的商城项目,覆盖了用户从注册、浏览商品、加购、下单到后台管理的完整链路,既有前端页面交互,又有后端事务处理,还有数据库的多表关联,用来练手再合适不过。这篇文章我把做这类系统时沉淀下来的完整思路、核心代码片段和各种坑总结出来,给打算做类似实训项目或毕业设计的同学做参考。尤其是那些已经选定了“JSP + SSM”组合、但不知道从哪里下手的同学,这套流程可以直接照着走。

1. 项目整体设计与技术选型解析

1.1 为什么选择 JSP + SSM 这套组合

很多人一上来就问,现在不都是前后端分离了吗,怎么还在用 JSP?这个问题我当时也纠结过。但仔细想想,商城系统是个典型的“管理系统 + 前台页面”二合一项目,JSP 最大的优势是能在同一套工程里直接通过 EL 表达式和 JSTL 标签把后端数据渲染出来,不用额外搭建前端工程。对一个人开发、周期有限的项目来说,这种“快速出活”的能力比什么都重要。

SSM 框架这边也各有分工:Spring 负责对象管理和事务控制,SpringMVC 负责请求路由和参数绑定,MyBatis 负责把 SQL 和 Java 方法映射起来。三者合在一起,正好把数据访问、业务处理、请求响应这三层拆得明明白白。学习这个项目,等于同时把 Java 生态里最常用的三板斧过了一遍。

另外,这套技术栈对运行环境的要求也非常友好。只要本机装了 JDK 8、MySQL 5.7 以上、Tomcat 8/9,基本就能跑起来,部署成本低。相比动不动就要 Docker、微服务、云原生的项目,这种传统 Web 应用反而更适合用来验证业务逻辑和基础知识。

1.2 商城系统的核心功能边界

动手之前一定要把功能边界画清楚,否则写代码时很容易想到哪写到哪。一个完整的网上购物商城通常分成两部分:前台用户端和后台管理端。

前台的核心用户流程是:注册登录 → 浏览商品分类 → 搜索关键词 → 查看商品详情 → 加入购物车 → 生成订单 → 在线支付或货到付款 → 查看订单状态。后台的核心管理流程是:商品分类管理 → 商品上下架与库存维护 → 订单处理(发货、取消、退款)→ 用户状态管理 → 基础数据统计。

我当时做的时候,把功能表做成了 Excel,每个模块对应哪些菜单位置、哪些数据库表、哪些权限,都提前列出来。这样做的好处是后面写接口时基本不需要反复改表结构,前后台都能顺畅联调。下面是我整理后的最小功能集:

  • 前台模块:用户注册、用户登录、商品列表(分页)、商品按分类筛选、商品关键词搜索、商品详情、购物车增删改查、订单确认、订单提交、我的订单列表。
  • 后台模块:管理员登录、商品分类管理、商品信息管理(含图片上传)、库存管理、订单管理(发货、取消)、用户管理、数据看板。

后台不需要做太复杂,能支撑商品的日常维护和订单流转就够了。千万别为了追求“全”加一堆不常用的功能,比如积分、秒杀、优惠券,那是给自己挖坑。

1.3 目录结构与分层思路

工程目录我建议使用标准的 Maven Web 项目结构,不要图省事用普通 Web 项目。Maven 管理依赖特别方便,尤其是 SSM 这个组合有一堆 JAR 包,手动导包容易版本冲突。

分层上我做了四个包:controller 放 SpringMVC 的 Controller,service 放业务接口和实现类,dao 放 MyBatis 的 Mapper 接口,entity 放数据库表对应的实体类。另外再加一个 common 包放工具类、常量类、通用返回结果。

src/main/java com.example.shop controller UserController.java GoodsController.java CartController.java OrderController.java AdminGoodsController.java AdminOrderController.java service UserService.java GoodsService.java CartService.java OrderService.java dao UserMapper.java GoodsMapper.java CategoryMapper.java OrderMapper.java OrderItemMapper.java entity User.java Category.java Goods.java Cart.java Order.java OrderItem.java common Constants.java MD5Util.java Result.java src/main/resources mapper UserMapper.xml GoodsMapper.xml CategoryMapper.xml OrderMapper.xml OrderItemMapper.xml jdbc.properties spring-mybatis.xml spring-mvc.xml src/main/webapp WEB-INF views user, goods, cart, order, admin web.xml

分层清晰之后,代码交接和调试都方便。举例来说,用户下单后需要扣减库存、生成主订单、生成订单明细、清空购物车,这些操作全部放在 OrderService 的一个事务方法里,Controller 只负责接收参数和返回视图。这样无论测试还是排查问题,都能很快定位到业务逻辑所在的层。

2. 环境准备与数据库设计

2.1 开发环境与版本对应关系

网上购物商城系统对环境的要求不高,但版本对应关系还是要重视。我使用的是 JDK 8、MySQL 5.7、Tomcat 9、Maven 3.6,框架版本用 Spring 5.1.x、SpringMVC 5.1.x、MyBatis 3.5.x。这里有一个容易踩的坑:Tomcat 10 以上把 Java EE 包从 javax 换成了 jakarta,很多老项目代码直接编译报错。如果没把握,就用 Tomcat 9 最稳。

工具方面我用的是 IntelliJ IDEA,虽然 Eclipse 也能跑,但 IDEA 对 Maven 和 Spring 的支持更顺手。创建项目时不要选错类型,要选 Maven 项目的 Web 骨架,或者直接新建一个普通 Maven 模块再手动添加 Web 支持。如果是 IDEA,一定要检查 Project Structure 里的 Artifacts,把项目依赖的 JAR 包加入打包输出,否则 Tomcat 启动后经常会报 ClassNotFound。

还有一个小技巧:MySQL 连接驱动用mysql-connector-java8.0.16 以上,但注意这和 MySQL 5.7 的驱动类名、URL 参数都有变化。连接池我用的是 Druid,配置简单,还自带了监控页面,适合做日志排查。

2.2 数据库表设计核心思想

数据库表设计是整个商城系统的地基。表数量不用太多,但每张表的字段和关系一定要提前想清楚。我最终设计了六张核心表:用户表、商品分类表、商品表、购物车表、订单表、订单明细表。有的同学还会加一张管理员表,但管理员功能少,可以和用户表并用一个 role 字段区分。

用户表存的就是账号、密码、昵称、手机号、邮箱、角色、创建时间。密码字段我建议用varchar(64),不存明文,统一存 MD5 加盐后的值。分类表字段很简单:分类名、父级分类、排序值、状态,一般做两级分类就够。

商品表是最关键的,字段包括商品名称、所属分类、商品主图、详情描述、市场价、销售价、库存、销量、上下架状态、创建时间。这里要特别注意商品详情的存储方式,我一开始用text字段直接存富文本编辑器的 HTML 片段,后期发现如果图片用的是相对路径,部署后容易丢图。最好在富文本上传接口里把图片路径转成完整可访问的 URL 再入库。

订单表和订单明细表是一对多的关系。订单表里除了订单号、用户 ID、总金额、收货地址、联系人信息、下单时间,还要有一个订单状态字段。订单明细表则要保存商品 ID、商品名称、商品图片、购买单价、数量、小计。为什么明细表里要冗余商品名称和图片?因为商品信息后续可能修改或下架,但历史订单必须保持当时的快照。这是个非常实用的设计经验。

2.3 关键 SQL 与数据初始化脚本

建表完成后,可以先用一些测试数据验证查询效果。会员表中我测试时会插入几十条模拟用户,商品表则准备四个分类共几十件商品,价格从几十到几千不等。商品列表页最常用的查询就是按分类和关键词分页:

SELECT id, goods_name, goods_pic, market_price, sell_price, stock, sales FROM goods WHERE status = 1 AND category_id = #{categoryId} AND goods_name LIKE CONCAT('%', #{keyword}, '%') ORDER BY sales DESC LIMIT #{offset}, #{pageSize};

这个 SQL 包含了筛选、模糊搜索、排序和分页四个核心要素,能覆盖前台商品列表 80% 的场景。统计销售排行时,可以直接按sales字段排序;后台看库存告警时,再加一个stock < 10的判断。购物车表我建议设计成独立表,字段是用户 ID、商品 ID、数量、加入时间。可能有人会觉得放 Session 里更简单,但实际做下来,独立表能处理掉线的用户下完订单还丢购物车的尴尬,也能为后台分析用户收藏偏好留数据。

3. 核心模块实现与实操要点

3.1 用户注册登录与登录拦截

用户模块是系统入口,逻辑不算复杂,但注册时的细节容易漏。注册接口除了校验用户名是否重复,还要对密码加密。我封装了一个工具类,用 MD5 做盐值哈希,盐可以用用户名或固定字符串拼接,避免直接用原始密码摘要。具体加密写法如下:

public static String md5WithSalt(String password, String username) { String raw = password + "{" + username + "}"; StringBuilder sb = new StringBuilder(); MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(raw.getBytes(StandardCharsets.UTF_8)); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); }

登录成功之后,把用户 ID 和用户名放到 Session 中,退出时调用session.invalidate()清除。

拦截器是个容易忽略但必须做的模块。我用 SpringMVC 的HandlerInterceptor拦截所有/user/**、/cart/**、/order/**路径,如果 Session 中没有用户信息就重定向到登录页。这个拦截器写好后一定要在 spring-mvc.xml 里声明拦截路径,否则前台用户没登录也能直接提单,这个问题在联调的时候特别隐蔽。

后台管理同样需要拦截,但角色不同。我通常在拦截器里加一个角色判断,只有role=admin的账号放行到/admin/**。学员做项目时常把登录状态和角色权限混在一起,建议还是拆开,否则后面加超级管理员会非常痛苦。

3.2 商品分类展示与分页查询

商品展示没有太多高级算法,核心就是分页查询做得顺手。我用的方案是 MyBatis 的 PageHelper 插件,在 Service 层查询前设置当前页码和每页条数,然后查询返回的结果自动带出PageInfo,里面包含了总条数、总页数、当前页等所有分页数据。

PageHelper.startPage(pageNum, pageSize); List<Goods> goodsList = goodsMapper.selectByCondition(categoryId, keyword); PageInfo<Goods> pageInfo = new PageInfo<>(goodsList);

在 JSP 页面里,遍历pageInfo.list渲染商品卡片,底部生成分页条。分页条的高亮逻辑用 JSTL 做一个循环,遍历1..pageInfo.pages,当前页加active样式。这里要注意,PageHelper 和 SQL 中的LIMIT不要混用,否则会出现第一次查询正常、翻页后数据错乱的情况。

商品详情页要展示图片、价格、库存和购买数量。我建议用商品 ID 直接拼一个restful风格的 URL:/goods/detail/${goodsId},这样搜索引擎和分享都更友好。如果库存不大于 0,前端要置灰“立即购买”按钮,后端在下单时也要再次校验库存,双重保障。

商品图片存在服务器上传目录,数据库只存相对路径,页面上展示时通过统一的FileController读取本地文件流返回。这样能避免图片文件被打进 WAR 包、重新部署丢失的问题。

3.3 购物车方案比较与最终实现

购物车是商城系统里最容易被低估的模块。最初我用 Session 保存购物车,一个 Map 结构,key 是商品 ID,value 是数量,代码写起来是很快。但测试时发现两个痛点:一是没登录也能加购物车,但登录后购物车数据不在;二是用户清浏览器缓存,购物车也跟着没。

所以最后我换成了数据库购物车。购物车表包含用户 ID、商品 ID、数量、更新时间三个核心字段。前端加购时调用/cart/add接口,后端先判断购物车中是否已经有该商品,有则数量累加,没有则插入新记录。查询购物车时关联商品表一起查出商品名称、图片和价格:

SELECT c.id, c.goods_id, c.quantity, g.goods_name, g.goods_pic, g.sell_price, g.stock FROM cart c LEFT JOIN goods g ON c.goods_id = g.id WHERE c.user_id = #{userId} ORDER BY c.update_time DESC;

购物车里商品数量修改和删除都是基于 ID 操作,接口也不复杂。需要强调的是,每次修改数量后最好重新计算一次总价,后台最好重新从数据库读取最新价格,不要信任前端传过来的单价,防止有人直接改请求参数把价格改低。

3.4 订单生成与库存扣减事务处理

订单模块是整个系统的“心脏”,最容易出现并发问题。创建订单至少包含这几步:校验商品库存 → 生成主订单 → 批量插入订单明细 → 扣减商品库存 → 清空购物车。这五步必须在一个事务里,任何一步失败都要整体回滚。

我使用的是 Spring 声明式事务,在OrderService的创建方法上加@Transactional,传播行为默认就行。但是在扣库存的时候要注意,不能只做“先查库存再 update”,否则高并发下会出现库存超卖。更稳妥的做法是把扣减条件写进 SQL:

UPDATE goods SET stock = stock - #{quantity} WHERE id = #{goodsId} AND stock >= #{quantity};

这条 SQL 如果影响行数为 0,说明库存不足,直接抛出运行时异常,整个事务回滚。这也是目前大多数商城项目用的“乐观锁式扣减”,实现简单又有效。

订单号建议用时间戳 + 随机数生成,避免自增主键暴露订单量。订单状态我用数字表示:1 待支付、2 已支付(待发货)、3 已发货、4 已完成、5 已取消、6 退货/退款中。后台管理员操作就是改状态,但要记录状态变更日志,不然用户投诉时说不清楚。我在订单表加了update_time和remark字段,处理异常订单时直接备注原因,这对实际运营很有帮助。

3.5 后台管理端的商品上传与订单处理

后台管理端主要是给管理员用的,页面不需要太花哨,但功能要完整。商品上传包含基础信息表单和多图片上传。多文件上传我用 CommonsMultipartResolver 配置一个拦截器,接收MultipartFile[]文件数组,然后保存到服务器目录。

保存文件时要生成新文件名,防止中文文件名乱码和重名覆盖。我习惯用UUID + 原文件扩展名:

String ext = originalFilename.substring(originalFilename.lastIndexOf(".")); String newFilename = UUID.randomUUID() + ext;

图片落地之后,把/upload/goods/xxxx.jpg这样的相对路径存入数据库。页面展示时在前端用一个全局前缀拼完整 URL。这个方案在本地和部署到 Linux 服务器都通用。

后台订单管理页就是表格加查询条件,支持按状态筛选、按订单号搜索。管理员点“发货”时,用 Ajax 请求发送订单 ID 和物流单号,后端更新状态和备注。这个操作非常简单,但要注意用 JSP+Ajax 返回 JSON 时,Controller 方法要加@ResponseBody,并且返回值类型尽量封装成统一的{code, msg, data},方便前端统一处理。

4. 常见问题与排查技巧实录

4.1 Tomcat 启动后首页 404

这个坑在实训项目里出现率非常高。如果项目启动后访问http://localhost:8080/是 404,首先检查web.xml里配置的欢迎页,如果配置的是index.jsp,要确认这个文件是否在webapp根目录下。如果是 IDEA 部署的问题,大概率是 Artifacts 没有加入项目依赖,导致 JAR 没被一起打包。解决办法是打开 Project Structure → Artifacts → Output Layout,把 “Available Elements” 里的依赖包右键添加到 WEB-INF/lib 下。

还有一种情况是项目部署名不对,默认部署名可能带_war_exploded后缀。可以直接在 Tomcat 配置里把 Application context 改成/,或者改成一个稳定的项目名,否则每次启动访问路径都不一样。

4.2 数据库查询结果中文乱码

中文乱码来自三层:数据库、JDBC 连接、JSP 页面。遇到乱码先看数据库字符集:

SHOW CREATE DATABASE shop_db;

如果显示的不是utf8mb4,可以执行修改语句把数据库和表都改成utf8mb4。然后检查 jdbc.properties 里连接地址是否带参数:

jdbc.url=jdbc:mysql://localhost:3306/shop_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai

这个参数一定要加,否则即使数据库是 utf8,连接时也可能按系统默认编码读。最后检查 JSP 页面头部是否写了pageEncoding="UTF-8"和contentType="text/html; charset=UTF-8"。这三层都对了,中文一般不会乱码。

我在实际调试中发现,用 Tomcat 8 以上默认编码是 UTF-8,但如果用 POST 提交表单,取参数时中文乱码,需要配置 CharacterEncodingFilter:

<filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

4.3 MyBatis 映射文件结果返回 null

用 SSM 开发时,实体类字段通常是驼峰命名,比如sellPrice、goodsName,数据库字段是下划线命名sell_price、goods_name。如果 MyBatis 开启了驼峰映射,查询结果才自动转换;没开启,整列全返回 null,页面全空。

解决办法是在 spring-mybatis.xml 里加一个全局配置:

<configuration> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> </configuration>

另外还要检查实体类有没有无参构造器,MyBatis 底层用反射创建对象,如果类里写了带参构造器却没提供无参构造,查询也会报错。

4.4 事务不生效,数据部分回滚

这是订单模块最常见的坑。明明加了@Transactional,但扣库存失败了主订单还是插入进去。原因一般是下面几个:

第一,方法没有被 Spring 代理。如果createOrder方法在同一个类里被另一个方法直接调用,事务拦截器不会生效。要确保事务方法是从 Controller 层进去,而不是同类内部自调用。

第二,事务没有加在 public 方法上,或异常被吞掉。我在创建订单时一开始 catch 了异常打印日志,事务以为方法正常返回,直接提交了。正确的做法是让 RuntimeException 往上抛,由 Spring 捕获回滚,或者手动TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()。

第三,MyBatis 的 Mapper 执行 SQL 时如果用到了 MySQL 的 MyISAM 引擎,因为该引擎不支持事务,即使代码写了事务也一样无效。建表时统一用 InnoDB 才能在项目里正常回滚。

4.5 图片上传成功但展示不出来

图片上传后,如果页面上<img src="/upload/xxx.jpg">访问 404,先看两个位置。一个是上传路径是否和读取路径一致。很多人本地跑时用绝对路径保存,比如D:/upload/,页面上却用相对路径访问,Tomcat 默认能访问的 webapp 根目录下并没有这个文件,所以 404。

最好的做法是把上传目录配置成和项目 webapp 同级的静态资源目录,然后在 spring-mvc.xml 里配置资源映射:

<mvc:resources mapping="/upload/**" location="file:D:/upload/"/>

部署到 Linux 时,把D:/upload/换成/opt/shop/upload/,映射配置不变。这样本地和线上路径都统一用/upload访问,几乎没有偏差。

5. 部署上线与安全加固

5.1 打包部署到服务器

项目跑通本地后,上线部署也不算难,但有几件事必须做。先改数据库连接配置为公网地址,然后使用 Maven 的 package 命令打成 WAR 包。在pom.xml里确认打包方式是 war:

<packaging>war</packaging>

打包后把 target 目录下的shop.war拷贝到服务器 Tomcat 的 webapps 目录下,启动后 Tomcat 会自动解压。如果服务器上已有运行中的 Tomcat,最好先停掉再扔 war 包,避免解压到一半出问题。

如果觉得直接访问 Tomcat 不够安全,可以在前面加一层 Nginx 做反向代理,把 80 端口转发到 Tomcat 的 8080 端口。Nginx 配置里只需要一个 proxy_pass:

server { listen 80; server_name example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

5.2 常见安全风险与对应处理

商城系统涉及用户资金,安全这一块不能只求“能跑”。最容易出问题的三个点分别是 SQL 注入、XSS 和非授权访问。

MyBatis 天然使用预编译语句,只要业务代码不拼接字符串到 SQL 里,SQL 注入风险就很小。但还需要防止一些工具同学直接把order by字段拼到查询语句里,这种做法会破坏预编译。前端搜索框和富文本内容要有 XSS 过滤,比如把<script>标签进行转义,否则别人在商品评价里插入脚本,就可能窃取其他用户 Session。

后台接口必须校验管理员权限。除了前面说的拦截器,还可以在敏感操作(修改价格、删除商品、处理订单)时,不仅要校验登录态,还要校验当前用户角色,避免普通用户直接调用后台接口。最后是密码不能明文入库,这个前面已经提过。支付功能如果只是模拟,状态直接由订单模块控制,那也要注意在订单状态变更时加上简单状态机校验,防止从“待支付”直接被人改到“已完成”。

5.3 项目扩展与后续优化方向

如果做完基础功能还有余力,可以从这几个方向往上扩展,让项目在答辩或简历上更出彩。

性能方面,商品列表页加 Redis 缓存是性价比最高的优化。把热门分类的商品列表缓存到 Redis,缓存过期时间设成 5 分钟,能明显降低数据库压力。查询 SQL 也要分析慢日志,给category_id、goods_name这些常用查询字段加索引。

功能方面,可以增加简单的秒杀限流模拟、用户积分、头像上传、轮播广告、库存告警提醒。这些功能都不需要改动现有表结构,只要在原表上加字段,再加几个接口就能完成。当然,我个人的建议是先把现有模块的质量做扎实,把事务、分页、权限、上传这些基础功能调得没有隐患,再去加花活。基础流程顺畅了,这个项目的学习价值才算真正拿到手。

我个人做完这个商城项目最大的体会是:技术框架只是工具,真正难的是想清楚业务状态和边界。比如订单状态怎么流转、库存怎么扣得安全、购物车怎么保证数据一致,这些问题想透之后再去敲代码,效率会高很多。另外还有一个小技巧,就是每次改完数据库表,马上把实体类和 Mapper XML 同步更新,不要等到运行时发现字段对不上才回去补,那样会让联调过程非常痛苦。希望这份实操记录能帮你少走一些弯路。

相关新闻

从日榜看技术趋势:Rust崛起与AI应用层霸榜的深度拆解

从日榜看技术趋势:Rust崛起与AI应用层霸榜的深度拆解

1. 日榜项目的整体观察与拆解思路每天早上刷一遍热榜&#xff0c;已经成了我这些年做技术选型和趋势判断的固定动作。2026年10月8日这一期的日榜&#xff0c;整体看下来有一个很明显的特征&#xff1a;工具类项目占比超过六成&#xff0c;AI 应用层项目继续霸榜&#xff0c;但底…

2026/10/20 13:40:50 阅读更多 →
日榜速报:从开源趋势到技术选型的评估方法论

日榜速报:从开源趋势到技术选型的评估方法论

1. 日榜速报到底在解决什么信息焦虑每天早上打开代码托管平台&#xff0c;首页那个趋势榜单就像一份技术圈的晨报。但问题在于&#xff0c;榜单只给你一个仓库名和一句话简介&#xff0c;至于它为什么突然冲上来、背后用了什么技术栈、值不值得你花半小时去克隆下来跑一遍&…

2026/10/20 13:40:50 阅读更多 →
C++中变量进行初始化的3种方法

C++中变量进行初始化的3种方法

前言 「变量初始化有哪几种写法」这个问题&#xff0c;答案取决于你按什么维度分类。按语法形式分&#xff0c;最常说的是三种&#xff1a;复制初始化&#xff08;copy-initialization&#xff0c;int a 1;&#xff09;、直接初始化&#xff08;direct-initialization&#xf…

2026/10/20 13:40:50 阅读更多 →

最新新闻

OSG项目GIF插件编译失败怎么办?giflib 4.1.6 64位静态库接入与避坑指南

OSG项目GIF插件编译失败怎么办?giflib 4.1.6 64位静态库接入与避坑指南

简介&#xff1a;面向需要在 OpenSceneGraph 3.2.1 中启用 GIF 插件编译的开发者&#xff0c;这份资源提供 giflib 4.1.6 的 64 位静态链接库及配套头文件&#xff0c;可解决 osg 的 Plugin gif 链接依赖问题&#xff0c;省去自行构建 giflib 的环节。压缩包共 3 个文件&#x…

2026/10/20 14:34:30 阅读更多 →
微电网两阶段鲁棒优化调度:CCG算法应对风光不确定性

微电网两阶段鲁棒优化调度:CCG算法应对风光不确定性

1. 微电网优化调度为什么要考虑不确定性 做园区级微电网调度的人应该都有过这种体会&#xff1a;今天光伏预测曲线明明很漂亮&#xff0c;上午十点突然飘来一片云&#xff0c;出力直接砍半&#xff1b;或者风电场那边预报微风&#xff0c;结果下午风速爬升&#xff0c;风机满发…

2026/10/20 14:34:30 阅读更多 →
AI气象数据融合实现流感提前两周预警的完整实践

AI气象数据融合实现流感提前两周预警的完整实践

流感预警这件事&#xff0c;难点从来不在“发现”&#xff0c;而在“提前”。我在复现某区域流感预警Demo系统时&#xff0c;核心目标只有一个&#xff1a;在流感监测曲线还没来得及明显抬头之前&#xff0c;用AI气象数据融合的方式提前两周给出区域风险判断。很多人问我&#…

2026/10/20 14:34:30 阅读更多 →
深入理解TensorFlow 2.x自动求导:GradientTape原理、实践与排坑指南

深入理解TensorFlow 2.x自动求导:GradientTape原理、实践与排坑指南

很多人从 TensorFlow 1.x 迁移过来&#xff0c;第一件事就是找tf.gradients&#xff0c;然后一脸懵&#xff1a;没了&#xff0c;取而代之的是一个叫tf.GradientTape的东西。更懵的是&#xff0c;新写的训练代码里看不到"计算图"这种概念&#xff0c;梯度就像变魔术一…

2026/10/20 14:34:30 阅读更多 →
用Qt+Windows API打造远程控制软件:架构、协议与实战

用Qt+Windows API打造远程控制软件:架构、协议与实战

简介&#xff1a;基于Qt框架实现的Windows远程控制软件资源&#xff0c;包含服务器端&#xff08;被控端&#xff09;与客户端&#xff08;主控端&#xff09;两部分&#xff0c;附完整源码与可直接运行的编译程序。服务器端以进程形式后台运行&#xff0c;客户端为图形界面程序…

2026/10/20 14:34:30 阅读更多 →
OpenCV 2.4.13 安装指北:源码编译、环境配置与五条血泪排错记录

OpenCV 2.4.13 安装指北:源码编译、环境配置与五条血泪排错记录

简介&#xff1a;面向计算机视觉与图像处理开发者&#xff0c;该zip压缩包提供的是OpenCV 2.4.13.3经典旧版安装资源&#xff0c;适合需要维护旧项目、复现历史算法或学习传统视觉知识的用户&#xff1b;相比高版本OpenCV&#xff0c;2.4.x在函数命名与调用方式上存在差异&…

2026/10/20 14:33:27 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →