第一章:SpringBoot基础入门

news2024/11/23 3:04:30

第一章:SpringBoot基础入门

1.1:SpringSpinrBoot

  1. Spring能做什么

    • Spring的能力
      在这里插入图片描述

    • Spring的生态

      网址:https://spring.io/projects/spring-boot

      覆盖了:Web开发、数据访问、安全控制、分布式、消息服务、移动开发、批处理等。

    • Spring5重大升级

      1. 响应式编程
        在这里插入图片描述

      2. 内部源码设计

        基于Java8的一些新特性。

  2. 为什么用SpringBoot

    Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run"。能快速创建出生产级别的Spring应用。

    • SpringBoot的优点

      1. Create stand-alone Spring applications:创建独立的Spring应用。
      2. Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files):内嵌Web服务器。
      3. Provide opinionated 'starter' dependencies to simplify your build configuration:自动starter依赖,简单构建配置
      4. Automatically configure Spring and 3rd party libraries whenever possible:自动配置Spring以及第三方功能。
      5. Provide production-ready features such as metrics, health checks, and externalized configuration:提供生产级别的监控、健康检查以及外部化配置。
      6. Absolutely no code generation and no requirement for XML configuration:无代码生成、无需编写XML

      SpringBoot是整合Spring技术栈的一站式框架,SpringBoot是简化Spring技术栈的快速开发脚手架。

    • SpringBoot的缺点

      1. 迭代快,需要时刻关注变化。
      2. 封装太深,内部原理复杂,不容易精通。
  3. 时代背景

    • 微服务

      James Lewis and Martin Fowler (2014) 提出微服务完整概念。https://martinfowler.com/microservices/

      ​ 微服务是一种架构风格。一个应用拆分为一组小型服务。每个服务运行在自己的进程内,也就是可独立部署和升级。服务之间使用轻量级HTTP交互。服务围绕业务功能拆,可以由全自动部署机制独立部署,去中心化,服务自治。服务可以使用不同的语言、不同的存储技术。

    • 分布式
      在这里插入图片描述

      1. 分布式的困难

        远程调用、服务发现、负载均衡、服务容错、配置管理、服务监控、链路追踪、日志管理、任务调度。

      2. 分布式的解决

        SpringBoot + SpringCloud
        在这里插入图片描述

  4. 如何学习SpringBoot

    • 官网文档架构
      在这里插入图片描述
      在这里插入图片描述

      查看版本新特性:https://github.com/spring-projects/spring-boot/wiki#release-notes
      在这里插入图片描述

1.2:SpringBoot2入门

需求:浏览器发送/hello请求,响应Hello, Spring Boot 2

  1. 创建maven工程

    IDEA创建一个新的工程boot_helloworld_01

  2. 引入依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    
  3. 创建主程序

    package com.wang;
    
    // 主程序类。@SpringBootApplication:这是一个SpringBoot应用
    @SpringBootApplication
    public class MainApplication {
        public static void main(String[] args) {
            SpringApplication.run(MainApplication.class, args);
        }
    }
    
  4. 编写业务

    package com.wang.controller;
    
    @RestController
    public class HelloController {
    
        @RequestMapping("/hello")
        public String handle01() {
            return "Hello, Spring Boot 2!";
        }
    }
    
  5. 测试

    直接运行mian方法,浏览器访问http://localhost:8080/hello
    在这里插入图片描述

  6. 修改配置

    resources文件夹下创建application.properties文件

    server.port=8888
    

    修改了上面配置,重新启动项目,http://localhost:8080/hello访问成功。

  7. 简化部署

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    

    重新打成一个jar包在cmd窗口下也能运行。
    在这里插入图片描述
    在这里插入图片描述

