news 2026/10/18 11:44:21

基于Spring Boot的高校毕业生实习管理系统核心设计解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Spring Boot的高校毕业生实习管理系统核心设计解析

简介:基于Java的高校毕业生实习管理系统毕业设计资料包,面向计算机相关专业毕业生与Java Web开发者,借助信息化手段解决高校实习管理中岗位发布分散、学生申请流程冗长、成绩统计困难等痛点,覆盖用户登录注册、实习岗位发布、学生实习申请、成绩录入与统计分析等业务模块。压缩包为rar格式,约29.05MB,内含项目设计论文、开题报告、任务书、数据库脚本、Excel表结构规划及Stutrain源码目录等,从选题、开题到编码实现均有据可查,目录结构清晰。已有595人学习下载,适合作毕业设计参考或Java Web综合实训项目。源码展示了Servlet、JSP、Java数据库连接与MySQL交互的典型写法,并采用模型-视图-控制器架构;数据库脚本可直接初始化MySQL表结构,Excel清晰呈现字段与类型。配合文档可系统复盘系统架构、功能模块与实现细节,深入理解面向对象设计、异常处理、集合框架、IO流与多线程等Java核心知识在实际项目中的应用,为二次开发与论文撰写提供扎实支撑。

1. 毕业生实习管理系统:它在解决什么

做过毕业设计的同学应该都遇到过这个场景:院系每年要收几百份实习材料,学生交纸质周报、企业导师手写评语、校内老师月底统一打分,材料在三个人手里转一圈,最后汇总到教学秘书的Excel里。整个过程最大的问题不是某个功能不会做,而是信息不同步——学生不知道企业导师是否已经审核了自己的周报,校内老师不知道学生这个月换了企业,教学秘书不知道哪些学生还没提交材料。基于Java的高校毕业生实习管理系统,本质上就是把这一整条业务链搬到线上:学生端提交实习申请和周期报告,企业端确认岗位和鉴定,校内端审核打分,院系端看汇总数据。它不是把增删改查拼起来就完事,而是要把“实习三方协同、过程留痕、成绩定级”这三点做成闭环。适合正在选毕业设计题目的同学,也适合要给高校做实训系统的开发者。看完这篇文章,你至少能搭出一套能答辩、能演示、结构清楚的可运行系统。

2. 方案选型与表结构:先把骨架立住

2.1 技术选型为什么是Spring Boot + MyBatis-Plus

毕业设计场景下,最怕的不是技术太旧,而是资料太少、报错没人解答。Java后端这个方向,Spring Boot生态是绕不开的主流选择,它的自动配置和starter机制能省掉大量XML配置,让一个空项目在十几分钟内跑起来。持久层我建议直接用MyBatis-Plus而不是原生MyBatis,原因有三个:第一,单表CRUD不需要手写SQL,BaseMapper里已经内置了insert、updateById、selectPage这些方法,写业务代码的速度快一大截;第二,LambdaQueryWrapper的条件构造器能让查询逻辑直接写在Java代码里,比拼SQL字符串安全得多;第三,分页插件是现成的,答辩时演示”第2页共10条数据”这种效果不需要自己封装。

数据库用MySQL 8.x,字符集固定utf8mb4,别用utf8,否则学生提交的实习心得里带个emoji表情就存不进去。前端部分,如果时间紧,直接用Spring Boot自带模板引擎渲染服务端页面就够了;如果想把项目做得漂亮些,常见做法是前后端分离,Vue 3 + Element Plus 配合一套后端接口。这里提醒一点,除非你已经在公司实习时用过Vue,否则不要为了”看起来高级”强行上前后端分离——答辩时老师看不懂前端代码会追着问,服务端渲染的项目反而容易讲清楚。

缓存和权限这块,Redis和JWT在毕业设计里属于加分项,但不是必选项。我的习惯是:先把业务跑通,再考虑用Redis存验证码和Token,用拦截器做接口鉴权。顺序反了容易陷入”权限调不通、业务没写完”的两难局面。

2.2 核心表结构与字段设计

实习管理系统的核心表,按业务流动的顺序来划分:用户表、企业信息表、实习岗位表、实习申请表、实习日志表、成绩评定表。不含权限相关的中间表,六张主表就够了。

用户表sys_user是所有角色的统一入口,用role_type字段区分角色,不建议为每种角色单独建表,否则登录逻辑要写多套,权限控制也会变得很啰嗦。字段至少要有:

