Java面试相关问题

news2024/11/16 20:26:16

 一.MySql篇

1优化相关问题

1.1.MySql中如何定位慢查询?


 慢查询的概念:在MySQL中,慢查询是指执行时间超过一定阈值的SQL语句。这个阈值是由long_query_time参数设定的,它的默认值是10秒1。也就是说,如果一条SQL语句的执行时间超过了long_query_time所设定的时间,那么这条SQL语句就被认为是慢查询。

现在的问题就是:出现页面加载过慢,响应时间过长。我怎么确定就是我sql的问题呢?就算是sql的问题,我应该怎么找出执行慢的那条sql语句呢?

方案一:使用开发工具

以Skywalking为例。这个工具,可以直观看到每个接口的执行时间。还可以追踪进接口,详细的看耗时情况,其中也包含了sql的耗时。

方案二:使用MySql自带的慢日志

简单来说,这个日志记录了执行时间较长的sql。

总结:

二.框架篇

       1.Spring框架

1.1.Spring框架中的bean默认情况下是单例的吗?


 Spring框架中的bean默认情况下是单例的。Spring中有一个注解@Scope,这是用来设置bean的情况。默认情况下设置为singleton(单例的)

1.2.Spring框架中的单例bean是线程安全的吗?


 

简单来说就是:判断当前成员变量能不能修改。如果是int这种可修改的类型,线程就不是安全的。

如果是,Service、DAO这些无状态类 (没有什么可变状态)就算是线程安全的。

总结:

        不是线程安全的,是这样的。
        当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这是多
个线程会并发执行该请求对应的业务逻辑(成员方法),如果该处理逻辑中
有对该单列状态的修改(体现为该单例的成员属性),则必须考虑线程同步
问题。
        Spring框架并没有对单例bean 进行任何多线程的封装处理。关于单例 bean的
线程安全和并发问题需要开发者自行去搞定。
        比如:我们通常在项目中使用的Spring bean都是不可可变的状态 (比如
Service类和 DAO ) ,所以在某种程度上说 Spring 的单例 bean是线程安全的。
如果你的bean 有多种状态的话(比如 View Model对象),就需要自行保证线
程安全。最浅显的解决办法就是将多态bean 的作用由 singleton ”变更为
“prototype ”。

1.3.什么是AOP?项目中有没有使用AOP?


AOP的概念及常见使用场景:
总结:
        
        aop是面向切面编程,在 spring 中用于将那些与业务无关,但却对多个对象产
生影响的公共行为和逻辑,抽取公共模块复用,降低耦合,一般比如可以做
为公共日志保存,事务处理等。
        实际项目中使用AOP的例子:
在后台管理系统中,就是使用 aop 来记录了系统的操作日志 主要思路是这样的,使用 aop 中的环绕通知 + 切点表达式,这个表达式就是要找到要记录日志的方法,然后通过环绕通知的参数获取请求方法的参数,比如类信息、方法信息、注解、请求方式等,获取到这些参数以后,保存到数据库。

1.4.Spring中事务是如何实现的?

这里的"保存用户"方法,就是我们要加事务的方法。在该方法上添加@Transactional注解。

总结:

        声明式事务管理实际上是基于Spring的AOP(面向切面编程)机制实现的。当你在方法上使用@Transactional注解时,Spring会在运行时创建一个代理对象,这个代理对象会在方法调用前后插入事务管理的代码,从而实现事务的自动管理。

        具体来说,当Spring容器在运行时遇到带有@Transactional注解的方法时,它会创建一个代理对象来拦截这个方法。在代理对象拦截方法调用时,Spring会在方法调用前后分别插入开始事务和结束事务的代码。如果方法执行过程中抛出异常,Spring会根据异常类型决定是否回滚事务。

        因此,虽然在使用声明式事务管理时,开发者不需要自己编写AOP代码,但是Spring仍然使用了AOP技术来实现事务管理。这也是为什么有时候我们会说声明式事务管理是基于AOP的。

1.5.Spring中业务失效的场景


 

这种情况下,自己把异常处理了,导致@Transactional没有发现异常,事务没有回滚。

Spring默认只会回滚非检查异常也就是runtime异常。而这里的FileNotFound是一个检查异常,并不能被捕获。

Spring为方法创建代理,添加事务通知,前提条件都是该方法是public修饰的!

1.6.Bean的生命周期


1.BeanDefinition

2.构造函数

在此期间,调用Bean的构造函数,实例化对象 (但是还未赋值!)

3.依赖注入

Spring容器会将Bean的属性设置为Bean定义中指定的值。这个过程也被称为依赖注入,因为Spring容器会自动寻找并注入Bean所依赖的其他Bean。

4.Aware接口

