【Java】spring

一、spring

spring是一个很大的生态圈,里面有很多技术。

其中最基础的是spring framework,主要的技术 是springboot以及springcloud。

1、spring framework

spring framework是spring生态圈中最基础的项目,是其他项目的基础。

1.1、核心概念

IoC控制反转:使用对象时,在程序方法中不要主动使用new创建对象,而是由外部提供对象,对象的控制权由程序转移到外部,这种思想叫做控制反转。这种思想的作用就是为了解耦。spring对IoC思想做了实现。spring提供了一个容器,称为IoC容器,用来充当IoC思想中的外部。

IoC管理的是service和dao之中的对象。

IoC容器负责对象的创建、初始化等一系列化工作,被创建和被管理的对象在IoC容器中被统称为bean

有时候,bean与bean之间有互相依赖的关系(比如service层的bean。肯定是要跟dao层的bean联系到一起的,service层的bean要创建一个dao层的bean),这时候,IoC容器会自动产生依赖。这个过程叫做DI(依赖注入)。

1.2、IoC容器配置

IoC容器主要用于解耦。

接口就是一个空壳,里面只写了规范,实现类才是接口的灵魂。

  • IoC容器配置

首先,导入springframework的坐标

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency></dependencies>

​ 导入依赖完毕后,idea已经识别到了坐标的导入,idea会在new file那里显示可以创建spring的配置文件。在resource之中创建一个就行了。把文件名取为applicationContext。接着,在applicateionContext里边配置bean。

在这里插入图片描述

​ 接下来就可以创建IoC容器,直接使用IoC容器来获取bean了(项目的准备工作已经创建了一个BookDao接口以及它的实现类)。IoC容器创建bean,实际上也是通过调用实现类的无参构造方法(下面会讲到)。

在这里插入图片描述

注意,bean的id不能重复。

由于BookService之中存在BookDao,在创建BookService的bean的时候需要创建BookDao的bean,所以需要在配置文件中的BookService之中使用属性表明BookService依赖于BookDao。

在这里插入图片描述

1.3、bean配置
1.3.1、单例化bean和非单例化bean

bean标签中,除了id和class以外,还可以再配置一个属性scope。默认是singleton(单例化),可以置为prototype实现非单例化。所谓单例和非单例,意思就是IoC容器是否会重复创建bean对象。假设有一个service层的接口EmpService,如果是单例,IoC容器只会在第一次用的时候创建出这个对象,之后一直保存这个对象(其实无影响,因为接口中的方法执行完毕后不会改变对象的字段),下一次用就从容器中取出该对象即可;如果是非单例对象,每一次用,IoC容器都会创建一个新的EmpService对象。

适合交给IoC管理的bean:单例对象(controller层、service层、dao层、工具对象);

不适合交给IoC管理的bean:非单例对象(entity/pojo中的实体)

1.3.2、实例化bean

bean是如何被创建出来的?spring程序启动时,

  • 第一种:构造器实例化bean

bean标签里id写给这个bean起的名字,class写bean所在的位置。当使用IoC获取bean对象时,IoC会直接使用无参构造方法构造一个对象。构造器实例化对象全部都是通过空参构造器进行构造的。一旦不存在无参构造方法,spring将抛出异常。

配置文件中写<bean>,会让spring自动使用无参构造方法对bean进行实例化。

  • 第二种是使用静态工厂构造对象

创建一个工厂类,在工厂类的方法中new出一个接口。主要作用是工厂类的方法中可以写逻辑。相应地,配置文件中将bean修改,需要写上对应两个属性表明要通过工厂中的哪个方法来创建bean。

不常用了,了解即可。

在这里插入图片描述

  • 第三种是使用实例工厂构造对象

把静态方法改成实例方法,同时必须要为工厂也创建一个bean交给IoC容器管理,这样IoC容器才能通过实例工厂创建出接口的bean。

不常用了,有兴趣了解即可。

在这里插入图片描述

  • 最重要的一种方式–通过FactoryBean构造对象

