Q&A:Spring


1.Spring

Spring,Spring MVC,Spring Boot 之间什么关系?

  • Spring 是一款开源的轻量级 Java 开发框架,Spring 提供的核心功能主要是 IoC 和 AOP。

  • Spring MVC 是 Spring 中的一个很重要的模块,主要赋予 Spring 快速构建 MVC 架构的 Web 程序的能力。MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。

  • Spring Boot 旨在简化 Spring 开发

①Bean

什么是 Spring Bean?

Bean 指的就是那些被 IoC 容器所管理的对象。我们需要告诉 IoC 容器帮助我们管理哪些对象,通过配置来实现。配置方式可以是 XML 文件、注解或者 Java 配置类。

<bean id="book" class="com.jwt.ioc.Book">
  <property name="bname" value="Java入门到精通"></property>
  <property name="bauthor" value="小简"></property>
</bean>

简述 bean 的生命周期

Bean生命周期:从对象创建到对象销毁的过程

  • 1、通过构造器创建 bean 实例(无参数构造)
  • 2、为 bean 的属性设置值和对其他 bean 引用(调用set方法)
  • 3、调用 bean 的初始化的方法(需要进行配置初始化的方法)
  • 4、bean 可以使用了(对象获取到了)
  • 5、当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

如果有bean后置处理器,则bean的生命周期有七种

  • 1、通过构造器创建 bean 实例(无参数构造)
  • 2、为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
  • 3、把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
  • 4、调用 bean 的初始化的方法(需要进行配置初始化的方法)
  • 5、把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
  • 6、bean 可以使用了(对象获取到了)
  • 7、当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
  1. 实例化(通过反射创建对象)
  2. 属性填充(属性值非自动装配)
  3. 初始化(如数据源赋值、校验属性)
  4. 销毁(ioc容器销毁关闭,关闭数据源)

什么是 Spring 容器

spring容器是spring的核心,一切的spring bean都存储在spring容器内,并通过ioc进行管理

spring容器就是一个bean工厂(BeanFactory),应用中bean的实例化、获取、销毁都是由这个bean工厂管理的。

ApplicationContext接口用于完成容器的配置,初始化,管理bean。一个Spring容器就是某个实现ApplicationContext

接口的类的实例。也就是说,从代码层面,Spring容器其实就是一个ApplicationContext。Spring容器的作用我觉得

是实现了控制反转这种思想

Spring自动装配方式有哪些?

bean装配:指在Spring容器中把bean组装到一起,前提是容器需要知道bean的依赖关系

什么是自动装配:根据指定装配规则(属性名称或者属性类型),Spring容器能够自动注入相互合作的bean,这意味着容器不需要配置,能通过Bean工厂自动处理bean之间的协作。

Spring的自动装配有五种模式:

  • no:不进行自动装配,通过手工设置ref属性来进行装配bean。

  • byName:根据Bean的名字进行自动装配。

  • byType:根据Bean的类型进行自动装配。

  • constructor:类似于byType,不过是应用于构造器的参数,如果正好有一个Bean与构造器的参数类型相同则可以自动装配,否则会导致错误。

  • autodetect:如果有默认的构造器,则通过constructor的方式进行自动装配,否则使用byType的方式进行自动装配。

🌟@Autowired 和 @Resource 的区别是什么?

  • @Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
  • Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配),但也可以通过类型byType进行匹配。
  • 当一个接口存在多个实现类的情况下,@Autowired 和@Resource都需要通过名称才能正确匹配到对应的 Bean。
    • Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。

举个例子,SmsService 接口有两个实现类: SmsServiceImpl1和 SmsServiceImpl2,且它们都已经被 Spring 容器所管理。

// 报错,无法匹配到 bean
@Autowired
private SmsService smsService;


// 正确注入 SmsServiceImpl1 对象对应的 bean
@Autowired
@Qualifier(value = "smsServiceImpl1")
private SmsService smsService;

---------------------------------------------------------------------------

// 报错,无法匹配到 bean
@Resource
private SmsService smsService;


