面灵AI→

客诺信息技术 Java后端 一二面面经:八股、项目与 Agent 追问

轮次
一面+二面
时间
2026-09
来源
牛客网

《面试题目》

一面(9.23,15 分钟)

  1. 自我介绍。
  2. 实习的时候做过的最有挑战性的事是什么?
  3. == 比较的是什么?
  4. 为什么使用 equals 之前我们也要重写 hashCode?
  5. String a = new String("abc"); 和 String b = new String("abc");,a == b 和 a.equals(b) 的答案分别是什么?
  6. 让你设计订单表,你会怎么设计?
  7. 一个商品今天卖 100,明天卖 120,那么昨天的订单价格会变化吗?
  8. 电脑连接 wifi,局域网 IP 是什么?
  9. 127.0.0.1 是什么 IP?
  10. 你平时使用的 AI 模型是什么?
  11. 你平时怎么去审查代码?

二面(9.29,50 分钟)· 实习相关

  1. 结合最近做的项目进行自我介绍。
  2. 实习项目中 RBAC 权限是怎么设计的?最终在后端是怎么控制用户调用接口的?
  3. 如果让你自己去实现权限注解,你会怎么设计?
  4. 实习中做的 Excel 数据表格导入这一块具体是怎么实现的?
  5. 邮件推送中的异常告警是怎么设计和触发的?
  6. 触发告警后怎么保证发送成功,链路是怎样的?失败了会怎么处理?

二面 · 八股和场景题

  1. 讲一下 Java 的集合框架。
  2. 讲一下这些集合容器有哪些常用的 API?
  3. 现在有一个学生成绩表(学生名字、各个科目的成绩),假设有一万条,现在要找出单科前十、总分前十的学生信息,使用集合进行实现。
  4. 在一个 controller 里面注入另一个 service,那么这个 service 是单例的还是多例的?
  5. 为什么 Spring 默认提供单例的 bean,为什么不是多例呢?有什么优缺点?
  6. 使用单例 bean 时有哪些需要注意的事项?
  7. SpringBoot 中你常使用的注解有哪些?
  8. 如果要将一个字符串存入数据库,那么有哪些字段类型可以进行存储?
  9. MySQL 中索引的创建和使用有哪些原则和技巧?
  10. 假设有班级表和学生表(有班级 id 冗余字段),现在要统计每个班级中有多少学生,具体 SQL 怎么写?
  11. 在上面的基础上,我还要统计男生人数和女生人数,应该怎么实现?
  12. Redis 中常见的数据结构有哪些?
  13. 对于这些数据结构,常见使用的 API 有哪些?
  14. git 中的常见操作有哪些?
  15. commit 和 push 的区别是什么?
  16. 浏览器中调试的开发者工具有使用过吗?
  17. network 里面你一般关注什么?
  18. 讲一下 HTTP 中你熟悉的状态码。

二面 · Agent 相关

  1. 大模型两种 API 的调用方式分别是什么?
  2. 这两种方式有什么区别?
  3. Agent 中的系统提示词和用户提示词有什么区别?
  4. 项目中 RAG 的评测是怎么做的?
  5. 精排的过程是怎么做的?

《参考解析》

== 与 equals、hashCode:== 对基本类型比的是值,对引用类型比的是地址;equals 默认也是比地址,被 String、Integer 这些类重写成比内容。重写 equals 就必须重写 hashCode,因为 HashMap、HashSet 先用 hashCode 定位桶、再用 equals 在桶内比较,两者不一致会出现「明明相等却查不到」或者同一个对象被存进两个桶的情况。规范写法是用同一个字段集合参与两者的计算,并且保证对象在放进集合后关键字段不再变化。

订单表设计与商品调价:订单表的核心是「下单那一刻的价格必须冻结」。所以订单表里除了商品 id,还要落成交价、数量、优惠金额、应付与实付,商品表改价不会回头改历史订单。第 7 题考的就是这个:昨天的订单价格不会变,因为订单存的是快照价而不是关联查询商品表当前价格。表结构上注意金额用 decimal 不要用 float、订单号独立于主键、状态字段配操作流水,方便对账和排查。