字段名类型说明
idbigint主键,雪花算法
usernamevarchar(50)登录账号,唯一索引
passwordvarchar(100)BCrypt加密后的密文
real_namevarchar(50)姓名,学生填学号+姓名方便老师辨认
role_typetinyint0系统管理员,1院系管理员,2校内老师,3企业导师,4学生
department_idbigint所属院系,学生和老师必填
enterprise_idbigint企业ID,企业导师必填
statustinyint0禁用,1启用

企业信息表enterprise_info记录企业资质和联系人信息,字段建议包括企业名称、统一社会信用代码、行业类别、联系人、联系电话、企业地址。这里有一个容易忽略的点:联系人字段一定要拆成联系人和联系电话两个字段,不要合并成一个“联系方式”,否则后面做消息通知时没法精准定位到人。

实习申请表internship_apply是整个系统的业务核心,它把学生、企业、岗位、校内老师四方面关联起来,同时记录了实习的时间边界和状态变化。核心字段如下:

字段名类型说明
idbigint主键
student_idbigint关联sys_user.id
post_idbigint关联实习岗位表
enterprise_idbigint冗余企业ID,方便按企业查
teacher_idbigint校内指导老师ID
statustinyint0待确认,1已确认,2已拒绝,3已终止,4已完成
start_datedate实习开始日期
end_datedate实习结束日期
create_timedatetime申请提交时间

status字段的每一步变更最好都在代码层校验当前状态是否合法,不要允许随意跳转。比如一个已拒绝的申请不能直接变成已完成,必须重新发起申请走一遍流程。

实习日志表internship_log按周期记录学生的工作内容,我的建议是统一定义为周报,不做日报。高校实习的考核粒度是周,日报会让数据量膨胀而且大多数学生不会坚持写。周报表里除了content和create_date,还要加一个week_seq字段,用来记录“这是实习的第几周”。这个字段是为了规避跨年日期计算问题——周数计算依赖日期解析时,很容易遇到元旦前后那周算错的情况,详见后面的避坑章节。

成绩评定表internship_score记录企业导师评分、校内导师评分、最终加权分和评语。这里要保留原始分和权重算法的历史快照,否则后期调整权重时历史成绩会跟着变。

2.3 状态字段的枚举设计与索引建议

状态字段最忌讳用魔法值,Java代码里写if(status == 1),三个月后自己都记不住1是什么含义。正确做法是定义枚举类,把状态码和文案放在一起,代码里只和枚举比较:

public enum ApplyStatus { PENDING(0, "待确认"), CONFIRMED(1, "已确认"), REJECTED(2, "已拒绝"), TERMINATED(3, "已终止"), FINISHED(4, "已完成"); private final int code; private final String desc; ApplyStatus(int code, String desc) { this.code = code; this.desc = desc; } public int getCode() { return code; } public String getDesc() { return desc; } }

这个枚举类承担了两个职责:一是让业务代码里不再出现裸数字,二是给前端下拉框提供数据源,通过ApplyStatus.values()遍历可以一次性把状态列表返回给页面。注意枚举的命名用动词过去式,PENDING、CONFIRMED、REJECTED,语义清晰,不要用中文拼音缩写。

索引设计方面,experience告诉我两个必加索引的位置:internship_apply(student_id)和internship_apply(enterprise_id),因为查询“某个学生的实习记录”和“某个企业的接收记录”是最高频的操作;internship_log(internship_id, week_seq)建议建联合索引,这是因为周报提交时要去重校验,判断某个实习的第几周是否已经存在记录。联合索引有一个注意点:字段顺序要把等值查询的字段放在前面,week_seq的等值条件比internship_id更频繁,但单独拿week_seq做查询没有意义,所以实际排序是(internship_id, week_seq)更合理。

建表时把所有时间字段统一命名为create_time、update_time,类型datetime,默认值CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP,这样统计和排查问题时看到一个表就知道哪些字段是审计字段。

3. 核心业务链路实现:从账号到成绩单

3.1 登录与身份标识

整个系统有五个角色,登录接口不能只验证用户名密码,还要把角色信息一并返回,让前端根据角色渲染不同的菜单和页面。密码存储必须用BCrypt加密,Spring Security里的BCryptPasswordEncoder可以直接拿来用,不要自己写MD5加盐,那属于重复造轮子且容易造出安全隐患。