// 正确注入 SmsServiceImpl1 对象对应的 bean(比较推荐这种方式)
@Resource(name = "smsServiceImpl1")
private SmsService smsService;

@Bean和@Component有什么区别?

  • @Component 注解用在类上,表明一个类会作为组件类,并告知Spring要为这个类创建bean,每个类对应一个 Bean。自动装配到 Spring 容器中

  • @Bean 注解用在方法上,表示这个方法会返回一个 Bean。@Bean 需要在配置类中使用,即类上需要加上@Configuration注解。

@Bean 注解更加灵活。当需要将第三方类装配到 Spring 容器中,因为没办法源代码上添加@Component注解,只能使用@Bean 注解的方式,当然也可以使用 xml 的方式。

@Bean注解使用示例:

@Component
public class UserServiceImpl {
    private String name = "Tom";
    public String getName() {
        return name;
    }
}

@Configuration
public class AppConfig {
    @Bean
    public UserService userService(){
        return new UserServiceImpl();
    }
}

上面的代码相当于下面的 xml 配置

<beans>
    <bean id="userService" class="com.test.UserServiceImpl"/>
</beans>

BeanFactory和FactoryBean的区别?

  • BeanFactory:管理Bean的容器,Spring中生成的Bean都是由这个接口的实现来管理的。

  • FactoryBean:通常是用来创建比较复杂的bean,一般的bean直接用xml配置即可,但如果一个bean的
    创建过程中涉及到很多其他的bean和复杂的逻辑,直接用xml配置比较麻烦,这时可以考虑用
    FactoryBean,可以隐藏实例化复杂Bean的细节。

🌟BeanFactory和ApplicationContext有什么区别?

BeanFactory 和 ApplicationContext 是 Spring 的两大核心接口,都可以当做 Spring 的容器,管理Bean。其中
ApplicationContext 是 BeanFactory 的子接口。

功能上的区别

  • BeanFactory是Spring框架中最基本的容器,它提供了最基础的IOC和DI的支持 。它的主要功能是用于创建、管理和查找Bean对象。

  • ApplicationContext则是在BeanFactory基础上扩展而来的,它提供了更多的功能和特性。ApplicationContext不仅支持IOC和DI,还支持国际化、事件传递、资源加载、AOP等功能。

加载方式的区别

  • BeanFactory会延迟加载Bean对象,只有在第一次使用时才会进行实例化。这样做的好处是可以避免在程序启动时加载所有的Bean对象,从而提高了应用程序的启动速度和性能。(懒汉思想生成Bean)

  • ApplicationContext会在应用程序启动时就立即实例化所有的Bean对象,同时也会提供更多的Bean生命周期管理功能,例如Bean的自动装配、Bean的自动注入、Bean的声明周期管理等。(饿汉思想生成Bean)

总的来说,BeanFactory是Spring框架中最基本的容器,提供最基础的IOC和DI的支持;而ApplicationContext是在BeanFactory的基础上扩展而来的,提供了更多的功能和特性。ApplicationContext是Spring框架中使用较为广泛的容器。

Spring中bean的作用域

作用域 作用范围 描述
singleton 所用spring应用 单例,Spring中的bean默认都是单例的。
prototype 所用spring应用 每次请求都会创建一个新的bean实例。即每次调用getBean()时,相当于执行newXxxBean()。
request spring web 应用 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
session spring web 应用 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean,该bean仅在当前HTTP session内有效。
application/global-session spring web 应用 全局session作用域,每个 Web 应用在启动时创建一个 Bean,该 bean 仅在当前应用启动时间内有效。
websocket spring web 应用 每一次 WebSocket 会话产生一个新的 bean。

配置 bean 的作用域呢?

xml 方式:

<bean id="..." class="..." scope="singleton"></bean>

注解方式:

@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person personPrototype() {
    return new Person();
}

🌟Spring框架中的单例Bean是线程安全的么?

单例 Bean 存在线程问题,主要是因为当多个线程操作同一个对象的时候是存在资源竞争的。所以最好在 Bean 中尽量避免定义可变的成员变量。

