news 2026/10/3 7:14:04

微信小程序+SSM驾考系统开发全攻略:从毕设开题到答辩排坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信小程序+SSM驾考系统开发全攻略:从毕设开题到答辩排坑

最近被问得最多的一个毕设题目,就是“基于微信小程序的优选驾考+SSM”。微信小程序做前端,SSM(Spring + SpringMVC + MyBatis)做后端,搭一套驾考学习、刷题、预约考试的系统。这个组合在近几年的毕业设计里出现频率非常高,看起来常规,但真正从开题到答辩全程走完,还是有不少坑。这篇文我按自己做过和指导过的实际经验,把需求拆解、系统架构、核心功能实现、论文写作、排坑实录完整过一遍,给正在准备这个题目的同学一条能直接走通的路线,也适合想快速上手小程序加SSM开发的读者参考。

1. 项目拆解:优选驾考系统到底要做什么

1.1 从题目反推功能边界

拿到题目第一件事不是写代码,而是把“优选驾考”这四个字拆开。“优选”不是只放一堆题,而是强调精选内容:科目一和科目四的精选真题、按错误率收敛的智能推荐、考试预约流程优化。驾考业务拆成用户端和管理端,功能边界大概是这样:

端侧功能模块说明
用户端(小程序)微信登录注册通过 wx.login 获取 openid,免输入账号密码
用户端科目一/科目四刷题按顺序练习、随机练习、专项练习
用户端模拟考试随机组卷、倒计时、自动评分、结果解析
用户端错题本自动收录错题、支持重复练习和移除
用户端考试预约选择场地/时间段,提交预约,查看审核结果
用户端个人中心头像昵称、学习统计、成绩记录
管理端(Web或后台接口)题库管理题目增删改查、导入导出
管理端预约审核管理员审核用户预约,状态流转
管理端用户管理查看用户列表、禁用异常账号
管理端公告发布推送考试通知、政策变更

这个边界你先写在文档里,后面所有表结构、接口、论文章节都对照它来。很多同学后面越做越乱,就是一开始没把功能边界画清楚,写着写着什么功能都想加,最后系统臃肿、论文也没法圆回来。

1.2 为什么选微信小程序 + SSM 这个组合

微信小程序适合驾考场景的核心原因是“用完即走”。用户考试前刷二十分钟题、查一下预约状态,不需要下载安装 App,扫码就能用。这个特性在论文的“研究意义”部分很好写:低使用门槛、触达成本低、覆盖中老年用户群体。

SSM 虽然相比 Spring Boot 显得老,但作为毕设它反而有优势。Spring 管对象、SpringMVC 接请求、MyBatis 负责持久层,三层结构清清楚楚,答辩时老师问你“请求怎么走的”,你可以从 Controller 一路讲到 Mapper,每一层都有话说。如果用了 Spring Boot 加 Vue 那种搭法,很多东西自动配置掉了,反而说不清楚底层机制。

另外,SSM 相关资料极多,遇到问题一搜就有答案,对没有实战经验的学生非常友好。这个组合还有一个隐藏好处:页面逻辑在小程序端,业务逻辑在后端,天然就是前后端分离的形态,论文里能画出清晰的结构图。

2. 系统架构与环境准备:先搭好地基

2.1 一条完整请求是怎么跑的

很多同学对“SSM后台”和“小程序前端”之间的关系是模糊的。我习惯用一个打车场景解释:小程序是乘客,后端接口是出租车司机,MySQL 是目的地的地图。乘客要数据,先叫车(wx.request 发出请求),司机接到订单(Controller 接收请求),规划路线(Service 处理业务逻辑),最终到达地图点去取货(MyBatis 操作数据库),再把货带回来(返回 JSON)。

具体到一次刷题请求,链路是这样的:

小程序页面 -> wx.request(url) -> HTTP请求 -> Tomcat -> SpringMVC前端控制器 -> QuestionController -> QuestionService -> QuestionMapper -> MySQL -> 数据逐层返回 -> 封装成JSON -> 小程序 setData 渲染页面

你把这条链路画在论文里,基本就是“系统总体架构”那一节的核心图。我建议学生在开题阶段就把这张图手绘一遍,后面所有模块都是往里填内容。