用于增强Bean的功能

如果Bean实现了以Aware结尾的接口,就要重写里面的方法。图中三个接口,就是分别用于在Bean的初始化过程中,用于获取:Bean的名字、Bean的工厂、容器的上下文对象(Spring容器本身)。

5.BeanPostProcessor#before

bean的后置处理器,在初始化方法调用之前执行。

6.初始化方法

        1.InitalizingBean接口,实现了该接口,就要实现里面的方法。而在这一步就会执行重写方法。

        2.自定义init:在bean中某个方法上标注了@PostConstruct注解。就会在这一步执行这个方法。

7.BeanPostProcessor#before

bean的后置处理器,在初始化方法调用之后执行。

当一个类的功能被增强了使用到了AOP,大概率就是使用后置处理器被增强的。

  

8.销毁Bean

如果在哪个方法上标注了@PreDestroy方法,Spring容器在关闭前就会调用该方法。

注:

1.Bean的创建和初始化是分开的,第2步是创建bean,3-7是初始化赋值

2.第5步和第7步的两个后置处理器。都是某个类实现了BeanPostProcessor接口,所重写的两个方法。分别在初始化方法前后执行。

测试代码:

第一个类User类,作为我们测试的Bean

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class User implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {

    public User() {
        System.out.println("1.User的构造方法执行了.........");
    }

    private String name;

    @Value("张三")
    public void setName(String name) {
        System.out.println("2.依赖注入执行了..........");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("3.BeanNameAware的实现方法执行了.......");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("3.BeanNameAware的实现方法执行了.......");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("3.ApplicationContextAware的实现方法执行了.......");
    }

    @PostConstruct
    public void init() {
        System.out.println("5.自定义初始化方法执行了..........");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("5.InitializingBean的实现方法执行了..........");
    }

    @PreDestroy
    public void destroy(){
        System.out.println("7.destroy方法执行了.........");
    }
}

第二个类:实现了BeanPostProcessor重写了其中方法的类。里面是两个后置处理器。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("user")) {
            System.out.println("4.postProcessBeforeInitialization方法执行了 -> user对象初始化方法之前执行");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("user")) {
            System.out.println("6.postProcessAfterInitialization方法执行了 -> user对象初始化方法之后执行");
        }
        return bean;
    }
}

执行结果

destroy方法要在容器关闭时执行

总结:

        1.首先会通过一个非常重要的类,叫做BeanDefinition获取bean的定义信息, 这里面就封装了bean的所有信息,比如,类的全路径,是否是延迟加载,是否是单例等等这些信息。        

        2.在创建bean的时候,第一步是调用构造函数实例化bean

        3.第二步是bean的依赖注入,比如一些set方法注入,像平时开发用的@Autowire都是这一步完成。

        4.第三步是处理Aware接口,如果某一个bean实现了Aware接口就会重写方法执行。

        5.第四步是bean的后置处理器BeanPostProcessor,这个是前置处理器。

        6.第五步是初始化方法,比如实现了接口InitializingBean或者自定义了方init-method标签或@PostContruct。

        7.第六步是执行了bean的后置处理器BeanPostProcessor,主要是对bean进行增强,有可能在这里产生代理对象。

        8.最后一步是销毁bean。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1526196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Leetcode-19.删除链表的第N个节点】

题目详情: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5]示例 2: 输入:head [1], n 1 输出&#xff1…

什么是Vector Database?

此为看完视频What is a Vector Database?后的笔记。 作者首先对数据库做了分类,其中RTweb表示real time web app。 然后对用例做了分类,最后一个就是适合于AI的近似搜索。 好处,包括灵活性,可扩展性和性价比。 本视频最重要的…

【bioinformation 10】ADMET-CYPs抑制剂预测实战

🌞欢迎来到AI医学的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 📆首发时间:🌹2024年3月17日&am…

/usr/local/bin/docker-compose: line 1: Not: command not found

安装docker-compose 检查是否安装成功 docker-compose --version 出错 /usr/local/bin/docker-compose: line 1: Not: command not found 检查下载连接是否正确 官网 https://dockerdocs.cn/compose/install/ 根据官网上连接下载 发现下载不了 在版本前加个V 就可以解决 版…

4.1_4 文件的物理结构

文章目录 4.1_4 文件的物理结构(一)文件块、磁盘块(二)文件分配方式——连续分配(三)文件分配方式——链接分配(1)链接分配——隐式链接(2)链接分配——显式链…

JETSON 配置并跑通 NanoDet

JETSON 配置 NanoDet 文章目录 JETSON 配置 NanoDetNanoDet 介绍源码环境搭建及测试配置 NanoDet 的环境环境配置过程中遇到的问题:环境配置完毕验证 NanoDet NanoDet 介绍 可以参考这个博客:NanoDet:这是个小于4M超轻量目标检测模型 源码 …

