news 2026/10/17 10:44:04

软件缺陷知识体系全梳理:从定义、报告到管理与度量

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
软件缺陷知识体系全梳理:从定义、报告到管理与度量

干了这些年测试,真要说什么东西一路陪着我,那一定是软件缺陷(Bug)。2020年这个特殊的年份,远程办公成为常态,版本的迭代节奏反而更快了,缺陷管理的重要性被推到了前所未见的高度。很多新人一上来就急着学自动化、学性能测试,但说实话,“缺陷”这个最基础的知识板块如果没吃透,后面做再多高阶手段都是空中楼阁。

这篇文章就把2020年软件测试中关于软件缺陷的知识体系做一次完整梳理,从缺陷的定义、来源、报告、管理流程,到度量和排查技巧,一次性讲清楚。如果你是刚入行的测试工程师,准备面试的求职者,或者想补齐测试知识体系的开发人员,这篇文章可以直接当作一份“缺陷知识自检清单”来用。我尽量用实际工作中的例子说话,少讲空泛理论,多讲怎么落地。

1. 软件缺陷的定义与判定:不是“跑不通”才叫Bug

1.1 缺陷的三种“官方定义”

软件缺陷,英文叫Defect或Bug,但不同场景下叫法不一样,理解这些细微差别,是你和开发沟通时显得“专业”的第一步。教科书上通常把缺陷定义为:软件在运行过程中表现出来的、与用户需求或设计说明不一致的地方。

我习惯把它拆成三个层次来理解:

  • 错误(Error):源代码层面就已经写错了,比如把i < 100写成了i <= 100,这是“因”。
  • 缺陷(Defect):错误被代码“固定”下来,成为可被发现的静态问题,这是“果的存在形式”。
  • 故障/失效(Failure):程序跑起来之后,缺陷被触发,用户感知到了异常,这是“果的显现”。

打个比方,错误就是菜谱上的一个错别字,缺陷是厨师照着错别字做出来的那道有问题的菜,而失效是顾客吃到嘴里觉得难吃的那一刻。测试人员的核心工作,就是尽可能在“顾客吃到”之前,把隐藏在菜谱和成品里的“错”找出来。

1.2 判断标准:拿什么来衡量“这是缺陷”

实际工作里,经常会碰到测试和开发争论“到底是不是Bug”。我觉得与其争论,不如列一套判断标准。一个现象满足以下任何一条,都可以作为缺陷提交:

  • 与产品需求文档(PRD)中明确规定的功能行为不一致;
  • 与原型图、UI设计稿的视觉和交互要求不一致;
  • 用户按照常规操作流程使用时,出现程序崩溃、数据错误、白屏等问题;
  • 软件运行结果不符合行业通用规则或法律法规要求;
  • 未达到产品经理口头沟通时承诺的隐含预期(这类最容易被开发反杀,所以尽量落到文字再提)。

换句话说,缺陷不应只理解为“崩溃”“闪退”这些严重故障。一个按钮颜色不对、一段提示文案有错别字、一个输入框没做格式校验,在广义上都属于缺陷的范畴。这一点想通了,测试用例设计的粒度自然就出来了。

1.3 严重级别与优先级:两套维度,别混为一谈

这是缺陷知识体系里最容易搞混的一对概念,也是很多初级测试在缺陷单上翻车的重灾区。

严重级别(Severity)描述的是“这个缺陷对系统造成的破坏程度”,是从技术角度评估的;优先级(Priority)描述的是“这个缺陷需要多快被修复”,是从项目管理和业务角度评估的。严重级别高,不代表优先级一定高;反之亦然。

我一般把严重级别分成四档:

级别名称典型表现处理策略
1致命系统崩溃、数据丢失、主流程完全不可用必须立即修复,甚至需要版本回退
2严重核心功能受阻、有绕过方案但代价很大当个迭代内必须修复
3一般非核心功能异常、有合理的临时绕过方案排期修复即可
4轻微界面错别字、样式偏差、布局错乱有空就修,没空可延期

优先级则通常用等级或“立即处理、版本内处理、排期处理、暂不处理”这样的标签来表示。

