Spring基础篇:Spring简介

news2024/10/6 18:34:25

第一章:Spring简介

SpringIOC工厂是Spring所有特性的基础,Spring所有的特性都是基于IOC控制反转特性而来的。
当今微服务已经成为主流,微服务依赖于SpringBoot和SpringCloud,而SpringBoot和SpringCloud是衍生于Spring,所以,学习Spring很重要。(Spring学习到位之后才能理解到位SpringBoot和SpringCloud)
Spring全称Spring Framework,2002年写出来的东西,轻量级企业开发开发解决方案,为了解决EJB的缺陷。

一:EJB框架缺陷

1:运行环境苛刻

当前我们开发的程序是属于JavaWeb程序,这样的程序运行的时候需要一个服务器环境,当前我们常用的服务器是Tomcat服务器,我们写好的Java代码都运行在Tomcat上,Tomcat帮我们集中处理请求响应,包括完成Servlet和相关代码的运行和解析。

在Tomcat当中最为核心的组件是一个Servlet引擎的这样一个组件,Tomcat当中所有的核心的工作都是交给一个叫做Servlet引擎的组件来做,这样Tomcat就能实现让我们的代码实现一下web请求的工作,Tomcat我们成为也就是web服务器。

EJB代码对于环境要求很苛刻,他的代码不能运行在Tomcat服务器当中,而是需要运行在EJB容器当中,Tomcat是不具备这个东西的,所以EJB需要运行在更复杂的服务器上,比方说weblogic服务器上,这个服务器上不仅包含servlet引擎,还包括EJB容器,所以这样的服务器也叫做ApplicationServer这个是非开源的是收费的。很多中小型公司没有钱的话用不了这两种收费的服务器,也就书写不了EJB的代码,而且因为是非开源的,无法进行定制。

2: 代码移植性差

EJB的代码运行在weblogic这个服务器当中需要实现webLogic服务器当中一些特殊的接口,才可以进行运行,当这样的代码想往WebSphere中进行迁移时,就这个服务器当中并没有提供这样接口,就无法进行移植
总结:EJB是一个重量级的框架,运行环境苛刻,代码移植性差

二: 什么是Spring

Spring是一个轻量级的Java2EE解决方案,聚合众多优秀的设计模式

1: 轻量级

对于运行环境没有额外要求的

2: 常用服务器

开源的:Tomcat,Resion,Jetty
收费的:WebLogic,WebSphere

3:Spring是全套企业开发解决方案

我们之前的开发是分层的,Controller层,Service层解决业务,Dao层访问数据库,而当今众多优秀的框架中Struct2(解决的是控制器),Mybatis都是解决的某一层的问题,而spring是一个解决方案,可以解决JavaEE开发当中所有层的问题,可以通过SpringMVC解决控制层的问题,可以通过SpringAop解决Service层事务的控制和日志处理的问题,还可以通过将Hibernate,Mybatis进行整合解决Dao层的问题。经过分析,整个Spring来讲每一层都有对应的解决方案。所以他是一个完整的整个体系的解决方案

4: Spring为什么是轻量级的

Spring并不是发明了什么新技术,而是对众多优秀的设计模式的进行了高度的封装和整合,所有的特点都是基于一些列设计模式的整合来实现的

5: 四个核心设计模式

1):什么是设计模式

设计模式是面向对象设计过程中解决特定问题的经典代码,Java中一共 23种设计模式。

2):工厂模式

简单 vs 通用工厂模式 反射+配置

通过反射我们可根据类的全限定类名获取到子类的运行时对象也就是他的Class对象,通过这个Class对象我们就可以创建这个类的实例。

通过将类的全限定类名可以写入到properties配置文件当中,在这个配置文件当中,我们基于对配置的解析,将配置文件通过流的方式读取到property集合对象当中,然后将全限定类名匹配到反射当中完成对象的创建。:

小的配置文件当中,我们一般使用properties,properties类型的文件介绍,在maven项目当中,main->Java下面完成的是代码,main->resources下边专门放置配置文件,Properties配置文件语法有一个特殊的要求,必须采用key_value的形式进行组成,Key随便写,唯一就行,Properties集合可以用于存储properties文件的内容,是一种特殊map形式,可以通过getProperty属性进行获取Properties集合创建之后可以通过io流的方式将properties文件中的对象转换成集合,io流在我们整个Java操作过程当中是系统级资源,我们一般避免重复打开io,并且最好在程序启动的时候一次性读取完毕我们所有的内容。所以,我们采用静态代码快的方式来完成,流用完了,我们要关闭一下。

