news 2026/9/29 1:45:23

Java Web学生信息管理系统实战:从数据库设计到Servlet分页与权限拦截

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java Web学生信息管理系统实战:从数据库设计到Servlet分页与权限拦截

简介:这份资源是面向计算机专业学生与Java Web初学者的一套学生信息管理系统完整项目源码,对应课程设计、实训作业或毕业设计等场景,帮助读者理解如何用Java技术栈搭建一个可运行的信息管理应用。压缩包为rar格式,整体约1.21MB,包内以Java源文件、JSP页面及数据库脚本等类型为主,分别承担后端业务逻辑、前端数据展示与数据表结构定义等职责。目前已有3006人学习下载,具备一定的参考热度。系统围绕学生信息的增删改查展开,涵盖登录验证、Session身份识别、Servlet请求处理、JDBC数据库连接以及PreparedStatement预编译防注入等关键环节,数据库表设计涉及学号、姓名、性别、出生日期、专业等字段,并兼顾主键、索引与密码加密存储等安全考量。读者可据此梳理Java Web项目的分层结构与开发流程,对照源码理解Servlet、JSP与JDBC的协作方式,为课程实践与技能提升提供可复用的参考方案。

1. 从一张成绩单说起:Java Web 学生信息管理系统到底在管什么

教务老师每学期末最怕什么?不是考试安排,是学生成绩、学籍异动、班级花名册散落在七八个 Excel 里,改一处要同步三处,查一个学生的历年成绩得翻五个文件。基于 Java Web 的学生信息管理系统,本质上就是把这堆表格收进一个浏览器能打开的页面里,让辅导员、教务、任课老师各看各的数据,各干各的活。它不新鲜,但每年毕业设计和课程设计里出现频率极高,原因也简单:业务边界清楚、技术栈成熟、能跑通增删改查就能交差。可真正动手写的时候,很多人卡在“表怎么设计”“权限怎么分”“分页查询为什么慢”这些具体问题上。这篇笔记就按一个能上线的学生信息管理系统来拆,从数据库表结构到 Servlet 跳转,再到部署排错,把能抄的代码和能踩的坑都摆出来。

2. 技术选型与数据库表设计:别急着写 Servlet,先把实体关系理清

2.1 为什么是 JSP + Servlet + JDBC,而不是一上来就 Spring Boot

打开招聘软件搜 Java Web,Spring Boot 铺天盖地,但学生信息管理系统这个题目有个现实约束:很多学校的实验环境只装了 Tomcat 和 JDK,连 Maven 仓库都连不上。我一般会建议先用 JSP + Servlet + JDBC 把业务跑通,原因有三。第一,Servlet 是 Java Web 的根,请求怎么进来、响应怎么出去、Session 怎么维持,这些在 Spring 里被封装成注解,出了问题只能靠猜,而在原生 Servlet 里每一步都看得见。第二,学生信息管理系统的核心操作是表单提交和列表展示,JSP 的 EL 表达式和 JSTL 标签足够应付,不需要前后端分离那一套。第三,调试成本低,改完 JSP 直接刷新浏览器,不用等热部署。

当然,这不是说 Spring Boot 不能用。如果你的环境允许,用 Spring Boot + MyBatis + Thymeleaf 会更省事,尤其是事务管理和连接池这块。但本文的代码示例以原生 Servlet 为主,因为它的报错信息最直白,适合用来理解“请求从浏览器到数据库再回来”的完整链路。

选型确定后,第一件事不是建工程,是画 ER 图。学生信息管理系统里最核心的实体就四个:学生、班级、课程、成绩。它们之间的关系是:一个班级有多个学生,一个学生选多门课,每门课对应一条成绩记录。很多新手上来就建一张大表,把学生姓名、班级名、课程名、分数全塞进去,结果改一个班级名要更新几十行,这就是典型的没做范式化。

2.2 学生课程成绩信息实体表设计:五张表撑起整个系统

下面这套表结构是我在多个课程设计里反复用过的,字段不多,但覆盖了增删改查和统计需求。注意student_no和course_no都加了唯一索引,因为学号和课程号是业务主键,不能重复。

