面经-Spring框架相关

news2024/9/28 13:24:33

面试题

Spring、SpringMVC、SpringBoot的区别

Spring是轻量级的开发框架,主要提供了IOC依赖注入容器和AOP面向切面编程的功能。

SpringMVC是基于Spring的一个用来解决Web开发的问题,主要处理web开发中路径映射和视图渲染等

SpringBoot是融合了Spring和SpringMVC等框架以及自带有Web服务器,采用约定大于配置来简化各种配置文件的配置

Spring中AOP是怎么实现的

Spring中的AOP是通过动态代理实现的,代理方式主要有两种:JDK动态代理、CGLIB动态代理

JDK动态代理是基于接口生成实现类并通过反射进行调用

CGLIB动态代理是基于继承实现的

依赖注入是什么

依赖注入是控制反转的一种实现方式,容器通过配置自动创建并注入对象来实现控制反转。

其优点是降低对象间的耦合度

Spring依赖注入主要有以下几种方式

  • set注入
  • 构造器注入
  • 自动注入

Spring框架中使用到的设计模式

  • 工厂模式:BeanFactory
  • 代理模式:Spring的AOP就是基于动态代理实现的
  • 单例模式:单例Bean的创建
  • 适配器模式:HandlerAdpter
  • 模板模式:提供了很多类似于jdbctemplate类

Spring启动流程

  • ResourceLoader加载XML配置信息后,由BeanDefinitionReader读取配置信息文件,把每个解析成BeanDefinition对象保存在BeanDefinitionRegistry注册表中。这时的BeanDefinition可能只是个半成品,因为某些XML属性配置里会有占位符变量,这些变量此时不会被解析出来,需要继续优化
  • 容器首先扫描注册表取出工厂后处理器,对注册表中的BeanDefinition进行加工处理,把占位符替换成真正的值,产生成品的BeanDefinition。
  • 通过反射机制扫描BeanDefinitionRegistry所有属性编辑器的bean类,并把这些bean放到spring容器的属性编辑器注册表(PropertyEditorRegistry)中
  • Spring容器从BeanDefinitionRegistry中取出加工后的BeanDefinition,并调用InstantiationStrategy着手对bean的实例化工作。(这里的实例化只是相当于new了一个新对象一样,也就是说,只是跑一个构造函数,不会具体的为属性设置值,当然如果构造函数里写了设置值的语句,那么也可以赋值。)
  • 实例化的过程中,spring容器使用BeanWrapper对bean进行封装,BeanWrapper结合BeanDefinition和属性编辑器注册表中的属性编辑器完成bean的属性设置工作
  • Bean后置处理器

Bean的生命周期

主要分为四个阶段:实例化、设置属性、初始化、销毁

  • 利用反射创建一个Bean的实例
  • 设置对象属性
  • 检查是否实现Aware相关接口,如果实现了就调用对应的方法
  • 执行BeanPostProcessor的前置处理
  • 检查是否实现InitializingBean接口,如果实现则执行afeterPropertiesSet()方法。
  • 检查是否配置又init-method方法,如果有则调用
  • 执行BeanPostProcess的后置postProcessAfterInitialization()方法。
  • 当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VElwdRbW-1677676338030)(null)]

Spring中的IOC及应用场景

BeanFactory和ApplicationContext的区别

BeanFactory是Spring中最底层的容器接口,ApplicationContext继承了BeanFactory是更高级的容器接口。这两个接口都主要提供获取Bean的功能

  • BeanFactory容器在启动时不会去初始化Bean,只有等真正调用getBean方法时才会初始化。ApplicationContext会在启动时将所有单例对象实例化
  • 由于ApplicationFactory是BeanFactory的子接口,所以包含其所有的功能,并且功能更强大,一般情况下使用ApplicationContextFactory

SpringBoot自动装配的原理

  • SpringBoot启动时会去扫描当前启动类的类路径,然后扫描这个路径下所有需要注入的信息
  • 并且会扫描项目内所有包的META-INF下的SpringFactory文件,将路径下的Configuration加载进去并且根据条件注入对应的Bean

DispatcherServlet工作流程

  1. DispatcherServlet调用HandlerMapping根据URL来找到对应的Handler执行器链
  2. DispatcherServlet调用HandlerAdpter来执行请求
  3. 请求执行结束后返回一个ModelAndView
  4. DispatcherServlet调用视图解析器将ModelAndView解析成视图返回给用户

