SpringBoot+Vue学科竞赛管理系统:从数据库设计到部署上线全解析

搞学科竞赛管理系统这种题目,在毕业设计和课程设计里出现频率极高。导员需要一个能管理报名、审核、发布成绩的后台,参赛学生需要一个能看到赛事信息、在线报名、上传作品、查成绩的入口,老师则需要一个能评审打分、导出数据的操作台。这种三方角色、多状态流转的项目,正好能完整展示SpringBoot+Vue全栈开发能力,所以很多同学选它作为毕设。本文就基于这个“SpringBoot+Vue学科竞赛管理平台”,把从数据库设计、后端接口、前端页面到部署上线的完整思路和实操细节都掰开揉碎讲一遍,重点说哪些坑是你自己写代码时容易忽略的。

我做过好几个类似的管理系统,说实话,这类项目功能本身不难,真正拉开差距的是对业务状态的理解、权限控制的严谨性,以及接口和页面的细节处理。下面直接从需求分析开始,带着你逐步把平台从0到1搭起来。

1. 从需求到架构:这个学科竞赛平台到底该怎么搭

1.1 学科竞赛管理的痛点与功能拆解

先想清楚一个问题:学科竞赛管理在日常工作中到底麻烦在哪?

  • 赛事信息发布渠道分散,学生看不到统一通知。
  • 报名靠Excel统计,人多容易漏、容易错。
  • 作品提交格式不统一,文件命名混乱。
  • 评委打分后数据汇总工作量大,还容易算错平均分。
  • 学生想查自己成绩只能等通知,状态不透明。

所以,一个合格的竞赛管理平台,至少要覆盖完整业务闭环:用户登录 → 查看赛事 → 在线报名 → 上传作品 → 评委打分 → 管理员发布成绩 → 学生查看结果。

平台用户大概分三类:

角色核心诉求权限边界
学生浏览赛事、报名、传作品、查成绩只能操作自己的报名记录
教师/评委发布赛事、审核报名、打分可管理自己创建的赛事,对分配到的作品评分
管理员全局配置、用户管理、数据汇总所有模块,可操作任何数据

功能模块也就随之清晰了:用户管理、赛事管理、报名管理、作品管理、评分管理、成绩发布、公告通知、数据统计。看起来不少,但每个模块拆开并不复杂,典型的CRUD加状态流转。

1.2 为什么选SpringBoot+Vue,而不是其他组合

有同学问,用SSH行不行?用JSP行不行?不是不行,但你得考虑毕设答辩和后续维护。SpringBoot最大的优势是简化了Spring配置,内嵌Tomcat,打个jar包就能跑。配合MySQL做数据存储,是Java领域最主流、参考资料最多的组合。Vue作为前端框架,组件化开发让页面维护非常方便,而且Vue2或Vue3都有大量现成的后台管理模板可以借鉴。

选择这个组合还有几个现实原因:

  1. 前后端分离的架构更容易在答辩时讲清楚,一个专门讲后端RESTful接口,一个专门讲前端组件通信和路由控制。
  2. SpringBoot生态完善,Spring Security或JWT方案都很成熟,写权限控制有标准打法。
  3. Vue+Element UI做后台页面是真的快,表格、表单、弹窗都是现成组件,几天就能把页面撸完。
  4. 对于学习者来说,这套技术栈的代表性足够强,毕业后写简历也能拿得出手。

当然,你也可以用MyBatis-Plus操作数据库,甚至用Redis做缓存。但既然是课程设计级需求,我建议不要过度设计,默认单机部署,MySQL+SpringBoot+Vue就够用,稳定、好演示、不给自己挖坑。

2. 数据库设计与核心表结构

2.1 用户、角色与权限怎么建模

表结构设计是这类项目的命脉,后端的业务逻辑基本都围绕表关系展开。我建议不要搞复杂的角色权限框架,就用最简单直接的“用户表 + 角色字段 + 中间关联表”来实现。

用户表可以这么设计:

CREATE TABLE `user` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL UNIQUE COMMENT '登录账号', `password` VARCHAR(255) NOT NULL COMMENT 'BCrypt加密后的密码', `real_name` VARCHAR(50) COMMENT '真实姓名', `student_no` VARCHAR(20) COMMENT '学号', `email` VARCHAR(100), `phone` VARCHAR(20), `role` TINYINT NOT NULL DEFAULT 3 COMMENT '1-管理员 2-教师 3-学生', `status` TINYINT NOT NULL DEFAULT 1 COMMENT '1-正常 0-禁用', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP );

这里的role用TINYINT数字表示,1、2、3分别对应管理员、教师、学生。很多同学会用字符串存储角色,比如"admin"、"teacher"、"student",这也能行,但用数字更省空间,而且后端做判断时用int比较不容易写错。前端再根据数字映射成中文名称。

不过需要注意,如果后续角色权限扩展更复杂,比如教师分成“评委”和“指导老师”,那单字段就不够用了。稳妥做法是加一张角色表和用户角色关联表,后端判断权限时用角色编码。对于毕设来说,单字段+TINYINT已经能应付,答辩时讲清取舍即可。

密码绝对不能用明文存储。使用Spring Security的BCryptPasswordEncoder加密,即使数据库泄露,也不会直接暴露密码。我看到太多毕设代码把密码直接放在数据库里,这是重大安全隐患,答辩老师一眼就能挑出毛病。

2.2 竞赛、报名、作品、评分表的设计要点

业务核心表不能少,竞赛表(competition)、报名表(enrollment)、作品表(work)、评分表(score)是最基本的四张。另外,竞赛和评委的关系也比较关键,建议单独建一张竞赛评委关联表。

竞赛表:

CREATE TABLE `competition` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `title` VARCHAR(100) NOT NULL COMMENT '竞赛名称', `description` TEXT COMMENT '竞赛简介', `type` VARCHAR(50) COMMENT '竞赛类别,如编程、数学建模', `start_time` DATETIME COMMENT '报名开始时间', `end_time` DATETIME COMMENT '报名结束时间', `status` TINYINT DEFAULT 0 COMMENT '0-未开始 1-报名中 2-进行中 3-已结束', `creator_id` INT COMMENT '创建人ID', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP );

报名表:

CREATE TABLE `enrollment` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `competition_id` INT NOT NULL, `user_id` INT NOT NULL, `team_name` VARCHAR(100) COMMENT '团队名称', `status` TINYINT DEFAULT 0 COMMENT '0-待审核 1-已通过 2-已拒绝 3-已取消', `apply_time` DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY `uk_comp_user` (`competition_id`, `user_id`) );

报名表上加唯一联合索引很有必要,防止同一个学生重复报名同一个竞赛。这个细节虽然小,但能体现你对数据库设计的思考。

作品表:

CREATE TABLE `work` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `enrollment_id` INT NOT NULL COMMENT '关联报名ID', `work_name` VARCHAR(100) COMMENT '作品名称', `work_file_url` VARCHAR(255) COMMENT '文件路径', `description` TEXT, `submit_time` DATETIME DEFAULT CURRENT_TIMESTAMP );

评分表:

CREATE TABLE `score` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `work_id` INT NOT NULL COMMENT '作品ID', `judge_id` INT NOT NULL COMMENT '评委用户ID', `score` DECIMAL(5,2) COMMENT '打分成绩', `comment` VARCHAR(500) COMMENT '评语', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY `uk_work_judge` (`work_id`, `judge_id`) );

评分表上的唯一索引也是关键,一对作品一个评委只能打一次分,避免重复记录。成绩计算的时候,如果多个评委打分,可以取平均分,也可以去掉最高最低再平均,具体按竞赛规则来,后端Service里写清楚即可。

竞赛与评委的关联表:

CREATE TABLE `competition_judge` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `competition_id` INT NOT NULL, `judge_id` INT NOT NULL COMMENT '评委用户ID,关联user表' );

这类关联表在可视化关系时很直观,在MyBatis的Mapper里做多表关联查询也方便。数据库设计阶段把主外键关系理清,后面写代码能省一半时间。外键约束可以看情况加,有些人喜欢在代码层维护关联关系,但至少逻辑外键要在设计文档里体现。

3. SpringBoot后端核心实现

3.1 项目结构与统一返回体设计

后端项目结构我习惯按功能分包,而不是按层分包。按层分包是controller/service/dao三层各建一个包,把所有Controller堆在一起。按功能分包则是一个模块对应一个包,比如user、competition、enrollment、work、score,每个包里有Controller、Service、Mapper。这样当你需要改动某个业务时,只需要在一个包内操作,思路清晰得多。

推荐结构示例:

com.example.competition ├── controller │ ├── UserController.java │ ├── CompetitionController.java │ ├── EnrollmentController.java │ └── ... ├── service │ └── impl ├── mapper ├── entity ├── dto ├── vo ├── config └── common

