项目面试题


最近都用到Spring Cloud Alibaba的哪些组件,都用来做什么

  1. Nacos(元数据集成规范平台 / 文献资源标引与馆藏管理平台 核心使用)
    Nacos 主要承担服务注册发现和统一配置中心两大核心作用:
    做服务注册发现时,所有微服务模块都注册到 Nacos,模块间相互调用不用手动配置地址,由 Nacos 自动寻址,
    做统一配置中心时,把两个项目里的核心配置,比如数据校验规则、多线程处理参数、ES 索引配置等,都集中在 Nacos 管理,修改配置无需重启服务,实时生效,
  2. Seata(HBOS 医疗业务中台 / 航天云膜库存管理系统 核心使用)
    Seata 主要用来解决微服务分布式事务一致性问题:
    HBOS 医疗业务中台,医嘱开立、药品库存扣减、诊疗费用核算这些操作会跨多个微服务,用 Seata 管控分布式事务,保证这些操作要么全部成功、要么全部回滚,避免出现医嘱开了但库存没扣、费用算错的情况;

航天云膜库存管理系统,库存扣减和订单创建跨模块操作,通过 Seata 解决了分布式场景下的数据不一致问题,杜绝超卖、库存账实不符的核心问题。
3. Sentinel(HBOS 医疗业务中台 / 青松职考在线教育平台 核心使用)
Sentinel 主要做流量治理、接口限流降级和熔断保护,保障系统稳定运行:
在 HBOS 医疗业务中台的门诊接诊、患者信息检索这些核心高并发接口,请求量超阈值时自动降级,避免服务被压垮,保障医院日常诊疗的核心业务可用;

青松职考在线教育平台,用 Sentinel 做限流和熔断, 课程数据检索的响应速度,又提升了用户体验。

元数据集成规范平台

元数据集成规范平台用到什么技术了

Java 多线程、规则引擎,还有 ETL 工具 Kettle,以及 Spring Cloud Alibaba、ES、Redis 这些基础架构技术

怎么实现异构数据标准化处理的?

数据都是xml格式,以NSTL数据为规范标准

  1. XXL-Job定时任务获取NSTL规范的XML数据
  2. 用 Dom4j 将第三方不同来源会议类型数据XML转换为NSTL格式的XML,通过NSTL提供的XSD做格式校验(一套模板对应一个数据源)
  3. 使用ETL进行机器质检,三方数据的文件上传+数据上传
  4. 进行人工复核质检,质检通过可关联,不通过可退回
  5. 通过ISBN相同或EISBN相同或ISBN与EISBN交叉匹配进行关联
  6. 没有NSTL规范数据的进行人工创建规范数据
  7. 展示规范数据,输出下游接口

元数据集成规范平台 / 文献资源标引平台(大数据处理,特色亮点)

处理 80 万 + 馆藏数据、50 万 + 脏数据,用了什么技术方案保证处理效率和准确率?

核心用了多线程分批 + 断点续传的方案,首先把海量数据按 ID 分批次,每批次 1000 条,用线程池开启多线程并行处理,避免单线程处理慢的问题。然后做了断点续传,在数据库中记录每个批次的处理状态,成功 / 失败 / 未处理,一旦服务挂了或者处理中断,重启后能从未处理的批次开始,不用重新处理,避免重复工作。对于脏数据,设计了规则引擎 + 机器质检 + 人工复核的机制,先通过规则引擎过滤掉明显的脏数据,比如缺主键、字段格式错误的,再用机器质检校验数据的完整性和规范性,最后把疑似错误的数据推送给人工复核,这样既保证了处理效率,又能提升准确率。最终 80 万 + 馆藏数据处理完,标引准确率从 89.5% 提到 99.6%,50 万 + 脏数据修复后准确率到 99.5%。

为什么用工厂方法模式做多数据源解析,不用抽象工厂?