事务失效原因

  • 对象没有被spring管理

  • 方法不是public

  • 同类的方法调用(此时没有经过代理)

    解决办法

    使用aspectj进行aop

  • 数据库不支持事务

  • 异常被捕获

  • 异常类型和配置异常不同

  • 有某个bean先于事务bean注入并且该bean引用这个bean导致事务bean提前注入没有被aop代理

Spring Bean的作用域

  • 单例
  • 原型
  • request
  • session

BeanFactory和FactoryBean

  • BeanFactory是所有Spring容器的核心接口,给容器实现提供规范。用于获取所有的bean
  • FactoryBean是针对实际的某个Bean的接口,Bean通过实现FactoryBean接口来配置Bean实例化时的操作

@Autowired和@Resources有什么区别

Spring

Spring框架本身是一个轻量级的IOC的容器框架。Spring的作用主要是帮我们创建了对象和管理对象的生命周期。我们在代码中可以不用再考虑创建对象时需要哪些参数,只需要从Spring的容器中取出来用即可。Spring是使用依赖注入的方式实现控制反转的,我们只需要通过简单的XML配置或者注解配置。Spring启动时就会将对象和它所依赖的对象创建出来。并且Spring还提供了AOP,单元测试、数据库、Web模块等框架,可以让我们轻松的将这些框架集合在一起使用。

IOC

IOC:控制反转,主要是指将对象创建的权力交给框架,并且由框架来管理。对象间复杂的依赖关系交给IOC容器来管理,对象的创建和属性的注入都由Spring来提供,我们只需要通过XML/注解来配置一下即可。

Spring容器中的对象与普通Java对象创建的区别

普通的Java对象,创建时虚拟机将对应的class文件加载进来,再将对象初始化。Class做为对象的模板进行创建的,并且创建对象是由我们来决定的,需要在代码中显式的创建对象才能使用。而Spring容器中的Bean创建是由Spring IOC容器来实现的,Bean对象的生命周期、依赖关系也都是容器来控制。我们只需要在XML文件、注解、JavaConfig中对Bean进行描述。Spring启动后会读取这些信息生成对应的BeanDefinition

Bean

Bean的作用域

主要分四种

  1. 单例:全局只保留唯一的一个对象,Spring中默认采用的单例
  2. 原型:每次获取该对象时都会创建一个全新的对象
  3. Request:bean的存活期限时一次请求
  4. Session:bean的存活时间是一次会话

Bean的生命周期

  1. 利用反射创建一个Bean的实例
  2. 设置对象属性
  3. 检查是否实现Aware相关接口,如果实现了就调用对应的方法
  4. 执行BeanPostProcessor的前置处理
  5. 检查是否实现InitializingBean接口,如果实现则执行afeterPropertiesSet()方法。
  6. 检查是否配置又init-method方法,如果有则调用
  7. 执行BeanPostProcess的后置postProcessAfterInitialization()方法。
  8. 当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法

Bean是线程安全的吗

Bean是否是线程安全是根据Bean的作用域来区分的

  • Bean如果是单例的,那就存在线程安全问题,但如果是像Controller这种只关注方法调用的无状态Bean(无状态Bean:Bean中不保存数据)一般也是不存在线程安全问题的
  • Bean如果是原型的,也不存在线程安全问题,因为每次获取都是一个全新的Bean。

解决方法:使用同步机制(时间换空间),或者将单例改为原型(空间换时间)

依赖自动注入六层筛选

循环依赖-三层缓存

构造器注入中出现循环依赖时,Spring在启动时就会抛出异常。解决循环依赖的办法是使用延迟加载,

Set方法的循环依赖解决办法

主要分三级缓存

一级缓存:放置实例化好的单例对象

二级缓存:存放提前曝光的单例对象(没有进行属性注入)

三级缓存:存放实例化对象的对象工厂

Tips:其实二级缓存就能解决循环依赖的问题,之所以采用三级循环是因为AOP

流程

  • 获取A时,先在一级缓存中获取
  • 一级缓存中没有,则进入二级缓存中查找
  • 二级缓存中也没有则会进入三级缓存中查找
  • 三级缓存中也没有则会将对象A进行实例化后放入三级缓存
  • 再对A进行注入,注入时发现A依赖于B,则去实例化B(放入三级缓存),因为B又依赖于A则将三级缓存中的A放入B中(因为三级缓存存放的是A的工厂对象,B是可以通过工厂对象获取到真正的代理对象的)
  • 将三级缓存中的A转如二级缓存中
  • 对B进行实例化后放入一级缓存
  • A再获取到B进行注入

