常见面试题12

简介: 通过SkyWalking链路追踪或MySQL慢查询日志定位慢SQL,结合explain分析执行计划,优化索引与表设计,提升SQL性能。Spring中IOC实现对象托管,DI完成依赖注入,Bean默认单例非线程安全,作用域可配置,初始化时机分情况而定。

如何定位出项目中的慢SQL?

  • 必答内容:

这个问题,在项目开发中,是非常常见的。 在我们之前的项目中,用到了链路追踪组件 SkyWalking,通过SkyWalking我们就能够知道,所有请求的调用链路及执行耗时,在显示的报表中,我们就可以看出哪一个接口比较慢,也可以看到这个接口执行过程中,每一个部分的具体耗时,包括SQL的执行具体时间也都可以看到,通过这个就可以定位慢SQL了。

那如果在一些项目中,没有用到这类的监控工具,也可以开启MySQL的慢查询日志,通过MySQL的慢查询日志来定位慢SQL。比如:我们可以在配置文件中配置一下,只要SQL语句的执行耗时超过1秒,我就需要将其记录在慢查询日志中,最终我们只需要通过这份慢查询日志,就能够知道哪些SQL的执行效率比较低。

  • 可能继续问道的问题:

而具体执行耗时多长时间才算慢 ,时间一般设置为多长呢?

这个时间,其实没有一个定数,不同性质的项目之间也有差异,所以这个慢查询的界定时间,一般都要根据项目的情况来设置一个经验值,我们之前的项目中,设置的是1秒。

在项目中如何知道SQL语句的执行性能,以及索引是否生效?

  • 必答内容:

这个我们可以借助于MySQL中提供的 explain 关键字,在查询的SQL语句之前,加上explain来查询SQL语句的执行计划。

当然explain查看到的执行计划信息比较多,我们主要关注几个核心指标就可以了。比如:

  • 通过 key 、key_len 就能够知道是否命中索引。
  • 通过 type 指标,就能知道该SQL的性能怎么样,有没有进一步优化的可能。一定要规避all全表扫描的情况。 type指标性能由好到坏,依次是:NULL > system > const > eq_ref > ref > range > index > all
  • 还需要关注一个指标,就是extra额外的信息。 通过这一项,我们就能够知道,有没有回表查询,有没有涉及到file sort排序。

然后,我们就可以针对 explain 查看到的执行计划,针对于SQL进行优化了。

谈谈你在SQL优化方面的经验?

  • 必答内容:

嗯,这个话题就比较大了。 那我们在项目中,优化SQL的查询执行效率,会从多个维度来考虑的。

  • 第一个呢,就是表的设计。
  • 比如数据类型的选择,数值类型到底选择 tinyint、int还是bigint,要根据实际需要选择。字符串类型,到底选择char还是varchar,也需要根据具体业务确定。(char定长字符串,效率高;varchar变长字符串,效率略低)
  • 还需要考虑主键的设计,主键在设计时,尽量考虑递增顺序插入的主键,比如:自增主键 或 雪花算法生成的主键。(这样可以规避页分裂、页合并现象的产生)
  • 第二个呢,就是索引的创建。
  • 针对于数据量较大,且查询比较繁琐的表创建索引。(单表超过10w记录)
  • 针对于经常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
  • 尽量选择为区分度高的列建立索引,如果该字段是唯一的,建立唯一索引,效率更高。(区分度越高,效率越高)。
  • 在varchar类型的字段上,建议指定索引长度(建立前缀索引),没必要对全字段建立索引,根据实际文本区分度决定索引长度就可以。
  • 尽量建立联合索引,而且在联合索引中将区分度高的字段放在前面,减少单列索引。(查询时,联合索引很多时候可以索引覆盖,避免回表,提高效率)
  • 在满足业务需求的前提下,建立适当的索引,索引不宜过多。(索引过多,会增加维护索引的成本,影响增删改的效率)
  • 第三个呢,就是索引的使用。
  • 编写DQL时,在满足业务需要的情况下,要尽量避免索引失效的情况。 【索引失效的情况,见 3.2
  • 尽量使用索引覆盖,避免回表查询,提高性能。
  • 那这些情况呢,都可以通过 explain 关键字来查看SQL语句的执行计划。
  • 进阶回答:
  • 那如果从数据库层面来讲,也可以基于读写分离的模式,来降低单台服务库的访问压力,从而提高效率。
  • 当然,如果数据量过大,也可以考虑对目前项目中的数据库进行分库分表处理。

