Java+MySQL实现在线考试系统(智能组卷+自动评分)

技术选型

后端框架:Spring Boot 2.7.x + MyBatis-Plus
数据库:MySQL 8.0(支持JSON字段存储动态题型)
前端技术:Vue 3 + Element Plus(可选,若需前后端分离)
智能组卷算法:遗传算法/权重随机法
自动评分引擎:规则引擎(Drools)或自定义逻辑


核心模块设计

数据库表结构

用户表(user)

CREATE TABLE user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(100) NOT NULL,
    role ENUM('admin', 'teacher', 'student') NOT NULL
);

题库表(question_bank)

CREATE TABLE question_bank (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    type ENUM('single_choice', 'multi_choice', 'true_false', 'fill_blank', 'essay') NOT NULL,
    content JSON NOT NULL,  -- 存储题目主干、选项、答案等动态结构
    difficulty TINYINT DEFAULT 1,  -- 1-5级难度
    subject_id BIGINT NOT NULL,  -- 关联学科
    knowledge_tags VARCHAR(255)  -- 知识点标签,逗号分隔
);

试卷表(exam_paper)

CREATE TABLE exam_paper (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(100) NOT NULL,
    rule JSON NOT NULL,  -- 组卷规则:题型分布、难度系数等
    user_id BIGINT NOT NULL  -- 组卷人
);

考试记录表(exam_record)

CREATE TABLE exam_record (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    paper_id BIGINT NOT NULL,
    answers JSON NOT NULL,  -- 存储考生答案
    score DECIMAL(5,2),
    auto_score BOOLEAN DEFAULT TRUE  -- 是否自动评分
);


智能组卷实现

基于权重的随机组卷
public List<Question> generatePaper(PaperRule rule) {
    // 按题型、难度、知识点权重筛选题目
    Map<String, Integer> typeDistribution = rule.getTypeDistribution();
    List<Question> paper = new ArrayList<>();
    
    typeDistribution.forEach((type, count) -> {
        List<Question> candidates = questionBankMapper.selectByTypeAndDifficulty(
            type, 
            rule.getDifficulty(),
            rule.getKnowledgeTags()
        );
        Collections.shuffle(candidates);
        paper.addAll(candidates.stream().limit(count).toList());
    });
    return paper;
}

遗传算法优化组卷

适用于高阶需求,通过适应度函数(覆盖度、难度系数、区分度)迭代优化试卷组合。


自动评分逻辑

客观题评分
public BigDecimal scoreObjective(ExamRecord record) {
    ExamPaper paper = paperMapper.selectById(record.getPaperId());
    Map<Long, String> correctAnswers = parseAnswers(paper.getAnswerKey());
    Map<Long, String> userAnswers = parseAnswers(record.getAnswers());
    
    return userAnswers.entrySet().stream()
        .map(e -> {
            if (e.getValue().equalsIgnoreCase(correctAnswers.get(e.getKey()))) {
                return paper.getQuestionScore(e.getKey());
            }
            return BigDecimal.ZERO;
        })
        .reduce(BigDecimal.ZERO, BigDecimal::add);
}

主观题评分(简版)
# 使用余弦相似度计算文本答案匹配度(需接入NLP库)
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

def score_essay(model_answer, student_answer):
    vectorizer = TfidfVectorizer()
    tfidf = vectorizer.fit_transform([model_answer, student_answer])
    return cosine_similarity(tfidf[0], tfidf[1])[0][0] * max_score


关键优化点

性能优化

  • 题库分库分表:按学科拆分question_bank
  • Redis缓存:热点试卷模板、学生历史成绩

安全措施

  • 防SQL注入:MyBatis-Plus内置防护
  • 考试防作弊:随机题目顺序 + 选项乱序

扩展性设计

  • 可插拔评分引擎:通过策略模式切换不同评分算法
  • 微服务化:将组卷、考试、评分拆分为独立服务

部署建议

  1. MySQL配置读写分离,组卷查询走从库
  2. 定时任务:凌晨执行试卷分析统计(ELK方案)
  3. 监控:Prometheus + Grafana监控JVM和SQL性能
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值