写一个工厂bean,这个bean一定要实现一个接口FactoryBean<>。然后重写方法返回bean对象和bean的接口class。配置文件中只需配置一个bean(指向FactoryBean),之后IoC容器就会到工厂中调用继承自FactoryBean的方法,创建出相应的接口对象。

在这里插入图片描述

问题来了,通过工厂bean来创建接口bean,接口bean默认就是单例的,工厂bean可以在<bean>中通过属性来控制单例/非单例,如果要让接口bean非单例,应该怎么做呢?只需要再实现一个方法即可。

1.3.3、bean的生命周期

生命周期:从创建到销毁的整个过程。

控制bean的生命周期:在bean创建后到销毁前做一些事情。

主要有两个方法,一个用在bean被初始化时,一个用在bean被销毁时。直接在bean里面写init和destroy方法就可以了。然后要在配置文件对应的bean标签里写属性init-method把初始化的方法名填进去,destroy-method把销毁的方法名填进去。

不过销毁的方法由于程序往往会极其快速关闭,IoC还没关呢程序就结束了。所以要使用IoC容器调用一个close()方法或者registerShutdownHook()。这样就会先把IoC容器关闭将bean销毁再结束程序。

在这里插入图片描述

另外,也可以通过实现接口,重写方法的方式来控制bean的生命周期。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在单例模式下,IoC容器被创建的时候,所有bean都会被创建出一个对象存储在IoC容器之中。非单例模式下,IoC容器被创建的时候,bean不会被实例化对象。只有主动调用IoC容器创建bean,bean才会被创建。所以,单例模式下,IoC容器创建完,所有bean的生命周期也就开始了。

在这里插入图片描述

总结,bean的生命周期主要如下:

  1. (单例)初始化IoC容器,执行bean的构造方法创建bean,执行属性注入,执行bean的钩子方法。
  2. (非单例)请求IoC容器创建bean,执行bean的构造方法,执行属性注入,执行bean的钩子方法。
  3. 使用bean执行业务操作
  4. 销毁IoC容器,所有bean执行钩子方法。
1.4、依赖注入

bean调用bean,或者bean使用数值字符串,需要使用依赖注入的方法来做。主要有四种方法:setter注入、构造器注入、自动装配(强大的方式)、集合注入

  • setter注入

    bean1的成员是bean2。bean1不能直接new出bean2,因为耦合度太高了。可以这样做:只把属性摆上去,使用setter来给属性传递引用,这样bean2的对象就有了。使用setter注入需要具备数值属性或者bean属性(bean属性要写一个setter方法)。然后在配置文件中配置就可以了。如此一来,当bean1创建的时候,会创建一个bean2,然后spring调用setter方法将bean2的引用传递给bean1的属性。

    xml文件要配置使用setter注入。在properties标签中,name属性是要被注入的成员的变量名(要给哪一个成员注入?)ref或者value是要注入的内容(要注入什么?)

在这里插入图片描述

  • 构造器注入

    bean1创建的时候,会调用bean1的构造方法,然后bean1的构造方法需要传入一个bean2。这时候spring会首先创建一个bean2,然后再创建bean1,这就是构造器注入。

    xml文件要配置使用构造器注入。==构造器注入非常严谨,第三方框架大量使用。==如果受控bean没有setter方法就必须使用构造器注入。

在这里插入图片描述

  • 依赖自动装配

    IoC自动根据类型、或名字等去容器中寻找与当前要引入的依赖成员。

    直接在bean标签里再加一个属性autowise即可。IoC识别到这个bean有依赖的时候,会自动在容器中寻找然后装配。这可以说是非常方便了。

    在这里插入图片描述

    然而也容易出现问题,如果要自动装配的bean不存在,必定报错;如果一个接口有两个实现类,就不能按照类型去自动装配了,而应该按照名称。

    自动装配只能应用于引用类型,不能对简单类型进行注入操作。自动装配的优先级低于setter注入和构造器注入,如果同时出现,自动装配失效。

  • 集合注入

    如果要注入的bean是集合/数组,应该如何注入呢?集合/数组中存放什么数据?

    在bean的标签体中写上属性标签,然后再在其中写入<array>/<list>/<set>/<map>/<properties>等标签中的一个,然后再在这些标签中使用<value>简单类型<ref>引用类型写入值。

