当前位置: 首页 > news >正文

OJ项目面经

为什么使用mybatis-plus而不是mybatis呢?

1.开发效率:从 “手写 SQL” 到 “约定大于配置”

2.复杂查询:链式调用替代 XML 拼接

3.性能优化:内置实用功能

分页查询:MyBatis 需手动编写分页 SQL 或集成第三方插件;MP 内置 Page 插件,一行代码实现分页。
逻辑删除:标记字段(如 deleted)自动转换为条件,查询时默认过滤已删除数据,避免物理删除风险。
4.高级功能:分布式场景支持

主键生成:MyBatis 需手动实现主键策略(如 UUID、自增);MP 内置雪花算法(IdentifierGenerator),支持分布式唯一主键。

为什么引入数据库连接池

借助mybatis-plus操作数据库虽然给我们提供了很⼤的便捷,但是这样⽅式操作数据库还是会存在⼀些问题:

频繁的创建连接和销毁连接 :包括TCP层的握⼿和MySQL协议握⼿,这会消耗⼤量时间。
连接数不受控制 :在业务流量⾼峰期,⼤量应⽤服务器可能同时请求数据库连接,⽽数据库能够承载的连接数有限,这可能导致数据库性能降低。
连接管理困难 :开发者需要⾃⾏管理数据库连接的创建、使⽤和关闭,这增加了开发的复杂性和出错的可能性

数据库连接池就是⽤来解决我们上⾯提到的这些问题,通过数据库连接池我们可以:

为什么采⽤HikariCP

最重要原因:与Spring Boot集成良好

Spring Boot对HikariCP提供了良好的⽀持,可以轻松地在项⽬中集成和使

⽤。Spring Boot的⾃动配置功能可以⾃动配置HikariCP的连接池参数,简化了配置过程。

主键为什么不使⽤⾃增id

总结:

1.如果使用数据库自带的自增id,只能保证在这个表/这个库里面是唯一的,但如果在分布式系统中,就可能会无法保证了

2.由于我们操作表的时候可能会出现大量的插入操作和删除操作,这可能会导致id不连续,浪费存储空间,以及可能影响某些逻辑

3.自增id是比较有规律的,可预测的,可能会带来安全隐患

那你是如何处理主键id问题呢

使用UUID或者雪花算法

那你最后为什么选择了雪花算法?

1.UUID存储会占据更大的空间,增加了数据库存储需求

2.UUID是一串字符串组成,不易于人类阅读记忆

为什么引入引入Swagger

加密算法

加密算法是⼀种将明⽂转换为密⽂的过程,以保护数据的安全性和机密性

为什么引入?

你在项目中用的是哪种加密算法

BCrypt
Bcrypt是⼀种哈希加密算法,被⼴泛应⽤于存储密码和进⾏⾝份验证。
Bcrypt算法在计算时会先⽣成⼀个随机的盐值与⽤⼾密码⼀起参与计算最终得到⼀个加密后的字符串。由于⽣成的盐值是随机的,所以即使每次使⽤相同的 密码得到结果也是不同的。这样可以有效的防⽌攻击者使⽤⼀些⼿段破解⽤⼾密码。

全局异常处理

使用全局异常处理的原因

如何使用:

⽇志框架引⼊

为了更加方便我们进行代码错误的定位,我们这里需要引入日志框架

这里选择slf4j+logback

为什么选择slf4j+logback

主要原因:配置灵活,springBoot的默认日志框架

按照时间滚动,文件大小滚动,固定窗口滚动

注意:日志只能接受比比日志级别高的日志

eg:定义为info时候可以接受到比它级别高的error日志,但是定义为error时候不能接受带info级别日志

配置nacos时候为什么要外置MySQL数据库

1.数据持久性(虽然内置的数据库也能存储,但是太小了,远不如用外置mysql数据库)

2.更高的可用性:nacos支持集群部署,但nacos内置数据库无法在nacos集群中数据共享,一旦发生故障,后果很大