谈谈你对Spring IOC 与 DI的理解 ?

  • Spring的IOC,翻译过来,叫控制反转。 指的是在Spring中使用工厂模式,为我们创建了对象,并且将这些对象放在了一个容器中,我们在使用的时候,就不用每次都去new对象了,直接让容器为我们提供这些对象就可以了。 这就是控制反转的思想。
  • 而DI,翻译过来,叫依赖注入。 那刚才提到,现在对象已经交给容器管理了,那程序运行时,需要用到某个对象,此时就需要让容器给我们提供,这个过程呢,称之为依赖注入。

可能继续追问的问题:

  • 那如何将一个对象,讲给IOC容器管理呢?

那现在项目开发,都是基于Springboot构建的项目,所以呢,声明bean对象,我们只需要在对应的类上加上注解就可以了。 比如:

  • 如果是controller层,直接在类上加上 @Controller@RestController 注解。
  • 如果是service层,直接在类上加上 @Service 注解。
  • 如果是dao层,直接在类上加上 @Repository 注解。当然现在基本都是Mybatis 或 MybatisPlus,所以这个注解很少用了,都用的是 @Mapper 注解。
  • 如果是一些其他的工具类、配置类啊,我们可以通过 @Component@Configuration 来声明。
  • 那如何完成依赖注入操作呢 ?  依赖注入的方式比较多,我们可以使用构造函数注入 或 成员变量输入,也是使用对应的注解就可以了。常用的注解有两个:
  • @Autowired@Resource 注解。 那 @Autowired 默认是根据类型注入,而 @Resource 注解默认是根据名称注入。

Spring容器中的bean是线程安全的吗?

不是线程安全的。

针对于这个问题呢,首先我们知道spring容器的bean默认是单例的。 当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这时多个线程会并发执行该请求对应的业务逻辑,也就是bean对象的业务方法,那如果在业务方法中操作了共享的成员变量,那可能就会存在线程安全问题。

而在Spring框架中并没有对单例bean进行任何多线程的封装处理,关于单例bean的线程安全和并发问题需要我们自行去搞定。但实际上,大部分情况下Spring 的bean并没有可变的状态(比如Controller、Service、Dao),所以在某种程度上说Spring的单例bean是线程安全的。

如果说存在这种情况,那就需要开发人员自行保证线程安全。要么,通过编码保证线程安全,要么,设置bean的作用域为 prototype。

Spring Bean的作用域如何设置,常见的取值有哪些 ?

Spring Bean的作用域可以通过 @Scope 注解来设置。常见的取值如下:

  • singleton :这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中同一个名称的bean只有一个实例,也就是单例的 。
  • prototype :这种范围,表示非单例的。也就是说每一次用到的bean都是一个新的 。
  • request :同一个请求,使用的是同一个bean。会为每一个来自客户端的请求都创建一个实例,在请求完成以后, bean会失效并被垃圾回收器回收 。
  • session:与request 请求范围类似,确保每个session会话范围内,是同一个实例,在session过期后, bean会随之失效 。

虽然,bean作用域可以设置这些值,但是在项目开发中,绝大部分的bean都不会添加这个 @Scope 注解,也就是说默认都是用的是单例的bean。

Spring容器的bean什么时候初始化的?

这个得分情况来看哈。

  • 如果是单例的bean,默认是Spring容器启动的时候,就完成bean的初始化操作,那这是默认情况,我们可以通过 @Lazy 注解来延迟bean的初始化,延迟到第一次使用的时候。
  • 而如果是非单例的bean(也就是prototype),则是在每次使用这个bean的时候,都会重新实例化一个新的bean。