首先选工厂方法,是因为这个项目只有数据源解析这一类核心业务,每个数据源对应一个解析实现类,工厂方法能实现解耦和扩展,符合开闭原则;落地时我定义了统一的解析接口,给 WOS、IEEE 各写了解析实现类,又封装了简单工厂做统一创建,,现在只用做解析,用抽象工厂就是过度设计,增加代码复杂度(避坑点);而且工厂方法后续新增数据源,只需要加实现类,不用改原有代码,扩展成本特别低。

怎么实现异构数据的标准化处理?比如 Web of Science、IEEE 的第三方数据和 NSTL 规范数据的整合?

首先对接了 NSTL 的 HTTP API 和第三方出版社的压缩包数据源,先把异构数据解析成统一的 Java 对象,然后设计了XML/XSD 校验框架,根据 NSTL 的规范制定了数据校验规则,对解析后的数据做格式、字段、类型的校验,不符合规则的数据标记为异常并返回原因。然后基于ISSN/ISBN 构建了自动关联规则,把第三方数据的标识和 NSTL 规范数据的标识做匹配,实现数据的自动关联。另外还开发了残缺数据简编补全功能,对于缺少数值、描述等字段的残缺数据,通过规则引擎从关联的规范数据中补全,最终实现了异构数据的标准化处理,支撑了研究所内部的文献检索。

数据修复

把数据按批次拆分,每个线程处理一个批次;
使用了Redisson 分布式锁,以批次 ID 作为锁 key,保证同一时间只有一个线程能处理这个批次;
同时在批次表加了乐观锁(版本号),更新批次状态时带上版本号,确保状态更新是原子操作,避免并发冲突;
每个批次的修复逻辑都包在事务里,要么全部成功,要么全部回滚,保证数据修复的原子性;
再通过 批次状态 实现断点续传,就算服务重启,也能接着处理。

线程池是自定义的,8 核 16G 服务器配了核心线程 10、最大 20、有界队列 100,避免 OOM 又能跑满 CPU;Redisson 锁是按批次 ID 生成唯一 Key,用 tryLock 加 5 秒等待、30 秒自动过期的锁,拿到锁才处理批次,finally 里释放锁,既保证并发安全,又不会死锁。

航天云膜库存数据不一致,怎么排查的,怎么解决的

  1. 按SKU+仓库ID加Redisson可重入锁,避免多线程并发冲突;
    扣减前后双重校验库存数值,搭配定时双缓存比对兜底,发现异常立即告警修正。
    高并发库存扣减时加分布式锁,避免并发冲突;库存扣减成功后同步更新DB和缓存,失败立即回滚
  2. 库存盘点机制(定时任务 + 双缓存对比)
    每天凌晨定时任务自动触发盘点流程:先拉取MySQL全量库存数据生成基准缓存,再同步提取Redis实时业务缓存,按商品ID+仓库ID做唯一匹配对齐维度;随后批量对比两份缓存数据,逐行核对库存数值,标记异常数据并区分偏差类型;紧接着生成异常清单,方便运维人员快速核查。

如何用 Redis 实现分布式锁

航天云膜中扣减 100 + 仓库库存时,对每个仓库的库存 key(如stock:warehouse1)加 Redisson 分布式锁,加锁成功后再执行库存扣减 + 库存变更日志记录,操作完成后释放锁,即使执行中出现错误,业务代码中捕获异常并回滚操作,保证一致性。

项目中如何保证 Redis 缓存和 MySQL 数据库的数据一致性?

库存扣减时,先更新 MySQL 的库存数据,保证数据持久化的正确性;
再删除 Redis 对应的库存缓存,而非更新缓存(避免多线程更新缓存导致的不一致);
若删除缓存失败,通过RabbitMQ 消息队列做重试,保证缓存最终被删除;
当有查询请求时,Redis 缓存不存在,会从 MySQL 查询最新数据,再写入 Redis,完成缓存更新。

销量 / 评分 / 热度动态加权排序算法

