简介这套基于Java与MySQL的B/S结构企业仓库存储管理系统采用Spring BootJavaMavenMySQLMyBatis技术栈后端与前端分层清晰面向Java课程设计、毕业设计或想了解企业级Web系统完整开发流程的开发者属于中等难度的综合实战项目。系统围绕客户基本信息、仓库基本信息、产品基本信息、用户管理、入库记录、出库记录、库存管理和系统日志八大模块展开完整覆盖仓储业务核心场景。压缩包共221个文件、约6.95MB以42个Java源码文件、28个HTML页面、24个JS脚本、8个CSS样式、1个SQL脚本及9个XML配置为主同时包含75张gif操作演示图与若干jpg/png界面截图便于直观理解各模块的实际运行效果。已有568人浏览学习。读者拿到压缩包后可对照源码、数据库脚本和演示动图快速还原出系统运行环境学习Spring Boot与MyBatis的整合方式、B/S结构的权限管理思路并可直接将其用作课程设计报告或答辩演示的项目基础。1. 为什么一个仓库系统最难的居然是库存流水对不上做企业仓库存储管理系统很多人第一反应是写几个 CRUD 页面商品增删改查、入库单、出库单撑死再加个库存列表。真正跑起来才发现账面库存和实际库存对不上是常态月底盘点差异能让人怀疑人生。这个项目的核心难点不在页面多好看而在「每一笔库存变动都有据可查」——入库、出库、退库、盘点调整每一步都要落流水、加事务、处理好并发。用 Java MySQL 做 Web 仓库系统选的其实就是这条最稳妥的技术路线Java 负责业务逻辑和事务控制MySQL 负责数据持久化和一致性保证。这套组合对单仓库、千级 SKU、日均几百笔单据的企业场景完全够用也是课程设计、毕设和企业内部小系统最常见的落地方案之一。适合正在做课程设计的学生也适合刚接手企业信息化项目、想快速搭一套可用系统的开发者。2. 技术选型与项目骨架为什么用 Spring Boot 而不是 JSP/Servlet2.1 框架选型Spring Boot MyBatis 是当前最常见组合标题写的是「基于 Java MySQL 实现 Web」这个范围内有三条常见路线纯 JSP Servlet JDBC、Spring MVC Spring MyBatisSSM、Spring Boot MyBatis。纯 JSP Servlet 不是不能做但你会发现大量时间浪费在手动封装请求参数、处理事务、管理数据库连接上。SSM 是前几年的主流配置繁琐一个 XML 配置文件动辄上百行。Spring Boot 把这些约定都内置了内嵌 Tomcat打一个 jar 包就能跑对仓库管理系统这种典型业务型项目开发效率高得多。MyBatis 和 JPA 之间我更倾向 MyBatis。仓库系统的 SQL 复杂多表联查多库存扣减这类操作需要精确控制 SQL 语句。MyBatis 把 SQL 写在 XML 里出了性能问题可以直接拿 SQL 去 EXPLAIN排查链路短。提示如果你是在校生做课程设计用 Spring Boot MyBatis 比 JSP/Servlet 在答辩时更有说服力同时代码量反而更少。2.2 用 Spring Initializr 生成项目骨架无论你是用 IDEA 还是直接访问 Spring Initializr 网站选以下依赖即可Spring Web提供 MVC 和内嵌 TomcatMyBatis Framework数据访问层MySQL DriverJDBC 驱动Lombok减少实体类样板代码生成后补一个工具包以 Maven 为例在pom.xml中添加 Hutool 或 Apache Commons Lang3用于字符串处理和日期格式化dependency groupIdcn.hutool/groupId artifactIdhutool-all/artifactId version5.8.25/version /dependency核心代码逻辑与 Spring 框架完全解耦Hutool 只是工具增强不会影响业务代码结构。版本号以你实际拉取的为准。项目结构按常见的分层走controller接收请求、service处理业务、mapper访问数据库、entity放实体、dto放参数对象。另外加一个common包放统一返回结果和异常处理。2.3 配置 application.yml5 个必调参数仓库系统最怕的是数据库连错、时区错乱、连接池不够用。application.yml里的核心配置如下server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/warehouse_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: root password: 你的密码 hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.warehouse.entity configuration: map-underscore-to-camel-case: true连接串里的characterEncodingutf8解决中文乱码serverTimezoneAsia/Shanghai解决 MySQL 8.x 的时区报错allowPublicKeyRetrievaltrue解决 MySQL 8.x 的 caching_sha2_password 认证问题。这三个参数不配齐项目启动就会报错或中文变问号。连接池用 HikariCPSpring Boot 2.x 之后默认就是它。maximum-pool-size设 20 对仓库管理系统足够不用盲目加。map-underscore-to-camel-case开启后数据库字段create_time能自动映射到 Java 属性的createTime少写一堆resultMap。注意MySQL 8.x 的驱动类名是com.mysql.cj.jdbc.Driver老资料里写的com.mysql.jdbc.Driver在新版驱动里已经移除了。2.4 统一返回格式与全局异常处理前后端交互不统一前端解析数据时就要写各种 if-else。仓库系统涉及多个模块统一返回格式能省大量联调时间Data public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(Integer code, String message) { ResultT result new Result(); result.setCode(code); result.setMessage(message); return result; } }全局异常处理用RestControllerAdvice拦截业务异常和兜底异常保证数据库约束冲突、空指针这类问题不会把堆栈信息直接抛给前端。前端只需要判断code是否为 200其余情况一律弹 message联调效率翻倍。3. 数据库设计仓库系统的表结构是照着「进销存」三个字拆出来的3.1 物理模型6 张核心表一张都不能少仓库系统的表结构不复杂但每张表的存在都有明确业务含义。少了任何一张表都会出现「某个业务场景没法落库」的尴尬。表名用途核心字段user系统用户管理员/操作员username, password, rolesupplier供应商信息name, contact, phoneproduct商品信息sku, name, spec, unit, pricestock实时库存product_id, quantity, locationstock_record库存流水每笔变动留痕product_id, type, quantity, before_qty, after_qty, create_timeoperation_record操作日志/出入库单据record_no, type, operator_id, remark这里最核心的几条设计原则第一库存实时表和流水表分开。stock表只存当前库存数量stock_record表记每一笔变动的前值、后值、类型。这样查询当前库存走索引极快对账时翻流水表两张表职责清晰。第二stock表必须建(product_id)唯一索引。一个商品在同一仓库只能有一条库存记录这是数据一致性的底线。没有唯一索引并发情况下可能出现同商品多条库存记录对账直接崩溃。第三所有金额字段用DECIMAL(10, 2)禁止用double或float。浮点数的二进制表示会导致精度丢失0.1 0.2 ! 0.3 这个经典坑在金额上就是事故。3.2 建表 SQL直接可跑的版本CREATE DATABASE IF NOT EXISTS warehouse_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE warehouse_db; CREATE TABLE user ( id INT NOT NULL AUTO_INCREMENT, username VARCHAR(50) NOT NULL COMMENT 登录名, password VARCHAR(100) NOT NULL COMMENT 密码BCrypt加密, real_name VARCHAR(50) DEFAULT NULL COMMENT 真实姓名, role TINYINT NOT NULL DEFAULT 0 COMMENT 0-操作员 1-管理员, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT系统用户表; CREATE TABLE product ( id INT NOT NULL AUTO_INCREMENT, sku VARCHAR(50) NOT NULL COMMENT 商品编码, name VARCHAR(100) NOT NULL COMMENT 商品名称, spec VARCHAR(100) DEFAULT NULL COMMENT 规格型号, unit VARCHAR(20) DEFAULT NULL COMMENT 单位件/箱/盒, price DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 参考进价, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_sku (sku) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT商品表; CREATE TABLE stock ( id INT NOT NULL AUTO_INCREMENT, product_id INT NOT NULL, quantity INT NOT NULL DEFAULT 0 COMMENT 当前库存数量, location VARCHAR(50) DEFAULT NULL COMMENT 库位, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_product_id (product_id), CONSTRAINT fk_stock_product FOREIGN KEY (product_id) REFERENCES product (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT实时库存表; CREATE TABLE stock_record ( id INT NOT NULL AUTO_INCREMENT, product_id INT NOT NULL, type TINYINT NOT NULL COMMENT 1-入库 2-出库 3-盘点调整 4-退货入库, quantity INT NOT NULL COMMENT 变动数量正数, before_qty INT NOT NULL COMMENT 变动前库存, after_qty INT NOT NULL COMMENT 变动后库存, remark VARCHAR(200) DEFAULT NULL, operator_id INT NOT NULL COMMENT 操作人, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_product_time (product_id, create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT库存流水表;建表时要特别注意stock_record里的before_qty和after_qty。这是整个系统对账的基石。没有这两个字段你只能在业务代码里猜测「当时库存是多少」查不了历史快照月底盘点差异根本定位不到是哪一笔出错的。字段命名也用quantity而不是count避免和 MySQL 的保留字产生冲突。外键只建在stock和product之间流水表不建外键。流水表数据量大外键会拖慢插入性能而且业务上不允许删除流水外键的级联删除功能用不上。3.3 索引设计别给所有列都加索引很多新手喜欢给每个字段都建索引这是最常见的翻车操作。索引不是越多越好——每次写入都要维护索引索引过多会让插入变慢还白白占磁盘。这六张表里真正需要索引的是user(username)唯一索引、product(sku)唯一索引、stock(product_id)唯一索引、stock_record(product_id, create_time)联合索引。其余字段走全表扫描完全可接受毕竟单表数据量撑死几万行。stock_record的联合索引要遵循最左前缀原则product_id放前面。查询某商品的历史流水是高频操作按商品查、按时间排序这个索引能直接命中。如果你还经常按时间范围查所有流水那再加一个单独create_time索引也合理但前期不用急着加。注意流水表只允许插入不允许修改、删除。所有库存调整必须走「新增流水 更新库存」两步这是保证账实一致的地基。谁要是图省事直接 UPDATEstock_record月底对账找平就要通宵了。4. 核心业务实现入库出库的事务与流水是系统的命根子4.1 库存变更的实现原理先加锁查询再更新再写流水库存扣减是这个系统里并发风险最高的场景。两个操作员同时出库同一个商品如果代码是「先查出来再减再更新」就会遇到经典的丢失更新——两个线程都查到库存 10各自减 1 后都写回 9实际应该剩 8。解决思路有三种常见方案悲观锁、乐观锁、原子更新。仓库系统我推荐「原子更新 后写流水」的组合。原子更新就是让数据库自己保证操作的原子性而不是在 Java 代码里做先查后改三步。4.2 出库业务代码事务边界划清楚Service public class StockService { Autowired private StockMapper stockMapper; Autowired private StockRecordMapper stockRecordMapper; Transactional(rollbackFor Exception.class) public void outbound(Integer productId, Integer quantity, Integer operatorId, String remark) { // 1. 原子扣减UPDATE 语句里带条件影响行数为 0 说明库存不足 int rows stockMapper.deductStock(productId, quantity); if (rows 0) { throw new BusinessException(库存不足或商品不存在); } // 2. 查扣减后的最新库存用于写流水 Stock stock stockMapper.selectByProductId(productId); int beforeQty stock.getQuantity() quantity; int afterQty stock.getQuantity(); // 3. 插入流水 StockRecord record new StockRecord(); record.setProductId(productId); record.setType(2); // 出库 record.setQuantity(quantity); record.setBeforeQty(beforeQty); record.setAfterQty(afterQty); record.setOperatorId(operatorId); record.setRemark(remark); stockRecordMapper.insert(record); } }对应 Mapper XML 中的扣减 SQLupdate iddeductStock UPDATE stock SET quantity quantity - #{quantity} WHERE product_id #{productId} AND quantity #{quantity} /update这段代码的核心逻辑在UPDATE ... WHERE quantity #{quantity}。数据库的 UPDATE 语句是行级原子操作两个并发请求同时执行时InnoDB 会对命中的行加锁第二个请求必须等第一个提交或回滚后才能执行。affected rows为 0 时说明库存不够直接在 Java 层抛业务异常事务回滚流水也不会写入。Transactional(rollbackFor Exception.class)指定所有异常都回滚。注意 Spring 默认只在 RuntimeException 时回滚如果业务代码里抛的是 checked exception事务不会回滚这是新手最常踩的事务坑。所以这里明确指定rollbackFor。流水记录用了「先加后减」的方式算beforeQty——查询到的当前数量加上本次变动数量就是变动前数量。这样做比「更新前先 SELECT 一次」少了查询开销也避免了两次查询之间数据又被改掉的窗口期。4.3 入库业务首次入库要自动建库存记录入库比出库多一个边界情况商品是第一次入库stock表里可能还没有记录。先尝试更新影响行数为 0 时执行插入Transactional(rollbackFor Exception.class) public void inbound(Integer productId, Integer quantity, Integer operatorId, String remark) { int rows stockMapper.increaseStock(productId, quantity); if (rows 0) { // 没有库存记录则创建注意并发场景下可能插入失败 stockMapper.insert(new Stock(productId, quantity)); } Stock stock stockMapper.selectByProductId(productId); int beforeQty stock.getQuantity() - quantity; int afterQty stock.getQuantity(); StockRecord record new StockRecord(); record.setProductId(productId); record.setType(1); record.setQuantity(quantity); record.setBeforeQty(beforeQty); record.setAfterQty(afterQty); record.setOperatorId(operatorId); record.setRemark(remark); stockRecordMapper.insert(record); }这里有个并发隐患两个线程同时首次入库同一商品都可能先更新影响 0 行然后都执行插入。但因为stock表有uk_product_id唯一索引只有一个插入成功另一个会抛 DuplicateKeyException——不过此时事务回滚会导致整体失败用户需要重试一次。更稳妥的做法是在catch掉 DuplicateKeyException 后再走一次更新逻辑。但考虑到首次入库同一商品本来就是低频场景重试一次用户完全可以接受我一般不会过度设计。你可以在「用唯一索引兜底 提示重新提交」之间选一种都能接受。update idincreaseStock UPDATE stock SET quantity quantity #{quantity} WHERE product_id #{productId} /update4.4 盘点功能为什么必须是「调整单」而不是直接改库存很多初级系统直接做一个「修改库存」的按钮输入新数量、保存。这种做法后患无穷——你只知道库存被改了但不知道是谁改的、为什么改、改之前是多少。亚马逊仓库的一个基本纪律是「任何库存变动都要有单据可追溯」。正确的做法是做盘点调整单操作员录入实际盘点数量系统对比账面库存自动计算差异然后生成一条类型为 3 的流水再更新库存-- 盘点调整新库存 盘点数流水里记录调整前后值 UPDATE stock SET quantity #{actualQty} WHERE product_id #{productId}盘点调整单还需要额外的表单字段盘点人、盘点时间、差异说明。这些信息跟着流水一起保存月底复盘时一眼就能看出是盘亏还是盘盈原因写没写。4.5 分页查询PageHelper 插件还是手写 LIMIT列表页和流水分页是仓库系统的高频请求。常见的做法是用 PageHelper 插件几行代码就搞定分页但它的实现原理是基于 MyBatis 拦截器会拦截所有查询并改写 SQL代码里审查起来不如手写直观。我一般选择手写 LIMITselect idselectRecordPage resultTypeStockRecord SELECT * FROM stock_record WHERE product_id #{productId} ORDER BY id DESC LIMIT #{offset}, #{pageSize} /select再用一个 COUNT 查询拿总数给前端算总页数两个查询一共 10 行 SQL可读性更好也不依赖第三方插件的分页方言解析。如果你的系统里分页场景特别多用 PageHelper 也没问题但要注意它分页线程隔离的坑——用 ThreadLocal 存分页参数在异步线程里会丢导致查出来全表数据。5. 避坑合集仓库系统现场的 4 个翻车记录5.1 现象数据库存的时间比本地时间早 8 小时或者启动报 Server time zone 错误原因MySQL 8.x 的连接串必须显式指定时区否则使用服务器默认时区。驱动和系统时区不一致时DATETIME类型的读写就会出现偏移。解决连接串加serverTimezoneAsia/Shanghai同时建库时显式声明CREATE DATABASE warehouse_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;不要用SET time_zone 8:00这种会话级设置因为连接池会复用连接多个会话之间互相被改了就出乱子。5.2 现象页面上中文全部变成问号查数据再写回也是问号原因MySQL 驱动连接串没有指定编码或者建库时用了默认的 latin1 字符集。驱动字符集和数据库字符集不一致中转过程就会丢失字符。解决连接串带characterEncodingutf8建库带DEFAULT CHARACTER SET utf8mb4。生产环境建议直接统一 utf8mb4它兼容所有 Unicode 字符包括生僻字和 emoji避免后期业务扩展时再迁移字符集。UTF8 在 MySQL 里最多存 3 个字节生僻字和 emoji 是 4 个字节会报Incorrect string value错误。5.3 现象两个操作员同时出库同一商品最终库存少减了或多减了原因业务代码是「先 SELECT 查库存判断是否充足再 UPDATE 减库存」两个请求都查到库存 10都判断通过各自减 1 后写回 9实际应该剩 8。这就是经典的丢失更新。解决用单一 UPDATE 语句原子扣减WHERE里带库存充足判断UPDATE stock SET quantity quantity - #{qty} WHERE product_id #{productId} AND quantity #{qty}影响行数为 0 即库存不足抛业务异常回滚。InnoDB 引擎对行级 UPDATE 自动加锁这一步就能解决大部分并发问题。如果这种场景极高频再考虑SELECT ... FOR UPDATE的悲观锁介入但要记得锁的粒度按product_id走别把整条库存表锁住。5.4 现象库存流水突然缺失对账怎么都对不上原因流水和库存更新不在一个事务里。常见的是先更新库存、再插流水中间抛了个异常库存已经提交但流水没写进去。或者用了 Spring 的Transactional但方法内部自调用事务注解根本没生效。解决核心业务代码中库存更新和流水插入必须在一个事务里且使用代理调用。事务是否生效的检查方法——把日志级别调到 DEBUG 看是否有Creating new transaction日志。自调用问题的修复办法是把业务方法拆分到另一个 Service 类里注入后调用让 Spring AOP 的代理对象去执行而不是this直接调用。5.5 现象删除商品报错说有外键约束不报错但历史单据里商品信息全乱了原因product表被stock表外键引用直接 DELETE 会被 MySQL 拦下。而如果不建外键商品删了历史流水里的商品名就变成了孤儿数据。解决商品表加status字段删除用逻辑删除——更新status 0查询列表时默认过滤掉。所有需要展示商品名的历史记录关联查询时保留当时的快照字段在单据表冗余商品名和编码删了商品也不影响历史对账。6. 部署上线与验收技巧从开发机到能跑一个月不出事的流程6.1 服务器部署与 JVM 参数项目打成 jar 包后在 Linux 服务器上直接扔给 Java 命令跑。真正要注意的是启动参数的设置nohup java -Xms512m -Xmx1024m \ -XX:HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath/app/logs/heapdump.hprof \ -jar warehouse-system.jar \ --spring.profiles.activeprod \ --server.port8080 \ /app/logs/app.log 21 JVM 参数的设置与你的服务器内存直接相关。2G 内存的服务器就给-Xmx1024m别贪心给大否则操作系统本身和 MySQL 内存容易吃紧。HeapDumpOnOutOfMemoryError是兜底手段万一内存溢出至少能导出堆快照让后续复查崩因。6.2 验证系统是否合格的 3 个标准第一连续入库出库 100 次查stock表数量与流水after_qty最新值完全一致。写个循环脚本自动跑手工点 100 次会疯掉for i in $(seq 1 100); do curl -X POST http://localhost:8080/api/stock/inbound \ -H Content-Type: application/json \ -d {productId:1,quantity:1,operatorId:1,remark:测试} \ -o /dev/null -s -w %{http_code}\n done第二模拟并发扣减用 JMeter 或一个简单的并发脚本50 个线程同时出库库存只剩 50 的商品最终库存必须是 0 且无一条流水是负数。这一步能验证第 4 章的原子扣减是否真的扛住了并发。第三登出登录、权限控制测试——操作员角色不能打开管理员页面。仓库系统的权限粒度不需要太细但「操作员不能删库级别的操作」是底线。6.3 两个能让你省半年维护心力的习惯第一个习惯是给数据库加定时备份。仓库系统的数据是资产服务器硬盘崩了不可怕数据没备份才可怕。最简单的做法是 cron 每天凌晨跑一次 mysqldump0 2 * * * mysqldump -uroot -p你的密码 warehouse_db /backup/warehouse_$(date \%Y\%m\%d).sql 2/dev/null find /backup -mtime 30 -exec rm {} \;保留 30 天备份磁盘占用完全可以接受。第二个习惯是在代码里打日志时带上「谁在什么时间对哪个商品做了什么操作」这个三元组。这个习惯靠的是Aspect加一个操作日志切面自动记录。也可以不建切面而是在业务方法里手动加一行log.info(userId{}, productId{}, actionoutbound, quantity{}, operatorId, productId, quantity)。等真出了账实不一致的问题日志和流水表能互相印证定位。这两个习惯是我自己踩过多次坑之后沉淀下来的——没备份时硬盘坏过一次没日志时出了问题把代码翻了个底朝天。现在做仓库系统先搭备份自动化再写业务逻辑顺序不能反。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
JDBC+JSP+Servlet图书管理系统搭建与部署全指南 简介:基于JDBCJSPServlet的图书管理系统,是一份面向Java Web学习者的课程设计/期末大作业完整源码包,项目内置数据库脚本与说明文档,导入IDE后即可运行,无需二次修改,适合需要快速交付或对照学习的在校学生… · 2026/9/23 3:41:11
2025年风口再审视:万字长文,用TaoToken统一Key打通大模型Agent多工具调用链路 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/23 3:41:05
自动驾驶多类别交通目标检测数据集7:从数据体检到YOLOv8训练与格式转换全流程 简介:这份自动驾驶多类别交通目标检测数据集面向自动驾驶感知算法开发者、智能交通研究人员及计算机视觉方向的学生,用于构建车辆、行人、交通标志等多目标实时检测系统,可支撑L2至L4级自动驾驶算法开发与ADAS功能优化。资源包共2000个文件&a… · 2026/9/23 4:22:25
基于印度肝病数据集的ANN与Flask诊断系统实战 简介:这份资源面向机器学习入门者、医学数据分析爱好者及需要完成课程设计或毕业项目的学生,提供基于印度肝病患者数据集的智能诊断完整实现。数据集包含416名肝病患者与167名非肝病患者记录,涵盖441名男性与142名女性样本,标签列… · 2026/9/23 4:22:25
RAG检索优化:从Chunking到混合检索再到Rerank的工程实践 1. 先别急着上 Rerank:把 RAG 当检索系统来工程化1.1 一条能跑的基线链路在 Spring AI 2.0 里长什么样最早我把 RAG 搭起来时,走的是最典型的四步流程:读文档、切块、写向量库、问答时检索增强。用 Spring AI 2.0 的 API 写出来非常简洁&… · 2026/9/23 4:22:25
Token 用不完?从上下文管理到报错排查的工程实践 1. "开启无限 token"这件事,得先把 token 的老底掀开看到"ChatGPT 开启无限 token"这类标题,我的第一反应是:又有人拿 token 这个概念做文章了。我在不少网站和短视频里刷到过类似的标题,点进去无非是几种套路… · 2026/9/23 4:22:25
气胸X光分割数据集实战:2000张像素级标注到模型训练与部署 简介:面向医学图像分割研究者和AI开发人员,本资源提供专门用于胸部X光气胸(Pneumothorax)语义分割的数据集,可支撑模型训练、验证与算法对比,适用于医学影像分析相关课题或竞赛。包内含超过2000张胸部X光图… · 2026/9/23 4:22:18
www.dy2018.com实战:从零到完整示例避坑全记录 www.dy2018.com实战:从零到完整示例避坑全记录 刚学完Python语法,是不是觉得手里有剑,却不知往哪里挥?很多人卡在“学会语法却不知怎么搭项目”这一步,代码能跑,但一上真实业务就崩。我翻遍CSDN、StackOverflow和… · 2026/9/23 4:22:18
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29