无状态bean:没有实例变量的bean,不能保存数据,是线程安全的。

有状态bean:有实例变量的bean,可以保存数据,是非线程安全的。

在Spring中无状态的Bean适合用单例模式,这样可以共享实例提高性能。有状态的Bean在多线程环境下

不安全,一般用 Prototype 模式或者使用 ThreadLocal (在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中)解决线程安全问题。

🌟如何解决 Spring 的循环依赖问题

Spring循环依赖问题指的是在Spring容器中出现相互依赖的情况,即两个或多个Bean之间相互依赖,形成了一个循环依赖链。例如,Bean A依赖Bean B,Bean B又依赖Bean A,这就构成了一个循环依赖。

Spring是通过三级缓存解决循环依赖问题的,三级缓存用来存放不同类型的Bean对象

  • 第一级缓存里存储完整的Bean对象(完全初始化好的bean),这些Bean是可以被直接使用的

  • 第二级缓存里存储原始的Bean对象(Bean里面的属性还没被赋值或没被依赖注入)

  • 第三级缓存存储Bean工厂的一个对象,用来生成原始Bean对象,放入二级缓存中

三级缓存的核心思想就是把Bean的实例化和Bean里面的依赖注入进行分离,采用一级缓存存储完整的Bean对象,采用二级缓存存储不完整的Bean对象,通过不完整的Bean对象作为突破口,解决循环依赖问题,三级缓存主要是解决代理对象的循环依赖问题

Spring是通过三级缓存解决的循环依赖问题,创建bean的过程分为实例化、属性注入、初始化三步。假设A和B发生了循环依赖,A完成实例化后会放到缓存中,这时需要在A中注入B的bean。对B进行实例化,这时需要在B中注入A的bean,从缓存中获取A实例化后的bean,B的bean创建完成。A从缓存中获取B的bean,完成属性注入和初始化。

具体而言,Spring通过三级缓存解决循环依赖问题的步骤如下:

  1. Spring在创建Bean对象时,首先从一级缓存中查找是否存在已经创建完成的Bean对象,若存在则直接返回该Bean对象;
  2. 若一级缓存中不存在该Bean对象,则从二级缓存中查找是否存在该Bean对象的代理对象,若存在则返回代理对象;
  3. 若二级缓存中也不存在该Bean对象的代理对象,则将正在创建的Bean对象放入三级缓存中,并在创建过程中进行依赖注入。此时,如果其他Bean对象中依赖了正在创建的Bean对象,Spring将直接从三级缓存中获取正在创建的Bean对象,而不是重新创建一个新的Bean对象。
  4. 当Bean对象创建完成后,Spring将其从三级缓存中移除,并将其加入一级缓存中,以便下次获取该Bean对象时直接从一级缓存中获取。

需要注意的是,三级缓存并不是无限制地缓存Bean对象,而是限定在Bean对象创建过程中使用,Bean对象创建完成后将会从三级缓存中移除。此外,如果Bean对象的依赖关系存在循环依赖,则在创建过程中将会抛出异常,因为无法通过缓存解决循环依赖的问题

②IOC

🌟简述 Spring 的 IOC 机制

https://mp.weixin.qq.com/s/uJv3KdSVUxgbz9Gkxy71aw

IOC(Inversion of Control,控制反转)是 Spring 框架的核心,是一种设计思想。基本思想就是将原本在程序中手动创建对象、管理对象的控制权,交由 Spring 框架来管理。通过反射实现对其他对象的控制,包括初始化、创建、销毁等。

  • 控制 :指的是对象创建(实例化、管理)的权力
  • 反转 :控制权交给外部环境(Spring 框架、IoC 容器)

Spring IOC 的主要实现方式是通过依赖注入(Dependency Injection,DI)来实现的。依赖注入是指在对象创建的过程中,自动注入该对象所依赖的其他对象,从而构建对象之间的依赖关系。Spring IOC 支持多种依赖注入的方式,如构造函数注入、Setter 方法注入、字段注入等。

