面试刷题项目
快来分享你的内容吧~
- 02-12 00:09·后端开发
- 2025-11-05·Java后端在面试刷题平台中,我使用 nacos 来配置 sentinel 的 rules 的时候,经常遇到修改了配置却监听不到情况,直到我重启 nacos 这种情况才得到解决,但可能在一会又会有这种情况,想知道大家又遇到这种情况吗?又是怎么解决的?HANAdes:好像是偶发的问题,现在又不会出现了。。。现在拓展实现了:使用 nacos 管理 sentinel 的规则,同时启动时自动加载黑名单以及 sentinel 规则,而不是被动监听 nacos 的修改230分享
- 2025-11-03·Java后端
- 2025-11-02·Java后端SpringBoot3 实测 能使用 Druid 控制台方案!网上基本没有其它解决方案,因为他们很多都是 SpringBoot2 的查看全文leikooo:我也遇到过,有时候是识别不出来但是可以正常使用211分享
2025-10-24·@官方运营 学习、求职、生活问题欢迎交流
2025-07-16·后端- 2025-04-10·后端开发智能面试刷题平台 的AI生成题目功能,被面试官问到如果生成类似的但有微小差异的题目上要怎么处理,结果语塞没回答上来,朋友们有什么好的想法吗?鱼友4189:需求不明确啊,是每次生成的题目类似,还是什么意思280分享
- 2025-04-09查看全文有人接毕设单子嘛?代码+部署+讲解。😘 鱼皮的面试刷题平台功能扩展(前后端): 点赞、收藏、发帖、评论、用户查看收藏列表、用户查看我的题目、用户个人信息(头像昵称修改)、管理员审核题目。 ...编程导航_小y:项目群里可以问问其他鱼友,私聊小助手拉你进面试刷题项目群310分享
- 2025-03-31·26届java后端
智能面试刷题平台学习笔记(前端)(1)
## 1、客户端渲染与服务端渲染 ### **客户端渲染CSR**: 客户端先向服务器请求得到html文件,html文件里面包含很多js脚本,这些js脚本在浏览器运行,再动态地请求后端数据,得到后端响应后将后端数据渲染到页面上。 ### **服务端渲染SSR**: 1. 网页在服务器就可以得到完整的html(并且服务端已经把所有内容渲染完毕),直接返回给客户端,客户端收到html文件后不用再去发起后端请求,直接渲染页面。 2. 好处是SSR可以在首次加载展示所有内容,减少白屏时间;并且SSR更有利于SEO,因为SSR直接获取到整个HTML包括内容,有利于搜索引擎通过爬虫直接抓取; 3. 缺点是增加了服务器的负载。 4. 实现服务端渲染的技术有jsp、PHP,现在有分别基于react或vue的next.js ## 2、其他渲染方式 ### **静态网站生成**: 1. 在构建阶段生成静态HTML(服务端渲染是用户请求时生成),本质上也是客户端渲染,但不需要动态请求后端。 2. 静态文件可以由内容分发网络CDN或静态服务器提供 3. 优点高性能、SEO友好、简化基础设施 4. 不支持内容变化频繁的页面、如果静态文件大,构建时间长 ### **增量静态生成**: 1. 相比于静态网站生成,允许部分页面在构建之后更新,无需重新构建整个站点 2. 这样就可以减少构建时间,但是架构复杂、维护成本高 ## 3、结合使用 ### **部分预渲染**: 1. 将客户端渲染与服务端渲染结合 2. 构建或请求时,把静态部分预先渲染。页面加载时,动态部分有js在客户端加载并渲染 3. 通过水合,客户端的js接管已经渲染的静态内容,并且处理交互逻辑 ### 同构渲染: 1. 同一套代码可以在客户端和服务端运行,在服务端渲染页面初始化内容,由客户端接管渲染和交互 2. 本项目采用的就是基于Next.js进行同构渲染
在面试刷题平台中,我使用 nacos 来配置 sentinel 的 rules 的时候,经常遇到修改了配置却监听不到情况,直到我重启 nacos 这种情况才得到解决,但可能在一会又会有这种情况,想知道大家又遇到这种情况吗?又是怎么解决的?
通过注解实现自动使用 HotKey 探测并缓存
首先我们要定义注解 `AutoHotKey`: ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AutoHotKey { @NotNull String keyPrefix() default ""; @NotNull Class<?> valueType(); } ``` 需要的参数是 **key 的前缀**,以及**结果的类型**(方便做类型的转换),使用的目标是方法,使用时机则自然是运行时。 然后进行 AOP 编程,进行环绕通知: 实现的困难点就是如何获取 id 作为 key 的后缀。 ```java private Long getId(Object[] args) { for (Object arg : args) { if (arg != null) { Long id = getIdFromArg(arg); if (id != null && id >= 0) { return id; } } } return null; } private Long getIdFromArg(Object arg) { if (arg instanceof Long) { return (Long) arg; } Long id = null; if (arg != null) { try { // 使用getId()方法获取id Method getIdMethod = arg.getClass().getMethod("getId"); Object idValue = getIdMethod.invoke(arg); if (idValue instanceof Long) { id = (Long) idValue; } if (id != null && id > 0) { return id; } } catch (NoSuchMethodException e) { return null; } catch (Exception e) { throw new BusinessException(ErrorCode.SYSTEM_ERROR); } } return id; } ``` > [!IMPORTANT] > > 没有做过多的校验,只能祈祷开发者传入的参数中有 `getId()` 方法,而且第一个有 `getId()` 方法的参数就是我需要的那一个。(或者参数本身就是 `Long` 类型),所以只适用于以 `Long` 类型参数 为 key 后缀 的时机。(要做其它的校验也可以,有点懒 orz) 最后完整的实现是这样的; ```java @Aspect @Component @Slf4j public class HotKeyInterceptor { @Around("@annotation(autoHotKey)") public Object autoHotKey(ProceedingJoinPoint proceedingJoinPoint, AutoHotKey autoHotKey) throws Throwable { Object[] args = proceedingJoinPoint.getArgs(); Long id = getId(args); ThrowUtils.throwIf(id == null, ErrorCode.SYSTEM_ERROR, "id 未初始化"); String key = autoHotKey.keyPrefix() + id; Object value = JdHotKeyStore.getValue(key); Class<?> valueType = autoHotKey.valueType(); if (valueType.isInstance(value)) { return ResultUtils.success(valueType.cast(value)); } else if (value != null) { throw new BusinessException(ErrorCode.SYSTEM_ERROR, "需要的缓存类型与设置的不匹配"); } Object result = proceedingJoinPoint.proceed(); if (result instanceof BaseResponse) { Object data = ((BaseResponse<?>) result).getData(); if (valueType.isInstance(data)) { JdHotKeyStore.smartSet(key, data); } } return result; } private Long getId(Object[] args) { for (Object arg : args) { if (arg != null) { Long id = getIdFromArg(arg); if (id != null && id >= 0) { return id; } } } return null; } private Long getIdFromArg(Object arg) { if (arg instanceof Long) { return (Long) arg; } Long id = null; if (arg != null) { try { // 使用getId()方法获取id Method getIdMethod = arg.getClass().getMethod("getId"); Object idValue = getIdMethod.invoke(arg); if (idValue instanceof Long) { id = (Long) idValue; } if (id != null && id > 0) { return id; } } catch (NoSuchMethodException e) { return null; } catch (Exception e) { throw new BusinessException(ErrorCode.SYSTEM_ERROR); } } return id; } } ``` 最后我们分别在 `getQuestionBankVOById` 方法以及 `getQuestionVOById` 方法进行试验:(一个是以带 `getId()` 方法的对象作为参数,一个参数本身就是 `Long` 类型) ```java @GetMapping("/get/vo") @AutoHotKey(keyPrefix = "bank_detail_", valueType = QuestionBankVO.class) public BaseResponse<QuestionBankVO> getQuestionBankVOById(QuestionBankQueryWithQuestionRequest questionBankQueryWithQuestionRequest, HttpServletRequest request) { ThrowUtils.throwIf(questionBankQueryWithQuestionRequest == null || questionBankQueryWithQuestionRequest.getId() <= 0, ErrorCode.PARAMS_ERROR); // 查询数据库 long id = questionBankQueryWithQuestionRequest.getId(); QuestionBank questionBank = questionBankService.getById(id); ThrowUtils.throwIf(questionBank == null, ErrorCode.NOT_FOUND_ERROR); // 获取封装类 QuestionBankVO questionBankVO = questionBankService.getQuestionBankVO(questionBank, request); if (questionBankQueryWithQuestionRequest.isNeedToListQuestion()) { QuestionQueryRequest questionQueryRequest = new QuestionQueryRequest(); questionQueryRequest.setQuestionBankId(id); questionQueryRequest.setPageSize(questionBankQueryWithQuestionRequest.getPageSize()); questionQueryRequest.setCurrent(questionBankQueryWithQuestionRequest.getCurrent()); Page<Question> questionPage = questionService.getQuestionPage(questionQueryRequest); Page<QuestionVO> questionVOPage = questionService.getQuestionVOPage(questionPage, request); questionBankVO.setQuestionVOPage(questionVOPage); } return ResultUtils.success(questionBankVO); ``` ```java @GetMapping("/get/vo") @AutoHotKey(keyPrefix = "question_detail_", valueType = QuestionVO.class) public BaseResponse<QuestionVO> getQuestionVOById(Long id, HttpServletRequest request) { ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR); // 查询数据库 Question question = questionService.getById(id); ThrowUtils.throwIf(question == null, ErrorCode.NOT_FOUND_ERROR); // 获取封装类 return ResultUtils.success(questionService.getQuestionVO(question, request)); } ``` 最后的结果如下:  能够正常使用,同时又实现了对热门题目的自动缓存,一箭双雕^v^
SpringBoot3 Druid 无法打开控制台解决方案
``` SpringBoot: 3.5.4 Druid: 1.2.23 ``` 通过查询 Maven Repository,我们能查到,Druid 的 Maven 如下: ```xml <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.23</version> </dependency> ``` 但是使用这个 Maven 是不起作用的,无法打开控制台,应该使用下面这个: ```xml <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-3-starter</artifactId> <!-->添加一个 -3- <--> <version>1.2.23</version> </dependency> ``` 虽然这样子 application.yml 会报和druid 相关的配置无法识别,  但是通过实际操作控制台,我们能发现是有在正确运行的,各种属性:账号、密码、连接数等都有被正确识别:   所以该方法有效!
🚀 编程导航成品项目(上百个真实项目)
编程导航已累计发布数十套项目教程:[课程地址](https://www.codefather.cn/course)。 为方便大家集中学习参考,也帮助已完成项目的同学获得更多曝光与真实用户,我们整理汇总了过往提交的优质项目帖。 🔍 如果你的项目已提交,欢迎确认是否被收录; 🚀 如果你正在开发中,不妨参考已有项目的实现思路与笔记总结,相信对你有帮助。 > 收录说明:若你的项目文章尚未被收录,欢迎评论区留言:项目文章链接 + 线上地址(如有),管理员会定期更新到汇总帖里,助力每一个认真分享的项目被更多人看见~ ## AI 零代码应用生成平台 企业级项目教程:https://codefather.cn/course/1948291549923344386 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### CodeLoom(已上线) 👉 线上地址:http://1.15.243.228:9010/CodeLoom/ 📚 原帖链接:https://codefather.cn/post/1960256724123316226   #### AI Code Mother(已上线) 👉 线上地址:https://joinoai.cloud/user/register?inviteCode=INVNJZKYSJH 📚 原帖链接:https://codefather.cn/post/1974436661408411649   #### 代码灵构 📚 原帖链接:https://codefather.cn/note/1957033275842670593   #### XiangAI 📚 原帖链接:https://codefather.cn/essay/1957335221259333633   #### AI Code easen 📚 原帖链接:https://codefather.cn/post/1954389275447824386   ## AI 超级智能体 企业级项目教程:https://codefather.cn/course/1915010091721236482 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### Crispix Agent 📚 原帖链接:https://codefather.cn/post/1962528203403792386  #### ApocalyxAI(智能助手平台) 📚 原帖链接:https://codefather.cn/post/1937413626668843010   #### 神农医慧库 📚 原帖链接:https://codefather.cn/post/1936010788000563201  #### AI 智能应用中心 📚 原帖链接:https://codefather.cn/post/1928019148442537985  #### CodeManus AI 助手 📚 原帖链接:https://codefather.cn/post/1966800552892235778   ## 智能协同云图库项目项目 企业级项目教程:https://codefather.cn/course/1864210260732116994 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 悦木图库(已上线) 👉 线上地址:https://lumenglover.com/ 📚 原帖链接:https://codefather.cn/essay/1890067861869486081   #### 暴龙图库(已上线) 👉 线上地址:https://picture.baolong.icu/ 📚 原帖链接:https://codefather.cn/post/1905997569888280577   #### Crispix AI 图库(已上线) 👉 线上地址:https://crispix.fun 📚 原帖链接:https://codefather.cn/post/1915861894909386754   #### 云图智联(已上线) 👉 线上地址:https://imagecore.netlify.app/ 📚 原帖链接:https://codefather.cn/post/1970098502037934081   #### 荒梦图库(已上线) 👉 线上地址:https://pichm.cloud/ 📚 原帖链接:https://codefather.cn/post/1960673049771610113   #### Picazza 图库(已上线) 👉 线上地址:https://picazza.com/ 📚 原帖链接:https://www.codefather.cn/post/1945659153240215554   #### 悦突突(已上线) 👉 线上地址:https://coder-live.cn/ 📚 原帖链接:https://codefather.cn/post/1950740016980426754   #### 图潮(已上线) 👉 线上地址:https://picwave.top/ 📚 原帖链接:https://codefather.cn/essay/1911024578559188993   #### 云相册(已上线) 👉 线上地址:https://pic.lin03.cn/ 📚 原帖链接:https://codefather.cn/post/1929477619980566530   #### HY 映像(已上线) 👉 线上地址:https://zhydoc.com/picture/ 📚 原帖链接:https://codefather.cn/post/1967843032026775553  #### 智图云链(已上线) 👉 线上地址:http://117.72.69.235/  #### han_picture 📚 原帖链接:https://codefather.cn/post/1974327430218887170   ## 面试刷题平台 企业级项目教程:https://codefather.cn/course/1826803928691945473 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 面试秘境(已上线) 👉 线上地址:http://mianshimijing.icu/ 📚 原帖链接:https://codefather.cn/post/1869660024067571713   ## AI 答题应用平台 企业级项目教程:https://codefather.cn/course/1790274408835506178 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 腾蛇问渊(已上线) 👉 线上地址:https://aianswerproj.vercel.app/ 📚 原帖链接:https://codefather.cn/essay/1809498338799878146  #### 智慧答 📚 原帖链接:https://codefather.cn/post/1826490068167761921   ## OJ 在线判题系统 企业级项目教程:https://codefather.cn/course/1790980707917017089 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 雪 OJ(已上线) 👉 线上地址:http://snowyee.cn/snowyee-oj/#/ 📚 原帖链接:https://codefather.cn/note/1810751001442844674   #### 流火 OJ 📚 原帖链接:https://codefather.cn/post/1827575600860672001   #### SSPU-OJ 📚 原帖链接:https://codefather.cn/post/1964988539086487554   #### 新 OJ 📚 原帖链接:https://codefather.cn/note/1806522941518364673   #### HHOJ 📚 原帖链接:https://codefather.cn/post/1895681485945774082   #### AICoder OJ 📚 原帖链接:https://codefather.cn/note/1811051057198858241  📚 原帖链接:https://codefather.cn/note/1829734814391640065   #### CsCS OJ 📚 原帖链接:https://codefather.cn/post/1836003849697837057  #### 疯 OJ 📚 原帖链接:https://codefather.cn/post/1913879429893369857   ## 代码生成器共享平台 企业级项目教程:https://codefather.cn/course/1790980795074654209 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 飞云代码生成 📚 原帖链接:https://codefather.cn/note/1816913082742140930  ## 智能 BI 项目 企业级项目教程:https://codefather.cn/course/1790980531403927553 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 灵犀 BI(已上线) 👉 线上地址:http://bi.hejiajun.icu/ 📚 原帖链接:https://codefather.cn/post/1876163793297530881  #### Kim 智能 BI 📚 原帖链接:https://codefather.cn/post/1908147328172138498   #### Liy 智能 BI 分析系统 👉 线上地址:https://8.141.7.82/login 📚 原帖链接:https://codefather.cn/essay/1853271746140782593   #### Admin 智能 BI 分析系统 📚 原帖链接:https://codefather.cn/post/1812563734513770498   #### Flance 智能 BI 系统 📚 原帖链接:https://codefather.cn/note/1813731731964133378   #### AI 洞察 📚 原帖链接:https://codefather.cn/post/1816913159401435138    #### hx BI 📚 原帖链接:https://codefather.cn/post/1812563043074367490   #### Solar BI 📚 原帖链接:https://codefather.cn/note/1816551710832824322   #### 哥布林智能 BI 分析系统 📚 原帖链接:https://codefather.cn/note/1811050100016742402   #### PS 智能 BI 分析系统 📚 原帖链接:https://codefather.cn/note/1810278024374505474   #### ToolVerse:一体化智能管理与创新服务平台 📚 原帖链接:https://codefather.cn/post/1810389203533025282   #### Nero 智能 BI 分析系统 📚 原帖链接:https://codefather.cn/note/1811010648561090562   #### GBC 智能 BI 分析系统 📚 原帖链接:https://codefather.cn/note/1808941076960215041   ### 聚合搜索平台 企业级项目教程:https://codefather.cn/course/1790979621621641217 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 空空-聚合搜索平台 📚 原帖链接:https://codefather.cn/note/1924150587763404802   #### 崽崽聚合搜索平台 📚 原帖链接:https://codefather.cn/note/1817637092455018497   #### 青年聚合搜索平台 📚 原帖链接:https://codefather.cn/post/1825764402195537921  ### API 开放平台 企业级项目教程:https://codefather.cn/course/1790979723916521474 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### Qi-API 接口开放平台(已上线) 👉 线上地址:https://api.qimuu.icu/user/login 📚 原帖链接:https://codefather.cn/note/1805877794735435778   #### 羊腿 API 开放平台(已上线) 👉 线上地址:http://api.panyuwen.top/user/login 📚 原帖链接:https://codefather.cn/note/1855478010485653505    #### Cxm-API 接口开放平台 📚 原帖链接:https://codefather.cn/essay/1905452207706185730    #### LeAPI 接口开放平台 📚 原帖链接:https://codefather.cn/note/1816551310788497409   #### X API 开放调用平台 📚 原帖链接:https://codefather.cn/note/1816913304989921281   #### Adagio 接口开放平台 📚 原帖链接:https://codefather.cn/note/1816551835571425281   #### 聚合 API 开放平台 📚 原帖链接:https://codefather.cn/note/1811049203207438337   #### EasyAPI 开放平台 📚 原帖链接:https://codefather.cn/note/1832713500474793986   #### 洛言接口开放平台 📚 原帖链接:https://codefather.cn/post/1828449609845428226  #### k 接口开放平台 📚 原帖链接:https://codefather.cn/note/1808772929765376001  #### 为-接口开放平台 📚 原帖链接:https://codefather.cn/note/1811050695448526849   #### API 接口服务平台 📚 原帖链接:https://codefather.cn/post/1839933551062880258  #### 银竹接口开放平台 📚 原帖链接:https://codefather.cn/post/1810389203533025282   #### Insight平台 📚 原帖链接:https://codefather.cn/post/1812563734513770498  ### 伙伴匹配系统 企业级项目教程:https://codefather.cn/course/1790950013153095682 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### homie 伙伴匹配系统(已上线) 👉 线上地址:http://hm.hejiajun.icu/ 📚 原帖链接:https://codefather.cn/note/1823592419365535746   #### 花语-伙伴匹配系统(已上线) 👉 线上地址:http://huayu.hanades.online  #### 速配 SUPER - 伙伴匹配系统(已上线) 👉 线上地址:https://ochiamalu.fun/ 📚 原帖链接:https://codefather.cn/essay/1909073423851560961   #### yes - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/post/1811047157863481345   #### 等闲 - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1812741780545921026   #### 鱼泡 - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1806571986623836161   #### Louis - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1806569725122228226  #### 知秋 - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1816551544797106177   #### 小虎 - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1814012455103463426  #### 龙 - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1818361301050142721   #### w - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1838446471885594625   #### 云交友 - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/post/1825763690480869378   #### 大学生 - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/note/1820898093159849986   #### Yz - 伙伴匹配系统 📚 原帖链接:https://codefather.cn/essay/1870039737155010561   ### 用户中心项目 企业级项目教程:https://codefather.cn/course/1790943469757837313 > 视频教程 + 项目文档 + 源码 + 简历写法 + 面试题解 + 专属交流群 #### 可乐用户中心(已上线) 👉 线上地址:http://user.xykcola.site/user/login 📚 原帖链接:https://codefather.cn/note/1811475602152685570   #### (NextJS 版)用户中心管理 📚 原帖链接:https://codefather.cn/post/1912880102888280065  #### chen 用户中心 📚 原帖链接:https://codefather.cn/note/1811050198691938306   #### Find Me 用户中心 📚 原帖链接:https://codefather.cn/note/1811342501757911041   #### 小汉用户中心 📚 原帖链接:https://codefather.cn/note/1810181026137473026   #### 用户中心 📚 原帖链接:https://codefather.cn/post/1925206864866131970   #### 吃鱼用户中心 📚 原帖链接:https://codefather.cn/post/1896897093685288961  📚 原帖链接:https://codefather.cn/note/1811049194567172097  #### 崽崽用户中心 📚 原帖链接:https://codefather.cn/note/1817637102550708225   #### Jiaxiong 用户中心 📚 原帖链接:https://codefather.cn/note/1815828758460895233  
pandora潘多拉——微服务刷题平台(求star版)
## 项目分享 因为之前一些原因一直没有时间去分享新写的项目,本项目一共有两个版本,大单体和微服务,该项目使用了多端部署和Nginx进行负载均衡。 <p align="center"> <a href="" target="_blank"> <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/RuWu8Hbtme5y6aNF.webp" width="280" /> </p> <h1 align="center">潘多拉魔盒 - 面试刷题平台</h1> <p align="center"><strong> 基于Next.js + Spring Cloud + Redis + MySQL + Elasticsearch 构建的程序员智能刷题平台。 <br>致力于程序员刷题,帮助每个人成为编程面试大师🚀。。 <br><em>持续更新中~</em> </strong></p> <div align="center"> <a href="https://github.com/cool-icu0/pandora"><img src="https://img.shields.io/badge/后端-项目地址-yellow.svg?style=plasticr"></a> <a href="https://github.com/cool-icu0/pandora"><img src="https://img.shields.io/badge/前端-项目地址-blueviolet.svg?style=plasticr"></a> 项目地址(如果上面的两个显示不出来):<a href= "https://github.com/cool-icu0/pandora">https://github.com/cool-icu0/pandora</a>求个github的star~~ </div> ## 一、项目介绍🚀 <p align="center"> <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/CFwCDwrq5rMi1y2L.webp" width="780" /> </p> 基于Next.js + Spring Cloud + Redis + MySQL + Elasticsearch 构建的面试刷题平台。 致力于面试刷题、智能解析面试八股文,帮助人们解决和掌握计算机中晦涩难懂的知识点等问题, 旨在为用户提供便捷、高效、安全的刷题体验, 同时为管理员提供全面的题库管理功能。 ## 二、架构设计图🎨 <p align="center"> <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/PBj5w6APDd1NZjXf.webp" width="780" /> </p> ## 三、技术亮点🔍 1. **性能提升** - 运用 Druid 数据库连接池技术,有效管理数据库连接,减少连接创建和销毁的开销,提升系统性能。 - 结合 JD- HotKey 热 Key 探测技术,及时发现热点数据,优化系统对高频请求的处理。 - 利用 Redis 缓存技术,缓存常用数据,减少数据库查询次数,加快数据访问速度。 - 使用高级数据结构,进一步优化数据处理逻辑,提高系统整体性能。 2. **安全保障** - 采用 Sa - Token 实现可靠的用户认证和授权机制,确保用户数据安全和操作合法性。 - 借助 Sentinel 进行流量控制和熔断处理,防止系统因突发大流量而崩溃,保障系统的稳定性和可用性。 - 通过动态 IP 黑白名单过滤技术,有效阻止恶意 IP 的访问,增强系统的网络安全性。 - 实现同端登录冲突检测,防止账号在多端异常登录,保护用户账号安全。 - 运用分级反爬虫策略,抵御恶意爬虫对系统内容的非法获取,确保平台数据的安全性。 ## 四、技术选型 ### 前端 - React 18 框架 - ⭐️ Next.js 服务端渲染 - ⭐️ Redux 状态管理 - Ant Design 组件库 - 富文本编辑器组件 - ⭐️ 前端工程化:ESLint + Prettier + TypeScript - ⭐️ OpenAPI 前端代码生成 ### 后端 - Java Spring Boot 框架 + Maven 多模块构建 - MySQL 数据库 + MyBatis-Plus 框架 + MyBatis X - Redis 分布式缓存 + Caffeine 本地缓存 - Redission 分布式锁 + BitMap + BloomFilter - ⭐️ Elasticsearch 搜索引擎 - ⭐️ Druid 数据库连接池 + 并发编程 - ⭐️ Sa-Token 权限控制 - ⭐️ HotKey 热点探测 - 微服务架构(SpringCloud Alibaba) - ⭐️ Sentinel 流量控制、限流熔断 - ⭐️ Nacos 配置中心、注册中心 - ⭐️ GateWay 微服务网关 - ⭐️ OpenFeign 远程调用 - ⭐️ 多角度项目优化:性能、安全性、可用性 ### 环境搭建 #### 🎉后端环境搭建 后端项目使用 SpringBoot 开发,需要安装 JDK 17 、 MySQL 数据库、Redis、Elasticsearch 。 在项目目录下的`application.yml`修改自己的启动环境`spring.profiles.active` = `dev` 然后找到同级文件`application-dev.properties`,填写自己的环境配置(MySQL、Redis)。 #### 🎉 前端环境搭建 前端项目使用 React 开发,需要安装 Node.js(Node 18 版本,请保持一致) 、npm 。 在项目目录下执行`npm install`安装依赖,然后执行`npm run start`启动项目。 ## 五、功能介绍 ### 简单介绍(粗略) 1. **管理员功能** - **用户管理**:管理用户信息,包括注册、登录、权限管理等。 - **题库管理**:可轻松管理题库,包括创建新库、为不同场景准备题目集合。 - **题目管理**:能在已有题库中添加多种类型题目。 - **题目详情**:支持多种类型题目,包括单选、多选、判断、填空、编程等。 - **题解管理**:为题目添加详细题解,助力用户学习。 2. **用户功能** - **注册与登录**:便捷注册登录,开启刷题。 - **知识论坛**:方便用户交流学习。 - **分词检索题目**:借助 Elasticsearch 分词检索快速找题。 - **在线刷题**:在平台刷题,答题情况被实时记录。 - **模拟面试**:模拟面试,根据题目进行答题。 - **在线编程**:在线编程,支持多种语言,实时编译运行。 - **刷题记录查看**:通过日历图查看刷题历程和进度。 3. **安全性** - **缓存热点与热 key**:用三级缓存技术处理热点数据和热 key,监测访问频率,优化性能,保障稳定。 - **限流与熔断**:运用限流与熔断机制,监控和控制流量,过载时防止系统崩溃。 - **IP 管理**:采用 IP 黑白名单技术,区分可信和恶意 IP,保障网络安全。 - **同端登录检测**:通过同端登录检测机制,监控账号状态,防止异常登录,保护账号安全。 - **反爬虫策略**:依据分级反爬虫策略,对访问请求监测,超限制先警告后封号,保护平台。 ### 功能展示(详尽) 1. **管理员功能** - **题库管理** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/vNPgajRQ7Yhd3d2B.webp" width="780" /> - **题目管理** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/FGwSktUQxB9latWJ.webp" width="780" /> - **题库详情** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/OOt1zg6G78I9UHil.webp" width="780" /> - **题解管理** 略 2. **用户功能** - **注册与登录** 略 - **分词检索题目** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/gXvknrc73L1fycvc.webp" width="780" /> - **在线刷题** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/MtP8eEgKKmtyykaz.webp" width="780" /> - 在线编程 <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/RAJHlZXSDldoZjiJ.webp" width="780" /> <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/i1l6Eb2qdQNleYKj.webp" width="780" /> - 模拟面试 - <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/RrCGkVNu3Lv0movS.webp" width="780" /> - **刷题记录日历图** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/yWqQppoBnVjckJ44.webp" width="780" /> - **知识论坛** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/t3qvzWcIbgIyAzwd.webp" width="780" /> - **论坛帖子详情** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/sDH5yUJaVNNOSLWv.webp" width="780" /> - **论坛帖子点赞/收藏/评论** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/WelJwtqOReqDielJ.webp" width="780" /> 3. **安全性** - **缓存热点与热key** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/Z90wpsQo4cHt1wiw.webp" width="780" /> - **限流与熔断** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/Z0d7mVoDgdyMUx7Z.webp" width="780" /> - **IP 黑白名单** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/vbWOHDvcXzacfKxe.webp" width="780" /> - **同端登录冲突检测** <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/6PtRParVoTsL84wR.webp" width="780" /> - **分级反爬虫策略** - 访问次数超过一定限制,发送邮件 - 访问次数超过限制太多,封号处理 <img src="https://pic.code-nav.cn/post_picture/1608480665257377793/PWClNfBoP5yRhXBN.webp" width="780" /> ## 六、nginx配置(仅供参考) ```text upstream backend { server 192.168.1.128:8081 weight=1; server 192.168.1.128:8082 weight=2; } server { listen 80; server_name 0.0.0.0; location / { proxy_pass http://backend; } } ```
面试刷题平台反爬虫计数扩展
技术栈与思路: - 本地缓存 + 异步消息(Pulsar) + 分布式缓存(Redis) - Redis Lua 脚本 保证点赞原子性与幂等 - 消息驱动:计数事件先落本地,再推送到 Pulsar,后台消费者批量缓存到Redis **1.本地计数与事件推送** ``` public long incrAndGetCounter(String key, int timeInterval, TimeUnit timeUnit, int expirationSec) { // 1. 生成分时 Redis Key String redisKey = generateRedisKey(key, timeInterval, timeUnit); // 2. 本地 Caffeine 缓存自增 counterCache.asMap().compute(redisKey, (k,v) -> v==null?1:v+1); // 3. 标记为脏数据,等待批量推送 dirtyKeys.add(redisKey); // 4. 本地读取优先返回 Integer newVal = counterCache.getIfPresent(redisKey); if (newVal!=null) return newVal.longValue(); // 5. 回退读取 Redis long redisCount = redissonClient.getAtomicLong(redisKey).get(); counterCache.put(redisKey,(int)redisCount); return redisCount; } ``` Caffeine 本地缓存:60s 后过期或显式清除时,会触发 RemovalListener,将 (key,value) 封装为 CounterEvent 通过 Pulsar 推送。 ``` // 本地缓存,过期时通过 Pulsar 事件发送同步命令 private final Cache<String, Integer> counterCache = Caffeine.newBuilder() .expireAfterWrite(60, TimeUnit.SECONDS) .removalListener((key, value, cause) -> { if (cause.wasEvicted() || cause == RemovalCause.EXPLICIT) { counterProducer.sendAsync(new CounterEvent((String) key, (Integer) value)) .exceptionally(ex -> { log.error("发送计数事件失败 key={} value={}", key, value, ex); return null; }); } }) .build(); ``` ``` @Data @NoArgsConstructor // 生成无参构造器,供 Jackson 反序列化使用 @AllArgsConstructor public class CounterEvent implements Serializable { private String key; private Integer value; } ``` 定时批量刷新:@Scheduled(fixedRate = 5000) 批量将 dirtyKeys 中的计数事件异步发送至 counter-sync-topic。 ``` // 新增:每5秒批量同步计数到 Redis @Scheduled(fixedRate = 5000) public void flushCounterEvents() { if (dirtyKeys.isEmpty()) { return; } // 批量发送脏数据,并移除标记 Set<String> keysToFlush = new HashSet<>(dirtyKeys); for (String k : keysToFlush) { Integer v = counterCache.getIfPresent(k); if (v != null) { counterProducer.sendAsync(new CounterEvent(k, v)) .exceptionally(ex -> { log.error("定时发送计数事件失败 key={} value={}", k, v, ex); return null; }); } dirtyKeys.remove(k); } } ``` ``` @PostConstruct public void init() throws PulsarClientException { // 创建 Pulsar 生产者,用于发送 CounterEvent counterProducer = pulsarClient .newProducer(Schema.JSON(CounterEvent.class)) .topic("counter-sync-topic") .create(); } ``` **2. 消费与同步到 Redis** 从 Pulsar 批量拉取 CounterEvent,并执行 Lua 脚本将本地缓存中的最新计数原子同步到 Redis。 ``` private void receiveMessages() { while (running) { try { Messages<CounterEvent> messages = consumer.batchReceive(); if (messages != null) { for (Message<CounterEvent> msg : messages) { try { CounterEvent evt = msg.getValue(); syncToRedis(evt.getKey(), evt.getValue()); consumer.acknowledge(msg); log.info("处理计数同步消息成功"); } catch (Exception ex) { log.error("处理计数同步消息失败", ex); consumer.negativeAcknowledge(msg); } } } } catch (AlreadyClosedException e) { log.info("Pulsar Consumer 已关闭,退出接收循环"); break; } catch (Exception e) { log.error("接收 CounterEvent 消息失败", e); } try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } ``` ``` private void syncToRedis(String key, Integer value) { try { RScript script = redissonClient.getScript(IntegerCodec.INSTANCE); script.eval(RScript.Mode.READ_WRITE, CounterManager.LUA_SCRIPT, RScript.ReturnType.INTEGER, Collections.singletonList(key), value, 60); log.info("Synced key: {}, value: {} to Redis", key, value); } catch (Exception e) { log.error("执行 Redis 脚本失败 key={} value={}", key, value, e); throw e; } } ``` ## 代码 ``` /** * Pulsar 事件:用于本地计数同步 */ @Data @NoArgsConstructor // 生成无参构造器,供 Jackson 反序列化使用 @AllArgsConstructor public class CounterEvent implements Serializable { private String key; private Integer value; } ``` ``` /** * 本地计数管理器——使用 Pulsar 事件驱动将过期的计数同步到 Redis */ @Slf4j @Service public class CounterManager { @Resource private RedissonClient redissonClient; @Resource private PulsarClient pulsarClient; private Producer<CounterEvent> counterProducer; // 跟踪需要批量刷新的 key private final Set<String> dirtyKeys = ConcurrentHashMap.newKeySet(); public static final String LUA_SCRIPT = "local exists = redis.call('exists', KEYS[1])\n" + "if exists == 1 then\n" + " redis.call('set', KEYS[1], ARGV[1])\n" + "else\n" + " redis.call('set', KEYS[1], ARGV[1], 'EX', ARGV[2])\n" + "end\n" + "return ARGV[1]"; // 本地缓存,过期时通过 Pulsar 事件发送同步命令 private final Cache<String, Integer> counterCache = Caffeine.newBuilder() .expireAfterWrite(60, TimeUnit.SECONDS) .removalListener((key, value, cause) -> { if (cause.wasEvicted() || cause == RemovalCause.EXPLICIT) { counterProducer.sendAsync(new CounterEvent((String) key, (Integer) value)) .exceptionally(ex -> { log.error("发送计数事件失败 key={} value={}", key, value, ex); return null; }); } }) .build(); public long incrAndGetCounter(String key) { return incrAndGetCounter(key, 1, TimeUnit.MINUTES); } public long incrAndGetCounter(String key, int timeInterval, TimeUnit timeUnit) { int expireSec; switch (timeUnit) { case SECONDS: expireSec = timeInterval; break; case MINUTES: expireSec = timeInterval * 60; break; case HOURS: expireSec = timeInterval * 3600; break; default: throw new IllegalArgumentException("Unsupported TimeUnit"); } return incrAndGetCounter(key, timeInterval, timeUnit, expireSec); } public long incrAndGetCounter(String key, int timeInterval, TimeUnit timeUnit, int expirationSec) { if (StrUtil.isBlank(key)) return 0; String redisKey = generateRedisKey(key, timeInterval, timeUnit); // 更新本地缓存中的计数 counterCache.asMap().compute(redisKey, (k, v) -> v == null ? 1 : v + 1); // 标记为脏数据,待定时刷新 dirtyKeys.add(redisKey); // 优先读取本地缓存 Integer newValue = counterCache.getIfPresent(redisKey); if (newValue != null) { return newValue.longValue(); } // 如果本地缓存中没有,再回退到 Redis long redisCount = redissonClient.getAtomicLong(redisKey).get(); counterCache.put(redisKey, (int) redisCount); return redisCount; } //生成key private String generateRedisKey(String key, int interval, TimeUnit tu) { long factor; switch (tu) { case SECONDS: factor = Instant.now().getEpochSecond() / interval; break; case MINUTES: factor = Instant.now().getEpochSecond() / 60 / interval; break; case HOURS: factor = Instant.now().getEpochSecond() / 3600 / interval; break; default: throw new IllegalArgumentException("Unsupported TimeUnit"); } return key + ":" + factor; } @PostConstruct public void init() throws PulsarClientException { // 创建 Pulsar 生产者,用于发送 CounterEvent counterProducer = pulsarClient .newProducer(Schema.JSON(CounterEvent.class)) .topic("counter-sync-topic") .create(); } @PreDestroy public void destroy() { if (counterProducer != null) { try { counterProducer.close(); } catch (PulsarClientException e) { log.error("关闭 CounterEvent 生产者失败", e); } } } // 新增:每5秒批量同步计数到 Redis @Scheduled(fixedRate = 5000) public void flushCounterEvents() { if (dirtyKeys.isEmpty()) { return; } // 批量发送脏数据,并移除标记 Set<String> keysToFlush = new HashSet<>(dirtyKeys); for (String k : keysToFlush) { Integer v = counterCache.getIfPresent(k); if (v != null) { counterProducer.sendAsync(new CounterEvent(k, v)) .exceptionally(ex -> { log.error("定时发送计数事件失败 key={} value={}", k, v, ex); return null; }); } dirtyKeys.remove(k); } } } ``` ``` @Service @Slf4j public class CounterSyncConsumer { private final PulsarClient pulsarClient; private final RedissonClient redissonClient; private Consumer<CounterEvent> consumer; private volatile boolean running = true; public CounterSyncConsumer(PulsarClient pulsarClient, RedissonClient redissonClient) { this.pulsarClient = pulsarClient; this.redissonClient = redissonClient; } @PostConstruct public void init() { try { consumer = pulsarClient.newConsumer(Schema.JSON(CounterEvent.class)) .topic("counter-sync-topic") .subscriptionName("counter-sync-subscription") .subscriptionType(SubscriptionType.Shared) .batchReceivePolicy(BatchReceivePolicy.builder() .maxNumMessages(500) .timeout(5000, TimeUnit.MILLISECONDS) .build()) .subscribe(); new Thread(this::receiveMessages).start(); } catch (PulsarClientException e) { log.error("初始化 CounterSyncConsumer 失败", e); } } private void receiveMessages() { while (running) { try { Messages<CounterEvent> messages = consumer.batchReceive(); if (messages != null) { for (Message<CounterEvent> msg : messages) { try { CounterEvent evt = msg.getValue(); syncToRedis(evt.getKey(), evt.getValue()); consumer.acknowledge(msg); log.info("处理计数同步消息成功"); } catch (Exception ex) { log.error("处理计数同步消息失败", ex); consumer.negativeAcknowledge(msg); } } } } catch (AlreadyClosedException e) { log.info("Pulsar Consumer 已关闭,退出接收循环"); break; } catch (Exception e) { log.error("接收 CounterEvent 消息失败", e); } try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } private void syncToRedis(String key, Integer value) { try { RScript script = redissonClient.getScript(IntegerCodec.INSTANCE); script.eval(RScript.Mode.READ_WRITE, CounterManager.LUA_SCRIPT, RScript.ReturnType.INTEGER, Collections.singletonList(key), value, 60); log.info("Synced key: {}, value: {} to Redis", key, value); } catch (Exception e) { log.error("执行 Redis 脚本失败 key={} value={}", key, value, e); throw e; } } @PreDestroy public void close() { running = false; if (consumer != null) { try { consumer.close(); } catch (PulsarClientException e) { log.error("关闭 CounterSyncConsumer 失败", e); } } } } ```
智能面试刷题平台 的AI生成题目功能,被面试官问到如果生成类似的但有微小差异的题目上要怎么处理,结果语塞没回答上来,朋友们有什么好的想法吗?
有人接毕设单子嘛?代码+部署+讲解。😘 鱼皮的面试刷题平台功能扩展(前后端): 点赞、收藏、发帖、评论、用户查看收藏列表、用户查看我的题目、用户个人信息(头像昵称修改)、管理员审核题目。 技术:springboot+Redis+React+Next.js 要求:对面试刷题平台代码有了解,能在半成品上快速上手开发。 ❗有意私聊,有信誉图更好。
面试鸭-模拟面试拓展上线
前几天看到鱼皮哥更新了面试鸭的AI模拟面试 后面自己也实现了一下 AI确实调的还挺久的哈哈哈哈 主要实现的功能有 AI模拟面试流式输出,还有就是正确渲染历史聊天记录 鱼皮哥一开始让AI写的那个应该是刷新页面之后聊天记录就渲染不出来了 大致实现效果如下 <img src="https://pic.code-nav.cn/post_picture/1803771144720003074/tvnlo8RRyNNXtDMi.webp" alt="file_1743415668316_347.png" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1803771144720003074/wGA1nLKe9G5FpptP.webp" alt="file_1743415570113_683.png" width="100%" />
