# programming-backend **Repository Path**: xiaosaima/programming-backend ## Basic Information - **Project Name**: programming-backend - **Description**: 编程刷题平台后端页面 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-07-16 - **Last Updated**: 2025-07-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 项目简介和计划 基于Next.js服务端渲染+Spring Boot+Redis+MySQL+Elasticsearch的面试刷题平台。管理员可以创建题库、题目和题解,并批量关联题目到题库;用户可以注册登录、分词检索题目、在线刷题并查看刷题记录日历等。项目涉及大量企业级新技术的讲解,比如使用数据库连接池、缓存、高级数据结构来提升性能。通过流量控制、熔断、动态IP黑白名单过滤来提升系统和内容的安全性。 第一阶段,开发基础的刷题平台,熟悉项目开发流程,实战Next.js服务端渲染+SpringBoot应用的快速开发。 第二阶段,对项目功能进行扩展,实战企业主流后端技术如Redis缓存和高级数据结构、Elasticsearch搜索引擎、Druid连接池、并发编程的应用。使用AI进行相关题目题解的生成 第三阶段,对项目安全性进行优化,比如基于Sentinel进行网站流量控制和熔断、基于Nacos实现动态的IP黑白名 单。最终将项目上线并保证可用性。 ## 需求分析 ![img.png](img.png) ## 功能梳理 ### 需求优先级 根据核心业务流程,明确需求开发的优先级 - P0 核心,非做不可 - P1 重点功能,最好做 - P2 实用功能,有空就做 - P3 可做可不做,时间充裕可以考虑 ### 基础功能(全是 P0) - 用户模块 - 用户注册 - 用户登录(暂定只需账号密码) - 查看和修改自己的部分资料 - 【管理员】管理用户---基础增删改查 - 题库模块 - 查看题库列表(Java基础,进阶,前端) - 查看题库详情(题库中的题目) - 【管理员】管理题库---基础增删改查(这里要关联题目表) - 题目模块 - 题目搜索 - 查看详情(查看题目,背题) - 【管理员】管理题目---基础增删改查(这里要关联题库表) - 【管理员】AI 自动生成题目和题解功能(使用火山引擎) ### 学习新功能(P1 ~ P2) - 批量管理题目(必须学)P1 - 【管理员】批量向题库中添加 - 【管理员】批量从题库中移除题目 - 【管理员】批量删除题目/题目 - 分词题目搜索P1 - 用户刷题记录日历图P1 - 动态 IP 白名单过滤P2 ## 技术选型 ### 前端 - ⭐ React 18 框架 - ⭐ Next.js 服务端渲染 - ⭐ Redux 状态管理 - Ant Design 组件库 - 富文本编辑器组件 - 前端工程化:ESLint + Prettier + TypeScript(代码校验、美化) - OpenAPI 前端代码生成 ### 后端 - Spring Boot 框架 + Maven 多模块构建 - MySQL 数据库 + MyBatis-Plus 持久层框架 + MyBatis X 代码生成 - ⭐ Redis 分布式缓存 - ⭐ Redission 分布式锁 +BitMap + BloomFilter - ⭐ Elasticsearch 搜索引擎 - ⭐ Druid 数据库连接池 + 并发编程 - ⭐ Sentinel 流量控制 - ⭐ Nacos 配置中心 - ⭐ AI 火山引擎 - ⭐ 多角度项目优化:性能、安全、可用 - ## 架构设计 ![img_1.png](img_1.png) ## 库表设计 数据库名:program ### 1、用户表 #### 核心设计 用户表的核心是用户的账号密码和个人信息,SQL如下: ```sql -- 用户表 CREATE TABLE IF NOT EXISTS USER ( id BIGINT auto_increment COMMENT 'id' PRIMARY KEY, userAccount VARCHAR ( 256 ) NOT NULL COMMENT '账号', userPassword VARCHAR ( 512 ) NOT NULL COMMENT '密码', userName VARCHAR ( 256 ) NULL COMMENT '用户昵称', userAvatar VARCHAR ( 1024 ) NULL COMMENT '用户头像', userProfile VARCHAR ( 512 ) NULL COMMENT '用户简介', userRole VARCHAR ( 256 ) DEFAULT 'user' NOT NULL COMMENT '用户角色:user/admin/ban', editTime datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '编辑时间', createTime datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间', updateTime datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', isDelete TINYINT DEFAULT 0 NOT NULL COMMENT '是否删除', INDEX idx_id ( id ) ) COMMENT '用户' COLLATE = utf8mb4_unicode_ci; -- 添加了更多信息 CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id', `userAccount` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '账号', `userPassword` varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码', `userName` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户昵称', `userAvatar` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户头像', `userProfile` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户简介', `userRole` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'user' COMMENT '用户角色:user/admin/ban', `editTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '编辑时间', `createTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updateTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `isDelete` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除', `phoneNumber` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号', `email` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '邮箱', `grade` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '年级', `workExperience` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '工作经验', `expertiseDirection` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '擅长方向', PRIMARY KEY (`id`), KEY `idx_id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1891381123345903618 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户'; ``` editTime 编辑时间和 updateTime 更新时间的区别是:编辑时间表示用户编辑个人信息的时间(需要业务代码来更新),而更新时间表示这条用户记录任何字段发生修改的时间(由数据库自动更新) ### 2、题库表 #### 核心设计 题库表核心是他们的标题、描述、图片等,SQL如下: ```sql -- 题库表 create table if not exists question_bank ( id bigint auto_increment comment 'id' primary key, title varchar(256) null comment '标题', description text null comment '描述', picture varchar(2048) null comment '图片', userId bigint not null comment '创建用户 id', priority int default 0 not null comment '优先级', viewNum int default 0 not null comment '浏览量', editTime datetime default CURRENT_TIMESTAMP not null comment '编辑时间', createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', isDelete tinyint default 0 not null comment '是否删除', index idx_title (title) ) comment '题库' collate = utf8mb4_unicode_ci; ``` 重点: 1.其中,picture 存储的是图片的 URL 地址,不是完整的图片文件。通过 userId和用户表关联,在本项目中只有管理员才能创建题目。 2.用户可能有按照题目搜索题库的需求,故给 title 字段加上索引。 3.考虑到题库排序功能,给基础的题库表加上 priority 显示优先级字段,可以根据该字段排序,此字段 还可实现题库的精选和置顶,如 priority =1000 的题库表示精选题库,priority=10000 的题库表示置顶。 4.写到这里突发奇想一个题库浏览量功能,增加一个 viewNum 字段,每次进入该题库的题目详情页面时该字段 +1,同时还可以根据该字段对于题库进行排序。(可以拓展一个用户浏览数,同一个用户浏览同一个题目最多 +1,这个可能要额外创建一个表,有时间再实现)。 ### 3、题目表 ```sql -- 题目表 create table if not exists question ( id bigint auto_increment comment 'id' primary key, title varchar(256) null comment '标题', content text null comment '内容', tags varchar(1024) null comment '标签列表(json 数组)', answer text null comment '推荐答案', userId bigint not null comment '创建用户 id', viewNum int default 0 not null comment '浏览量', thumbNum int default 0 not null comment '点赞数', favourNum int default 0 not null comment '收藏数' priority int default 0 not null comment '优先级', source varchar(512) null comment '题目来源', editTime datetime default CURRENT_TIMESTAMP not null comment '编辑时间', createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', isDelete tinyint default 0 not null comment '是否删除', index idx_title (title), index idx_userId (userId) ) comment '题目' collate = utf8mb4_unicode_ci; ``` ### 4、题目题库关系表 #### 核心设计 同一个题库可以有多个题目,同一个题目可以属于多个题库,因此新建一个关系表方便记录操作。SQL如下: ```sql -- 题库题目表(硬删除) create table if not exists question_bank_question ( id bigint auto_increment comment 'id' primary key, questionBankId bigint not null comment '题库 id', questionId bigint not null comment '题目 id', questionOrder int default 0 not null comment '题目顺序(题号)', userId bigint not null comment '创建用户 id', createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', UNIQUE (questionBankId, questionId) ) comment '题库题目' collate = utf8mb4_unicode_ci; ``` 重点: 1.上述代码中的 userId 表示添加题目到题库的用户 id,目前设计仅管理员可实现此操作。 2.如上,关联表中的数据记录仅由管理员维护,直接采取硬删除方式,于此 createTime 时题目加入到题库的时间。 3.通过给题库 id 和题目 id 添加联合唯一索引,防止一个题目被重复添加进同一个题库,在设计时,要将 questionBankId 放在前面,因为数据库中大部分查询是基于 questionBankId 字段进行,例如查询某个题库的所有问题或者在一个题库中查询特定的问题,将 questionBankId 放在见面符合查询模式,使得查询更高效(索引最左前缀原则)。 4.添加 questionOrder 便于对题库重点题目进行排序,如果要实现任意移动题目顺序的功能,可能每次要更新多条记录的顺序,比较影响性能。如果追求更高性能的话,可以先在内存中计算出要变更的题目顺序,以减少更新的记录数。比如将第 100 题移动到第 98 题,只需要修改几条记录的顺序,不影响前面的题目。 5.这里不想设计逻辑删除,此表记录并没有啥卵用