统一返回体是前后端分离项目必须做的事。没有统一返回格式,前端处理数据就要写一堆重复代码。我推荐一个简单的Result类:

@Data public class Result<T> { private Integer code; private String msg; private T data; public static <T> Result<T> success(T data) { Result<T> result = new Result<>(); result.code = 200; result.msg = "操作成功"; result.data = data; return result; } public static <T> Result<T> error(String msg) { Result<T> result = new Result<>(); result.code = 500; result.msg = msg; return result; } }

code用200/500已经够用了,也可以细分:400代表参数错误、401代表未登录、403代表无权限。不过毕设阶段不用强行参照HTTP状态码,只要前后端约定一致即可。前端Axios统一拦截器里对code做判断,非200就弹错误提示,代码清晰又省事。

3.2 JWT登录鉴权与角色权限控制

登录鉴权方案推荐JWT,无状态,适合前后端分离,实现也不复杂。流程就是:用户输入用户名密码 → 后端校验 → 生成Token返回前端 → 前端每次请求带在Header里 → 后端拦截器校验Token并解析用户信息。

先添加依赖,SpringBoot 2.x用:

<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>

注意jjwt 0.9.1依赖javax.xml.bind,JDK8没问题,如果你用JDK11以后,需要额外加jaxb-api,否则启动会报错。用SpringBoot 3.x的同学建议换jjwt 0.11.5,API有变化。

JWT工具类核心方法就三四个:生成Token、解析Token、判断是否过期。Token里放userId和role就可以,不放敏感信息。密钥写死在配置里也行,最好用Base64编码的长字符串。

登录接口逻辑:

public Result<LoginVO> login(LoginDTO dto) { User user = userMapper.findByUsername(dto.getUsername()); if (user == null || !bcrypt.matches(dto.getPassword(), user.getPassword())) { return Result.error("用户名或密码错误"); } if (user.getStatus() == 0) { return Result.error("账号已被禁用"); } String token = jwtUtils.generateToken(user.getId(), user.getRole()); LoginVO vo = new LoginVO(); vo.setToken(token); vo.setRole(user.getRole()); vo.setRealName(user.getRealName()); return Result.success(vo); }

把role放进Token里很有用,后续拦截器解析出角色后可以直接做权限判断,省得每次请求都查数据库。当然,如果有人修改了角色,只靠Token里的信息不够安全。严谨的做法是在需要时再去数据库校验角色,但毕设不用过度设计。

拦截器实现权限控制时,我建议用HandlerInterceptor,在preHandle里从Header取Token,无效则返回401错误。然后自定义一个注解,比如@RequireRole(role = 2),在Controller方法上标注需要哪种角色。拦截器里通过反射拿到方法上的注解再判断。这样写出来的代码比较乾净,答辩讲起来也清楚。

3.3 竞赛报名和成绩管理的业务逻辑

竞赛模块的接口无非是增删改查,但要处理好状态联动。比如报名截止时间到了,status自动变成进行中;报名未开始的竞赛不能报名;竞赛结束后不能再提交作品。这些规则写在Service层,别散落在Controller里。

报名业务伪代码:

@Transactional public Result<String> apply(EnrollmentDTO dto) { // 1. 检查竞赛存在且状态为报名中 Competition comp = competitionMapper.findById(dto.getCompetitionId()); if (comp == null || comp.getStatus() != 1) { return Result.error("竞赛不存在或不在报名时间"); } // 2. 检查是否已报名 int count = enrollmentMapper.selectCountByCompAndUser(dto.getCompetitionId(), currentUserId()); if (count > 0) { return Result.error("请勿重复报名"); } // 3. 创建报名记录 enrollment.setStatus(0); // 待审核 enrollmentMapper.insert(enrollment); return Result.success("报名成功,等待审核"); }

注意@Transactional,如果后续还有作品表、审核表的同时操作,必须保证事务一致。这里要在Service层加事务而不是Controller层。

成绩管理的核心是评委打分。普通用户肯定不能访问打分接口,所以接口上标@RequireRole(role = 2),只有教师角色能访问。成绩计算时涉及多个评委打分取平均,SQL可以这样写:

Double avgScore = scoreMapper.getAvgScoreByWorkId(workId);

对应Mapper XML:

<select id="getAvgScoreByWorkId" resultType="java.lang.Double"> SELECT AVG(score) FROM score WHERE work_id = #{workId} </select>

注意空结果处理,如果还没有任何评委打分,AVG返回null,需要判断一下。发布成绩时,管理员可以选择“一键公布”,实际上就是修改竞赛状态或者成绩表里的publish字段,学生端查询接口只返回已公布的成绩。

4. Vue前端页面与接口联调

4.1 前端工程结构和路由权限

前端我用Vue3 + Vite + Element Plus,最近几年新项目多数这么搭。Vue2也可以,但Vue3是趋势,而且Element Plus在Vue3下表现很稳定。用Vite创建项目:

npm create vite@latest competition-frontend -- --template vue cd competition-frontend npm install element-plus axios vue-router pinia npm run dev

前端工程结构:

src ├── api // 接口请求封装 │ ├── auth.js │ ├── competition.js │ └── ... ├── router // 路由配置 ├── store // 状态管理 ├── views // 页面 │ ├── login.vue │ ├── admin │ ├── teacher │ └── student ├── utils // 工具函数 └── App.vue

路由权限分两块:一是未登录跳转登录页,二是不同角色访问不同菜单。最简单的方式是在路由meta里写role数组,然后路由守卫里判断当前用户角色是否在允许列表中。

router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (to.path === '/login') { next() } else if (!token) { next('/login') } else { const role = Number(localStorage.getItem('role')) const allowed = to.meta.roles if (allowed && !allowed.includes(role)) { next('/403') } else { next() } } })