1.3:了解自动配置原理

  1. SpringBoot特点

    • 依赖管理

      1. 父项目做依赖管理

        几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制。

        <!-- 依赖管理,自己工程引入的依赖 -->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.4.RELEASE</version>
        </parent>
        
        <!-- 它的父项目 -->
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.3.4.RELEASE</version>
        </parent>
        
      2. 开发导入starter场景启动器

        • 见到很多spring-boot-starter-**就是某种场景。

        • 只要引入starter,这个场景的所有常规需要的依赖我们都自动引入。

        • SpringBoot所有支持的场景:

          https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

        • 见到*-spring-boot-starter:第三方为我们提供的简化开发的场景启动器。

        • 所有场景启动器最底层的依赖

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter</artifactId>
              <version>2.3.4.RELEASE</version>
              <scope>compile</scope>
          </dependency>
          
      3. 无需关注版本号,自动版本仲裁

        • 引入依赖默认都可以不写版本。
        • 引入非版本仲裁的jar,要写版本号。
      4. 可以修改默认版本

        查看spring-boot-dependencies里面规定当前依赖的版本用的key

        <!-- 举例:修改mysql的版本依赖 -->
        <properties>
            <mysql.version>5.1.43</mysql.version>
        </properties>
        
    • 自动配置

      1. 自动配好Tomcat

        • 引入Tomcat依赖

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-tomcat</artifactId>
              <version>2.3.4.RELEASE</version>
              <scope>compile</scope>
          </dependency>
          
        • 配置Tomcat

      2. 自动配置好SpringMVC

        • 引入SpringMVC全套组件。
        • 自动配好SpringmVC常用组件(功能)。
      3. 自动配好Web常见功能

        • SpringBoot帮我们配置好了所有Web开发的场景。
      4. 默认的包结构

        • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描出来。

        • 无序以前的包扫描配置。

        • 想要改变扫描路径:@SpringBootApplication(scanBasePackages = "com")或者@ComponentScan("com.wang")指定扫描路径

          @SpringBootApplication(scanBasePackages = "com.wang")
          // 等同于
          @SpringBootConfiguration
          @EnableAutoConfiguration
          @ComponentScan("com.wang")
          
      5. 各种配置拥有默认值

        • 默认配置最终都是映射到某个类上。
        • 配置文件的值最终会绑定在每个类上,这个类会在容器中创建对象。
      6. 按需加载所有自动配置项

        • 非常多的starter
        • 引入了哪些场景这个场景的自动配置才会开启。
        • SpringBoot所有的自动配置功能都在spring-boot-autoconfigure包里面。
  2. 容器功能

    • 添加组件

      先创建两个实体类:UserPet

      package com.wang.bean;
      
      // 用户
      public class User {
          private String name;
          private Integer age;
          private Pet pet;
      
          // 省略空参、全参构造、get/set方法、toString方法
      }
      
      package com.wang.bean;
      
      // 宠物
      public class Pet {
          private String name;
      
          // 省略空参、全参构造、get/set方法、toString方法
      }
      
      1. @Configuration

        Full模式与Lite模式:

        • 配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断。
        • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式。
        // Configuration使用示例
        package com.wang.config;
        
        // 配置类里面使用@Bean标注在方法给容器注册组件,默认也是单实例的。
        // 配置类本身也是组件
        // proxyBeanMethods =  false:代理bean的方法
        	// Full(proxyBeanMethods =  true): 【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
        	// Lite(proxyBeanMethods =  false): 【每个@Bean方法被调用多少次返回的组件都是新创建的】
        	// 组件依赖必须使用Full模式默认。其他默认是否Lite模式
        
        // 告诉SpringBoot这一个配置类 == 配置文件
        @Configuration(proxyBeanMethods =  false)
        public class MyConfig {
        
            // 给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
            @Bean
            public User user01() {
                User zhangsan =  new User("zhangsan", 18);
                // User组件依赖了Pet组件
                zhangsan.setPet(tomcatPet());
                return zhangsan;
            }
        
            @Bean("tom")
            public Pet tomcatPet() {
                return new Pet("tomcat");
            }
        }
        
        // Configuration测试代码
        package com.wang;
        
        @SpringBootApplication
        public class MainApplication {
        
            public static void main(String[] args) {
                // 1. 返回我们IOC容器
                ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
                
                // 2. 查看容器里面的组件
                String[] names = run.getBeanDefinitionNames();
                for (String name: names) {
                    System.out.println(name);
                }
        
                // 3.从容器中获取组件
                Pet tom01 = run.getBean("tom", Pet.class);
                Pet tom02 = run.getBean("tom", Pet.class);
                System.out.println("组件:" + (tom01 == tom02));
                MyConfig bean = run.getBean(MyConfig.class);
                System.out.println(bean);
                
                // 4. 组件是否单例
                User user1 = bean.user01();
                User user2 = bean.user01();
                System.out.println(user1 == user2);
        
                User user01 = run.getBean("user01", User.class);
                Pet tom = run.getBean("tom", Pet.class);
                System.out.println("用户的宠物: " + (user01.getPet() == tom));
            }
        }
        
      2. @Import()

        @Import({User.class, DBHelper.class})给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名。

      3. @Conditional

        条件装配:满足Conditional指定的条件,则进行组件注入。

        // 条件转配示例
        package com.wang.config;
        
        @Configuration
        // 容器中存在tom组件时,才给类中的bean进行组件注入
        @ConditionalOnBean(name = "tom")
        public class MyConfig {
        
            @Bean
            public User user01() {
                User zhangsan =  new User("zhangsan", 18);
                zhangsan.setPet(tomcatPet());
                return zhangsan;
            }
        
            @Bean("tom22")
            public Pet tomcatPet() {
                return new Pet("tomcat");
            }
        }
        
        // 测试条件装配
        package com.wang;
        
        @SpringBootApplication()
        public class MainApplication {
            public static void main(String[] args) {
                ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        
                boolean tom = run.containsBean("tom");
                System.out.println("容器中Tom组件:" + tom);
                boolean user01 = run.containsBean("user01");
                System.out.println("容器中user01组件:" + user01);
                boolean tom22 = run.containsBean("tom22");
                System.out.println("容器中tom22组件:" + tom22);
            }
        }
        
    • 原生配置文件引入

      1. @ImportResource

        <!--创建beans.xml配置文件-->
        <bean id="haha" class="com.wang.bean.User">
            <property name="name" value="zhangsan"></property>
            <property name="age" value="18"></property>
        </bean>
        
        <bean id="hehe" class="com.wang.bean.Pet">
            <property name="name" value="tomcat"></property>
        </bean>
        
        package com.wang.config;
        
        // 添加@ImportResource注解
        @ImportResource("classpath:beans.xml")
        public class MyConfig { .... }
        
        // 测试IOC容器是否存在haha和hehe组件
        package com.wang;
        
        @SpringBootApplication
        public class MainApplication {
            public static void main(String[] args) {
                ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        
                boolean haha = run.containsBean("haha");
                System.out.println("haha: :" + haha);
                boolean hehe = run.containsBean("hehe");
                System.out.println("hehe::" + hehe);
            }
        }
        
    • 配置绑定

      如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用:

      # application.properties文件中 
      mycar.brand=BYD
      mycar.price=100000
      
      1. @ConfigurationProperties

        package com.wang.bean;
        
        // 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
        @Component
        @ConfigurationProperties(prefix = "mycar")
        public class Car {
            private String brand;
            private Integer price;
        	
            // 省略get/set方法、toString方法
        }
        
      2. @EnableConfigurationProperties+@ConfigurationProperties

        package com.wang.bean;
        
        @ConfigurationProperties(prefix = "mycar")
        public class Car { ..... }
        
        package com.wang.config;
        
        @Configuration
        // 1.开启Car配置绑定功能
        // 2.把这个Car这个组件自动注册到容器中
        @EnableConfigurationProperties(Car.class)
        public class MyConfig { ... }
        
  3. 自动配置原理入门

    • 引导加载类自动配置

      @SpringBootConfiguration
      @EnableAutoConfiguration
      @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
      public @interface SpringBootApplication { ... }
      
      1. @SpringBootConfiguration

        // 代表当前是一个配置类
        @Configuration
        public @interface SpringBootConfiguration {}
        
      2. @ComponentScan

        // 指定扫描那些注解
        @Repeatable(ComponentScans.class)
        public @interface ComponentScan { .... }
        
      3. @EnableAutoConfiguration

        @AutoConfigurationPackage
        @Import(AutoConfigurationImportSelector.class)
        public @interface EnableAutoConfiguration { ... }
        
        • @AutoConfigurationPackage

          // 利用Registrar给容器中导入一系列组件
          // 将指定的一个包下的所有组件导入进来,MainApplication主程序所在的包下
          @Import(AutoConfigurationPackages.Registrar.class)
          public @interface AutoConfigurationPackage { .... }
          
          package org.springframework.boot.autoconfigure;
          
          public abstract class AutoConfigurationPackages {
          
              ......
              
          	/**
          	 * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
          	 * configuration.
          	 */
          	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
          
          @Override
          public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
          	register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
           }
                  
          		@Override
          		public Set<Object> determineImports(AnnotationMetadata metadata) {
          			return Collections.singleton(new PackageImports(metadata));
          		}
          	}
              
              .....
          }
          

          在这里插入图片描述

        • @Import(AutoConfigurationImportSelector.class)

          // 1.利用getAutoConfigurationEntry(annotationMetadata)给容器中批量导入一些组件
          // 2.调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)
          // 获取到所有需要导入到容器中的配置类
          package org.springframework.boot.autoconfigure;
          
          public class AutoConfigurationImportSelector implements  DeferredImportSelector,
          	BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
                  
                  ......
                  
              @Override
          	public String[] selectImports(AnnotationMetadata annotationMetadata) {
          		if (!isEnabled(annotationMetadata)) {
          			return NO_IMPORTS;
          		}
               AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
          		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
          	}
                  
          protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
          		if (!isEnabled(annotationMetadata)) {
          			return EMPTY_ENTRY;
          		}
          		AnnotationAttributes attributes = getAttributes(annotationMetadata);
          		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
          		configurations = removeDuplicates(configurations);
          		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
          		checkExcludedClasses(configurations, exclusions);
          		configurations.removeAll(exclusions);
          		configurations = getConfigurationClassFilter().filter(configurations);
          		fireAutoConfigurationImportEvents(configurations, exclusions);
          		return new AutoConfigurationEntry(configurations, exclusions);
          	}
                       
                  .......   
          }
          

          在这里插入图片描述

          // 接上面的类
          protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, 
                                                            AnnotationAttributes attributes) {
          		List<String> configurations = 
                      SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
          		Assert.notEmpty(configurations, 
                                  "No auto configuration classes found in META-INF/spring.factories. If you "
          				+ "are using a custom packaging, make sure that file is correct.");
          		return configurations;
          }
          
          
          
          
          // 3.利用工厂加载Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader)
          // 得到所有的组件
          
          // 4.从META-INF/spring.factories位置来加载一个文件。
          // 默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件。
          // spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面有META-INF/spring.factories
          package org.springframework.core.io.support;
          
          public final class SpringFactoriesLoader {
              
              ....
              
              // 此方法的返回值
              public static List<String> loadFactoryNames(Class<?> factoryType, 
                                                          @Nullable ClassLoader classLoader) {
          		String factoryTypeName = factoryType.getName();
          	return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
          	}
              
              private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
          		MultiValueMap<String, String> result = cache.get(classLoader);
          		if (result != null) {
          			return result;
          		}
          
          		try {
          			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 factoryTypeName = ((String) entry.getKey()).trim();
          					for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
          						result.add(factoryTypeName, factoryImplementationName.trim());
          					}
          				}
          			}
          			cache.put(classLoader, result);
          			return result;
          		}
          		catch (IOException ex) {
          			throw new IllegalArgumentException("Unable to load factories from location [" +
          					FACTORIES_RESOURCE_LOCATION + "]", ex);
          		}
          	}
                  
              ....
              
          }
          

          在这里插入图片描述

    • 按需开启自动配置项

      # 文件里面写死了springBoot启动就要给容器加载的所有配置类
      ....
      # Auto Configure
      org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
      org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
      org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
      org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
      ....
      
      # 虽然我们127个场景的所有自动配置启动的时候默认全部加载。XxxAutoConfiguration
      # 按照条件装配规则(@Conditional),最终会按需配置。
      
    • 总结

      // 随便点开spring-boot-autoconfigure-2.3.4.RELEASE.jar包下XxxAutoConfiguration文件看是否配置了此组件
      @Configuration(proxyBeanMethods = false)
      @EnableConfigurationProperties(ServerProperties.class)
      @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
      @ConditionalOnClass(CharacterEncodingFilter.class)
      @ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
      public class HttpEncodingAutoConfiguration { .... }
      
      1. SpringBoot先加载所有的自动配置类XxxAutoConfiguration
      2. 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。XxxProperties里面拿。XxxProperties和配置文件进行了绑定。
      3. 生效的配置类就会给容器中装配很多组件。
      4. 只要容器中有这些组件,就相当于这些功能就有了。
      5. 定制化配置。
        • 用户直接自己@Bean替换底层的组件。
        • 用户去看这个组件是获取的配置文件什么值就去修改。

      XxxAutoConfiguration ——> 加载组件 ——> XxxProperties里面拿值 ——> application.properties修改配置

    • 最佳实践

      1. 引入场景依赖
      2. 查看自动配置了哪些(选做):配置文件中debug=true开启自动配置报告。【Negative(不生效)、Positive(生效)】
      3. 是否需要修改:参照文档修改配置项
      4. 自动加入或者替换组件:@Bean、@Component....
      5. 自定义器XxxCustomizer

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

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