AOP

AOP:面向切面编程,主要用于具有横切性质的系统级服务如日志收集、事务管理、安全检查等,比如我们代码中经常会记录操作日志或者权限校验,不使用AOP时我们需要在每个地方加上对应的代码。非常冗余也使代码不宜维护。AOP的作用就是将这些公共部分的代码抽离出来写成一个公共的方法。这样就减少了代码的冗余并且利于维护。

优点:降低代码耦合、提高代码复用性、易于扩展

AOP的实现

Spring AOP是怎么实现的

Spring中使用动态代理来实现AOP,动态代理的实现方式有两种,一种是JDK动态代理,一种是CGLIB动态代理。

JDK动态代理

JDK动态代理是基于接口实现的,它是利用反射生成接口的一个匿名实现类,生成的这个类在调用方法前会先调用InvokeHandler来处理。JDK代理的限制是必须要求代理类实现了某个接口才能被代理

优点

  • 生产代理类的速度更快
  • JDK原生不需要依赖

缺点

  • 只能代理接口实现类
  • JDK动态代理是通过反射调用方法,速度更慢

CGLIB动态代理

CGLIB使用了字节码生成技术,在运行时通过继承被代理的类来实现代理。CGLIB不需要考虑代理对象是否实现接口,不过需要考虑代理对象是否被final修饰(final修饰的类不能被继承自然不能被CGLIB代理)

Spring对接口的实现类都采用JDK动态代理,对于没有实现接口的类采用CGLIB实现

优点

  • CGLIB代理的类不需要实现接口
  • 因为CGLIB生成的类是通过继承实现的,所以调用方法时速度更快

缺点

  • 不能代理final和private方法
  • 不能代理final类
  • 生产代理类的速度慢

AspectJ和SpringAOP的区别

SpringAOP采用的是JDK动态代理和CGLIB动态代理,是一种运行时增强,是在运行时对动态的生成类来实现的。并且SpringAOP只能对Spring容器中的Bean进行代理,不能对普通对象使用。

AspectJ是采用的静态代理,在编译时期对代码进行织入。因为AspectJ是在编译时期对代码进行增强,所以它在运行时是没有其他开销的,性能要比SpringAOP的性能更高,并且AspectJ还提供了很多织入方式和功能。AspectJ可以对任何对象进行代理

Advice通知的类型

  • 前置通知:方法执行前调用通知
  • 后置通知:方法执行后调用通知
  • 返回通知:方法正常返回后调用通知
  • 异常通知:方法返回异常后调用通知
  • 环绕通知:方法执行前后都可以自定义行为

Around Around

Before Before

执行 执行

Around 抛出异常

After After

AfterReturning AfterThrowing

img

img

多个切面织入时执行顺序

多个切面织入时顺序是不固定的,可以通过指定order级别来实现固定顺序

Spring中的设计模式

工厂模式

Spring中的BeanFactory就是简单工厂的实现,根据传入的唯一标识来回去bean

单例模式

提供了全局的访问点BeanFactory

代理模式

Spring的AOP就是使用代理模式来增强

装饰器模式

依赖注入就需要使用BeanWrapper。

观察者模式

Spring中各种Listener

策略模式

AOP动态代理时采用何种方式来增强(CGLIB、JDK动态代理)

常用注解

@Component

将一个类注册为Bean,spring启动时会将加了这个注解的类注册为一个Bean放入容器中

@Controller

标识这个类是一个MVC的控制器,作用和Component相同

@Service

标识这个类是一个服务层的Service,作用和Component相同

@Resource

将依赖的对象自动注入进来,默认是按照Bean的名字来注入,名字不匹配时才会按照类型来注入

@Autowird

将依赖的对象自动注入进来,默认是根据Bean的类型进行自动装配Bean,并且要求这个对象必须存在,如果不存在会抛出异常

@Qualify

指定装入Bean的名字,与Autowird一起使用(@Autowird默认使用的按类型注入)

@Transactional实现原理

在类或者方法上使用,可以开启事务。开启事务的方法执行时抛出异常后,事务会执行回滚。

实现原理

Spring启动时扫描Bean,遇到@Transactional的注解时就会使用AOP对这个类进行动态代理(相当于以@Transactional注解为切点切入事务,类似于环绕型通知)。代理对象在执行真正方法时抛出异常,代理对象就会进行回滚,反之将事务提交

事务