这个策略简单直接,适合大多数管理后台。菜单渲染时再根据角色过滤一次,前端不会把无权限的菜单展示给用户。

4.2 核心页面设计与Axios封装

后台管理系统页面就那几个套路:登录页、布局页、表格页、表单页、详情页。用Element Plus组件库能大幅提速,重点把Axios封装做好,这是前后端联调最关键的环节。

Axios实例设置基础URL,并添加请求拦截器:

import axios from 'axios' import { ElMessage } from 'element-plus' import router from '../router' const request = axios.create({ baseURL: '/api', timeout: 10000 }) request.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = 'Bearer ' + token } return config }) request.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { ElMessage.error(res.msg || '请求失败') if (res.code === 401) { router.push('/login') } return Promise.reject(new Error(res.msg)) } return res.data }, error => { ElMessage.error('网络异常,请稍后重试') return Promise.reject(error) } )

这段代码是前后端联调命脉。很多同学前后端对接不上,多半是BaseURL配错、跨域没解决或者拦截器处理不正确。做开发时Vite代理配置能解决跨域:

// vite.config.js export default defineConfig({ server: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } })

这样前端请求/api开头的地址,Vite在开发服务器阶段自动转发到后端8080端口,避免浏览器跨域拦截。

接口文件推荐按模块拆分,不要把所有请求都写在一个大文件里。比如competition.js:

import request from '../utils/request' export function getCompetitionList(params) { return request({ url: '/competition/list', method: 'get', params }) } export function createCompetition(data) { return request({ url: '/competition/create', method: 'post', data }) }

4.3 表格、表单和状态流转的实现

竞赛管理页面是典型的表格+弹窗组合。用el-table展示赛事列表,列包括竞赛名称、类别、报名时间、状态、操作按钮。状态列用el-tag显示不同颜色,这样一眼就能看清是报名中还是已结束。

表单提交时注意日期格式化问题。Element Plus的el-date-picker默认返回Date对象或时间字符串,后端如果接收字符串,直接存MySQL的DATETIME即可。如果你用了Jackson,注意时区配置,否则数据库存储时间可能差了8小时。可在application.yml加:

spring: jackson: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss

前端日期格式配置也要明确:

<el-date-picker v-model="form.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" />

状态流转是业务难点。在报名管理页面,管理员或教师点击“通过”按钮,调用接口将报名记录状态从0改为1。前端操作后需要刷新列表或局部更新行数据。我的经验是,操作成功后不要直接修改当前行的status字段,而是重新调用列表接口刷新,这样后端最新状态才能同步到页面,避免因为复杂逻辑导致状态不一致。

作品上传功能建议用el-upload组件,提交前设置文件大小限制和格式校验。后端用MultipartFile接收,保存到本地磁盘或者OSS。毕设一般存本地,把文件路径存到数据库,注意处理文件名冲突,比如使用UUID重命名:

String originalFilename = file.getOriginalFilename(); String ext = originalFilename.substring(originalFilename.lastIndexOf(".")); String newName = UUID.randomUUID().toString().replace("-", "") + ext;

静态资源访问配置也要有,否则上传的文件浏览时404。SpringBoot里加:

@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceLocations("file:" + System.getProperty("user.dir") + "/upload/"); } }