RBAC 与权限注解:RBAC 三张核心表——用户、角色、权限(或资源),加两张关联表。后端控制通常分两层:路由或方法级用注解声明所需权限,拦截器或 AOP 切面在调用前取出当前用户的权限集合做比对,越权直接抛异常。要自己实现一个权限注解,思路是自定义 @RequiresPermission 注解 → 在切面里通过反射拿到方法上的注解值 → 从 SecurityContext 或 ThreadLocal 取当前用户 → 查权限集合判断 → 不通过就抛 403,同时把校验结果做缓存避免每次打库,再补上超管放行和数据行级过滤这两处例外。

Spring 单例 bean:默认单例,因为绝大多数 bean 是无状态的(Service、DAO、工具类),复用同一个实例省去了反复创建的开销,也让依赖注入和生命周期管理简单得多。单例的代价是必须无状态:不能往成员变量里塞请求相关数据,否则并发下会互相串数据。所以单例 bean 的注意事项集中在一处——成员变量只放线程安全的、不可变的东西,请求级数据走方法参数或 ThreadLocal;真要持有可变状态就把作用域改成 prototype 或 request。

两条统计 SQL:每个班级的学生数是 select class_id, count(*) from student group by class_id。加男女分列不用查两次,用条件聚合一次出来:select class_id, count(*) total, sum(case when gender = 'M' then 1 else 0 end) male, sum(case when gender = 'F' then 1 else 0 end) female from student group by class_id。MySQL 里也可以写 count(if(gender = 'M', 1, null)),效果一样、更短,回答时点出「用 count 而不是 sum,避免没有男生时返回 0 行语义不一致」更容易加分。

Redis 数据结构与选型:String 做缓存与计数器(incr、setnx 做锁),Hash 存对象字段(hget、hincrby),List 做队列(lpush/rpop、brpop 阻塞取),Set 做去重与共同好友(sadd、sinter),ZSet 做排行榜与延时队列(zadd、zrange、按 score 取区间),再往上就是 bitmap 做签到、HyperLogLog 做 UV 估算、Stream 做消息。面试官问 API 其实是在问「你会不会按场景选结构」,把「什么场景用什么结构、为什么」讲出来比背命令列表值钱。

大模型的两种 API:Completion(文本补全,输入一段 prompt 直接续写)与 Chat(对话,输入是 role 为 system / user / assistant 的消息数组)。区别在三点:Chat 有角色区分、能多轮维护上下文,模型侧按对话格式训练,指令跟随和拒答表现更好;Completion 更接近裸的下一 token 预测,适合补全、改写这类任务,且没有多轮状态。现在新模型基本都推荐 Chat 接口,Completion 更多是兼容遗留代码或纯续写场景。

系统提示词与用户提示词:system 是调用方(应用)设定的角色、边界和输出格式,对整段会话生效,属于「规则」;user 是这次请求的具体输入,属于「内容」。两者冲突时模型通常优先遵守 system,这也是 prompt injection 要从这里防的原因——用户输入里出现「忽略以上指令」这类内容时,应用侧要做拼接隔离和输入校验,不能指望模型自己分辨。

RAG 评测与精排:评测一般分两层——检索层看 recall@k 和 MRR(该被召回的资料有没有进前 k、排得靠不靠前),生成层看忠实度(答案是否只依据召回内容,也就是幻觉率)、答案相关性、上下文利用率,手里要有标注好的问答对当测试集,改一次参数跑一遍对比。精排(rerank)在粗排召回之后,用 cross-encoder 这类模型把 query 与每篇候选文档拼在一起打分,比向量相似度更准但更慢,所以只对前几十条做;工程上还要注意截断长度、批次大小和打分归一化,否则排序结果在不同 query 之间不可比。