新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于Spring Boot的学习课程辅助系统设计实战:从需求到部署

发布时间:2026/10/1 17:39:14来源:尧图网络
基于Spring Boot的学习课程辅助系统设计实战:从需求到部署
毕业设计做到一半最让人头疼的不是写代码而是“不知道下一步该干什么”。尤其是这种“基于Spring Boot的学习课程辅助系统”选题听起来很标准查资料也到处都是但真正动手时才发现——要么是代码片段东拼西凑跑不起来要么是数据库表设计得一塌糊涂做到后面自己都分不清哪个模块对应哪张表。这篇文章我想把自己的完整设计思路和实现过程整理出来包括需求分析、技术选型、数据库设计、核心模块代码怎么写、联调时踩了哪些坑以及一些在常规文档里不会写但实际很有用的经验。如果你也在做类似的Spring Boot毕设或课程设计或者说想用一个项目把Spring Boot、MyBatis、Vue这套主流技术栈串起来这篇文章应该能帮你省下不少时间。1. 为什么选Spring Boot做学习辅助系统需求拆解与技术选型1.1 这类系统到底在解决什么问题“学习课程辅助系统”这个名称听起来有点抽象我刚开始理解得也比较浅以为就是做个课程列表加个视频播放页面。后来跟指导老师聊了两次才明白这类系统的核心价值其实落在“辅助”两个字上——它不是在线教育平台那样要把整个教学过程搬上线而是给“教”和“学”两端提供支撑工具老师能发布课程、布置作业、查看学生完成情况学生能查看课程、提交作业、记录学习进度、看到自己的统计结果。所以在做需求分析时我没有直接照搬网上那些动辄十几张表的后台管理系统设计而是先梳理了三类核心角色和各自关心的问题管理员要管理教师账号、课程分类、系统基础配置关心的是“系统能不能稳定运行、数据是否统一”。教师要维护课程内容、发布作业、查看学生提交情况关心的是“发布是否方便、批改结果能否留存”。学生要浏览课程、报名学习、提交作业、查看自己的学习进度关心的是“操作是否顺畅、数据是否准确”。基于这些我把系统功能收敛成下面几条主线用户认证与角色权限、课程管理、作业提交与批改、学习进度记录与统计、后台管理。这些功能往下拆就是具体的接口和页面整个项目的范围就清楚了后面写代码时不会东一榔头西一棒槌。1.2 技术栈选型为什么是Spring Boot MyBatis Vue选技术栈时我其实纠结过一段时间。网上类似项目的方案五花八门有说用Spring Boot JPA的有说用SSM传统三层架构的还有直接用若依这类脚手架二次开发的。我的结论是如果你跟我一样是拿这个项目做毕设或课程设计而不是给真实企业做系统那**Spring Boot MyBatis MySQL Vue或Thymeleaf**这套组合是性价比最高的选择。原因有三个。第一Spring Boot是目前Java后端的主流框架自动装配、起步依赖、内嵌容器这些特性让项目搭建成本直线下降而且面试和答辩时被问到Spring Boot自动装配原理、约定优于配置这些概念你都有真实的代码可以佐证。第二MyBatis相比JPA更直观SQL自己控制排查问题时能看到完整的SQL语句对于学生项目来说SQL的可控性比ORM的便捷性更实用。第三这个组合的资料极其丰富遇到问题基本都能搜到解决方案不会因为某个冷门技术卡住整个进度。不过这里有一个很多人容易忽略的点**前后端分离到底要不要做。**如果你前端基础一般我建议不要强行拆成Spring Boot后端 Vue独立前端因为联调时的跨域、Token传递、接口联调会产生大量额外工作。我自己最终做的是前后端分离因为我前面前端比较熟但如果你时间紧张用Spring Boot Thymeleaf直接把页面渲染好集成在一个项目里毕设答辩完全够用而且工作量会少很多。1.3 整体架构设计单体应用 分层思想架构上我并没有搞微服务那套一个单体Spring Boot应用就够了。但单体不意味着代码可以乱写我还是按照标准的Controller-Service-Mapper三层来组织同时增加了DTO和VO的转换层。这样做的好处是各层职责清晰答辩时能讲清楚每一层的定位后续加功能时不需要改动已有代码的结构。项目结构设计如下course-helper ├── src/main/java/com/example/coursehelper │ ├── common // 统一返回结果、异常处理、工具类 │ ├── config // 拦截器、跨域、静态资源配置 │ ├── controller // 接口层 │ ├── service // 业务逻辑层 │ ├── mapper // 数据访问层 │ ├── entity // 数据库实体 │ ├── dto // 数据传输对象 │ └── vo // 视图对象 ├── src/main/resources │ ├── mapper // MyBatis XML文件 │ ├── static // 静态资源 │ └── application.yml └── pom.xml这里我想特别说明一下DTO和VO的使用。很多学生项目图省事直接用Entity返回给前端结果就是前端能拿到密码字段、一些不必要的关联信息也会被序列化出去。我在实现时所有接口返回的都是VO接收参数都用DTOEntity只在Service和Mapper之间传递。这个习惯看起来多写几个类但到了联调和答辩时你能很清楚地说明“哪些字段暴露给了前端哪些没有”这是加分项。2. 系统核心模块拆解与数据库设计2.1 功能模块划分先把边界画清楚系统功能我拆成了六个模块每个模块在代码里有独立的包和Controller互不混淆模块核心功能涉及角色用户认证模块登录、注册、Token签发与校验全部用户管理模块用户信息维护、角色分配、状态管理管理员课程管理模块课程CRUD、分类管理、上下架管理员、教师学习记录模块课程学习进度记录、进度查询学生作业管理模块作业发布、提交、批改、成绩查看教师、学生数据统计模块学习时长统计、作业完成率、选课人数教师、管理员模块划分完之后我做了接口文档用表格记下每个接口的路径、请求方式、参数、返回值。虽然开始觉得麻烦但后来写前端页面时就不用反复翻代码了而且答辩时的“系统设计”部分也有了现成素材。2.2 数据库设计六张核心表怎么建数据库设计是整个项目的地基表结构不合理后面写SQL时会非常痛苦。我最终设计了六张核心表外加两张关联表下面把其中最重要的列出来字段解释也一并写上。用户表user字段名类型说明idbigint主键自增usernamevarchar(50)登录用户名唯一passwordvarchar(100)BCrypt加密后的密码real_namevarchar(50)真实姓名roletinyint角色1管理员 2教师 3学生emailvarchar(100)邮箱可空statustinyint是否启用1启用 0禁用create_timedatetime创建时间课程表course字段名类型说明idbigint主键course_namevarchar(100)课程名称teacher_idbigint授课教师IDcategory_idbigint所属分类cover_urlvarchar(255)封面图地址descriptiontext课程简介total_hoursint总学时statustinyint状态1上架 0下架create_timedatetime创建时间学习记录表study_record字段名类型说明idbigint主键user_idbigint学生IDcourse_idbigint课程IDchapter_idbigint章节IDstudy_durationint本次学习时长秒study_datedate学习日期create_timedatetime记录创建时间作业表homework和作业提交表homework_submit也类似homework记录作业基本信息homework_submit记录每个学生的提交内容和教师批改结果。设计表的时候有一个很重要的教训**一定要考虑角色权限在数据库层面的落点。**比如课程表里直接存teacher_id这样查询“某教师教的所有课程”就只是一条SQL而不需要写复杂的关联逻辑用category_id关联分类表则方便做课程分类筛选。这种“把业务关系直接落到外键字段”的设计思路能让后续的开发高效很多。2.3 生产环境不可忽略的一点时间字段和软删除很多项目在做数据库设计时会把这两件事忽略掉但到了真正部署运行的时候才发现问题。第一个是时间字段类型Java里的LocalDateTime对应MySQL的datetime但为了避免时区问题我在连接串上强制指定了serverTimezoneAsia/Shanghai同时在实体类上统一用LocalDateTime类型不让Date和Timestamp混用——混用的后果是前端拿到的数据格式非常混乱有的带毫秒、有的不带。第二个是软删除我在每张业务表上都加了deleted字段默认0删除操作统一用update语句把deleted置为1这样数据不会物理消失对学习记录、作业这类审计需求很强的业务来说特别重要。3. 核心功能实现认证、拦截器与课程管理链路3.1 基于JWT的登录认证从签发到拦截的完整链路用户认证我选的是JWT方案没有用Session。原因很简单前后端分离架构下Session要处理跨域Cookie问题而JWT无状态后端不用存会话信息扩展性也更好。实现过程并不复杂核心就三步。第一步引入依赖。在pom.xml里加上jwt相关库和Spring Security的crypto模块这里只用它的BCryptPasswordEncoder做密码加密避免引入完整Spring Security导致拦截逻辑冲突dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-api/artifactId version0.11.5/version /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-impl/artifactId version0.11.5/version scoperuntime/scope /dependency dependency groupIdorg.springframework.security/groupId artifactIdspring-security-crypto/artifactId /dependency第二步写JwtUtil工具类。这里要注意的是密钥不要硬编码在代码里我放在application.yml中用Value注入这样部署时可以随时修改而不需要重新编译。签发Token时把用户ID、用户名、角色放进claim过期时间设置为72小时方便开发调试。Component public class JwtUtil { Value(${jwt.secret}) private String secret; Value(${jwt.expire-hours:72}) private Long expireHours; public String generateToken(Long userId, String username, Integer role) { Date now new Date(); Date expiryDate new Date(now.getTime() expireHours * 3600 * 1000); return Jwts.builder() .setSubject(username) .claim(userId, userId) .claim(role, role) .setIssuedAt(now) .setExpiration(expiryDate) .signWith(SignatureAlgorithm.HS256, secret.getBytes(StandardCharsets.UTF_8)) .compact(); } }第三步写拦截器解析Token。这里有一个非常容易踩坑的地方拦截器里拿到的request是HttpServletRequest但要往Controller传用户信息一般是通过request.setAttribute或者ThreadLocal。我最终用的是ThreadLocal 一个UserContext工具类在拦截器里解析出userId和role后存入ThreadLocalController里直接UserContext.getUserId()就能拿到当前登录用户用完再在拦截器的afterCompletion里remove掉避免线程池复用导致数据串线。拦截器的注册也要注意放行路径。登录、注册、首页课程列表这些不需要Token的接口必须放在排除列表里其他接口全部拦截。我一开始配置时就漏掉了一个静态资源路径结果前端一直报401排查了很久才发现。3.2 课程管理模块的开发从接口定义到Mapper映射课程管理模块是最典型的CRUD业务但它能扩展出不少技巧。我以课程列表的分页查询为例说明整个链路怎么写。Controller层接收分页参数和筛选条件返回统一分页对象RestController RequestMapping(/api/course) public class CourseController { GetMapping(/list) public ResultPageResultCourseVO page(RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size, RequestParam(required false) String courseName, RequestParam(required false) Long categoryId) { CourseQueryDTO dto new CourseQueryDTO(); dto.setPage(page); dto.setSize(size); dto.setCourseName(courseName); dto.setCategoryId(categoryId); return Result.success(courseService.pageQuery(dto)); } }Service层把查询条件转成Map传给Mapper核心是构建动态SQLpublic PageResultCourseVO pageQuery(CourseQueryDTO dto) { MapString, Object params new HashMap(); params.put(page, (dto.getPage() - 1) * dto.getSize()); params.put(size, dto.getSize()); params.put(courseName, dto.getCourseName()); params.put(categoryId, dto.getCategoryId()); ListCourseVO list courseMapper.selectPage(params); Long total courseMapper.countPage(params); return PageResult.of(list, total, dto.getPage(), dto.getSize()); }Mapper XML里的动态SQL用where和if标签拼接条件select idselectPage resultTypecom.example.coursehelper.vo.CourseVO SELECT c.id, c.course_name, c.teacher_id, t.real_name AS teacher_name, c.category_id, c.cover_url, c.description, c.total_hours FROM course c LEFT JOIN user t ON c.teacher_id t.id where c.deleted 0 if testcourseName ! null and courseName ! AND c.course_name LIKE CONCAT(%, #{courseName}, %) /if if testcategoryId ! null AND c.category_id #{categoryId} /if /where ORDER BY c.create_time DESC LIMIT #{page}, #{size} /select动态SQL这块是MyBatis的灵魂尤其多条件筛选场景用where加if比拼接字符串安全得多还能自动处理多余AND的问题。我个人强烈建议把SQL写在XML里而不是写在注解里因为后期SQL一旦复杂起来注解方式会非常难维护而XML有着清晰的层级和注释空间。3.3 为什么Mapper要返回VO而不是Entity这个问题是我写代码时反复纠结过的。最终答案是Mapper返回VO并没有问题尤其是在这种关联查询场景。比如课程列表需要显示教师姓名而course表里只有teacher_idEntity里根本没有teacherName这个字段如果Mapper返回Course对象你还要在Service里做二次查询来补全教师名白白多出N1条SQL。直接在SQL里LEFT JOIN查出teacherName返回CourseVO一次查询全部搞定性能更好代码也更简洁。当然实体和VO分离也有代价就是需要写转换逻辑。我用MapStruct来做对象转换比手写BeanUtils.copyProperties性能更好而且在编译期就能发现字段不匹配的问题。这个工具值得花半小时学一下。3.4 文件上传与作业提交本地存储还是对象存储作业提交功能必然涉及文件上传。我最初想的是把文件存到服务器本地磁盘实现简单但对于部署在云服务器上的项目来说文件会随着容器重建而丢失。后来我改成了本地存储 数据库记录路径的方式架构上给未来替换对象存储留了接口。具体实现时我定义了StorageService接口默认的LocalStorageServiceImpl把文件写到配置好的upload.dir目录文件名用UUID重命名避免中文名和重名问题。提交作业的接口逻辑是PostMapping(/submit) public ResultVoid submitHomework(RequestParam(homeworkId) Long homeworkId, RequestParam(file) MultipartFile file) { Long studentId UserContext.getUserId(); // 检查作业是否已提交过 HomeworkSubmit submit homeworkSubmitMapper.selectByHomeworkIdAndStudentId(homeworkId, studentId); if (submit ! null) { return Result.error(400, 该作业已提交请勿重复提交); } // 保存文件记录文件路径 String fileUrl storageService.store(file); // 插入提交记录 homeworkSubmitService.create(homeworkId, studentId, fileUrl); return Result.success(); }这里有几个隐藏问题值得注意第一是文件类型校验不能只依赖前端后端必须判断扩展名和Content-Type我限制为常见的文档类型doc、docx、pdf、zip等。第二是文件大小限制我在application.yml中配置了spring.servlet.multipart.max-file-size和max-request-size分别设为10MB和20MB。第三是提交去重一个作业每个学生只能提交一次如果允许重新提交则需要修改已有记录的fileUrl而不是新增。3.5 统一返回结果与全局异常处理项目气质的分水岭很多学生项目的接口返回值是裸的JSON要么是Map要么直接把Entity序列化出去错误处理更是随心所欲有的返回null有的抛异常直接弹500页面。从专业角度来看这其实是项目质量的关键分水岭。我自己封装了一个Result 结构是code、message、data三个字段成功时code为200失败时code为业务错误码。全局异常处理用RestControllerAdvice捕获参数校验异常、业务异常和未知异常统一格式返回避免把堆栈信息暴露给前端。写全局异常处理时有一个容易忽略的点RestControllerAdvice默认只能处理进入Controller之前的异常对于在过滤器中抛出的异常需要额外处理。我后来把JWT解析失败等认证异常在拦截器里直接catch住手动写回JSON不走全局异常处理器这样就避免了拦截器异常被容器包装成HTML错误页的问题。4. 学习进度跟踪与数据统计从埋点到可视化的完整设计4.1 学习进度数据怎么设计一张记录表解决计算问题学习辅助系统区别于普通课程管理系统的最核心模块就是学习进度跟踪。这个功能如果设计不好很容易做成摆设——数据记录了但学生看不到价值教师也用不上。我的思路是设计一张study_record表每次学生学习一个章节时前端每隔一段时间向后端上报学习记录内容包含学生ID、课程ID、章节ID、本次学习时长。后端收到记录后写入数据库。计算学习进度时只需要根据course表里配置的总章节数统计学生已学过的章节数两者相除就得到百分比。这里有一个细节学习时长的准确性。如果前端只是退出页面时上报一次用户直接关浏览器就会丢失数据。所以我间隔30秒发送一次心跳后端做幂等处理同一节课同一分钟内只算一次有效时长。这也是为什么study_record表里要有study_date字段——用于统计某天的学习时长避免同一用户同一课程的数据重复累加。上报接口的代码很简单PostMapping(/record) public ResultVoid recordStudy(RequestBody StudyRecordDTO dto) { Long studentId UserContext.getUserId(); studyRecordService.record(studentId, dto); return Result.success(); }真正的逻辑在Service层先检查该学生当天是否已经记录过该章节的学习数据如果有就累加时长没有就插入新记录。4.2 进度计算逻辑从课时维度而不是章节维度在学习进度计算上我开始犯了一个错误直接用“已学章节数/总章节数”来计算百分比结果发现有些视频章节时长40分钟有些只有10分钟进度百分比根本不能准确反映学习量。后来改成了课时维度在course表增加total_hours字段记录总学时在前端学习页面记录每一节课的真实视频时长学习进度 已学课时数 / 总课时数。这个改动虽然只是在计算层面调整但它在真实使用场景中的意义很大——教师可以一眼看出学生是否只是“挂机刷进度”对于真实的在线学习来说学习时长的积累比章节打卡更具参考价值。4.3 数据统计接口给教师端看板用的SQL写法数据统计模块是答辩时的亮点所在。我实现了三个核心统计接口教师端课程总览、学生端个人学习报告、管理员端系统概览。教师端总览需要的数据包括任教课程数量、全部课程累计报名人数、作业平均提交率。这里最关键的是作业提交率的SQL写法。作业提交率 已提交作业数 / 应提交作业数应提交作业数 作业数量 × 选课人数。我通过子查询和聚合函数实现SELECT h.course_id, COUNT(DISTINCT h.id) AS total_homework, COUNT(DISTINCT s.id) AS submitted_count, COUNT(DISTINCT h.id) * (SELECT COUNT(*) FROM course_selection cs WHERE cs.course_id h.course_id) AS expected_count FROM homework h LEFT JOIN homework_submit s ON s.homework_id h.id WHERE h.deleted 0 GROUP BY h.course_id刚开始我直接JOIN然后COUNT数据一直不对后来排查发现是课程与作业一对多、作业与提交一对多两张一对多表JOIN会导致数据翻倍。这个坑让我意识到做统计SQL时宁可多写子查询也不要盲目JOIN尤其当关联关系层级较多时子查询的可读性和正确性都比JOIN更可靠。学生端个人学习报告则是查询当前学生所有选课记录关联课程表计算出每门课的进度百分比并按最近学习时间排序方便学生看到“最近在学什么”。4.4 前端可视化图表不必炫技清楚即可前端我用了Vue Element Plus图表用了ECharts。统计页面展示了三个图选课人数最多的Top5课程用横向柱状图最近的每日学习时长用折线图课程完成率分布用饼图。ECharts的数据结构非常简单后端只需返回统计结果前端用chart.setOption填充即可。这个部分不建议花太多时间调样式清爽直观是最重要的。5. 联调与部署阶段的坑这些问题花了整整三天5.1 Maven依赖冲突版本仲裁不是万能的项目开发到一半时我突然发现启动不了报错信息是No qualifying bean of type XXXX available。排查了很久发现是因为Spring Security的crypto模块传递依赖了旧版本的commons-logging和项目里其他依赖产生冲突导致部分Bean的自动装配被影响。解决方法是使用Maven依赖树分析冲突mvn dependency:tree -Dverbose发现冲突后在pom.xml里用exclusion排除掉传递依赖或者用dependencyManagement统一指定版本。这个经验说明一个问题不要盲目引入完整Spring Security尤其在只需要密码加密的场景单独引入spring-security-crypto更轻量能极大避免依赖冲突带来的莫名其妙报错。5.2 拦截器放行路径配置失误前后端联调的第一道坎前后端联调时前端访问/api/course/list一直返回401未认证。我一开始以为是Token没带前端检查了请求头也没问题最后才发现是拦截器配置里放行路径写错了。我的WebMvcConfig是这样的registry.addInterceptor(jwtInterceptor) .addPathPatterns(/api/**) .excludePathPatterns(/api/auth/login, /api/auth/register, /api/course/list);然后发现前端请求的路径实际上是/api/course/list这个路径包含在放行中但前端登录后访问/api/course/detail/1时拦截器拿到的Token却是undefined。问题不在路径而在前端没有在请求拦截器中统一携带Token。这是前后端分离联调的典型问题解决方案是前端用Axios的请求拦截器统一从localStorage取Token并写入Authorization头。5.3 Spring Boot默认使用CGLIB代理事务注解失效的坑这是一个很经典但很容易被忽略的问题。Spring Boot 2.x以上版本中EnableTransactionManagement默认使用CGLIB代理而CGLIB代理对public方法生效对同类内部方法调用不生效。我在写作业提交和成绩批改时把两个写操作放在同一个Service类的两个方法里其中一个方法调另一个方法结果事务没生效数据只写了一部分导致出现脏数据。解决方法是要么把事务方法放到不同的Service类中通过注入调用要么在同一个类中自注入代理对象来调用。但最稳妥的方案是避免自调用把涉及多个写操作的核心业务独立成一个事务方法。这也是面向切面编程的一个经典应用场景答辩时如果你能讲清楚这个原理会显得很有深度。5.4 统一时间格式前后端时区不一致的惨痛教训有一次前端反馈学生提交作业成功的时间显示成了“2026-07-20 02:37:00”比实际时间早了8个小时。排查发现后端返回的时间是UTC格式而前端浏览器默认按本地时区解析导致显示偏差。解决方式是在application.yml里配置Jackson的时区和格式spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai同时在后端实体类的LocalDateTime字段上统一用JsonFormat(pattern yyyy-MM-dd HH:mm:ss)这样任何接口返回的时间格式都完全由后端控制不会再被环境差异影响。5.5 部署时Spring Boot版本太高带来的连带问题我最初为了尝鲜用了Spring Boot 3.2版本结果发现很多第三方库还没有适配Jakarta EE 9的包路径变化。比如最开始引入的旧版分页插件直接报ClassNotFoundException因为我用的是javax.命名空间而Spring Boot 3已经全部迁移到jakarta.。如果你做毕设我建议直接用Spring Boot 2.7.x这是整个2.x系列的稳定收官版本兼容性好、资料多、各种第三方组件适配成熟。除非你有明确需求否则不必追新版本毕竟项目的核心目标是跑得稳、讲得清、可答辩。5.6 YAML配置随机端口与内嵌容器问题有段时间为了调试方便我尝试在application.yml里配置随机端口server: port: ${PORT:0}这意味着每次启动端口都不同本地调试时前端强转的接口地址就全部失效。所以开发阶段不要用随机端口直接把端口固定为8080测试环境再用server.port8081等命令行参数覆盖即可。6. 一点个人经验总结整个项目从零到一我最大的感受是这类“基于Spring Boot的XX系统”最考验的不是单一的奇技淫巧而是把常规功能稳稳当当串联起来的能力。登录认证、权限拦截、课程CRUD、作业文件上传、进度计算、统计报表——每一个模块单独看都不难但组合在一起就是一套完整的技术栈练兵场。对正在做这个选题的同学我的建议是先花三天把需求边界和数据库设计想清楚再开始写代码这比你边写边改高效得多。前端如果时间紧张就用Thymeleaf把Spring Boot集成好即可不必强行上Vue。后端代码一定要分层明确、统一返回、全局异常处理这三件事做扎实它们是答辩时体现专业度的关键。至于我自己写完这个项目之后再去看Spring Boot的自动配置源码理解程度和前一阵子完全不一样——很多原来觉得抽象的概念在真实业务场景里一下就变得具体。这大概就是做项目的意义吧代码只是载体真正收获的是把知识落地的能力。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

