大厂Java面试实录:从Spring Cloud微服务到Redis缓存穿透,谢飞机如何翻车
大厂Java面试实录从Spring Cloud微服务到Redis缓存穿透谢飞机如何翻车前言在互联网大厂Java求职面试中面试官往往通过层层递进的方式考察候选人的技术深度和广度。本文以电商支付金融场景为背景记录了一次真实的面试过程——严肃的面试官李工 vs 搞笑的水货程序员谢飞机。 面试开始面试官李工你好我是技术负责人李明今天我们聊聊你在电商支付系统方面的经验。谢飞机李工好我...我看过您的博客特别专业 第一轮基础技术考察8:00-8:15Q1你简历上说熟悉Spring Boot能说说它的自动配置原理吗谢飞机这个简单就是EnableAutoConfiguration注解它会扫描classpath下的xxx.properties文件然后根据条件装配Bean。李工很好那具体是扫描哪些包呢谢飞机好像是META-INF/spring.factories...哦不是org.springframework.boot.autoconfigure.AutoConfiguration.imports...李工不错继续深入。在电商支付场景下如果订单创建接口响应超过2秒你会怎么排查谢飞机用...用JVM自带的jstack或者看日志李工思路对但具体步骤呢谢飞机呃...先查慢SQL再看线程堆栈然后...分析GC日志李工基本正确。最后一个问题MyBatis的一级缓存和二级缓存有什么区别谢飞机一级缓存是SqlSession级别的默认开启二级缓存是Mapper级别的需要手动配置...这个我知道李工嗯基础还算扎实。进入下一轮。 第二轮中间件与架构8:15-8:30Q2支付系统中我们用了Redis做缓存如果发生缓存穿透怎么办谢飞机缓存穿透就是查询不存在的数据...可以用布隆过滤器拦截。李工很好那缓存雪崩和击穿呢谢飞机雪崩是大量Key同时过期...设置随机过期时间。击穿是热点Key过期...加互斥锁李工不错继续。你们用的消息队列是什么为什么选择它谢飞机Kafka...因为吞吐量大适合日志采集...李工支付系统的消息可靠性怎么保证谢飞机ACK机制生产者确认消费者手动提交Offset李工具体到支付场景如果消费者处理失败了怎么处理谢飞机重试...死信队列...但是具体配置我不太清楚...李工OK下一个。JWT和OAuth2的区别是什么谢飞机JWT是无状态的Token...OAuth2是授权协议...李工结合我们的电商登录场景你是怎么设计的谢飞机用户登录生成JWT...存在Redis里...前端存Localstorage...李工可以最后一问。Dubbo和Spring Cloud的RPC方式有什么本质区别谢飞机Dubbo用Zookeeper注册中心...Spring Cloud用Eureka或Consul...李工性能上有差异吗谢飞机Dubbo更快...因为是长连接李工回答不错继续深化。 第三轮架构设计与运维8:30-8:45Q3支付系统涉及资金交易分布式事务怎么保证一致性谢飞机分布式事务...TCC模式Saga模式李工具体到支付场景你的方案是什么谢飞机用Seata...XA模式还是本地消息表李工哪种更适合金融场景谢飞机应该是本地消息表...最终一致性但是补偿逻辑怎么写...李工明白继续。你们的生产环境监控是怎么做的谢飞机Prometheus Grafana...ELK收集日志...李工业务指标怎么埋点比如支付成功率、订单转化率谢飞机Micrometer打点...自定义Metric李工链路追踪呢一个请求经过多少个服务谢飞机Jaeger...Zipkin...TraceId透传...李工好的最后一个。CI/CD流程你了解多少谢飞机GitLab CI...Jenkins Pipeline...Docker镜像构建...李工蓝绿部署怎么做回滚策略是什么谢飞机Kubernetes Deployment...滚动更新...但是金丝雀发布不太熟...李工嗯... 面试结束李工今天聊得差不多了你有什么想问的吗谢飞机那个...咱们公司加班多吗有房补吗李工哈哈这个问题很好。我们会综合评估你的技术能力HR会在3个工作日内联系你。谢飞机好的好的谢谢李工李工回去等通知吧。 详细答案与技术解析小白必看一、Spring Boot自动配置原理// 核心注解 SpringBootApplication SpringBootConfiguration ComponentScan EnableAutoConfiguration // 自动配置加载入口 EnableAutoConfiguration ↓ Import(AutoConfigurationImportSelector.class) ↓ spring.factories (Spring Boot 2.x) org.springframework.boot.autoconfigure.EnableAutoConfiguration\netal\ com.example.MyAutoConfiguration // Spring Boot 3.x新写法 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports关键点Conditional注解控制条件装配spring.factories文件定义所有可能的AutoConfiguration类通过SPI机制动态加载二、MySQL缓存穿透/雪崩/击穿解决方案| 问题类型 | 原因 | 解决方案 | |---------|------|----------| |缓存穿透| 查询不存在的数据 | 布隆过滤器 空值缓存 | |缓存雪崩| 大量Key同时过期 | 随机过期时间 多层缓存 | |缓存击穿| 热点Key突然失效 | 互斥锁 永不过期 |代码示例// 缓存穿透 - 布隆过滤器 public boolean exists(String key) { return bloomFilter.mightContain(key); } // 缓存击穿 - 互斥锁 public Object getData(String key) { Object value cache.get(key); if (value null) { synchronized (key.intern()) { value cache.get(key); if (value null) { value db.query(key); cache.set(key, value, 600L, TimeUnit.SECONDS); } } } return value; }三、分布式事务方案对比| 方案 | 适用场景 | 优点 | 缺点 | |-----|---------|------|------| |2PC/XA| 强一致性 | 数据一致性好 | 阻塞、性能差 | |TCC| 金融支付 | 性能好 | 开发复杂 | |Saga| 长事务 | 解耦 | 状态管理难 | |本地消息表| 最终一致性 | 可靠、易实现 | 延迟高 |支付场景推荐方案-- 本地消息表结构 CREATE TABLE payment_msg ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id VARCHAR(64), status TINYINT, -- 0:待发送 1:已发送 2:已消费 retry_count INT DEFAULT 0, create_time DATETIME );四、JWT OAuth2实战// JWT Token生成 public String generateToken(User user) { MapString, Object claims new HashMap(); claims.put(userId, user.getId()); claims.put(role, user.getRole()); return Jwts.builder() .setClaims(claims) .setSubject(user.getUsername()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() 7200000)) // 2小时 .signWith(SignatureAlgorithm.HS256, secretKey) .compact(); } // OAuth2资源服务器配置 Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers(/api/public/**).permitAll() .anyRequest().authenticated() .and() .oauth2ResourceServer() .jwt(); } }五、Kafka消息可靠性保障# 生产者配置 spring: kafka: producer: acks: all # 全部副本确认 retries: 3 # 失败重试次数 batch-size: 16384 linger-ms: 1 # 消费者配置 spring: kafka: consumer: auto-offset-reset: earliest enable-auto-commit: false # 手动提交 max-poll-records: 500关键参数说明acksall确保所有ISR副本写入成功enable.auto.commitfalse业务成功后再提交Offset幂等性防止重复消费导致资损六、Prometheus Grafana监控体系// Micrometer自定义指标 Component public class PaymentMetrics { private final Timer paymentSuccessTimer; private final Counter paymentFailedCounter; public PaymentMetrics(MeterRegistry registry) { this.paymentSuccessTimer Timer.builder(payment.success.duration) .description(支付成功耗时) .register(registry); this.paymentFailedCounter Counter.builder(payment.failed) .description(支付失败次数) .register(registry); } public void recordPayment(boolean success, long duration) { if (success) { paymentSuccessTimer.record(duration, MILLISECONDS); } else { paymentFailedCounter.increment(); } } }Grafana面板配置支付成功率趋势图99% SLAP99/P95响应时间监控异常告警阈值错误率1%七、Dubbo vs Spring Cloud RPC对比| 维度 | Dubbo | Spring Cloud | |-----|-------|--------------| |注册中心| Zookeeper/Etcd | Eureka/Consul/Nacos | |序列化| Hessian2/Dubbo Protocol | JSON/FST/Protobuf | |负载均衡| 支持多种算法 | Ribbon/LoadBalancer | |性能| 高二进制协议 | 中等HTTP/REST | |生态| 阿里系为主 | Spring全家桶 |选型建议内部高性能调用 → Dubbo对外开放API → Spring Cloud OpenFeign微服务治理 → Spring Cloud Alibaba 总结与建议谢飞机的问题总结✅ 基础概念知道但细节不够深入❌ 复杂场景缺少实战经验⚠️ 分布式系统设计能力不足⚠️ 生产环境运维经验欠缺给求职者的建议技术深度不要只停留在使用层面理解底层原理场景思维每个技术方案都要考虑业务场景实战经验多参与真实项目积累踩坑经验持续学习关注云原生、Service Mesh等新趋势面试不是终点而是成长的起点。祝各位Java开发者都能找到心仪的工作
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2566185.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!