登录成功后,我一般会把用户ID、角色类型、所属院系ID放进Token里,这样后续接口鉴权时不需要每次查数据库就能判断操作权限。Token生成用JWT,注意设置过期时间,毕业设计场景建议设为12小时,太短了演示时频繁重新登录很尴尬,太长了不安全。

public String createToken(SysUser user) { long expireMillis = 12 * 60 * 60 * 1000; Date expireDate = new Date(System.currentTimeMillis() + expireMillis); return Jwts.builder() .setSubject(user.getId().toString()) .claim("roleType", user.getRoleType()) .claim("departmentId", user.getDepartmentId()) .claim("realName", user.getRealName()) .setExpiration(expireDate) .signWith(SignatureAlgorithm.HS256, secretKey) .compact(); }

这里的secretKey放在application.yml里配置,不要硬编码在代码中。JWT的payload默认是Base64URL编码,不是加密,所以不要把密码放进去。该代码块对应的逻辑是:登录验证通过后,将用户的关键身份信息编码进Token,前端后续请求在Header中携带Token,后端拦截器解析出roleType和departmentId后放入请求上下文,后续业务代码直接从上下文取,不必每次查库。

3.2 实习申请与分配状态流转

实习申请这个功能,不同高校的管理模式不太一样。有的学校是学生自己在系统里找企业投递,有的是院系统一分配。系统设计上最好兼容两种模式:学生端可以发起申请选择岗位,企业导师或院系管理员确认;院系管理员也可以直接指定学生到某个企业,批量创建申请记录。

状态流转的校验逻辑放在Service层,这是最常见也最不易出错的方案。controller只负责接收参数和返回结果,切勿在controller里写业务判断,否则回看代码时运维和排错的成本会翻倍。下面这段是“待确认状态才能执行操作”的通用写法:

public boolean confirmApply(Long applyId, boolean pass) { InternshipApply apply = getById(applyId); if (apply == null) { throw new BusinessException("申请记录不存在"); } if (apply.getStatus() != ApplyStatus.PENDING.getCode()) { throw new BusinessException("当前状态不允许该操作"); } apply.setStatus(pass ? ApplyStatus.CONFIRMED.getCode() : ApplyStatus.REJECTED.getCode()); return updateById(apply); }

这段代码里有一个容易被忽视的竞态问题:用户连点两次提交,两次请求同时读到了PENDING状态,然后都执行updateById,最后一个请求覆盖前一个结果。解决办法是update的时候带上条件WHERE status = 待确认,被影响行数为0说明状态已变更:

public boolean confirmApply(Long applyId, boolean pass) { int targetStatus = pass ? ApplyStatus.CONFIRMED.getCode() : ApplyStatus.REJECTED.getCode(); return lambdaUpdate() .eq(InternshipApply::getId, applyId) .eq(InternshipApply::getStatus, ApplyStatus.PENDING.getCode()) .set(InternshipApply::getStatus, targetStatus) .update(); }

注意这里的lambdaUpdate().eq(...).eq(...),两个eq条件同时生效,数据库层面的乐观锁效果,比先查询再更新安全得多。参数说明:applyId是申请记录ID,pass表示是否通过,返回boolean表示是否有记录被更新。建议所有状态变更接口都采用这种“条件更新”写法,可以省掉大量并发问题。

3.3 周报提交、审核与分页查询

周报是实习过程管理最重头的模块。学生提交周报时,前端会传内容文本、实习ID、本周序号。后端要做三件事:校验该学生当前有处于“已确认”状态的实习记录;校验这周的周报是否已经提交过;保存并通知校内老师和企业导师。

“校验本周是否重复”用前面提到的唯一索引做兜底,代码里的查询逻辑也不可少:

public void submitLog(InternshipLog log) { long count = lambdaQuery() .eq(InternshipLog::getInternshipId, log.getInternshipId()) .eq(InternshipLog::getWeekSeq, log.getWeekSeq()) .count(); if (count > 0) { throw new BusinessException("本周周报已提交,请勿重复操作"); } log.setStatus(LogStatus.PENDING.getCode()); save(log); }

审核端是典型的列表页加详情页结构,列表分页查询用MyBatis-Plus的分页插件,查询条件需要支持按状态筛选、按学生姓名模糊搜索、按提交时间排序:

public Page<InternshipLog> queryLogPage(int pageNum, int pageSize, Integer status, String studentName, Long teacherId) { Page<InternshipLog> page = new Page<>(pageNum, pageSize); LambdaQueryWrapper<InternshipLog> wrapper = Wrappers.lambdaQuery(); wrapper.eq(status != null, InternshipLog::getStatus, status) .like(StringUtils.hasText(studentName), InternshipLog::getStudentName, studentName) .orderByDesc(InternshipLog::getCreateTime); return logMapper.selectPage(page, wrapper); }

