异工同智-Java开发 二面 面经

1、详细介绍一下你最有成就感的项目

我最有成就感的项目是一个智能数据分析平台,这个平台主要为企业提供数据采集、清洗、分析和可视化的一站式解决方案。

项目背景是客户有大量的业务数据分散在不同系统中,包括ERP、CRM、财务系统等,他们希望能统一管理这些数据,并通过数据分析辅助决策。我们团队负责从零开始搭建这个平台,我在其中担任核心开发的角色。

技术架构方面,我们采用了微服务架构。后端用Spring Cloud Alibaba全家桶,包括Nacos做服务注册和配置中心,Gateway做网关,Sentinel做限流熔断,Seata做分布式事务。数据存储用MySQL做业务数据存储,MongoDB存储非结构化数据,Redis做缓存,ElasticSearch做全文检索和日志分析。消息队列用RocketMQ做异步处理和系统解耦。前端用Vue3+Element Plus。

我主要负责数据采集模块和数据分析模块的设计开发。数据采集模块支持多种数据源接入,包括数据库、API接口、文件上传等方式。我设计了一套插件化的架构,每种数据源对应一个采集器插件,通过配置就能灵活扩展新的数据源。采集到的数据先进行清洗和转换,然后存储到数据仓库。

数据分析模块是最有挑战的部分。用户可以通过拖拽的方式配置分析维度和指标,系统动态生成SQL查询。我用了模板引擎和SQL构建器来实现,支持多表关联、分组聚合、条件过滤等复杂查询。为了提升性能,我做了几个优化:1)查询结果缓存到Redis,相同查询直接返回缓存;2)大数据量查询用分页和流式处理,避免内存溢出;3)热点数据预计算,定时任务提前算好结果存起来。

项目中遇到的最大挑战是性能问题。初期版本在处理百万级数据时查询很慢,经常超时。我通过几个方面优化:1)数据库层面,给常用查询字段建索引,优化慢SQL,对大表做分区;2)应用层面,引入多级缓存,用本地缓存+Redis缓存;3)架构层面,把实时查询和离线分析分开,离线分析用定时任务预计算。经过优化,查询响应时间从10秒降到了1秒以内。

这个项目让我对系统架构设计有了更深的理解,特别是在处理大数据量、高并发场景时如何做性能优化。项目上线后得到了客户的高度认可,也为公司带来了更多的业务机会,这让我很有成就感。

2、Spring Cloud的核心组件你用过哪些,解决什么问题

我在项目中深度使用了Spring Cloud Alibaba技术栈,对各个组件比较熟悉:

  1. Nacos服务注册与发现,这是微服务架构的基础。每个服务启动时会向Nacos注册自己的信息,包括IP、端口、健康状态等。服务调用时从Nacos获取目标服务的实例列表,然后通过负载均衡选择一个实例调用。Nacos还支持服务分组和命名空间,可以实现环境隔离。我们用命名空间区分开发、测试、生产环境,避免互相干扰。
  2. Nacos配置中心,统一管理所有服务的配置。配置修改后可以动态推送到各个服务,不需要重启。我们把数据库连接、Redis地址、业务参数等都放在Nacos配置中心。还支持配置的版本管理和回滚,配置错了可以快速恢复。配置可以按环境、按服务分组管理,很灵活。
  3. Gateway网关,作为系统的统一入口。我们在Gateway层做了几件事:1)路由转发,根据请求路径转发到对应的服务;2)认证鉴权,验证JWT Token,判断用户权限;3)限流熔断,用Sentinel做流量控制;4)日志记录,记录每个请求的信息用于监控和排查问题;5)跨域处理,配置CORS策略;6)参数校验,拦截非法请求。
  4. OpenFeign声明式HTTP客户端,简化了服务间调用。只需要定义一个接口,加上@FeignClient注解,就可以像调用本地方法一样调用远程服务。Feign集成了Ribbon做负载均衡,集成了Hystrix做熔断降级。我们还配置了请求重试、超时时间、日志级别等参数。
  5. Sentinel流量控制,这是阿里开源的流量治理组件。我们用它做了几个方面的控制:1)QPS限流,限制接口每秒请求数;2)线程数限流,限制并发线程数;3)熔断降级,接口异常率或响应时间超过阈值时自动熔断;4)热点参数限流,针对特定参数值限流;5)系统自适应限流,根据系统负载自动调整限流阈值。Sentinel有可视化的控制台,可以实时查看流量情况和调整规则。
  6. Seata分布式事务,解决跨服务的事务一致性问题。我们用的是AT模式,对业务代码无侵入,只需要加@GlobalTransactional注解。Seata会自动生成回滚SQL,事务失败时自动回滚。我们在订单创建、库存扣减、积分增加这种跨服务场景用Seata保证数据一致性。
  7. Sleuth链路追踪,给每个请求生成唯一的traceId,可以追踪请求在各个服务间的调用链路。配合Zipkin可以可视化展示调用链,快速定位性能瓶颈和异常点。我们在排查线上问题时经常用链路追踪,很方便。

这些组件组合起来,解决了微服务架构中的服务治理、配置管理、流量控制、分布式事务、链路追踪等核心问题,让我们可以专注于业务开发。

3、如何保证系统的高可用性