在这里插入图片描述

1.5、使用xml文件加载properties文件
  • 开启context命名空间,在xml文件中写入一个标签<context>

  • 使用context命名空间加载properties文件

<!--使用命名空间加载properties文件。system-properties-mode="NEVER"是说让里面的键不要被识别成系统变量-->
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>
  • 在xml文件中的其他位置使用${}占位符,将properties的属性使用于配置文件中。

在这里插入图片描述

1.6、容器

加载容器,除了上述的方法以外,还有:

在这里插入图片描述

获取bean的方法还有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

IoC容器最早是由BeanFactory实现的,之后随着版本的迭代,功能的追加,才逐渐到ApplicationContext这一级。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.7、注解开发

在要定义成bean的controller、service、dao层的类中使用@Component,可以直接将这个类定义成bean。这时候不需要在配置文件中使用bean标签。但是配置文件中需要定义一个命名空间(就是上边的加载properties文件那个命名空间)。然后使用命名空间扫描对应包的所有类文件,通过反射哪些类添加了@Component注解,会将该类自动变成bean。

<--注意要在类上使用@Component注解 -->
<context:component-scan base-package="person.ghl"/>

为了便于区分,spring让@Component衍生出三种注解分别对应表现层、业务层、数据层:@Controller、@Service、@Repository。这三种注解的作用跟@Component的作用完全一样,只是名字不一样用于区分罢了。

@Controller、@Service、@Repository这三个注解后面加个括号写上id。也可以不加括号不写id,但是这样的话容器获取bean就必须使用类名的方式获取bean。而不能使用id的方法获取bean。

1.8、纯注解开发

spring的思想就是简化开发。使用注解确实大大简化了开发,但是还有一个东西存在——xml配置文件。

能不能让xml配置文件也简化一下呢?

可以用Java类来代替配置文件。

新建一个包叫做config包,里面新建一个SpringConfig类,这个类使用注解@Configuration,于是这个类就是一个配置文件了。**再次使用注解@ComponentScan(“bean所在包”)扫描bean。**如果想要加载多个包,在注解参数里使用数组{“包名”,“包名”,“包名”}来进行加载。

