引子

对于最近有找工作需求的人来说,这几天是挺难的。最近听闻身边的一些公司裁员的消息,不知道,这悲伤的2020下,是否隐藏着契机。

周末突然想到了之前面试被问到的一道面试题:请简单描述下SpringBoot的启动过程。当时只是简单地说了下,有些点并没有覆盖到。正好,周末有空闲,看了看源码,结合着一些资料,这里就记录下我的理解。

软件版本

SpringBoot   2.1.4.RELEASE

流程分析

在启动方法 main() 方法中,调用了 SpringApplication.run() 方法,在一连串的调用链后,前面的那些简单的调用就不说了,最终,代码会执行到 org.springframework.boot.SpringApplication 类中的这个方法:

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return (new SpringApplication(primarySources)).run(args);
}

对于这个方法,我们看其返回值,将这个方法的逻辑分为两部分:

  • new SpringApplication(primarySources)方法
  • run(args) 方法

下面,我们就分别看看这两部分都做了些什么。

new SpringApplication(primarySources)

我们查看这个方法的源码,发现其最终执行的是下面这个方法:

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();// 这个方法,主要看下面这两行代码setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();
}

PS:上面的内容,是下载的Spring源码里面的代码(就是查看源码时,idea会弹出一个黄色的提示条,可以选择Download Sources下载源码),而不是class文件反编译后的代码。我原本是看的反编译的代码,后来因为想看看作者的注释,就下载了源码,结果这个方法体本身的内容也变了——原本这个方法行数很多,但核心逻辑都是一样的。在下文中,我查看的依旧是 下载后的源码。

对于这个方法,从上面代码的备注处隔开,备注的上面的代码,主要做一些启动配置的初始化,比如,初始化resourcesLoadere、Web应用类型(Servlet或Reactive)等。而备注下方的两行代码:

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

这两行代码,我分别查看 set方法,这两行代码是初始化了 ApplicationContextInitializer 的实现和 ApplicationListener 的实现。这两个接口干什么的后面再说。

这里,我们注意到,两个方法都调用了 getSpringFactoriesInstances()方法。追其源码,最终该方法调用的是下面这个方法:

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {ClassLoader classLoader = getClassLoader();// Use names and ensure unique to protect against duplicatesSet<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);AnnotationAwareOrderComparator.sort(instances);return instances;
}

对于上面 getSpringFactoriesInstances() 这个方法,逻辑也比较简单,从它调用的方法的方法名来看,该方法主要执行三个动作:

  1. 读取 给定类型(type参数)的工厂实现的全限定类名(实际上是从 resources/META-INF/spring.factories 文件中读取的)
  2. 根据读取到的全限定类名,创建对象实例
  3. 根据@Order注解的值进行排序

记住这个方法,后面讲第二部分 springApplication.run(args) 方法的时候,还会用到这个方法。

下面我们分别仔细看看这个方法的流程。上面读取权限定名的时候,代码跳到了org.springframework.core.io.support.SpringFactoriesLoader 这个类中,调用了 SpringFactoriesLoader.loadFactoryNames() 这个方法,而该方法中又调用了另一个重要方法—— loadSpringFactories()。下面一起看看它们俩的源码:

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {String factoryClassName = factoryClass.getName();return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}// 这个是 org.springframework.core.io.support.SpringFactoriesLoader 这个类中定义的常量属性,在下面这个方法中会用到,为了方便源码阅读,我放到这里
private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap<>();private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = cache.get(classLoader);// 首先从缓存中获取,如果获取到了,就直接返回;否则,从 spring.factories 文件中获取if (result != null) {return result;}try {// 下面这个常量,值为 “META-INF/spring.factories”Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));result = new LinkedMultiValueMap<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry<?, ?> entry : properties.entrySet()) {String factoryClassName = ((String) entry.getKey()).trim();for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {result.add(factoryClassName, factoryName.trim());}}}// 注意这里,将结果放到了 缓存中cache.put(classLoader, result);return result;} catch (IOException ex) {throw new IllegalArgumentException("Unable to load factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);}
}