事务的隔离级别(5种)和传播特性(7种)

5种事务隔离级别

Spring事务传播属性和隔离级别 - Eunice_Sun - 博客园 (cnblogs.com)

Spring中的事务隔离级别和数据库的隔离级别相同,只多一个默认隔离级别(使用数据库默认隔离级别)

如果数据库中设置的事务隔离级别和Spring设置的不同,以Spring为主

7种传播特性

REQUIRED

如果当前存在事务则沿用事务,否者创建新事务

REQUIRED-NEW

不论当前是否有事务都会创建新的事务,将原来的事务挂起

SUPPORT

如果当前有事务则沿用事务,如果没有则以无事务方式运行

NOT-SUPPORT
以非事务方式运行,如果当前存在事务则挂起事务

MANDATORY

使用当前事务,如果没有事务则抛出异常

NEVER

以非事务方式运行,如果当前存在事务则抛出异常

NESTED

嵌套事务(类似于REQUIRED),实现部分提交。子事务catch异常可以实现父事务不回滚。在Required中子事务发生异常不论是否catch都会导致整个事务回滚。

事务实现的原理

Spring中提供两种事务方式:编程式事务和声明式事务

编程式事务

编程式事务需要在代码中手动进行处理,一般不会使用这种方法

声明式事务

声明式事务主要是使用@Transactional注解

底层就是通过AOP来代理这个对象,如果调用方法后抛出异常则会进行回滚,反之则提交事务

SpringMVC

SpringMVC执行流程

  1. 请求URL由DispatcherServlet来进行分发
  2. 调用HandlerMapping处理器根据请求的URL找到对应的处理器
  3. 由HandlerAdapter(处理器适配)调用真正的Handler来进行处理
  4. Handler处理后返回一个ModelAndView对象(数据视图对象)
  5. 视图解析器对视图进行解析找到要返回的视图
  6. DispatcherServlet将Model渲染到视图上返回给浏览器

SpringBoot

SpringBoot相比SSM框架的优点

  • SpringBoot采用的约定大于配置,它内置了很多基本配置,大大的减少了xml文件的配置。
  • SpringBoot中内置服务器,项目可以独立运行,可以更快速的启动一个Web项目
  • 引入第三方框架时只需要配置很少的信息

SpringBoot的常用注解

@SpringBootApplication

springboot项目的启动类,标识这是一个springboot项目,用来开启springboot的各项能力。

@springbootappliation其实是三个注解的组合(@Configuration,@EnableAutoConfiguration,@ComponentScan)

@Configuration

表明这是一个配置类,类中配置的bean都会被加载到spring容器中

@EnableAutoConfiguration

允许springboot开启自动注解配置,开启后springboot会扫描启动类下的包和类来配置spring bean。这个注解也是SpringBoot自动装配的关键。

自动装配的原理

Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到所有META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它能从Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,properties配置类会从application中读取它对应前缀的属性,如果没有配置一般也会有默认值。

@RestController

@ResponseBody+@Controller的结合体,标识这个Controller返回的信息直接写入response body,以json格式返回

@Bean

标注这个方法的返回值注册为一个Bean

手写SpringBootStarter

  • 创建一个starter项目

  • 创建一个ConfigurationProperties用来保存配置信息(一般要设置默认值)

    @ConfigurationProperties(prefix = "http") // 自动获取配置文件中前缀为http的属性,把值传入对象参数
    @Setter
    @Getter
    public class HttpProperties {
    
        // 如果配置文件中配置了http.url属性,则该默认属性会被覆盖
        private String url = "http://www.baidu.com/";
    
    }
    
  • 创建一个AutoConfiguration,在 AutoConfiguration 中实现所有 starter 应该完成的操作,并且把这个类加入 spring.factories 配置文件中进行声明

    • 创建一个业务类(Bean)
    @Setter
    @Getter
    public class HttpClient {
    
        private String url;
    
        // 根据url获取网页数据
        public String getHtml() {
            try {
                URL url = new URL(this.url);
                URLConnection urlConnection = url.openConnection();
                BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));
                String line = null;
                StringBuilder sb = new StringBuilder();
                while ((line = br.readLine()) != null) {
                    sb.append(line).append("\n");
                }
                return sb.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "error";
        }
    
    }
    
    • 创建 AutoConfiguration
    @Configuration
    @EnableConfigurationProperties(HttpProperties.class)
    public class HttpAutoConfiguration {
    
        @Resource
        private HttpProperties properties; // 使用配置
    
        // 在Spring上下文中创建一个对象
        @Bean
        @ConditionalOnMissingBean
        // 指这个bean在哪些情况下不加载
        public HttpClient init() {
            HttpClient client = new HttpClient();
    
            String url = properties.getUrl();
            client.setUrl(url);
            return client;
        }
    
    }
    
  • resources 文件夹下新建目录 META-INF,在目录中新建 spring.factories 文件,并且在 spring.factories 中配置 AutoConfiguration:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.nosuchfield.httpstarter.HttpAutoConfiguration
    
  • 打包项目即可