IOC的好处

  • 降低了类之间的耦合,对象创建和初始化交给Spring容器管理,在需要的时候只需向容器进行申请。
  • 资源不由使用资源者管理,而由第三方管理,实现资源的可配置和易管理。
  • 通过使用 Spring IOC,应用程序可以更加关注业务逻辑,而不需要过多关注对象的创建和管理,增加了可维护性且降低了开发难度。

🌟IOC的实现原理

Spring IOC 的实现原理可以分为两个步骤:

  • 扫描和解析配置文件或注解信息,将其转换为内部的对象定义和依赖关系;

  • 根据对象定义和依赖关系,使用反射机制动态创建和初始化对象,并将对象注入到需要使用它们的地方。

具体来说,Spring IOC 的实现过程如下:

  1. 读取配置文件或解析注解信息,将其转换为内部的对象定义和依赖关系。在 Spring 中,可以使用 XML 文件或注解来配置对象和依赖关系。Spring 通过解析配置文件或注解信息,将其转换为内部的对象定义和依赖关系(BeanDefinition)放到容器(BeanFactory)中。对象定义包括对象的类型、属性、构造函数等信息,依赖关系包括对象之间的依赖关系、依赖注入方式等信息。
  2. 使用反射机制创建对象。在 Spring 中,通过反射机制来创建对象。Spring 会根据对象定义的类型和构造函数信息,使用反射机制来创建对象。
  3. 初始化对象。在创建对象之后,Spring 会调用对象的初始化方法,如实现了 InitializingBean 接口的 afterPropertiesSet 方法或配置文件中指定的初始化方法。
  4. 注入依赖关系。在初始化对象之后,Spring 会自动注入对象之间的依赖关系。Spring 支持多种依赖注入方式,如构造函数注入、Setter 方法注入、字段注入等。
  5. 返回对象。在注入依赖关系之后,Spring 将创建并初始化完成的对象返回给调用方(通过BeanFactory.getBean方法)。

总的来说,Spring IOC 的实现原理是通过反射机制动态创建和初始化对象,并将对象注入到需要使用它们的地方。通过解耦对象之间的依赖关系,使得应用程序更加灵活、可维护、可扩展。

Spring依赖注入的方式有哪些

构造器注入、Setter方法注入、注解注入(@Autowired、@Resource、@Value)、接口注入、字段注入

③AOP

🌟简述 Spring AOP 的原理

AOP 就是在运行时通过动态代理技术对目标方法进行增强,可以在目标方法的调用前后或者调用过程中执行其他额外的逻辑。

AOP能够将那些与业务无关,却被业务模块所共同调用的逻辑(横切关注点:例如事务处理、日志管理、权限控制等)封装起来,减少系统的重复代码,降低模块间的耦合度,并有利于未来的拓展和维护(不通过修改源代码方式,在主干功能里面添加新功能)。

Spring AOP 基于动态代理模式实现,它通过在运行期间动态代理目标对象,将被业务模块所共同调用的逻辑(横切关注点)织入到系统中,从而实现了业务逻辑与横切关注点的分离。

  • 1、有接口情况,使用 JDK 动态代理
    • 创建接口实现类代理对象,增强类的方法
  • 2、没有接口情况,使用 CGLIB 动态代理
    • 创建子类的代理对象,增强类的方法

AOP 切面编程设计到的一些专业术语:

术语 含义
目标(Target) 被通知的对象
代理(Proxy) 向目标对象应用通知之后创建的代理对象
连接点(JoinPoint) 目标对象的所属类中,定义的所有方法均为连接点
切入点(Pointcut) 实际增强的方法(切入点一定是连接点,连接点不一定是切入点)
通知(Advice) 增强的逻辑 / 代码,也即拦截到目标对象的连接点之后要做的事情
切面(Aspect) 将通知应用到切入点的过程就叫切面,切入点(Pointcut)+通知(Advice)
Weaving(织入) 将通知应用到目标对象,进而生成代理对象的过程动作