在上面的代码中我们可以看到,在org.springframework.core.io.support.SpringFactoriesLoader 这个类中维护了一个Map作为缓存。这个缓存的访问权限为 private,在源码中看了下,我发现这个缓存就只用于上面这一块代码中,用于缓存指定类加载器能够从 spring.factories 文件中读取到的工厂实现的全限定类名。

首先我们看 loadSpringFactories() 这个方法,这个方法逻辑很简单:

首先去缓存中拿当前classLoader能读取到的数据;如果缓存中没有,就去读取 spring.factories 文件。将数据读取出来后,放入缓存中,然后将数据返回。这里的数据,指的就是在 spring.factories 文件中配置的相关实现类的全限定名

然后是 loadFactoryNames() 这个方法,该方法首先调用了 loadSpringFactories() 这个方法,拿到了当前ClassLoader能读取到的所有工厂实现,然后再根据参数factoryClass的名称去获取指定类型的全限定名,一个类型可能有多个实现。

在获取全限定名的逻辑执行完后,紧接着就是调用 createSpringFactoriesInstances() 方法完成对象的实例化。这里以及后面的排序,代码都很简单,就不贴了。

现在,我们来回顾一下,new SpringApplication(primarySources) 所做的事情:

  1. 做了一些启动配置的初始化。
  2. 读取 spring.factories 文件中所配置的类型的全限定名,并放入缓存(一个Map);后续访问类型信息时就直接从缓存中获取。
  3. 根据上文拿到的类的全限定名,构建出 ApplicationContextInitializer、ApplicationListener 的所有实现的实例,并赋值给当前 SpringApplication对象。

而对于  ApplicationContextInitializer、ApplicationListener 这两个接口,其作用分别是:

  • ApplicationContextInitializer:该接口定义了一个 initialize()方法。在 ApplicationContext 配置完毕之后、被刷新之前,initialize() 方法会被调用。
  • ApplicationListener:该接口定义了一个 onApplicationEvent() 方法。在 ApplicationContext准备的各个阶段,该方法都会被调用。调用的时机,可以参考 org.springframework.boot.SpringApplicationRunListener 这个接口,而具体的调用动作,则可以参考 SpringApplicationRunListener接口的实现类 org.springframework.boot.context.event.EventPublishingRunListener 这个类。

上面两个接口的使用,后文会提到。至此,Spring加载的第一部分 new SpringApplication(primarySources) 的逻辑就分析完了。

springApplication.run(args)

run()方法要比上面麻烦很多了。但是总来说,逻辑还是比较清晰的,我们一步一步来看。下面是run()方法的源码:

public ConfigurableApplicationContext run(String... args) {// 就是一个计时器,没什么玄乎的StopWatch stopWatch = new StopWatch();stopWatch.start();// 这个就是后文会配置的ApplicationContext对象ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();// 这个好像是配置什么AWT属性,感觉不重要,不用管configureHeadlessProperty();// 下面这一行代码,相当重要。这里就是配置 ApplicationListener 的地方SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[]{ConfigurableApplicationContext.class}, context);prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);} catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);} catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;
}

这个方法不长,但是逻辑却比较复杂。我们将其分而治之,一步一步来看。

getRunListeners(args)

首先,前面的什么计时器什么的我们就不看到,直接看到我们第一处应该关注的代码,就是下面这行:

SpringApplicationRunListeners listeners = getRunListeners(args);

我们查看 getRunListeners() 方法的源码,如下:

private SpringApplicationRunListeners getRunListeners(String[] args) {Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };return new SpringApplicationRunListeners(logger, // 重点关注下面这个方法getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}

在继续分析之前,请大家睁大眼睛,注意上面代码中两个名称记为相似的引用:

  • org.springframework.boot.SpringApplicationRunListener:一个用于监听 ApplicationContext配置过程的监听器,里面提供了一些描述该过程的方法。
  • org.springframework.boot.SpringApplicationRunListeners:上面代码块中方法的返回类型,是一个包访问权限的类,里面存储了所有 SpringApplicationRunListener 的实现,其源码很简单,当它调用一个描述ApplicationContext加载过程的方法(例如:starting()、contextPrepared()等方法)时,相当于所有的 SpringApplicationRunListener 实例都调用了这个方法。

大家在阅读源码的时候都看仔细咯,别看错了。下面回到源码。在上面这个 getRunListeners() 方法中,重要的是其调用了getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args) 这个方法。这里,我将方法的参数也带上了,注意第三个参数 this,代表的是 前面的 new SpringApplication() 得到的那个 SpringApplication 对象。

前面我们已经分析过 getSpringFactoriesInstances() 这个方法了,我说该方法主要执行三个动作,第一个就是获取指定类型的工厂实现的全限定类名,这里就是 SpringApplicationRunListener 的所有实现的全限定类名。并且,前文中已经提到了这里的缓存机制,也就是说现在实际上可以直接从缓存中去获取了。

第二个动作就是根据获取到的全限定名,将这些类实例化。之前 createSpringFactoriesInstances() 这个方法我没讲,这里,我们只看它是如何实例化对象的:

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {// 忽略其他代码Class<?> instanceClass = ClassUtils.forName(name, classLoader);Assert.isAssignable(type, instanceClass);Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);T instance = (T) BeanUtils.instantiateClass(constructor, args);// 忽略剩下的代码
}

从代码上看,这里是通过参数类型去获取有参构造方法,然后通过有参构造方法完成对象的实例化的。而这里,我们需要实例化的是 SpringApplicationRunListener 接口的实现类。通过查阅代码,在默认情况下,该接口只有一个实现类,就是前文我们提到过的 org.springframework.boot.context.event.EventPublishingRunListener 这个类。Mac系统下,我们下载源码后,可以通过 Command + Optionn + 点击 查看 SpringApplicationRunListener 接口的实现类。

也就是说,这里实际上实例化时,构建出的是 EventPublishingRunListener 这个类的实例。这个类提供了一个有参构造方法,实例化的时候也是调用的这个,我们看看其源码:

// 贴出这个属性,只是为了让大家明白,application 指代的是一个 org.springframework.boot.SpringApplication对象
private final SpringApplication application;
private final SimpleApplicationEventMulticaster initialMulticaster;public EventPublishingRunListener(SpringApplication application, String[] args) {this.application = application;this.args = args;this.initialMulticaster = new SimpleApplicationEventMulticaster();// 注意下面遍历的对象,是 application.getListeners() 的返回值for (ApplicationListener<?> listener : application.getListeners()) {this.initialMulticaster.addApplicationListener(listener);}
}

这个方法里面,我们只需要关注for循环的逻辑,实际上就是将 application.getListeners() 的返回值全部都 add 到 initialMulticaster 这个属性中。而 application.getListeners() 的逻辑也很简单,看源码:

public Set<ApplicationListener<?>> getListeners() {return asUnmodifiableOrderedSet(this.listeners);
}

这里的 this,也是代表的是 前面的 new SpringApplication() 得到的那个 SpringApplication 对象。asUnmodifiableOrderedSet() 返回的是一个不可变的、已经排好序的 LinkedHashSet。前面分析 new SpringApplication() 的时候,提到了初始化了 ApplicationContextInitializer 和 ApplicationListener 这里两个接口的实现。而这里的 this.listeners,就是前面我们初始化了的 ApplicationListener 接口的实现。

也就是说,当我们构建 EventPublishingRunListener 这个类的对象时,会将前文得到的 ApplicationListener 接口的实现添加到该类的 initialMulticaster 属性中。

至此,getRunListeners(args) 这部分的逻辑咱们就看完了。咱们来梳理一下:

该方法用于获取到所有 SpringApplicationRunListener 的实现,并将这些实现封装为到一个 SpringApplicationRunListeners 中。在默认情况下(可以开发人员实现这个接口),SpringApplicationRunListener 的实现类是 EventPublishingRunListener 类,在构造 EventPublishingRunListener 对象的时候,会将前面从 spring.factories 中定义的 ApplicationListener 接口的实现也添加到 EventPublishingRunListener 对象的 initialMulticaster 属性中。

后续当 SpringApplicationRunListeners 的对象调用类似 starting() 方法时,Spring会根据 事件类型(EventType) 选出所有符合条件的 ApplicationListener 的实现,并异步调用他们的 starting()方法。这里就简单的提一下,要是看具体的逻辑,又得好多时间。

prepareEnvironment(listeners, applicationArguments);

上面获取到所有的 listener 后,需要进行的第一个动作就是准备环境,也就是这里的 prepareEnvironment() 方法的逻辑。下面看看这个方法的源码:

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {// 默认情况下,下面这个方法会 new 一个 StandardServletEnvironment 返回;ConfigurableEnvironment environment = getOrCreateEnvironment();// 配置环境,实际核心逻辑是配置了 Properties 和 ProfileconfigureEnvironment(environment, applicationArguments.getSourceArgs());// 环境准备完毕后,调用 ApplicationListener 实例的 environmentPrepared() 方法listeners.environmentPrepared(environment);bindToSpringApplication(environment);if (!this.isCustomEnvironment) {environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());}ConfigurationPropertySources.attach(environment);return environment;
}

 

未完待续,周末继续~

 

参考文档

1、https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/ApplicationContextInitializer.html

 

 

 

 

 

 

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