这是最容易踩坑的点之一,我后面会专门列个问题清单。

5. 部署上线与常见问题排查

5.1 本地运行与打包部署

先在本地把项目跑通。MySQL要建好数据库并导入SQL文件;后端启动时检查端口占用和数据库连接配置;前端npm install耐心等完,把代理配置好。全部跑通后再考虑打包部署。

后端打包:

mvn clean package -DskipTests

生成的jar包直接运行:

java -jar target/competition-0.0.1.jar

如果想让前端也通过Nginx部署在同一个端口,先构建前端:

npm run build

构建产物在dist目录,把dist下的文件复制到Nginx的html目录,然后配置反向代理:

server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

try_files那行很重要,因为Vue路由是history模式,直接刷新某个非根路径会404,需要这里回退到index.html。如果不想搞Nginx,也可以用Vite的base配置配合SpringBoot把前端静态文件打进后端jar包,也能运行,但Nginx方案更通用,图个省事。

MySQL数据库连接配置要检查几项:useSSL是否关掉、serverTimezone是否设置。否则启动时会报时区错误或者SSL警告。我常用配置:

url: jdbc:mysql://localhost:3306/competition?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: yourpassword

5.2 常见报错和解决方案

这部分我直接整理成表格,都是实操中高频出现的问题,每个都值得提前排查。

现象原因解决方案
前端请求接口报CORS错误后端未配置跨域或前端代理未生效开发环境用Vite proxy;生产环境配Nginx反向代理
后端启动Failed to configure a DataSourceMySQL没启动、库名不对、密码错误检查application.yml和数据库状态
JWT解析报SignatureException密钥不一致,重启后每次生成新密钥固定配置密钥,不要每次new随机密钥
上传文件后访问404未配置静态资源映射WebConfig配置addResourceHandlers,访问路径和保存路径对应
查询结果中文乱码数据库字符集不是utf8mb4建库时指定utf8mb4,连接URL加characterEncoding=utf8
java.sql.SQLException: Unknown column 'xxx'实体类字段与表字段对不上检查MyBatis映射或开启驼峰自动映射
前端刷新页面404路由history模式但Nginx未配置try_filesNginx配置location /中的try_files
Whitelabel Error Page后端接口路径跟前端请求不匹配统一RestController里的基础路径与前端api封装保持一致

另外再分享一个实际问题:很多同学在IDEA里开发时,后端改了代码启动,结果前端还是旧数据。这不是Bug,多半是后端启动失败,或者端口被旧进程占用。Windows下可以用netstat -ano | findstr 8080查端口占用,然后用taskkill杀进程。Mac/Linux用lsof -i:8080。这个操作一定要熟练,否则排查能浪费一晚上。

关于MyBatis,建议在application.yml里开启驼峰映射:

mybatis: configuration: map-underscore-to-camel-case: true

这样数据库字段create_time可以自动映射到实体属性createTime,省去写一堆ResultMap。如果不开启,查询结果里createTime就全是null,很隐蔽。

使用MyBatis-Plus的话更好办,自带BaseMapper几乎所有单表CRUD都免写XML。毕设用MyBatis-Plus会省很多时间,而且答辩完全可以解释为“减少样板代码,提高开发效率”。但要注意,复杂多表关联查询还是要手写XML,不能太依赖条件构造器。

最后给出我的个人实操体会:做这种管理系统项目,开发顺序很重要。先搭建数据库和项目骨架,按模块推进,每个模块完成后立刻用Postman或Apifox测接口,别等全部写完了再一起测。前端联调时优先处理登录和用户信息接口,把Token流程跑通,再开发其他页面,因为所有业务接口都依赖登录状态。我遇到过好几个同学,页面写了一大堆,最后登录Token没通,全部请求都401,心态直接崩了。先把基础打牢,再往上面垒功能,看起来慢,实际是最快的路径。

数据还在的时候多测几个边界情况:同一用户重复报名、非评委访问评分接口、报名截止后提交作品。这类异常场景往往就是课程设计答辩时的加分点,你提前处理好了,演示起来自然流畅。如果时间充裕,还可以把Excel导出功能加上,用EasyExcel把报名列表导出来,这也是很讨喜的亮点功能。

相关新闻

串口数据截取工具实战:Modbus报文解析与调试技巧

串口数据截取工具实战:Modbus报文解析与调试技巧