2.2 开发环境清单

环境搭错是常见的起步翻车点。我列一份亲测稳定的版本组合:

工具版本用途
JDK1.8SSM项目运行基础,毕设足够
Maven3.6.3依赖管理和打包
Tomcat8.5.x后端运行容器
MySQL5.7数据库
IDEA2019及以上后端开发
微信开发者工具稳定版小程序开发与调试
Navicat任意版本数据库可视化操作
Postman任意版本后端接口测试

版本不用最新,稳定最好。比如 JDK 21 虽然新,但可能和旧版 SSM 的某些 jar 包冲突,没有必要去踩。Tomcat 也建议 8.5 而不是 10,因为 10 之后 Jakarta 命名空间变了,老项目跑起来容易报 ClassNotFoundException。

2.3 数据库表设计:五张核心表够撑起论文

数据库设计是论文里“重头戏”,也是答辩时老师喜欢深挖的地方。设计核心表时,每个字段都要能解释“为什么存在”。下面这五张表基本覆盖全部业务:

用户表 t_user

字段类型说明
idint主键自增
openidvarchar(64)微信唯一标识,建索引
nicknamevarchar(50)用户昵称
avatarvarchar(255)头像URL
phonevarchar(20)手机号,预约时用
roletinyint0普通用户 1管理员
create_timedatetime注册时间

openid 要加唯一索引。同一个用户每次 wx.login 返回的 code 不同,但后端换取的 openid 是固定的,这是冷启动时最容易踩的坑。

题库表 t_question

字段类型说明
idint主键
subjectint科目:1科目一 3科目四
typeint0单选 1判断
questionvarchar(500)题干内容
option_a / option_b / option_c / option_dvarchar(255)选项
answervarchar(5)正确答案
analysisvarchar(500)答案解析
tagsvarchar(100)标签,如扣分、标志

科目四和科目一的题型混在一个表里,用 subject 区分即可。注意科目四很多选择题是“多选”,如果你只想做单选和判断,在题目要求里必须写清楚,不然表结构和前端都要改。

错题表 t_wrong_question

字段类型说明
idint主键
user_idint用户ID
question_idint题目ID
wrong_countint累计错误次数
last_wrong_timedatetime最近一次错题时间

错题表是“优选”功能的核心支撑。累计错误次数做降序排列,就能生成“你最薄弱的十道题”,这是论文里非常有亮点的数据推荐逻辑。

考试记录表 t_exam_record

字段类型说明
idint主键
user_idint用户ID
scoreint考试成绩
total_questionint题目总数
wrong_countint错题数
use_timeint用时秒数
create_timedatetime交卷时间

预约表 t_appointment

字段类型说明
idint主键
user_idint用户ID
subjectint考试科目
exam_datedate预约日期
time_slotvarchar(20)时间段
statustinyint0待审核 1通过 2拒绝
remarkvarchar(255)管理员备注

预约表的状态流转(待审核 -> 通过/拒绝)是论文“业务流程设计”章节里好写的内容,记得画一张状态图。

3. 核心功能实现:从0到1能直接落地的方案

3.1 小程序页面架构与顶部导航适配

小程序端我建议用 tabBar 三页结构:首页、题库、我的。首页放公告轮播、考试预约入口、学习统计;题库页放科目切换和题目列表;个人中心放登录信息、错题本、成绩记录。

初始代码结构:

{ "pages": [ "pages/index/index", "pages/question/question", "pages/exam/exam", "pages/mine/mine", "pages/wrong/wrong" ], "tabBar": { "list": [ { "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/question/question", "text": "题库" }, { "pagePath": "pages/mine/mine", "text": "我的" } ] }, "window": { "navigationStyle": "custom" } }

这里有个隐藏问题:如果启用自定义导航栏(navigationStyle 设置为 custom),你就需要自己适配顶部状态栏和胶囊按钮的高度,否则页面内容会被微信的胶囊按钮挡住。适配代码我一般写在 page 的 onLoad 里:

const { statusBarHeight, screenWidth } = wx.getWindowInfo(); const menuRect = wx.getMenuButtonBoundingClientRect(); this.setData({ statusBarHeight: statusBarHeight, navBarHeight: menuRect.height + (menuRect.top - statusBarHeight) * 2 + statusBarHeight });