Spring AOP 通过配置文件或注解的方式来定义切面、连接点、切入点和通知等信息,并使用代理模式将切面织入到目标对象中。通过 AOP 技术,可以有效地解耦业务逻辑和横切关注点,提高了系统的可维护性和可扩展性。

🌟动态代理了解吗?

Java动态代理是Java中一种重要的代理模式,它允许在运行时动态地生成代理类和对象,无需编写静态代理类。

在Java中,动态代理可以通过Java自带的两种方式实现:基于接口的动态代理和基于类的动态代理。

  1. 基于接口的动态代理—— JDK 动态代理

基于接口的动态代理是Java官方提供的一种动态代理实现方式。在这种实现方式中,代理类必须实现一个或多个接口,然后在运行时动态创建代理对象。

  1. 基于类的动态代理——CGLIB 动态代理

基于类的动态代理是通过CGLIB库(字节码生成技术)实现的。在这种实现方式中,代理类不需要实现接口,而是通过继承一个已有的类来实现代理功能。

CGLIB(Code Generation Library)是一个高性能的代码生成库,它可以在运行时动态生成字节码来实现类的增强功能。通过CGLIB库,可以直接在运行时创建目标对象的子类,从而实现基于类的动态代理。

基于类的动态代理相比于基于接口的动态代理,可以代理那些没有实现任何接口的类,更加灵活。但是它的实现原理比较复杂,需要在运行时动态生成字节码,会带来一定的性能开销。

④事务

Spring事务的实现方式和原理

  • 编程式事务:在代码中硬编码(不推荐使用) : 通过 TransactionTemplate或者 TransactionManager 手动管理事务,实际应用中很少使用
  • 声明式事务:在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)

Spring事务的隔离级别?

  • TransactionDefinition.ISOLATION_DEFAULT :
    • 使用后端数据库默认的隔离级别,MySQL 默认采用的 REPEATABLE_READ 隔离级别 Oracle 默认采用的 READ_COMMITTED 隔离级别.
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED :
    • 最低的隔离级别,使用这个隔离级别很少,因为它允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
  • TransactionDefinition.ISOLATION_READ_COMMITTED :
    • 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
  • TransactionDefinition.ISOLATION_REPEATABLE_READ :
    • 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • TransactionDefinition.ISOLATION_SERIALIZABLE :
    • 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

spring事务传播机制

1.TransactionDefinition.PROPAGATION_REQUIRED

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

(@Transactional注解默认使用)

2.TransactionDefinition.PROPAGATION_REQUIRES_NEW

创建一个新的事务,如果当前存在事务,则把当前事务挂起。

3.TransactionDefinition.PROPAGATION_NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

4.TransactionDefinition.PROPAGATION_MANDATORY

如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

spring事务什么时候会失效?

⑤注解

简述 Spring 注解的实现原理

简述 Spring 的初始化流程

Spring 是怎么解析 JSON 数据的?

Spring 框架中都用到了哪些设计模式?

2.SpringMVC

说说自己对于 Spring MVC 了解?

Spring MVC是一个基于Java的实现了MVC设计模式的轻量级Web框架,通过把模型-视图-控制器分离,将web各层进行解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合

🌟Spring MVC 的核心组件有哪些?

  • DispatcherServlet :前置控制器,负责接收请求、分发,并给予客户端响应。
  • HandlerMapping :处理器映射器,负责将请求映射到对应的 Handler 即控制器(Controller)。
  • HandlerAdapter :处理器适配器,负责调用处理器方法并封装处理结果,将其传递给 DispatcherServlet。
  • Handler :请求处理器,完成具体的业务逻辑。
  • ViewResolver :视图解析器,根据 Handler 返回的逻辑视图,解析并渲染真正的视图,最终将渲染结果响应给客户端。