在反射工厂中采用一个反射机制+配置文件的方式可以彻底解决类的耦合的问题。这样替换的时候,不需要修改任何一行代码,直接增加一个类,实现对应的接口,然后修改配置文件中的内容既可以了,重启一下服务器就可以了。

在Service层当中也有耦合的情况,对于dao层对象的耦合,在工厂类当中,工厂设计的核心就是工厂类。在这个反射工厂当中要对一个对象进行解耦合,就需要在反射工厂类中添加一个对应的方法,通过一种反射+配置文件(流读取成集合)的方式进行解耦,有大量的冗余的代码。这样造成的工厂类中的方法是无穷无尽的。

对于spring来讲,最为核心的就是spring的工厂设计模式,作为spring的框架来讲,spring当中的工厂模式已经创建好了,spring当中的工厂类是ApplicationContext类,对应的配置文件是ApplicationContext.xml,spring的配置文件用的是xml,实现思路和我们工厂是一样的,只不过spring的工厂模式更为强大

第二章:第一个Spring程序

一:Spring依赖

当前我们都是基于maven进行jar包的管理,我们只需要引入相应的坐标就可以了。maven会自动为我们下载我们所以来的jar包和依赖的依赖进行下载下来,单纯的使用一个Spring的IOC的话,spring-context就够用了,我们使用的版本是spring-context 5.1.4release版本。

在这里插入图片描述
仅仅一个上下文就可以引入:
在这里插入图片描述

二: 配置文件

1:Spring配置文件的要求

任何一个框架都需要进行配置文件,Spring框架的配置文件,不要求具体的放置位置,在项目中都可以,也没有具体的配置名称,但是ApplicationContext.xml是Spring官方推荐的配置名称, 日后应用Spring框架时需要进行配置文件路径的配置,需要告诉Spring我们的配置文件的位置在哪里,在创建对象的时候有体现。

在Spring核心配置文件的根标签是一个Beans标签,在里边引入了Spring的一个默认的Schema(书写提示),方便进行获取标签中的xml语法书写提示

2: Spring核心API

ApplicationContext是Spring的核心Api就是指的spring的核心类,这是一个框架最核心的类。这是一个接口

核心类的作用和好处
作用:Spring当中最为核心的API就是提出的那个工厂ApplicationContext.java工厂主要作用是对象的创建。
好处:就是解耦合。

为什么spring进行设计的时候会把核心Api设计成接口
Spring设计工厂的时候会设计成接口,接口的最主要的目的是为了屏蔽实现的差异,提供规范性
作者考虑到这个工厂会应用到不同的开发环境(例如web与非web),为了屏蔽具体工厂类型之间的差异,Spring将工厂API设计成了接口,可以屏蔽具体工厂之间的差异,提供规范性。

Spring当中提供的常用的两种工厂类型
1:非web环境:ClassPathXmlApplicationContext (main junit)
2:web环境: XmlWebApplicationContext

补充说明:
1:以上是Spring中主要提供了两种类型的工厂
2:对于web环境,我们很熟悉,非web英勇主要指的是我们的,main函数和Junit单元测试,在main函数和Junit单元测试里边是不启动服务器的,在main函数和Junit当中和在web当中用到的工厂类是不一样的
3:查看继承关系,idea快捷键是ctrl+h,如果查看继承关系图当中没有这个类的话,是因为没有导入相关的web依赖。添加依赖的快捷键是<dep

为什么ApplicationContext是一个重量级资源
1:ApplicationContext工厂的对象会占用大量内存资源。
2:ApplicationContext工厂对象不会频繁的创建,一个应用只会有一个工厂对象。
3:ApplicationContext工厂一定是线程安全的。

重量级资源都具有以上三种特性:
1:区分一个资源或者对象的轻重量级的区别在于在内存中占用资源的多少,如果一个对象占用内存比较小,就是一个轻量级资源,重量级资源就是会占用大量内存
2:我们在这值得工厂是他的具体的实现类,主要指的是那两种的实现类,我们不会频繁的创建这两个的对象,一个应用只会创建一个工厂对象
3:在一个项目中只有一个这个对象,在一个项目中只会有一个这个对象实例,大家都会访问,那么就会产生比并发访问问题,但凡是这种重量级资源可以被多线程多用户访问,说明他们一定是线程安全的,一定做了锁的设置,它是线程安全的,可以被多线程并发访问