我设计的是动态加权排序算法,核心是先把销量、评分、热度标准化为 0-10 分,再结合基础权重 + 时间衰减 + 个性化调整计算最终得分:比如新课的销量 / 热度权重会提升,用户常点高评分课程就调高评分权重。算法通过 ES 的 Function Score Query 落地,权重参数配置在 Nacos 可动态调整,同时预计算排序因子缓存到 Redis,保证排序不影响检索性能。最终搜索结果点击率提升了 25%,用户找课更精准

RabbitMQ 实现课程预约状态异步更新

课程预约功能高峰期写请求多,同步写库导致数据库压力大,我用 RabbitMQ 做了异步改造:用户点击预约后,接口只做基础校验,发送 MQ 消息就返回成功,消费端异步更新课程预约数、用户状态和日志。同时加了本地消息表保证消息不丢,手动 ACK + 死信队列处理失败消息,预约数缓存到 Redis 保证查询性能。最终数据库写压力降了 60%,高峰期系统完全不卡顿,接口响应也快了很多。

消息丢失的情况?如果有,是怎么处理的?如果没有,你们怎么确保消息的可靠传输?

项目中通过三重保障确保消息可靠传输:生产者端开启 confirm 机制,消息发送后等待 Broker 确认,失败则重试;Broker 端队列和消息都设为持久化,落盘存储;消费者端用手动 ACK,处理完消息再确认,避免未处理就丢失。实际运行中没出现过消息丢失,还通过定时扫描死信队列,对失败消息进行重试或人工介入,进一步保障可靠性。

其它问题

线上CPU突然100%怎么排查?

线上 CPU 100% 我会按 4 步排查:

  1. 先用 top 命令定位占用 CPU 的 Java 进程;
  2. 再用 top -Hp 定位进程内的异常线程,把线程 ID 转 16 进制;
  3. 用 jstack 抓取线程栈,结合 16 进制线程 ID 找到问题代码,同时用 jstat 排查是否是 GC 导致;
  4. 最后分析根因 —— 常见的是死循环、死锁、Full GC 频繁

接口超时排查思路是什么?

先看服务器日志,定位超时的接口和具体报错信息;再查数据库,用 explain 看是否是 SQL 慢查询;然后检查中间件,比如 Redis 是否缓存击穿、RabbitMQ 是否消息堆积;最后看服务器资源,CPU、内存、磁盘是否过载,一步步缩小范围,定位问题后针对性优化,比如加缓存、优化 SQL、扩容资源。

接口响应时间从 3.2 秒降至 1.5 秒、4.5 秒降至 1.2 秒,做了哪些具体的优化?

主要是索引重构 + 查询逻辑优化 + 缓存高频数据三步。第一,重构了 MySQL 的索引,删除了冗余索引,对核心的关联查询字段建立了联合索引和覆盖索引,比如文献表的 ISSN+ISBN、馆藏表的馆藏编号 + 索书号,避免回表查询,提升查询效率;第二,优化了复杂的关联查询逻辑,把多表联查拆成两次单表查询,用内存做关联,减少数据库的压力,同时移除了查询中不必要的字段,只查业务需要的字段;第三,用 Redis 缓存高频访问的文献基础数据、馆藏定位数据,这些数据变更频率极低,缓存后直接从 Redis 取,不用查数据库。通过这三步,接口响应时间大幅下降,馆员的工作效率也提升了 60%。

多服务查相同数据

可以搭建独立的course-data-service数据服务:
把课程表的所有查询逻辑(多维度筛选、分页、数据转换)都封装在这个服务里,对外暴露标准化 Feign 接口,其他服务通过 OpenFeign 调用该接口获取数据。
这样一来,所有服务共用同一套查询逻辑,修改时只需改数据服务,无需改所有调用方;
同时给数据服务做了多实例部署和 Sentinel 限流,保证高可用,最终彻底解决了业务逻辑重复、维护成本高的问题。

