本文最后更新于0 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
一面
- 自我介绍
- 找工作优先南京?
- 为什么想做toC业务而不是toB?
- 挑一个项目比较有挑战性的地方介绍?讲了rag企业知识库的背景
- 做这个项目有什么收获?拓宽了技术栈 es kafka
- kafka使用的详细场景介绍下?对用户上传文档——文档向量化解析两个操作进行异步解耦,优化用户体验
- 文件上传这一块的并发量大概是多少?随便编了一个QPS在100左右
- 异步操作为什么选择消息队列而不是其他方案?为什么使用kafka而不是其他消息队列?
- 像redis,zookeeper也可以实现简单的消息队列(pub/sub),但无法支持更复杂的功能(如重试机制、持久化等)
- 选择kafka而不是mq的原因一方面是自己想学习这方面技术,另外也是rocketmq相比kafka更适合这个场景(这里追问为什么适合 不了解),也能保证高可用和高性能、消息不丢这种
- 追问:那你运用到了kafka,是怎么保证消息不丢的?
- 生产者设立确认机制,设置acks=all,保证消息写入broker所有节点
- broker设置replica副本数为3,保证持久性
- 消费者建立确认机制
- kafka具体是怎么使用的?
- 代码实现就是定义了生产者和消费者
- 生产者部分:当用户分片上传文档且minIO合并操作完成后发送一条消息给topic a
- 消费者部分:订阅该topic,有消息时获取消息内的对应信息,然后执行文档向量化操作
- 文档向量化操作是什么,详细解释下?
- 正常关键词检索只需要比对原始上传文档和用户查询词即可,但无法实现语义查询(如查询“雪糕”返回“冰淇淋”)
- 对上传合并后的文档执行分块chunk操作,然后对每个chunk执行向量化service,并将对应向量存到es中,当用户输入query的时候计算输入query的向量,然后进行向量相似度比对,语义越相近比对分数越高,搜索排名越靠前,最后返回topK条结果
- 向量化服务是你们自己实现的还是调用了已有的服务?
- 向量化本地也可以实现(?不太确定),但考虑到机器计算成本和执行效率,最后还是采用调用第三方embedding api完成,所谓的向量实际就是计算得到的固定长度(维度)的float数组
- 那你这个向量的存储是实时的吗,还是每次用户查询都要现算?
- 针对用户query的向量化是每次查询实时计算的,但是用户上传的知识库向量化是异步在后台完成的
- 那向量化api具体的响应时间是多少?
- 这个根据向量的输入token长度决定,长度为几十的token通常几百毫秒左右,但针对长文本(如十几兆的txt)等可能会有所增加,具体时间不清楚
- 那你的整个用户提问——检索——生成总服务的qps大概是多少?
- 会根据知识库规模增大而提升,如果只有十几个小型知识库 那么qps可以达到100左右,如果是成百上千条文档,那么性能瓶颈就会体现在es的检索部分,qps下降至几十左右
- 你是如何定位并发现这块的性能瓶颈的?具体是怎么做的
- 我们邀请了几百个用户使用,根据他们的使用反馈进行迭代测试
- 有用户反馈初期知识助手检索问答很快,使用人数增加后响应时间变慢
- 那你是如何考虑优化的?
- 优化方向主要是技术替换,使用专业的向量数据库替换es(如faiss)
- 或者对代码检索逻辑进行改进,比如把检索方法从knn替换成hnsw(不知道es原生是否支持)
- 笔试成绩是49.59分,排名41,39%,编程ac了1道剩下两道部分通过, 怎么看?
- java的学习方式
- Spring最大的特点是什么?这里扯了springboot的特点,约定大于配置,IoC和DI,AOP,快速启动starter等等
- 追问:什么场景需要AOP?可以抽离出公共逻辑的场景(如记录日志)等
- 追问:如果一个方法上定义了两个AOP,那么他们的执行顺序是什么?不太了解,随便扯了下around beforeall before afterall after,一般顺序是beforeall- before-around-after-afterall,可能还有只执行一次的
- 追问:那如果我两个AOP都是@Around呢,具体的执行顺序是什么?不清楚,可能根据方法名或者扫描的顺序决定,也可能跟@Order定义的优先级有关(不了解)
- Full gc问题怎么解决?
- 讲了排查思路 先硬件再软件,看运维平台指标和告警,去服务器看日志信息,执行jstus命令和jdump命令定位具体方法,然后优化对应语句(try-with-resouce,finally及时释放资源),扩容(将机器内存从8g->16g)等多种方法
- mysql中什么场景下会出现死锁?
- 讲了死锁产生的四个条件(互斥 请求和保持 不剥夺 环路等待) 引申到mysql中就是比如两个事务互相持有对方需要的资源并构成了请求链
- 那怎么去解决死锁呢?
- 对于上面所讲的例子只需要调整请求资源的顺序就可以了
反问,具体业务(贷款?) toBtoC都有 技术栈都比较符合
二面是HR面,比较奇怪
- 自我介绍
- 一面的体验
- 什么渠道了解我们公司的
- 本科和硕士转专业,为什么做java?
- 离职了对吧?当时怎么获得实习机会的
- 实习的核心工作?两个组
- 比较大的困难?举了需求case
- 除了问别人还有哪些渠道或者方法?wiki,ai
- 有实习转正吗?有 考虑北京不想去
- 有对象吗
- 选择平台关注的信息?地域>薪资>其他
- 有投递其他公司吗?
- 除了地域 其他比如导师 成长空间 技术栈更看重哪个?起点 技术
反问:部门业务(进去再划分) 培养机制 催尽快进度
三面主管面
- 自我介绍
- 熟悉哪个项目 ai
- 业务角度:介绍下面向的目标用户?所有企业员工
- 怎么衡量这个系统的好坏?主观评价(用户点赞点踩反馈) + 客观指标(准确度 + 召回率)
- 具体的准确率指标是多少?准确率0.9,召回率0.74
- 具体的项目架构是什么,微服务还是什么?Springboot单体前后端分离项目
- 你觉得最大的难点是什么?分片上传
- 你提到了分片上传和断点续传,这两者的关系是?分片上传是实现断点续传的一种方式,但不唯一
- 追问:除了分片还有哪些方式实现断点续传?不知道
- 追问:假设有两种实现方式,一种用redis缓存各分片上传状态,另一种直接记录当前上传进度点,你觉得这两种方式各自的优缺点和适用场景?第一种不适合分布式场景,第二种实现可能简单
- 还有哪些难点?讲了kafka异步,超大文件上传解析如何保证不oom
- 如果企业级商用,你觉得还有哪些地方需要改进?重新做技术选型,
- 如何写出好的代码?命名规范,遵守开发手册,考虑更多边界情况(空值等),自己测试
- 挑一个你觉得熟悉的中间件讲一下:mysql
- 你提到了索引,除了满足最左匹配原则外还应该满足什么?多使用联合索引,避免索引列执行函数操作,注意隐式转换
- 追问:为什么不能在索引列上执行函数操作?可能会创建临时表,不清楚
- 场景:假如我有同一张表,一个在测试环境可以走索引,另一个在生产环境发现没有走索引,你觉得可能的原因是?可能跟数据的规模量有关,mysql的服务层的优化器会根据io消耗和cpu消耗选择最终的执行计划,可能因为生产环境数据量太多,走索引反而不如全表扫描耗时短
同一条 SQL 在测试环境走索引,在生产环境不走索引,通常是因为成本优化器根据两环境的统计信息和数据分布,做出了不同的执行计划选择。
生产环境的数据量更大、数据分布不同、索引选择性变差,优化器可能认为“索引扫描 + 回表”成本更高,而“全表扫描”更便宜,从而不走索引。
除此之外,还有很多常见原因会导致索引失效,包括:
1)统计信息不同或过期
InnoDB 使用采样统计,两环境数据分布不一样,可能导致优化器误判索引选择性。可以通过 ANALYZE TABLE 更新统计信息。
2)SQL 写法在生产环境触发了索引失效
- 隐式类型转换(如 int 列用字符串比较)
- 在索引列上使用函数或表达式
- 前缀模糊搜索 %xxx
- 字符集 / 排序规则不同
3)索引本身的质量不同
- 索引碎片严重
- 索引选择性非常差(比如 sex、status)
4)数据库配置或版本不同
不同的 MySQL 版本或优化器参数可能影响执行计划。
**总结一下:**差异通常来自 SQL 写法、统计信息不一致、数据分布不同、索引选择性差,以及优化器参数不同。实际排查时通常先看 EXPLAIN、检查统计信息、执行 ANALYZE TABLE,并对比两环境的表结构和执行计划。
- 追问:如果用mysql存18位身份证号,现在需要对后六位执行查询操作,有哪些方法?将身份证号细分为地区+出生日期+xx+后六位 执行查询
- 追问:如果不拆分表项应该怎么做? 用”%like”但效率低,
可以用mysql倒排索引后面想了下或许可以reverse配合like做 - 手撕:两个有序数组a[1,3,5,6],b[2,3,5,7],求两个数组中的共同元素数组c[3,5]
说了三种方法,hashset, hashmap(这两种都没用到有序特性),双指针
- 追问:双指针这种思路在编写时需要注意什么情况? 注意单个数组是否有重复元素,以及遍历结束条件判断等
- 追问:双指针方法的复杂度是多少?假设数组长度分别为n和m,时间复杂度O(m+n) 空间复杂度O(1)
- 场景:假设有很大量级的数据(如数字),内存中无法全部放下,如何快速判断? 借助堆排序,或者说分段的思想,将总数据分块,然后对每个分块数据用一个指针比较
- 追问:你说的这种方法是指对分块数据遍历吗,这种情况必须要求原数据有序吧?确实 ,如果无序的话可以借助bitmap思想,假设有一亿数据,就设置2^10*10^9bit 每位0 1 表示元素是否存在
- 追问:那如果不是数字而是字符类型呢?用布隆过滤器的思想,设定多个hashmap计算对应为是否为1,这也是布隆和bitmap的区别,布隆不要求字符类型必须为数字
- 追问:你说的这种方法有误判率,还有没有更好的方案?不知道
- 聊聊jvm,你对不同垃圾回收器(如g1 cms)的理解,和你认为以后gc的发展趋势?没答上来,后期反问提示要根据微服务内容和大内存机器,以及STW来思考
- 聊聊你的优缺点
- 聊聊自己觉得具备内驱力的一件事
反问,金融方向,早期用美团中间件现在自研 后期等hr通知