🌟Spring MVC 的原理和流程?

  1. 客户端(浏览器)发送请求, DispatcherServlet拦截请求。
  2. DispatcherServlet 根据请求信息调用 HandlerMapping 。将请求映射到对应的 Handler (即控制器Controller),并会将请求涉及到的拦截器和 Handler 一起封装。
  3. DispatcherServlet 调用 HandlerAdapter执行 Handler 。
  4. Handler 完成对用户请求的处理后,会返回一个 ModelAndView 对象给DispatcherServlet,ModelAndView 顾名思义,包含了数据模型以及相应的视图的信息。Model 是返回的数据对象,View 是个逻辑上的 View。
  5. ViewResolver 会根据逻辑 View 查找实际的 View。
  6. DispaterServlet 把返回的 Model 传给 View(视图渲染)。
  7. 把 View 返回给请求者(浏览器)

在这个过程中,DispatcherServlet是整个SpringMVC的核心,它负责协调各个组件的工作。HandlerMapping负责将请求映射到对应的Controller,而HandlerAdapter负责执行Controller。ViewResolver则根据逻辑视图名(如JSP文件名)解析出View对象,最后由View渲染出实际的页面内容。通过这种分工协作的方式,SpringMVC可以实现灵活、高效、可扩展的Web应用程序开发。

3.SpringBoot

  • SpringBoot 是如何进行自动配置的?

4.注解

1. 声明bean

  • @Component:通用的注解,可标注任意类为 Spring 组件。

    • 如果一个 Bean 不知道属于哪个层,可以使用@Component 注解标注。
  • @Controller:对应 Spring MVC 控制层,即Controller层

  • @Service:对应服务层,即Service层

  • @Repository:对应持久层,即 Dao 层

2. 自动注入

@Autowired、@Resource、@Qualifier、@Value

  • @Autowired按照类型(ByType)注入,当一个接口存在多个实现类的情况下,用@Qualifier制定具体的名称
  • @Resource按照名称(ByName)注入,当一个接口存在多个实现类的情况下,用name属性指定具体的名称

3. 配置相关

@Configuration、@Bean、@ComponentScan(扫描Bean)

读取配置信息

AOP相关

@Aspect、@PointCut、@Before、@After、@Around

异步相关

@EnableAync、@Async

前后端传值

  • @PathVariable:用于获取路径参数。用于将路径参数数据映射到控制器方法的参数上

  • @RequestParam:用于获取查询参数。用于将请求参数区数据映射到控制器方法的的参数上


如果请求的 url 是:/user/007/info?userName=Tom

@GetMapping("/user/{userId}/info")
public List<Teacher> getIdAndName(
         @PathVariable("userId") Long userId,
         @RequestParam(value = "userName", required = false,defaultValue = "anonymous") String userName ) {
...
}

服务获取到的数据就是:userId=123456,userName=Tom

请求相关

  • @RequestMapping:映射请求url

  • @RequestParam:获取请求路径后面的参数值

  • @PathVariable:用于获取路径参数。

  • @RequestBody:获取请求体上的参数值

  • @ResponseBody:接口返回以json的形式

  • @RestController:@Controller和@ResponseBody的合集

异常处理相关

  • @ControllerAdvice:定义全局异常处理类
  • @ExceptionHandler:声明异常处理方法

参考

Sponsor❤️

您的支持是我不断前进的动力,如果您感觉本文对您有所帮助的话,可以考虑打赏一下本文,用以维持本博客的运营费用,拒绝白嫖,从你我做起!🥰🥰🥰

支付宝 微信

文章作者: 简简
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 简简 !
打 赏
评论
填上邮箱会收到评论回复提醒哦!!!
 上一篇
RSA总结 RSA总结
已知(dp,e,n,c) dp=d%(p-1)eg: e = 65537 n = 24825400785152624117772152669890180298583276617622160961225887737162058006
2019-10-01
下一篇 
BUUCTF-Web-WriteUp BUUCTF-Web-WriteUp
WarmUp【2018-HCTF】知识点:代码审计,phpmyadmin任意文件包含漏洞参考:phpmyadmin 4.8.1任意文件包含 涉及函数:$_REQUEST , in_array() , mb_substr() , mb_st
2019-08-28
  目录