线上 OOM 突然爆了,怎么排查?

  1. 先用 jmap 导出堆的内存快照 ,或者靠 JVM 参数自动生成快照
  2. 重启服务,保证业务可用
  3. 接着用 MAT 分析 dump,重点看谁占内存最大、引用链有没有问题
    一般就两种情况:
    要么是大对象、批量查询没分页导致内存瞬间打满;
    要么是内存泄漏,比如静态集合、缓存没清理,对象一直无法回收。
    找到问题后改代码、加监控、优化 JVM 参数,再压测验证

数据更新时,请求进来,redis是旧数据,MySQL是新数据

业务代码 只写 MySQL,不碰 Redis
MySQL 一增删改,就会产生 binlog 日志
Canal 伪装成从库,订阅 binlog,抓到变化
Canal 把数据推给我们的 Java 服务
Java 服务异步更新 / 删除 Redis 缓存
前端读的时候,直接读 Redis 就行

如何保证MySQL和redis数据的一致性

我们不追求强一致,保证最终一致性。
方案是先更新数据库,再删除缓存,绝对不先删缓存。
因为先删缓存会导致并发查询写入旧数据。
极端不一致情况概率极低,可通过缓存过期时间兜底。
如果要严格保证,可通过MQ 重试或订阅 binlog 异步删除,确保缓存一定被删掉

SSO单点登录

单独搞一个认证中心(专门管登录的服务),所有系统都认它。
你打开 A 系统,没登录 → 自动跳去认证中心登录页。
输账号密码,认证中心校验通过,给你发一个全局凭证(比如 Token / Ticket)。
带着这个凭证再跳回 A 系统,A 系统拿着凭证去认证中心校验,校验通过就登录成功。
再打开 B 系统,B 系统发现你没登录,也跳认证中心。
认证中心一看你已经登录过了,直接给凭证,不用再输密码,B 系统校验完就自动登录

通用项目问题(所有项目都能答,兜底)

你在项目中遇到的最大的技术难点是什么?怎么解决的?

印象最深的是航天云膜库存系统中,多仓库分布式场景下的库存数据一致性问题,一开始只用了 Redis 扣减库存,但是出现了 Redis 和 MySQL 数据不一致的情况,比如服务挂了导致 Redis 扣减了但 MySQL 没更新。解决的话,首先把库存操作分成预扣减和实际扣减,下单预扣 Redis,支付成功再扣 MySQL,取消订单就回滚;然后用RabbitMQ 做异步同步,Redis 扣减成功后发送 MQ 消息,消费端消费消息再更新 MySQL,同时做了消息的重试和死信队列,保证消息必达;最后加了定时对账任务,每天凌晨比对 Redis 和 MySQL 的库存数据,把不一致的做人工修正。通过这三步,彻底解决了分布式场景下的库存一致性问题,线上再也没出现过数据不一致的情况。

你在项目中是怎么做性能优化的?从哪些维度入手?

一般从数据库、缓存、代码、中间件四个维度入手,这也是我在多个项目中验证过的有效方法。数据库层面:建立合适的索引、优化 SQL 查询、分库分表(大数据量场景)、减少多表联查;缓存层面:用 Redis + 本地缓存做二级缓存、遵循先更 DB 再删缓存的原则、给缓存加合理的过期时间;代码层面:优化循环和判断逻辑、避免重复查询、用线程池处理异步任务;中间件层面:MQ 做异步解耦、Elasticsearch 替代数据库做全文检索、Nginx 做负载均衡。比如在泰康理赔系统和元数据平台中,都是通过这几个维度的优化,把接口响应时间大幅降低,提升了系统性能。

怎么解决项目中的分布式数据一致性问题?