CORS跨域问题

跨域问题

SpringBoot配置Cors解决跨域请求问题 - 袁老板 - 博客园 (cnblogs.com)

同源策略:同源策略是浏览器的一个安全功能,非同源的请求在没有明确授权下不能读取对方资源。同源是指请求的协议、ip地址、端口号完全相同。同源策略下,非同源的请求是不能发送的

CORS跨域就是为了解决同源策略不能访问的问题,在不破坏原有的同源策略下实现跨源通信。CORS将请求分为两类简单请求和非简单请求。

  • 简单请求:服务器在接收到请求后判断该地址是否跨域访问,如果可以访问则在响应中设置Access-Control-Allow-Origin字段,不设置则表示不支持该IP地址访问
  • 非简单请求:浏览器在发送请求时会发送一个OPTIONS的预检请求来检测服务器是否可访问。服务端在收到请求后设置对应的字段返回来表示是否支持访问。

SpringBoot设置CORS

1、@CrossOrigin

在Controller的方法和类上使用,表明该接口或一系列接口允许跨域访问

2、全局配置

添加全局配置

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }
}

3、使用Filter

@Bean
public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);    config.addAllowedOrigin("http://localhost:9000");
    config.addAllowedOrigin("null");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效
    FilterRegistrationBean bean = newFilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(0);
    return bean;
}

主要作用就是判断请求是否为跨域请求,是否需要设置必要的跨域信息。

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

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

相关文章

关于算力的未来,新一代PowerEdge告诉你答案

从ChatGPT等大模型海量参数的训练,自动驾驶领域感知模型的训练与仿真,到蛋白质机构预测、流体力学仿真等AIScience,再到矿山、交通、能源等部署广泛的边缘计算设备……如今,我们愈发确切地认识到,算力在数字经济时代不…

Ubuntu系统设置开机自启

在测试国产操作系统:银河麒麟、UOS统信机器的过程中,发现开机不自启,总结以下几种方式实现自启 一.rc.local rc.local脚本是一个Ubuntu开机后自动执行的脚本,可以在脚本内添加行指令,该脚本位于/etc/路径下&#xff…

【Pytorch】Pytorch深度学习实战教程:超分辨率重建AI与环境搭建

一、基础开发环境搭建 1)cuda安装 需要根据自己的显卡的型号选择支持的CUDA版本 显卡驱动查看: 鼠标右键 CUDA安装版本查看:https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html 注意看自己的电脑配置,我的…

基于麻雀算法改进的BP神经网络坑基监测,BP神经网络详细原理,

目标 背影 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 麻雀算法原理 麻雀算法主要参数 麻雀算法流程图 麻雀算法优化测试函数代码 基于麻雀算法改进的BP神经网络坑基监测 数据 matlab…

matlab-数据和数据运算

学习视频基本数据类型1.1 整型与浮点型在matlab中同样有8、16、32、64bit的数据大小之分,同时也可以叠加signed(有符号)和unsigned(无符号)的区别,默认数据类型为double(双精度浮点型)参考其他博客的详述1.2 复数还有一些其他常用的函数方法:…

STM32之定时器

定时器软件定时缺点:不精确,占用CPU资源定时器工作原理使用精准的时基,通过硬件的方式,实现定时功能。定时器的核心是计数器。通用定时器框图该框图主要分成四部分:时钟产生器、时基单元、输入捕获、输出比较时钟产生器…

springboot通过aop实现全局日志(是否自定义注解都可以)

内容参考自以下两个链接1、springboot中使用AOP切面完成全局日志_aop全局日志_邹飞鸣的博客-CSDN博客使用AOP记录日志_aop日志_trusause的博客-CSDN博客第一个链接思路很清晰,讲的也很详细,第二个链接讲了自定义注解为了便于自己理解做了以下整理目录 1.aspectj基本概念 2.添加…

闪光桐人の实习日记(2023年2月27日-3月3日)

