当前位置: 首页 > news >正文

4-spring篇

ApplicationContext refresh的流程

12个步骤

  1. prepareRefresh
    这一步创建和准备了Environment对象,并赋值给了ApplicationContext的成员变量
    要理解Environment对象的作用

  2. obtainFreshBeanFactory
    ApplicationContext 里面有一个成员变量,Beanfactory
    bean的来源有 xml配置文件,配置类,扫描

  3. prepareBeanFactory

  4. postProcessBeanFactory
    是一个空实现,留给子类实现的

  5. invokeBeanFactoryPostProcessors
    bean工厂后处理器

  6. registerBeanPostProcessors
    注册bean后处理器 对bean的创建过程中,各种功能的增强

  7. initMessageSource
    MessageSource实现国际化的

  8. initApplicationEventMulticaster
    应用事件广播器

  9. onRefresh
    空实现,留给子类实现

  10. registerListeners
    事件监听器

  11. finishBeanFactoryInitialization

  12. finishRefresh

spirng bean 生命周期

  1. 阶段一:处理名称,检查缓存
    • 1.1 把别名解析成实际名称,再进行后续处理
    • 1.2若要factoryBean本身,需要使用&名称获取
    • 1.3singletonobjects是一级缓存,放单例成品对象
    • 1.4singletonFactories是三级缓存,放单例工厂
    • 1.5earlySingletonObjects是二级缓存,放单例工厂的成品,可称为提前单例对象

2.阶段二:检查父工厂
- 1.父子容器的bean名称可以重复
- 2.优先找子容器的bean,找到了直接返回,找不到继续到父容器找

3.阶段三:检查DependsOn

4.阶段四:按Scope 创建bean
* 1.创建singleton
* 2.创建prototype
* 3.创建其他scope

  1. 阶段五:创建bean

    • 1.创建bean实例 @Autowired,唯一带参构造,默认构造
    • 2.依赖注入 @Autowired @value@Resource,ByName ByType 精确指定
    • 3.初始化- Aware接口处理,@PostConstruct,InitializingBean,initMethod
    • 4.登记可注销bean
  2. 类型转换

  3. 销毁bean

spring 事务失效的几种场景及原因

1.抛出检查异常导致事务不能正确回滚
spring默认情况下,只对,runtimeException,和Error这两个异常及其子类会回滚。如果是检查异常,是不会回滚的
解决方案:
@Transactional(rollbackFor = Exception.class)

2.业务方法内自己try-cach 异常导致事务不能正确回滚
原因:事务通知只有捉到了目标抛出的异常,才能进行后续的回滚处理,如果目标自己处理掉异常,事务通知无法知悉
解决1:异常原样抛出
解决2:手动设置TransactionStatus.setRollbackOnly()

3.aop切面顺序导致事务不能正确回滚
原因:事务切面优先级最低,但如果自定义的切面优先级和他一样,则还是自定义切面在内层,这时若自定义切面没有正确抛出异常,那外层的事务切面没有办法感知异常。
解法:同情况2

4.@Transactional 一定要放在public的方法上,否则无效
原因:spring为方法创建代理、添加事务通知、前提条件都是该方法是public的

5.父子容器导致的事务失效
原因:子容器的扫描范围过大,把未加事务配置的service扫描进来
解法1:各扫描各的,不要图简便
解法2:不要用父子容器,所有bean放在同一个容器

6.调用本类方法导致传播行为失效
原因:本类方法调用不经过代理,因此无法增强
解法1:依赖注入自己(代理)来调用
解法2:通过AopContext拿到代理对象,来调用
解法3:通过CTW,LTW实现功能增强

  1. @Transactional没有保证原子行为
    原因:事务的原子性仅涵盖insert,update,delete,select…for update语句,select方法并不阻塞
    8.@Transactional方法导致的synchronized失效
    原因:synchronized保证的是目标方法的原子性,环绕目标方法的还有commit等操作,他们并未处于sync块内

解法1:synchronized 范围阔大至代理方法调用
解法2:使用select…for update替换select

SpringMVC 执行流程

初始化阶段:
1.在Web容器第一次用到DispatcherServlet的时候,会创建其对象并执行init方法
2.init方法会创建Spring Web容器,并调用容器refresh方法

3.refresh过程中会创建并初始化SpringMVC中的重要组件,例如MultipartResolver,HandlerMapping,HandlerAdapter,HandleExceptionResolver,ViewResolver等
4.容器初始化后,会将上一步初始化好的重要组件,赋值给DispatcherServlet的成员变量,留待后用

