58 同城 Agent 开发一面:数据分析 Agent 与 Java 基础
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 描述一下这个数据分析 Agent 的主要使用对象、主要功能,以及它解决什么问题。
- 这个项目主要解决了什么问题?追问:如果不用 Agent,正常也能取数,那 Agent 带来的价值是什么?
- 你提到 MCP 接口,这个 MCP 接口对外包含哪些能力/有多少种方法?
- 这个里边有一个你们开发的 Agent 吗?对外跟用户交互的是有一个 Agent 吗?
- 外层整个大流程的控制是由项目来控的吗?是 Java 项目吗?相当于在项目里实现了一个工作流?
- 整个流程里你们怎么拿到想要的部分?是否是在某个节点请求一次模型?
- 以 SQL 生成为例:给很多表和需求,生成 SQL 的整个逻辑是什么?数据来源和流程控制大概分几步?
- 第二项生产环境内存问题治理,展开说一下原因、分析过程,以及怎么修复的。
- 最后有调 JVM 参数吗?还是只从工程上优化?
- 第二个项目都是 Java 相关项目吗?
- 校园智能招聘助手里的智能系统涉及 AI 开发吗?
- 后面这两个项目都是你在学校做的课题或实验室项目吗?
- 你熟悉的语言主要就是以 Java 为主吗?
- 你有真正自己开发过 Agent 或写过 Skill 吗?不一定生产,自己练习也行。
- 说一下 Spring 的动态代理。
- MySQL 熟悉是吧?说一下 MySQL 的索引。
- 现场写一个你比较熟悉的排序算法,伪代码或完整代码都可以。
《参考解析》
数据分析 Agent 的价值不是「替人写 SQL」,而是把取数链路缩短。 使用对象通常是运营、产品、业务分析这类懂问题但未必熟 SQL 的人,功能包括自然语言问数、指标解释、维度下钻、异常归因和图表生成。传统 BI 也能取数,但需要人先知道表结构、口径和 JOIN 关系,再写 SQL、等结果、反复改;Agent 把「理解意图 → 找表 → 生成 SQL → 校验 → 执行 → 解释结果」串起来,能多轮追问,也能在失败时自动修正。它的代价是延迟、成本和不确定性,所以适合探索式、口径相对稳定的分析,不适合强一致、强审计的核心报表——后者仍然要走固化模型和人工复核。
MCP 接口要按「能力」而不是「方法数量」回答。 一个数据分析 MCP 通常暴露几类能力:列出数据源/表、描述表结构与字段含义、检索指标口径、执行只读 SQL、返回结果与执行计划、可能还有画图或导出。方法数不是重点,重点是把 schema、权限、超时、行数限制和错误码定义清楚,让 Agent 知道什么时候该调用哪个。外层如果已经有 Java 服务,Agent 可以作为其中一个节点:Java 控流程、鉴权、审计和结果落库,模型只在「选表、生成 SQL、解释异常」这些需要判断的节点被调用,而不是让模型接管整个请求生命周期。
SQL 生成是一条带校验的流水线。 第一步解析问题,识别指标、维度、时间范围、过滤条件和期望粒度;第二步做 schema linking,从大量表里召回相关表与字段,连同字段注释、枚举值、示例值一起放进上下文;第三步生成 SQL,要求只读、带 limit、使用指定方言;第四步静态校验(语法、表字段是否存在、是否全表扫描、是否命中分区)和权限校验;第五步执行,失败时把数据库错误和结果空/异常回传给模型做一次修复;最后把 SQL、口径、结果和假设一起返回给用户。数据来源要标新鲜度和口径版本,避免模型把相似字段拼错。整个链路要有 trace,能回放是哪一步出错。
生产内存问题治理先取证,再改代码或参数。 先看监控曲线是缓慢上涨还是阶梯上涨,配合 GC 日志判断是老年代泄漏、频繁 Full GC,还是堆外/元空间/线程栈问题;然后抓 heap dump,用 MAT 或 JProfiler 看 dominator tree,找占比最大的对象和 GC root 引用链,常见嫌疑是无界缓存、静态集合、ThreadLocal 未清理、连接/流未关闭、类加载器泄漏、直接内存。修复优先改代码:给缓存设上限和过期、拆分大对象、及时 close、避免一次性把大结果集读进内存;参数是辅助手段,比如按容器 limit 设置 -Xmx、合理的 -XX:MaxDirectMemorySize、选低停顿 GC、开 HeapDumpOnOutOfMemoryError。改完要在压测里复现并观察 Full GC 次数、老年代回收后占用和 RSS,确认不是把问题推迟。
Spring 动态代理分 JDK 和 CGLIB 两条路。 JDK 代理要求目标类实现接口,运行时生成实现同一接口的代理类,方法调用转发到 InvocationHandler;CGLIB 通过继承生成子类,覆盖非 final 方法,不需要接口,但 final 类和 final 方法代理不了。Spring AOP 原生默认有接口用 JDK、没有接口用 CGLIB,也可以通过 proxyTargetClass=true 强制 CGLIB;Spring Boot 2.x 起自动配置默认走 CGLIB。代理对象是 AOP 生效的边界:同类内部方法自调用不走代理,事务/缓存/切面会失效,这是常见坑。
MySQL 索引的主线是 B+ 树、聚簇与最左前缀。 InnoDB 主键索引是聚簇索引,叶子节点存整行;二级索引叶子存主键值,查非覆盖字段要回表。联合索引按定义顺序排序,遵循最左前缀,范围查询之后的列通常用不上索引;能用覆盖索引就避免回表。设计时看选择性、区分度、查询模式,别给低基数列盲目加索引;用 EXPLAIN 看 type、key、rows、Extra,关注全表扫描、filesort、临时表和回表次数。索引不是越多越好,写入放大、空间和优化器选择成本都要算。
手写排序优先写快排,但要讲清边界。 选基准、分区、递归左右;工程上随机选基准或三数取中,避免有序数组退化到 O(n²),小数组切换插入排序,递归深度过大时改用堆排。若要求稳定排序就写归并,时间 O(n log n)、额外 O(n) 空间。面试时先把思路和复杂度说清,再写代码,最后补一句「Java 里直接用 Arrays.sort,对象数组是 TimSort,基本类型是双轴快排」。