相关文章

面试题 : Top-k问题

目录 题目 示例 提示 开始解题 1.思路 2.解题代码 3.时间复杂度 4.运行结果 ​编辑 目前问题 真正的解法 1.以找前K个最大的元素为例 2.代码执行过程&&时间复杂度的计算 3.画图演示代码执行过程 4.解题代码 两种解法的比较 完结撒花✿✿ヽ(▽)ノ✿✿ …

CAPL通过lookupSignal和DBLookup获取DBC信号的属性信息

文章目录 演示CAPL通过lookupSignal和DBLookup获取DBC信号的属性信息lookupSignalDBLookup代码问题:DBLookup(信号名).AttributeName报错问题: motorola格式的信号使用DBLookup获取信号的bitstart跟ig模块里的信息不一样演示 CAPL通过lookupSignal和DBLookup获取DBC信号的属性…

Django的模型

定义模型 from django.db import models class User(models.Model):# 类属性是表示表的字段username models.CharField(max_length50,uniqueTrue)password models.CharField(max_length200)create_time models.DateTimeField(auto_now_addTrue) # auto_now_add新增数据时间…

发布python模仿2023年全国职业的移动应用开发赛项样式开发的开源的新闻api,以及安卓接入案例代码

python模仿2023年全国职业的移动应用开发赛项样式开发的开源的新闻api&#xff0c;以及原生安卓接入案例代码案例 源码地址:keyxh/newsapi: python模仿2023年全国职业的移动应用开发赛项样式开发的开源的新闻api&#xff0c;以及安卓接入案例代码 (github.com) 目录 1.环境配…