3.性能更高:mysql可以通过各种优化手段处理高负载

你的项目中用到了gateway网关,那说说⽹关的核⼼作⽤:

1.权限控制:对用户进行校验,如果失败则拦截

2.动态路由:一切请求读得先经过网关,网关根据某种规则,讲请求转发到某个微服务

3.负载均衡

4.限流:当流量过高时候,进行限流,防止服务器压力过大

⾝份认证

你怎么实现身份认证功能的?

使⽤JWT认证机制,完成⽤⼾⾝份的认证。

jwt的组成部分

它由三部分组成:头部(header)、载荷(payload)和签名(signature)。

讲一讲⾝份认证流程:

1.客⼾端使⽤户名跟密码请求登录 

2.服务端收到请求,去验证⽤⼾名与密码 。

3.验证成功后,服务端会签发⼀个Token,再把这个Token发送给客⼾端 。(token上述的jwt串)

4.客⼾端收到Token以后可以把它存储起来,⽐如放在Cookie⾥面

5.客⼾端每次向服务端请求资源的时候需要带着服务端签发的Token 。 

6.服务端收到请求,然后去验证客⼾端请求⾥⾯带着的Token,如果验证成功,就向客⼾端返回请求的数据 

为什么选择JWT

1.简单方便:所有认证授权信息都包含在jwt中,简化了流程

2.安全可靠:jwt使用签名保证真实性,确保传输过程中不被篡改(如果篡改了就无法识别了)

3.支持跨域:客户端将jwt作为请求的一部分发给服务器。不用依赖cookie和session,因此不会受到限制

可能提出问题:⾝份认证仅仅使⽤jwt机制就可以吗?

总结:

1.我们需要敏感信息,但是敏感信息不能通过jwt令牌传送过来

2.jwt是无状态的,如果用户修改个人信息之后就需要重新登录

3.如果用户正在答题,突然令牌到期了,影响用户体验

问题处理思路:

1.payload中不能存放敏感信息

2.想办法⽤⼾修改了个⼈信息之后,jwt不变。
  • payload中仅仅存储⽤⼾唯⼀标识信息,那么修改⽤⼾信息就不会引起jwt改变。
3.能够控制jwt的过期时间

封装Redisservice

为什么封装service

  • 你封装Service后如果你的其他服务和你对应的接口改变了的时候,你只用修改你的Service层即可,而不用修改大量代码(类似于门面模式)
  • 如果有好多个第三方工具,但是他们的方法不同(前提:类似),你只需要进行封装,把他们变成一个统一的接口样式即可,而不用理解底层代码

JWT验证流程

1.登录的时候创建token(userkey+userid),对userKey处理之后,作为key存入redis中,value是用户相关信息,对redis的键值对进行设置过期时间,而不对jwt设置过期时间,最后将token返回给前端

2.当我们再次登录的时候,我们去请求头中获得token,解析token,获得userKey,对获得的userKey进行判断是否过期,如果没过期,则允许通过

延迟token时间

由于我们延迟token的时机在于登录获得token之后,在调用Controller之前,那我们可以把延长的时机订到拦截器中,我们可能会想着可以单独弄一个过滤器,但是这样一方面以后可能添加其他过滤器导致问题,也会增加代码直接耦合度,所以我们这里选择使用过滤器

剩余时间不足时候,进行增时(不卡在结束后访问页面即可)

为什么要这么区分:

1.提高代码可读性和可维护性

2对当前功能需求进行封装裁剪,对返回值进行选择,将不想给客户端暴露的信息不进行封装(例如密码)

3.解耦:修改某一个部分逻辑时候,只改对应的就行

添加竞赛为什么要先保存后新增呢?

1.为了防止太多没有竞赛名字的题目集合存在,导致最后不知道到底是哪个

2.添加一个题目即可存在这个竞赛中,不用害怕突然退出导致的重新添加

