啥是循环依赖?

下面这种情况比较常见,A中注入了属性B,B中注入了A属性。

@Component
public class A {@Autowiredprivate B b; //在A中注入B
}
@Component
public class B {@Autowiredprivate A a; //在B中注入A
}

还有一种极限情况,A中注入属性A。

@Component
public class A {@Autowiredprivate A a;
}

Spring可以解决循环依赖的条件

一、出现循环依赖的Bean必须是单例,原型不行。

第一点很好理解,也很好验证,因为原型的Bean,每次获取的时候都会创建一个新的,那么问题来了,假设在初始化A的时候,需要注入原型的B,接着新建一个A,又新建B……无穷尽。如果真是这样,那还得了。因此,原型情况下Spring无法解决循环依赖,会报错:

aused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?

二、不全是构造器注入的方式。

  • 均采用setter方法注入,可以被解决。
  • 全是构造器注入,无法被解决。
  • setter和构造器都存在,具体情况具体分析,Spring会按照AB的顺序选择新创建哪个。为什么先构造器不行,其实和Spring解决循环依赖的策略相关,后面会谈到。
依赖情况依赖注入方式循环依赖是否被解决
AB相互依赖(循环依赖)均采用setter方法注入
AB相互依赖(循环依赖)均采用构造器注入
AB相互依赖(循环依赖)A中注入B的方式为setter方法,B中注入A的方式为构造器
AB相互依赖(循环依赖)B中注入A的方式为setter方法,A中注入B的方式为构造器

Spring如何去解决循环依赖

SpringBean的创建流程

在讨论Spring如何解决循环依赖之前,我们需要清除SpringBean的创建流程,之前的那篇文章讨论了容器的启动销毁与对象完整的生命周期,这里将其中涉及循环依赖的主要部分再做一个说明:

  • createBeanInstance:实例化,其实也就是调用对象的构造方法或者工厂方法实例化对象
  • populateBean:填充属性,这一步主要是对bean的依赖属性进行注入(@Autowired)
  • initializeBean:回调执行initMethodInitializingBean等方法

可以想到,对于单例的bean,在createBeanInstance的时候,应该没啥问题,循环依赖的问题应该发生在第二步属性注入的时候,而这时后这个实例的状态,正好处于:已经实例化,还未初始化的中间状态。这一点非常关键!!!!

Spring维护的三级缓存

DefaultSingletonBeanRegistry类中,维护了三个注释以Cache of开头的Map,通过反省可以注意到,三级缓存与前两级缓存不太一样,Map中维护的值是ObjectFactory类型。

//单例缓存池 beanName - instance 一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);//bean的早期引用, bean name to bean instance 二级缓存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);//单例工厂 beanName - ObjectFactory  三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  • singletonObjects:一级缓存,一个单例bean【实例化+初始化】都完成之后,将会加入一级缓存,也就是我们俗称的单例池。
  • earlySingletonObjects:二级缓存,用于存放【实例化完成,还没初始化】的实例,提前暴露,用于解决循环依赖问题。
  • singletonFactories:三级缓存,存放单例对象工厂ObjectFactory,与二级缓存不同的是,它可以应对产生代理对象。
@FunctionalInterface //函数式接口
public interface ObjectFactory<T> {T getObject() throws BeansException;
}

还有几个比较重要的集合:

//bean被创建完成之后,注册
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);//正在创建过程中的bean待的地儿,bean在开始创建的时候放入,知道创建完成将其移除
private final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16)); 

getSingleton

AbstractBeanFactory.doGetBean中将会出现两个重载的getSingleton方法:

protected <T> T doGetBean(...){Object sharedInstance = getSingleton(beanName);//// // typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。表示已经创建过一次if (!typeCheckOnly) {markBeanAsCreated(beanName);}// 这个getSingleton方法非常关键。//1、标注a正在创建中~//2、调用singletonObject = singletonFactory.getObject();(实际上调用的是createBean()方法)  因此这一步最为关键//3、标注此时实例已经创建完成//4、执行addSingleton()添加进一级缓存,//同时移除二级和三级缓存,还有注册sharedInstance = getSingleton(beanName, () -> { ... return createBean(beanName, mbd, args); });
}

