ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

超市管理系统.zip从解压到跑通:环境配置与核心改造

超市管理系统.zip从解压到跑通:环境配置与核心改造

简介:这份毕业设计与课程设计两用的超市管理系统项目,面向计算机相关专业在校生、初入行的开发者及需要快速搭建完整演示系统的同学,可覆盖前端页面展示、后端业务逻辑与数据库配置等常见课设/毕设环节。压缩包共 2001 个文件、约 52.19MB,其中 jsp/java/jar/class 等承担系统业务与运行依赖,css/js/html 及大量 png/jpg/gif 构成界面样式与展示素材,db/xml 文件则用于数据库与配置信息的落地,整体结构对二次开发较为友好。已有 48 人学习浏览该项目,代码经运行验证后上传,适合作为超市进销存、订单结算等场景的课程设计或初期立项演示基础。下载后可结合 README 说明与目录结构快速定位源码,在此基础上做功能扩展或界面调整,均可作为项目交付与答辩展示的参考起点。

1. 超市管理系统.zip:课设项目到手,先别急着解压双击

每年到毕设和课设节点,「超市管理系统.zip」都是下载榜上的常客,JavaWeb、Swing、Python版本都有,里面装的是一套典型的进销存骨架:商品、进货、销售、订单、库存和员工登录。它的价值不是代码本身,而是给你一个能跑、能讲、能改的起点。但我见过太多人卡在起点之前:解压报错、JDK版本对不上、数据库初始化失败,最后对着一个打不开的zip干着急。也有不少人把包下下来一解压就双击exe,结果发现根本不是自己熟悉的技术栈。所以说,拿到zip先别急着双击,先花十分钟做三件事:校验完整性、看清目录、确定技术栈。

2. 从zip到跑通:解压校验、环境匹配与数据库初始化

2.1 解压前先校验:损坏检测、目录结构与README

先校验zip是否完整。很多下载站的包下到一半就断了,或者上传时损坏,解压到一半弹出「invalid zip archive: could not find eocd」,然后你以为是工具问题,换一个解压软件还是一样。其实这是文件本身不完整,eocd(End Of Central Directory)标记在压缩包末尾,找不到说明整个zip的结尾丢了,常见原因是下载中断或者文件被改过后缀。我一般拿到zip先跑一遍测试解压,不实际释放文件,几秒钟就能判断能不能用:

# -t 只测试压缩包完整性,不产生解压文件 unzip -t 超市管理系统.zip # 测试通过后再解压到指定目录,避免把当前目录弄乱 unzip -o 超市管理系统.zip -d ./supermarket ls -la ./supermarket

unzip的-t参数只读取并校验每个文件条目,不会落盘,所以很安全。-d指定解压目录,-o表示覆盖已有文件。测试通过后再解压,避免解到一半才报错的尴尬。这里有个容易被忽视的坑:Windows自带资源管理器的zip查看和解压对非UTF-8编码的文件名支持不好,很多打包的人自己就在中文目录下压缩,解压后会出现乱码目录名。我一般换用7-Zip或Bandizip,右键解压时选择按UTF-8处理文件名,能省掉一半的乱码问题。

压缩包解出来之后先别急着导入IDE,先看一眼目录结构。典型的JavaWeb课设项目根目录下面会有src、web或WebContent、sql或database文件夹,外加README和配套文档。如果是Swing或Python版本,会有src目录或main.py,外加一些资源文件。README里一般写了JDK版本、数据库版本和启动步骤,我建议把它当成第一份需求文档,后面所有配置都以它为准。没有README也不要慌,按“看后缀”的原则确认技术栈:有pom.xml是Maven工程,有build.gradle是Gradle,只有.classpath和.project的是Eclipse导入的历史工程,这个判断在第4章还会用到。

提示:如果解压出来多套了一层同名父目录,直接用那层目录当工作区,不要手动把文件往外挪,避免路径引用失效。

顺带一提,不少人习惯用「linux压缩当前文件夹到zip」的方式把整个项目打包传给别人:cd到项目父目录,然后zip -r supermarket.zip supermarket/,这样解压出来会多一层目录。如果你拿到手的包多套了一层,直接把最外层的文件夹作为工作区打开即可,不用改任何路径。真正需要警惕的是压缩包根目录散落一堆文件、没有统一父目录的情况,那通常是随手压缩的,结构可能不完整。

