在当今竞争激烈的IT行业,技术面试已经成为求职过程中至关重要的环节。作为一名经历过数十场技术面试的Java开发者,我深知一套高效的面试刷题系统对求职者的价值。这个基于SpringBoot+SSM的面试刷题平台,正是为了解决求职者在准备技术面试时的痛点而设计。
这个系统不同于普通的题库网站,它整合了以下几个核心功能:
我在开发过程中特别注重还原真实面试场景,比如在算法题部分加入了在线代码编辑器,支持自动补全和语法高亮,就像在实际面试中使用白板编程一样。
系统采用经典的三层架构,但针对面试场景做了特殊优化:
code复制前端层:Thymeleaf模板引擎 + Bootstrap5 + jQuery
业务层:SpringBoot 2.7 + Spring MVC + MyBatis Plus
数据层:MySQL 8.0 + Redis缓存
选择这样的技术栈主要基于以下考虑:
为避免用户反复刷到相同题目,我设计了一套权重随机算法:
java复制public Question getRandomQuestion(Long userId, String category) {
// 获取用户历史答题记录
List<AnswerRecord> records = recordService.getByUser(userId);
// 计算每道题的权重(答错次数越多权重越高)
Map<Long, Integer> weightMap = records.stream()
.filter(r -> !r.isCorrect())
.collect(Collectors.groupingBy(
AnswerRecord::getQuestionId,
Collectors.summingInt(r -> 1)));
// 加入随机因子
Random random = new Random();
return questionMapper.selectByCategory(category).stream()
.max(Comparator.comparingInt(q ->
weightMap.getOrDefault(q.getId(), 0) + random.nextInt(10)))
.orElseThrow();
}
为支持在线编程题即时执行,我基于Docker搭建了安全沙箱环境:
bash复制# Dockerfile配置
FROM openjdk:17
RUN useradd -m runner && \
chmod 755 /home/runner && \
chown runner:runner /home/runner
USER runner
WORKDIR /home/runner
这个模块包含几个关键技术点:
题目分类体系:
记忆曲线算法:
根据艾宾浩斯遗忘曲线,系统会自动安排复习时间:
sql复制CREATE TABLE review_schedule (
user_id BIGINT,
question_id BIGINT,
next_review_time DATETIME,
memory_strength INT DEFAULT 1,
PRIMARY KEY (user_id, question_id)
);
真实还原大厂面试流程:
关键实现代码片段:
java复制@PostMapping("/mock/start")
public R startMockInterview(@RequestBody MockConfig config) {
// 验证配置合法性
if (config.getDuration() <= 0) {
throw new BizException("面试时长必须大于0");
}
// 生成面试会话
MockSession session = new MockSession();
session.setUserId(SecurityUtils.getUserId());
session.setStartTime(LocalDateTime.now());
session.setEndTime(session.getStartTime().plusMinutes(config.getDuration()));
// 按配置筛选题目
List<Question> questions = questionService.selectByConfig(config);
session.setQuestions(questions);
// 存入Redis并设置过期时间
String sessionId = "mock:" + UUID.randomUUID();
redisTemplate.opsForValue().set(sessionId, session);
redisTemplate.expire(sessionId, config.getDuration() + 10, TimeUnit.MINUTES);
return R.ok().put("sessionId", sessionId);
}
sql复制-- 题目表
CREATE TABLE question (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200) NOT NULL,
content TEXT NOT NULL,
category VARCHAR(50) NOT NULL,
difficulty TINYINT DEFAULT 1,
answer TEXT,
analysis TEXT,
is_deleted TINYINT DEFAULT 0,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 用户答题记录表
CREATE TABLE answer_record (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
question_id BIGINT NOT NULL,
is_correct TINYINT(1) DEFAULT 0,
user_answer TEXT,
duration INT COMMENT '答题耗时(秒)',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_question (user_id, question_id)
);
读写分离:
缓存策略:
java复制@Cacheable(value = "questions", key = "#id")
public Question getById(Long id) {
return questionMapper.selectById(id);
}
推荐使用Docker Compose编排服务:
yaml复制version: '3'
services:
app:
image: interview-app:1.0
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- redis
- mysql
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- redis_data:/data
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=yourpassword
volumes:
- mysql_data:/var/lib/mysql
volumes:
redis_data:
mysql_data:
Spring Boot Actuator集成:
properties复制management.endpoints.web.exposure.include=health,metrics,info
management.endpoint.health.show-details=always
Prometheus监控配置:
yaml复制- job_name: 'interview-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app:8080']
并发提交问题:
多个用户同时提交答案时出现数据竞争,解决方案:
java复制@Transactional
public void submitAnswer(AnswerDTO dto) {
// 使用SELECT FOR UPDATE加锁
Question question = questionMapper.selectForUpdate(dto.getQuestionId());
// 业务处理...
}
XSS防护:
用户提交的代码需要过滤特殊字符:
java复制public String sanitizeCode(String code) {
return HtmlUtils.htmlEscape(code);
}
懒加载题目解析:
只有当用户点击"查看解析"时才加载详细内容
批量处理用户行为:
将用户的浏览、收藏等操作批量提交,减少数据库压力
前端资源优化:
AI面试官功能:
集成NLP技术分析用户答案质量
面试模拟视频系统:
接入WebRTC实现视频面试模拟
企业定制题库:
为企业HR提供专属题库管理后台
学习路线规划:
根据用户目标岗位智能推荐学习路径
这个项目从最初的想法到最终实现,我花了近3个月时间,期间重构了两次核心架构。最大的收获是深刻理解了如何平衡系统的灵活性和性能。比如在题目分类体系设计上,最初使用的是固定三级分类,后来改为标签系统,大大提升了扩展性。