ES解决什么问题

全⽂检索(全部字段)、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)

搜索原理

ES 的核心优势源于 Lucene 的倒排索引(Inverted Index) 结构,这是区别于传统数据库 “正向索引” 的关键设计:

  • 正向索引:以文档为单位存储内容(如数据库表),查询时需遍历所有文档,效率低下。
  • 倒排索引:将 “词项(Term)” 与 “文档 ID” 映射,例如:
  • 词项“云计算” → 关联文档ID:[101, 205, 312]
  • 词项“大数据” → 关联文档ID:[205, 431, 502]
  • 检索逻辑:查询时直接定位词项对应的文档集合,通过集合运算(交集、并集等)快速筛选目标文档,时间复杂度从 O (n) 降至 O (log n)。
  • 压缩优化:ES 使用压缩索引,减少内存占用,提升词项查找速度。

安装Kibana

Kibana是ElasticSearch的数据可视化和实时分析的⼯具。通过Kibana,⽤⼾可以搜索、查看和与存储 在Elasticsearch索引中的数据进⾏交互,执⾏⾼级数据分析,并通过各种图表、表格和地图将数据可视化。

分词器


根据前⾯学习的倒排索引的概念。倒排索引是按照⽂档中的词汇(关键词)来组织的,索引的键
是⽂档集合中出现过的每个独特词汇或关键词。那es是怎么将这些关键词提取出来的呢?这其实就是es中的分词器在起着作⽤,它负责将⽂本切分成⼀个个有意义的词语,以建⽴索引或进⾏搜索和分析。

ES和MySQL有哪些不同,各有什么优势?

1.倒排索引和正排索引的区别

  • 如果需要存储结构化或半结构化的数据,并且需要保证数据操作的正确性和完整性,可以选择 MySQL 作为主要数据库系统。例如,电商网站、社交网络、博客平台等。
  • 如果需要存储非结构化或多样化的数据,并且需要支持复杂的全文检索和相关度评分,可以选择 Elasticsearch 作为主要数据库系统。例如搜索引擎、日志分析、推荐系统等。

你的判题项目中用到了ES实现了题目搜索功能,那你说一下倒排索引吧

倒排索引(Inverted Index) 是实现高效全文检索的核心数据结构,其设计思路与传统数据库的 “正排索引”(按文档 ID 映射内容)相反,核心是 从关键词映射到文档”

倒排索引的基本原理

  1. 分词处理:当文档(如一道题目)写入 ES 时,ES 会先对指定字段(如题目描述、标签)进行分词,将文本拆分为一个个有意义的 “词条(Term)”。例如,对文本 “两数之和的 Java 解法” 分词后,可能得到词条:两数之和Java解法(具体取决于分词器)。

  2. 建立映射关系:为每个词条创建一个 “倒排列表”,记录该词条出现的所有文档 ID、出现位置、频次等信息。例如:

    • 词条 Java → 文档 1(频次 2)、文档 3(频次 1)、文档 5(频次 3)
    • 词条 解法 → 文档 1(频次 1)、文档 2(频次 2)
  3. 查询时快速匹配:当用户搜索 “Java 解法” 时,ES 会先对查询词分词,得到 Java 和 解法,然后通过倒排索引找到两个词条对应的文档交集,再根据频次、相关性等排序返回结果。

这种结构让 ES 无需遍历所有文档,直接通过关键词定位相关文档,极大提升了全文检索效率。

你在使用ES去存储题目的时候,用的是什么的分词插件?

IK 分词器

为什么选择 IK 分词器?

  1. 专为中文优化
  2. 支持自定义词典:可以将编程领域的专业词汇(如 “LeetCode”“动态规划”“哈希表”)添加到自定义词典中,避免被错误拆分(例如 “哈希表” 不会拆成 “哈希”“表”)。
  3. 两种分词模式:ik_max_word:最大化拆分(细粒度),ik_smart:最小化拆分(粗粒度)