2.2 环境匹配:JDK8 zip安装、Tomcat与MySQL版本对应

JavaWeb课设最常见的组合是JDK8 + Tomcat 8/9 + MySQL 5.7/8.0。为什么先说版本?因为很多项目代码用了JDK8以后才有的语法特性,比如lambda和try-with-resources,你用JDK7编译会直接语法报错。而MySQL 8对驱动的连接参数要求更严格,不写时区参数直接连不上。很多机器上装的是Oracle安装版JDK,而zip绿色版更适合快速切换版本,解压之后配几个环境变量就好:

# Windows下给JDK8 zip版配置环境变量(临时生效,当前终端) set JAVA_HOME=D:\dev\jdk1.8.0_202 set PATH=%JAVA_HOME%\bin;%PATH% java -version # 用setx可以永久写入用户环境变量 setx JAVA_HOME "D:\dev\jdk1.8.0_202" setx PATH "%JAVA_HOME%\bin;%PATH%"

java -version应该输出1.8.x,如果输出别的版本,说明PATH里别的JDK顺序靠前,把JAVA_HOME的bin提到最前面。setx写入的是用户环境变量,不需要管理员权限,适合在机房机器上临时切版本。这里还有一个典型翻车点:有的包要求JDK11甚至17,但你按默认的JDK8去编译,报错一堆「非法字符」或「不支持发行版本」,解决办法是看README给出的编译参数,或者在IDE里把Project SDK和Language Level改成对应版本。

Tomcat不建议单独下载zip了,更常见的做法是直接用IDEA或Eclipse自带的Tomcat集成。注意Tomcat版本和Servlet/JSP规范对应关系:Tomcat 9对应Servlet 4.0,Tomcat 10对应Jakarta EE命名空间。如果你拿到的是老项目(javax.servlet包),强行放到Tomcat 10下会编译报「程序包javax.servlet不存在」,需要改成jakarta.servlet。课设项目我一般建议用Tomcat 8.5或9.0,兼容性最好,不用改代码。

2.3 数据库初始化:导入SQL、改连接配置与MySQL zip免安装

与其纠结手上有没有MySQL安装包,不如直接学一下MySQL zip免安装的玩法。MySQL官方就提供zip压缩包,解压后初始化数据目录、启动服务,再导入SQL文件,全程不需要管理员权限,很适合课设机房的机器。初始化命令贴在下面:

# MySQL zip版免安装初始化:生成data目录 mysqld --initialize-insecure --basedir=D:/dev/mysql-8.0 --datadir=D:/dev/mysql-8.0/data # 启动服务(前台模式,适合调试) mysqld --console --basedir=D:/dev/mysql-8.0 --datadir=D:/dev/mysql-8.0/data

--initialize-insecure会生成一个root空密码的实例,省去改密码的步骤;如果用了--initialize,会生成临时密码,你拿到还得再改一次,课设调试阶段我不推荐。启动后另开一个终端连接:

mysql -uroot -p # 建库、导数据 CREATE DATABASE IF NOT EXISTS supermarket DEFAULT CHARACTER SET utf8mb4; USE supermarket; SOURCE D:/delivery/supermarket/init.sql; SHOW TABLES;

SOURCE是mysql客户端的内置命令,等价于执行一个SQL脚本;路径里的反斜杠在Windows下要转义,建议写成/。执行完之后SHOW TABLES能看到商品表、订单表、用户表等,说明导入成功。如果导到一半报错,多半是脚本里写了USE别的库名,和你建的库对不上,用文本编辑器打开SQL文件看开头几行就知道。

数据库起来之后改Java侧的连接配置。JavaWeb项目里一般叫jdbc.properties、db.properties或application.yml,内容大概是这样(不同项目变量名有差异,但结构一样):

jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/supermarket?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=123456

这里要改的主要是库名、用户名和密码。MySQL 8必须用com.mysql.cj.jdbc.Driver,老驱动会报「Loading class... is deprecated」或直接连接失败。url里的serverTimezone指定时区,不写的话在MySQL 8下会报连接时区错误,这个是血泪经验。useSSL=false是为了跳过证书校验,课设环境没有配HTTPS证书,不关掉也会连不上。改完配置保存,重启Tomcat,登录页能出来就说明整个链路通了。