-- 班级表:一个班级对应多个学生 CREATE TABLE class ( id INT PRIMARY KEY AUTO_INCREMENT, class_name VARCHAR(50) NOT NULL COMMENT '班级名称,如计算机2101', grade_year INT NOT NULL COMMENT '入学年份', counselor VARCHAR(20) COMMENT '辅导员姓名' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 学生表:学号唯一,外键关联班级 CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL UNIQUE COMMENT '学号', name VARCHAR(20) NOT NULL, gender CHAR(1) DEFAULT '男', birth_date DATE, class_id INT, phone VARCHAR(15), FOREIGN KEY (class_id) REFERENCES class(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 课程表:课程号唯一 CREATE TABLE course ( id INT PRIMARY KEY AUTO_INCREMENT, course_no VARCHAR(20) NOT NULL UNIQUE COMMENT '课程编号', course_name VARCHAR(50) NOT NULL, credit DECIMAL(3,1) DEFAULT 2.0 COMMENT '学分', teacher VARCHAR(20) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 成绩表:学生和课程的多对多关系,分数保留一位小数 CREATE TABLE score ( id INT PRIMARY KEY AUTO_INCREMENT, student_id INT NOT NULL, course_id INT NOT NULL, score DECIMAL(4,1) COMMENT '0-100分', exam_date DATE, UNIQUE KEY uk_student_course (student_id, course_id), FOREIGN KEY (student_id) REFERENCES student(id), FOREIGN KEY (course_id) REFERENCES course(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 用户表:登录用,角色区分管理员和普通教师 CREATE TABLE sys_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(30) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL COMMENT '存MD5值,不存明文', role VARCHAR(10) DEFAULT 'teacher' COMMENT 'admin或teacher', real_name VARCHAR(20) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

建完表后,往sys_user里插一条管理员记录,密码用 MD5 加密。下面这段 Java 代码用来生成 MD5 值,跑一次拿到结果直接写进 SQL 就行。

import java.security.MessageDigest; public class MD5Util { public static String md5(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(input.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (Exception e) { throw new RuntimeException("MD5计算失败", e); } } public static void main(String[] args) { // 把 admin123 转成 MD5,插入数据库时用这个值 System.out.println(md5("admin123")); } }

参数说明:MessageDigest.getInstance("MD5")指定算法,digest返回 16 字节数组,%02x保证每个字节转成两位十六进制。注意 MD5 现在不安全,但学生系统里用来避免明文存储足够了,真要上生产得换 BCrypt。

2.3 连接池配置:为什么你的系统跑十分钟就卡死

很多课程设计里直接用DriverManager.getConnection()拿连接,用完close()。这在单用户测试时没问题,但一旦多人同时访问,每个请求都新建 TCP 连接,数据库很快耗尽连接数,表现就是页面转圈然后报Too many connections。正确做法是用连接池,Tomcat 自带 DBCP,配置在META-INF/context.xml里。

<Context> <Resource name="jdbc/studentDB" auth="Container" type="javax.sql.DataSource" maxTotal="20" maxIdle="10" maxWaitMillis="10000" username="root" password="yourpassword" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/student_db?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8"/> </Context>

然后在web.xml里引用这个资源,Servlet 里通过InitialContext查找。maxTotal="20"表示最多 20 个活跃连接,maxWaitMillis="10000"表示拿不到连接时等 10 秒就抛异常,避免请求无限挂起。这个配置在 50 人同时在线的小系统里够用了,如果班级规模大,把maxTotal调到 50,同时观察 MySQL 的max_connections参数别超。

3. 用 Servlet + JSP 跑通学生列表分页:从请求到渲染的完整链路

3.1 分页查询的 SQL 写法与 Servlet 参数接收

学生列表是使用频率最高的页面,一个年级几百人,不分页的话页面加载慢,数据库也吃力。分页的核心是LIMIT offset, size,但 offset 不能写死,要根据当前页码算。下面这个StudentListServlet接收page和keyword两个参数,keyword用来按姓名或学号模糊搜索。

@WebServlet("/student/list") public class StudentListServlet extends HttpServlet { private static final int PAGE_SIZE = 10; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 接收页码,默认第一页 String pageStr = request.getParameter("page"); int page = (pageStr == null || pageStr.isEmpty()) ? 1 : Integer.parseInt(pageStr); // 2. 接收搜索关键词,用于姓名或学号模糊匹配 String keyword = request.getParameter("keyword"); if (keyword == null) keyword = ""; Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; List<Student> students = new ArrayList<>(); int totalCount = 0; try { conn = DBUtil.getConnection(); // 3. 先查总数,用于计算总页数 String countSql = "SELECT COUNT(*) FROM student s " + "LEFT JOIN class c ON s.class_id = c.id " + "WHERE s.name LIKE ? OR s.student_no LIKE ?"; ps = conn.prepareStatement(countSql); ps.setString(1, "%" + keyword + "%"); ps.setString(2, "%" + keyword + "%"); rs = ps.executeQuery(); if (rs.next()) totalCount = rs.getInt(1); rs.close(); ps.close(); // 4. 再查当前页数据,关联班级名 String listSql = "SELECT s.id, s.student_no, s.name, s.gender, c.class_name " + "FROM student s LEFT JOIN class c ON s.class_id = c.id " + "WHERE s.name LIKE ? OR s.student_no LIKE ? " + "ORDER BY s.student_no LIMIT ?, ?"; ps = conn.prepareStatement(listSql); ps.setString(1, "%" + keyword + "%"); ps.setString(2, "%" + keyword + "%"); ps.setInt(3, (page - 1) * PAGE_SIZE); ps.setInt(4, PAGE_SIZE); rs = ps.executeQuery(); while (rs.next()) { Student stu = new Student(); stu.setId(rs.getInt("id")); stu.setStudentNo(rs.getString("student_no")); stu.setName(rs.getString("name")); stu.setGender(rs.getString("gender")); stu.setClassName(rs.getString("class_name")); students.add(stu); } // 5. 计算总页数,向上取整 int totalPages = (totalCount + PAGE_SIZE - 1) / PAGE_SIZE; request.setAttribute("students", students); request.setAttribute("currentPage", page); request.setAttribute("totalPages", totalPages); request.setAttribute("keyword", keyword); request.getRequestDispatcher("/WEB-INF/views/student_list.jsp").forward(request, response); } catch (SQLException e) { throw new ServletException("查询学生列表失败", e); } finally { DBUtil.close(conn, ps, rs); } } }

逻辑说明:先查COUNT(*)拿到总记录数,再查当前页数据,两次查询用同一个连接。(page - 1) * PAGE_SIZE是偏移量,第一页 offset 为 0,第二页为 10,以此类推。totalPages用(totalCount + PAGE_SIZE - 1) / PAGE_SIZE计算,避免浮点数除法。参数keyword前后拼%实现模糊匹配,注意这里用了PreparedStatement,能防 SQL 注入。

3.2 JSP 页面渲染与分页条实现

Servlet 把数据放到 request 域后转发到 JSP,JSP 里用 JSTL 遍历。分页条要显示上一页、下一页和页码,当前页高亮。下面这段 JSP 放在/WEB-INF/views/student_list.jsp,注意WEB-INF下的页面不能直接通过浏览器访问,必须走 Servlet 转发,这是为了安全。

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>学生列表</title> <style> table { border-collapse: collapse; width: 80%; margin: 20px auto; } th, td { border: 1px solid #ccc; padding: 8px; text-align: center; } .pagination { text-align: center; margin: 20px; } .pagination a, .pagination span { margin: 0 5px; padding: 4px 10px; border: 1px solid #ddd; } .pagination .current { background: #4a90d9; color: #fff; } </style> </head> <body> <form action="${pageContext.request.contextPath}/student/list" method="get"> <input type="text" name="keyword" value="${keyword}" placeholder="输入姓名或学号"/> <input type="submit" value="搜索"/> </form> <table> <tr> <th>学号</th><th>姓名</th><th>性别</th><th>班级</th><th>操作</th> </tr> <c:forEach items="${students}" var="stu"> <tr> <td>${stu.studentNo}</td> <td>${stu.name}</td> <td>${stu.gender}</td> <td>${stu.className}</td> <td> <a href="${pageContext.request.contextPath}/student/edit?id=${stu.id}">编辑</a> <a href="${pageContext.request.contextPath}/student/delete?id=${stu.id}" onclick="return confirm('确认删除?')">删除</a> </td> </tr> </c:forEach> </table> <div class="pagination"> <c:if test="${currentPage > 1}"> <a href="?page=${currentPage - 1}&keyword=${keyword}">上一页</a> </c:if> <c:forEach begin="1" end="${totalPages}" var="p"> <c:choose> <c:when test="${p == currentPage}"> <span class="current">${p}</span> </c:when> <c:otherwise> <a href="?page=${p}&keyword=${keyword}">${p}</a> </c:otherwise> </c:choose> </c:forEach> <c:if test="${currentPage < totalPages}"> <a href="?page=${currentPage + 1}&keyword=${keyword}">下一页</a> </c:if> </div> </body> </html>

参数说明:${pageContext.request.contextPath}拿到应用上下文路径,避免部署到不同目录时链接失效。分页链接里带上keyword,这样翻页时搜索条件不丢失。onclick="return confirm(...)"是删除前的二次确认,防止误操作。

3.3 中文乱码的三种场景与对应解法

中文乱码是 Java Web 的经典翻车点,分三种情况。第一种是表单 POST 提交,请求体编码不对,表现为插入数据库后变成问号。解法是在 Servlet 里第一行加request.setCharacterEncoding("UTF-8"),或者用 Filter 统一处理。第二种是 GET 请求 URL 参数乱码,Tomcat 8 以后默认 URI 编码是 UTF-8,但老版本需要在server.xml的 Connector 上加URIEncoding="UTF-8"。第三种是响应输出乱码,页面显示问号,解法是response.setContentType("text/html;charset=UTF-8")。

我一般会写一个CharacterEncodingFilter,在web.xml里配成/*,一劳永逸。

@WebFilter("/*") public class CharacterEncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); chain.doFilter(req, resp); } }

注意这个 Filter 要放在其他 Filter 之前,否则编码设置会被覆盖。如果用了 Spring 的CharacterEncodingFilter,确保forceEncoding设为true。

4. 登录鉴权与权限拦截:别让普通老师看到管理员菜单

4.1 Session 存用户信息与登录 Servlet 实现

学生信息管理系统里,管理员能增删改所有数据,普通老师只能查成绩和录入自己课的成绩。这个区分靠 Session 里的role字段。登录成功后把user对象放进session,后续每个受保护的 Servlet 先检查session.getAttribute("user")是否为空,为空就跳登录页。

@WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = MD5Util.md5(request.getParameter("password")); try (Connection conn = DBUtil.getConnection(); PreparedStatement ps = conn.prepareStatement( "SELECT id, username, role, real_name FROM sys_user WHERE username=? AND password=?")) { ps.setString(1, username); ps.setString(2, password); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setRole(rs.getString("role")); user.setRealName(rs.getString("real_name")); request.getSession().setAttribute("user", user); response.sendRedirect(request.getContextPath() + "/student/list"); } else { request.setAttribute("msg", "用户名或密码错误"); request.getRequestDispatcher("/login.jsp").forward(request, response); } } } catch (SQLException e) { throw new ServletException("登录查询失败", e); } } }

参数说明:密码在前端传过来是明文,这里先 MD5 再比对数据库里的 MD5 值。request.getSession()默认创建新 Session,如果之前有旧 Session 会被复用。登录成功后重定向到学生列表,避免刷新页面重复提交表单。

4.2 用 Filter 做统一权限拦截

每个 Servlet 里都写一遍 Session 检查太啰嗦,用 Filter 拦截/student/*、/score/*等路径,统一判断。下面这个AuthFilter还做了角色判断:删除操作只允许admin。

@WebFilter(urlPatterns = {"/student/*", "/score/*", "/class/*"}) public class AuthFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; HttpSession session = request.getSession(false); // 1. 未登录,跳转登录页 if (session == null || session.getAttribute("user") == null) { response.sendRedirect(request.getContextPath() + "/login.jsp"); return; } User user = (User) session.getAttribute("user"); String uri = request.getRequestURI(); // 2. 删除操作仅管理员可执行 if (uri.contains("/delete") && !"admin".equals(user.getRole())) { response.sendError(403, "无权限执行删除操作"); return; } chain.doFilter(req, resp); } }

注意request.getSession(false)表示不新建 Session,只取已有的。如果写成true或空参,每个请求都会创建 Session,浪费内存。sendError(403)会返回 Tomcat 的错误页,如果想自定义,可以在web.xml里配<error-page>。

4.3 密码存储与 SQL 注入的两个硬性要求

密码不能明文存,这是底线。MD5 虽然弱,但比明文强,至少数据库被拖库时不会直接暴露。更好的做法是 BCrypt,加盐哈希,但需要引入jbcrypt依赖。如果环境不允许,MD5 加固定盐值也能凑合,比如md5(password + "student_sys_2024")。

SQL 注入方面,所有带参数的查询必须用PreparedStatement,不要用字符串拼接。下面这两种写法,第一种是安全的,第二种一搜' OR '1'='1就绕过登录。

// 安全:PreparedStatement 预编译 ps = conn.prepareStatement("SELECT * FROM sys_user WHERE username=? AND password=?"); ps.setString(1, username); ps.setString(2, password); // 危险:字符串拼接,别用 String sql = "SELECT * FROM sys_user WHERE username='" + username + "' AND password='" + password + "'";

PreparedStatement会把参数当成数据而不是 SQL 语法,即使用户输入' OR '1'='1,也会被当成普通字符串匹配,查不到记录。

5. 避坑与排查:部署到 Tomcat 后最容易翻车的五个地方

5.1 现象:页面报 404,但路径明明是对的

原因:JSP 放在WEB-INF下,浏览器直接访问/WEB-INF/views/student_list.jsp会被 Tomcat 拒绝,返回 404。这是 Servlet 规范的安全限制,WEB-INF下的资源只能通过 Servlet 转发访问。

解决:所有页面跳转走 Servlet,用request.getRequestDispatcher("/WEB-INF/views/xxx.jsp").forward(...)。如果确实需要直接访问,把 JSP 移到WebContent根目录下,但这样会暴露源码逻辑,不推荐。

5.2 现象:数据库连接报No suitable driver found

原因:MySQL 驱动 jar 没放到WEB-INF/lib下,或者driverClassName写错。MySQL 8 的驱动类是com.mysql.cj.jdbc.Driver,不是老版本的com.mysql.jdbc.Driver。

解决:把mysql-connector-java-8.0.xx.jar复制到WEB-INF/lib,检查context.xml里的driverClassName和url。URL 里要加serverTimezone=Asia/Shanghai,否则 MySQL 8 会报时区错误。

5.3 现象:分页查询第二页数据重复或丢失

原因:ORDER BY的字段有重复值,比如按class_id排序,同一个班的学生顺序不稳定,MySQL 每次返回的顺序可能不同,导致分页错乱。

解决:ORDER BY后面加一个唯一字段,比如ORDER BY s.student_no或ORDER BY s.id。学号和 id 都是唯一的,能保证排序稳定。

5.4 现象:删除学生时报外键约束错误

原因:score表里有该学生的成绩记录,直接删student表会触发外键约束,报Cannot delete or update a parent row。

解决:先删score里对应的记录,再删student。或者在建表时把外键设为ON DELETE CASCADE,但这样会连带删除成绩,要确认业务上是否允许。我一般会在删除前弹窗提示“该学生有成绩记录,确认一并删除?”,确认后在一个事务里先删成绩再删学生。

5.5 现象:Tomcat 启动慢,日志里刷SEVERE: Unable to process Jar entry

原因:WEB-INF/lib下放了重复或冲突的 jar,比如同时有servlet-api.jar和 Tomcat 自带的servlet-api.jar,类加载器扫描时冲突。

解决:servlet-api.jar和jsp-api.jar不要放进WEB-INF/lib,Tomcat 已经提供了。只放 MySQL 驱动、JSTL、连接池等业务依赖。用 Maven 的话,把这两个依赖的scope设为provided。

6. 进阶技巧:用一条 SQL 查出班级成绩排名与及格率

系统跑通后,教务最常问的是“哪个班平均分最高”“这门课及格率多少”。这些统计不需要在 Java 里循环算,一条 SQL 就能出结果。下面这条查询按班级统计每门课的平均分、最高分、最低分和及格率,直接返回给 JSP 渲染成报表。

SELECT c.class_name AS 班级, co.course_name AS 课程, COUNT(*) AS 人数, ROUND(AVG(sc.score), 1) AS 平均分, MAX(sc.score) AS 最高分, MIN(sc.score) AS 最低分, CONCAT(ROUND(SUM(CASE WHEN sc.score >= 60 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 1), '%') AS 及格率 FROM score sc JOIN student s ON sc.student_id = s.id JOIN class c ON s.class_id = c.id JOIN course co ON sc.course_id = co.id GROUP BY c.class_name, co.course_name ORDER BY c.class_name, 平均分 DESC;

参数说明:CASE WHEN sc.score >= 60 THEN 1 ELSE 0 END把及格记录标记为 1,SUM后除以总人数得到及格率。ROUND(..., 1)保留一位小数。GROUP BY同时按班级和课程分组,ORDER BY先按班级再按平均分降序,方便一眼看出哪个班哪门课考得好。

如果要在 JSP 里展示,Servlet 里把ResultSet转成List<Map<String, Object>>,JSP 用c:forEach遍历即可。注意Map的 key 是列别名,中文别名在 JDBC 里可能乱码,建议用英文别名再在 JSP 里映射成中文表头。

我自己的习惯是,统计类查询一律不写进 Java 循环,能交给 SQL 就交给 SQL。数据库的聚合函数比 Java 快一个数量级,而且代码短,维护起来不容易出错。唯一要注意的是GROUP BY的字段和SELECT里的非聚合字段必须一致,MySQL 8 默认开启了ONLY_FULL_GROUP_BY,不一致会直接报错,这其实是好事,能帮你发现逻辑漏洞。

最后说一个我踩过的坑:统计查询不要和分页查询共用同一个Connection,因为ResultSet没关闭前,同一个连接上再执行查询会报Streaming result set错误。要么用两个连接,要么先把统计结果读进内存再关ResultSet。这个错误在本地测试时不容易出现,一上压力测试就暴露,血泪经验。希望帮到你。

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

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

高精度除法算法详解:模拟竖式实现大数整除

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

作者头像 李华
网站建设 2026/9/29 1:42:36

仓储托盘到底贵在哪:把一次看似便宜的选择拆开算账

1. 看起来省下几万块&#xff0c;最后为什么在流水线上赔得肉疼&#xff1f;很多人在给仓库或者车间采购托盘时&#xff0c;直觉逻辑非常朴素&#xff1a;这不就是一块垫在货物下面的塑料板吗&#xff1f;既然都是长方形、都能被叉车挑起来&#xff0c;那报价表里谁便宜就选谁&…

作者头像 李华
网站建设 2026/9/29 1:41:49

Allegro差分对等长设计:从Constraint Manager规则到Delay Tune绕线实操

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

作者头像 李华
网站建设 2026/9/29 1:40:46

用DeepSeek搭建酒店投诉知识库:RAG检索增强生成落地实践

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

作者头像 李华
网站建设 2026/9/29 1:40:36

logviewer日志查看工具:告别tail与grep,高效排查大日志

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

作者头像 李华
网站建设 2026/9/29 1:40:35

开源p-net协议栈实战:从零打造PROFINET从站

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

作者头像 李华