举一个我自己踩过的坑:有一次某项目的登录页文案里有个错别字,测试新人标了个“致命”,理由是“用户看到的文字是错的”,但事实是功能完全正常、业务不受影响,就是一个轻微问题。相反,一个只影响“导出报表”操作、但该操作每周才用一次的缺陷,被标成了“一般”,却在周五下午阻碍了全员周报的输出。这种严重级别和优先级倒挂的情况,会让整个团队的执行节奏乱套。

注意:提交缺陷时,先判断技术破坏力填严重级别,再结合用户影响范围和业务紧急度判断优先级。如果项目有约定俗成的评分规则,一律按规则来。

1.4 缺陷生命周期:一张从生到死的流转图

一个缺陷从被提交到被关闭,会经历一系列状态变化,这个过程叫缺陷生命周期。不同团队叫法略有差异,但核心状态大体一致:

  • 新建(New):测试提交缺陷单。
  • 打开/确认(Open):开发或测试负责人确认这是一个有效缺陷。
  • 已修复(Fixed):开发完成了代码修复,等待验证。
  • 已验证/关闭(Closed):测试在最新版本上回归通过。
  • 重新打开(Reopened):测试验证失败,或发现修复不彻底。
  • 拒绝(Rejected):开发认为不是缺陷,或者重复、无法复现。
  • 延期(Deferred):确认是缺陷,但当前版本不修,留待后续版本。

实际工作中,状态机背后的意义比状态本身更重要。一个缺陷如果在“新建”和“打开”之间被驳回,往往是报告格式有问题或者信息严重不全;如果一个缺陷在“已修复”和“重新打开”之间反复横跳,那就要警惕,可能是修复方案只堵住了表层现象,没有解决根因。

2. 缺陷从哪来:追溯源头,比逮住Bug本身更有价值

2.1 开发各阶段的缺陷注入:越早犯的错,代价越昂贵

缺陷不是凭空产生的,它们在软件开发的各个阶段都有可能被“注入”。我给自己画过一张“缺陷来源地图”,每次分析版本问题时都会拿它来归类。

需求阶段的缺陷最贵,因为这时候的纰漏会被后续所有环节放大。常见的有:需求描述太模糊(比如“列表页要支持快速查看详情”,但“快速”到底是什么交互没人定义)、需求相互冲突(一个页面既要展示全部字段,又要保持视觉简洁)、需求变更后没有同步到设计文档。

设计阶段的缺陷同样隐蔽。逻辑分支遗漏、异常情况没有设计兜底方案、接口字段定义不完整,这类问题通常要等到系统联调甚至线上运行才会暴露。

编码阶段的缺陷是最多也最“容易”被发现的。边界值处理不当、空指针、并发访问没有加锁、异常被吞掉,典型如:用户输入一个超长字符串,界面直接崩溃,这就是典型的边界值缺陷。

环境与配置缺陷在2020年远程办公场景下尤其突出。本地环境正常、测试环境正常,一到生产环境就报错,多半是依赖的服务地址、数据库连接、环境变量、第三方SDK版本不对。还有一类数据缺陷,比如脏数据导致统计报表计算出错、历史存量数据与新格式不兼容。

我整理过这样一个对照表,初学者可以把它打印出来贴工位上:

阶段典型缺陷形态例子发现手段规避思路
需求逻辑遗漏、二义性登录失败提示文案只有成功场景需求评审、用例评审建立需求验收标准,用反向提问补全场景
设计状态缺失、接口不兼容订单取消后没有释放库存设计评审、接口文档走查采用状态机建模,定义完整的异常分支
编码边界溢出、空指针、并发冲突超过1000条记录时查询超时单元测试、代码评审、静态扫描用边界值分析和代码Review守住底线
环境配置错误、依赖缺失生产环境缺少某字体导致排版错乱环境巡检、发布Checklist用配置中心统一管理,环境差异自动化比对
数据脏数据、旧数据兼容老用户昵称含特殊字符导致页面报错数据迁移测试、线上巡检数据清洗、兼容性测试和灰度校验

2.2 测试并非“挑刺者”:缺陷来源分析的隐藏价值

很多刚做测试的朋友,把大部分精力放在“抓开发的小辫子”上,这是没理解缺陷来源分析的真正价值。做这个分析,目的从来不是找人背锅,而是帮助团队找到最容易出错的环节,然后动态调整测试策略。