getSingleton重载一号

protected Object getSingleton(String beanName, boolean allowEarlyReference)

我们的流程进行到AbstractBeanFactory#doGetBean的时候,会执行Object sharedInstance = getSingleton(beanName);,接着会执行getSingleton(beanName,true),一路跟进去,最终会进到DefaultSingletonBeanRegistry 的getSingleton方法,这个方法十分重要,我们具体看一看:

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {//先从一级缓存中获取,获取到,就直接返回Object singletonObject = this.singletonObjects.get(beanName//如果一级缓存获取不到,且这个获取的这个bean正在创建中,就从二级缓存中获取if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) {//从二级缓存中获取singletonObject = this.earlySingletonObjects.get(beanName);//还是获取不到,并且allowEarlyReference为trueif (singletonObject == null && allowEarlyReference) {  //从三级缓存中获取ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) {//循环依赖第二次进入的时候,发现A 的三级缓存,于是可以获取到A 的实例,singletonObject = singletonFactory.getObject();//获取到之后将其置入二级缓存this.earlySingletonObjects.put(beanName, singletonObject); //原先的那个就从三级缓存中移除this.singletonFactories.remove(beanName); }}}}return singletonObject;
}
  1. 先尝试从一级缓存中获取,如果获取到,表示这个对象已经【初始化+实例化】全部完成,当然,对于循环依赖的案例来说,这一步都是获取不到的。
  2. 如果一级缓存中获取不到,没关系,看看这个bean是不是正在创建中【已经开始实例化,但还没有初始化完全】,如果是这个情况,就尝试从二级缓存中获取。
  3. 如果都获取不到,且allowEarlyReference为true的时候,从三级缓存中取,三级缓存中存放的是ObjectFactory。

getSingleton重载二号

另外一个Singleton重载的方法:public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {//将beanName放入到singletonsCurrentlyInCreation这个集合中,标志着这个单例Bean正在创建beforeSingletonCreation(beanName);boolean newSingleton = false;// 传入的lambda在这里会被执行,调用createBean方法创建一个Bean后返回singletonObject = singletonFactory.getObject(); newSingleton = true;singletonObject = this.singletonObjects.get(beanName);}// 创建完成后将对应的beanName从singletonsCurrentlyInCreation移除afterSingletonCreation(beanName);}if (newSingleton) {//加入一级缓存addSingleton(beanName, singletonObject); }}return singletonObject;
}

addSingleton

	protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {//加入一级缓存this.singletonObjects.put(beanName, singletonObject);//三级缓存移除this.singletonFactories.remove(beanName);//二级缓存移除this.earlySingletonObjects.remove(beanName);//注册一下this.registeredSingletons.add(beanName);}}

addSingletonFactory

AbstractAutowireCapableBeanFactory#doCreateBean

在对象实例化完成,初始化之前进行:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean. 实例化BeanWrapper instanceWrapper = null;// 调用构造器或工厂方法 实例化instanceWrapper = createBeanInstance(beanName, mbd, args);我们通常说的bean实例,bean的原始对象,并没有进行初始化的对象 A{ b:null}Object bean = instanceWrapper.getWrappedInstance();//表示是否提前暴露原始对象的引用,对于单例的bean,一般来说为true, 可以通过allowCircularReferences关闭循环引用解决循环依赖问题boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName)); //是否允许单例提前暴露if (earlySingletonExposure) {//调用这个方法,将一个ObjectFactory放进三级缓存,二级缓存会对应删除//getEarlyBeanReference方法:  1、如果有SmartInstantiationAwareBeanPostProcessor,调用他的getEarlyBeanReference方法,2、如果没有,则不变还是,exposedObject//这里也是AOP的实现之处,AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessoraddSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//在bean实例化后,属性注入之前,Spring将bean包装成一个工厂添加进三级缓存中}//此时bean已经实例化完成, 开始准备初始化// bean为原始对象Object exposedObject = bean;try {//负责属性的装配(如依赖注入),遇到循环依赖的情况,会在内部getBean("b")->getSingleton(b)populateBean(beanName, mbd, instanceWrapper);//处理bean初始化完成后的各种回调这里有可能返回一个代理对象exposedObject = initializeBean(beanName, exposedObject, mbd);}//如果bean允许被早期暴露,进入代码if (earlySingletonExposure) { //第二参数为false表示不会从三级缓存中在检查,最多从二级缓存中找,其实二级缓存就够了,其实之前getSingleton的时候,已经触发了A 的ObjectFactory.getObject(),A实例已经放入二级缓存中Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {//如果没有代理,进入这个分支if (exposedObject == bean) {exposedObject = earlySingletonReference; /}}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {//如果一级缓存中尚未存在if (!this.singletonObjects.containsKey(beanName)) { //添加到三级缓存中this.singletonFactories.put(beanName, singletonFactory);//从二级缓存中移除this.earlySingletonObjects.remove(beanName);//注册一下this.registeredSingletons.add(beanName); }}
}

