新闻详情

新闻详情

首页 / 资讯中心 / 详情

JSP+Servlet+MySQL学生成绩管理系统实战:从环境搭建到部署全解析

发布时间:2026/10/1 14:55:48来源:尧图网络
JSP+Servlet+MySQL学生成绩管理系统实战:从环境搭建到部署全解析
1. 老技术新问题这个成绩管理系统到底要解决什么JSP Servlet Bootstrap MySQL这个组合放到2025年看确实不算新潮——Spring Boot 已经占领了绝大多数新项目的默认起点。但在学校里的课程设计、毕业设计以及不少老单位正在运行的教务系统里这套技术栈依然是实打实的生产主力。我见过太多学生拿着学生成绩管理系统这个题目直接照着一个 Spring Boot 课程视频改改就交了结果问 Servlet 生命周期、Session 原理、JDBC 连接池是什么一脸茫然。反而那些老老实实用 JSP Servlet 把每一个请求、每一次数据库操作都摸清楚的人后面学框架的时候速度和质量都明显吊打前者。这个项目的核心需求非常明确给教务处提供一个管理学生、课程、成绩的 Web 系统学生能查成绩教师能录成绩管理员能统筹全部数据。听起来功能不多但仔细拆一遍它天然覆盖了 JavaWeb 最关键的几个知识点三层架构设计、Servlet 生命周期、JSP 九大内置对象、四大作用域、JDBC 编程、数据库连接池、Filter 拦截器、EL 表达式和 JSTL 标签库。任何一个环节没搞懂系统跑起来就会出各种莫名其妙的 bug。所以这篇文章我不打算给你贴一个完整源码让你直接复制交差了事。我想把它当成一个完整的工程案例从技术选型的思考、环境搭建的参数细节、后端分层的代码写法到前端 Bootstrap 整合、打包部署的完整流程把每一步的关键决策和踩坑点都讲清楚。这篇文章适合三类人正在做 JavaWeb 课程设计的学生、想补传统 JavaWeb 技术细节的框架使用者、以及需要维护老项目的初级开发。看完你不仅能把这套系统跑起来还能明白它为什么这么设计。2. 从零搭环境IDEA配置JavaWeb项目与MySQL一次跑通先说句实话这个项目超过三分之一的坑都出在环境搭建阶段。代码还没写几行光是在 IDEA 里把 Tomcat 跑起来、让 MySQL 连上就劝退了不少人。所以环境这部分我讲得细一点版本搭配、参数配置、可能出现的报错一次性说清楚后面你照着做基本能一把过。2.1 环境版本怎么搭配才不折腾我自己在教学中验证过很多套组合最省心的搭配是这样的JDK 1.8真的不用上 17传统 JavaWeb 项目上 17 反而容易出现各种兼容问题、IDEA 2023 或 2024 版本、Tomcat 8.5、MySQL 5.7 或者 8.0 都行。这里有个重要提醒如果选 MySQL 8.0连接驱动必须用mysql-connector-java 8.0.x别用老旧的 5.1.x 驱动硬怼不然会报 SSL 连接错误或者Public Key Retrieval is not allowed这类问题。具体版本对照我整理在下面照着配可以少踩很多坑。软件推荐版本选择理由与注意点JDK1.88u202兼容 Tomcat 8.5 和传统 JSP/Servlet 规范避免新版本模块化限制IDEA2023.x 或 2024.x自带 Tomcat 集成社区版也够用但配置稍微绕建议 UltimateTomcat8.5.x对应 Servlet 3.1 规范支持 JSP 2.3对传统项目最友好MySQL5.7 或 8.08.0 注意时区参数5.7 直接一把梭驱动mysql-connector-java 8.0.338.0 数据库必须配 8.x 驱动5.7 用 5.1.49 也行提醒一点如果之前机器上装过 MySQL 5.7这次想换 8.0卸载时一定记得把数据目录、服务注册、环境变量全部清理干净不然net start mysql经常会报服务无法启动大概率就是注册表和残留目录冲突了。2.2 数据库建库脚本与连接串的关键细节数据库设计是整个系统的地基。我习惯按照学生、教师、课程、成绩、班级这五张核心表来做教务系统的典型场景就齐了。设计时要注意学生表里加班级字段或者单独拆班级表都有道理我建议拆出来因为后续做按班级查成绩汇总会特别方便。建库脚本核心部分长这样CREATE DATABASE edu_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE edu_system; CREATE TABLE tb_student ( id INT PRIMARY KEY AUTO_INCREMENT, stu_no VARCHAR(20) NOT NULL UNIQUE COMMENT 学号, stu_name VARCHAR(50) NOT NULL COMMENT 姓名, gender CHAR(1) DEFAULT 男, class_id INT COMMENT 班级外键, created_time DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE tb_course ( id INT PRIMARY KEY AUTO_INCREMENT, course_no VARCHAR(20) NOT NULL UNIQUE, course_name VARCHAR(100) NOT NULL, credit INT DEFAULT 2 ); CREATE TABLE tb_score ( id INT PRIMARY KEY AUTO_INCREMENT, stu_id INT NOT NULL, course_id INT NOT NULL, score DECIMAL(5,2), exam_type VARCHAR(20) DEFAULT 期末, FOREIGN KEY (stu_id) REFERENCES tb_student(id), FOREIGN KEY (course_id) REFERENCES tb_course(id), UNIQUE KEY uk_stu_course (stu_id, course_id) );字符集这里我用的是utf8mb4而不是utf8原因很简单MySQL 的utf8最多只能存 3 字节的字符碰上生僻字或者部分特殊符号会直接报错utf8mb4才是完整兼容 Unicode 的。JSP 页面里也保持 UTF-8然后在 JDBC 连接串里再指定一遍三层统一后中文乱码问题能省掉一半。JDBC 连接串我推荐直接这么写注意characterEncoding、serverTimezone和useSSL这三个参数String url jdbc:mysql://localhost:3306/edu_system?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8mb4allowPublicKeyRetrievaltrue;useSSLfalse本地开发不需要走 SSL 证书避免握手报错serverTimezoneAsia/ShanghaiMySQL 8.0 默认时区和本地系统不一致时会报错指定之后一劳永逸allowPublicKeyRetrievaltrueMySQL 8.0 配合 caching_sha2_password 认证插件时的必选项不加就报访问被拒绝characterEncodingutf8mb4和数据库、页面三级统一彻底根治中文乱码。2.3 IDEA部署Tomcat的完整配置流程IDEA 里跑 JavaWeb 项目很多新手卡在不知道项目怎么才能访问到。传统 JavaWeb 项目在 IDEA 里的部署逻辑和 Spring Boot 完全不同Spring Boot 内嵌容器点运行就行JSP Servlet 项目必须手动把 Web 项目打包或爆炸目录部署进 Tomcat 的 webapps 下再启动。具体步骤是这样的新建项目时选择 Java Enterprise勾选 Web Application这样 IDEA 会生成标准的web/WEB-INF目录结构打开 Run/Debug Configurations点加号选择 Tomcat Server - Local在 Deployment 标签页点加号选择 Artifact通常用项目名:war explodedApplication context 填/或者/edu_system推荐后者方便后面部署多个项目不冲突回到 Server 标签页确认 HTTP port 默认 8080如果被占用改成 8081 就行端口冲突是非常常见的问题。明说一个经验如果不是特殊需要建议用 war exploded 而不是 war 包。exploded 模式本质是把编译后的目录直接映射到 Tomcat支持 JSP 修改后刷新即生效开发体验比打 war 包热部署舒服太多。等最后要部署到服务器再手动打成 war 包也不迟。配置完成后点运行IDEA 会自动启动 Tomcat 并打开浏览器访问你的项目路径。如果能看到默认的 index.jsp 页面环境就通了。3. 后端核心代码Servlet生命周期、DAO与三层架构落地环境通了之后接下来的核心就是把后端代码写清楚。我不打算把所有代码全文贴出来那样文章会变成代码仓库。我挑四个最核心、最影响整体质量的点来说Servlet 生命周期如何体现在项目里、数据库连接池封装与 DAO 层写法、登录认证与 Session 机制、成绩分页查询的 Servlet 实现。这四个点吃透了整个系统的主干就通了。3.1 Servlet生命周期到底怎么体现在项目里面试和考试总爱问 Servlet 生命周期很多人背得滚瓜烂熟但真到写代码的时候就忘了。其实这个概念非常简单Servlet 从创建到销毁一共经历三个阶段——init、service、destroy。init 在容器启动后首次收到请求时被调用且只调用一次适合做资源初始化service 每次请求都会进来负责分发到 doGet 或 doPostdestroy 在项目停止或 Servlet 移除时调用适合释放资源。在这个系统里我实际用到了这个生命周期的地方有两个。第一个是在登录接口里重写了init()方法读取初始化参数比如验证码开关虽然这个项目里我直接用硬编码了但这是一个很好的扩展点第二个是在整个应用层面我用 ServletContextListener 来初始化 Druid 连接池而不是在每次请求里新建数据库连接。你写代码的时候要有这个意识一切只需要初始化一次的资源都应该放进 init 或者 context 生命周期里而不是丢到每次请求的处理逻辑中。看一个最典型的登录 Servlet感受一下 doGet 和 doPost 的分工WebServlet(/login) public class LoginServlet extends HttpServlet { Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { request.getRequestDispatcher(login.jsp).forward(req, resp); } Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username req.getParameter(username); String password req.getParameter(password); User user userDao.findByUsernameAndPassword(username, password); if (user ! null) { req.getSession().setAttribute(loginUser, user); if (admin.equals(user.getRole())) { resp.sendRedirect(admin/index.jsp); } else { resp.sendRedirect(student/index.jsp); } } else { req.setAttribute(errorMsg, 用户名或密码错误); req.getRequestDispatcher(login.jsp).forward(req, resp); } } }这里必须解释一个很多新手绕不清的点为什么登录失败用 forward而登录成功用 sendRedirect因为 forward 是服务器内部的请求转发浏览器地址栏不会变request 域里的errorMsg还能传给 JSP 显示sendRedirect 是让浏览器重新发起一次请求地址栏会变成目标路径能避免刷新页面弹窗提示确认重新提交表单。这正是 request 作用域和 session 作用域的典型使用场景一次性提示消息用 request跨页面保持登录状态用 session。3.2 数据库连接池封装与 DAO 层写法传统 JDBC 编程最容易被喷的问题就是每次请求都DriverManager.getConnection()这个操作非常昂贵性能差不说连接数一多数据库直接扛不住。所以这个项目我直接用 Druid 连接池。Druid 是国产的开源连接池组件监控页面和 SQL 日志对调试特别友好配置文件放在src/druid.propertiesdriverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/edu_system?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8mb4allowPublicKeyRetrievaltrue usernameroot password123456 initialSize5 maxActive20 maxWait60000然后在项目里写一个 DBUtil 工具类用静态代码块加载配置把getConnection()和close()封装好。这里用静态代码块其实就体现了 Servlet 生命周期思想在普通 Java 里的延伸连接池是整个应用共享的资源初始化一次就够了。public class DBUtil { private static DruidDataSource dataSource; static { try { Properties props new Properties(); props.load(DBUtil.class.getClassLoader().getResourceAsStream(druid.properties)); dataSource (DruidDataSource) DruidDataSourceFactory.createDataSource(props); } catch (Exception e) { throw new ExceptionInInitializerError(数据库连接池初始化失败); } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }DAO 层写法的核心准则就一条一个方法只做一件事SQL 全部用 PreparedStatement 预编译参数用?占位。这里我不厌其烦地强调不要在 DAO 里拼字符串 SQLSQL 注入的教训太多尤其在成绩管理系统这种登录和查询场景密集的项目里拼字符串等于把数据库裸奔给人看。看一个典型的查询方法public ListScoreVO findScorePage(int pageNo, int pageSize) { ListScoreVO list new ArrayList(); String sql SELECT s.stu_no, s.stu_name, c.course_name, sc.score FROM tb_score sc JOIN tb_student s ON sc.stu_id s.id JOIN tb_course c ON sc.course_id c.id ORDER BY sc.id DESC LIMIT ?, ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, (pageNo - 1) * pageSize); ps.setInt(2, pageSize); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { ScoreVO vo new ScoreVO(); vo.setStuNo(rs.getString(stu_no)); vo.setStuName(rs.getString(stu_name)); vo.setCourseName(rs.getString(course_name)); vo.setScore(rs.getBigDecimal(score)); list.add(vo); } } } catch (SQLException e) { e.printStackTrace(); } return list; }LIMIT ? 分页参数的计算是个高频易错点第一页是(1 - 1) * pageSize 0从第 0 条开始取第二页是(2 - 1) * pageSize pageSize跳过第一页。注意这里用try-with-resources把 Connection、PreparedStatement、ResultSet 三个资源都自动关闭了不会因为忘写 close 导致连接泄漏。3.3 登录认证与成绩分页的Servlet实现登录功能是这个系统最核心的拦截点。光在登录 Servlet 里判断用户名密码还不够你还得保证没登录的人不能直接访问管理页面不同角色的人不能互相越权。这个需求用 Filter 过滤器来做最优雅。写一个 LoginFilter拦截所有/admin/*和/student/*路径的请求检查 session 里有没有用户对象没有就重定向回登录页WebFilter(urlPatterns {/admin/*, /student/*}) public class AuthFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; HttpSession session req.getSession(false); Object loginUser (session ! null) ? session.getAttribute(loginUser) : null; if (loginUser null) { resp.sendRedirect(req.getContextPath() /login.jsp); return; } chain.doFilter(request, response); } }整个请求流转的链路是这样的浏览器发起请求 - Tomcat 接收 - 经过 Filter 过滤器链 - 匹配到对应 Servlet 的 service 方法 - 根据请求方式分发到 doGet/doPost - Servlet 调 DAO 查询数据 - 把结果放进 request 域 - forward 到 JSP 渲染 - JSP 返回 HTML。这个链路在框架里被隐藏得太深很多只学过 Spring Boot 的开发真不知道请求经过了什么。但在传统 JavaWeb 里每一步都是代码里实打实看得见的这也是我推荐学生做这个项目的原因。成绩查询我做了分页分页算法本身不复杂但很值得掌握。前端传 pageNo 和 pageSize默认 pageNo1、pageSize10后端先查总记录数计算出总页数再查当前页数据把数据、当前页、总页数全部塞进 request 域跳转到 JSP。总页数的计算就一行int totalPages (int) Math.ceil(totalCount * 1.0 / pageSize);这里用Math.ceil向上取整保证最后不满一页的数据也能有单独的一页展示。4. 前端页面JSP Bootstrap整合的实用写法后端写得再好页面一塌糊涂也不行。Bootstrap 在这个项目里的定位是低成本快速做出能看的后台界面不用自己写复杂的 CSS。但传统 JSP Bootstrap 项目的页面写法有一些特有的讲究很多用惯了 Vue 的人上手反而不适应。4.1 Bootstrap引入方式的选择一个很实际的问题Bootstrap 用 CDN 还是本地文件如果你是在实验室、内网环境做课程设计交付我强烈建议把 Bootstrap 的 css/js 文件下载到项目web/static目录下通过本地路径引用。原因很简单你答辩的时候如果现场网络不好CDN 加载失败整个项目的样式全部崩掉那画面太尴尬了。本地引入的标准写法head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 link relstylesheet href${pageContext.request.contextPath}/static/bootstrap/css/bootstrap.min.css /head body script src${pageContext.request.contextPath}/static/bootstrap/js/bootstrap.bundle.min.js/script /body注意这里必须用${pageContext.request.contextPath}动态拼接项目名。因为项目部署时 context path 是/edu_system如果你在 JSP 里写死href/static/...浏览器解析的时候会跑到 localhost 根路径下面去找 static 目录结果就是 404。这个问题困扰了无数刚接触 JavaWeb 的新手。4.2 列表页与表单页的 Bootstrap 组装页面结构我用三块来组织顶部导航栏、侧边功能菜单、主体内容区。顶部用 Bootstrap 的 Navbar侧边栏用 Nav 组件搭配flex-column主体内容用container-fluid加卡片。典型的成绩列表页 JSP 片段长这样div classcontainer-fluid div classcard shadow-sm div classcard-header d-flex justify-content-between h5 classmb-0成绩列表/h5 button classbtn btn-primary btn-sm>String scoreStr request.getParameter(score); if (scoreStr null || scoreStr.trim().isEmpty()) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, 成绩不能为空); return; } try { BigDecimal score new BigDecimal(scoreStr); if (score.compareTo(BigDecimal.ZERO) 0 || score.compareTo(new BigDecimal(100)) 0) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, 成绩必须在0-100之间); return; } } catch (NumberFormatException e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, 成绩必须是数字); return; }这一层校验在大型系统里通常会配合 Hibernate Validator 之类的框架来做但传统 JSP Servlet 项目里就手写逻辑清楚且零依赖。前端校验保证普通用户操作流畅后端校验保证数据安全两条腿走路。5. 常见问题排查表与性能优化心得说实话写这个项目的过程基本就是一部报错处理手册。我把自己在教学和开发中真实遇到过的问题整理成一个速查表每一项都是实战经验不是从文档里抄的。这些问题如果等你上了线才发现排查成本会高出十倍提前看完能帮你省下大量时间。5.1 高频报错问题与解决方案问题现象根本原因解决办法JSP 页面中文全部乱码页面编码、数据库编码、连接串编码不统一三级统一为 UTF-8 / utf8mb4JSP 头部加pageEncodingUTF-8response 设置setCharacterEncoding(UTF-8)浏览器直接下载 JSP 文件而不是执行Tomcat 配置了 JSP 引擎但没能正确编译检查新建项目时是否生成了 WEB-INF/web.xml确认文件扩展名是.jsp而不是.html访问 Servlet 报 404Servlet 映射路径写错或注解路径没带WebServlet检查注解或 web.xml 中 servlet-mapping 的 URL 是否和请求路径一致确认 context path 正确MySQL 连接报 Public Key Retrieval is not allowedMySQL 8 使用 caching_sha2_password 插件时缺参数连接串加allowPublicKeyRetrievaltrue或者在 MySQL 里把加密规则改回 mysql_native_passwordtomcat 8080 端口被占用其他程序占用端口命令行 netstat -ano修改 JSP 后页面不生效war 包模式部署没有热更新开发阶段用 war exploded确认 IDEA 层面开启了 build project automatically点击删除按钮不弹确认框就删了没有做二次确认在页面加 JS 的 confirm 弹窗确认后再跳转正式场景建议改 POST fetch 删除登录后刷新页面直接退出登录Session 过期或浏览器禁用了 Cookie设置 session 超时时间检查 Tomcat context.xml 是否配置了 Cookie 接收规则这里特别想强调 MySQL 8 的认证插件问题。MySQL 8 默认使用caching_sha2_password而老的应用和驱动默认期望的是mysql_native_password。如果你连的是 8.0 数据库但驱动还是 5.x就会报认证失败。两条路一是升级驱动到 8.x 并在连接串里加allowPublicKeyRetrievaltrue二是执行一条 SQL 把用户加密规则改回去。我把第二种方法也贴出来方便需要在老代码环境里快速解决问题的情况ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;这个方法治标但有时候就是最快能救场的解法。5.2 细节优化预编译、事务、连接复用除了报错排查这个项目里还有几处值得做的细节优化直接决定系统是能跑还是跑得耐艹。第一个是 SQL 预编译。前面 DAO 部分我已经强调过了这里再展开说一个数据安全问题如果你把 SQL 写成SELECT * FROM tb_student WHERE stu_no stuNo 那么一个恶意构造的学号参数 OR 11就能让你把整个学生表的数据全部拉出来。这不是理论这是真实发生过无数次的攻击方式。PreparedStatement 预编译机制保证了参数作为数据被传递永远不会被解释为 SQL 指令。第二个是事务处理。成绩录入经常是批量操作比如一个老师录全班 30 个人的成绩。如果每录一条就自动提交一次中途第 20 条出错前 19 条已经写进数据库了数据就不一致。正确做法是开启事务、批量插入、全部成功才提交、失败则回滚。核心代码模式如下Connection conn null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); // 关掉自动提交 for (Score score : scoreList) { scoreDao.insert(conn, score); } conn.commit(); // 全部成功才提交 } catch (SQLException e) { if (conn ! null) conn.rollback(); // 出错回滚 throw e; } finally { if (conn ! null) conn.setAutoCommit(true); DBUtil.close(conn); }事务这块很多初学者总觉得用不上但课程设计答辩的时候只要你在成绩录入这个功能里提到事务处理基本就能让答辩老师高看你一眼。因为这说明你已经意识到真实业务系统里数据一致性这个核心问题。第三个是连接复用。很多人写完项目发现 Tomcat 启动后MySQL 服务时不时报 Too many connections原因就是代码里每次都DriverManager.getConnection()用完又不归还。用数据库连接池之后连接是复用的用完归还给池子而不是销毁高并发场景下性能差距极其明显。我上面给出的 DBUtil 里用 Druid 就是这个目的。6. 部署发布war打包与后续扩展方向项目写完开发完还不算完你得能把它打包部署到服务器上。传统 JSP 项目的部署方式说简单也简单说绕也绕。主要分两步打 war 包然后放到 Tomcat 的 webapps 目录里。IDEA 里打 war 包很简单Project Structure - Artifacts - 点加号 - Web Application - Archive - 选对应模块然后 Build - Build Artifacts选择 build 或者 rebuildwar 文件就会生成到你配置的 output 目录。生成的 war 包直接拷贝到 Tomcat 的 webapps 目录下启动 Tomcat它会自动解压并部署。这里要特别注意一个问题war 包里的WEB-INF/web.xml会被部署时读取而如果你是纯注解方式WebServlet、WebFilter写的项目没有 web.xml那也没关系。但如果你用的是 IDEA 自动生成的 web.xml里面通常有一个welcome-file-list默认指向 index.jsp这个路径要和你的项目结构对得上不然访问根路径会 404。另外一个部署后的常见问题是数据库连接配置。本地开发时druid.properties里的用户名密码可能是root/123456但部署到服务器上时密码可能不同。这里我建议把数据库连接信息做成外部可配置的最简单粗暴的方式就是改 properties 文件但更好的方式是让系统在启动时读取环境变量或外置配置文件这样换环境部署不用重新打 war 包。最后说说这个项目的扩展方向。如果你打算在这个项目基础上继续做毕业设计或者个人项目我有几个建议的演进路径把 DAO 层换成 MyBatis-Plus保留 Servlet 层不动体验一下框架带来的开发效率提升把 JSP 替换成 Vue Element UI 做前后端分离Servlet 改成提供 JSON 接口这样界面能漂亮一大截引入 Redis 缓存成绩查询热点数据感受缓存穿透、击穿这些名词到底是什么场景给系统加登录验证码、操作日志、数据导出 Excel 功能让功能完整度更像真实产品。我自己实际带过不少学生走完这套路径最有意思的现象是做完 JSP Servlet 项目再学 Spring Boot很多人不再觉得 Bean、自动配置、起步依赖是什么魔法因为他们已经在最底层体验过 Tomcat 处理请求的完整流程了。框架终究是对传统模式的封装理解了底层框架就只是工具而不是黑盒。如果你真遇到卡住的地方把自己断言的代码路径、报错日志、Tomcat 的 localhost 日志发出来把问题描述清楚通常很快就能定位。这个项目本身不复杂它难的是对整体流程的把握和理解希望你不仅把它跑起来还能把它吃透。
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

从化工仿真到三维资产与扫描归档:跨领域Batch批处理实战指南 2026/10/1 16:31:30

从化工仿真到三维资产与扫描归档:跨领域Batch批处理实战指南

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

阅读更多 →
MotionBuilder动捕数据处理与角色重定向实战指南 2026/10/1 16:31:30

MotionBuilder动捕数据处理与角色重定向实战指南

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

阅读更多 →
Node.js+Vue在线招聘平台全栈开发:前后端分离从0到1实战解析 2026/10/1 16:31:30

Node.js+Vue在线招聘平台全栈开发:前后端分离从0到1实战解析

我最近把一个在线招聘平台的完整开发流程过了一遍,技术栈是 Node.js 加 Vue,前后端分离,覆盖了从需求拆解、数据库建模、接口开发、前端页面搭建到上线部署的每个环节。这类项目在毕业设计和课程实训里出现频率很高,但网上能查到的…

阅读更多 →
PackML状态机标准解析:从PLC编程到设备集成与MES对接的工程实践 2026/10/1 16:31:30

PackML状态机标准解析:从PLC编程到设备集成与MES对接的工程实践

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

阅读更多 →
MIPI多路同步聚合:从物理层Deskew到V4L2硬件级对齐 2026/10/1 16:31:30

MIPI多路同步聚合:从物理层Deskew到V4L2硬件级对齐

/* 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 16:31:23

享元模式实战:解决对象爆炸与内存泄漏

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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