相关文章

  1. web页面PC端和移动端的区别有哪些?

    操作方式:PC端的操作方式与移动端已经有了明显的差别,PC端使用鼠标操作,操作包含滑动、左击、右击、双击操作,操作相对来说单一,交互效果相对较少,而对于手机端来说,包含手指操作点击、滑动、双击、双指放大、双指缩小、五指收缩和苹果最新的3Dtouch按压力度,除了手指操…...

    2024/4/24 8:47:53
  2. Servlet复习笔记(5)——监听器、过滤器、文件的上传和下载

    1. Listener监听器Listener 监听器它是 JavaWeb 的三大组件之一。JavaWeb 的三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。 Listener 它是 JavaEE 的规范,即接口。 监听器作用:监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处…...

    2024/4/24 8:47:49
  3. zookeeper入门及集群搭建

    zookeeper是什么 目前,在分布式协调技术方面做得比较好的就是Google的Chubby还有Apache的ZooKeeper他们都是分布式锁的实现者。有人会问 既然有了Chubby为什么还要弄一个ZooKeeper,难道Chubby做得不够好吗?不是这样的,主要是Chbby是非开源的,Google自家 用。后来雅虎模仿C…...

    2024/5/6 6:58:36
  4. 网络安全技术第一章——计算机网络安全概述

    计算机网络安全概述 这里写目录标题计算机网络安全概述一. 网络安全现状和问题1.网络安全的现状2.典型的网络安全问题二. 网络安全研究的动因1、知识普及2、 Internet应用的快速发展带来的安全问题归纳:网络安全研究的动因:三、 网络安全的相关概念定义:安全的意义是将资源可…...

    2024/4/24 8:47:47
  5. 操作系统正确的学习姿势 --- 你不可错过的宝藏资源

    一般很少有人推荐操作系统的网站吧。。。。。。这几个网站来源于我平常的学习总结,也有一些是来源于网上优秀的回答,希望这几个网站能够助力你对操作系统有更深的认识。 studytonight studytonight 简直太棒了!!! studytonight 会包括 operationg system,但是并不是说 st…...

    2024/4/24 8:47:46
  6. Elasticsearch简介1

    这里写目录标题Elasticsearch安装安装ElasticSearch的注意事项ES的主要名词概念倒序索引:ES节点的选举规则为何主分片数目不可变ES文档相关ES搜索写法操作添加规则:添加数据![这里是引用](https://img-blog.csdnimg.cn/20200524221503140.png?x-oss-process=image/watermark…...

    2024/4/24 8:47:48
  7. 对话CDO|从“数据资产”到“数据价值”,数据管理助力首席数据官引领变革

    在数据3.0时代,随着科技创新、AI赋能,数据作为最具时代特征的新生产要素,如同土地、矿产和劳动力一样,具有战略资源的重要意义。那如何将数据变为资产,如何创造数据价值,成为各行各业的共同挑战和命题。首席数据官CDO应运而生,进入企业高管团队,承担起全面发挥数据价值…...

    2024/4/24 12:47:30
  8. MyBatis三剑客

    目录MyBatis Generator(MBG)方式一(推荐)方式二MyBatis-PluginMyBatis-PageHelpermybatis三剑客MyBatis Generator  mybatis逆向工程,根据数据表自动生成实体类、mapper接口、xml映射文件 MyBatis-Plugin  IDEA插件,可以实现mapper接口方法、xml映射文件元素之间的快…...

    2024/5/6 8:54:25
  9. 看懂带宽和吞吐量,了解如何充分利用网络

    大数据时代,数据体量日益壮大,数据类型多种多样,随之而来的是大数据交互面临严峻的速度挑战。回归本质,无论传输TB级大文件和海量小文件,或两者都要传输,网络带宽利用是数据交互效率的关键所在。为了确保内容的快速交换,许多企业花费大量资金来提升带宽,希望随着网络带…...

    2024/4/19 16:28:00
  10. SpringBoot集成nacos动态刷新数据源

    目录前言第一步:重写DruidAbstractDataSource类第二步:配置动态获取nacos配置信息第三步:手动刷新数据源 前言 因为项目需要,需要在项目运行过程中能够动态修改数据源(即:数据源的热更新)。这里以com.alibaba.druid.pool.DruidDataSource数据源为例 第一步:重写DruidAb…...

    2024/4/27 1:12:50
  11. break on _CFRunLoopError_RunCalledWithInvalidMode to debug

    今天出现这个问题,代码也没指定对应的地址和相关的信息,只是抛出了invalid mode kCFRunLoopCommonModes provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.libc++abi.dylib…...

    2024/5/2 17:05:07
  12. 全网首发,腾讯T3-3整理Netty学习方案(体系图+项目+学习文档)

    前言:想要学好一门技术,最起码要对他有一定的了解,起码听说过相应的底层原理的东西吧,最起码你要有一点能和别人交流的内容吧,下面是我精简的一点内容,希望对于大家了解netty能有一点帮助Netty是建立在NIO基础之上,Netty在NIO之上又提供了更高层次的抽象。在Netty里面,…...

    2024/4/16 13:55:44
  13. 一直卡在 Initializing Spring embedded WebApplicationContext

    描述:Spring Boot项目启动不了,一直卡在 Initializing Spring embedded WebApplicationContext,看启动日志,找到 ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console…...

    2024/4/20 4:51:31
  14. 机器学习笔记(支持向量机)

    文章目录线性分类器线性可分问题原问题对偶问题线性不可分问题原问题对偶问题核函数 线性分类器 线性分类器是 nnn 维空间中的分类超平面,它将空间分成两个部分。这个超平面的方程为 wTx+b=0,\mathbf{w}^{\text{T}} \mathbf{x} + b = 0,wTx+b=0, 其中,x\mathbf{x}x 是输入向量…...

    2024/4/16 13:55:54
  15. 获取二维数组长度

    public class array_length {public static void main(String[] args) {String[][] data=new String[2][5];System.out.println("第一维数组长度为:"+data.length);System.out.println("第二维数组长度为:"+data[0].length);} }输出结果:第一维数组长度…...

    2024/5/2 20:13:56
  16. 好子串的个数(计数)

    题意:一个由01组成的字符串,如果它的子串的长度等于这个子串转换成10进制的值,那么这个子串就是好子串。输出好子串的个数。所有子串的长度小于2e5题目链接思路:2e5的数据,小于2的30次方。从左到右遍历,遇到1的时候,往后遍历30个字符,记录数值,判断数值是否小于可能的…...

    2024/4/24 8:47:43
  17. 端口号大全

    端口号大全 标签(空格分隔): 常用文档https://blog.csdn.net/qq_34646546/article/details/88545165 计算机系统“端口”是英文 port 的义译,可以认为是计算机与外界通讯交流的出口。其中 硬件领域的端口又称接口,如:USB 端口、串行端口、打印机端口等。软件领域的端口一…...

    2024/4/29 3:10:23
  18. 币均赋:要做自己的市场主导者

    做单技巧大全-看!要看!必须要看!入行这么久,从开始的一切都是懵懂,到现在的得心应手,一路走过来,背后的故事有很多,一直以来都想有时间把做单的技巧给大家一起分享一下,下面这些是老赋总结出来的一些做单经验技巧,大家可以作为参考学习。1、每次入市买、卖,损失不应…...

    2024/4/24 8:47:41
  19. 【leetcode】373. Find K Pairs with Smallest Sums(未理解)

    题目:思路: 抄作业https://leetcode.com/problems/find-k-pairs-with-smallest-sums/discuss/84607/Clean-16ms-C%2B%2B-O(N)-Space-O(KlogN)-Time-Solution-using-Priority-queue。实在是没有理解。代码实现: class Solution { public:vector<vector<int>> kSm…...

    2024/4/24 8:47:40
  20. 程序设计思维与实践 Week15 作业 A ZJM与霍格沃兹

    题目描述:ZJM 为了准备霍格沃兹的期末考试,决心背魔咒词典,一举拿下咒语翻译题 题库格式:[魔咒] 对应功能 背完题库后,ZJM 开始刷题,现共有 N 道题,每道题给出一个字符串,可能是 [魔咒],也可能是对应功能 ZJM 需要识别这个题目给出的是 [魔咒] 还是对应功能,并写出转…...

    2024/4/24 8:47:40

最新文章

  1. 亚马逊测评工作室如何轻松实现高收益,跨境电商揭秘汇率差赚钱术

    随着跨境电商在国内市场的持续繁荣&#xff0c;众多电商卖家纷纷将目光投向了这一充满活力的领域。面对国内市场的激烈竞争&#xff0c;许多卖家选择向外拓展&#xff0c;寻求更广阔的发展空间。其中&#xff0c;亚马逊成为了众多卖家的不二选择&#xff0c;毕竟老外的市场还是…...

    2024/5/6 12:08:33
  2. 梯度消失和梯度爆炸的一些处理方法

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

    2024/5/6 9:38:23
  3. JVM学习笔记

    文章目录 一、内存模型1. 程序计数器2. 栈3. 本地方法栈4. 堆5. 方法区方法区位置字符串常量池位置 6. 直接内存 二、虚拟机参数设置三、类的生命周期1. 加载2. 连接1&#xff09;验证2&#xff09;准备3&#xff09;解析 3. 初始化4. 卸载 四、类加载器1. 启动类加载器2. 扩展…...

    2024/5/5 8:36:54
  4. 蓝桥杯加训

    1.两只塔姆沃斯牛&#xff08;模拟&#xff09; 思路&#xff1a;人和牛都记录三个数据&#xff0c;当前坐标和走的方向&#xff0c;如果人和牛的坐标和方向走重复了&#xff0c;那就说明一直在绕圈圈&#xff0c;无解 #include<iostream> using namespace std; const i…...

    2024/5/3 9:22:44
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/6 9:21:00
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

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

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

    2022/11/19 21:17:18
  26. 错误使用 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
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

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

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

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

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

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

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

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

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

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

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

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

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,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
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    2022/11/19 21:16:58
  44. 如何在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