如果是库存扣减、订单创建这种核心场景,用Seata 的 AT 模式,轻量级,对业务代码侵入小;如果是跨系统数据同步、消息通知这种非核心场景,用MQ 异步同步 + 重试机制,比如理赔系统的合作渠道数据同步、库存系统的 Redis 到 MySQL 同步;
如果是缓存和数据库的一致性,遵循先更 DB 再删缓存的原则,加过期时间兜底;如果是分布式锁场景,用 Redisson 的 Redis 锁,避免超卖、重复提交等问题。不同的场景用不同的方案,既保证数据一致性,又兼顾系统性能

Spring AOP 底层怎么实现的?JDK 动态代理和 CGLIB 有什么区别?

Spring AOP 底层就是动态代理,默认优先用 JDK 动态代理,目标类没有实现接口时用 CGLIB;JDK 动态代理是基于接口的,通过反射生成实现目标接口的代理类,调用目标方法;CGLIB 是基于继承的,通过 ASM 字节码框架生成目标类的子类,重写目标方法。项目里我做数据源解析时,因为所有解析类都实现了统一接口,所以用的 JDK 动态代理,结合 AOP 做了日志和校验的切面。

Redis 分布式锁的核心原理?为什么不用原生的 setnx,用 Redisson?

原生 setnx 做分布式锁,核心是setnx+expire,保证锁的原子性,但有两个坑:一是 setnx 和 expire 非原子,可能加锁成功但没设过期时间,锁永久有效;二是锁过期后业务没执行完,会导致锁释放,出现并发问题。Redisson 解决了这些问题,它的可重入锁是基于Redis 的 hash 结构实现的,加锁时记录线程 ID 和重入次数,还自带看门狗机制,业务没执行完会自动给锁续期,而且加锁和设过期时间是原子操作,项目里做库存扣减时用它,彻底避免了超卖和锁失效的问题。

RabbitMQ 怎么保证消息不丢失?

从三个层面保证:一是生产者层面,用 confirm 确认机制,消息发送到交换机后,MQ 会给生产者回传确认,没收到就重发;二是MQ 层面,开启交换机和队列的持久化,避免 MQ 宕机消息丢失;三是消费者层面,关闭自动 ACK,业务执行成功后手动 ACK,执行失败则拒绝并重新入队(或死信队列)。我在库存管理项目里就是这么做的,保证了 10 万级 / 天的消息处理零丢失。

航天云膜库存管理系统

你做的库存管理系统支撑 100 + 仓库高并发扣减,QPS 峰值 500+,怎么解决超卖问题的?

首先用了Redisson 的分布式锁,因为单 JVM 的锁在分布式场景下没用,Redisson 的锁是基于 Redis 实现的,还能自动续期避免锁超时。然后库存的存储结构用了Redis Hash,按仓库 ID 做 key、商品 ID 做 field,这样能精准定位每个仓库的商品库存,扣减时先查 Redis 库存,大于 0 再扣减,扣减成功再同步到 MySQL。另外还做了库存预扣减,下单时扣 Redis 库存,支付成功再扣 DB 库存,取消订单就把库存回滚,从流程上避免超卖。压测到 500+QPS 都没出现超卖,线上运行也很稳定。

这个项目里用了 Redis+Caffeine 二级缓存,为什么这么设计?怎么保证缓存和数据库一致性的?

主要是为了降低 Redis 的访问压力,提升接口响应速度。Caffeine 是本地缓存,访问速度比 Redis 快,适合存那些访问极高频、变更频率低的库存基础数据,比如商品规格、仓库基础信息;Redis 是分布式缓存,存实时变化的库存数量,所有服务节点共享。一致性方面,我遵循先更 DB,再删缓存的原则,更新库存时先更新 MySQL,再删除 Redis 对应的缓存,本地 Caffeine 因为是单机的,用了过期时间兜底,同时更新时会主动清除当前节点的本地缓存,下次查询再从 Redis 加载最新数据,保证最终一致性。

自动盘点功能准确率 99.8%,是怎么实现的?