三: 程序开发

1:Spring核心配置文件

    <!--id属性:起个名字,要求:唯一-->
    <!--class属性:写全限定类名-->
    <bean id = "person" class = "com.pactera.spring.Person"/>

2:Java代码

        //获取spring的工厂对象,这里我们在单元测试当中指定的是非web工厂。
        ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        //getBean返回的是Object对象。
        Person person = (Person)clx.getBean("person");//这里边传入的是id值。
        System.out.println(person.getClass());

3:实现思路

1:创建Bean的类文件。
2:在ApplicationContext.xml文件中配置该对象属性;
3:使用spring原生工厂类获取对象;

补充说明:
1:Spring最大的特点就是为我们提供了工厂对象,而这个工厂创建对象起到了一个很好的解耦合的作用,Spring提供的工厂和我们写的工厂本质上是没有区别的,都是创建对象解耦合,对于Spring工厂和通用工厂模式是没有本质区别的
2:如果在Junit当中进行测试的话,应该使用ClassPathXmlApplicationContext这个类

4: 细节分析

1):什么叫做Bean或者组件

Spring工厂为我们创建对象,由spring为我们创建的对象叫做bean或者组件(Component)这些指的都是spring工厂为我们创建的对象

2):Spring工厂提供的一些方法

ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Person person = (Person)clx.getBean("person");
Person person = clx.getBean("person", Person.class);
Person person1 = clx.getBean(Person.class);
package com.pactera.spring;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring {
    /**
     * 研究目的:用于测试第一个spring的程序。
     * */
    @Test
    public void test03(){
        //获取spring的工厂对象,这里我们在单元测试当中指定的是非web工厂。
        ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Person person = (Person)clx.getBean("person");//这里边传入的是id值。
        System.out.println(person.getClass());
    }
    /**
     * 用于测试Spring工厂为我们提供的其他的方法。
     * 研究目的:Spring工厂对象核心方法getBean方法的重载。
     * */
    @Test
    public void test04(){
        ApplicationContext clx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        //这个重载的getBean的方法的好处在于不用进行强制类型转换了。
        Person person = clx.getBean("person", Person.class);
        System.out.println("person="+person);//person=com.pactera.spring.Person@2a4fb17b
        System.out.println("person="+person.getClass());//person=class com.pactera.spring.Person

        //这个重载的getBean的方法的好处在于不用进行强制类型转换了。
        //如果是这种方式:
            //<bean id = "person" class = "com.pactera.spring.Person"/>
            //<bean id = "person1" class = "com.pactera.spring.Person"/>
        //使用getBean(Person.class)会抛出异常,因为无法保证一个唯一性。
        //使用这个方法的时候必须保证spring配置文件中标签的唯一性。
        //Person person1 = clx.getBean(Person.class);//expected single matching bean but found 2
        /**
         * 在上边创建了一次Person的对象,将这个对象储存了起来,如果下边使用的话直接拿给我们
         * spring当中的当前这个对象只创建了一次,默认是单例设计模式。
         * */
        //System.out.println("person1="+person1);//person1=com.pactera.spring.Person@2a4fb17b

        //获取spring核心配置文件当中所有的id值;
        //---bean的定义:就是在spring核心配置文件当中的bean标签就叫做bean的定义
        //---bean定义的名字就是获取的是:id的值,返回的是是一个名字的数组。
        String[] beanDefinitionNames = clx.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName="+beanDefinitionName);
        }

        //根据类型获取spring配置文件当中的所有的id值
        //---获取工厂类型当中所有Person类的值。获取的都是id
        String[] beanNamesForType = clx.getBeanNamesForType(Person.class);
        for (String id : beanNamesForType) {
            System.out.println("id="+id);
        }

        //判断spring工厂中是否存在这个bean,参数传入的是id值;
        boolean b = clx.containsBeanDefinition("a");
        System.out.println("b="+b);

        //判断spring工厂中是否存在指定id的bean
        System.out.println(clx.containsBean("person"));
        //目前角度来讲这两个方法是没啥区别的。

    }
     /**
     * 研究目的:在spring核心配置文件中的bean标签当中值配置class,spring可以不可以创建对象。
     *        :可以
     *        :spring会不会为他默认分配一个id值呢?
     *        :会,默认是 全限定名+#+num,这个id是spring按照一定的算法生成的。这个num是因为在
     *          配置文件当中可能默认不止配置一次。
     * 应用场景:如果这个bean只使用一次,那么就可以省略id值,如果这个bean会被使用多次,或者被其他bean
     *          就需要进行设置。
     * 研究目的2:name属性在spring配置文件中的使用
     *         :为bean对象定义别名,小名。id是大名,是唯一标识,name属性定义的内容是别名,是小名,
     *           spring当中通过大名和小名都是找到这个bean对象的,可以获取到这个bean对象。
     * */
    @Test
    public void test05(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Person person = ctx.getBean(Person.class);
        System.out.println("person="+person);//person=com.pactera.spring.Person@128d2484
        String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName="+beanDefinitionName);//beanDefinitionName=com.pactera.spring.Person#0
        }
    }
    /**
     *研究目的2:name属性在spring配置文件中的使用
     *        :为bean对象定义别名,小名。id是大名,是唯一标识,name属性定义的内容是别名,是小名,
     *          spring当中通过大名和小名都是找到这个bean对象的,可以获取到这个bean对象。
     *应用场景:id和name有共性,他们相同的地方在于都能使用获取对象,相同的地方在于<bean id,class/>等效与
     * <bean name,class/>都可以定义一个对象。
     *       :区别在于别名可以定义多个,别名之间用,间隔就可以了使用任何一个别名都可以找到这个。,id只能定义一个,
     *         applicationContext.xml(xml语法导致的区别)这个文件当中id属性值命名的时候必须以字母开头,后面可以根字母、数字、下划线、连字符。
     *         name属性定义的时候比较灵活没有要求,可以明明在特殊场景下,比方说\的使用
     *         到了今天xml里的id属性的限制已经不存在了,已经没有这个约束了。
     *        :区别当中的类的 containsBeanDefinition()和containsBean;
     *
     *  */
    @Test
    public void test06(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Person person = (Person)ctx.getBean("p");
        System.out.println("person="+person);//person=com.pactera.spring.Person@2a4fb17b
        Person person1 = (Person)ctx.getBean("p",Person.class);
        System.out.println("person1="+person1);//person=com.pactera.spring.Person@2a4fb17b
        boolean p1 = ctx.containsBean("p1");//既能判断id也能判断name属性。
        System.out.println(p1);//true
        boolean p11 = ctx.containsBeanDefinition("p1");//只能判断id,不能判断name值。
        System.out.println(p11);//false

    }
}

