news 2026/5/30 2:22:17

JavaWeb问卷系统实战工程:含完整源码、MySQL建库脚本与可直接运行的JSP页面

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaWeb问卷系统实战工程:含完整源码、MySQL建库脚本与可直接运行的JSP页面

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

简介:这个JavaWeb问卷系统是基于Servlet + JSP + MySQL开发的轻量级调查工具,不依赖Spring等框架,适合教学和入门实践。项目结构清晰,包含标准Maven配置(pom.xml),支持IDEA或Eclipse一键导入运行。功能覆盖用户登录验证、问卷新建与编辑、单选/多选/填空题型管理、答卷实时提交、结果统计查看等全流程操作。数据库使用MySQL,附带question.sql建表与初始化脚本,字段命名规范、关系明确,可快速部署。前端页面全部采用原生JSP+HTML+CSS+JavaScript实现,兼容Chrome/Firefox/Edge主流浏览器,无额外JS框架依赖。资源包内含src源码目录、web页面资源、WEB-INF配置文件、static静态资源、编译输出out目录,以及需求文档、README说明、数据库设计图(pdm.png)等辅助材料,方便理解整体架构与MVC分层逻辑。特别适合作为高校Java Web课程设计、毕业设计参考案例,也适合自学巩固Servlet生命周期、JSP内置对象、会话管理、JDBC连接等核心知识点。

1. 项目概述:为什么这个JavaWeb问卷系统值得你花30分钟认真读完

我带过六届Java Web课程设计,每年都有学生卡在“到底怎么把Servlet、JSP和MySQL串成一个能跑起来的完整系统”这一步。不是不会写单个登录Servlet,也不是不懂JSP怎么显示数据,而是当所有知识点散落在课本不同章节时,没人告诉你——数据库字段怎么命名才不踩外键陷阱?WEB-INF/web.xml里filter和servlet的加载顺序差一行就会导致登录拦截失效?JSP里用 还是直接request.getAttribute()更利于调试?这套问卷系统,就是我从2018年至今在实验室反复打磨、给三届学生手把手调通后沉淀下来的“最小可运行MVC骨架”。它不炫技,没有Spring Boot自动配置的魔法,所有代码都裸露在src目录下,连JDBC连接池都用最朴素的BasicDataSource手动管理;但它足够真实——你导入IDEA后点Run,首页index.jsp弹出来那一刻,后台Tomcat日志里刷出的那几行“[INFO] QuestionDaoImpl - Loaded 3 questions from DB”,就是教科书上“三层架构”四个字最踏实的注脚。关键词里的“JavaWeb问卷”“Servlet问卷系统”不是虚名:用户登录走的是HttpSession会话验证,问卷提交用的是标准POST表单+request.getParameterValues()处理多选题数组,结果统计页面甚至用原生JSTL的 遍历Map 计数结果——这些细节,正是初学者理解“请求-响应生命周期”的最佳沙盒。如果你正为课程设计发愁,或者想亲手拆解一个不依赖框架的MVC系统如何呼吸,那么接下来的5000字,就是你跳过所有弯路的直达电梯。

2. 整体架构与技术选型逻辑:为什么坚持不用Spring,而选择“原始”技术栈

2.1 技术栈决策背后的教学深意

这套系统的技术组合(Servlet 4.0 + JSP 2.3 + MySQL 8.0 + Maven 3.8)看似“复古”,实则是刻意为之的教学设计。我曾对比过Spring Boot版本的问卷系统:学生导入后能秒启动,但当ta想搞懂“为什么点击提交按钮后,数据会跑到数据库里”,就得钻进@Controller注解背后层层代理、事务管理器、自动装配的迷宫。而本项目中,一个完整的业务闭环清晰可见:
-前端触发:index.jsp里的


-后端承接:web.xml中 /SubmitServlet 映射到SubmitServlet.java
-数据落地:SubmitServlet中new QuestionService().submitAnswer(request) → 调用QuestionDaoImpl.executeUpdate(“INSERT INTO answer…”)
这种线性链条,让每个环节的输入输出都肉眼可见。比如,当学生发现提交后页面空白,ta会立刻检查SubmitServlet的doPost()里是否漏写了response.sendRedirect(“success.jsp”)——而不是去翻Spring的@ResponseStatus配置。