这里eq(status != null, ...)的意思是:status参数为空时这个条件不生效,即不筛选状态。这种写法很常见,但注意前端传来的参数一定要做空值处理,不要把字符串“null”传进来。分页参数pageNum从1开始,pageSize建议限制最大100,防止有人把页面大小设成一万拖垮数据库。

周报审核通过后,系统要自动更新统计信息。统计逻辑放在事务里,用@Transactional注解包裹。这里提一个容易翻车的地方:Spring的@Transactional默认只对RuntimeException回滚,如果业务异常继承的是Exception,需要指定rollbackFor = Exception.class,否则脏数据就落库了。

3.4 成绩评定与归档

成绩评定模块要支持企业导师录入企业评分,校内老师录入校内评分,系统按权重计算最终得分。权重规则不要写死在代码里,存到sys_config表,这样答辩时调整规则不需要重新编译部署:

public BigDecimal calcFinalScore(Long applyId) { InternshipApply apply = getById(applyId); InternshipScore score = scoreMapper.selectByApplyId(applyId); // 从配置表读取权重,例如key为score.enterprise.weight String weightStr = configService.getValue("score.enterprise.weight"); BigDecimal enterpriseWeight = new BigDecimal(weightStr); BigDecimal teacherWeight = new BigDecimal("1").subtract(enterpriseWeight); BigDecimal finalScore = score.getEnterpriseScore() .multiply(enterpriseWeight) .add(score.getTeacherScore().multiply(teacherWeight)) .setScale(2, RoundingMode.HALF_UP); score.setFinalScore(finalScore); scoreMapper.updateById(score); return finalScore; }

成绩计算完成后,整个实习记录的状态更新为“已完成”,同时把实习报告附件上传的入口打开。这里有一个边界情况:如果企业导师还没评分,此时计算最终成绩会得到空指针或零值,所以调用calcFinalScore前必须校验enterpriseScore和teacherScore都已经录入。

4. 多角色权限与数据隔离:把权限矩阵落地

4.1 五类角色的权限矩阵

实习管理系统的角色权限,本质上是同一个系统的不同操作面。系统管理员管账号和字典,院系管理员负责分配和统计,校内老师管审核和评分,企业导师只能看分配到自己企业的学生,学生只能操作自己的申请和周报。权限矩阵用表格整理如下:

功能模块系统管理员院系管理员校内老师企业导师学生
用户管理增删改查本院系查看无无无
企业管理增删改查审核入驻查看维护本企业查看
岗位管理全部本院系查看发布/修改查看/投递
实习分配全部分配本院系查看确认/拒绝申请
周报管理查看全部审核/评语审核/评语提交/查看
成绩管理查看全部录入教师分录入企业分查看
系统配置增删改无无无无

表格里“查看”和“操作”要分开设计,有些页面对学生是只读的,有些字段对企业导师不可见。毕业设计答辩时,老师很可能会现场问“我以企业导师登录能看到什么”,你这个矩阵如果能脱口而出,就是明显的加分项。

接口层面的权限控制,常见做法是拦截器加注解,而不是在controller里每个方法里if判断角色。定义一个@RequireRole注解,标注在方法上,拦截器统一校验。

4.2 拦截器与注解实现接口权限

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequireRole { int[] value(); }

这个注解的值是一个int数组,表示允许访问的角色类型。例如@RequireRole({2, 3})表示只有校内老师和企业导师能访问。在拦截器的preHandle方法里,从Token中解析出当前用户的角色,再判断是否在注解允许的范围内:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (!(handler instanceof HandlerMethod)) { return true; } RequireRole requireRole = ((HandlerMethod) handler).getMethodAnnotation(RequireRole.class); if (requireRole == null) { return true; } Integer roleType = getCurrentUser().getRoleType(); for (int role : requireRole.value()) { if (roleType == role) { return true; } } throw new PermissionDeniedException("当前角色无权访问"); }

这里getCurrentUser是从ThreadLocal里取当前登录用户,这个用户对象在登录拦截器里已经被填充好了。注意一个问题:拦截器里只做了角色判断,没有做数据范围过滤,数据范围过滤必须在Service层处理。如果拦截器里同时做两件事,代码会变得非常长而且难以测试。这一层只保证“能不能访问”,至于“能看到哪些数据”由Service层的条件构造器决定。