原理就是:胶囊按钮顶部到状态栏底部有一段间距,底部也有对称间距,导航栏总高度 = 状态栏高度 + 胶囊按钮高度 + 上下间距之和。如果你不用自定义导航,直接保留默认导航栏,这段代码可以跳过。但很多同学为了界面美观会自定义,这块就成了第一个卡点。

3.2 题库列表与“加载更多”的实现

题库数据量大,一次全加载会让页面卡死,必须做分页。小程序里最自然的做法是触底加载更多,也就是 onReachBottom 触发了,再请求下一页。

Page({ data: { questionList: [], pageNum: 1, pageSize: 10, total: 0, loading: false }, onReachBottom() { if (this.data.questionList.length >= this.data.total || this.data.loading) { return; } this.loadQuestions(); }, loadQuestions() { this.setData({ loading: true }); wx.request({ url: 'http://192.168.1.100:8080/api/question/list', data: { pageNum: this.data.pageNum, pageSize: this.data.pageSize, subject: this.data.currentSubject }, success: (res) => { const data = res.data.data; this.setData({ questionList: this.data.questionList.concat(data.list), pageNum: this.data.pageNum + 1, total: data.total }); }, complete: () => { this.setData({ loading: false }); } }); } });

防止重复请求的关键是 loading 标记。很多同学触底加载会出现列表闪烁、重复数据,就是没有用 loading 把关。另外,后端分页要返回 total 和 pages 字段,前端才知道“是否还有下一页”。

3.3 刷题与提交答案:自动判题和错题记录

刷题页设计成“一题一页”:题干、选项、提交按钮。用户选择选项后,先本地判断对错:

checkAnswer(e) { const selected = e.currentTarget.dataset.value; const question = this.data.currentQuestion; if (selected === question.answer) { this.setData({ answered: true, correct: true }); } else { this.setData({ answered: true, correct: false }); this.addWrongQuestion(question.id); } }

addWrongQuestion 请求后端接口把错题写入数据库。这里要注意:不是每次答错都重复新增记录,而是如果这条错题已经存在,就让 wrong_count 加一。用一条 INSERT ... ON DUPLICATE KEY UPDATE 就能搞定,不过需要给 user_id 和 question_id 建联合唯一索引。

判断题的选项 A 对应“正确”、B 对应“错误”,后端存储答案字段可以直接存 “A” 或 “B”,前端不用特意转成布尔值,保持统一反而更好扩展。

3.4 模拟考试:随机抽题和自动评分

模拟考试的核心是后端随机组卷。最简单稳定的 SQL 是:

SELECT * FROM t_question WHERE subject = 1 ORDER BY RAND() LIMIT 100;

RAND() 在题量几千的表中性能没问题,毕设完全够用。但要注意:抽取出的试卷要固定下来,不能让用户每次刷新题目顺序都变。所以后端在用户进入考试的那一刻,把抽取的题目 ID 列表存下来(可以存到 session 或一张 exam_question 关联表),考试过程中的作答都基于这份固定快照。

自动评分逻辑不复杂:

public ExamResultVO calculateScore(List<AnswerDTO> answers) { int score = 0; for (AnswerDTO answer : answers) { Question question = questionMapper.selectById(answer.getQuestionId()); if (question.getAnswer().equals(answer.getSelected())) { score += 1; } } // 科目一每题1分,总分100 return ExamResultVO.builder() .score(score) .correctCount(score) .wrongCount(answers.size() - score) .build(); }

交卷后要展示三个信息:分数、错题解析、本次成绩是否合格(驾考科目一 90 分合格,科目四 90 分合格)。这个合格线写在配置类里,不要写死在 SQL 里,方便后续调整。

3.5 微信登录与授权

登录这块是后端最容易出 bug 的地方。小程序端先调 wx.login 拿到临时 code,再把 code 传给后端:

wx.login({ success: res => { wx.request({ url: 'http://192.168.1.100:8080/api/user/login', method: 'POST', data: { code: res.code }, success: res => { wx.setStorageSync('token', res.data.data.token); } }); } });

后端拿到 code 后,需要向微信接口 https://api.weixin.qq.com/sns/jscode2session 发起请求,用 appid 和 secret 换取 openid。这一步用 Spring 的 RestTemplate 就能完成:

public LoginResult wxLogin(String code) { String url = "https://api.weixin.qq.com/sns/jscode2session?" + "appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code"; String response = restTemplate.getForObject(url, String.class); JSONObject json = JSON.parseObject(response); String openid = json.getString("openid"); // 查库或创建用户,生成token }

拿到 openid 后,给用户生成一个自定义 token 返回给前端,后续所有需要登录态的接口都在请求头里带 token。开发时在微信开发者工具勾选“不校验合法域名”,可以直接用 http://192.168.x.x:8080 访问本机后端,但上传体验版后必须配置 HTTPS 合法域名,否则真机无法请求。

3.6 SSM后端:常用注解和统一接口规范

SSM 的 Controller 层注解是论文里必须写清楚的技术点。我整理了一张对照表:

注解作用使用位置
@Controller标注这是一个控制器类类上
@ResponseBody把返回值直接写入HTTP响应体,配合@Controller返回JSON方法上
@RequestMapping映射URL路径和请求方式类或方法上
@RequestParam接收URL参数,如?pageNum=1方法参数上
@PathVariable接收路径参数,如/question/1中的1方法参数上
@RequestBody接收请求体中的JSON并绑定到对象方法参数上
@Autowired注入Service依赖字段上
@Service标注业务层组件Service实现类上

一个标准的分页查询接口长这样:

@Controller @RequestMapping("/api/question") public class QuestionController { @Autowired private QuestionService questionService; @RequestMapping(value = "/list", method = RequestMethod.GET) @ResponseBody public Result list(@RequestParam Integer pageNum, @RequestParam Integer pageSize, @RequestParam Integer subject) { PageHelper.startPage(pageNum, pageSize); List<Question> list = questionService.listBySubject(subject); PageInfo<Question> pageInfo = new PageInfo<>(list); return Result.success(pageInfo); } }

所有接口返回统一的 Result 结构:

public class Result { private Integer code; // 200成功,500失败 private String msg; private Object data; public static Result success(Object data) { Result r = new Result(); r.code = 200; r.msg = "success"; r.data = data; return r; } }

统一返回结构非常重要。否则小程序端每个请求都要写不同的解析逻辑,排错时也很痛苦。我见过一个项目里有的接口返回 {code:200},有的直接返回数组,还有的返回字符串,前端一堆 if else,极其混乱。

4. 毕业论文怎么写才能有深度

4.1 论文框架:每一章该写什么

毕设论文最忌讳的是“功能说明书”,全篇都是截图和代码粘贴。老师要看到的是你“为什么这么设计”的思考过程。一个稳妥的框架是这样的:

章节核心内容常见错误
第一章 绪论研究背景、意义、国内外现状、主要工作背景写成一堆空话套话
第二章 关键技术微信小程序、SSM、MySQL 的原理与选型理由变成名词解释,没有结合项目
第三章 需求分析可行性分析、功能需求、用例图、非功能需求功能需求没有边界
第四章 系统设计总体架构图、模块设计、数据库设计、接口设计E-R图和数据表脱节
第五章 系统实现分模块展示核心代码和运行截图大量贴代码,没有解释
第六章 系统测试测试环境、功能测试用例、测试结果只写“测试通过”
第七章 总结与展望总结工作、分析不足、展望后续总结等于复制摘要

“国内外研究现状”这一节,很多同学不知道怎么写。有个取巧但有效的方法:去知网或万方搜“在线考试系统”“微信小程序驾考”“移动学习平台”等关键词,找几篇近三年的硕士论文,看他们怎么归纳已有系统的特点和局限,然后列出几个代表系统的对比。你不需要完全创新,重点是体现出你调研过同类系统。

4.2 把“优选”写实:数据统计和智能推荐

“优选”两个字如果只在题目里出现,论文里找不到落点,答辩必被问住。我建议至少做一层数据统计加一层简单推荐:

错题统计接口可以用一条 SQL 完成:

SELECT q.id, q.question, q.answer, COUNT(w.id) AS wrong_num FROM t_wrong_question w LEFT JOIN t_question q ON w.question_id = q.id WHERE w.user_id = #{userId} GROUP BY q.id ORDER BY wrong_num DESC LIMIT 10;

小程序端看到一个“薄弱题目 Top10”,这就是“优选”的可视化成果。推荐逻辑不用做得太复杂,按错误次数降序 + 按最近错误时间排序,已经能体现出“针对用户弱项精准练习”的闭环。论文第 4 章可以画一张推荐流程图:用户交卷 -> 答案比对 -> 错题写入 -> 统计排序 -> 生成推荐练习,每一步都对应代码的哪个方法。

4.3 图表、测试数据与答辩准备

论文里的图,至少要有三张:系统总体架构图、功能结构图、数据库 E-R 图。画图工具推荐 ProcessOn 或者 Draw.io,线条统一、配色干净,不要用 Word 自带的形状硬凑。

测试部分要准备一张功能测试用例表:

用例编号测试功能操作步骤预期结果实际结果结论
TC001用户登录微信授权登录自动注册并跳转首页成功通过
TC002随机组卷点击“模拟考试”生成100题试卷成功通过
TC003提交答案答完所有题后交卷显示分数和解析成功通过
TC004错题收藏答错后查看错题本错题自动出现成功通过

答辩时老师最常问的几个问题,提前准备好答案:

  • 为什么不用 Spring Boot?明确回答:学校课程体系以 SSM 为主,且 SSM 各层职责清晰,便于理解底层原理。
  • 微信登录单点问题怎么处理?回答:用 code 换取 openid,openid 在小程序平台内唯一,配合自定义 token 维持会话。
  • 错题推荐的算法是什么?回答:基于错误频次统计的简单推荐,属于非个性化推荐,后续可引入遗忘曲线优化。

5. 常见问题与排坑实录

5.1 真机连不上本地后端

开发工具里跑得好好的,一发到手机就白屏,这是最常见的问题。根源通常是:代码里写了 http://localhost:8080 或 http://127.0.0.1:8080,到了手机,localhost 指向手机自己,当然连不上。

正确做法是改成电脑在局域网里的 IP,比如 http://192.168.1.100:8080,并且保证手机和电脑连同一个 WiFi。另外,微信小程序正式版要求请求域名必须是 HTTPS 且已备案,开发调试阶段可以在微信开发者工具右上角“详情 -> 本地设置”里勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”。

5.2 跨域和 Session 失效

SSM 后端默认不允许跨域,小程序虽然不是浏览器环境,但真机调试时仍可能遇到跨域问题。最省事的方案是在后端加一个 CORS 过滤器:

@Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization"); chain.doFilter(req, res); } }

在 Web.xml 里注册过滤器,放到 SpringMVC 的 DispatcherServlet 之前。注意如果后端的 Controller 里用了 session,小程序默认是不会自动带上 Cookie 的,这也是很多人发现“登录状态一刷新就丢”的原因。解决办法就是别依赖 session,用自定义 token 做登录态,前端每次 wx.request 在 header 里手动加 token。

5.3 加载更多时列表重复或数据错乱

加载更多出现重复数据的常见原因就是 pageNum 没有正确累加。还有一个隐蔽问题:请求是异步的,用户快速触底两次,第二次请求还在进行中,pageNum 已经加了两次,导致跳过一页数据。解决方案就是前面代码里的 loading 标记,请求结束之前不允许发起下一次请求。另外每次切换科目时,要把 questionList 清空、pageNum 重置为 1,不然会混着上一科目的数据。

5.4 小程序包体积超限

如果用了 uniapp 或者引入了很多静态资源,编译时会出现类似 source size 2612kb exceed max limit 2mb 的报错。小程序主包限制 2MB,解决办法有三个:

  1. 开启分包,把题库、考试等非首页页面放到 subpackages 里;
  2. 压缩图片,题库里不要直接存 base64 图片,用图床或后端返回图片 URL;
  3. 去掉没用到的组件和插件,很多模板自带了一堆 echarts、vant 组件,实际用不到。

以分包为例,app.json 里这样配置:

{ "subpackages": [ { "root": "pages/exam", "pages": [ "pages/exam/exam", "pages/exam/result" ] } ] }

注意小程序里访问分包页面的路径要带包名,例如 wx.navigateTo({ url: '/pages/exam/exam' })。分包配置好之后,主包体积瞬间能降下来。

5.5 常见问题速查表

现象可能原因解决方法
真机白屏请求地址用了localhost或未勾选域名校验使用局域网IP并勾选不校验合法域名
接口返回404Controller或Mapper扫描路径配置错误检查applicationContext.xml和组件扫描包路径
登录状态丢失服务端依赖session改用自定义token方案
中文乱码接口返回编码不一致设置UTF-8字符集过滤器
提交答案没反应请求参数名对不上用Network面板核对请求参数名与后端方法参数
数据库连接失败MySQL版本或驱动不匹配MySQL5.7搭配mysql-connector-java 5.1.47
订阅消息发送失败模板ID配置错误或用户未授权在后台申请模板并检查小程序订阅消息配置

开发调试时,优先用微信开发者工具的 Network 面板看请求状态码和返回体。很多前端报错其实是后端已经返回了 500,只是前端没有做错误提示逻辑。先把接口用 Postman 全部测通,再写页面绑定,能省一半排查时间。

5.6 体验版分发与反馈收集

小程序开发完成后,需要把代码上传到微信公众平台,生成体验版二维码,发给身边的同学和导师试用。在微信开发者工具点击“上传”,填好版本号和备注,然后在公众平台“版本管理”里把该版本设为体验版,就可以生成二维码。体验版不需要审核,成员和体验成员都可以直接扫。收集试用反馈的重点是:让测试者关注业务流程是否闭环,比如“预约考试-收到审核结果-查看记录”这条链路走不走得通。我在实际操作中发现,大家反馈最多的问题集中在页面提示不友好,比如提交预约后没有任何成功提示,用户以为没提交成功。这类问题要在一轮反馈后集中修复。

我个人在实际指导项目时最大的体会是:这个题目的代码量不大,真正拉开差距的是“能不能把系统讲清楚”。把一次请求的完整链路背下来,把五张表之间的关联画明白,把错题推荐这个“优选”的亮点逻辑说明白,答辩基本就稳了。如果后续想扩展,可以把科目二、科目三的视频教学和约车进度管理加进来,系统就从“刷题工具”升级成“全流程驾考助手”,这也正好是“优选驾考”这个题目可以深挖的方向。

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

手机PDF转换成Word免费版!安卓苹果通用,简单好用

日常办公、学习中&#xff0c;我们经常会遇到PDF文件无法编辑的问题。PDF格式虽然排版稳定、不易错乱&#xff0c;但无法直接修改文字、调整表格&#xff0c;想要二次编辑内容&#xff0c;唯一便捷的方式就是转换成可随意修改的Word文档。很多人习惯用电脑转换&#xff0c;其实…

作者头像 李华
网站建设 2026/10/3 7:13:21

PDF拆分合并超全教程!本地+在线双方案,新手零门槛搞定

日常办公、学习、整理资料时&#xff0c;大家经常会遇到PDF处理难题&#xff1a;多份PDF需要整合为一份、长篇PDF需要拆分出指定页面、多余空白页需要删除等等。很多人要么找不到合适工具&#xff0c;要么下载软件捆绑广告、收费有水印&#xff0c;在线工具又担心文件隐私泄露。…

作者头像 李华
网站建设 2026/10/3 7:12:40

实验室预约系统|基于java+ vue实验室预约系统(源码+数据库+文档)

实验室预约系统 目录 基于springboot vue实验室预约系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue实验室预约系统 一、前言 博主介绍&#x…

作者头像 李华
网站建设 2026/10/3 7:12:36

餐饮采购系统数据库建设:原材料清单结构化与导入实战

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

作者头像 李华
网站建设 2026/10/3 7:11:18

30岁转行Python,还来得及吗?

来得及&#xff0c;但前提是你别骗自己网上到处是“三十岁从零学Python&#xff0c;半年入职大厂”的帖子。我不否认有这样的人&#xff0c;但那是幸存者偏差。多数人三十岁转行&#xff0c;不是从零开始&#xff0c;是带着七年的行业积累换赛道。我认识一个做财务的姐姐&#…

作者头像 李华