返回 Bug 清单
BUG-0409project-13高已修复backend-logic

补全选项的逻辑把无选项的主观题强转成单选题、覆盖答案为 A 并伪造占位选项,污染 24% 题库与 IRT 能力估计

发现:2026-10-03验证:2026-10-09置信度:95%

症状

用户在练习中遇到「选项是 A.选项A」的题,无法作答;因为这些题的正确答案被伪造成 "A",随手一选就算答对,虚假的正确记录抬高 IRT 的能力值 θ,使自适应练习难度整体失真。

根因

QuestionService.fillMissingOptions 为了让所有题都能用选择题界面渲染,对无选项题型做了兜底:题型含「计算」且非单/多选时改成单选题,答案若不匹配 [A-D] 就 setAnswer("A");随后为单/多选/未知题型生成 "A. 选项A"…"D. 选项D" 占位选项。于是计算分析题(122 道)与综合题(176 道)共 298 道(占题库 1247 的 24%)被伪装成单选题,真实答案(会计分录、长篇论述)在响应中被丢弃。

修复方案

①新增 isNonChoiceType(qtype)(题型含 计算/综合/简答/案例/论述/分析 且非单/多选/判断),在 fillMissingOptions 入口直接 return,保持原题型、原答案、无选项;②移除末尾分支中残留的 setQuestionType("单选题");③在全部 7 个选题入口(QuestionRepository 新增 findRandomChoiceBySubject 做查询层过滤、QuestionService、IrtService 的 company 分支与非 company 分支及冷启动兜底、EnhancedIrtService、AdaptivePracticeService、ExamPaperService、DynamicQuestionBankService)统一排除主观题;④判定逻辑收敛为单一 public 静态方法,避免各入口各写一份而漂移;⑤加对照实验测试:测试内原样复现修复前的代码路径,先证明它确实毁坏数据,再证明修复后不再发生(仅断言「修复后没坏」是弱证明)。

错误签名

API 返回 options=["A. 选项A","B. 选项B","C. 选项C","D. 选项D"],question_type 由「计算分析题」变为「单选题」,answer 被改写为 "A";DB 中这些题 options 为 NULL、answer 为会计分录长文本

技术信息

来源项目

project-13

涉及文件

backend/src/main/java/com/project-13/service/QuestionService.java, backend/src/main/java/com/project-13/repository/QuestionRepository.java, backend/src/main/java/com/project-13/service/IrtService.java +4

标签

数据伪造, 能力估计污染, 占位符, 弱证明, ID碰撞补交...