与此同时,获取IoC容器就不能通过加载xml配置文件创建IoC容器对象来获取了。而是通过读取IoC配置类来创建对象:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 注解方式配置bean

    在bean的类上@Scope:控制创建对象时创建单例对象还是非单例对象。(”prototype“)和(”singleton“)

    bean的生命周期:在bean的方法上加上注解@PostConstruct/@PreDestory。(注意是在方法上

  • 注解方式引入外部文件

    在SpringConfig类上加上注解@PropertySource(”外部文件名称“)来引入外部文件。有多个配置文件的时候使用数组。

  • 注解方式实现依赖注入

    首先是引用类型注入。

    注解方式实现引用类型依赖注入是使用自动装配的方式进行的。只需要在成员上添加注解@Autowired即可。IoC容器首选的装配方式是根据类型(接口的实现类的类型)进行装配。然而接口如果有多个的话肯定就报错了,因为IoC不知道要给接口装配哪一个实现类。如果bean的接口成员有多个实现类的话,可以在@Autowired下边在加上一个@Qualifier(”实现类bean的id“)来确定具体装配的实现类。

    接下来是基本类型注入

    只需要在bean的成员上添加@valuie(”值“)注解就可以了。但是这样有点儿多余,直接让成员等于不就好了。所以要换一种写法,一般是使用外部文件给@value注入值。所以最后就是这样写:@value(”${}“)

  • 第三方bean配置

    第三方的bean可不会允许在类名上方加注解。

    所以只能写一个方法,在方法中new出要获取的第三方的对象,给这个对象设置好属性,然后将对象返回。

    最后,在这个方法上添加一个注解@Bean,表示当前方法的返回值是一个bean,可以在IoC容器中找到的。

    ==这个方法要写在一个新的类XXConfig里面,不能直接写在SpringConfig里面,不然耦合度太高了。==但是如果写在新的类里边,就不能识别到了。所以,在SpringConfig类名上边还要再加一个注解@import({XX.class})

  • 第三方依赖注入

    如果第三方的bean需要一些依赖,也是需要手动set一下。

    基本类型,第三方bean的Config类中字段写所有想要注入的成员,并使用注解@value(”${}“)。之后在方法里使用这些字段为第三方bean对象set值。

    引用类型注入,这个比较特殊:不需要使用任何注解,直接在方法参数中写想要注入的bean即可。IoC会使用自动装配为形参传递引用。

    最后,将自定义的Config类在SpringConfig类中引入:使用@Import注解引入。

总结

spring的核心作用就是管理bean。

==只需要将实现类注解成bean就可以了接口不用注解成bean。==使用的时候只使用接口。因为spring会根据接口自动获取实现类注入接口。

2、spring整合mybatis

首先,再来看看mybatis原生开发的核心代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

mybatis的核心对象是SqlSessionFactory。这个对象应该成为一个bean被spring管理。这个对象是由mybatis配置文件(数据源信息和mapper所在包信息)得来的。这个配置文件里边大部分信息其实都可以交给框架进行管理(除了数据源和mapper所在包需要手动配置)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

mybatis为了和spring整合,专门写了一个包用于spring整合mybatis。这个包里最核心的就是SqlSessionFactoryBean类。只需要new出一个SqlSessionFactoryBean对象,然后再用setter设置其数据库连接池的属性(需要导入druid包,将druid数据库连接池也配置成bean),就没有必要再写mybatis配置文件了。

除了基本的spring-context包以及mybatis包以及mysql驱动包以外,需要导入三个包(spring操作数据库的包、mybatis用于整合入spring的包、druid数据源的包)。

导包完毕之后,如何整合?

其实很简单,新建一个MybatisConfig类,写两个方法让IoC托管mybatis的两个核心配置bean(一个bean负责数据库连接,一个bean用于代理开发包扫描),这样mybatis的核心配置就搞定了。不用写核心配置文件了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后:

  • pojo:表的实体类这个不必多说。

  • dao层:写接口并实现数据访问逻辑(注解开发或者代理开发)。让这个接口成为bean让IoC容器接管(之后如果需要用到这个接口的实现类进行注入,IoC容器会寻找mybatis的两个配置bean然后反射给这个接口提供实现类,完成注入)。应当注意,如果没有整合mybatis,该接口在其他地方是无法完成自动装配的,因为我们没有写该接口的实现类,实现类是mybatis通过动态代理技术创建的。

  • service层:写dao层对应的service接口并且写接口的实现类。让这个实现类成为bean让IoC容器接管。这个实现类中有dao层的接口对象,使用自动装配完成注入。然后写业务逻辑就可以了。

关键就在于将mybatis的核心配置文件变成两个bean并让IoC容器接管。然后就跟我之前学的mybatis操作没有什么区别了。甚至dao层的接口都不用写成bean,mybatis整合入spring,那么它创建的代理对象必定也是已经注册成bean的了,自动装配的时候spring通过接口在IoC容器中寻找实现类,是可以找到的。

3、AOP

AOP即面向切面编程。它的作用是在不惊动原始设计的基础上为程序进行功能加强。

核心概念:

  • 连接点:将所有的方法都视为“连接点”
  • 切入点:想要追加功能的连接点方法称为切入点
  • 通知:追加的功能
  • 通知类:通知写在通知类里边
  • 切面:描述通知与切入点之间的关系
AOP入门案例

导入坐标:由于spring-aop的坐标在导入spring-context的时候就已经导入了,所以不需要导入。只需要导入aspectjweaver的坐标就可以了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接着,写一个定义一个切面(一个类)。

然后,切面中定义切入点和通知的关系。切面中**写一个私有的void无参数方法,用于绑定切入点方法,并且上边添加一个注解@Pointcut("execution(void 切入方法所在位置)")。**然后,写一个通知方法(这个通知方法就是用来写逻辑的),通知方法要和切入点绑定在一起,所以通知方法上边也要添加一个注解@Before(“私有返回void无参数方法名()”)。

最后,切面上边要写注解@Component@Aspect,让IoC能够识别为bean且能识别为切面。且在SpringConfig类名上边要加一个注解@EnableAspectJAutoProxy让IoC开启识别切面的模式。

配置完毕,切入点方法会实现通知的功能但是不会影响原本切入点方法的设计。

AOP工作流程
  1. IoC容器启动

  2. 读取所有切面配置中的切入点

  3. 初始化bean,确定所有bean对应的类中方法是否匹配到切入点

    bean匹配失败,创建bean的原始对象,调用原始对象的方法

    bean匹配成功,创建bean原始对象的代理对象,调用通知方法和原始对象的方法实现功能

AOP切入点

切入点绑定方法上的注解@PointCut()的参数是一个切入点表达式。

切入点表达式的标准格式:

@PointCut(execution(修饰符 返回值 方法(参数) 异常名))
//修饰符和异常名都可以省略
//其实这个东西就是用来精准匹配的嘛

可以使用通配符描述切入点表达式(切入点表达式中的每一个东西都可以替代):

  • *:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀匹配符出现
  • ..:多个连续的任意符号,可以独立出现,常用于简化包名和参数的书写
  • +:专用于匹配子类类型
    • 比如excution(* *..*Service+.*(..)),修饰符任意,返回值任意,包名任意,类名以Service结尾,必须是其子类,方法任意,参数任意。

一般来说,空方法绑定的切入点方法是接口里的方法(当然实现类中的也可以),但是绑定了接口方法那所有的实现类也可以使用了。

AOP通知

通知类型有三种:

  • @Before:在切入点方法之前嵌入通知,通知方法可以传入一个JoinPoint对象,用于获得切入点方法的信息

  • @After:在切入点方法之后嵌入通知,通知方法可以传入一个JoinPoint对象,用于获得切入点方法的信息

  • @Around:在切入点方法之前和之后嵌入通知

    @Around的使用和before以及after有一些不同。使用@around会默认把切入点方法覆盖。如果不想覆盖,需要给通知方法传入ProceedingJoinPoint对象(继续连接点),然后在Around型通知方法中调用ProceedingJoinPoint对象的proceed方法继续连接点方法的操作。值得注意的是:如果这样调用了原始连接点方法的操作,而且原始连接点方法有返回值,必须让通知方法有一个Object的返回值,然后proceedJoinPoint.proceed()返回的值再返回就可以了(不用强转,就直接返回一个object就可以,之后再在业务中进行强转)。而且由于无法预知连接点方法是否会抛异常,所以通知方法也要抛异常。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • @AfterThrow:连接点抛出异常后嵌入通知

一般来说,最好用的就是@Around,因为它可以实现@After和@Before的效果。

proceedJoinPoint就是切入点方法,所以它可以获取连接点的信息。先用getSigature获取执行的签名信息,再用sigature.getDeclaringTypeName()获取包类名,用sigature.getName()获取方法名。可以使用proceedJoinPoint.getArgs获取连接点方法的参数(获取到之后可以修改!!真正的暗箱操作)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5、spring事务

事务:要么同时成功,要么同时失败,不会出现成功了一半这种现象。成功了就提交,中间出现异常了就回滚到原始状态。spring事务能够保证数据层或者业务层中一系列的数据库操作同时成功或者同时失败。

三步开启事务:

  • 事务管理注解不仅可以写在接口方法上,也可以写在接口/类上,表示当前接口/类的所有方法都开启事务。写在接口上是为了降低耦合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 在jdbc配置类中除了配置druid数据库连接池为bean外,还要再配一个第三方bean。这个第三方bean要注入dataSource,需要写在参数上。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 在SpringConfig类中添加注解,表示要开启事务驱动。

在这里插入图片描述

事务管理员、事务协调员以及事务传播行为

打个比方,银行转账业务。转账业务是在service中的,转账业务需要调用dao层中两个方法:入账和出账。

转账业务就是一个事务管理员,入账和出帐就是事务协调员。

而事务传播行为,就是设置事务管理员以及事务协调员之间关系的。当传播属性是REQUIRED时,事务协调员的事务会加入事务管理员的事务。当传播属性时REQUIRE_NEW时,事务协调员不会加入事务管理员的事务。具体见下表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

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

相关文章

Http---HTTP 请求报文

1. HTTP 请求报文介绍 HTTP最常见的请求报文有两种: GET 方式的请求报文POST 方式的请求报文 说明: GET: 获取web服务器数据POST: 向web服务器提交数据 2. HTTP GET 请求报文分析 HTTP GET 请求报文效果图: GET 请求报文说明: ---- 请求行 ---- GET / HTTP/1.1 # GET请…

华为鸿蒙开发适合哪些人学习?

随着鸿蒙系统的崛起&#xff0c;越来越多的人开始关注鸿蒙开发&#xff0c;并希望成为鸿蒙开发者。然而&#xff0c;鸿蒙开发并不适合所有人&#xff0c;那么哪些人最适合学习鸿蒙开发呢&#xff1f;本文将为您总结鸿蒙开发适合的人群。 一、具备编程基础的人 学习鸿蒙开发需要…

账号多、用户咨询量大无法及时回复?「互动管理」助力高效经营!

随着互联网行业不断向纵深发展&#xff0c;内容形态与营销场景也更加多元化。越来越多的品牌跑步入场&#xff0c;深耕社媒营销&#xff0c;建立多平台营销矩阵&#xff0c;借助社媒平台的全域态势助力品牌增长。 据云略《2023品牌新媒体矩阵营销洞察报告》显示&#xff0c;目前…

多任务数据采集

进程&#xff1a;操作系统中资源分配的基本单位 线程&#xff1a;使用进程资源处理具体任务 一个进程中可以有多个线程&#xff1a;进程相当于一个公司&#xff0c;线程是公司里面的员工。 一 多线程 多线程都是关于功能的并发执行。而异步编程是关于函数之间的非阻塞执行&…

数据结构和算法-红黑树(定义 性质 查找 插入 删除)

文章目录 红黑树的定义和性质为什么要发明红黑树&#xff1f;红黑树怎么考总览红黑树的定义实例&#xff1a;一颗红黑树练习&#xff1a;是否符合红黑树的要求一种可能的出题思路补充概念&#xff1a;节点黑高 红黑树的性质 红黑树的查找红黑树的插入实例小结与黑高相关的理论 …

【Java】网络编程-TCP回显服务器代码编写

前面我们讲了基于UDP的网络编程 UDP回显服务器 UDP字典服务器 下面我们来讲基于TCP的回显服务编写 1、服务器 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; impo…

opencv入门到精通——OpenCV4.1.2之性能衡量与优化方法

目录 目标 使用OpenCV衡量性能 OpenCV中的默认优化 在IPython中衡量性能 更多IPython魔术命令 性能优化技术 目标 在图像处理中&#xff0c;由于每秒要处理大量操作&#xff0c;因此必须使代码不仅提供正确的解决方案&#xff0c;而且还必须以最快的方式提供。因此&#…

1270. 数列区间最大值(线段树求区间最大)

题目&#xff1a; 1270. 数列区间最大值 - AcWing题库 输入样例&#xff1a; 10 2 3 2 4 5 6 8 1 2 9 7 1 4 3 8输出样例&#xff1a; 5 8 代码&#xff1a; #include <cstdio> #include <iostream> #include <climits>//INT_MIN头文件using namespace s…

【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…

2023年终总结 | 四平八稳

年度回顾 年度关键词&#xff1a;四平八稳 百科解读&#xff1a;形容物体放置的平稳或言行稳当&#xff1b;也指做事但求无过&#xff0c;不思进取。 我在写这篇文章就在思考用什么关键词来描述我过去这一年&#xff0c;似乎这一年没有特别让我特别惊喜的事情&#xff0c;无论是…

【实训项目】消费账单记录小程序

1.项目说明 背景&#xff1a; 着网络技术的不断发展&#xff0c;人们的消费观念在不断变化&#xff0c;消费手段也变得错综复杂。很多人都在困扰&#xff0c;钱到底花在了那里。 目的&#xff1a; 为了解决很多人的钱花在哪了的困扰&#xff0c;我们组决定制作一个消费账单…

【原理图PCB专题】原理图图纸锁定/解锁与PCB文件加密方式

在工作中我们会遇到需要冻结原理图进行评审和加密图纸防止被他人盗用的需求。那么在OrCAD Capture中如何对图纸进行锁定与解锁,如何在Allegro中对PCB工程进行加密呢? 原理图锁定与解锁 打开原理图,在图纸中单击右键,选择lock/unlock就可以进行锁定与解锁。 锁定时图纸图…

xml 可扩展标记语言

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

【CF闯关练习】—— 900分段

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;cf闯关练习 &#x1f48c;其他专栏&#xff1a; &#x1f534;每日一题 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓…

java定义三套场景接口方案

一、背景 在前后端分离开发的背景下&#xff0c;后端java开发人员现在只需要编写接口接口。特别是使用微服务开发的接口。resful风格接口。那么一般后端接口被调用有下面三种场景。一、不需要用户登录的接口调用&#xff0c;第二、后端管理系统接口调用&#xff08;需要账号密…

loki-日志

一、loki Github ELK虽然功能丰富&#xff0c;但规模复杂&#xff0c;资源占用高&#xff0c;操作苦难&#xff0c;很多功能往往用不上&#xff0c;loki 受 prometheus 启发的水平可扩展、高可用、多租户日志聚合系统&#xff0c;它的设计非常经济高效且易于操作&#xff0c;…

使用【OpenI启智平台】进行模型训练

前言 启智平台OpenI是一个人工智能开源开放平台&#xff0c;提供免费GPU算力可以进行模型训练。模式是git进行项目管理&#xff0c;可以创建调试任务调试代码以及保存镜像&#xff0c;创建训练任务训练模型&#xff0c;也提供推理和评测&#xff0c;我没用过就不讲述了。后来我…

Sketch软件免费中文版在线使用教程及下载安装指南

什么是Sketch&#xff1f; Sketch是一款专为设计量身定制的矢量绘图软件&#xff0c;广泛应用于UI/UX设计和原型制作。 Sketch由荷兰Bohemiancoding公司开发&#xff0c;并于2010年首次发布。当时&#xff0c;AdobePhotoshop、AdobeIlustrator等主流设计工具虽然功能强大&…

MySQL-1

1 数据库基础概念 Data数据 对客观事物的符号表示&#xff0c;如图形符号、数字、字母等&#xff0c;数据是数据库中存储的基本对象。2. DB数据库数据库(Database,简称DB)的定义&#xff1a;“按照数据结构来组织、存储和管理数据的仓库” 3. DBMS数据库管理系统概念&#xff…

Qt WebAssembly开发环境配置

目录 前言1、下载Emscripten SDK2、 安装3、环境变量配置4、QtCreator配置5、运行示例程序总结 前言 本文主要介绍 Qt WebAssembly 开发环境的配置。Qt for Webassembly 可以使Qt应用程序在Web上运行。WebAssembly&#xff08;简称Wasm&#xff09;是一种能够在虚拟机中执行的…