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 接口有两个实现类: SmsServiceImpl1SmsServiceImpl2,且它们都已经被 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 对象给DispatcherServletModelAndView 顾名思义,包含了数据模型以及相应的视图的信息。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
  目录