举例来说,如果一个版本流出很多“需求变更导致的实现不一致”缺陷,说明需求沟通存在系统性缺陷,那么下个版本你应该把70%的精力放在需求评审和用例前移上,而不是把自动化脚本再扩100条。如果一个版本缺陷集中在订单支付这类核心交易的并发处理上,那你就该重点设计高并发场景的测试用例,而不是反复在界面上点按钮。

这也是我特别建议测试团队做“缺陷归因分类统计”的原因。把每个缺陷标注为需求类、设计类、编码类、环境类、数据类、兼容类等,每个迭代结束后花半小时归类汇总,你会慢慢从一个“执行用例的人”,变成“帮团队识别风险的人”,这完全是两种职业高度。

3. 缺陷报告的艺术:写出让开发“秒懂”的Bug单

3.1 核心心法:一分钟原则

写缺陷报告这件事,入门门槛极低,但想写好真不容易。我给团队定的标准是“一分钟原则”——开发收到你的缺陷单,在一分钟内能判断出这个问题是什么模块、什么现象、严重程度如何,这个单子才算合格。如果一个Bug单看完三分钟还不知道对方在说什么,别怀疑,不是开发没耐心,是你的报告写得有问题。

想要做到一分钟看懂,缺陷单必须包含几个核心要素:缺陷标题、前置条件、复现步骤、实际结果、预期结果、缺陷附件(截图或录屏)、环境信息、缺陷类型和级别。

3.2 缺陷标题:一句话说清楚“谁坏了,怎么坏的”

缺陷标题是bug单的第一印象,我见过太多人写“XXX页面显示异常”“某个功能不可用”这种不痛不痒的标题,开发看完根本不知道是哪个页面的哪个按钮出了什么问题。好的标题长这样:

  • “支付成功后订单状态未更新,订单列表仍显示待支付”
  • “iOS 14.2下首页轮播图切换偶发白屏,复现概率约30%”
  • “Excel导入超1000条数据时提示系统错误,无明确错误信息”

注意观察这几条标题的结构:核心模块 + 具体操作 + 实际现象。这就够了,不需要在标题里写一堆客套话。

反向对比一下:

不好的标题问题所在改成
页面有问题不知道哪个页面、什么问题“个人中心头像上传后显示裂图”
系统报错“报错”太笼统,没有具体错误信息“新增日程保存时弹出’系统错误’,无法保存”
登录很慢没有量化“慢”的程度和环境信息“弱网环境下(模拟4G限速)登录耗时超过10秒”

3.3 复现步骤:从“必现”到“可复现”

如果说标题是缺陷单的脸面,复现步骤就是缺陷单的内核。写复现步骤有三个要素,缺一不可:

前置条件:需要什么账号、数据、环境、权限。比如“需要已登录的企业管理员账号”“需要一个创建超过5000条数据的租户”“需要在Chrome浏览器无痕模式下访问”。

具体操作路径:要精确到单击、双击、长按,要写明输入的测试数据。很多人写“输入一个超长字符串”,这太含糊。“输入一行包含200个英文字母的文本”就叫精确。

实际结果与预期结果:写明程序实际给出的反应,以及你根据需求判断理应出现的反应。

这里有一个常见误区:很多测试人员习惯把“预期结果”省略掉,只写“出现异常”。但如果你不写预期结果,开发就无法判断当前行为到底是需求定义的“正常行为”还是BUG。有了预期结果一对比,问题性质立刻就清晰了。

有时候缺陷不是每次都能复现,比如偶发性的崩溃、偶发性的白屏。这类缺陷在步骤里要额外标注:

  • 已尝试的重试次数(比如“连续尝试10次,出现2次”)
  • 触发前的完整操作序列(不要跳步,哪怕是看似无关的停留时间也要写)
  • 现场留下的日志、异常堆栈、崩溃时间点

3.4 缺陷附件的正确姿势:截图、录屏、日志一个都不能少

我见过一些测试同学,截图拍得挺漂亮,但截图上没有标出问题区域,开发还得自己找半天。正确做法是:

  • 截图要在关键位置用红框或箭头标注;
  • 录屏要记录完整的复现过程,包括前置操作;
  • 日志要截取报错前后10分钟内的有效片段,不要丢一个几百MB的完整日志包上去;
  • 涉及数据问题的缺陷,要附上测试数据的构造方式,甚至导出一份脱敏数据快照。