设计了定时任务 + MySQL/Redis 双缓存比对的机制,用 xxl-job 做分布式定时任务,按仓库分批执行盘点。首先拉取 MySQL 的库存账面数,再拉取 Redis 的实时库存数,逐行比对两者的差值,把不一致的数据标记为异常,生成盘点报表推送给仓库管理员。另外还做了断点续传,如果盘点过程中服务挂了,重启后能从上次中断的位置继续,不用重新盘点。对于少量比对不一致的,排查下来大多是异步同步延迟导致的,加了短暂的重试机制,最终准确率做到了 99.8%,人工干预减少了 90%。

泰康保险理赔管理系统(金融行业核心,高频)

你负责了合作渠道管理模块,怎么设计的机构权限分级体系?

首先结合泰康的业务场景,把机构分为总公司、分公司、合作机构、线下网点四个层级,基于RBAC 权限模型设计,给每个层级分配不同的角色,角色绑定对应的接口和数据权限。比如总公司能看所有渠道的理赔数据,分公司只能看自己辖区的,合作机构只能看自己的业务数据。然后做了数据行级权限控制,在数据库表中加了机构 ID 字段,查询时自动拼接机构 ID 条件,避免越权访问。另外还设计了跨系统数据同步方案,通过 MQ 把合作渠道的业务数据同步到理赔系统,同时做了数据校验,保证跨系统数据的一致性,支撑了理赔对外协作的核心链路。

核心接口响应时间从 500ms 降到 150ms,做了哪些优化?

主要从三个方面优化:第一是数据库优化,对核心查询表建立联合索引,比如理赔表的机构 ID + 报案时间、产品表的产品 ID + 状态,同时优化了关联查询逻辑,减少多表联查和子查询,把复杂的统计查询改成分步查询;第二是缓存优化,用 Redis 缓存高频访问的产品信息、审批规则、机构信息,这些数据变更频率低,缓存过期时间设为 1 小时,更新时主动删缓存;第三是代码逻辑优化,移除了代码中不必要的循环和判断,把一些重复的查询逻辑抽成公共方法,同时关闭了 MyBatis 的一级缓存兜底,避免缓存脏数据。优化后核心接口的响应时间直接从 500ms 降到 150ms 内,满足金融行业的性能要求。

理赔系统中用了 Elasticsearch 做全文检索,怎么保证检索准确率 95% 的?

首先基于理赔资讯、产品名称、案件描述等字段建立了自定义检索索引,用了 IK 分词器的智能分词模式,能对中文长句做精准分词,避免漏词和错分词。然后做了字段权重设置,比如把理赔资讯的标题权重设为 3,内容权重设为 1,产品名称权重设为 2,这样搜索结果会优先匹配权重高的字段,提升相关性。另外还做了同义词扩展,比如把 “理赔”“核保”“报案” 的同义词加入词典,避免用户输不同的词搜不到结果,同时对搜索结果做了精准过滤,根据用户的机构权限过滤掉无权访问的内容。最终检索准确率做到了 95%,满足业务方的需求。

医疗中台

:你们医疗中台多服务调用,数据一致性怎么保证?Seata 怎么用?

我们医疗中台是微服务架构,医嘱、收费、药品、病历多个服务互相调用,传统本地事务保证不了一致性,所以我们用了 Seata AT 模式 实现分布式事务。
实现流程(口语化)
搭建 Seata Server(TC 事务协调器)
单独部署,负责全局事务的提交与回滚,管理所有分支事务。
每个微服务引入 Seata 依赖,配置数据源代理
Seata 会自动代理数据源,无侵入式接管事务。
在发起方方法上加 @GlobalTransactional
比如开立医嘱这个接口,作为全局事务入口。
执行流程
开启全局事务,生成 XID;
调用订单、药品、收费服务,自动传递 XID;
所有服务执行成功 → 全局提交;
任意一个服务失败 / 异常 → 全局回滚。
原理(简单说)
Seata AT 模式基于undo_log 回滚日志,自动记录数据前镜像,需要回滚就恢复,对业务代码零侵入。
业务场景(医疗最贴合)
比如开立医嘱:
扣药品库存 + 生成费用 + 记录病历,
任何一步失败,所有操作全部回滚,
绝对不会出现 “扣了库存没生成费用” 这种数据错误。