匹配阶段:
1.用户发送的请求统一到达的前端控制器DispatcherServlet
2.DispatcherServlet遍历所有HandlerMapping,找到与路径匹配的处理器对象

  • 1.HandlerMapping有多个,每个HandlerMapping会返回不同的处理器对象,谁先匹配,返回谁的处理器。其中能识别@RequestMapping的优先级最高
  • 2.对应@RequestMapping的处理器是HandlerMethod,它包含了控制器对象和控制器方法信息
  • 3.其中路径与处理器的映射关系在HandlerMapping初始化时就会建立好
    3.将HandlerMethod连同匹配到拦截器,生成调佣链对象HandlerExecutionChain返回
    4.遍历HandlerAdpter处理器适配器,找到能处理HandlerMethod的适配器对象,开始调用

执行阶段:
1.执行拦截器preHandle
2.由HandlerAdapter(适配器)调用HandlerMethod(处理器)

  • 1.调用前处理不同类型的参数
  • 2.调用后处理不同类型的返回值
    3.第二步没有异常
  • 1.返回ModelAndView
  • 2.执行拦截器postHandle方法
  • 3.解析视图,得到View对象,进行视图渲染
    4.第2步有异常,进入HandlerExceptionResolver异常处理流程
    5.最后都会执行拦截器的afterCompletion方法
    6.如果控制器方法标注了@ResponseBody注解,则在第二步,就会生成json结果,并标记ModelAndView已处理,这样就不会执行第3步的试图渲染

spring注解大全

1.事务
@EnableTransactionManagement 启用声明式的事务
@Transactional
2.核心
@Order 多个bean控制执行顺序
3.切面
@EnableAspectAutoProxy 启用Aop自动代理
以下这些不是spring的注解,是第三方spring-aspects的注解
@Aspect //标记该类为切面类
@Before
@After
4.组件扫描和配置类的
@Component
@Controller
@Service
@Repository
@ComponentScan
@Conditional 组件扫描时,做条件判断 bean加载时,做条件判断
@Configuration
@Bean
@Import
@Lazy 标注在类上,表示类是延迟实例化和初始化的
@PropertySource 加载外部properties文件
5.缓存
@EnableCaching
@CacheConfig
@CacheEvict
@CachePut
@Cacheable
@Caching
6.依赖注入
@Autowired
@Qualifier 依赖注入时,同一类型有多个bean,可以用名字进行区分
@Value
7.mapping
@Mapping
@RequestMapping 建立请求路径和控制器方法的映射关系
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
8.rest
@RequestBody 请求体里面的json数据,转换成java数据
@ResponseBody,将java数据,转换成json数据放到响应体
@ResponseStatus控制响应的状态
@RestController
是一个组合注解 组合了: @Controller 和 @ResponseBody
9.统一处理
@ControllerAdvice
@ExceptionHandler
@RestControllerAdvice
10.参数
@RequestHeader 请求头的信息
@CookieValue
@PathVariable 获取路径参数
@RequestParam 获取请求参数 ?后的,或者表单的
11.转换和格式化
@DateTimerFormat
@NumberFormat
@InitBinder
12.validation bean的校验
@Validated
13 scope
@ApplicationScope
@RequestScope
@SessionScope
@ModelAttribute
@RequestAttribute
@SessionAttribute
@SessionAttributes
14.ajax
@CrossOrigin 解决ajax的跨域问题
spring-boot注解
1.@EnableConfigurationProperties 启用
2.@ConfigurationProperties bean 值的初始化
3.@Configuration!!!!!!!!!!!!!!!!!!!!

注意:

    1. 配置类其实就相当于一个工厂。
    1. @bean注解的方法,就是工厂方法 @Bean,不支持方法重载,如果有多个重载方法,仅有一个能入选为工厂方法。参数越多,权重越高
	  	@Beanpublic Bean1 bean1(){System.out.println("new bean2.....");return new Bean1();}@Beanpublic Bean1 bean1(@Value("${java.class.version}") String a){System.out.println("a:"+a);return new Bean1();} @Bean //这个参数有2个权重高public Bean1 bean1(@Value("${java.class.version}") String a,@Value("${JAVA_HOME}") String b){System.out.println("bena1 a:"+a+" b:"+b);return new Bean1();}
    1. 注意点3:@Configuration 默认会为标注的类生成代理,其目的是保证@Bean 方法互相调用时,仍然能保证其单例特性
  • 4.注意点4:@Configuration中如果含有BeanFactory 后处理器,则实例方法会导致MyConfig提前创建,造成其依赖注入失败。

