news 2026/11/6 11:15:45

SpringBoot+Vue课程教学平台实战:PDF预览与一体化部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot+Vue课程教学平台实战:PDF预览与一体化部署

简介:这是一套面向计算机专业本科生及毕业设计指导教师的课程教学平台完整源码,基于SpringBoot+Vue实现前后端分离架构,解决高校在线教学管理中课程发布、作业布置、成绩查询与师生互动等核心需求。资源共719个文件,包含163个Java后端业务逻辑文件、123个Vue组件页面、159个SVG图标资源、86张JPG教学素材图及63个JS交互脚本,辅以SQL建表语句、YML配置、BAT部署脚本和详尽的源码说明文档,压缩包大小21.38MB。已有45人学习下载,适合开展毕业设计、课程实训或二次开发实践。读者可直接获取模块化清晰的工程结构(用户/课程/作业三大子系统)、MySQL数据库设计蓝图、Spring Security权限控制实现、Vue单页应用路由与API调用范式,以及含install.bat、run.bat在内的开箱即用部署方案。

1. 为什么用 SpringBoot + Vue 做课程教学平台,不是“堆技术”,而是解决真问题

你可能已经见过太多“SpringBoot + Vue 毕设项目”——名字雷同、功能相似、部署即崩。但真正跑起来的课程教学平台,核心痛点从来不是“能不能写出来”,而是:教师上传 PPT 后学生打不开、课件 PDF 在线预览白屏、作业提交后时间戳错乱、多班级排课冲突校验失效、Vue 路由嵌套三层后导航守卫失灵、SpringBoot 接口返回中文字段在前端被转义成乱码……这些不是玄学,是真实课堂场景下每天发生的“教学流中断”。本项目(基于SpringBoot和vue的课程教学平台的设计与实现_f2840y9o_245-QQ.zip)之所以能落地,关键在于它把 SpringBoot 的事务控制、文件流处理、定时任务能力,和 Vue 的动态路由、组件懒加载、PDF 预览封装、表单校验链路,做了教学业务语义级对齐:比如“发布课程公告”操作,后端不是简单存一条 record,而是自动触发邮件通知 + 学生端未读红点 + 教师端已读统计;前端不是渲染一个 div,而是绑定v-model.lazy防抖 +@keydown.enter.prevent防误提交 +el-upload自定义 request 适配 SpringBoot 的MultipartFile接收逻辑。它适合两类人:一是需要交付可演示、可答辩、可扩展的毕设/实训项目的同学(尤其关注vue打包放进springboot中的实际路径);二是想快速验证教学类 SaaS 核心模块(课程管理、作业批改、在线测验)是否能闭环的一线开发——不讲架构图,只讲哪一行代码改了能让 PDF 在 Chrome 和 Edge 都正常显示。


2. 从零搭建:SpringBoot 后端服务与 Vue 前端工程的最小可行联调方案

2.1 初始化 SpringBoot 项目:选型依据与关键依赖锁定

本项目采用 SpringBoot 2.7.18(非最新版),原因很实在:SpringBoot 3.x 默认要求 JDK 17+,而高校机房、学生笔记本普遍仍是 JDK 8 或 11;且 2.7.x 对 MyBatis-Plus 3.5.x、Shiro 1.10.x 兼容性更稳,避免springboot版本太高导致的Failed to load tsconfig类编译错误传导到后端。使用 Spring Initializr 创建基础工程时,必须勾选以下依赖(其他如 Lombok、DevTools 可选):

<!-- pom.xml 关键依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>

提示:spring-boot-starter-thymeleaf不是为了做模板渲染,而是为后续vue打包放进springboot中提供静态资源托管能力——Thymeleaf 的templates/目录可被 SpringBoot 自动识别为视图根路径,而static/目录则用于存放 Vue 打包后的index.html及js/css文件。这是实现前后端同源部署的底层支撑,比 Nginx 反向代理更轻量、更适合毕设演示。

2.2 Vue CLI 工程初始化与教学场景定制化配置

使用 Vue CLI 4.5.19(非 Vite)创建项目,原因明确:Vite 在vue播放m3u8免安装场景下需额外配置@videojs-player/vue插件,而 Vue CLI 4.x 对vue-router动态路由、vuex状态持久化、axios请求拦截器的集成更成熟,且与 SpringBoot 的@CrossOrigin注解配合更少踩坑。执行命令:

vue create course-platform-frontend # 选择 Manually select features → Router (History mode), Vuex, CSS Pre-processors (Sass), Linter / Formatter

初始化后,立即修改vue.config.js,关键配置如下:

// vue.config.js const path = require('path') module.exports = { // 1. 输出路径必须与 SpringBoot static 目录对齐 outputDir: path.resolve(__dirname, '../backend/src/main/resources/static'), // 2. 开发服务器代理,解决跨域(仅开发用) devServer: { port: 8080, proxy: { '/api': { target: 'http://localhost:8081', // SpringBoot 默认端口 changeOrigin: true, pathRewrite: { '^/api': '' } } } }, // 3. 关闭 eslint 强校验(避免 `vue安装依赖` 后大量报错干扰开发) lintOnSave: false, // 4. 配置 public 目录资源拷贝(如 favicon.ico、pdf.worker.min.js) configureWebpack: { resolve: { alias: { '@': path.resolve(__dirname, 'src') } } } }

参数说明:outputDir指向 SpringBoot 项目的static目录,是vue打包放进springboot中的物理落点;devServer.proxy是开发阶段的救命配置,让http://localhost:8080/api/course/list实际请求http://localhost:8081/course/list,避免浏览器 CORS 报错;lintOnSave: false是血泪经验——毕设阶段优先保证功能跑通,ESLint 规则可在答辩前统一修复。

2.3 前后端联调第一步:打通登录接口并验证跨域与会话

SpringBoot 后端编写/api/auth/login接口(使用@RestController):

// LoginController.java @PostMapping("/api/auth/login") public ResultVO login(@RequestBody LoginDTO dto, HttpServletRequest request) { // 1. 查询用户(此处省略密码校验逻辑) User user = userService.getByUsername(dto.getUsername()); if (user == null || !passwordEncoder.matches(dto.getPassword(), user.getPassword())) { return ResultVO.fail("用户名或密码错误"); } // 2. 生成 token(使用 JWT,非 Session) String token = jwtUtil.generateToken(user); // 3. 设置响应头(关键!Vue axios 需要手动携带) response.setHeader("Authorization", "Bearer " + token); return ResultVO.success("登录成功", user); }

Vue 前端调用该接口(src/api/auth.js):

// api/auth.js import request from '@/utils/request' export function login(data) { return request({ url: '/api/auth/login', method: 'post', data }) }

其中request封装(src/utils/request.js)必须启用withCredentials:

// utils/request.js import axios from 'axios' const service = axios.create({ baseURL: process.env.NODE_ENV === 'production' ? '/' : '/', // 生产环境走相对路径 timeout: 10000, withCredentials: true // ✅ 关键!允许携带 cookie(若用 Session)或 Authorization 头(若用 JWT) }) service.interceptors.response.use( response => { // 从响应头读取 token(JWT 场景) const token = response.headers.authorization if (token && token.startsWith('Bearer ')) { localStorage.setItem('token', token.substring(7)) } return response.data } )

逻辑说明:withCredentials: true是跨域请求携带认证信息的开关,没有它,SpringBoot 的@CrossOrigin(origins = "*", allowCredentials = true)注解无效;baseURL: '/'确保生产环境下所有请求路径相对于根目录,与 SpringBoot 的static/静态资源托管路径一致;response.headers.authorization提取 JWT token 并存入localStorage,为后续所有请求提供Authorization头。


3. 教学核心功能落地:课程管理、课件上传与 PDF 在线预览的完整链路

3.1 课程 CRUD 与多角色权限隔离(教师/学生/管理员)

后端使用 MyBatis-Plus 的QueryWrapper构建动态查询条件,区分角色数据权限:

// CourseController.java @GetMapping("/api/course/list") public ResultVO list(@RequestParam(required = false) String keyword, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size, HttpServletRequest request) { // 1. 从 JWT 解析当前用户(工具类封装) User currentUser = jwtUtil.getCurrentUser(request); // 2. 教师只能查自己开的课,学生查已选课,管理员查全部 QueryWrapper<Course> wrapper = new QueryWrapper<>(); if ("TEACHER".equals(currentUser.getRole())) { wrapper.eq("teacher_id", currentUser.getId()); } else if ("STUDENT".equals(currentUser.getRole())) { // 关联 student_course 表查已选课程 wrapper.inSql("id", "SELECT course_id FROM student_course WHERE student_id = " + currentUser.getId()); } if (StringUtils.isNotBlank(keyword)) { wrapper.like("name", keyword).or().like("description", keyword); } Page<Course> pageObj = new Page<>(page, size); IPage<Course> result = courseService.page(pageObj, wrapper); return ResultVO.success(result); }