航天云膜库存管理,怎么解决 100 + 仓库高并发扣减的超卖问题?

我核心用了Redisson 的分布式锁+Redis Hash 分仓库存储库存(方案);细节上,首先用 Redis Hash 按仓库 ID 做 key,存储每个商品的库存,避免单 key 竞争;然后用 Redisson 的可重入锁,给每个商品 + 仓库的组合加锁,设置锁过期时间 30 秒,同时利用 Redisson 的看门狗机制,业务没执行完会自动续期,避免锁提前释放导致超卖;还做了库存预扣减,扣减前先判断库存是否充足,不足直接返回

茶悦

用户权限与登录模块怎么设计实现?

我用的是 SpringBoot + Spring Security + JWT 实现的登录认证和权限控制。
流程是:
用户输入账号密码 → 后端校验通过 → 生成 JWT 令牌 返回前端;
前端每次请求把 token 放在请求头里;
后端通过 JWT 拦截器 校验 token 合法性、过期时间,解析出用户信息;
权限基于 RBAC 模型:用户 → 角色 → 权限,不同角色(管理员、门店、用户)看到不同菜单、接口权限。
安全方面:密码 BCrypt 加密、token 过期自动刷新、敏感接口防止重复提交。

基于 RabbitMQ 实现订单、支付结果异步通知怎么做?

流程:
用户支付成功 → 支付服务发送 MQ 消息(订单号、支付状态);
订单服务监听队列,消费消息,更新订单状态为 “已支付”;
同时通知库存服务:扣减真实库存;
整个流程 异步化,不阻塞主线程,提升系统吞吐量。
保证消息可靠:
开启 消息持久化、生产者确认、消费者手动 ACK,确保消息不丢、不重复消费。

青松职考

怎么搭建 Elasticsearch 集群?

我用的是 3 节点高可用 Elasticsearch 集群,基于 ES 7.x 版本搭建。
架构:
3 个节点:1 个主节点(负责集群管理)+ 2 个数据节点(负责存储、检索);
集群配置:
开启 集群发现,配置同一集群名称;
副本数设置为 1,分片数设置为 3,保证高可用、负载均衡;
高可用:任何一个节点挂掉,其他节点能自动接管,不影响线上服务;
配合 Kibana 做日志监控、索引管理、性能分析。

索引(题库、试卷、课程)怎么设计?

我根据业务做了 3 个核心索引:题库索引、课程索引、试卷索引,结构分离、互不干扰。
题库索引(核心)
字段:题目 ID、题干、选项、答案、难度、分类、标签、创建时间、权重
分词:IK 分词器(智能分词),支持题干、标签模糊检索
keyword 类型 用于精准筛选(难度、分类);
text 类型 用于全文检索;
float 类型 预留 weight 权重,用于加权排序。
课程 / 试卷索引
字段:名称、简介、分类、价格、热度、更新时间
支持:模糊搜索 + 分类过滤 + 热度排序

动态加权排序算法怎么实现?

我基于 ES function_score 自定义评分 实现了动态加权排序算法。
核心公式:
最终得分 = 匹配度得分 * 权重系数
加权因子(动态计算)
题目热度(点击量、收藏量)
题目难度(易中难加权)
更新时间(新题权重更高)
用户做题偏好(个性化)
后台手动设置的权重
ES 实现方式
使用 function_score
组合 field_value_factor、weight、script 动态计算最终分数
结果按 总分倒序 返回
效果
搜索更精准
热门题、优质题、新题优先展示
支持后台动态调整权重,不用改代码


文章作者: zrh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 zrh !
  目录