不愧是高级Java开发岗,确实有点难~

wangzhongyang007 · · 732 次点击 · · 开始浏览    

今天和大家分享一下[组织内部](https://mp.weixin.qq.com/s/OQD8MJakqkgMxdyvaYoX7w)成员在**高级Java开发工程师**岗位的面经详解,看看面试强度如何(删除了跟主人公项目相关的问题): # 面经详解 ### 1. 线程池参数怎么配置?拒绝策略? #### 线程池参数配置: 1. **核心线程数(corePoolSize)** • **CPU密集型任务**:通常设置为 `CPU核心数 + 1`,例如4核CPU设置5。 • **IO密集型任务**:建议设置为 `CPU核心数 × 2`,例如4核CPU设置8,或通过公式 `CPU核心数 × (1 + 平均等待时间/计算时间)` 动态调整。 • **获取CPU核心数**:通过 `Runtime.getRuntime().availableProcessors()` 获取。 2. **最大线程数(maxPoolSize)** • 根据任务突发流量和资源限制调整。IO密集型任务可设置为 `CPU核心数 × 2~4`,突发场景可更高。 3. **队列(workQueue)** • **有界队列**(如 `ArrayBlockingQueue`):防止内存溢出,容量按需设置(如100~1000)。 • **无界队列**(如 `LinkedBlockingQueue`):需谨慎使用,可能导致任务堆积。 4. **空闲线程存活时间(keepAliveTime)** • 非核心线程空闲超过此时间会被回收,通常设为60秒。 #### 拒绝策略: • **AbortPolicy**(默认):直接抛出异常,适用于需快速失败场景。 • **CallerRunsPolicy**:由提交任务的线程执行任务,用于降级处理。 • **DiscardPolicy**:静默丢弃新任务,可能导致数据丢失。 • **DiscardOldestPolicy**:丢弃队列中最老任务,尝试提交新任务。 --- ### 2. IO密集型与CPU密集型任务配置 1. **CPU密集型任务**(如复杂计算、视频编码) • **特点**:高计算量、低IO等待、CPU使用率高。 • **线程池配置**:核心线程数 ≈ CPU核心数,最大线程数等于核心线程数,避免过多线程导致上下文切换。 2. **IO密集型任务**(如网络请求、文件读写) • **特点**:高IO等待时间、CPU空闲多。 • **线程池配置**:核心线程数 ≈ CPU核心数 × 2,最大线程数可更高(如16),队列容量根据任务平均处理时间调整。 • **公式参考**:`线程数 = CPU核心数 × (1 + 平均等待时间/计算时间)`。 **示例**: • 4核CPU的Web服务(IO密集型):核心线程数8,最大线程数16,队列容量200,拒绝策略 `CallerRunsPolicy`。 --- ### 3. 为什么消费消息和推送分开? 1. **解耦与扩展性** • 消费消息负责处理业务逻辑(如订单支付),推送负责通知(如短信、App推送),解耦后两者可独立扩展。 2. **可靠性** • 推送失败时,消息仍保留在队列中,避免数据丢失。分开后消费服务无需关注推送的稳定性。 3. **流量控制** • 高并发场景下,分开可避免推送阻塞消费流程。例如,第三方推送接口QPS低时,推送服务可异步处理或降级。 4. **实时性优化** • 消费完成后立即返回结果,推送可延迟或批量处理(如合并多条通知)。 --- ### 4. 如何优化索引? 1. **索引选择** • **覆盖索引**:查询字段全在索引中,避免回表。 • **联合索引**:按最左前缀原则设计,例如 `(a, b, c)` 可优化 `WHERE a=1 AND b=2`。 2. **避免无效索引** • 删除未使用或重复索引,减少写操作开销。 3. **查询优化** • **索引下推**:在存储引擎层过滤数据,减少回表次数(如MySQL 5.6+)。 • **避免深分页**:使用游标分页(记录上一页最后ID)替代 `LIMIT offset`。 4. **分库分表** • 数据量过大时,按业务垂直分库或按ID哈希水平分表。 --- ### 5. 为什么不用openid和unionid联合分表? 1. **数据分布不均** • `openid` 是用户唯一标识,而 `unionid` 是同一主体下多应用的统一ID。联合分表可能导致数据倾斜(如同一企业用户集中在少数分表)。 2. **查询复杂度** • 联合分表需同时处理两个字段的路由逻辑,增加代码和维护成本。 3. **业务需求** • 若业务场景仅需按 `openid` 查询(如用户订单),单字段分表更简单高效。 --- ### 6. JVM如何优化? 1. **堆内存设置** • 初始值(`-Xms`)和最大值(`-Xmx`)设为相同,避免动态调整(如 `-Xms4g -Xmx4g`)。 2. **垃圾回收器选择** • **G1**:适合大内存、低延迟场景(JDK9+默认)。 • **Parallel GC**:高吞吐量场景(如批处理)。 3. **新生代与老年代比例** • 通过 `-XX:NewRatio=2` 设置新生代:老年代=1:2。 4. **监控工具** • 使用 `jstat`、`VisualVM` 分析GC日志,定位内存泄漏或频繁Full GC原因。 --- ### 7. 多个RPC接口调用如何实现? 1. **线程池异步调用** • 为每个RPC接口分配独立线程池,避免资源竞争。例如,支付接口和库存接口使用不同线程池。 2. **CompletableFuture编排** • **链式调用**:使用 `thenApply()`、`thenCompose()` 串联任务。 • **并行调用**:`CompletableFuture.allOf()` 等待多个接口完成。 --- ### 8. 锯齿遍历二叉树(算法题) **思路**: 1. **层序遍历**:使用队列按层遍历节点。 2. **方向标记**:偶数层反转结果(如第0层从左到右,第1层从右到左)。 **代码**: ```java public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> ans = new ArrayList<>(); if (root == null) return ans; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); boolean isReverse = false; while (!queue.isEmpty()) { int size = queue.size(); List<Integer> level = new ArrayList<>(); for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); level.add(node.val); if (node.left != null) queue.offer(node.left); if (node.right != null) queue.offer(node.right); } if (isReverse) Collections.reverse(level); ans.add(level); isReverse = !isReverse; } return ans; } ``` --- ### 9. 第三方SDK QPS低如何处理? 1. **限流** • **令牌桶算法**:控制请求速率(如Guava `RateLimiter`)。 • **队列缓冲**:将请求暂存队列,异步处理。 2. **缓存** • 缓存高频请求结果,减少重复调用。 3. **异步调用** • 使用线程池或消息队列异步发送请求,避免阻塞主线程。 4. **备用方案** • 主备SDK切换(如腾讯云短信和阿里云短信)。 --- ### 10. 低优先级消息如何进一步区分? 1. **多级队列** • 按优先级分队列(如高、中、低),每个队列独立处理。 2. **动态权重** • 根据系统负载调整低优先级消息的处理权重(如空闲时多处理低优先级)。 3. **延迟处理** • 低优先级消息延迟消费(如Kafka消息设置 `delay` 时间)。 --- ### 11. ES的作用? 1. **全文搜索** • 支持分词、模糊查询、高亮显示(如商品搜索)。 2. **日志分析** • 实时分析日志数据(如ELK栈)。 3. **数据分析** • 聚合统计(如用户行为分析)。 --- ### 12. ES读和写的区别? 1. **写入** • **近实时**:数据写入后需 `refresh`(默认1秒)才可查。 • **分片策略**:文档根据 `_routing` 写入特定分片。 2. **读取** • **实时性**:通过 `GET` 可立即读取(因主分片直接返回)。 • **分布式查询**:协调节点聚合各分片结果。 --- ### 13. 现网问题如何处理? 1. **监控告警** • 使用APM工具(如SkyWalking)监控CPU、内存、GC。 2. **日志分析** • 通过ELK分析异常日志,定位错误堆栈。 3. **回滚与扩容** • 紧急问题回滚至稳定版本,并发过高时扩容实例。 4. **限流降级** • 触发熔断(如Sentinel)或关闭非核心功能。 **处理流程**: 1. 复现问题 → 2. 分析日志/监控 → 3. 定位代码 → 4. 修复验证 → 5. 灰度发布。 ## 欢迎关注 ❤ 我们搞了一个**免费的面试真题共享群**,互通有无,一起刷题进步。 **没准能让你能刷到自己意向公司的最新面试题呢。** 感兴趣的朋友们可以加我微信:**wangzhongyang1993**,备注:面试群。

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

732 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传