什么是网站?为什么要搭建网站?

网站:简单来说,网站就是通过互联网来展示信息的页面集合。它可以在电脑或者手机上打开,提供各种功能,比如查看新闻、购买商品、搜索信息等。 一、建网站的目的:展示个人或企业的存在 网站建设的首要目的之一是展示个人…

23-分支和循环语句_习题练习

1、转换以下ASClI码为对应字符并输出他们:73,32,99, 97,110,32,100,111,32,105,116,33 输入:无 输出:一行输出转换题目中给出的所有ASClI码对应的字符,无需以空格隔开。 输入: int main() {int i 0;int arr[] { …

加拿大光量子计算公司Xanadu入局英国多企业量子合作计划

内容来源:量子前哨(ID:Qforepost) 编辑丨慕一 编译/排版丨沛贤 深度好文:1200字丨8分钟阅读 英国航空发动机制造商罗尔斯罗伊斯(Rolls-Royce)、英国量子计算公司Riverlane和加拿大量子计算公…

【Nutx3】middleware目录介绍

简言 记录下nuxt3middleware目录的使用方法。 middleware middleware是存放路由中间件的文件目录。 路由中间件有三种: 匿名(或内联)路由中间件直接在页面中定义。已命名的路由中间件,放在 middleware/ 中,页面使用…

leetcode代码记录(移除元素

目录 1. 题目:2. 我的代码:小结: 1. 题目: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1)…

Docker入门二(应用部署、迁移与备份、DockerFile、docker私有仓库、Docker-Compose)

文章目录 一、应用部署1.MySQL部署2.Redis部署3.Nginx部署 二、迁移与备份1.容器做成镜像2.镜像备份和恢复(打包成压缩包) 三、DockerFile0.镜像从哪里来?1.什么是DockerFile2.DockerFile 构建特征3.DockerFile命令描述4.构建一个带vim的centos镜像案例5…

网安渗透攻击作业(4)

Unload-labs-01 function checkFile() { var file document.getElementsByName(upload_file)[0].value; if (file null || file "") { alert("请选择要上传的文件!"); return false; } //定义允许上传的文件类型 v…

面渣逆袭:Java基础面试题,46道Java基础八股文(4.8万字,30+手绘图)

1、什么是 Java? Java是一种广泛使用的编程语言,由Sun Microsystems(现为Oracle Corporation的一部分)在1995年首次发布。它是一种面向对象的语言,这意味着它支持通过类和对象的概念来构造程序。 Java设计有一个核心理…

软件工程-第5章 结构化设计

5.1 总体设计的目标及其表示方法 5.2 总体设计 变换设计基本步骤: 第1步:设计准备--复审并精华系统模型; 第2步:确定输入、变换、输出这三部分之间的边界; 第3步:第一级分解--系统模块结构图顶层和第一层…

arcgis数据导出到excel

将arcgis属性数据导出到excel: 1) 工具箱\系统工具箱\Conversion Tools.tbx\Excel\Excel 转表 2)用excel打开导出的图层文件中后缀为.dbf的数据(方便快捷,但是中文易乱码)

GPT-5:人工智能的下一个前沿即将到来

当我们站在人工智能新时代的门槛上时,GPT-5即将到来的呼声愈发高涨且迫切。作为革命性的GPT-3的继任者,GPT-5承诺将在人工智能领域迈出量子跃迁式的进步,其能力可能重新定义我们与技术的互动方式。 通往GPT-5之路 通往GPT-5的旅程已经标记着…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:FolderStack)

FolderStack继承于Stack(层叠布局)控件,新增了折叠屏悬停能力,通过识别upperItems自动避让折叠屏折痕区后移到上半屏 说明: 该组件从API Version 11开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件…

探秘atoi与atof的模拟之路:从原理到实践的全能指南!

目录 ​编辑 一.atoi及atof库函数的工作原理 1.1atoi 1.2atof 1.3使用时的注意事项 注意事项 1. 检查输入字符串是否为 NULL 2. 检查字符串是否仅包含有效的数字字符 3. 检查转换结果是否在预期范围内 4. 使用更健壮的替代函数 二. 模拟实现atoi和atof 2.1模拟 atoi…

罗马不是一天建成的:DevOps 转型分步指南

“罗马不是一天建成的”这句格言非常适合 DevOps。许多公司都渴望通过“闪电战”获得市场主导地位的即时满足感,但DevOps 的真正成功是一场马拉松,而不是短跑。它需要致力于建立可持续的 DevOps 文化——一种从头开始促进协作、自动化和安全性的文化。 …