当前位置: 首页 > 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…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…...