1. 为什么需要一款独立的串口数据截取工具平时调Modbus设备&#xff0c;最头疼的就是数据在眼前却看不懂。串口助手只能傻傻地显示十六进制流&#xff0c;发了一堆命令&#xff0c;回了一堆报文&#xff0c;得一条一条对着手册数字节。要是遇到CRC错误、从站无应答、地址冲突&a…

2026/10/20 19:11:11 阅读更多 →
LTspice第三方模型导入全流程:从.lib文件到仿真验证

LTspice第三方模型导入全流程:从.lib文件到仿真验证

很多人在 LTspice 里画好原理图、跑自带元件仿真都挺顺手&#xff0c;可真到用第三方芯片模型的时候就开始卡壳了&#xff1a;从官网下载了一个 .lib 文件&#xff0c;照着网上说的“放进去”&#xff0c;却总是报 Unknown subckt&#xff0c;要么就是仿真波形怎么看都不对劲。…

2026/10/20 19:11:11 阅读更多 →
上下文模式深度解析:架构设计、选型逻辑与工程实践

上下文模式深度解析:架构设计、选型逻辑与工程实践

1. 从"上下文模式"说起&#xff1a;一个被低估的架构决策第一次看到"context-mode"这个词&#xff0c;很多人会下意识地把它当成某个框架里的一个配置项&#xff0c;或者某个API的一个参数。但如果你真正在系统设计里摸爬滚打过几年&#xff0c;就会意识到…

2026/10/20 19:10:10 阅读更多 →

最新新闻

FlashAttention 解析:让注意力计算快 3 倍、省 20 倍显存的核心

FlashAttention 解析:让注意力计算快 3 倍、省 20 倍显存的核心

一、标准注意力&#xff0c;GPU 的"显存黑洞" 先抛一个问题。你用 PyTorch 写一个标准的多头注意力&#xff0c;序列长度 N8192&#xff0c;单头维度 d128。算注意力时中间那张分数矩阵 S 的尺寸是 NN 81928192&#xff0c;每个元素是 float16&#xff08;2 字节&a…

2026/10/20 19:58:57 阅读更多 →
上下文模式实战:从if-else到可配置调度系统的工程实践

上下文模式实战:从if-else到可配置调度系统的工程实践

1. 从“上下文模式”说起&#xff1a;一个被低估的工程概念第一次看到“context-mode”这个词&#xff0c;很多人会下意识觉得它是个抽象到没法落地的概念。但如果你写过稍微复杂一点的系统&#xff0c;或者维护过一个跑了半年以上的项目&#xff0c;就会明白&#xff1a;上下文…

2026/10/20 19:58:57 阅读更多 →
面试官:Spring Boot 是怎么启动起来的?答完这十八步直接封神【附启动事件时序与排查清单】

面试官:Spring Boot 是怎么启动起来的?答完这十八步直接封神【附启动事件时序与排查清单】

/* 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 19:58:57 阅读更多 →
【大数据毕设项目】基于Spark的电商购物趋势数据可视化大屏\基于Hadoop的电商购物趋势数据可视化大屏

【大数据毕设项目】基于Spark的电商购物趋势数据可视化大屏\基于Hadoop的电商购物趋势数据可视化大屏

文章目录 一、项目开发背景意义 二、项目开发技术 三、项目开发内容 四、项目展示 五、项目相关代码 六、最后 一、项目开发背景意义 基于大数据的购物趋势数据可视化分析系统开发背景&#xff1a;随着电子商务的迅猛发展&#xff0c;平台积累了海量的用户行为与交易数据…

2026/10/20 19:58:57 阅读更多 →
从流式消息到多会话:TinyRobot Kit 如何组织 AI 对话数据层?

从流式消息到多会话:TinyRobot Kit 如何组织 AI 对话数据层?

其实实现一个基础的 AI 对话页面&#xff0c;通常会从维护消息数组、调用模型接口和渲染结果开始。 但真正进入产品开发后&#xff0c;复杂度很快会从“调一次接口”扩散到整个页面&#xff1a;流式内容需要持续合并&#xff0c;请求需要能够停止&#xff0c;多轮上下文要正确…

2026/10/20 19:58:57 阅读更多 →
批量修改文件名 shell脚本

批量修改文件名 shell脚本

1. 批量加前缀bash#!/bin/bash # add_prefix.sh - 给目录下所有文件加前缀DIR"/data/photos" PREFIX"img_"cd "$DIR" || exit 1 for f in *; do[ -f "$f" ] || continuemv "$f" "${PREFIX}${f}" done echo "…

2026/10/20 19:57:55 阅读更多 →

日新闻

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 阅读更多 →