前往闪闪の小窝以获得更好的阅读和评论体验 文章目录2023年3月2日(测试流程)为什么是什么如何进行2023年3月1日(消息队列MQ)什么是消息队列为什么要使用消息队列消息队列(kafka)的优势关键信息SpringBoot整…

LeetCode题目笔记——448. 找到所有数组中消失的数字

文章目录题目描述题目链接题目难度——简单方法一:使用额外空间,字典代码/Python代码/C方法二:进阶,原地修改代码/C代码/C总结题目描述 这好像是一到经典的面试题 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间…

遮挡检测--基于角度的遮挡检测方法

文章目录1基于角度的遮挡检测方法2遮挡检测遍历方法2.1方法1--自适应径向扫描方法2.2方法2--螺旋扫描法参考1基于角度的遮挡检测方法 在基于角度的方法中,通过依次分析DSM中沿径向方向的投影光线的角度来识别遮挡。定义α\alphaα角:DSM三维点与相机中心…

解决Windows虚拟机启动资源占用过多

由于虚拟机中的Windows一般是指定版本的,创建后,其自身仍在不断自动更新,因此这里我们禁用两个服务,以后启动Windows之后就不会占用太多资源了: 禁用setuphost.exe禁用.net runtime optimization 文章目录1. 禁用setu…

分布式定时任务-学习笔记

1 发展历程 1.1 Linux命令-CronJob 只能控制单台机器 1.2 任务调度-Quartz 单任务极致控制 1.3 分布式定时任务 1.3.1 定时任务 系统为了自动完成特定任务,实时、延时、周期性完成任务调度的过程 1.3.2 分布式定时任务 把分散的、可靠性差的定时任务纳入统一的平…

VScode下 ESP32 下载程序

ESP32-S3 下载方式可以通过UART0 下载,USB 下载,JTAG下载,还可以使用WIFI进行远程OTA升级程序。插件底栏按键介绍:①选择串口端口号,如COM3; ②选择芯片型号; ③工程idf设置,相当于menuconfig; …

Redis缓存雪崩、缓存击穿、缓存穿透

用户的数据一般都是存储于数据库,数据库的数据是落在磁盘上的,磁盘的读写速度可以说是计算机里最慢的硬件了。 当用户的请求,都访问数据库的话,请求数量一上来,数据库很容易就奔溃的了,所以为了避免用户直…

【Java】Spring Boot 日志文件

文章目录SpringBoot日志文件1. 日志有什么用2. 日志怎么用3. 自定义日志打印3.1 在程序中得到日志对象3.2 使用日志对象打印日志4. 日志级别4.1 日志级别有什么用?4.2 日志级别的分类与使用5. 日志持久化6. 更简单的日志输出--lombok6.1 添加 lombok 依赖6.2 输出日…

操作系统真相还原——第6章内存管理系统

第八章 内存管理系统 makefile 编译整个项目,如果改变局部关系,只靠人工难以维护文件间的依赖关系,所以通过make程序进行处理 makefile文件是make程序的搭档:发现某个文件更新后,只编译该文件和受该文件影响的相关文…

为什么95%的Java程序员人,都是用不好Synchronized?

Synchronized锁优化 jdk1.6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。 锁主要存在四中状态,依次是:无锁-> 偏向锁 -> 轻量级锁 -> 重量级锁,他们…

upload-labs通关详细教程

文章目录文件上传要点1、前端验证绕过做题步骤源码分析2、Content-Type方式绕过做题步骤源码分析3、黑名单绕过做题步骤源码分析4、.htaccess文件绕过简介做题步骤源码分析5、后缀大小写绕过简介做题步骤源码分析6、文件后缀(空)绕过简介做题步骤源码分析…

CAN工具-VSpy(ValueCAN) - Panel面板(续)

继续上次的Panel面板介绍!!!7. LED 控件LED控件可以用作指示器。在Graphical Panels中选中该控件,在界面右侧侧拉框的Properties中可设置LED控件的通用属性。LED控制属性LED On Color:双击打开标准的Windows颜色选择器…

Vue 3.0 学习笔记之基础知识

系列文章目录 提示:阅读本章之前,请先阅读目录 文章目录系列文章目录前言Vue 3.0 创建与Vue2.0对比的变化关闭语法检查setup 组合式函数compositions前言 Vue 3.0 创建 与Vue2.0对比的变化 关闭语法检查 lintOnSave: false setup 组合式函数compositions…