再补一句,缺陷单里一定要写清楚“环境信息”:操作系统版本、浏览器版本、设备型号、App版本、后端接口版本号。2020年很多项目都是移动端+PC端+小程序多端并行,同一个功能在不同端上表现完全不一样,环境信息漏了,开发可能就得靠猜。

提示:如果是文本类的缺陷报告,可以用代码块格式展示复现步骤和日志,这样在缺陷管理系统里阅读起来会更清晰。

4. 缺陷管理与回归验证:让Bug从“提交”到“关闭”顺畅流转

4.1 缺陷状态流转与人员分工

缺陷管理的本质是“流程”,流程的核心是“闭环”。很多小型团队没有专门的测试平台,直接用表格或者在线文档记录缺陷,但无论用什么载体,流程逻辑必须健全。

我习惯把缺陷管理中的角色分成四类:

  • 测试人员:提交缺陷、回归验证、关闭缺陷、对缺陷的真实性负责。
  • 开发人员:修复缺陷、补充修复影响说明、在需要时驳回无效缺陷。
  • 测试负责人/测试经理:审核缺陷的有效性、分配缺陷处理优先级、协调争议缺陷。
  • 产品经理:裁决与需求理解不一致的缺陷、确认延期缺陷的排期。

流转规则上,有几个关键节点值得注意。开发提交“已修复”时,最好要求他在缺陷单里备注“根因分析”和“修复方案概要”,而不是简单改个状态。这样测试回归时就能判断这个修复会影响到哪些周边功能,回归范围和测试重点也就有了依据。

4.2 争议缺陷怎么处理:别让情绪代替逻辑

测试和开发对某个缺陷是否成立有分歧,这在每家公司都存在。我的处理原则是“先对需求,再对流程”。

第一步,翻需求文档和原型图。如果需求文档白纸黑字写了预期行为,那就按文档执行,没什么好争的。

第二步,如果需求文档没写或者写得不清晰,那就拉上产品经理做三方确认。产品经理说“这里就该这样”,那这个缺陷就成立;产品经理说“这里本来就应该由前端限制,后端不用管”,那就按产品定的规则走。

第三步,如果产品经理也拿不定主意,那就把它记录成“待确认缺陷”,继续开发而测试暂不阻塞发布。但一定要在缺陷单里留下明确的跟进责任人和时间点,避免这种悬而未决的单子拖到版本发版日才爆发。

这里遇到最多的一种对抗是:开发说“这是历史遗留问题,不是我这次改出来的”。这种情况下,我不会纠结于“谁改出来的”,而是先确认“当前版本是否有用户会因此受影响”。如果影响用户,就推动修复;如果只是存量数据问题且影响有限,则记录为技术债,排期修复。

4.3 回归测试策略:修复的Bug,要验证到什么程度才算“好”

回归验证很多人只做一件事:按照复现步骤看现象消失没有。这是远远不够的。

一次合格的回归,至少要覆盖三个层次:

  • 第一层:主现象验证。按复现步骤走一遍,确认原始缺陷不再出现。
  • 第二层:边界变体验证。在原复现步骤的基础上,修改数据、环境、操作顺序,确认缺陷没有在相邻场景下复发。比如,修复了“输入100个字符导致页面卡死”,你不仅要测100个字符,还要测101个、200个、特殊字符组合。
  • 第三层:关联功能验证。根据开发填写的“影响范围说明”,对同一模块的相关功能做冒烟。比如修复了“订单取消后库存不释放”,那订单列表、库存查询、再次购买等关联功能都得点一遍。

回归通过后,我建议第一时间在缺陷单里备注“本次验证的范围和结论”,而不是只把状态改成“关闭”。这样将来版本回溯时,每个缺陷的来龙去脉都清清楚楚。

有些团队会把“已验证待发布”这个状态单独抽出来,表示回归通过但版本尚未上线。等线上验证通过后,再由测试将缺陷最终关闭。这种做法对发布质量要求较高的项目特别适用,毕竟测试环境和生产环境的差异永远存在。

5. 缺陷度量与质量评估:用数据说话,不用感觉说话

5.1 几个必备的缺陷度量指标

没有度量就没有改进,缺陷维度同样如此。我在2020年最常用的几个指标如下:

缺陷密度(Defect Density):缺陷数 ÷ 代码规模(通常是千行代码或功能点数),用来衡量某个模块的质量水平。如果A模块的缺陷密度远高于B模块,那就说明A模块的开发复杂度或协作质量存在问题,值得重点关注。

缺陷检出率(Defect Detection Percentage):测试阶段发现的缺陷数 ÷ (测试阶段发现缺陷数 + 线上用户反馈缺陷数)× 100%。这个指标衡量测试团队发现缺陷的能力,数值偏低就说明测试覆盖存在盲区。

缺陷去除率(Defect Removal Efficiency,DRE):某个阶段(比如测试阶段)之前发现并修复的缺陷数 ÷ 该阶段之前注入的缺陷总数。它可以分阶段统计,比如需求评审阶段、设计评审阶段、编码评审阶段、测试阶段各自能拦截多少缺陷。很多团队只测“测出来多少”,忽视了需求评审和设计评审阶段就能拦截的部分,其实那里的性价比更高。

5.2 ODC分类思想:给每个缺陷一个“身份标签”

1992年,IBM的一位工程师提出了ODC(Orthogonal Defect Classification,正交缺陷分类法),核心思想很简单:不要只看缺陷“表面现象”,而是给每个缺陷打上多维度的“身份标签”,比如缺陷来源(需求/设计/编码)、缺陷类型(功能/性能/接口/界面/兼容性)、缺陷触发条件(边界/并发/异常/时序)、缺陷影响(数据/功能/安全性)。

打标签本身不难,难的是坚持。我推荐每个迭代结束后做一次“缺陷分类统计”,哪怕只统计“缺陷来源”和“缺陷类型”两个维度,坚持三个迭代,你就能看出不同模块的质量趋势。

举个例子,某版本统计后发现,“并发类”缺陷占比超过40%,这通常不是某个程序员代码写得不好,而是系统架构层面缺少并发控制的统一方案。这时候你再怎么让单个开发多写单元测试都无济于事,必须推动架构层面做一次专项治理。这就是缺陷度量真正的价值——它让你从个别问题的解决上升到系统性问题的治理。

5.3 缺陷评审会:怎么开才不流于形式

缺陷评审会(Bug Review)是很多团队都会有的会议,但也是最容易变成“念单子大会”的会议。我的建议是,会议之前,测试负责人先做一轮数据梳理,把缺陷单按模块、级别、类型归类,挑出Top 10的高价值缺陷重点剖析。

会上重点讨论三个问题:

  • 这个缺陷为什么测试阶段没有拦截到?是覆盖遗漏,还是测试环境差异,还是用例设计问题?
  • 这个缺陷的根因是什么?是需求缺失、编码错误,还是设计缺陷?
  • 这个缺陷的修复是否引发新的风险?影响的模块是否需要补充回归?

会议结束,输出一份“缺陷质量周报”,包含模块缺陷分布、遗留缺陷趋势、缺陷关闭时长、线上反馈缺陷数等核心数据。这份周报不追求大而全,但一定要能回答领导层的三个问题:目前质量处于什么水平?主要风险在哪里?下一步要干什么。

6. 常见问题与排查技巧实录

6.1 高频问题速查表

整理了一份测试日常工作中高频遇到的缺陷问题速查表,每一个都是我自己或团队真实踩过的坑。

场景现象排查方向最佳处理实践
缺陷提交后被开发“秒拒”开发说“我这跑是好的”环境配置差异、数据状态差异在缺陷单里同步环境和数据快照,必要时远程协助复现
偶发缺陷不可复现同一个操作有时异常有时正常内存时序、网络延迟、并发冲突持续抓日志、增加埋点、多跑几遍并记录触发频率
缺陷单信息完整但没人处理单子躺在“打开”状态很久优先级设置是否合理、责任分配是否明确升级给测试负责人进行人工协调
回归测试漏测了关联功能原Bug修复但周边功能坏了回归清单覆盖不完整回归前找开发确认影响面,维护一条“关联用例映射表”
线上反馈了一个不曾在测试环境出现的Bug生产环境异常,测试环境正常线上数据与配置差异、流量差异优先拉取线上日志、梳理线上环境配置,限制“高概率复现才能修”的思维

6.2 典型排查实录:不可复现Bug的“破案”思路

2020年我最难忘的一个排查案例是这样的:某个Web项目的有用户反馈,在提交表单时会偶发“浏览器卡死几秒,随后提示页面无响应”,但测试人员在测试环境怎么操作都复现不了。