2.2 目录结构即架构说明书

资源包里的目录树不是随意排列,而是MVC分层思想的物理映射:

src/ ├── main/ │ ├── java/ │ │ └── com/example/question/ │ │ ├── controller/ // Servlet入口:LoginServlet, CreateQuestionServlet │ │ ├── service/ // 业务逻辑:QuestionService, AnswerService │ │ ├── dao/ // 数据访问:QuestionDaoImpl, AnswerDaoImpl │ │ └── model/ // 实体类:Question, Option, Answer │ └── resources/ // JDBC配置:db.properties web/ ├── index.jsp // 视图层起点 ├── login.jsp // 登录视图 ├── create_question.jsp // 问卷编辑视图 ├── WEB-INF/ // 安全边界:web.xml, web.xml中定义的JSP无法被直接URL访问 │ ├── web.xml // 核心配置:servlet-mapping, filter, context-param │ └── lib/ // 依赖jar包(已由Maven管理,此处为兼容旧版Tomcat) static/ ├── css/ // 原生CSS:reset.css, style.css(无Bootstrap) └── js/ // 原生JS:form-validator.js(仅校验邮箱格式)

特别注意WEB-INF的不可直访特性:当你在浏览器输入http://localhost:8080/WEB-INF/web.xml,Tomcat会返回404——这是Servlet规范强制的安全机制,也是学生理解“为什么JSP要放在WEB-INF外而配置文件必须放里面”的第一课。

2.3 Maven依赖精简哲学

pom.xml中仅保留4个核心依赖:

<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> <!-- Tomcat已提供,编译时需要,运行时不打包 --> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>

没有MyBatis的XML映射文件,没有Log4j的复杂配置——所有SQL都写在DAO实现类的字符串里。这么做不是拒绝现代化工具,而是让学生看清:ORM框架本质是把SQL字符串封装成方法调用,而本项目中,那句”SELECT * FROM question WHERE status=1”就明晃晃躺在QuestionDaoImpl.java第47行。当学生亲手把ResultSet逐列getXXX()赋值给Question对象时,ta才真正理解了“对象关系映射”五个字的重量。

3. 数据库设计与question.sql脚本深度解析:字段命名如何避免“删库跑路”式错误

3.1 表结构设计的三个反直觉细节

question.sql脚本创建了5张表:user,questionnaire,question,option,answer。表面看是标准的一对多关系,但有三个关键设计点常被初学者忽略:

第一,user表的password字段长度设为64而非32

CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL, -- 注意:不是32! email VARCHAR(100), created_time DATETIME DEFAULT CURRENT_TIMESTAMP );

原因在于:系统采用SHA-256算法加密密码(见LoginServlet.java第82行),其十六进制字符串长度恒为64位。若此处设为VARCHAR(32),当用户密码加密后存入时会被截断,导致后续登录永远失败。我在指导学生时总强调:“数据库字段长度不是拍脑袋定的,它必须和你的加密算法输出长度严格对齐。”

第二,question表的sort_order字段类型为TINYINT而非INT

CREATE TABLE question ( id INT PRIMARY KEY AUTO_INCREMENT, questionnaire_id INT NOT NULL, content TEXT NOT NULL, type ENUM('single', 'multiple', 'text') NOT NULL, sort_order TINYINT NOT NULL DEFAULT 0, -- 问卷内题目排序,0-255足够 FOREIGN KEY (questionnaire_id) REFERENCES questionnaire(id) );

这里用TINYINT(-128~127)而非默认的INT(-21亿~21亿),既是空间优化(每条记录省3字节),更是业务约束:一份问卷题目通常不超过50道,用TINYINT能天然防止“sort_order=1000000”这种明显异常值入库。

第三,answer表的复合主键设计

CREATE TABLE answer ( user_id INT NOT NULL, question_id INT NOT NULL, option_id INT NULL, -- 单选/多选时关联option,填空题为NULL text_answer TEXT NULL, -- 填空题内容,单选/多选时为NULL submit_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, question_id, option_id), -- 复合主键防重复提交 FOREIGN KEY (user_id) REFERENCES user(id), FOREIGN KEY (question_id) REFERENCES question(id), FOREIGN KEY (option_id) REFERENCES option(id) );