遇到过IK分词器的分词结果不理想的情况吗?

  • 专业术语被拆分过细
  • 生僻词或自造词被拆分成单字

解决方案:通过 “自定义词典” 优化分词

有一个题目,我用IK去分词,然后去搜索,那这个时候我应该用哪一种检索的命令呢?

取决于你的搜索需求

  • match query(最常用,适合模糊匹配)

  • match_phrase query(短语匹配,适合精确连续匹配)

match和match_phrase这两种检索方式有什么区别?

 match_phrase 查询将查询字符串视为一个整体短语,查找包含完整短语的文档,而 match 查询对查询字符串进行分词处理,查找包含分词的任意一个词的文档

讲一下项目里的日志设计,是怎么实现的

基于 SLF4J+Logback 的日志框架

项目中采用SLF4J 作为日志门面(统一接口),Logback 作为日志实现(性能优于 Log4j,原生支持 SLF4J)

通过 SLF4J 的Logger接口记录日志,避免直接依赖 Logback 实现,便于后期切换日志框架

为什么引入XXL-JOB

1.C端竞赛列表那里

2.用户竞赛消息那里:每天竞赛结束之后,都要将结束竞赛的成绩排名发给用户

一开始有想过用RabbitMQ来代替XXL-JOB吗?,为什么不采用RabbitMQ代替XXL-JOB

  • RabbitMQ 的延迟队列依赖 “死信交换机 + TTL” 实现,其定时精度受限于消息投递、队列处理的耗时,且在高并发场景下可能因队列堆积导致延迟(例如大量竞赛同时到期时,消息处理排队,导致状态更新滞后)。

JWT配置Redis解决是如何JWT无状态的问题

想办法⽤⼾修改了个⼈信息之后,jwt不变。
  • payload中仅仅存储⽤⼾唯⼀标识信息,那么修改⽤⼾信息就不会引起jwt改变。
3.能够控制jwt的过期时间

http://www.dtcms.com/a/581551.html

相关文章:

  • 免费空间领取网站为企业设计网站
  • 邮储政务金融云平台官网地址无法百度
  • Flutter AnimatedRotation 实现旋转动画
  • 五、CSS盒子模型(下)
  • 网站建设的方法有四种怎样创建公众号
  • 开源项目ruoyi-ai本地部署
  • 乡镇同城O2O系统开发:Java与PHP技术选型对比
  • google提交网站入口能打开各种网站的搜索引擎
  • MyBatis完整教程IDEA版(3)--动态SQL/MyBatis缓存
  • 基于Vue的饮食健康管理系统的设计与实现fs9r43tj(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • linux tomcat注册服务
  • OpenCV计算机视觉实战(29)——OpenCV DNN模块
  • 基于若依-内容管理动态修改,通过路由字典配置动态管理
  • 中江门户网站中铁建设集团有限公司招投标平台
  • Oracle与HGDB拼接的差异
  • Rust高级类型与零成本抽象实战
  • 数据结构 -- 树(遍历)
  • 浅析MySQL InnoDB存储引擎的MVCC实现原理
  • 手机传奇手游发布网站如何做网站做网站需要多少钱
  • ​TVS管选型设计:从理论到实践的全面解析-ASIM阿赛姆
  • 嵌入式开发中的“偷懒”艺术大纲
  • 网站开发期末作品代码和数据库运行好大全企业seo推广的绝密诀窍曝光
  • 石家庄企业网站网页设计wordpress主题demo
  • 宝塔 wordpress 多站点乐清营销网站
  • 【一、基础篇】Transformer 模型主要由哪两部分组成?
  • YASKAWA机器人焊机气体省气
  • Java--ACM常用语句
  • uniapp 微信小程序记录
  • Fastapi 进阶三:数据库的应用
  • 把VMware虚拟机下的Ubuntu系统文件夹中文路径名称改为英文(图文详解)