当前位置: 首页 > news >正文

面试题之高频面试题

最近开始面试了,410面试了一家公司 针对自己薄弱的面试题库,深入了解下,也应付下面试。在这里先祝愿大家在现有公司好好沉淀,定位好自己的目标,在自己的领域上发光发热,在自己想要的领域上(技术管理、项目管理、业务管理等)越走越远!希望各位面试都能稳过,待遇都是杠杠的!因为内心还是很慌,所以先整理所有高频的面试题出来,包含一些业务场景及java相关的所有面试。

Spring相关面试题


1.Spring AOP底层实现原理是什么?
  • Spring AOP(面向切面编程)的底层实现基于动态代理技术,主要通过两种实现方式:JDK动态代理和CGLIB字节码生成。当目标类实现了接口,Spring默认使用了JDK动态代理,否则使用CGLIB方式,而spring-boot选择了VCGLIB方式来实现。
    • JDK动态代理(基于接口)
      • 适用条件:目标类实现了至少一个接口
      • 代理对象通过JDK直接生成,实现目标类的接口,并通过反射调用目标类
      • 特点:
        • 运行时生成接口的代理类
        • 通过InvocationHandler拦截方法调用
        • 性能较好,但只能代理接口方法
    • CGLIB字节码生成(基于子类)
      • 适用条件:不能使用final
      • 适用对象:目标类没有实现接口
      • CGLIB通过CFLIB-ASM操作框架生成,继承目标类,通过子类调用父类的方式进行调用目标方法
      • 特点:
        • 通过ASM库直接生成目标类的子类(Enhancer)
        • 可以代理普通类方法(包括非public方法)
        • 创建代理对象速度较慢,但执行效率高
    • 代理创建流程
      • Spring AOP创建代理的核心流程:
        • 解析切面配置
        • 通过@Aspect注解或者XML配置识别切面
        • 解析切入点表达式(Pointcut)
        • 创建代理工厂(proxyFactory)
        • 选择代理机制
        • 生成代理对象
      • JDK代理:proxy.newProxyInstance()
      • CGLIB:enhance.create()
    • 拦截器链执行
      • Spring AOP通过责任链模式执行增强逻辑
      • 增强类型与顺序执行
    • spring aop支持了五种通知类型
      • @Aroud环绕通知
      • @before前置通知
      • 目标方法执行
      • @AfterReturing(返回通知,正常返回时执行)
      • @After(后置通知,finally块中执行)
      • @AfterThrowing(异常通知,抛出异常时执行)
    • 性能优化与实现
      • Spring对AOP进行了多项优化
        • 缓冲机制
          • 代理类缓冲DefaultAopProxyFactory
          • 拦截器链缓冲AdvisedSupport
        • 预过滤
          • 预先排除不可能匹配的方法
          • 选择性代理
          • 支队匹配切入点的方法生成代理逻辑
          • 其他方法直接调用目标方法
  • 与AspectJ的关系
特性Spring AOPAspectJ
实现方式运行时动态代理编译时/加载时织入
性能较好最优(编译期完成)
功能范围仅方法级别字段、构造器、静态块等
依赖仅Spring核心需要AspectJ编译器/织入器
适用场景简单切面需求复杂切面需求
  • 总结:
    • Spring AOP的底层实现本质上是基于代理模式的运行时增强,其核心特点是
      • 非侵入性:通过代理实现,不修改原始代码
      • 灵活性:支持多种通知类型和切入点表达式
      • 可扩展性:可与AspectJ部分功能集成
      • 性能平衡:通过缓存和优化策略保证运行时效率

组合面试题


1.如何有效的阻止订单重复提交和支付

理论上只会在用户在下单的这个动作可能因为网络抖动、RPC重试等进行多次下单的操作,其他步骤确认订单只是修改订单状态,跳转支付和确认支付这些不会出现多次支付的问题。所以该题主要是针对用户多次调用下单接口怎么处理即下单接口的幂等性问题。

  • 订单重复提交问题
    • 前端防重复提交方案
      • 按钮置灰等操作
      • PRG模式:post/redirect/get模式,用户点击表单时重定向跳转到其他页面。
      • token机制,在用户进入订单界面前生成固定的token,前端限制一个token调用时,后端拦截token的一次性,做请求拦截限制
      • 请求拦截:通过axios拦截器拦截信息
    • 后端接口设计
      • 幂等性设计
        • 每次请求先配合客户端生成一个唯一id,可由订单id+用户id+确认标识做绑定,同一接口,每次调用的id一致则不生成新的订单,注意标识符的失效时间
        • 请求参数中带有时间戳与当前时间对比,若时间太长则默认为重复请求
        • 请求状态检查,根据日志查询、用户订单关联查询是否有重复数据
      • 数据库唯一约束
        • 先获取数据库唯一ID来处理
      • redis原子操作
        • setnx操作,对同一个订单id+用户id+确认标识做绑定,设置失效时间,进行处理
  • 支付方重复方案
    • 订单状态机制
    • 第三方支付幂等
    • 支付结果异步核对
  • 分布式系统解决方案
    • 分布式锁
    • 消息队列去重
  • 异常处理机制
    • 补偿事务处理
    • 人工审核接口
  • 监控与报警
    • 重复请求监控 设置ip白名单防止恶意操作
  • 建议:
    • 多层次防御:前端+后端+数据库约束等
    • 核心原则:所有写操作必须实现幂等性接口
    • 关键数据:订单号、用户ID、时间戳组合防重复
    • 状态管理:严格的状态机控制流程
    • 补偿机制:自动核对+人工干预双重保险
  • 技术选择