全球地震分析寻找难以捉摸的前震信号

发现前震的本质可以帮助地震学家预测大地震。 2019 年里奇克莱斯特地震序列使南加州沙漠​​的道路发生偏移。图片来源&#xff1a;Ken Hudnut/USGS 小地震是否预示着大地震是地震学中长期存在的问题。 简而言之&#xff0c;答案是&#xff0c;有时他们会这样做。这是根据对全…

老胡的周刊(第104期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 whistle[2] Whistle 是基于 Node 实现的跨平…

点亮一颗LED灯

TOC LED0 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能APB2的外设时钟GPIO_InitTypeDef GPIO_Initstructure;GPIO_Initstructure.GPIO_Mode GPIO_Mode_Out_PP;//通用推挽输出GPIO_Initstructure.GPIO_Pin GPIO_Pin_5;GPIO_Initstructure.GPIO_Speed GPIO_S…

从LeakCanary看如何判断对象被回收了

前面已经了解了Service&#xff0c;Fragment&#xff0c;ViewModel对象的销毁时机&#xff0c;那么在触发销毁时机后&#xff0c;我们怎么判断这些对象有没有回收呢&#xff1f; 大家都知道在Java中有强引用&#xff0c;弱引用&#xff0c;软引用&#xff0c;虚引用四种引用方…

难缠客户背后的秘密:项目经理的危机处理手册

难缠的客户&#xff0c;每个项目经理都会或多或少遇到。他们可能会频繁更改需求&#xff0c;对细节吹毛求疵&#xff0c;或者在关键时刻提出与之前完全不同的意见。但是&#xff0c;难缠的客户其实并不都是坏事&#xff0c;他们也为项目经理提供了宝贵的学习机会。本文将深入探…

git拉取失败/git fatal终极解决方法

前言 被折磨不下20次总结出来的终极方案 步骤 0 首先关闭代理试试&#xff0c;不行就下一步 1 重置代理或者取消代理的方式 git config --global --unset http.proxy git config --global --unset https.proxy添加全局代理 git config --global http.proxy git config …

虚拟化 VMware sphere

一 VMware sphere用途&#xff1a; VMware vSphere 是 VMware 的虚拟化平台&#xff0c;可将数据中心转换为包括 CPU、存储和网络资源的聚合计算基础架构。vSphere 将这些基础架构作为一个统一的运行环境进行管理. 1. **虚拟化&#xff1a;** vSphere 的主要用途是将物理服务…

打印X型的图案

int main() {int n0;int i0;int j0;scanf("%d",&n);for(i0;i<n;i){for(j0;j<n;j){if(ij){printf("*");}else if((ij)n-1){printf("*");}elseprintf(" ");}printf("\n");}return 0; }

mapper.xml中循环执行多条语句时报错,但是单独拿SQL到数据库却可以执行

我是批量修改数据&#xff0c;用foreach标签包住update语句&#xff0c;报错信息如下&#xff1a; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the …

HCIP的VLAN实验

实验步骤&#xff1a; 1.首先&#xff0c;对交换机SW1进行操作&#xff0c;创建需要的VLAN并对接口进行划分 [SW1]vlan batch 2 to 6 [SW1]port-group group-member Ethernet 0/0/2 Ethernet 0/0/4 [SW1-port-group]port link-type access [SW1-port-group]port default vlan …

聚焦电力行业CentOS迁移,麒麟信安受邀参加第六届电力信息通信新技术大会暨数字化发展论坛并发表主题演讲

为加快推进“双碳”目标下的新型能源体系和新型电力系统建设&#xff0c;深化新一代数字技术与电力业务的融合发展&#xff0c;促进电力行业关键技术自主创新、安全可控&#xff0c;助力电力企业数字化转型升级和高质量发展&#xff0c;2023年8月9-11日&#xff0c;第六届电力信…

使用mysql:5.6和 owncloud 镜像,构建一个个人网盘。

一.根据自己版本选择镜像 uname -a cat /etc/centos-releaseuname -a 命令用于查看当前系统的硬件和操作系统信息&#xff0c;包括内核版本、处理器架构、系统类型等。 其中&#xff0c;"Linux" 表示操作系统类型为 Linux&#xff0c;"3.10.0-1160.el7.x86_64…

C++ 网络编程项目fastDFS分布式文件系统(四)-fastCGI项目相关技术以及linux搜狗输入法相关问题。

目录 1. Nginx作为web服务器处理请求 2. http协议复习 Get方式提交数据 Post方式提交数据 3. fastCGI 3.1 CGI 3.2 fastCGI 3.3 fastCGI和spawn-fcgi安装 1. 安装fastCGI 2. 安装spawn-fcgi 3.4 nginx && fastcgi 4其他知识点 1. fastCGI环境变量 - fas…

week5刷题

题解: 斐波那契数的边界条件是 F(0)0和 F(1)1。当 n>1 时&#xff0c;每一项的和都等于前两项的和&#xff0c;因此有如下递推关系&#xff1a; F(n)F(n−1)F(n−2) 由于斐波那契数存在递推关系&#xff0c;因此可以使用动态规划求解。动态规划的状态转移方程即为上述递推…

vector的迭代器失效问题

vector的迭代器存在一定隐患&#xff0c;以下几种方式会导致其迭代器失效 resize、reserve、insert、assign、push_back。 1.push_back导致迭代器失效 示例代码&#xff1a; #include<vector> #include <iostream> using std::cout; using std::endl; using std:…

PyTorch学习笔记(十六)——利用GPU训练

一、方式一 网络模型、损失函数、数据&#xff08;包括输入、标注&#xff09; 找到以上三种变量&#xff0c;调用它们的.cuda()&#xff0c;再返回即可 if torch.cuda.is_available():mynn mynn.cuda() if torch.cuda.is_available():loss_function loss_function.cuda(…