spring面试题总结
1、spring是什么?
spring是一个轻量级IOC和AOP容器框架,是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用的开发,开发者只需要关注业务需求即可:

- core container 容器组件
- spring context,容器上下文
- spring core 核心类库,所有功能都依赖该类库,提供IOC和DI服务
- spring beans 进行实例的管理
- spring AOP 提供AOP服务
- spring web -- 实际就是MVC框架,spring提供了面向web的综合特性,提供了对常见web框架的支持,spring可以管理这些框架,并将spring的资源注入给框架,也可以在框架的前后插入拦截器。
- data acess --- spring的数据访问组件,帮助完成事务管理及持久化操作(没有mybatis也可以完成持久化操作)
- test --- 单元测试组件
2 spring 的优点?
- 基于POJO的轻量级和最小侵入性编程
- 通过依赖注入和面向接口,减低了组件的耦合性
- 提供了AOP技术,支持将一些通用的任务,如安全,日志,事务等进行集中管理,从而实现更好的代码复用
- spring对主流的应用框架提供了集成支持
3、spring框架中都用到了哪些涉及模式?
- 工厂模式: BeanFactory 简单工厂模式,用来创建对象
- 单例模式:spring创建出来的bean默认就是单例模式
- 代理模式:spring的aop功能用到了动态代理技术(jdk、CGLib)
- 模板方法:解决代码重复问题,比如 RestTemplate, JmsTemplate, JpaTemplate
- 观察者模式:定义对象键,一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖他的对象都会得到通知被动刷新,如spring中listener的实现 ---ApplicationListener
4、spring框架中有哪些不同类型的事件?
spring提供了一些5种标准的事件:
- 上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
- 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
- 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
- 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
- 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。
5 、spring 的IOC?
5.1、什么是IOC?
IOC,inversion of control,控制反转,将对象的控制权转移给spring框架进行管理,由spring来控制对象的生命周期(创建,销毁)和对象之间的依赖关系。
也就是说,以前创建对象的时机和主动权是由开发者把握的,如果在一个对象中使用外面的对象,就需要new去创建对象,用完后还涉及到对象的销毁,这种情况下,当前对象就会和其他的接口或者类耦合起来。而IOC则是由专门的容器去创建对象,我们只需要将所有的类在spring中进行登记,当需要某个对象时,只需要告诉spring容器,然后spring就会在适当的时机,把想要的对象主动给我们。也就是说,IOC中,所有的容器都被spring控制,spring容器帮我们创建,查找,注入依赖对象。
5.2 、什么是DI
DI ,dependency injection 依赖注入,在spring完成对象创建的同时,完成对象属性的赋值。这个行为是动态的。
容器全权负责依赖的查询,受管组件只需要暴露JavaBean的setter方法或者带参数构造器,容器就可以在初始化的时候组装对象的依赖关系。
依赖注入的实现方式?
- 接口注入(不用)
- setter方法注入 --- bean标签中通过property标签的value属性进行赋值(实际就是通过反射调用set方法完成属性输入)
- 构造器注入 --- Java类中定义带参数构造器,<constructor-arg index="0" value="10001"/> ,index是参数的位置
两种依赖方式都可以使用,一般来说,自己定义的类,用setter注入比较多,第三方的技术整合时,构造器注入用的比较多。
5.3 、IOC的原理
spring ioc的实现原理就是工厂模式加反射。简单实例代码如下
Class.forName(ClassName).newInstance();
interface Fruit {public abstract void eat();}class Apple implements Fruit {public void eat(){System.out.println("Apple");}
}class Orange implements Fruit {public void eat(){System.out.println("Orange");}
}class Factory {public static Fruit getInstance(String ClassName) {Fruit f=null;try {f=(Fruit)Class.forName(ClassName).newInstance();} catch (Exception e) {e.printStackTrace();}return f;}
}class Client {public static void main(String[] a) {Fruit f=Factory.getInstance("io.github.dunwu.spring.Apple");if(f!=null){f.eat();}}
}
5.4、 IOC的作用?
- 管理对象的创建和依赖的维护
- 解耦,由容器去维护具体的对象
- 托管类的生产过程,如通过代理在类的生产过程中做一些处理,交给容器去做。
5.5 、spring的IoC支持哪些功能?
- 依赖注入DI --- 最重要的功能,从XML的配置上说,就是ref标签,对应着spring的RuntimeBeanRefrence对象。
- 依赖检查
- 自动装配
- 指定初始化和销毁方法
- 支持回调某些方法
6、BeanFactory和ApplicationContext有什么区别?
BeanFactory和ApplicationContext是spring的两大核心接口,都可以当做spring的容器,其中ApplicationContext是BeanFactory的子接口。
依赖关系:
BeanFactory:是spring中最底层的接口,包含了各种bean的定义,读取bean配置文档,管理bean的加载,实例化,控制bean的生命周期,维护bean之间的依赖关系。
ApplicationContext是BeanFactory的子接口,除了提供BeanFactory所有的功能外,还提供了更完整的框架功能(其他继承接口的功能),如支持国际化(继承MessageSource)、统一的资源文件访问方式,提供在监听器中注册bean的事件,同时加载多个配置文件等。
![]()
加载方式:
BeanFactory采用的是延迟加载形式来注入Bean,因此只有在使用到某个Bean时(调用getBean()方法),才会该Bean进行加载实例化,这样如果存在配置问题,不容易第一时间发现
ApplicationContext是在容器启动的时候,一次性创建所有的Bean, 这样在容器启动过程中就可以发现Spring中的配置错误,有利于检查依赖是否注入。不足是占用内存空间,但在是也可以定义成延迟加载,bean的元数据中定义 lazy-init=“true”
7、spring是如何设计容器的,BeanFactory和ApplicationContext关系详解
BeanFactory 可以称为“低级容器”,底层是个HashMap, key是BeanName,value是Bean的实例,通常只提供注册(put),和获取(get)功能。
ApplicationContext可以称为“高级容器”,他继承了多个接口,因此具备了更多的功能,这个接口定义了一个refresh方法,用于刷新整个容器,即重新加载所有的bean。
IoC在spring中,其实只需要低级容器就可以实现,两个步骤如下:
1、加载配置文件,解析成BeanDefinition放在Map中;
2、调用getBean的时候,从BeanDefinition所属的Map中,拿出Class对象进行实例化,如果有依赖关系,则递归调用getBean方法,完成依赖注入。
至于高级容器ApplicationContext,包含了上述功能,同时支持不同的信息源头,支持访问文件资源,支持事件发布通知,支持接口回调等等功能。
8、ApplicationContext通常的实现有哪些?
FileSystemXmlApplicationContext: 从一个xml文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。---常用于配置文件在文件系统路径下
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。--- 常用于配置文件在类路径下。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
AnnotationConfigApplicationContext:基于注解加载bean,避免使用application.xml进行配置。相比XML配置,更加便捷。
9、什么是spring beans?
在spring中,构成应用程序主干并由spring IOC管理的对象称为bean,或者说是被Spring IoC容器初始化,装配和管理的Java对象,这些beans通过容器配置的元数据创建。
bean相关的元数据
<beanid="bookDao" ----bean的idname="dao" ----bean的别名class="com.itheima.dao.BookDaoImpl" ----bean的类型,全路径名scope="singleton" ----控制bean的实例数量,默认是singleton单例,prototype是多例beaninit-method="init" ---- bean生命周期的初始化方法destory-method="destory" ----bean生命周期的销毁方法,销毁前运行的方法autowire="byType" ----自动装配类型factory-method="getInstance" ----bean的工厂方法,应用于静态工厂或者实例工厂factory-bean="com.itheima.factory.BookDaoFactory" ----实例工厂beanlazy-init="true" ----控制bean的延迟加载,默认是false
/>