系统高可用是我们架构设计的重点,主要从这几个方面保证:

  1. 服务冗余和负载均衡,每个服务至少部署3个实例,分布在不同的服务器上。前面用Nginx做负载均衡,配置健康检查,实例异常自动摘除。服务内部用Ribbon或LoadBalancer做客户端负载均衡,支持轮询、随机、权重等策略。这样单个实例挂掉不影响整体服务。
  2. 数据库高可用,MySQL配置主从复制,一主两从架构。主库负责写操作,从库负责读操作,实现读写分离。主库宕机后,通过MHA或Orchestrator自动切换到从库。我们还配置了双主模式作为备份方案。数据库连接池用Druid,配置了连接检测和自动重连。
  3. 缓存高可用,Redis用哨兵模式,一主两从三哨兵。主节点宕机后哨兵自动选举新的主节点,实现故障自动转移。我们还在应用层做了降级处理,Redis不可用时降级到数据库查询,虽然慢一点但保证服务可用。
  4. 消息队列高可用,RocketMQ配置主从同步,消息写入主节点后同步到从节点才返回成功。NameServer部署多个节点,Broker注册到所有NameServer。这样单个节点故障不影响消息收发。
  5. 限流熔断降级,用Sentinel做流量控制。配置了QPS限流、慢调用熔断、异常比例熔断等规则。接口异常时快速失败,返回降级数据或友好提示,避免雪崩效应。非核心功能可以降级,比如推荐服务挂了就返回默认推荐。
  6. 超时和重试机制,所有的远程调用都配置了超时时间,避免无限等待。对于幂等的接口配置了重试机制,失败后自动重试3次。用指数退避算法,重试间隔逐渐增加,避免雪崩。
  7. 异地多活,核心服务部署在两个机房,通过专线同步数据。一个机房故障时流量自动切换到另一个机房。我们用DNS做流量调度,配置了健康检查和自动切换。
  8. 监控告警,用Prometheus采集系统指标,Grafana做可视化展示。配置了多维度的告警规则,包括服务可用性、接口响应时间、错误率、系统资源等。告警通过钉钉和短信通知,确保第一时间发现问题。
  9. 容灾演练,定期做故障演练,比如模拟数据库宕机、服务宕机、机房断网等场景。验证系统的容错能力和应急预案。每次演练后总结问题,持续改进。
  10. 灰度发布,新版本先发布到一小部分实例,观察没问题再全量发布。用Gateway做流量控制,可以按比例或按用户分流。发现问题可以快速回滚。

通过这些措施,我们系统的可用性达到了99.95%以上,基本满足了业务需求。

4、JVM内存溢出如何排查和解决

JVM内存溢出是生产环境常见的问题,我有一些排查和解决的经验:

  1. 问题现象,通常表现为应用突然无响应,日志中出现OutOfMemoryError异常。可能是堆内存溢出、栈溢出、元空间溢出等不同类型。首先要看异常信息确定是哪种类型的OOM。
  2. 堆内存溢出排查,这是最常见的情况。首先配置JVM参数-XX:+HeapDumpOnOutOfMemoryError和-XX:HeapDumpPath,OOM时自动dump堆内存。然后用MAT或JProfiler分析dump文件,看哪些对象占用内存最多。常见原因有:1)内存泄漏,对象无法被GC回收,比如集合类持续增长没有清理、ThreadLocal没有remove、静态集合持有大量对象;2)内存溢出,对象太多超过堆容量,比如一次性加载大量数据、

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java面试圣经 文章被收录于专栏

Java面试圣经,带你练透java圣经

全部评论
求采集器设计
点赞 回复 分享
发布于 03-17 11:17 北京
你这总结的真好
点赞 回复 分享
发布于 03-15 21:12 北京

相关推荐

03-12 09:11
门头沟学院 Java
先给结论:实习没人带、放养式管理,再正常不过;但学不到东西,也许是你自己的问题。很多实习生陷入一个误区:觉得学习就得有人手把手教,mentor 不安排活、同事不带着做项目,就等于学不到东西,然后躺平摆烂、疯狂内耗,最后实习结束骂一句 “垃圾公司,啥也学不到”。但你要先认清一个现实:职场不是校园,公司招实习生,不是请了个学生来免费上课,是找个人来解决问题、创造价值的。你的 mentor 和同事,没有义务当你的全职老师,拿自己的工作时间,手把手教你从 0 到 1 学东西。所谓的 “放养”,从来不是放弃,是职场里最基础的考验。没人给你安排活,你就不会主动找活吗?看组里的过往项目文档、代码仓库,找 mentor 要一些边缘的、简单的活,哪怕是改 bug、写测试用例,也比天天坐着打杂强;没人解答你的问题,你就不会正确提问吗?别张口就问 “这个怎么做”,先自己查文档、搜解决方案,带着 2 个自己想的方案去问,别人只需要帮你判断对错,自然愿意教你;天天干打杂的活,就真的只能打杂吗?让你整理数据表格,你能不能顺便分析数据规律,做一个可视化看板?让你核对文档,你能不能顺便梳理清楚项目的业务逻辑?哪怕是贴发票,你都能搞懂公司的财务报销流程。实习是锻炼还是放弃,从来不是公司和 mentor 决定的,是你自己决定的。等着别人喂到嘴里的人,就算进了核心项目,也照样学不到东西;主动找机会、主动学习的人,就算是放养式实习,也能攒够秋招的硬通货。
实习学不到东西正常吗?
点赞 评论 收藏
分享
评论
1
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务