Vue 前端使用vue动态路由实现菜单权限控制:

// router/index.js const routes = [ { path: '/course', component: () => import('@/views/layout/Layout.vue'), children: [ { path: 'list', name: 'CourseList', component: () => import('@/views/course/List.vue'), meta: { roles: ['ADMIN', 'TEACHER', 'STUDENT'] } // ✅ 角色白名单 }, { path: 'create', name: 'CourseCreate', component: () => import('@/views/course/Create.vue'), meta: { roles: ['TEACHER'] } // 仅教师可创建 } ] } ] router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (!token) return next('/login') const user = JSON.parse(localStorage.getItem('user') || '{}') const hasRole = to.meta.roles?.includes(user.role) if (!hasRole) { next('/403') // 无权限跳转 } else { next() } })

参数说明:meta.roles是路由元信息,存储角色数组;router.beforeEach全局守卫在每次跳转前校验当前用户角色是否匹配目标路由所需角色;inSql是 MyBatis-Plus 提供的原生 SQL 片段插入方式,用于复杂关联查询,比@Select注解更易维护。

3.2 课件上传与存储:解决vue image能显示pdf吗的本质问题

课件上传分两步:前端文件选择 + 后端接收存储。关键在于PDF 不是图片,不能直接<img src="xxx.pdf">显示,必须通过 PDF.js 渲染。

Vue 前端使用el-upload组件(Element UI):