//	问题复现
public class TestConfiguration {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.registerBean("myConfig",Myconfig.class);context.refresh();System.out.println(context.getBean(Myconfig.class));System.out.println();}@Configuration()static class Myconfig{@Beanpublic Bean1 bean1(){System.out.println("bean1().....");return new Bean1();}@Beanpublic Bean2 bean2(){System.out.println("bean2().....");return new Bean2();}@Value("${java.class.version}")private String version;@Bean	//	这个实现了BeanFactory后处理器public  MapperScannerConfigurer configurer(){MapperScannerConfigurer scanner = new MapperScannerConfigurer();scanner.setBasePackage("aaa");return scanner;}@Beanpublic Bean3 bean3(){System.out.println("Bean3():"+version);		//	这个version无法获取了,因为提前有后处理器在这个Configuration类里面,所以这个Myconfig提前创建了,所以他的功能没有增强。@Value 这些增强没有了。return new Bean3();}class Bean3{}class Bean1{}class Bean2{}}
}
  • 解决办法:
      1. bean工厂后处理器在配置类中定义,就用 static 修饰
      1. 如果想在@Bean修饰的方法依赖注入,用局部变量就可以,用参数注入,尽量不要用成员变量来注入
    @Beanpublic Bean3 bean3(@Value("${java.class.version}") String version){System.out.println("Bean3():"+version);		//	这个version无法获取了,因为提前有后处理器在这个Configuration类里面,所以这个Myconfig提前创建了,所以他的功能没有增强。@Value 这些增强没有了。return new Bean3();}
    

15.@Import 放在 @Configuration配置类上
import5种用法

public class TestImport {public static void main(String[] args) {//	普通容器GenericApplicationContext context = new GenericApplicationContext();//后处理器AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());//注册beancontext.registerBean(Myconfig.class);//refreshcontext.refresh();for (String name : context.getBeanDefinitionNames()) {System.out.println(name);}}@Configuration
//    @Import(bean1.class)          //  1.引入单独bean
//    @Import(OtherConfig.class)    //  2.引入一个配置类
//    @Import(MySelector.class)      //   3.通过MySelector实现了引入多个类 ,MySelector本身不会注册成bean
//    @Import(MyRegister.class)      //   4.通过MyRegister注册器引入多个类,MyRegister本身不会注册成bean@Import(MySelector2.class)      //   5.通过MySelector2注册器实现了DeferredImportSelector引入多个类,MySelector2本身不会注册成beanstatic class Myconfig{}static class MySelector2 implements DeferredImportSelector{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{Bean3.class.getName(),Bean4.class.getName()};}}static class MyRegister implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {registry.registerBeanDefinition("bean5", BeanDefinitionBuilder.genericBeanDefinition(Bean5.class).getBeanDefinition());}}static class MySelector implements ImportSelector{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{Bean3.class.getName(),Bean4.class.getName()};}}@Configurationstatic class OtherConfig{@Beanpublic Bean2 bean2(){return new Bean2();}}static class bean1{}static class Bean2{}static class Bean3{}static class Bean4{}static class Bean5{}
}

16.@Import-DeferredImportSelector


public class TestDeferredImport {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();beanFactory.setAllowBeanDefinitionOverriding(false);    //  不允许同名定义覆盖AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);context.registerBean(Myconfig.class);context.refresh();System.out.println(context.getBean(MyBean.class));}//  1.同一个配置类中,@Import 先解析 @Bean 后解析//  2.同名定义,默认后面解析的会覆盖前面解析的//  3.不允许覆盖的情况下,如何能让Myconfig(主配置类)的配置优先?(虽然覆盖方式能解决)//  4.@Import 导入的类MyDeferredImportSelector 实现了DeferredImportSelector 最后工作,可以简单认为先解析@Bean,再解析@Import@Configuration@Import(MyDeferredImportSelector.class)static class Myconfig{  //  主配置 -程序员自己配置的@Beanpublic MyBean myBean(){return new Bean1();}}static class MyDeferredImportSelector implements DeferredImportSelector{@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{OtherConfig.class.getName()};}}@Configurationstatic class OtherConfig{   //  从属配置 - 自动配置@Bean@ConditionalOnMissingBeanpublic MyBean myBean(){return new Bean2();}}interface MyBean{}static class Bean1 implements MyBean {}static class Bean2 implements MyBean {}
}

Springboot 自动配置

@SpringbootApplication 是一个组合注解这个注解包含下面这些

  • @SpringBootConfiguration 标记了这个类其实就是个配置类,没什么特别的
  • @ComponentScan 用来在组件扫描时进行排除,也会排除自动配置类
  • @EnableAutoConfiguration是一个组合注解
    • @AutoConfigurationPackage -用来记住扫描的起始包
    • @Import(AutoConfigurationImportSelector.class)可以分离主从配置。用来加载META-INF/spring.factories中的自动配置类

Spring中有哪些设计模式

1.Spring中的Singleton Bean 是否是单例模式?

  • spring中的singleton bean 并非实现了单例模式,singleton bean 只能保证每个容器内,想通的id的bean单例
  • spirng中也有单例模式

2.Spring中的Builder 构建器模式
他的主要亮点有三处:
1.较为灵活的构建产品对象
2.在不执行最后的build方法前,产品对象都不可用
3.构建过程采用链式调佣,看起来比较爽
spring中体现Builder模式的地方:

  • org.springframework.beans.factory.support.BeanDefinitionBuilder
  • org.springframework.web.util.UriComponentsBuilder
  • org.springframework.http.ResponseEntity.HeadersBuilder
  • org.springframework.http.ResponseEntity.BodyBuilder

3.Spirng中的Factory Method 工厂方法模式

4.Spring 中的 Adapter 适配器模式
把一套接口转换成调用者所期望的接口

5.Spring 中的 Composite 组合器模式

6.spring 中的 Decorator 装饰器模式
对目标对象做功能增强,避免子类继承进行功能可扩展

7.spring中的 Proxy 代理模式
对目标对象的控制和访问

8.Spring 中的 Chain of Responsibility 责任链模式
拦截器

9.Spirng 中的 Observer 观察者模式

ApplicationListener 监听器
ApplicationEventMulticaster 发送器
ApplicationEvent 事件对象

10.Spring 中的Strategy 策略模式

11.Spring 中 的 Template Method 模板方法

  • 大部分以Template 命名的类, 如jdbcTemplate TransactionTemplate
  • 很多以 Abstract命名的类,如AbstractApplicationContext

创建代理要点:

  • 要完全理解循环依赖,需要理解代理对象的创建时机
  • 掌握proxyFactory创建代理的过程,理解Advisor,Advice,Ponitcut 与 Aspect
  • 掌握AnnotationAwareAspectJAutoProxyCreator筛选Advisor合格者,创建代理的过程
    proxyFactory的基本使用
    总结:
  • Advisor 是最基本的切面,Aspect 切面对应一个或多个Advisor切面
  • 最基本的Advice 是MethodInterceptor,其他的Advice最终都将适配为MethodInterceptor
  • 创建代理的方式:
    • 实现了用户自定义接口,采用jdk动态代理
    • 没有实现用户自定义接口,采用cglib代理
    • 设置了setProxyTargetClass(true),同意采用cglib代理
  • 切面、切点、通知等不会被代理
  • AnnotationAwareAspectJAutoProxyCreator 调用时机:创建阶段、依赖注入阶段、初始化阶段
//	编程方式
public class APP64_2 {public static void main(String[] args) {//  aspect = (通知)advice + pointcut(切点),一个切面类可能有一个多个通知方法//  advisor = 更细粒度的切面,包含一个通知和切点ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setTarget(new Target1());  //  设置目标对象//  添加通知:MethodInterceptor 是环绕通知
//        proxyFactory.addAdvice((MethodInterceptor) invocation -> {
//            try {
//                System.out.println("befor...");
//                return invocation.proceed();    //  调用目标
//            } finally {
//                System.out.println("atfer....");
//            }
//        });//  设置切点AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression("execution(* foo())");proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation -> {try {System.out.println("before1...");return invocation.proceed();    //  调用目标} finally {System.out.println("after1...");}}));proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation -> {try {System.out.println("before2...");return invocation.proceed();    //  调用目标} finally {System.out.println("after2...");}}));proxyFactory.addInterface(I1.class);
//        proxyFactory.setProxyTargetClass(true);I1 proxy = (I1) proxyFactory.getProxy();  //  创建代理对象System.out.println(proxy.getClass());proxy.foo();proxy.bar();}interface I1{void foo();void bar();}static class Target1 implements I1{@Overridepublic void foo() {System.out.println("target1 foo");}@Overridepublic void bar() {System.out.println("target1 bar");}}}
//	使用注解的方式
package org.springframework.aop.framework.autoproxy;public class APP64_1 {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();context.registerBean("aspect1",Aspect1.class);context.registerBean("aspect2",Aspect2.class);context.registerBean("aspect3",Aspect3.class);context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class); //  自动代理后处理器context.refresh();AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);//	这里是演示一下 自动代理后处理器 是怎么创建代理对象的
//		wrapIfNecessary 是protected 为了实验可以成功,把这个当前这个类放在了同包下测试Object o = creator.wrapIfNecessary(new Target1(), "target1", "target1");System.out.println(o.getClass());	//	是代理类Object b = creator.wrapIfNecessary(new Aspect1(), "aspect1", "aspect1");System.out.println(b.getClass());	//	Aspect1是aop的基础设施,所有就不用代理对象}@Aspectstatic class Aspect1{@Around("execution(* com.libin..autoproxy..foo())")   //  对应成一个Advisor切面public Object around(ProceedingJoinPoint pjp) throws Throwable {try {System.out.println("aspect1 around before");return pjp.proceed();} finally {System.out.println("after....");}}}@Aspectstatic class Aspect2{   //  对应成两个Advisor切面@Before("execution(* foo())")public void before()  {System.out.println("aspect2 before");}@After("execution(* foo())")public void after()  {System.out.println("aspect2 after");}}@Aspectstatic class Aspect3{@Before("execution(* bar())")   //  对应成一个Advisor切面public void around()  {System.out.println("aspect3 before...");}}static class Target1 {public void foo() {System.out.println("target1 foo");}}static class Target2 {public void bar() {System.out.println("target1 bar");}}}

set循环依赖

一级缓存,限制bean 在BeanFactory中只存一份,实现 Singleton scope

循环依赖图示,只有一级缓存的情况下
在这里插入图片描述

二级缓存解决:但是解决不了循环依赖里面有代理的情况 。
a先生成半成品代理对象,后依赖注入,但是b注入的时候是半成品的a,不是成品的代理对象a
在这里插入图片描述
三级缓存
在这里插入图片描述

构造方法循环依赖

在这里插入图片描述
解决思路:
在这里插入图片描述
第一种方式解决构造方法循环依赖


public class App60_1 {static class A{private static final Logger log = LoggerFactory.getLogger("A");private B b;//	使用@Lazy 让B后面再加载使用代理方式public A(@Lazy B b){log.debug("A(B b){}",b.getClass());this.b =b;}@PostConstructpublic void init(){log.debug("init()");}}static class B{private static final Logger log = LoggerFactory.getLogger("B");private A a;public B(A a) {log.debug("B({})",a);this.a = a;}@PostConstructpublic void init(){log.debug("init()");}}public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();context.registerBean(A.class);context.registerBean(B.class);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.refresh();System.out.println(context.getBean(B.class));}}

第二种方式解决构造方法循环依赖

public class App60_1 {static class A{private static final Logger log = LoggerFactory.getLogger("A");private ObjectFactory<B> b;	//	构造方法注入 ObjectFactory 工厂或者他的子类ObjectProperty,可以延迟bean加载public A(ObjectFactory<B> b){log.debug("A(B b){}",b.getClass());this.b =b;}@PostConstructpublic void init(){log.debug("init()");}}static class B{private static final Logger log = LoggerFactory.getLogger("B");private A a;public B(A a) {log.debug("B({})",a);this.a = a;}@PostConstructpublic void init(){log.debug("init()");}}public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();context.registerBean(A.class);context.registerBean(B.class);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.refresh();System.out.println(context.getBean(B.class));System.out.println(context.getBean(A.class).b.getObject());}}

第三种方式

public class App60_1 {static class A{private static final Logger log = LoggerFactory.getLogger("A");private Provider<B> b;// 注入 Provider 需要pom依赖//<dependency>//   <groupId>org.aspectj</groupId>//  <artifactId>aspectjweaver</artifactId>// <version>1.9.19</version>
//        </dependency>public A(Provider<B> b){log.debug("A(B b){}",b.getClass());this.b =b;}@PostConstructpublic void init(){log.debug("init()");}}static class B{private static final Logger log = LoggerFactory.getLogger("B");private A a;public B(A a) {log.debug("B({})",a);this.a = a;}@PostConstructpublic void init(){log.debug("init()");}}public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();context.registerBean(A.class);context.registerBean(B.class);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.refresh();System.out.println(context.getBean(A.class).b.get());System.out.println(context.getBean(B.class));}}

第四种方式:用@Scope方式,不推荐,就不看了了

相关文章:

4-spring篇

ApplicationContext refresh的流程 12个步骤 prepareRefresh 这一步创建和准备了Environment对象&#xff0c;并赋值给了ApplicationContext的成员变量 要理解Environment对象的作用 obtainFreshBeanFactory ApplicationContext 里面有一个成员变量&#xff0c;Beanfactory b…...

提升 Web 应用程序的性能:如何使用 JavaScript 编写缓存服务

缓存是一种重要的优化技术&#xff0c;用于加速数据访问和降低服务器负载。缓存存储经常访问的数据&#xff0c;以便在需要时可以快速检索。在本文中&#xff0c;我们将探索如何使用简单的数据结构在 JavaScript 中编写缓存服务。 编码缓存服务的第一步是定义将用于访问缓存的…...

供应商绩效管理指南:挑战、考核指标与管理工具

管理和优化供应商绩效既关键又具有挑战性。要知道价格并不是一切&#xff0c;如果你的供应商在商定的价格范围内向你开具发票&#xff0c;但服务达不到标准或货物不合格&#xff0c;你也无法达到节约成本的目标。 供应商绩效管理可以深入了解供应商可能带来的风险&#xff0c…...

干货文稿|详解深度半监督学习

分享嘉宾 | 范越文稿整理 | William嘉宾介绍Introduction to Semi-Supervised Learning传统机器学习中的主流学习方法分为监督学习&#xff0c;无监督学习和半监督学习。这里存在一个是问题是为什么需要做半监督学习&#xff1f;首先是希望减少标注成本&#xff0c;因为目前可以…...

信箱|邮箱系统

技术&#xff1a;Java、JSP等摘要&#xff1a;在经济全球化和信息技术飞速发展的今天&#xff0c;通过邮件收发进行信息传递已经成为主流。目前&#xff0c;基于B/S&#xff08;Browser/Server&#xff09;模式的MIS&#xff08;Management information system&#xff09;日益…...

JS数组拓展

1、Array.from Array.from 方法用于将两类对象转为真正的数组&#xff1a; 类似数组的对象,所谓类似数组的对象&#xff0c;本质特征只有一点&#xff0c;即必须有length属性。 因此&#xff0c;任何有length属性的对象&#xff0c;都可以通过Array.from方法转为数组 和 可遍历…...

一道很考验数据结构与算法的功底的笔试题:用JAVA设计一个缓存结构

我在上周的笔试中遇到了这样一道题目&#xff0c;觉得有难度而且很考验数据结构与算法的功底&#xff0c;因此Mark一下。 需求说明 设计并实现一个缓存数据结构: 该数据结构具有以下功能&#xff1a; get(key) 如果指定的key存在于缓存中&#xff0c;则返回与该键关联的值&am…...

(10)C#传智:命名空间、String/StringBuilder、指针、继承New(第10天)

内容开始多了&#xff0c;慢品慢尝才有滋味。 一、命名空间namespace 用于解决类重名问题&#xff0c;可以看作类的文件夹. 若代码与被使用的类&#xff0c;与当前的namespace相同&#xff0c;则不需要using. 若namespace不同时&#xff0c;调用的方法&#xff1a…...

基于Jetson Tx2 Nx的Qt、树莓派等ARM64架构的Ptorch及torchvision的安装

前提 已经安装好了python、pip及最基本的依赖库 若未安装好点击python及pip安装请参考这篇博文 https://blog.csdn.net/m0_51683386/article/details/129320492?spm1001.2014.3001.5502 特别提醒 一定要先根据自己板子情况&#xff0c;找好python、torch、torchvision的安…...

MySQL存储引擎详解及对比和选择

什么是存储引擎&#xff1f; MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术&#xff0c;你能够获得额外的速度或者功能&#xff0c;从而改善…...

【推拉框-手风琴】vue3实现手风琴效果的组件

简言 在工作时有时会用到竖形手风琴效果的组件。 在此记录下实现代码和实现思路。 手风琴实现 结构搭建 搭建结构主要实现盒子间的排列效果。 用flex布局或者其他布局方式将内容在一行排列把每一项的内容和项头用盒子包裹&#xff0c; 内容就是这一项要展示的内容&#xf…...

滑动窗口最大值:单调队列

239. 滑动窗口最大值 难度困难2154收藏分享切换为英文接收动态反馈 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例…...

负载均衡算法

静态负载均衡 轮询 将请求按顺序轮流地分配到每个节点上&#xff0c;不关心每个节点实际的连接数和当前的系统负载。 优点&#xff1a;简单高效&#xff0c;易于水平扩展&#xff0c;每个节点满足字面意义上的均衡&#xff1b; 缺点&#xff1a;没有考虑机器的性能问题&…...

C语言数组二维数组

C 语言支持数组数据结构&#xff0c;它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据&#xff0c;但它往往被认为是一系列相同类型的变量。 数组的声明并不是声明一个个单独的变量&#xff0c;比如 runoob0、runoob1、…、runoob99&#xff0c;而是…...

7年测试工程师,裸辞掉17K的工作,想跳槽找更好的,还是太高估自己了....

14年大学毕业后&#xff0c;在老师和朋友的推荐下&#xff0c;进了软件测试行业&#xff0c;这一干就是7年时间&#xff0c;当时大学本来就是计算机专业&#xff0c;虽然专业学的一塌糊涂&#xff0c;但是当年的软件测试属于新兴行业&#xff0c;人才缺口比较大&#xff0c;而且…...

企业为什么需要做APP安全评估?

近几年新型信息基础设施建设和移动互联网技术的不断发展&#xff0c;移动APP数量也呈现爆发式增长&#xff0c;进而APP自身的“脆弱性”也日益彰显&#xff0c;这对移动用户的个人信息及财产安全带来巨大威胁和挑战。在此背景下&#xff0c;国家出台了多部法律法规&#xff0c;…...

重回利润增长,涪陵榨菜为何能跑赢周期?

2022年消费市场持续低迷&#xff0c;疫情寒冬之下&#xff0c;不少食品快消企业均遭遇严重的业绩下滑&#xff0c;但一年里不断遭遇利空打击的“榨菜茅”涪陵榨菜&#xff0c;不仅安然躲过“酸菜劫”、走出“钠”争议&#xff0c;而且顺利将产品价格提起来&#xff0c;并在寒冬…...

这6个高清图片素材库,马住,马住~

网上找的图片素材清晰度不够&#xff0c;版权不明确怎么办。看看这几个可商用图片素材网站&#xff0c;解决你的所有图片需求&#xff0c;高清无水印&#xff0c;赶紧马住&#xff01; 1、菜鸟图库 美女图片|手机壁纸|风景图片大全|高清图片素材下载网 - 菜鸟图库 ​ 网站素材…...

绝对零基础的C语言科班作业(期末模拟考试)

编程题&#xff08;共10题&#xff1b; 共100.0分&#xff09;模拟1&#xff08;输出m到n的素数&#xff09;从键盘输入两个整数[m,n], 输出m和n之间的所有素数。 输入样例&#xff1a;3&#xff0c;20输出样例&#xff1a;3 5 7 11 13 17 19 &#xff08;输出数据之间用空格间…...

注解开发定义bean

注解开发定义bean 使用Component定义bean在核心配置文件中通过组件扫描加载bean&#xff0c;需要指定扫描包的范围 当然也可以使用Component的衍生注解&#xff0c;可以更加形象的表示 纯注解的开发模式 使用java类来代替了以前的 配置文件&#xff0c;在java类中&#xff…...

剑指 Offer 19. 正则表达式匹配

摘要 剑指 Offer 19. 正则表达式匹配 请实现一个函数用来匹配包含. 和*的正则表达式。模式中的字符.表示任意一个字符&#xff0c;而*表示它前面的字符可以出现任意次&#xff08;含0次&#xff09;。在本题中&#xff0c;匹配是指字符串的所有字符匹配整个模式。例如&#x…...

CSS——学成在线案例

&#x1f353;个人主页&#xff1a;bit.. &#x1f352;系列专栏&#xff1a;Linux(Ubuntu)入门必看 C语言刷题 数据结构与算法 HTML和CSS3 目录 1.案例准备工作 2.CSS属性书写顺序&#xff08;重点&#xff09; 3.页面布局整体思路 4.头部的制作​编辑 5.banner制作…...

元数据的类型

元数据通常分为三种类型&#xff1a;业务元数据、技术元数据和操作元数据。这些类别使人们能够理解属于元数据总体框架下的信息范围&#xff0c;以及元数据的产生过程。也就是说&#xff0c;这些类别也可能导致混淆&#xff0c;特别是当人们对一组元数据属于哪个类别或应该由谁…...

LEAP模型的能源环境发展、碳排放建模预测及不确定性分析

LEAP&#xff08;Long Range Energy Alternatives Planning System/ Low emission analysis platform&#xff0c;长期能源可替代规划模型&#xff09;是一种自下而上的能源-环境核算工具&#xff0c;由斯德哥尔摩环境研究所和美国波士顿大学联合研发。该模型与情景分析法紧密结…...

C# Task详解

1、Task产生背景 Task出现之前&#xff0c;微软的多线程处理方式有&#xff1a;Thread→ThreadPool→委托的异步调用&#xff0c;虽然也可以基本业务需要的多线程场景&#xff0c;但它们在多个线程的等待处理方面、资源占用方面、线程延续和阻塞方面、线程的取消方面等都显得比…...

Blob分析+特征

Blob分析特征0 前言1 概念2 方法2.1 图像采集2.2 图像分割2.3 特征提取3 主要应用场景&#xff1a;0 前言 在缺陷检测领域&#xff0c;halcon通常有6种处理方法&#xff0c;包括Blob分析特征、Blob分析特征差分、频域空间域、光度立体法、特征训练、测量拟合&#xff0c;本篇博…...

4EVERLAND 的 IPFS Pinning 服务:4EVER Pin

我们很高兴地宣布 4EVERLAND Storage 的一个令人兴奋的补充&#xff0c;即 4EVER Pin。什么是 4EVER Pin&#xff1f;您可能已经知道星际文件系统或IPFS是一个分布式存储网络&#xff0c;来自世界各地的计算机组成节点共享数据。通常&#xff0c;在IPFS中获取一条数据时&#x…...

activiti整合springBoot其他操作

如果单纯使用activiti进行流程的自动控制&#xff0c;是可以实现的。但是通常我们都需要结合自定义的表&#xff0c;便于在流程执行中更加清晰的看到每一个流程实例节点的具体信息。关联自定义表与activiti表才能完成真正的业务 BusinessKey关联 // 定义businessKey Test pub…...

深度探索C++预编译头机制

深度详见预编译头&#xff0c;以vs编译器实现的预编译头管理为例 预编译头是为了节省庞大的编译时间&#xff0c;采取的一种方法&#xff1b;C标准并没有规定如何实现预编译头机制&#xff1b;因此其具体实现方式由编译器供应商自行决定。 下面就以VS中观测的结果为例进行说明…...

Leaflet基础入门教程(一)

leaflet是一个前端的轻量的gis框架,为什么说它轻量呢。因为相比于传统的“庞大的”GIS框架比如openlayers和mapbox,leaflet不仅代码体积小,而且API构成也极为简单。是GIS行业小白入门级别学习的最好的框架,没有之一。 那么话不多说我们首先来学习一下如何使用leaflet搭建一…...

php标签wordpress/阿里云域名注册流程

对L的配二阶方阵有特征值则矩阵必有特征值为( )。设&#xff0c;内核&#xff0c;则.( )选用行编需要无线广播通信系统的工作方式为( )。设四阶方阵的秩为2&#xff0c;置方执行则其伴随阵的秩为2.( )设为矩阵&#xff0c;式进.( )若向量空间为的子空间&#xff0c;对L的配则.(…...

外贸网站布局/谷歌商店官网

文章目录1.判断单链表是否带环为什么快指针走2步&#xff0c;慢指针走1步一定可以相遇如果快指针每次不是走两个节点&#xff0c;是否还会相遇2.找入环点1.判断单链表是否带环 给定一个单链表&#xff0c;如果带环返回true&#xff0c;不带环返回false. 这里设了两个指针&…...

济南网站建设公司有哪些/百度seo快速见效方法

OpenVAS漏洞扫描基础教程之创建用户 OpenVAS管理服务 默认情况下&#xff0c;OpenVAS服务仅创建了一个名为admin的用户&#xff0c;而且是管理员用户&#xff08;拥有最高的权限&#xff09;。如果想要其它客户端登陆的话&#xff0c;不可能都以管理员身份访问&#xff0c;否则…...

微信审批小程序/seo是什么服务

本文为美国俄亥俄州立大学&#xff08;作者&#xff1a;Christine Ann Bryant&#xff09;的硕士论文&#xff0c;共97页。 本文研究了在单接收机数据速率有限的情况下&#xff0c;实现多输入单输出&#xff08;MISO&#xff09;合成孔径雷达&#xff08;SAR&#xff09;空时自…...

临沂企业自助建站/外贸建站

图解TCP数据报结构以及三次握手&#xff08;非常详细&#xff09; TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的通信协议&#xff0c;数据在传输前要建立连接&#xff0c;传输完毕后还要断开连接…...

手机网站app制作/天津百度推广电话号码

修复此问题 禁用内核调试&#xff0c;在 Visual Studio 中调试。- 或 -使用内核调试器而不是 Visual Studio 进行调试。- 或 -在内核调试器中禁用用户模式异常。在当前会话中禁用内核调试 在命令提示处&#xff0c;键入&#xff1a; 复制代码 Kdbgctrl.exe -d对所有会话禁用内核…...