依赖注入相关的元数据
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><constructor-arg name="bookDao" ref="bookDao"/><constructor-arg name="userDao" ref="userDao"/><property name="bookDao" ref="bookDao"/>
</bean>
10、怎么定义类的作用域?spring支持哪几种作用域?
spring中,可以通过bean定义中的scope属性来定义bean 的作用域,spring中默认的作用域是singleton,表示单例模式。
spring中支持bean的几种作用域如下
- singleton 单例bean,在每个spring IOC 容器中只有一个实例
- prototype:多例bean,一个bean的定义有多个实例,相当于new ---频繁的创建和销毁bean会带来比较大的开销,需要注意。
- request:每次http请求都会创建一个bean,该作用域仅在基于web的spring ApplicationContext情况下有效
- session:在一个http session中,一个bean对应一个实例,该作用域仅在基于web的spring ApplicationContext情况下有效
- global-session: 在一个全局的http session中,一个bean对应一个实例,该作用域仅在基于web的spring ApplicationContext情况下有效
11、spring框架中单例bean是线程安全的吗?
不是,单例bean不是线程安全的,spring框架并没有对单例bean进行多线程的封装处理
实际上,大部分的时候,spring 中的bean都是无状态的(比如dao类,不保存数据),这种bean就无所谓线程安全了,而针对有状态的bean(view,model对象),就需要开发者自己去保证线程安全了。
解决办法:
- 使用prototype,改变bean的作用域
- 使用ThredLocal,将成员变量放在ThredLocal里面,传进来的参数都是跟随线程的,因此也是线程安全的 ---- ThredLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突,属于空间换时间
- 使用同步锁 synchronized ,属于时间换空间的办法,会影响吞吐量。
12、Spring bean 的生命周期
1、加载bean的定义
通过loadBeanDefinitions扫描所有xml配置,注解等将bean 记录在 beanDefinitionMap中
2、创建bean对象
通过doCreateBean()遍历beanDefinitionMap 来创建bean
2.1 构建对象
容器通过createBeanInstance()进行对象的构造(获取构造方法,首先是加了@Autowired注解的构方法,其次是无参构造方法、、、如果存在多个构造方法spring难以识别,则会抛出异常)
准备参数(构造器的入参) 首先是根据类型进行查找,其次通过参数名查找
构造对象,对于无参对象,则直接实例化,有参数的则进行属性的填充
2.2 属性填充
通过populateBean()方法为bean内部的属性进行赋值,通常是@Autowired注解的变量
2.3 初始化bean对象
通过initializeBean()方法对填充后的实例进行初始化
第一步是初始化容器相关信息,通过invokAwareMethods()方法,为实现了aware接口(信息感知接口)的bean设置注入 beanName,beanFactory等容器相关信息
第二步是执行bean的初始化方法,通过invokeInitMethods()方法进行初始化-------如果Bean实现了InitializingBean接口,则会调用他的afterPropertiesSet()方法,同样的,如果用户自定义了init-method方法,那么也会执行
如果Bean实现了BeanPostProcessors接口【bean后置处理器】,则会在初始化方法invokeInitMethods()前后分别执行 postProcessBeforeInitialization()和postProcessAfterInitialization() 方法,此时,bean已经准备就绪,可以被应用程序使用了
如果bean实现了DisposableBean接口,spring会调用他的destory()方法。
2.4 添加到单例池
如果bean被声明为singleton,则会被加入单例池,由spring进行管理。
3. 销毁
销毁前,调用bean中@PreDestroy注解 的方法,
然后通过postProcessBeforeDestruction方法调用destoryBean逐一销毁Bean
调用 invokeCustomDestoryMethod执行客户自定义的销毁。
13. 声明是Spring的内部bean? spring inner beans?
当一个bean仅被用作另一个bean的属性时,能被声明为一个内部bean,内部bean可以用setter注入属性 和 构造方法注入构造参数的方法来实现,内部bean通常是匿名的,scope一般是prototype。
14 spring中如何注入一个集合?
<list>类型用于注入一列值,允许有相同的值。
<set> 类型用于注入一组值,不允许有相同的值。
<map> 类型用于注入一组键值对,键和值都可以为任意类型。
<props>类型用于注入一组键值对,键和值都只能为String类型。
15、什么是bean装配?什么是bean的自动装配?
bean的装配就是指在spring容器中,把bean组装到一起,前提是知道bean的依赖关系,通过依赖注入把他们装配到一起。
自动装配就是Spring容器能够自动装配相互合作的bean,通过beanFactory自动处理bean之间的协作
XML里面配置自动装配方式 autowire属性:
- no:默认的方式是不进行自动装配的,而是通过手工配置ref属性来指定要装配的bean
- byName: 通过bean的名称进行自动装配,如果一个bean的property属性和另一个bean的name(id)相同,则进行自动装配
- byType:通过参数的数据类型进行自动装配
- constructor:利用构造函数进行装配,并且构造函数的参数通过bytype进行装配
- autodetect: 自动探测,有构造方法,则通过构造方法,没有则根据byType
@Autowired注解:
启动spring的IOC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。
- 如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;
- 如果查询的结果不止一个,那么@Autowired会根据名称来查找;
- 如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。
16、 自动装配有哪些局限性?
基本数据类型和string字符串不能自动装配
自动装配不如显式装配精确。
17 什么是基于注解的配置?
允许在少量Java注解的帮助下,进行大部分spring的配置,而不是xml文件
如,@Configuration声明配置这是一个配置类,然后在这个类中使用@Bean注解,定义bean
@Configuration
public class StudentConfig {@Beanpublic StudentBean myStudent() {return new StudentBean();}
}
18 怎么开启注解装配
注解装配默认是关闭的,如果想使用,则需要在spring的配置文件中配置
<!-- 声明使用注解配置 -->
<context:annotation-config/><!-- 声明Spring工厂注解的扫描范围 -->
<context:component-scan base-package="com.qfedu.beans"/>
- @Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
- @Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。
- @Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。
- @Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。
19 @Required 注解有什么用?
这个注解表明bean的属性必须在配置的时候进行设置值,如果未设置,则会抛出BeanInitializationException异常。
20 @Autowired注解和@Resource注解之间的区别?
都是属性注解, @Autowired还可以用作set方法上
- @Autowired 按照类型进行装配,默认情况要求依赖对象必须要存在(可以设置required属性为false)
- @Resource 按照名称进行装配,找不到名称才会按照类型装配
21 @Qualifier注解作用?
当创建多个相同类型的bean时,并希望仅仅使用属性进行装配其中一个bean时,可以使用@Qualifier 注解进行指定,通常和@Autowired注解一起使用在setter方法
@Autowired
public void setClazz(@Qualifier("c2") Clazz clazz) {this.clazz = clazz;
}
22 spring 支持的事务管理类型?
spring事务的本质其实是对数据库事务的支持。
- 编程式事务管理,在代码中显示调用开启事务,提交事务,回滚事务的相关方法。优点是灵活性高,但是难以维护
- 声明式事务管理,底层建立在AOP基础上,本质是对方法的前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在方法执行完之后,根据执行情况提交或者回滚事务。----从业务代码里面分离出事务管理,仅仅用注解或者xml来配置管理事务
大多数Spring框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。
23 spring 事务隔离级别
spring中有五大隔离级别,默认值是isolation_default(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致,读未提交,读已提交,可重复读,串行化。
24 spring 的事务传播行为
事务的传播行为,指的是当多个事务同事存在的时候,spring如何处理这些事务。
- PROPAGATION_REQUIRED:如果没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,是最常见的设置
- PROPAGATION_SUPPORTS:支持当前事务,如果存在事务,就加入该事务,如果当前不存在事务,则以非事务执行
- PROPAGATION_MANDATORY:强制事务,如果当前存在事务,则加入该事务,如果不存在,则抛出异常
- PROPAGATION_REQUIRES_NEW:创建新的事务,不管当前是否存在事务
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则将事务挂起
- PROPAGATION_NEVER:以非事务执行,如果当前存在事务,则抛出异常
- PROPAGATION_NESTED:嵌套事务,如果不存在事务,则创建事务,如果存在事务,则创建一个新事务,嵌套到当前事务中。
25 spring框架的事务管理有哪些优点?
为不同的事务API提供了一个不变的编程模式(JDBC/JTA等)
为编程式事务管理提供了一套简单的API
支持声明式事务管理,易于管理,对代码侵入性小
和spring各种数据访问抽象层很好的集成。
26 什么是AOP?
Aspect - Oriented Programming ,面向切面编程。是一种通过动态代理,对原有的业务逻辑进行拦截,并且在这个拦截的横切面上添加特点的处理逻辑,实现对原有业务的增强。
连接点(jointPoint): 程序中的方法
切入点(pointCut): 被spring横切的方法
通知/增强(Advice):定义切点放在切入点的前面、后面,还是哪里。。。
切点: 添加到切入点的方法(如事务的begin,commit,rollback)
切面:定义切点方法的类
织入(weaving): 就是把切面应用到目标对象,并创建新的代理对象的过程。
27 spring 中的通知都有哪些类型?
AOP中,切面的工作被称为通知,实际上是程序执行时要通过springAOP框架触发的代码段。
spring切面可以配置以下5种类型的通知:
- 前置通知 before:在目标方法调用之前调用通知功能
- 后置通知 after: 在目标方法完成之后调用通知,不会关心方法输出什么
- 返回通知 After-returning: 在目标方法成功之后调用通知
- 异常通知 After-throwing:在目标方法异常之后调用
- 环绕通知around:通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义行为。
after 和 after-returning根据配置的顺序决定执行顺序
28、代理模式,动态代理?
代理模式的优点:将通用性的工作交给代理对象完成,而被代理对象只需要专注自己的核心业务即可。减少代码耦合。
动态代理,几乎可以为所有的类产生代理对象,无需声明式的创建Java代理类,在运行过程中生成虚拟的代理类,被classLoader加载。动态代理的实现方式有两种:JDK动态代理和CGLib动态代理。
28.1 JDK动态代理:
通过被代理对象实现的接口产生代理对象的:
- 创建一个类,实现InvocationHandler接口,重写invoke方法 ---method.invoke(obj,args); 这个就是通过反射执行被代理类的方法。
- 在类中定义一个Object类型变量,并提供这个变量的有参数构造器,用于把代理对象传递进来
- 定义getProxy()方法,用于创建并返回代理对象。
public class JDKDynamicProxy implements InvocationHandler {//被代理对象private Object obj;public JDKDynamicProxy(Object obj) {this.obj = obj;}//产生代理对象,返回代理对象public Object getProxy(){//1.获取被代理对象的类加载器ClassLoader classLoader = obj.getClass().getClassLoader();//2.获取被代理对象的类实现的接口Class<?>[] interfaces = obj.getClass().getInterfaces();//3.产生代理对象(通过被代理对象的类加载器及实现的接口)//第一个参数:被代理对象的类加载器//第二个参数:被代理对象实现的接口//第三个参数:使用产生代理对象调用方法时,用于拦截方法执行的处理器Object proxy = Proxy.newProxyInstance(classLoader, interfaces,this);return proxy;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {begin();Object returnValue = method.invoke(obj,args); //执行method方法(insert)commit();return returnValue;}public void begin(){System.out.println("----------开启事务");}public void commit(){System.out.println("----------提交事务");}
}测试代码//创建被代理对象
BookDAOImpl bookDAO = new BookDAOImpl();
StudentDAOImpl studentDAO = new StudentDAOImpl();//创建动态代理类对象,并将被代理对象传递到代理类中赋值给obj
JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(studentDAO);//proxy就是产生的代理对象:产生的代理对象可以强转成被代理对象实现的接口类型
GenaralDAO proxy = (GenaralDAO)jdkDynamicProxy.getProxy();//使用代理对象调用方法,并不会执行调用的方法,而是进入到创建代理对象时指定的InvocationHandler类种的invoke方法
//调用的方法作为一个Method参数,传递给了invoke方法
proxy.insert(student);
28.2 CGLib动态代理
JDK是通过被代理类实现InvocationHandler接口来产生代理对象的,如果一个类没有实现接口,改如何产生代理对象呢?
CGLib动态代理,是通过创建被代理类的子类来创建代理对象的,因此即使没有实现任何接口,也可以通过CGLib动态代理产生代理对象。----因此CGLib动态代理不能够产生 final类 的代理对象
- 添加CGLib依赖
- 创建CGLib代理类,实现MethodInterceptor接口,重写intercept方法
- 类中定义一个Object类型的变量,并提供这个变量的有参构造器,用于传递被代理对象
- 定义getProxy方法创建并返回代理对象(代理对象是通过创建被代理类的子类来创建的)
public class CGLibDynamicProxy implements MethodInterceptor {private Object obj;public CGLibDynamicProxy(Object obj) {this.obj = obj;}public Object getProxy(){Enhancer enhancer = new Enhancer();enhancer.setSuperclass(obj.getClass());enhancer.setCallback(this);Object proxy = enhancer.create();return proxy;}public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {begin();Object returnValue = method.invoke(obj,objects); //通过反射调用被代理类的方法commit();return returnValue;}public void begin(){System.out.println("----------开启事务");}public void commit(){System.out.println("----------提交事务");}
}测试//创建被代理对象
BookDAOImpl bookDAO = new BookDAOImpl();
StudentDAOImpl studentDAO = new StudentDAOImpl();//通过cglib动态代理类创建代理对象
CGLibDynamicProxy cgLibDynamicProxy = new CGLibDynamicProxy(bookDAO);
//代理对象实际上是被代理对象子类,因此代理对象可直接强转为被代理类类型
BookDAOImpl proxy = (BookDAOImpl) cgLibDynamicProxy.getProxy();//使用对象调用方法,实际上并没有执行这个方法,而是执行了代理类中的intercept方法,将当前调用的方法以及方法中的参数传递到intercept方法
proxy.update();
相关文章:
spring面试题总结
1、spring是什么? spring是一个轻量级IOC和AOP容器框架,是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用的开发,开发者只需要关注业务需求即可: core container 容器组件 spring context,…...
使用MUI与H5+构建移动端app
前言 通过mui构建APP 效果图: <!DOCTYPE html> <html> <head><meta charset...
第17篇:Java变量总结
目录 1.变量的概念 1.1 变量来源 1.2 计算机中的变量 1.3 变量如何在内存中存储 2.Java变量...
使用51单片机的GPIO输出占空比可调节的PWM波
一、前言 在一些单片机或微控制器中,通用GPIO可以被配置为产生PWM信号。PWM即脉冲宽度调制,是一种用于模拟输出的技术。它可以通过改变输出信号的脉冲宽度来控制电路中的电平,从而实现对电路的控制。 二、什么是PWM波? PWM波&a…...
从产品经理的角度如何提升项目的交付质量?
提高交付质量 ,对于每个IT公司都是永恒的话题。 交付质量其实包含2重意义, 一是交付的高质量(客户角度),即客户的满意度;二是高质量的交付(交付团队的角度),这里是指如何…...
JavaScript BOM【快速掌握知识点】
目录 Window对象的常用属性 语法: Window对象的常用方法 语法: open()和close()方法 History对象 常用属性和方法 示例 Location对象 常用属性 常用方法 Document对象的常用方法 定时函数 超时调用:setTimeout() 间歇调用&…...
【算法】哈希表
作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下来🐾 文章目录1.定义2.优点3.数字哈希3.1拉链法3.2开放寻址法3.3 例题4.字符串哈希1.定义 哈希表(Hash table),是根据键…...
彻底搞懂React-hook链表构建原理
写在前面的小结 每一个 hook 函数都有对应的 hook 对象保存状态信息useContext是唯一一个不需要添加到 hook 链表的 hook 函数只有 useEffect、useLayoutEffect 以及 useImperativeHandle 这三个 hook 具有副作用,在 render 阶段需要给函数组件 fiber 添加对应的副…...
【数据挖掘实战】——应用系统负载分析与容量预测(ARIMA模型)
项目地址:Datamining_project: 数据挖掘实战项目代码 目录 一、背景和挖掘目标 1、问题背景 2、传统方法的不足 2、原始数据 3、挖掘目标 二、分析方法与过程 1、初步分析 2、总体流程 第一步:数据抽取 第二步:探索分析 第三步&a…...
【华为OD机试模拟题】用 C++ 实现 - 九宫格按键输入(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明九宫格按键输入题目输入输出示例一输入输出说明示例二输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高…...
Linux: config: CONFIG_SYN_COOKIES
文章目录 CONFIG_SYN_COOKIESLinux kernel里的超时设置Huawei SBC详细工作机制CONFIG_SYN_COOKIES config SYN_COOKIES,布尔值;是否支持IP:TCP syncookie功能。 详解:一般来说TCP/IP网络不能够阻挡SYN flooding工具。这个工具很容易被利用,而且会导致DOS工具,妨碍其他整…...
【笔记】C# 数据类型转换
文章目录前言类型转换的概念1,隐式转换2,显式转换3,程序类转换结语前言 🌻 大家好啊,我是writer桑,本章是关于 C# 数据类型转换的一个总结,其中包含隐式、显示转换和程序类转换,方便…...
JavaWeb JavaBean,MVC三层架构
9、JavaBean 实体类 JavaBean有特定的写法: 必须要有一个无参构造属性必须私有化必须有对应的get/set方法; 一般用来和数据库的字段做映射 ORM; ORM :对象关系映射 表—>类字段–>属性行记录---->对象 people表 …...
JavaEE简单实例——MyBatis一对多关联映射的嵌套结果集查询
简单介绍: 在之前的章节,我们简单介绍了MyBatis中的一对一的关联查询,使用了嵌套查询和嵌套结果集两种方式进行讲解,但是在实际的使用中,我们常用的是嵌套结果集的查询方式,所以在一对多的查询中ÿ…...
大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——OutputFormat数据输出
3.6.1OutputFormat接口实现类 OutputFormat是MapReduce输出的基类,所有实现MapReduce输出都实现了OutputFormat接口。下面我们介绍几种常见的OutputFormat实现类。 1、文本输出TextOutputFormat 默认的输出格式是TextOutputFormat,它把每条记录写为文…...
Linux搜索、编辑
目录 1.搜索 1.1.基础用法 1.2.高级用法 2.编辑 2.1.vim简洁 2.2.vim快捷键 1.搜索 1.1.基础用法 find命令用于搜索,格式如下: find 指定目录 -匹配方式 所要匹配的关键字 所要匹配的关键字支持通配符,?代表一个字符*代表任意个字符。 如果想设…...
Git Commit提交规范总结
文章目录前言git commit 提交规范提交消息头(commit message header)提交消息具体内容(commit message body)提交消息尾述(commit message footer)Revert表情(Emojis)标识idea插件其他操作Commitizen生成 Change logGit获取提交消息格式化输出相关参考前言 我们都知道…...
【ESP 保姆级教程】疯狂毕设篇 —— 案例:基于ESP8266和EMQX的教室灯光控制系统
忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-26 ❤️❤️ 本篇更新记录 2022-02-26 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...
SpringBoot (一) 项目构建、配置读取、静态资源定义
哈喽,大家好,我是有勇气的牛排(全网同名)🐮 有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!。 前言 SpringBoot是基于Spring开发的开源项目,…...
<JVM上篇:内存与垃圾回收篇>12 - 垃圾回收相关概念
笔记来源:尚硅谷 JVM 全套教程,百万播放,全网巅峰(宋红康详解 java 虚拟机) 文章目录12.1. System.gc()的理解12.2. 内存溢出与内存泄露内存溢出(OOM)内存泄漏(Memory Leakÿ…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