RabbitMQ 安装部署与插件配置实战:从入门到高频问题排查 2026/10/1 19:51:37

RabbitMQ 安装部署与插件配置实战:从入门到高频问题排查

先说句实在话,RabbitMQ 是我在生产环境里用得最久的消息队列,没有之一。很多后端同学第一次接触它,被 Erlang、管理插件、MQTT 这些名词一搅和,很容易在安装阶段就栽跟头。这篇文章我就把 RabbitMQ 及其插件的安装从头捋一遍&…

阅读更多 →
收藏!小白程序员必看:揭秘AI Agent的“记忆”如何决定其能否持续工作——TaoToken统一Key/API通道下的记忆架构拆解 2026/10/1 19:51:35

收藏!小白程序员必看:揭秘AI Agent的“记忆”如何决定其能否持续工作——TaoToken统一Key/API通道下的记忆架构拆解

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

阅读更多 →
FreeRTOS内核机制与工程实践:任务调度、移植与源码解析 2026/10/1 19:51:29

FreeRTOS内核机制与工程实践:任务调度、移植与源码解析

1. FreeRTOS到底解决了什么问题 1.1 从裸机到RTOS:你为什么会需要它 先说个我早年做项目时的真实经历。当时用STM32F103C8T6做了一个带按键、OLED显示、传感器采集的小设备,裸机大循环里写了状态机,一个 while(1) 里面塞了五六件事。功能倒…

阅读更多 →
Codex 技术实践分享:Vue3 后台项目中的 TypeScript 工程化落地 2026/10/1 19:51:29

Codex 技术实践分享:Vue3 后台项目中的 TypeScript 工程化落地

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

阅读更多 →
家政公司订单管理系统开发实战:从需求到部署全流程解析 2026/10/1 19:51:29

家政公司订单管理系统开发实战:从需求到部署全流程解析

1. 先说实话:家政公司缺的不是订单,而是把订单管明白的工具我在帮家政公司做系统选型和落地这件事上,接触过不下几十位老板和店长。聊到最后几乎都会落到同一个问题上:客户不缺咨询,订单也不缺,缺的是一套能…

阅读更多 →
Ionic Tab导航实战指南:路由、隐藏、角标与样式定制 2026/10/1 19:51:23

Ionic Tab导航实战指南:路由、隐藏、角标与样式定制

先问一个实际的问题:你上一次被要求“把App的底部导航改成Tab样式”是什么时候?我估计大多数做过移动端开发的同学,简历里都写着“基于Ionic开发跨平台应用”,然后实际工作里最常打交道的,恰恰就是这个由IonicTab撑起来…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