getEarlyBeanReference

前面谈到了这个方法,还没有细说:

    //是否允许单例提前暴露if (earlySingletonExposure) {addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}

它实际上就是调用了后置处理器的getEarlyBeanReference,而真正实现了这个方法的后置处理器只有AbstractAutoProxyCreator,与Aop相关,也就是说,在不考虑Aop的情况下,这个方法压根就和没调用似的。这里我们也能更加明确,三级缓存出现很大程度上也是为了更好处理代理对象。

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {//调用后值处理器的getEarlyBeanReference  exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);}}return exposedObject;
}

我们可以跟进去看一看:

	//AbstractAutoProxyCreator@Overridepublic Object getEarlyBeanReference(Object bean, String beanName) {Object cacheKey = getCacheKey(bean.getClass(), beanName);this.earlyProxyReferences.put(cacheKey, bean);//如果需要的话,返回一个代理对象return wrapIfNecessary(bean, beanName, cacheKey);}

那么如果考虑可能会存在代理对象出现,这时三级缓存中存在的就是这个代理对象,并且之后通过getSingleton从三级缓存中取出,放入二级缓存中的也是这个对象。

解决循环依赖的流程

本质其实就是 让A注入B,B注入A ,B先注入的是一个还没初始化就提前用的A 的引用。【这里不考虑AOP】

以开头的A,B为例,假设他们都使用属性字段注入:

  1. A首先getBean,试图获取容器中单例A,第一次容器中还不存在,于是就需要开始创建A。

  2. 一顿操作,落点:A此时已经被实例化完成,但是还没有初始化,紧接着将A与一个ObjectFactory存入三级缓存 。如果A被AOP代理,通过这个工厂获取到的就是A代理后的对象,如果没有代理,工厂最后获取到的就是A 的实例化对象。

  3. 初始化A,意为A的属性赋值,这时发现B需要注入,于是getBean,来一遍相同的步骤。

  4. 一顿操作,落点:B此时已经被实例化完成,但是还没有初始化,紧接着将B与一个ObjectFactory存入三级缓存 。

  5. 初始化B,发现需要注入A,于是getBean("a"),此时它在三级缓存中找到了A与ObjectFactory<?> singletonFactory,通过singletonFactory.getObject();得到A的引用。并将其存入二级缓存,且从三级缓存移除 。

  6. B注入从对象工厂获得的A的引用,此时B已经初始化完成【代表已经注入A成功,其实是拥有了A的引用】,将B加入到一级缓存,并将B在二级缓存、三级缓存中的玩意清除,返回。

  7. 刚刚是A初始化到一半切出来开始实例化B的,那么接下来也应该返回到A的初始化流程中去。

  8. 显然B都已经初始化完毕了,A当然也顺利地初始化成功了,同样,也将A加入一级缓存中,并将A在二级缓存、三级缓存中清除。

  9. 至此,Spring解决循环依赖结束,A与B都已实例化+初始化完成,并存入一级缓存,且二级缓存、三级缓存中已经没有了A和B。