3、Bean标签的特殊写法?

1.只配置class属性不配置id属性
<bean class =  "..."/>
//这样是可以的,spring会默认分配一个默认的id值,格式一般是全限定类名+特殊符号+num

3):Spring工厂实现思想

在这里插入图片描述
1、为什么我们应用了Spring工厂实现类,写了类搞了配置之后,就可以通过工厂创建对象呢?
当我们定义好类,在applicationContext.xml配置文件中配置好Bean标签之后,创建工厂对象就可以获取相应的配置文件中的对象配置,Spring在Junit或者main方法的程序入口执行之后,创建工厂类对象的时候,Spring会读取applicationContext.xml配置文件,读取之后获取每个bean标签的id和class,根据class采用反射的方式获取对象,并将引用地址赋值给id属性,随后可以通过Spring工厂对象中重载的getBean的方法进行获取对应的对象引用

2、 反射创建对象调用不调用这个类的构造方法呢?
一定会的,默认调用的是无参的构造方法。验证方法:在无参构造方法内部加入一个打印语句就可以了。虽然反射创建了对象,但是反射创建对象其实等效于new创建对象,底层也会调用new来创建对象。反射的底层调用的这个对象的无参构造方法
3、如果一个类的构造方法是私有的怎么办呢?
private修饰的内容只可以在本类中进行使用,如果构造器是private的,spring也能够创建对象,实际上底层通过反射调用私有的属性或者方法的,在反射中私有的内容也可以通过暴力反射的方式进行获取
4、在开发过程中,是不是所有的对象都会交由spring进行创建?
理论上来讲是这样的,但是有特例:实体对象(entity)这个对象中的属性是和数据库进行一一对应的,他的对象往往用于封装数据库中的数据,所以一般实体类对象都是交由mubatis,hibernate的持久层框架进行创建。