3. 看懂数据库骨架:商品、库存、订单三张表和业务闭环

3.1 三张核心表的关系:product、orders、stock_log怎么落库

超市管理系统的“管理”两个字,落到数据库里就是三张核心表:商品表、订单表和库存流水表。商品表描述“有什么”,订单表记录“卖了什么”,库存流水表记录每一次库存变化。拿到SQL脚本先别急着执行,打开看一眼表结构,比直接跑起来更能理解这个系统的业务。

CREATE TABLE product ( product_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '商品ID', barcode VARCHAR(32) UNIQUE COMMENT '条码', name VARCHAR(128) NOT NULL COMMENT '商品名', category VARCHAR(32) COMMENT '分类:饮料/食品/日化', sale_price DECIMAL(10,2) NOT NULL COMMENT '售价', stock INT NOT NULL DEFAULT 0 COMMENT '当前库存' ); CREATE TABLE stock_log ( id INT PRIMARY KEY AUTO_INCREMENT, product_id INT NOT NULL COMMENT '商品ID', change_qty INT NOT NULL COMMENT '变化数量,正入负出', biz_type TINYINT NOT NULL COMMENT '1=进货 2=销售 3=退货 4=盘点', create_time DATETIME NOT NULL COMMENT '发生时间' );

这两张表反映了最常见的设计:库存放在product表里,库存流水单独记录。为什么要单独记流水?因为“现在有多少”是状态,“怎么变成这样”是过程,答辩评委大概率会问一句——你怎么知道哪一批货卖完了还是丢了?有流水表就能回答。注意change_qty用正负号表达方向,不要建四个字段(入库数、出库数、退货数、盘点数),后者写起来很啰嗦,查起来也不好对账。

订单表一般拆成订单主表和订单明细表,主表存订单号、收银员、总金额、下单时间,明细表存每一件商品的单价和数量。拆两张是因为一次购买多件商品时,明细数量不固定,主表存汇总、明细表存每一条,这是非常经典的1:N关系。我看到极少数课设把商品名直接写在订单表里,那意味着一个订单只能买一件商品,收银台根本没法用,这种设计到答辩时是硬伤。

3.2 业务闭环:进货、销售、退货的数据流向与一致性问题

用一个完整业务串一遍:早上开门,仓管录入一批进货单,商品库存从100变成150;中午收银员卖出一瓶水,库存从150变成149,同时生成一笔订单;下午有顾客退货,库存加回一件,订单状态改成已退货。你看,每一步操作都至少落在两张表上,这也是MIS系统最常见的“数据一致性”考点。

进货操作的SQL逻辑典型是这样:先判断商品是否存在,存在就INSERT一条进货流水,再UPDATE product.stock。这两个动作要么都成功,要么都失败,否则就会出现流水有记录但库存没变化的情况。销售方向也一样,先扣库存再生成订单明细。这里有一个特别容易被忽略的细节:扣库存的UPDATE语句必须带条件。

-- 先扣库存,受影响行数为0说明库存不足 UPDATE product SET stock = stock - 5 WHERE product_id = 1 AND stock >= 5;

这种写法比“先查库存再判断够不够”安全得多。为什么?因为两步之间可能有并发,两个收银员同时卖同一个商品时,先查再改会出现“查的时候有货,改的时候库存已经没了”的窗口期。WHERE条件把校验和更新合成一个原子操作,这是实现上的关键点,答辩时提这一句能加分。

退货方向是反过来的:INSERT退货流水,然后UPDATE product SET stock = stock + 退货数量。同样要带事务。如果项目里把三个动作的SQL分散写在Servlet里,没有事务控制,一旦中间抛异常,库存和流水就对不上了。这是评审最常挑的问题之一,我在第4章给一段能直接抄的事务代码。

3.3 角色权限:管理员、收银员、仓管的登录校验与菜单控制

进货、销售、盘点这些操作,不是所有登录用户都能干的。常见设计是在用户表里加一个role字段,取值是ADMIN、CASHIER、STOCKER三个角色,分别对应用管理员、收银员、仓管。界面上最简单的控制是菜单隐藏,登录时把用户角色放进Session,页面里按角色渲染菜单。但这只是“界面隐藏”,真正拦住越权要靠后端校验。