目录
相关文章
|
3月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
534 12
|
3月前
|
人工智能 运维 Java
Flink Agents:基于Apache Flink的事件驱动AI智能体框架
本文基于Apache Flink PMC成员宋辛童在Community Over Code Asia 2025的演讲,深入解析Flink Agents项目的技术背景、架构设计与应用场景。该项目聚焦事件驱动型AI智能体,结合Flink的实时处理能力,推动AI在工业场景中的工程化落地,涵盖智能运维、直播分析等典型应用,展现其在AI发展第四层次——智能体AI中的重要意义。
1254 27
Flink Agents:基于Apache Flink的事件驱动AI智能体框架
|
2月前
|
数据库 微服务
常见面试题19
BASE理论提出“基本可用、软状态、最终一致性”,是分布式系统中对CAP定理的实践妥协。相比强一致的刚性事务(ACID),它属于柔性事务,强调高可用与最终一致,适用于Seata等分布式事务方案中的AT、TCC、SAGA模式,而非传统2PC的强一致性。
68 7
|
2月前
|
负载均衡 安全 应用服务中间件
常见面试题18
正向代理代表客户端发起请求,隐藏客户端身份,用于访问控制与隐私保护;反向代理代表服务器接收请求,实现负载均衡与安全防护;CDN通过全球节点加速内容分发;Nginx可作反向代理实现轮询、权重等负载均衡策略;CAP定理指出分布式系统无法同时满足一致性、可用性与分区容错性。
96 4
|
2月前
|
XML SQL Java
常见面试题15
Spring Boot配置优先级:命令行参数 > 系统属性 > application.properties > .yml > .yaml;自动配置基于@Import与条件注解,SpringBoot3使用xxx.imports替代spring.factories。自定义starter需分离starter与autoconfigure模块。MyBatis支持XML或注解映射结果集,参数传递可用@Param或直接传对象/Map。
133 4
|
2月前
|
缓存 负载均衡 Java
常见面试题16
MyBatis提供一级缓存(SqlSession级)和二级缓存(Mapper级),提升查询效率。Eureka通过注册、续约、发现、下线实现服务治理,Nacos在功能与性能上更优,支持配置管理与实时推送。Spring Cloud LoadBalancer取代Ribbon,提供轮询、随机等负载策略。Hystrix与Sentinel均支持熔断限流,但Sentinel在流量控制和实时性上更强。
72 2
|
3月前
|
缓存 Java 数据库
常见面试题13
本文详解Spring核心机制:Bean生命周期(实例化、依赖注入、初始化、销毁)、三级缓存无法解决构造函数循环依赖(需@Lazy解决)、AOP原理(动态代理实现日志、权限控制)及事务管理(@Transactional与传播行为),并梳理常用注解分类。
202 5
|
3月前
|
JSON 前端开发 Java
常见面试题14
Spring MVC核心组件包括DispatcherServlet、HandlerMapping、HandlerAdapter、Handler及ViewResolver。拦截器用于登录校验等,与过滤器在范围和机制上有所不同。常用注解如@RequestMapping、@RequestBody等简化开发。SpringBoot则通过起步依赖、自动配置和内嵌服务器,大幅简化Spring应用的搭建与部署。
69 2
|
3月前
|
存储 网络协议 关系型数据库
常见面试题10
HTTP是超文本传输协议,基于TCP,规定客户端与服务器通信规则。常见请求方式有GET和POST,区别在于参数传递、安全性和用途。HTTPS通过SSL加密更安全,但耗资源。常用状态码如200成功、404未找到、500服务器错误。转发在服务端完成,重定向由浏览器发起两次请求。MySQL中char定长、varchar变长;事务具ACID特性,隔离级别解决并发问题。
103 3
|
3月前
|
SQL 监控 JavaScript
天啊,Gitee 16k star项目,不要再傻傻重复造轮子啦,高效搭建企业级后台系统框架,你不应该试一下吗?
Guns 是基于 Spring Boot3 + Vue3 的企业级后台框架,获 Gitee 16.2k Star。支持权限、多机构、代码生成、插件化扩展,助力高效搭建 OA、CRM、ERP 等系统,提升开发效率,降低重复造轮子成本。
140 5