4.3 数据权限的两种实用方案

数据权限是实习管理系统最容易做错的地方。某学校的A同学,第一次做系统时只做了接口权限,结果学生登录后调接口传入别人的applyId就能看到别人的周报内容——因为他没做数据归属校验。

第一种方案:显式传参过滤。在Service方法的查询条件里强制带上当前用户的departmentId或enterpriseId,数据从源头就只查本部门/本企业的。优点是逻辑直观,容易审查;缺点是每个查询方法都要多几个参数,代码上有一定的重复操作。

第二种方案:MyBatis-Plus的DataPermissionInterceptor,通过拦截器自动在SQL上追加部门条件。优点是省事,各业务方法不用显式传部门ID;缺点是排查问题时SQL被自动改写,初学者容易懵。我的建议是直接用第一种方案,毕业设计代码被老师逐行审查时不至于解释不清。数据隔离的底线要求是:学生只能操作自己名下的申请和周报,校内老师只能看到本学院的数据,企业导师只能看到分配到自己企业的学生数据。这三点在Service层用eq(字段, 用户ID)即可实现。

5. 毕业设计避坑指南:四段需要冷静处理的现场

5.1 实习跨年导致周报评估出错

现象:学生12月底提交的周报,周次显示为第1周,但实际上是第15周;1月初提交的周报,周次计算成负数或者直接报错。

原因:计算实习周数用的是(当前日期 - 开始日期) / 7,遇到跨年时如果按自然周解析,元旦那周不仅跨年还跨月,日期计算就会出现偏移,让人摸不着头脑。

解决:周数不要依赖实时日期计算。正确做法是:实习分配确认时,根据start_date计算出总共的周数并初始化各周的起止日期,存入实习周期表或直接在申请确认时写入周报的week_seq字段。学生提交周报时后端只校验week_seq是否超出总周数,不动态计算日期。具体到代码层面,可以使用YearWeek类或按WeekFields.of(Locale.CHINA)设置周一为一周的开始,避免默认周日为第一天带来的偏移。

5.2 文件上传只校验了后缀名

现象:学生上传实习报告时传了一个伪装成jpg的jsp文件,系统居然接受并允许访问,服务器直接被上传了一个网页木马。

原因:很多项目的上传校验只做了文件名后缀判断,比如filename.endsWith("jpg"),这种校验可以在一秒钟之内被绕过——修改文件扩展名是人人都会的操作。

解决:校验文件真实类型。图片文件读取文件头部的Magic Number,jpeg的头两个字节是0xFF 0xD8,png是0x89 0x50 0x4E 0x47,pdf是%PDF。用Java的InputStream读取前几个字节判断,不要用contentType判断,前端的Content-Type完全可以伪造。另外存储路径要使用UUID重命名,不允许保留原始文件名——很多攻击就是利用原始文件名中的路径穿越符../触发漏洞。

5.3 双击提交按钮产生了重复周报

现象:学生手速快或者网络慢时双击“提交周报”按钮,数据库里插入了两条内容完全相同的记录,状态都是待审核。

原因:前端没有做防重复提交,后端又没有唯一约束兜底。网络慢的时候第一个请求还没返回,第二个请求已经进来了,后端两个请求同时执行了count查询,都发现没有记录,于是都走了插入逻辑。

解决:双保险。前端提交后立即禁用按钮并设置一个isSubmitting标志;后端在internship_log表上加上uk_internship_week唯一索引,字段是(internship_id, week_seq),数据库层面拒绝重复插入。后端的唯一索引是最终防线,即使前端被绕过也不会产生脏数据。

5.4 导出Excel中文名乱码与内存溢出

现象:导出学生实习名单时,下载的文件名显示为%E5%AE%9E%E4%B9%A0%E5%90%8D%E5%8D%95.xlsx,打开文件后发现几百条数据导出卡顿,甚至服务直接OOM。

原因:文件名没有做URL编码处理,浏览器解析不了中文;导出时一次性把所有数据load进内存,再用POI写文件,数据量大时内存瞬间被打满。

解决:文件名设置时用URLEncoder.encode(filename, "UTF-8"),并把Content-Disposition设置为attachment; filename*=UTF-8''这种编码形式。导出数据改用分批查询,每查1000条就写入一次工作簿,用SXSSFWorkbook代替XSSFWorkbook,SXSSF会自动将已经写完的缓冲区刷到磁盘,内存占用从全量数据降到滚动窗口大小。

