CVTE 应用软件开发一面(凉经):线程池参数怎么定、WebSocket 与 SSE、微服务拆分原则
- 轮次
- 一面
- 结果
- 面完秒挂
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 挑一个你认为最有亮点的项目介绍:是否全程参与设计和实现?是否参与技术方案讨论与评审?你具体负责哪部分?有没有印象深的、需要重点设计和解决的技术难点?
- 你熟悉哪些设计模式?项目中实际用过哪些?
- 有没有实际做过多线程并发编程?多线程下如何保证数据操作的安全性?平时主要用 Python 还是 Java?
- Java 线程池使用时需要配置哪些参数?参数一般根据什么指标配置?实际会配多少线程、依据是什么?
- 现场编程:写一个洗牌算法。
- WebSocket 和 SSE 有什么区别?分别适用于什么场景?
- 是否了解微服务?微服务主要解决什么问题?如果现在要拆分一个项目,会遵循哪些原则?按业务领域拆分后是否一定要拆得这么细?有没有其他辅助判断服务粒度的原则?
《参考解析》
线程池参数按「任务类型 + 资源上限」推:核心线程数、最大线程数、空闲存活时间、任务队列、线程工厂、拒绝策略。CPU 密集任务取 CPU 核数 + 1(超过只会增加上下文切换),IO 密集可以用「核数 × (1 + 等待时间/计算时间)」估算,线上更可靠的做法是压测找拐点再定;队列长度要考虑内存与延迟(无界队列等于掩埋积压,有界队列要配拒绝策略:Abort 直接报错、CallerRuns 让调用线程背压、Discard 丢任务)。这些要是能结合自己压测数据说,比背公式强。
洗牌算法写 Fisher-Yates:从后往前,对第 i 个位置在 [0, i] 里取随机下标 j 并交换;证明每个排列等概率。常见错误是用 random()*n 取整(有偏)、或者前后交换但范围写错([0, n-1] 会破坏均匀性)。写的时候顺手说一句「用 Random 而不是 Math.random 便于设种子复现测试」。
WebSocket vs SSE:WebSocket 是全双工、基于 TCP 的独立协议(HTTP Upgrade 后切换),适合聊天、协同编辑、需要客户端持续上行;SSE 是单向的服务端推送(text/event-stream,跑在普通 HTTP 上),自带断线重连与事件 id,适合通知、进度、AI 流式输出,实现比 WebSocket 简单、更容易过代理和网关(但 HTTP/1.1 下同域连接数有限,HTTP/2 下才宽裕)。选择逻辑:只需要服务端说 → SSE;需要双向高频交互 → WebSocket;都不需要实时 → 轮询。
微服务拆分原则:按业务能力 / 限界上下文拆(每个服务拥有自己的数据)、高内聚低耦合、按变更频率与团队边界(康威定律)、考虑事务边界(需要强一致的操作尽量留在同一服务)、以及故障隔离与性能要求。粒度判断除了业务域,还看「团队规模与交付节奏、数据一致性成本、调用链长度与运维能力」——拆得过细会带来分布式事务、链路延迟与运维爆炸,所以常见做法是先模块化单体(清晰的模块边界 + 独立数据表),等团队与流量真的需要时再拆。「业务域拆完是否一定要拆这么细」的正确答案是「不一定」,能说出理由比背原则重要。