第三章:Spring整合日志框架

为什么Spring要和日志框架进行整合
1:Spring和日志框架整合之后,日志框架就可以在控制台中输出Spring框架运行时的一些重要的信息。方便我们了解spring程序的运行的过程,方便我们调试程序

Spring如何整合日志框:
1:Spring不同的版本对于框架的整合,不同的框架整合起来是有区别的,对于Spring1.2.3这是spring的早期版本,都是和与Commons-logging(Apache)
2:Spring4尤其是Spring5.x之后,默认的日志框架是logback log4j2这两个框架,默认的意思就是已经帮我们整合好了的。我们可以选择用logback,也可以选择用Log4J,log4j2和log4j也是不太一样,我们让spring整合log4j就好了

一: 引入log4j相关的jar包

//这个东西叫做日志门面,他的核心作用是把spring5默认集成的日志框架logback和log4j2进行干掉,进而来支持我们的log4j,详细的可以去日志课程中去看,引入这个依赖的目的就是为了让spring支持log4j.摒弃另两个日志框架。
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

二: 引入log4.properties

log4j.rootLogger=debug,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.Out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[frame] %d{yyyy-MM-dd HH:mm:ss,SSS} - %-4r %-5p [%t] %C:%L %x - %m%n

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/52261.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

贺利坚汇编课程笔记2 访问寄存器和内存

贺利坚汇编课程笔记2 访问寄存器和内存 文章目录贺利坚汇编课程笔记2 访问寄存器和内存0201 寄存器及数据存储CPU的组成寄存器是CPU内部的信息存储单元通用寄存器--以AX为例“字”在寄存器中的存储0202 mov 和 add指令0203 确定物理地址的方法物理地址8086CPU给出物理地址的方法…

pytorch模型网页部署——Flask

一、Flask用法 Flask是python的轻量级web框架&#xff0c;可用来做简单的模型部署。Flask的基本用法如下&#xff1a; step1&#xff1a;定义Flask类的对象&#xff0c;即创建一个基于Flask的服务器 step2&#xff1a;定义公开的路由及路由对应的调用函数 step3&#xff1a…

分享新零售系统商城小程序开发制作功能介绍_商城小程序开发好处

小编主要专注于新零售系统开发商城的领域&#xff0c;新零售系统开发商业模式有哪些&#xff1a; ① 多种销售模式&#xff1a;邀请有奖、销售业绩奖、团队业绩奖、区域分红&#xff0c;分销模式等。 ② 团队协作功能&#xff1a;立即邀约分销模式&#xff0c;清楚搜索直属代…

大型ERP生产制造管理系统源码

&#x1f353;&#x1f353;【淘源码】&#xff1a;一个专业提供高品质源码免费下载的资源共享平台&#x1f353;&#x1f353; &#x1f447;&#x1f447;&#x1f447;以下是博主整理的淘源码网站内大家都比较感兴趣的一些源码&#xff0c;需要源码学习的朋友可以私信博主哦…

Exception | ShardingSphere | ShardingSphere引发的IndexOutOfBoundsException

ShardingSphere引发的IndexOutOfBoundsException一、异常二、 原因三、解决方法四、总结一、异常 ### Error querying database. Cause: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 ### The error may exist in file [D:\JetBrains\Idea\workspace\zohe\bjxz\ru…

N-gram和NNLM语言模型

背景&#xff1a; one-hot:缺点&#xff1a;1.高维稀疏&#xff0c;2.不能体现句子中词的重要性&#xff0c;3.不能体现词与词之间的关系。 embedding:1.解决了高维稀疏 tf-idf&#xff1a;2.解决了one-hot中不能体现句子中词的重要性这一特点。 语言模型&#xff1a;3.解决不能…

【20221201】【每日一题】划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段&#xff0c;同一字母最多出现在一个片段中。 注意&#xff0c;划分结果需要满足&#xff1a;将所有划分结果按顺序连接&#xff0c;得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 思路&…

协程Part1-boost.Coroutine.md