6. 进阶技巧与验收自检

如果时间充裕,我建议再补三个细节。第一,写一个演示数据生成器,通过CommandLineRunner在启动时检测数据库为空就自动插入几十个学生、几家企业、若干岗位和一批周报数据。答辩前把项目跑起来,页面上有数据,老师就不会觉得是个空壳系统。生成器要注意密码统一用BCrypt加密,不要明文插入数据库。第二,成绩权重配置化已经说过了,把企业评分占比和教师评分占比放到sys_config表,UI上做一个配置页面,让管理员能实时调整,这会成为答辩时的亮点。第三,实习报告导出用模板引擎,把实习基本信息、周报摘要、成绩明细填充到预制的Word模板中,生成完整报告。用POI手写文档流非常费时且不稳定,用模板占位符省事得多。

验收自查清单可以按三条业务主线走:学生视角,从注册、投递岗位、提交周报到查看成绩,整个流程是否畅通;教师视角,能否准确审核自己名下学生的周报和成绩,能否拒绝不规范的周报;管理员视角,能否查看全院系的实习进度统计数据,能否导出所需表格。这条链路跑通了,系统的核心价值就兑现了。

这里有一个代价与收益的权衡:不要一开始就追求微服务、分布式、消息队列这些工程化概念,毕业设计的核心是“能跑通、能讲清、能演示”。在你把所有模块跑通之后,再去考虑加Redis缓存和JWT拦截器,效果会好得多。我过去在某模拟项目里就是把成绩计算逻辑写在controller方法中,后来要加权重配置时改了三天,回看时头皮发麻。先设计好表结构和状态流转,再写代码,这个习惯真的能救命。希望这些经验和踩坑记录能帮你少走弯路,顺利把这个系统做出来。

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

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

Attention-GRU单维时序预测实战:原理、代码与调参详解

做时间序列预测的人迟早都会遇到这种需求&#xff1a;手头只有一列数值&#xff0c;没有外部特征&#xff0c;要预测未来几个时间步的走势。比如某个站点过去两年的用电负荷、某条管道的水位、某个业务的日活跃量&#xff0c;这种问题在行业里统一叫单维时序预测。我最初拿这类…

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

Java课设学生成绩管理系统:从三件套到JDBC排错与批量导入

简介&#xff1a;一套面向初学JavaWeb开发者的学生成绩管理系统实战项目&#xff0c;旨在帮助读者把Servlet、JSP、模型-视图-控制器设计模式与动态代理等知识串联起来&#xff0c;落实到登录认证、学生管理、课程管理、成绩录入等完整业务流程中。压缩包内有271个文件&#xf…

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

MATLAB原生PPO实现主动配电网电压控制

简介&#xff1a;本资源是一套基于MATLAB实现的深度强化学习&#xff08;DRL&#xff09;主动配电网电压控制策略完整方案&#xff0c;面向电气工程、智能电网方向的本科生与研究生&#xff0c;适用于毕业设计、课程设计及中小型科研项目开发。方案以IEEE33节点标准配电系统为仿…

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

list底层探秘:动态数组与链表的实现对比与选型

list这两个字&#xff0c;几乎所有写代码的人都用过。但真要说清楚它是什么、底层怎么实现的&#xff0c;能讲明白的人不算多。很多初学者把list当成一个“能装东西的盒子”就完事了&#xff0c;等到面试被问一句“Python的list和C的list有什么区别”&#xff0c;或者排查线上问…

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

AI生成代码的技术债:识别、规避与重构实战

最近我在帮一个老同学收拾他的项目&#xff0c;代码量不大&#xff0c;技术栈也不复杂&#xff0c;但翻出来的每一处改动都有同一个味道&#xff1a;AI写的。函数能跑&#xff0c;边界条件没人测过&#xff0c;异常处理约等于没有&#xff0c;注释里写着“这里逻辑先这样”。这…

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

快速上手InternVL3-1B-AWQ:从下载模型到图片问答的6步实战教程

【免费下载链接】InternVL3-1B-AWQ 项目地址&#xff1a; https://ai.gitcode.com/OpenGVLab/InternVL3-1B-AWQ 点击查看 免费下载 InternVL3-1B-AWQ 是 OpenGVLab 推出的 InternVL3-1B 多模态大模型的 AWQ 4-bit 量化版&#xff0c;能在单张消费级显卡上流畅完成图片问答、多…

作者头像 李华