当然了,这个过程其实是在实例化A的时候,把B一并实例化了,于是在遍历BeanNames实例化B的时候,就不需要进行这么复杂的操作了,因为一级缓存中已经存在B了。

为什么先用构造器注入不能解决循环依赖?

原因在于,Spring解决循环依赖其实是在Bean已经实例化但未初始化这个中间状态的时候进行处理的,因此bean的实例化与初始化两个操作必须分开,才有机会存入三级缓存,提前暴露原始对象。

但是如果使用如果A先使用构造器,在注入的时候,他会去找B,B再注入A,可此时A并没有暴露,也就失败了。

但如果A先用setter注入,A会先暴露,再注入B,B再注入A的时候,就可以通过三级缓存拿到A了。

仅用一级缓存可以解决循环依赖么?

显然不能,Spring通过多个缓存达到存储不同状态的对象:

  • 实例化和初始化都已经完成。
  • 已经实例化,但还没初始化。

如果只有一级缓存,并发情况下,可能取到实例化但未初始化的对象。

为什么需要三级缓存,直接二级暴露引用不行么?

三级缓存使用的是工厂,而不是引用,原因在于:https://mp.weixin.qq.com/s/kS0K5P4FdF3v-fiIjGIvvQ

延迟队实例化阶段生成的对象的代理,只有真正发生循环依赖的时候,才去提前生成代理对象,否则只会创建一个工厂并将其放入到三级缓存中,但是不会去通过这个工厂真正创建对象。

答:这个工厂的目的在于延迟对实例化阶段生成的对象的代理,只有真正发生循环依赖的时候,才去提前生成代理对象,否则只会创建一个工厂并将其放入到三级缓存中,但是不会去通过这个工厂去真正创建对象

我们思考一种简单的情况,就以单独创建A为例,假设AB之间现在没有依赖关系,但是A被代理了,这个时候当A完成实例化后还是会进入下面这段代码:

// A是单例的,mbd.isSingleton()条件满足
// allowCircularReferences:这个变量代表是否允许循环依赖,默认是开启的,条件也满足
// isSingletonCurrentlyInCreation:正在在创建A,也满足
// 所以earlySingletonExposure=true
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));
// 还是会进入到这段代码中
if (earlySingletonExposure) {// 还是会通过三级缓存提前暴露一个工厂对象addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

看到了吧,即使没有循环依赖,也会将其添加到三级缓存中,而且是不得不添加到三级缓存中,因为到目前为止Spring也不能确定这个Bean有没有跟别的Bean出现循环依赖。

假设我们在这里直接使用二级缓存的话,那么意味着所有的Bean在这一步都要完成AOP代理。这样做有必要吗?

不仅没有必要,而且违背了Spring在结合AOP跟Bean的生命周期的设计!Spring结合AOP跟Bean的生命周期本身就是通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来完成的,在这个后置处理的postProcessAfterInitialization方法中对初始化后的Bean完成AOP代理。如果出现了循环依赖,那没有办法,只有给Bean先创建代理,但是没有出现循环依赖的情况下,设计之初就是让Bean在生命周期的最后一步完成代理而不是在实例化后就立马完成代理。

总结

图片来源:https://blog.csdn.net/f641385712/article/details/92801300

Spring通过三级缓存解决了循环依赖:

  • singletonObjects:一级缓存,一个单例bean【实例化+初始化】都完成之后,将会加入一级缓存,也就是我们俗称的单例池。
  • earlySingletonObjects:二级缓存,用于存放【实例化完成,还没初始化】的实例,提前暴露,用于解决循环依赖问题。
  • singletonFactories:三级缓存,存放单例对象工厂ObjectFactory,与二级缓存不同的是,它可以应对产生代理对象。

Spring不能够解决先用构造器注入情况的循环依赖,原因在于Spring解决循环依赖的关键在于bean实例实例化完成,初始化之前的状态,将其加入三级缓存,提前暴露bean。


最后,循环依赖应当在编码的时候就考虑去尽量避免,如果避免不了,那就尽量不要使用构造器注入,可以使用字段注入。

有点晕了,本来想简单地学习一下,没想到一套接着一套,头晕眼花,还是代码看的太少了,继续努力。感觉有点乱,如果有说的不对的地方,还望评论区指点一二!!抱拳!!!

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. pytorch --tensorboardX可视化的使用

    直接上中点 当然了&#xff0c;我们想要在pytorch中使用tensorboardX你需要先安装这些依赖 我在安装的过程中也遇到了一些小问题&#xff0c;基本上都是一些安装依赖版本的问题。 pip install tensorflow1.13.2因为tensorboardX是tensorflow下的一个依赖&#xff0c;所以安装这…...

    2024/4/24 19:19:56
  2. 剑指 Offer 最优题解系列python--字符串

    剑指 Offer 最优题解系列python--字符串替换空格表示数值的字符串字符串的排列替换空格 class Solution(object):def replaceSpace(self, s):""":type s: str:rtype: str"""res []for c in s:if c : res.append("%20")else: res.a…...

    2024/4/1 17:31:44
  3. PostgreSQL JOIN 多表查询

    JOIN用于多张表的关联查询&#xff0c;如SELECT子句(SELECT A.a,A.b,B.a,B.d)中既有表A的字段&#xff0c;同时还有B表的字段&#xff0c;此时使用单独使用FROM A或FROM B已经解决不了问题了&#xff0c;使用JOIN来关联表A和表B即可解决问题&#xff0c;即FROM A,B或A JOIN B&a…...

    2024/4/29 12:39:03
  4. JUC并发进阶之Reentrantlock可重入锁(递归锁)

    一、什么是可重入锁 二、用法 package lock.reentrantlock;import java.util.concurrent.locks.ReentrantLock;/*** 描述&#xff1a; TODO*/ public class GetHoldCount {private static ReentrantLock lock new ReentrantLock();public static void main(String[] ar…...

    2024/4/23 17:57:17
  5. tomcat+myeclipse+mysql环境搭建

    一、java和jdk安装 1、jdk解压安装在C盘中 2、新建环境变量名&#xff1a;JAVA_HOME&#xff0c;变量值&#xff1a;C:\Program Files\Java\jdk-14.0.2 3、在Path变量中&#xff0c;点编辑&#xff0c;再添加变量值&#xff1a;%JAVA_HOME%\bin 4、测试&#xff1a;在cmd中&am…...

    2024/4/1 17:31:42
  6. 2020护网xday整理收集

    参考公众号:F11Team 一:天融信TopApp-LB 负载均衡系统sql注入 POC如下: POST /acc/clsf/report/datasource.php HTTP/1.1Host:Connection: closeAccept: text/javascript, text/html, application/xml, text/xml, */*X-Prototype-Version: 1.6.0.3X-Requested-With: XMLHttp…...

    2024/4/1 17:31:39
  7. TCP的三次握手与四次挥手理解

    本文借鉴其他博客及自身理解而成!、 序列号seq&#xff1a;占4个字节&#xff0c;用来标记数据段的顺序&#xff0c;TCP把连接中发送的所有数据字节都编上一个序号&#xff0c;第一个字节的编号由本地随机产生&#xff1b;给字节编上序号后&#xff0c;就给每一个报文段指派一…...

    2024/4/1 17:31:38
  8. idea 导入项目无外部依赖

    今天用idea导入项目代码的时候始终无法加载外部依赖&#xff0c;External Libraries为空导致JDK外的依赖包导入失败&#xff0c;咋回事呢&#xff1f; 一般通过正常import as maven项目是可以正常导入并且加载外部依赖的&#xff0c;由于不规范导入或直接open可能会存在问题&am…...

    2024/4/21 5:47:24
  9. 华为鸿蒙OS正式开源,安卓要凉了?

    鸿蒙 OS 2.0 正式开源 9月10日&#xff0c;在2020年华为开发者大会上&#xff0c;华为消费者业务CEO余承东宣布&#xff0c;鸿蒙OS升级至2.0版本。 最重要的是&#xff0c;鸿蒙OS 2.0面向应用开发者发布Beta版本&#xff0c;9月10日面向大屏、手表、车机发布&#xff0c;2020…...

    2024/4/10 16:24:05
  10. 4、Jmeter之发送post请求

    还是拿上节聚合上面的老黄历接口做测试接口 这块要改成post&#xff0c;其他不变就好 具体怎么添加的可以看我的上一篇博客&#xff0c;有详细的步骤 注意&#xff1a;保存请求的时候有个坑&#xff1a; 一定要选择这个保存&#xff0c;上面那个保存有时候保存不全 一点要记…...

    2024/4/18 21:27:41
  11. 欢乐SSL模拟赛(2020.9.12)

    rank有算别的大佬&#xff08;只算初二和初三&#xff09; ranknamescoreT1T2T3T4111myselfmyselfmyself290290290100100100100100100101010808080222lzhlzhlzh280280280100100100100100100000808080333lkjlkjlkj260260260100100100606060202020808080444gyxgyxgyx25025025010…...

    2024/4/25 16:41:14
  12. SVO论文翻译总结

    SVO论文翻译总结 SVO: fast semi-direct monocular visual odometry SVO: fast semi-direct monocular visual odometrySVO论文翻译总结 SVO: fast semi-direct monocular visual odometry一、介绍二、系统概述三、符号四、运动估计A、 基于稀疏模型的图像对齐B、 通过特征对齐…...

    2024/4/1 17:17:06
  13. Dubbo-go应用维度注册模型

    Dubbo-go 团队近期发布了 Dubbo-go v1.5.1&#xff0c;Dubbo-go 是 Apache Dubbo 项目的 Go 实现。 根据团队的介绍&#xff0c;虽然 v1.5.1 是 v1.5 的一个子版本&#xff0c;但相比于 v1.5.0&#xff0c; 社区还是投入了很大人力添加了如下重大改进。 1 应用维度注册模型 在…...

    2024/4/29 1:48:08
  14. linux 对文件加密 和 对文件或者文件夹隐藏的方法

    1 对文件夹加密&#xff1a; vim 进入文件 – 编辑完后-- Esc退出 – 输入&#xff1a;X --两次出入密码 – &#xff1a;wq 保存退出 解除密码 vim 进入文档后 Esc退出&#xff0c;输入:X 两次密码提示都不输入任何字符 直接回车&#xff0c;然后输入&#xff1a;wq 即可 参考…...

    2024/4/29 1:15:20
  15. 切割字符串,使得子字符串首尾相同的最小切割数

    #include<bits/stdc.h> using namespace std; //给定一个非空字符串s, 将s切割成若干个非空子串&#xff0c;要求每个子串头尾是相同字符&#xff0c;给出切割子串的数量的最小的方法。 int ans INT_MAX; ///AC 75%版本 void fun(string s, int cnt, int left, int righ…...

    2024/4/24 9:27:38
  16. 完美!京东出品“架构师成长手册”首次落地,其实架构离你并不远

    前言 现在面试造火箭&#xff0c;工作拧螺丝是现在很普遍的现象。可是有时候我常常会看到这么一种现象&#xff1a;同时期进入到同一家公司&#xff0c;时间长了之后&#xff0c;有的人已经有一定的架构能力了&#xff0c;已经缓步向架构师方向迈进了&#xff0c;有的人却还在…...

    2024/4/28 21:09:18
  17. docker 命令整理

    1. 容器生命周期管理 命令作用备注docker run [OPTIONS] IMAGE [COMMAND] [ARG…]创建一个新的容器并运行一个命令OPTIONS说明&#xff1a;-a stdin: 指定标准输入输出内容类型&#xff0c;可选 STDIN/STDOUT/STDERR 三项&#xff1b; -d : 后台运行容器&#xff0c;并返回容器…...

    2024/4/14 2:49:09
  18. Spring Cloud Alibaba:Seata基础知识

    1、介绍 Seata是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 分布式事务处理过程一ID三组件模型&#xff1a; Transaction ID XID 全局唯一的事务ID 三组件&#xff1a; TC (Transaction Coordinator) - 事务协调者…...

    2024/4/27 6:41:40
  19. POJ-6187:Destroy Walls(最大生成树)

    传送门 Problem Description Long times ago, there are beautiful historic walls in the city. These walls divide the city into many parts of area. Since it was not convenient, the new king wants to destroy some of these walls, so he can arrive anywhere from …...

    2024/4/17 7:47:14
  20. DX播放YUV的问题-frame->linesize[0]

    问题现象&#xff1a; 播放一个飞常规设备的视频&#xff0c;解码出来视频的宽度为1056&#xff0c;高度为1792&#xff0c;播放花屏&#xff0c;如下图所示&#xff1a; 问题排查过程&#xff1a; 这种现象一眼就觉得是视频的宽高不对&#xff0c;然后就各种怼FFmpeg&#xf…...

    2024/4/23 3:59:09

最新文章

  1. AI智能名片商城小程序构建企业级私域的IMC模型:IP、MarTech与Content的深度融合

    在数字化营销的新时代&#xff0c;为企业定制开发的AI智能名片B2B2C商城小程序&#xff0c;结合我们丰富的私域运营实践&#xff0c;我们深刻领悟到构建企业级私域的三大核心要素&#xff1a;IP&#xff08;企业人设&#xff09;、MarTech&#xff08;营销技术&#xff09;和Co…...

    2024/5/4 21:18:22
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Golang快速入门教程(一)

    目录 一、环境搭建 1.windows安装 2.linux安装 3.开发工具 二、变量定义与输入输出 1.变量定义 2.全局变量与局部变量 3.定义多个变量 4.常量定义 5.命名规范 6.输出 7.输入 三、基本数据类型 1.整数型 2.浮点型 3.字符型 4.字符串类型 转义字符 多行字符…...

    2024/4/30 15:22:52
  4. Linux mount用法

    在Linux系统中&#xff0c;系统自动挂载了以下挂载点&#xff1a; /: xfs文件系统&#xff0c;根文件系统, 所有其他文件系统的挂载点。 /sys: sysfs文件系统&#xff0c;提供内核对象的信息和接口。 /proc: proc文件系统&#xff0c;提供进程和系统信息。 /dev: devtmpfs文件系…...

    2024/5/2 2:43:39
  5. #QT项目实战(天气预报)

    1.IDE&#xff1a;QTCreator 2.实验&#xff1a; 3.记录&#xff1a; &#xff08;1&#xff09;调用API的Url a.调用API获取IP whois.pconline.com.cn/ipJson.jsp?iphttp://whois.pconline.com.cn/ipJson.jsp?ip if(window.IPCallBack) {IPCallBack({"ip":&quo…...

    2024/5/2 23:16:18
  6. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/4 12:05:22
  7. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/4 11:23:32
  8. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/4 14:46:16
  9. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/3 16:00:51
  10. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/5/4 12:10:13
  11. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/3 21:22:01
  12. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/3 23:17:01
  13. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/4 14:46:12
  14. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/4 14:46:11
  15. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/4 14:46:11
  16. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/5/4 2:14:16
  17. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/3 16:23:03
  18. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/4 12:39:12
  19. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/4 13:16:06
  20. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/4 16:48:41
  21. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/4 14:46:05
  22. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/4 2:00:16
  23. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/3 22:03:11
  24. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/4 9:07:39
  25. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/4 14:46:02
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57