// 登录校验过滤器:未登录一律跳登录页 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); if (session == null || session.getAttribute("loginUser") == null) { response.sendRedirect(request.getContextPath() + "/login.jsp"); return; } String role = (String) session.getAttribute("role"); String uri = request.getRequestURI(); // 仓管访问进货与库存路径,收银员访问订单路径,管理员全部放行 boolean ok = "ADMIN".equals(role) || "CASHIER".equals(role) && uri.contains("/order/") || "STOCKER".equals(role) && uri.contains("/stock/"); if (ok) { chain.doFilter(request, response); } else { response.sendError(403); } }

这段过滤器的思路很直白:没有登录就重定向到登录页,登录了但角色不对就返回403。这里注意三个细节:第一,getSession(false)拿不到Session时不会新建;第二,用uri.contains按路径前缀判断权限,跳转返回要用sendRedirect,转发用getRequestDispatcher时路径计算方式不同;第三,静态资源(CSS、JS、图片)要放行,否则登录页样式全丢,这也是新手常见的“登录页能开但丑得没法看”的原因。

菜单隐藏只影响体验,过滤器才管安全。答辩问“权限怎么做”的时候,把这两层都讲出来就是完整答案。下一章进入代码导读,看登录、收银、进货三个最常被要求改动的模块怎么读。

4. 读懂代码的修改点:登录、收银、进货三处高频改动落在哪

4.1 登录链路:JSP→Servlet→DAO的调用顺序与密码保存

拿到项目代码后,第一个能快速定位的模块是登录——从login.jsp的form表单的action出发,一路上能看见Servlet、Service、DAO三层调用。典型的链路是:登录页提交用户名密码到LoginServlet,LoginServlet调用UserService.login(),Service再调UserDAO.findByUsernameAndPassword(),最终执行一条SELECT语句。

登录模块最值得改、也最好改的地方有两个。第一个是密码保存方式。很多课设源码里直接明文存密码,SELECT WHERE password='123456'当然能跑,但如果想把项目写漂亮一点,至少要懂“密码应该存hash而不是明文”这个观点:

// MD5加盐示例:密码入库前做一次处理,而不是存明文 public static String hashPassword(String rawPassword, String salt) { String input = rawPassword + salt; // 生产环境应使用BCrypt或PBKDF2,课设中MD5足够展示安全意识 return DigestUtils.md5DigestAsHex(input.getBytes(StandardCharsets.UTF_8)); }

盐值一般取用户名或随机串,每个用户的盐不一样,防止两张彩虹表直接比对出同一密码。改完密码存储方式,登录校验也要对应改成“查出来再hash比对”,而不是SQL里直接password='xx'。注意,如果包里原本是明文,你改成hash后,原SQL脚本里已有的用户数据也要同步更新,否则老账号全部登不上。

第二个改点是登录失败的提示。不少旧项目登录失败只是弹个JavaScript提示,或者直接返回空页面。改成在登录页显示错误信息并保留用户名的体验会好很多,这不是核心技术问题,但答辩演示时观感差别很大。改了登录要重新跑通一遍“未登录访问受保护页面会跳登录页”的用例,正好验证第3章那个过滤器是否正常。很多改登录的人只测了登录成功,把密码错误后的Session残留问题漏了——Session里已经写入错误状态,下一次登录失败时页面上显示的还是上一次的错误。

4.2 收银台核心:订单生成与库存扣减的原子性

收银台是超市管理系统的门面。收银员扫描商品条码,页面把商品加进购物车列表,点了“结账”之后,后端要做三件事:生成订单主表记录、生成订单明细、扣减库存。这三个动作如果没有事务保护,就会产生“订单生成了但库存没扣”的脏数据,第二天盘点时一对账就露馅。我一般建议在Service方法里手动控制事务:

public Long createOrder(OrderDTO dto) { Connection conn = null; try { conn = dataSource.getConnection(); conn.setAutoCommit(false); // 手动控制事务 // 第一步:扣减库存,stock >= ? 防止扣成负数 try (PreparedStatement ps = conn.prepareStatement( "UPDATE product SET stock = stock - ? WHERE product_id = ? AND stock >= ?")) { ps.setInt(1, dto.getTotalQty()); ps.setInt(2, dto.getProductId()); ps.setInt(3, dto.getTotalQty()); if (ps.executeUpdate() == 0) { throw new RuntimeException("库存不足"); } } // 第二步:插入订单主表,返回自增主键 try (PreparedStatement ps = conn.prepareStatement( "INSERT INTO `order`(order_no, cashier_id, total_amount, create_time) VALUES (?,?,?,NOW())", Statement.RETURN_GENERATED_KEYS)) { ps.setString(1, dto.getOrderNo()); ps.setInt(2, dto.getCashierId()); ps.setBigDecimal(3, dto.getTotalAmount()); ps.executeUpdate(); } conn.commit(); return orderId; } catch (Exception e) { if (conn != null) { try { conn.rollback(); } catch (SQLException ignored) {} } throw new RuntimeException("下单失败,已回滚", e); } finally { if (conn != null) { try { conn.setAutoCommit(true); conn.close(); } catch (SQLException ignored) {} } } }

这段代码有四个关键点。第一,setAutoCommit(false)之后所有的SQL都在一个事务里,commit才真正落库。第二,扣库存的UPDATE带了stock >= ?条件,这行返回0表示库存不够,直接抛异常触发回滚——这就是前面说的防超卖手段。第三,订单主表插入用Statement.RETURN_GENERATED_KEYS拿到自增ID,明细表的外键就靠这个ID。第四,finally里把连接状态恢复成autoCommit并关闭,不恢复的话连接池里的下次复用会出问题。

注意:手动事务的finally里一定要把autoCommit恢复为true,否则连接池复用时会收到一个仍处于事务中的脏连接,后续SQL全部失效。

SpringBoot项目里通常用@Transactional注解更省事,但注解背后的原理就是上面这段代码——开启、提交、回滚、恢复。答辩时能讲清“事务注解干了什么”的人,比只会用注解的人高一个档次。如果包里的项目用的是Hibernate或MyBatis,事务写法会换成session或SqlSession的commit/rollback,但“先校验再更新”的思路完全一样。

4.3 进货模块:直更库存与审核流两种实现怎么选

进货模块的实现风格能直接体现这个项目的完成度。最低配的写法是一个表单填商品名和数量,后端UPDATE product SET stock = stock + ?就完事。应付“能跑”没问题,但你得知道还有审核流这个升级方向:仓管先填入库单,状态为“待审核”;管理员审核通过后,才真正累加库存、写流水。审核流的实现比直更库存多一张入库单表(purchase_order)和状态字段。

课设阶段怎么选?我建议代码量不够就做直更库存,但把“审核流”作为答辩时的扩展点来回答“系统还能怎么改进”。如果你已经做过用户管理、订单模块,代码量够,加一张入库单表和审核状态字段,逻辑上只是把“直接UPDATE库存”改成“UPDATE入库单状态+UPDATE库存”两个动作,事务写法复用4.2的模板就行,改动风险不大。

选型还有一条经验判断:看包里的SQL脚本有没有purchase_order或stock_in表。有,说明作者做了审核流,你改的优先级应该是数据流转顺序;没有,说明是直更库存,你硬加审核流要动表结构,改动面大、风险高,不如保留直更并在文档里写清楚扩展方案。软件的坑有七成不在代码里,而在“你要改的方向和原有架构合不合”,这一点对课设尤其适用。

5. 避坑:超市管理系统.zip从解压到交差的5个翻车现场

5.1 解压报错 invalid zip archive: could not find eocd

现象:双击解压或unzip -t时,中途提示invalid zip archive: could not find eocd,或者解压出来的文件只有零散的几个目录,缺文件。

原因:zip格式的eocd标记写在压缩包末尾,找不到说明文件不完整——下载中断、源文件损坏、或者上传时被截断。换解压软件没用,文件本身坏了。

解决:回到源站重新下载,下完先看文件大小是否和页面标注一致,再unzip -t校验。别指望改后缀能修复,扩展名改对了也不会补全内部结构。如果对方给的是分卷包(.z01、.z02),把所有分卷放在同一目录,用7-Zip右键合并解压。

5.2 导入IDE后中文全部乱码

现象:项目导入IDEA后,代码注释、JSP页面上的中文全是问号或方块,控制台输出System.out的中文也乱。原因:源文件编码是GBK,IDEA默认UTF-8,按UTF-8去读GBK字节流,自然全是乱码。

解决:在IDEA右下角把File Encoding改成GBK,等乱码恢复后再考虑是否统一转成UTF-8。千万不要在乱码状态下直接改代码保存,会把原本正确的字符写坏。控制台输出乱码还要检查Tomcat的日志编码参数,和文件编码是两回事。

5.3 数据库连接失败 Communications link failure

现象:启动Tomcat后点登录,页面报Communications link failure,或Access denied for user 'root'@'localhost'。原因:Communications link failure一般是MySQL没启动、端口不是3306、或URL里缺时区参数;Access denied是用户名密码或授权不对。

解决:先用命令行mysql -uroot -p试连,确认服务在跑;再核对jdbc.properties里的端口和时区参数。推荐在url上带useSSL=false&serverTimezone=Asia/Shanghai,很多项目的失败案例就差这个serverTimezone。驱动类也要确认是com.mysql.cj.jdbc.Driver而不是老的com.mysql.jdbc.Driver。

5.4 项目启动404:先查部署路径再查编译输出

现象:Tomcat启动正常、控制台无报错,但访问http://localhost:8080/项目名/login.jsp返回404,写死的首页也看不到。

原因:部署名不对或代码没有编译。IDEA里项目名和Context Path不一致最常见,部署包名改了,原路径全部失效;另一类是target或classes目录下没有class文件,说明编译失败。

解决:IDEA中打开Run Configuration,看Deployment标签下的Application context是否为期望的项目名,改成/supermarket或/项目名,重启再访问。第二步看编译输出目录里有没有对应的class文件,没有就是编译错误没清干净,先把编译错误解决再谈启动。

5.5 商品库存变成负数:收银并发时少了哪个条件

现象:演示时快速双开两个浏览器窗口同时下单同一件商品,库存直接变成-1,或者页面明明显示有货却下单失败。

原因:代码是“先SELECT库存,若大于0再UPDATE”,两个步骤之间有间隙,并发场景下两个请求都读到库存为1,各自扣1,最终变成-1。本质是校验和更新没有合并成一个原子操作。

解决:把校验条件写进UPDATE:WHERE product_id=? AND stock >= ?,受影响行数为0就抛异常回滚,4.2节的事务代码可以直接抄,不需要改表结构。改完开两个窗口并发测试,库存不会再变负,这就是验收通过的标准。

6. 答辩前的一小时:把系统讲「活」的三次验证

6.1 三分钟自检脚本:端口、服务、登录页一次看清

答辩前不要只点开浏览器看页面,要验证整个链路。我固定用三件事检查:MySQL进程在不在、Tomcat端口有没有监听、登录页能不能返回正常状态。写成命令就是下面三行:

# Windows命令行三连查 tasklist | findstr mysqld netstat -ano | findstr :8080 curl -I http://localhost:8080/supermarket/login.jsp

前两条没有输出就是服务没起,第三条看返回的HTTP状态码。别嫌这三条命令粗暴,很多在浏览器里看不出来的问题,比如数据库服务没起来、端口被占用,命令一眼就定位了。现场机器如果没装curl,就手动确认地址栏里的端口和项目路径是对的,直接访问登录页看是否加载出样式。

6.2 两组演示数据,把业务闭环走给人看

演示最怕讲完一个功能忘了下一个。我的习惯是准备两份数据:一份基础数据,包含10个左右商品和3个用户;一份演示脚本,串起一次完整进货、一次完整销售、一次退货。演示时按脚本操作,每一步说清楚“我正在做什么、数据会发生什么变化”,而不是漫无目的地点菜单。比如销售演示时,我先把某商品库存数值记下来,卖出一件后打开库存页面指着数字变化说明,评委立刻能看懂系统在干什么。

最后一个建议:把控制台日志级别调低,隐藏调试信息。答辩现场控制台刷屏会盖住关键业务日志,看起来像系统不稳定。把日志级别改成WARN,只留错误信息,配合上面两条自检,大概率能顺滑收场。我自己吃过一次亏:当年答辩前只改了代码忘了重启MySQL服务,开讲时登录页一直转圈,评委眼里全是怀疑。从那次之后我养成一个习惯——无论改了什么配置,答辩前必须完整执行一遍“清空浏览器缓存→重启MySQL→重启Tomcat→走一遍演示脚本”的流程。这世上没有后悔药,但流程能帮你把翻车概率压到最低。希望帮到你。

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

返回列表