首先&#xff0c;在计算机科学中 routine 被定义为一系列的操作&#xff0c;多个 routine 的执行形成一个父子关系&#xff0c;并且子 routine 一定会在父 routine 结束前结束&#xff0c;也就是一个个的函数执行和嵌套执行形成了父子关系。 coroutine 也是广义上的 routine&a…

网页JS自动化脚本(五)修改文字元素的内容和大小

今天的网页打开全是灰色的,顺便缅怀一下伟人,那么我我们今天定位换成按钮文字 window.onloadfunction(){var theElementdocument.querySelector("input[typesubmit]");theElement.value"爱我中华";theElement.style"font-size:25px"; }这一次的…

提分必练!中创教育PMP全真模拟题分享来喽

湖南中创教育每日五题分享来啦&#xff0c;“日日行&#xff0c;不怕千万里&#xff1b;常常做&#xff0c;不怕千万事。”&#xff0c;每日五题我们练起来&#xff01; 1、一个项目正在实行敏捷方法&#xff0c;在迭代过程中&#xff0c;团队成员互相合作&#xff0c;解决了一…

【机器学习】核函数

核方法 核技巧 非线性分类问题是指通过利用非线性模型才能很好地进行分类的问题。如图 111 所示&#xff0c;“●”表示正样本&#xff0c;“”表示负样本&#xff0c;显然无法用直线&#xff08;线性模型&#xff09;将正负样本正确分开&#xff0c;但是可以用一条椭圆曲线&…

记一次大事务优化历程(短信发送)

问题背景 短信服务数据库连接数告警&#xff0c;grafana查看数据库连接池被打满。 问题分析 在这段时间内&#xff0c;通过链路分析&#xff0c;发现最终调用第三方短信发送服务偶然耗时过长&#xff0c;分析了原有发送逻辑的代码&#xff0c;该实现在入口send处加了事务&am…

leetcode4. 寻找两个正序数组的中位数python_二分查找和递归(困难)

题目 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,3], nums2 [2] 输出&#xff1a;2.00000 解释…

第二证券|疫情扰动叠加需求不足,11月制造业PMI回落至48%

国家统计局周三称&#xff0c;11月&#xff0c;受国内疫情点多面广频发&#xff0c;世界环境更趋复杂严峻等多重要素影响&#xff0c;我国制造业收购经理人指数&#xff08;PMI&#xff09;较上月回落1.2个百分点至48.0%。制造业PMI接连两个月低于临界点&#xff0c;制造业下行…

第4季2:并口、MIPI、LVDS的简介

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、并口的简介 1、并口的含义 并口的含义&#xff0c;可以从AR0130或OV9712的原理图中形象地理解。 如下图所示&#xff0c;AR0130采用12bit的并口向SoC传输图像数据信息&#xff0c;而SoC和AR0130…

b站黑马JavaScript的Ajax案例代码——评论列表案例

目标效果&#xff1a; 1.在表单界面输入评论人和内容&#xff0c;点击发表评论按钮&#xff0c;可以在页面下面看到自己刚刚输入的内容 2.发表评论成功之后&#xff0c;用DOM对象的reset方法&#xff1a;重置表单为其默认值 e.g.1初始状态&#xff1a;【下面的评论内容会因为…

STC 51单片机48——数码管显示外部中断次数

#include<reg52.h> #include<intrins.h> #include "math.h" #define uchar unsigned char #define uint unsigned int #define ulong unsigned long //共阴字形码表【实验】数码管实验时&#xff0c;一定要将点阵模块跳针放到VCC上&#xff01;&…

【C语言】哈夫曼树,再来一次解剖

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录一、定义结构1.1 定义结点权值的数据类型1.2 定义单个结点信息1.3 字符指针数组中存储的元素类…

C++ Reference: Standard C++ Library reference: Containers: list: list: list

C官网参考链接&#xff1a;https://cplusplus.com/reference/list/list/list/ 公有成员函数 <list> std::list::list C98 默认构造函数 (1) explicit list (const allocator_type& alloc allocator_type()); 填充构造函数 (2) explicit list (size_type n,…

将整个网站变为黑白色

目录 效果&#xff1a; 代码&#xff1a; 兼容性写法&#xff1a; 原理&#xff1a; 效果&#xff1a; ps&#xff1a;实测淘宝也是用的这种方式&#xff0c;有兴趣可以去看看 代码&#xff1a; 使用方式就是找到根标签&#xff0c;将里面的两行代码放进去即可 html {filte…