<!-- views/course/Upload.vue --> <template> <el-upload class="upload-demo" action="/api/file/upload" :http-request="customUpload" :on-success="handleSuccess" :on-error="handleError" :limit="1" :auto-upload="false" > <el-button slot="trigger" size="small" type="primary">选取文件</el-button> </el-upload> </template> <script> export default { methods: { customUpload({ file, onSuccess, onError }) { const formData = new FormData() formData.append('file', file) this.$axios.post('/api/file/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then(res => { onSuccess(res.data) }).catch(err => { onError(err) }) }, handleSuccess(response) { this.$message.success('上传成功') this.fileUrl = response.data.url // 后端返回的访问路径 this.previewPdf() // 触发 PDF 预览 } } } </script>

SpringBoot 后端接收并保存文件(FileController.java):

@PostMapping("/api/file/upload") public ResultVO upload(@RequestParam("file") MultipartFile file) throws IOException { if (file.isEmpty()) { return ResultVO.fail("文件不能为空"); } // 1. 生成唯一文件名(防重名) String originalFilename = file.getOriginalFilename(); String extension = FilenameUtils.getExtension(originalFilename); String newFilename = UUID.randomUUID().toString() + "." + extension; // 2. 保存到服务器指定目录(非 static,避免被直接访问) String uploadPath = "D:/course-files/"; // 生产环境建议用 NAS 或 MinIO File uploadDir = new File(uploadPath); if (!uploadDir.exists()) uploadDir.mkdirs(); file.transferTo(new File(uploadPath + newFilename)); // 3. 返回可访问 URL(SpringBoot 静态资源映射) String url = "/files/" + newFilename; // 通过 WebMvcConfigurer 添加 /files/** 映射到 uploadPath return ResultVO.success("上传成功", url); }

逻辑说明:MultipartFile是 SpringBoot 对文件上传的标准抽象,transferTo()安全写入磁盘;/files/**映射需在WebMvcConfigurer中配置,确保http://localhost:8081/files/xxx.pdf可直接访问;前端拿到url后,不直接<iframe src="xxx.pdf">(Chrome 会下载),而是用 PDF.js 渲染:

<!-- PDF 预览组件 --> <template> <div id="pdf-container" style="width:100%;height:600px;"></div> </template> <script> import * as pdfjsLib from 'pdfjs-dist/build/pdf' export default { mounted() { this.renderPdf() }, methods: { renderPdf() { const loadingTask = pdfjsLib.getDocument(this.fileUrl) loadingTask.promise.then(pdf => { pdf.getPage(1).then(page => { const viewport = page.getViewport({ scale: 1.5 }) const canvas = document.getElementById('pdf-container').appendChild(document.createElement('canvas')) const context = canvas.getContext('2d') canvas.height = viewport.height canvas.width = viewport.width const renderContext = { canvasContext: context, viewport: viewport } page.render(renderContext) }) }) } } } </script>

3.3 在线测验模块:Vue 表单校验与 SpringBoot 事务一致性保障

测验提交需满足:单选题必答、时间截止自动交卷、答案提交后不可修改、分数实时计算。后端使用@Transactional保证原子性:

// ExamController.java @PostMapping("/api/exam/submit") @Transactional(rollbackFor = Exception.class) public ResultVO submit(@RequestBody ExamSubmitDTO dto, HttpServletRequest request) { User user = jwtUtil.getCurrentUser(request); // 1. 校验考试是否在有效期内 Exam exam = examService.getById(dto.getExamId()); if (exam.getEndTime().before(new Date())) { return ResultVO.fail("考试已结束"); } // 2. 保存考生答案(student_answer 表) List<StudentAnswer> answers = dto.getAnswers().stream() .map(a -> new StudentAnswer().setStudentId(user.getId()) .setExamId(dto.getExamId()) .setQuestionId(a.getQuestionId()) .setAnswer(a.getAnswer())) .collect(Collectors.toList()); studentAnswerService.saveBatch(answers); // 3. 计算分数并更新考试记录 int score = calculateScore(dto.getExamId(), user.getId()); examResultService.update(new UpdateWrapper<ExamResult>() .eq("exam_id", dto.getExamId()) .eq("student_id", user.getId()) .set("score", score) .set("submit_time", new Date())); return ResultVO.success("提交成功", score); }

Vue 前端使用el-form+rules实现前端校验:

<el-form :model="form" :rules="rules" ref="formRef"> <el-form-item v-for="(q, index) in questions" :key="q.id" :label="'第' + (index+1) + '题:' + q.content" prop="answer"> <el-radio-group v-model="form.answers[index].answer"> <el-radio v-for="opt in q.options" :key="opt.id" :label="opt.content">{{ opt.content }}</el-radio> </el-radio-group> </el-form-item> </el-form> <script> export default { data() { return { rules: { answer: [ { required: true, message: '请选择答案', trigger: 'change' } ] } } } } </script>

参数说明:@Transactional(rollbackFor = Exception.class)确保答案保存失败时,分数更新也回滚;el-form的prop必须与v-model数据路径一致(如answers.0.answer),否则校验不生效;trigger: 'change'表示选项变更时触发校验,比blur更及时。


4. 避坑指南:SpringBoot + Vue 联调中最常翻车的 5 个硬核问题

4.1 现象:Vue 打包后index.html能打开,但所有 API 请求 404

原因:Vue 路由使用history模式,生产环境部署在 SpringBoot 的static/目录下,但 SpringBoot 默认不处理/*路径的 HTML 回退,导致刷新子页面(如/course/list)时 SpringBoot 返回 404。
解决:在 SpringBoot 中添加WebMvcConfigurer,将所有非 API 请求重定向到index.html:

@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("forward:/index.html"); registry.addViewController("/course/**").setViewName("forward:/index.html"); registry.addViewController("/exam/**").setViewName("forward:/index.html"); // 其他前端路由路径... } }

4.2 现象:PDF 在 Chrome 正常显示,Edge 白屏或报PDF.js worker not found

原因:PDF.js 依赖pdf.worker.min.js,Vue CLI 4.x 默认不将其复制到public/目录,且node_modules/pdfjs-dist/build/pdf.worker.min.js路径在打包后失效。
解决:

  1. 将node_modules/pdfjs-dist/build/pdf.worker.min.js复制到public/js/目录;
  2. 在 PDF 渲染前设置 worker 路径:
import * as pdfjsLib from 'pdfjs-dist/build/pdf' pdfjsLib.GlobalWorkerOptions.workerSrc = '/js/pdf.worker.min.js' // ✅ 指向 public 下的文件

4.3 现象:vue路由参数传递中文时,后端接收到乱码(如?name=数学变成?name=%E6%95%B0%E5%AD%A6)

原因:Vue Router 的params默认使用encodeURI编码,SpringBoot 的@RequestParam默认用 ISO-8859-1 解码。
解决:

  • 方案一(推荐):前端用encodeURIComponent()显式编码,后端用URLDecoder.decode()解码:
// Vue 跳转 this.$router.push(`/course/detail?name=${encodeURIComponent(this.course.name)}`)
// SpringBoot Controller @GetMapping("/api/course/detail") public ResultVO detail(@RequestParam String name) throws UnsupportedEncodingException { String decodedName = URLDecoder.decode(name, "UTF-8"); // ✅ 主动解码 // ... }
  • 方案二:在application.yml中全局配置 URI 编码:
server: tomcat: uri-encoding: UTF-8

4.4 现象:springboot配置中spring.servlet.context-path=/edu,Vue 打包后 API 请求路径错乱

原因:Vue 的axios基础 URL 写死为/api,未考虑上下文路径,导致请求发送到http://localhost:8081/api/xxx而非http://localhost:8081/edu/api/xxx。
解决:

  1. SpringBoot 配置server.servlet.context-path=/edu;
  2. Vue 中vue.config.js添加publicPath:
// vue.config.js module.exports = { publicPath: process.env.NODE_ENV === 'production' ? '/edu/' : '/', // ... }
  1. axios实例的baseURL改为相对路径:
// utils/request.js const service = axios.create({ baseURL: '/edu/api/', // ✅ 匹配 context-path // ... })

4.5 现象:vue打包放进springboot中后,CSS 样式丢失或 JS 报Cannot find module 'vue'

原因:Vue CLI 打包时,outputDir指向static/,但static/目录下已有index.html,而js/css文件被覆盖或路径错乱;或package.json中dependencies与devDependencies混淆,导致生产环境缺失vue。
解决:

  • 确保vue.config.js中outputDir指向绝对路径,且static/目录为空或已备份;
  • 运行npm run build前,检查package.json:
"dependencies": { "vue": "^2.6.14", "vue-router": "^3.5.3", "axios": "^0.21.4" }, "devDependencies": { "@vue/cli-service": "^4.5.19", "vue-template-compiler": "^2.6.14" }

注意:vue-template-compiler必须与vue版本严格一致,否则npm run build会报错。


5. 进阶技巧:把 Vue 打包产物无缝注入 SpringBoot,实现真正的“一体化部署”

5.1 不用mvn clean package,改用maven-resources-plugin自动同步前端资源

很多教程教你在backend/src/main/resources/static手动粘贴dist/文件,这在 CI/CD 中不可靠。正确做法是:让 Maven 在package阶段自动将 Vue 打包产物复制到 SpringBoot 的static目录。在backend/pom.xml中添加插件:

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <id>copy-frontend-resources</id> <phase>process-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.outputDirectory}/static</outputDirectory> <resources> <resource> <directory>../frontend/dist</directory> <!-- Vue 项目 dist 目录 --> <filtering>false</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin>

逻辑说明:maven-resources-plugin在process-resources阶段执行,早于compile,确保static/目录在打包前已就绪;<directory>../frontend/dist</directory>是 Vue 项目dist目录的相对路径,需根据你的实际目录结构调整(如../../course-frontend/dist);filtering=false避免 Maven 对 HTML/CSS 文件做属性替换。

5.2 SpringBoot 启动时自动检查前端资源完整性,失败则拒绝启动

光复制不够,还要验证index.html是否存在、js/app.js是否可读。在ApplicationRunner中添加校验:

@Component public class FrontendResourceChecker implements ApplicationRunner { @Value("classpath:static/index.html") private Resource indexHtml; @Value("classpath:static/js/app.js") private Resource appJs; @Override public void run(ApplicationArguments args) throws Exception { if (!indexHtml.exists() || !appJs.exists()) { throw new RuntimeException("前端资源缺失:请先运行 npm run build"); } // 可选:校验文件大小(防空文件) if (indexHtml.contentLength() < 1000 || appJs.contentLength() < 1000) { throw new RuntimeException("前端资源损坏:index.html 或 app.js 为空"); } System.out.println("✅ 前端资源校验通过,服务启动中..."); } }

参数说明:@Value("classpath:static/index.html")利用 Spring 的Resource抽象,直接定位static/下的文件;contentLength()获取字节数,1000 字节是index.html的合理下限(含基本 HTML 结构);抛出RuntimeException会让 SpringBoot 启动失败,强制开发者先构建前端。

5.3 使用spring-boot-maven-plugin打包成可执行 JAR,并验证部署效果

最终打包命令只需一步:

# 在 backend 目录下执行 mvn clean package -DskipTests

生成的target/course-platform-backend-1.0.0.jar即为完整应用(含前端静态资源)。验证方式:

java -jar target/course-platform-backend-1.0.0.jar # 访问 http://localhost:8081 —— 应直接显示 Vue 的首页 # 查看 network tab,所有 js/css 请求状态码为 200,且路径为 /js/app.xxx.js # 调用 /api/course/list,返回 JSON 数据

关键验证点:

  • http://localhost:8081/js/app.xxx.js能直接下载,证明静态资源映射成功;
  • http://localhost:8081/api/course/list返回数据,证明后端接口可用;
  • 刷新任意 Vue 子页面(如/course/list)不报 404,证明WebMvcConfigurer重定向生效;
  • 上传 PDF 后,http://localhost:8081/files/xxx.pdf可访问,且 PDF.js 渲染正常。

我带过三届毕设,最常看到的翻车不是代码写错,而是把 Vue 当成独立 SPA 部署,结果答辩现场连不上后端;或者盲目升级 SpringBoot 版本,导致 Shiro 权限注解失效,最后三天重写鉴权逻辑。所以我的习惯是:第一周只做登录 + 课程列表,跑通axios请求、JWT 解析、角色路由;第二周加课件上传和 PDF 预览,重点调通MultipartFile和pdf.worker.min.js路径;第三周补测验和作业模块,用@Transactional锁住分数一致性。剩下的时间,全花在application.yml的logging.level.com.xxx=debug上——看清楚每一行 SQL 和每个请求头,比背一百道springboot面试题都管用。希望帮到你。

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

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

基于Django与Vue的考研信息共享平台开发实战

1. 项目概述与整体设计思路 1.1 这个项目到底解决什么问题 考研这件事,信息差比想象中严重得多。每年三四月份,各大院校的招生简章、专业目录、报录比、复试线陆续公布,考生要挨个学校官网去翻,翻完研招网翻学院网站,翻完学院网站再去考研论坛找经验帖,信息散落得到处都是。 …

作者头像 李华
网站建设 2026/11/5 18:14:22

Codex Token 省流实战:从上下文工程到 Prompt 约束降低 80% 消耗

1. 这篇文章真正要解决的问题 最近 Codex 在开发者圈子里热度越来越高&#xff0c;很多人已经不只是把它当成一个“能写代码的聊天助手”&#xff0c;而是真正接入了日常开发流程&#xff1a;让它修 bug、写测试、做代码审查、自动补全工程脚手架。但很快大家就发现了同一个痛点…

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

基于开源模型的本地AI新闻聚合与摘要管道构建实践

该主题涉及选举政治、国际冲突、涉事人物与案件调查等敏感新闻内容&#xff0c;不在技术内容撰写范围内。按内容安全要求&#xff0c;我不能生成此类文章。 如果您的目标是写一篇 CSDN 技术博客&#xff0c;可以把方向调整到以下任一主题&#xff0c;我可以立刻按规范输出 500…

作者头像 李华
网站建设 2026/10/25 8:49:51

免公众号交友恋爱盲盒源码:部署、参数与微信生态避坑指南

简介&#xff1a;这套新版免公众号交友恋爱盲盒源码采用PHP开发&#xff0c;专门解决传统盲盒交友系统必须认证服务号、需商户号才能收款的问题。站点无须微信公众号即可运营&#xff0c;并已对接易支付&#xff0c;省去300元服务号认证成本与商户封禁风险&#xff0c;适合个人…

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

日语到中文翻译实战:Transformer模型从数据清洗到部署全流程

简介&#xff1a;这份资源是基于Transformer的日语到中文神经机器翻译系统完整项目包&#xff0c;面向计算机、人工智能相关专业的学生与自学者&#xff0c;适用于毕业设计、课程设计及期末大作业等场景&#xff0c;帮助读者理解并复现NMT从数据预处理到模型训练的完整流程。压…

作者头像 李华
网站建设 2026/10/24 23:00:51

Android Studio Profiler各版本内存泄漏排查:从Heap Dump到引用链

用 Android Studio 的 Profiler 工具抓内存泄漏&#xff0c;是我这几年排查性能问题做得最多的一件事。每次帮人定位“App 越用越卡、一开页面就 OOM”&#xff0c;我基本都是先打开 Profiler 看内存曲线&#xff0c;再抓一次 Heap Dump。但 Android Studio 不是静态工具&#…

作者头像 李华