场景推荐方案优点
简单单体系统本地锁+数据库唯一约束实现简单
分布式高并发Redis分布式锁+消息队列扩展性好
金融级支付系统状态机+定时核对+人工干预可靠性最高
旧系统改造前端Token+后端幂等接口侵入性最小

2.RestTemplate 如何优化连接池
  • restTemplate默认是没有连接池,他的调用原理是每次都会创建一个HTTP连接,默认使用simpleClientHttpRequestFactory去创建连接,底层通过HttpURLConnection创建连接。在高并发的条件下,会无上限的创建连接,消耗系统资源。所以需要通过连接池来限制最大连接数,当请求的域不是很多且不随机的情况下,还可以复用同一个域的HTTP连接;
  • HTTP请求流程:在我们发起一个http请求连接的时候,会对域名解析,连接之前的三次握手,如果是HTTPS还需要传递安全证书,以及请求完成之后的4次挥手。但是我们真正请求和响应只在其中的一小环节,所以我们通过一个连接池就可以对同一个域来建立一个长链接,就无需执行每次的无关业务请求的动作,这样就实现了连接的复用。
  • 通过resttemplate来配置连接池的话有HttpClient和OkHttp.
  • 具体实现:
    • 代码上引入httpclient连接池的包,修改RestTemplate请求工厂,将默认工厂的simpleClientHttpRequestFactory换成HttpClientFactory,在为这个工厂配置请求bean。最后去设置连接池参数信息。设置最大连接数,根据QPS的响应时间平均值来设置,设置某个域的长链接复用,但是如果该值太小,比如设置2,那么只会创建两个长链接,这样后续的接口会进行阻塞等待。
    • 在实现连接池的方法时,需要注意以下几点:
      • 路由区分:对重要API设置独立的路由连接数
      • 异常处理:配置重试机制
      • DNS刷新:避免DNS缓冲问题
      • 连接存活时间
参数建议值说明
setMaxTotal100-500最大连接数,根据服务器配置调整
setDefaultMaxPerRoute50-100每个路由(host:port)的最大连接数
setConnectTimeout3000-5000ms建立TCP连接的超时时间
setSocketTimeout5000-10000ms数据传输超时时间
setConnectionRequestTimeout1000-2000ms从连接池获取连接的超时时间
evictIdleConnections30-60s空闲连接回收时间

相关文章:

  • 扩展欧几里得算法【Exgcd】的内容与题目应用
  • MySQL-数据查询(CASE练习)-01
  • Vue 组件化开发
  • netty知识点
  • 51、Spring Boot 详细讲义(八) Spring Boot 与 NoSQL
  • C++栈与堆内存详解:Visual Studio实战指南
  • MyBatisPlus-QueryWrapper的exists方法拼接SQL中的EXISTS子句
  • Nginx | Apache 配置 WebSocket 多层代理基本知识(附疑难杂症)
  • 基于LightRAG进行本地RAG部署(包括单卡多卡本地模型部署、调用阿里云或DeepSeekAPI的部署方法、RAG使用方法)
  • 分布式存储数据恢复—hbase和hive数据库文件被删除如何恢复数据?
  • Layout 路由
  • Trea初体验:使用Trea从零到一创建一个项目,用来演示glog库的使用,一行代码没改完成了整个项目的搭建运行
  • 2843. 统计对称整数的数目
  • 【Pandas】pandas DataFrame xs
  • 全自动驾驶(FSD,Full Self-Driving)自动驾驶热点技术的成熟之处就是能判断道路修复修路,能自动利用类似“人眼”的摄像头进行驾驶!值得学习!
  • MYSQL “Too Many Connections“ 错误解决
  • 自动驾驶地图数据传输协议ADASIS v2
  • LCOV 使用文档
  • 制表符是什么?与.txt文件的关系?
  • 【JavaWeb】详细讲解 HTTP 协议
  • 上市公司重大资产重组新规九要点:引入私募“反向挂钩”,压缩审核流程
  • 美官方将使用华为芯片视作违反美出口管制行为,外交部回应
  • 丰富“互换通”产品类型,促进中国金融市场高水平对外开放
  • 联合国秘书长欢迎中美经贸高层会谈成果
  • 广东韶关一镇干部冲进交通事故火海救人,获授“见义勇为”奖励万元
  • 人民日报钟声:通过平等对话协商解决分歧的重要一步