我们先是按照社区里最常见的建议,找用户要了浏览器版本、系统版本、网络类型,一致,可依然复现不了。后来我让用户提供了一个完整的操作录屏,才发现用户在打开表单页之前,先开了两个资源占用极高的在线协作文档页面,内存占用已经超过80%,表单页又被设计得特别重,提交瞬间触发了浏览器崩溃阈值。

这个案例有两个教训:一是很多“不可复现”的缺陷,本质上是被前置条件隐藏了,你的复现步骤里没有包含那些看起来无关紧要的上下文信息;二是在远程协作时代,让用户提供一份录屏的沟通成本其实很低,远比测试人员盲目猜测要高效得多。

6.3 我的几点避坑心得

最后分享几个压箱底的避坑经验,都是我实际工作中一点点攒出来的。

缺陷单里写上“期望修复版本”是高风险操作。你填了一个版本号,开发可能就只在这个版本修,其他版本全都不管。更好的做法是只写优先级,让项目经理来排期。

不要把“一个流程的多个问题”合并成一个缺陷单。比如“注册页面有3个问题”,有些人图省事就建一个单子,结果开发修完一个改状态为“已修复”,测试验证时发现另外两个还挂着,反而把流程搞乱了。记住:一个缺陷单只描述一个独立问题。

缺陷单不是发泄情绪的出口。我见过有人在备注里写“开发怎么写的代码,这都能报错”,这种情绪发泄除了制造对立没有任何价值。缺陷单是协作工具,不是问责工具。

如果发现缺陷率高发集中在某些测试用例区域,要优先怀疑自己的测试设计,而不是开发的质量。用例本身设计得边界模糊、步骤笼统,很容易诱发开发与测试之间的无效沟通和重复劳动。

回到开头那句话,2020年大家都很忙,版本节奏比以往任何时候都要快。在这种情况下,缺陷知识的力量不在于“你会开一张标准bug单”,而在于你能用这套知识把“发现缺陷—定位根因—推动修复—验证回归—沉淀度量”这条链路跑通。把这件事做成习惯的团队,发布时不慌,线上出问题时有迹可循,测试人员也能从“点点点”的工作状态里跳出来,真正成为一个用数据说话的质量守护者。

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

Linux磁盘管理进阶:LVM、RAID与配额实战指南

1. 从“能用”到“好用”&#xff1a;磁盘管理进阶到底在解决什么问题上一篇聊完fdisk分区、mkfs格式化、mount挂载这条基础链路&#xff0c;不少朋友留言说“分完区能用不就行了”。确实&#xff0c;单机跑个小服务&#xff0c;传统分区方案足够。但只要你经历过磁盘写满业务挂…

作者头像 李华
网站建设 2026/10/17 10:42:39

开源代码审查CLI工具:基于Git与LLM的结构化审查实践

1. 项目概述&#xff1a;一个真正能落地的开源代码审查 CLI 工具“open-code-review”这个名字乍一听像某个 GitHub 上刚起步的玩具项目&#xff0c;但如果你真把它当成一个普通 CLI 工具去试&#xff0c;很快就会发现——它不是“又一个调用 LLM 的 wrapper”&#xff0c;而是…

作者头像 李华
网站建设 2026/10/17 10:42:33

PPPL新发现:先加热后压缩,聚变点火或许更容易

引言近日&#xff0c;普林斯顿等离子体物理实验室&#xff08;PPPL&#xff09;发文称&#xff0c;他们为聚变点火找到了一条可能更省能量的路径——其做法是颠倒传统顺序&#xff1a;先加热等离子体&#xff0c;再提高其密度。PPPL计算显示&#xff0c;改变加热与压缩的先后顺…

作者头像 李华
网站建设 2026/10/17 10:41:21

JavaWeb课程设计实战:手写Servlet+JSP打造个人主页与家乡档案系统

1. 从课程设计到个人名片&#xff1a;这个项目到底在做什么很多同学拿到“JavaWeb课程设计”这个题目时&#xff0c;第一反应是去网上找一套现成的后台管理系统模板&#xff0c;改改标题就交差。但“展示和管理自己和家乡的信息”这个题目&#xff0c;其实比想象中更有发挥空间…

作者头像 李华