科大讯飞 Java 一面面经:Agent 设计范式、线程池参数与 MVCC
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
一面
- 自我介绍
- 深挖项目
- Agent 的设计范式
- 如果想给你的项目多加一个付费模块,需要考虑什么
- 深挖实习
- Java 线程安全主要解决什么问题?
- 线程安全的方法有哪些?
- 线程池有哪些核心参数?
- 拒绝策略有哪些?
- 具体讲一下 MVCC?
- 除了分配给你的工作,有没有自己主动发现问题?
- 你自己沉淀了多少 Skill?挑一个讲
- 反问
《参考解析》
-
Agent 的设计范式:别只背 ReAct 一个词。可以按「推理与执行怎么耦合」把范式串起来讲——ReAct 是「想一步、调一次工具、看结果再想」的循环,适合路径不确定的多源查询;Plan-and-Execute 先出结构化计划再逐步执行,适合步骤多、可并行、需要审计的长流程;多智能体协作(规划者 + 执行者 + 校验者)适合职责天然可分的场景。再补一层工程判断:能用确定性工作流解决的不要交给模型自由规划,模型只负责需要语义判断的那一步,其余用代码锁死。这样说既有名词,又有取舍。
-
给项目加付费模块要考虑什么:这题考的是商业化意识,不是写支付代码。要点是——计费口径(按次、按量、按席位还是订阅,先定义清楚什么算「一次」)、用量采集与对账(计量点放在服务端、可追溯、能重算,避免前端上报被绕过)、权限与配额(额度不足时的拦截与提示、超额是阻断还是欠费)、幂等与退款(回调重试不能重复扣款,退款与撤销要有状态机)、灰度与体验(免费额度、试用、计费变更要提前告知)。如果项目本来就面向企业,还要补合同、发票和对账周期。
-
线程安全要解决什么问题、有哪些手段:本质是三个性质——原子性(复合操作不被中途插入)、可见性(一个线程的写对另一个线程及时可见)、有序性(编译器和 CPU 的重排不破坏逻辑)。手段按代价从低到高排:不可变对象与栈封闭(最省事)、局部变量与 ThreadLocal(天然隔离)、CAS/原子类(无锁、适合计数类竞争)、synchronized 与 Lock(互斥,临界区要短)、并发容器(ConcurrentHashMap 等已经处理好分段与可见性)。回答时最好点一句「先尽量不用共享可变状态,其次才是加锁」,这比罗列 API 更能说明理解。
-
线程池核心参数与拒绝策略:七个参数——核心线程数、最大线程数、空闲存活时间与时间单位、工作队列、线程工厂、拒绝策略。任务提交后的顺序是「核心线程 → 队列 → 扩到最大线程 → 触发拒绝」,这个顺序很多人会答反。参数怎么估:CPU 密集型约为核数 + 1,IO 密集型按「核数 × (1 + 等待时间/计算时间)」估,再用压测校准;队列必须有界,无界队列会把最大线程数这个参数架空,还会把内存撑爆。四种拒绝策略是 AbortPolicy(抛异常)、CallerRunsPolicy(调用方线程自己跑,天然限流)、DiscardPolicy(静默丢弃)、DiscardOldestPolicy(丢最老的),生产上更常见的是自定义策略——落盘、告警、降级返回,而不是丢掉就完事。
-
MVCC:靠「隐藏版本链 + ReadView」实现读不加锁。InnoDB 的每行有事务 ID 和回滚指针,旧版本存在 undo log 里串成版本链;读的时候生成一个 ReadView(记录当前活跃事务集合),沿着版本链找到对当前事务可见的那个版本。RC 与 RR 的区别就在 ReadView 的生成时机——RC 每条语句都重新生成,所以能看到别人已提交的新数据;RR 只在第一次读时生成并复用,于是同一事务内重复读结果一致。要补一句边界:MVCC 只作用于快照读(普通 select),
select ... for update、update、delete属于当前读,读的是最新版本并加锁。