复合主键(user_id, question_id, option_id)确保同一用户对同一道题不能重复选择同一选项(如用户ID=1对题目ID=5选了选项ID=10两次)。这个设计直接规避了“用户狂点提交按钮导致答案重复计数”的经典并发问题,比在Servlet里加synchronized块更底层、更可靠。

3.2 初始化脚本的隐藏陷阱与修复方案

question.sql末尾的INSERT语句包含一个易被忽略的坑:

INSERT INTO user (username, password, email) VALUES ('admin', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', 'admin@example.com');

该密码哈希值对应明文”123456”,但若学生直接复制此SQL到MySQL命令行执行,可能因字符集问题导致哈希值存储异常。实测解决方案:
1. 在MySQL客户端执行SET NAMES utf8mb4;
2. 然后执行question.sql全文
3. 验证:SELECT HEX(password) FROM user WHERE username='admin';应返回8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92(全大写无空格)
这个细节在README.md里没写,却是学生部署失败的最高频原因——因为MySQL 8.0默认字符集已改为utf8mb4,而旧版脚本未显式声明。

3.3 外键约束的实战价值:当删除问卷时,答案数据如何自毁

在questionnaire表的DELETE操作中,外键级联被精心设计:

ALTER TABLE question ADD CONSTRAINT fk_question_questionnaire FOREIGN KEY (questionnaire_id) REFERENCES questionnaire(id) ON DELETE CASCADE;

这意味着:当管理员在后台删除一份问卷(DELETE FROM questionnaire WHERE id=100),数据库会自动触发级联删除——所有question表中questionnaire_id=100的题目、所有option表中关联这些题目的选项、所有answer表中关联这些题目的答案,全部被清空。这种设计避免了“问卷删了但答案还留在库里”的数据不一致,也省去了在QuestionService.deleteQuestionnaire()方法里手动编写四层循环删除的繁琐代码。我在课堂演示时,会让学生先查SELECT COUNT(*) FROM answer;,再删问卷,再查一次——数字归零的瞬间,就是ACID原则最直观的呈现。

4. 核心功能模块实现详解:从登录拦截到结果统计的全流程代码拆解

4.1 登录验证的双重保险机制

系统未使用Spring Security,而是通过Filter+Session实现轻量级权限控制。关键代码在src/main/java/com/example/question/filter/LoginFilter.java

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; // 白名单:允许未登录访问的资源 String uri = req.getRequestURI(); if (uri.endsWith("/login.jsp") || uri.endsWith("/LoginServlet") || uri.endsWith("/static/")) { chain.doFilter(request, response); return; } // 黑名单拦截:检查Session中是否存在user属性 HttpSession session = req.getSession(false); if (session == null || session.getAttribute("user") == null) { resp.sendRedirect(req.getContextPath() + "/login.jsp?error=not_logged_in"); return; } chain.doFilter(request, response); }

这个Filter的精妙之处在于白名单优先策略:即使你忘了在web.xml中配置filter-mapping,只要/login.jsp和LoginServlet不在拦截链里,系统就不会陷入“重定向循环”。我在调试时曾故意注释掉web.xml中的filter配置,结果发现登录页仍能正常打开——这证明了防御性编程的价值。

4.2 问卷创建的动态表单生成逻辑

create_question.jsp页面的题目添加功能,不依赖JavaScript框架,而是用纯JSP+HTML实现:

<!-- 动态添加题目区域 --> <div id="questions-container"> <div class="question-block"> <input type="text" name="question_content_1" placeholder="请输入题目内容" required> <select name="question_type_1" onchange="toggleOptions(this, 1)"> <option value="single">单选题</option> <option value="multiple">多选题</option> <option value="text">填空题</option> </select> <div id="options-1" class="options-group" style="display:none;"> <input type="text" name="option_content_1_1" placeholder="选项A"> <input type="text" name="option_content_1_2" placeholder="选项B"> </div> </div> </div> <button type="button" onclick="addQuestion()">+ 添加新题目</button>

关键在toggleOptions()函数(位于static/js/form-validator.js):

function toggleOptions(select, index) { const optionsDiv = document.getElementById('options-' + index); if (select.value === 'text') { optionsDiv.style.display = 'none'; // 清空该题目下所有选项输入框的值,防止填空题提交时混入空选项 const inputs = optionsDiv.querySelectorAll('input'); inputs.forEach(input => input.value = ''); } else { optionsDiv.style.display = 'block'; } }

这个设计解决了初学者常犯的错误:当用户创建填空题后又切换回单选题,若不清空选项框,后端接收到的request.getParameter("option_content_1_1")可能是空字符串,导致插入数据库时报错。我在批改作业时,看到过太多学生在这里栽跟头。

4.3 答卷提交的原子性保障

SubmitServlet.java中的核心逻辑:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = null; PreparedStatement pstmt = null; try { conn = DataSourceUtil.getConnection(); // 从DBCP连接池获取 conn.setAutoCommit(false); // 关键:开启事务 // 步骤1:插入answer主记录(填空题) String sql1 = "INSERT INTO answer(user_id, question_id, text_answer) VALUES(?, ?, ?)"; pstmt = conn.prepareStatement(sql1); pstmt.setInt(1, userId); pstmt.setInt(2, questionId); pstmt.setString(3, request.getParameter("text_answer")); pstmt.executeUpdate(); // 步骤2:插入answer_option关联记录(单选/多选) String[] selectedOptions = request.getParameterValues("option_id"); if (selectedOptions != null && selectedOptions.length > 0) { String sql2 = "INSERT INTO answer(user_id, question_id, option_id) VALUES(?, ?, ?)"; pstmt = conn.prepareStatement(sql2); for (String optionId : selectedOptions) { pstmt.setInt(1, userId); pstmt.setInt(2, questionId); pstmt.setInt(3, Integer.parseInt(optionId)); pstmt.executeUpdate(); } } conn.commit(); // 所有步骤成功才提交 response.sendRedirect("result.jsp?success=1"); } catch (SQLException e) { if (conn != null) { try { conn.rollback(); } catch (SQLException ex) { /* 忽略回滚异常 */ } } request.setAttribute("error", "提交失败:" + e.getMessage()); request.getRequestDispatcher("error.jsp").forward(request, response); } finally { DataSourceUtil.close(pstmt, conn); // 确保连接归还池 } }

这里体现了两个关键实践:
-事务边界精准控制:只包裹真正的业务操作(INSERT),不包含request.getParameter()等非数据库操作,避免事务过长阻塞连接池;
-连接池资源兜底:finally块中强制关闭PreparedStatement和Connection,即使发生异常也能保证连接被释放——这是学生项目中最容易引发“连接耗尽”的地方。

4.4 结果统计的JSTL原生实现

result.jsp页面用JSTL标签库实现饼图数据生成,完全不依赖ECharts:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <!-- 计算各选项占比 --> <c:set var="totalAnswers" value="${fn:length(answerList)}"/> <c:forEach items="${optionList}" var="option"> <c:set var="optionCount" value="0"/> <c:forEach items="${answerList}" var="answer"> <c:if test="${answer.optionId == option.id}"> <c:set var="optionCount" value="${optionCount + 1}"/> </c:if> </c:forEach> <c:set var="percentage" value="${(optionCount * 100) / totalAnswers}"/> <!-- 输出JSON格式数据供前端渲染 --> {"option":"${option.content}","count":${optionCount},"percentage":${percentage}}, </c:forEach>

这段代码的巧妙在于:它把复杂的百分比计算逻辑完全交给JSTL在服务端完成,前端JavaScript只需解析JSON数组并绘制简单SVG圆环。我在课堂上对比过:用jQuery AJAX异步请求数据再渲染,学生要调试跨域、JSON解析、DOM插入三重问题;而本方案把计算压力卸载到服务端,前端只剩10行SVG代码——这才是教学项目的务实选择。

5. 实操部署与常见问题排查:从IDEA导入到生产环境避坑指南

5.1 IDEA一键导入的5个关键确认点

学生常以为“File → Open → 选pom.xml”就万事大吉,实际需手动验证以下5点:

检查项正确配置错误表现解决方案
Project SDKJDK 11或更高版本编译报错“lambda表达式不支持”File → Project Structure → Project → Project SDK选JDK 11+
Tomcat Server本地安装Tomcat 9.0+启动时报“Cannot run program ‘catalina.bat’”Run → Edit Configurations → Tomcat Server → Configure → 选Tomcat安装目录
Artifactsweb-application exploded访问http://localhost:8080/显示404Project Structure → Artifacts → + → Web Application: Exploded → From modules → 选main module
Database URLjdbc:mysql://localhost:3306/question?serverTimezone=Asia/Shanghai登录时报“Unknown system variable ‘tx_isolation’”修改src/main/resources/db.properties中的url,添加serverTimezone参数
Static Resourcesweb/static/css/style.css路径正确页面样式丢失,F12看Network显示404确认web.xml中 的 是否覆盖/static/*,或检查IDEA的Artifact输出路径是否包含static目录

我在实验室发现,80%的“导入失败”问题都集中在第4项——MySQL 8.0的时区变更导致JDBC驱动报错。解决方案不是降级MySQL,而是精准添加serverTimezone=Asia/Shanghai参数,这比修改MySQL全局时区配置更安全。

5.2 浏览器兼容性调试实录

系统宣称支持Chrome/Firefox/Edge,但实际测试发现一个IE11专属Bug:
-现象:在IE11中点击“提交问卷”按钮,页面卡死,F12控制台报错“Object doesn’t support property or method ‘forEach’”
-根因:static/js/form-validator.js中使用了Array.prototype.forEach(),而IE11不支持该方法
-修复:在js文件顶部添加Polyfill:

// IE11兼容forEach if (!Array.prototype.forEach) { Array.prototype.forEach = function(callback, thisArg) { for (var i = 0; i < this.length; i++) { callback.call(thisArg, this[i], i, this); } }; }

这个修复方案比引入整个Babel Polyfill更轻量,且不影响现代浏览器性能。我在毕业答辩现场,曾用IE11打开系统演示,当评委看到“兼容性”字样时露出质疑表情,而我敲出这段代码后页面立刻恢复正常——这就是工程化思维的价值。

5.3 生产环境部署的3个硬性要求

若将本系统部署到阿里云ECS等生产环境,必须调整以下配置:

第一,数据库密码加密
当前db.properties中密码明文存储:

jdbc.password=123456

生产环境必须改为:

jdbc.password=${DB_PASSWORD} # 通过JVM参数传入:-DDB_PASSWORD=your_real_password

并在DataSourceUtil.java中读取:

String password = System.getProperty("DB_PASSWORD", props.getProperty("jdbc.password"));

第二,静态资源CDN化
将web/static/目录下的所有CSS/JS文件上传至OSS,然后在JSP中替换引用:

<!-- 原来 --> <link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/style.css"> <!-- 改为 --> <link rel="stylesheet" href="https://your-bucket.oss-cn-hangzhou.aliyuncs.com/css/style.css">

第三,Session持久化配置
Tomcat默认将Session存在内存,重启即丢失。生产环境需配置Redis:
1. 添加依赖:redis.clients:jedis:3.9.0
2. 修改web.xml,添加<distributable/>标签
3. 在context.xml中配置Redis集群地址
这个改造能让系统支持水平扩展,当用户量激增时,只需增加Tomcat实例即可——这才是企业级应用的起点。

6. 教学延伸与能力跃迁:如何把这个项目变成你的技术跳板

这个问卷系统绝不是终点,而是你技术成长的起跳板。我指导过的优秀学生,都基于它完成了三个层次的跃迁:

第一层:夯实基础(1周内可完成)
- 给所有Servlet添加日志:在doGet/doPost开头加入System.out.println("[DEBUG] " + this.getClass().getSimpleName() + " received request from " + request.getRemoteAddr());
- 为数据库操作添加执行时间监控:在DAO方法中用long start = System.currentTimeMillis();System.out.println("Query executed in " + (System.currentTimeMillis()-start) + "ms");
- 这些改动看似简单,却让你第一次看清“一次HTTP请求在服务器内部流转了哪些环节”,这是理解分布式链路追踪(如SkyWalking)的前置知识。

第二层:架构升级(2周挑战)
- 将JDBC手动管理替换为MyBatis:保留原有SQL逻辑,仅将QuestionDaoImpl.java改为继承SqlSessionDaoSupport,用getSqlSession().selectList("questionMapper.selectAll")替代原生ResultSet遍历。
- 这个过程会暴露MyBatis的核心矛盾:XML映射文件中<resultMap>的column与property映射错误,会导致对象属性为null——而这个问题在原生JDBC中根本不存在。解决它,你就掌握了ORM框架的元认知。

第三层:工程化实战(毕业设计级)
- 接入微信小程序前端:用uni-app重写前端,后端保持Servlet不变,仅需将response.setContentType("application/json");并输出JSON格式数据。
- 这个改造迫使你直面跨域问题:小程序域名白名单限制导致Ajax请求被拦截。解决方案是配置Nginx反向代理,将https://api.yourdomain.com/question转发到http://localhost:8080/question——此时你写的不再是“Hello World”,而是真实的微服务网关雏形。

最后分享一个真实案例:去年一位学生在本项目基础上,增加了“问卷定时发布”功能。他没用Quartz,而是用ServletContextListener监听Tomcat启动,在contextInitialized()中启动一个ScheduledExecutorService,每分钟扫描questionnaire表的publish_time字段。当发现publish_time <= NOW()status=0时,自动更新状态为1。这个方案代码不足50行,却完美满足了课程设计“创新性”要求,最终获得优秀答辩。所以,请记住:最好的学习,永远发生在你为解决真实问题而主动搜索、调试、重构的每一分钟里。

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

简介:这个JavaWeb问卷系统是基于Servlet + JSP + MySQL开发的轻量级调查工具,不依赖Spring等框架,适合教学和入门实践。项目结构清晰,包含标准Maven配置(pom.xml),支持IDEA或Eclipse一键导入运行。功能覆盖用户登录验证、问卷新建与编辑、单选/多选/填空题型管理、答卷实时提交、结果统计查看等全流程操作。数据库使用MySQL,附带question.sql建表与初始化脚本,字段命名规范、关系明确,可快速部署。前端页面全部采用原生JSP+HTML+CSS+JavaScript实现,兼容Chrome/Firefox/Edge主流浏览器,无额外JS框架依赖。资源包内含src源码目录、web页面资源、WEB-INF配置文件、static静态资源、编译输出out目录,以及需求文档、README说明、数据库设计图(pdm.png)等辅助材料,方便理解整体架构与MVC分层逻辑。特别适合作为高校Java Web课程设计、毕业设计参考案例,也适合自学巩固Servlet生命周期、JSP内置对象、会话管理、JDBC连接等核心知识点。


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

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

单片机伺服电机加减速控制子程序

该代码实现了一个电机自动加减速控制程序。通过设置加减速标志MtAdDc_FLAG&#xff0c;程序分为加速和减速两个阶段&#xff1a;加速时根据运行距离分三个阶段调整速度&#xff08;3mm内3倍延时、3-20mm内2倍延时、20mm以上正常速度&#xff09;&#xff1b;减速时根据剩余距离…

作者头像 李华
网站建设 2026/5/30 2:19:22

如何永久保存微信聊天记录:3步打造个人数字记忆库

如何永久保存微信聊天记录&#xff1a;3步打造个人数字记忆库 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg…

作者头像 李华
网站建设 2026/5/30 2:16:48

NetcoreKevin:.NET 企业级智能体管理框架

NetcoreKevin&#xff1a;.NET 企业级智能体管理框架 1. 框架简介 NetcoreKevin 是一款基于 .NET 8 的企业级智能体&#xff08;AI Agent&#xff09;管理框架&#xff0c;为团队提供智能体 Skill 与工具的可视化编排能力&#xff0c;并通过细粒度的角色权限体系实现智能体的…

作者头像 李华
网站建设 2026/5/30 2:15:55

定了!创想三维明日上市,12周年新品齐发

据了解&#xff0c;创想三维将于2026年5月29日正式在香港交易所挂牌上市&#xff08;股份代号&#xff1a;03388.HK&#xff0c;发行价&#xff1a;18.80港元&#xff09;&#xff0c;成为消费级3D打印领域第一股。同日&#xff0c;公司还将举办以“AI生态”为主题的12周年新品…

作者头像 李华