Spring核心与设计思想、创建与使用

news2024/9/20 18:36:32

文章目录

  • 一、Spring是什么
  • 二、为什么要学习框架
  • 三、IoC和DI
    • (一)IoC
      • 1. 认识IoC
      • 2. Spring的核心功能
    • (二)DI
  • 四、Spring项目的创建
    • (一)使用 Maven 方式创建一个 Spring 项目
  • 五、Spring项目的使用
    • (一) 存储 Bean 对象到容器(Spring)中
    • (二)从 spring 将 bean 对象读取出来并使用
    • (三)getBean的更多用法
  • 六、Spring更简单的存储和读取对象的方式
    • (一)存储 Bean 对象
    • (二)读取 Bean 对象
      • 1. 属性注入
      • 2. 构造方法注入
      • 3. Setter 注入
      • 4. 使用 @Resource 代替 @Autowired
      • 5. 问题一:@Resource VS @Autowired
      • 6. 问题二:属性注入、构造方法注入与set方法注入有什么区别
      • 7. 问题三:当我们使用 @Bean 保存了多个相同类的不同对象,此时上述代码就会出现问题,会报出不唯一的异常
  • 七、Bean 作用域和生命周期
    • (一)Bean 作用域的问题
      • 1. 案例
      • 2. 原因分析
    • (二)作用域的定义
      • 1. Bean 的六种作用域
      • 2. 设置作用域
    • (三)Spring 执行流程和 Bean 的生命周期
      • 1. Spring 执行流程
      • 2. Bean 生命周期

一、Spring是什么

  我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单
  ⽤⼀句话概括 Spring:Spring 是包含了众多⼯具⽅法的 IoC 容器

二、为什么要学习框架

  1. 就像我们装修房子,不使用框架就像我们材料自己买,关于房子的事情都需要亲力亲为,使用框架时就像我们请了装修公司,材料、人员安排等等我们不再关系,而只需要提出需求,跟进进度即可,特点就是高效
  2. 框架更加易用,并且使用起来也是非常简单

  上述优势通过 SpringBoot 和 Servlet 对比能够更容易地看出:

  1. SpringBoot 添加外部 jar 包更容易,不易出错,直接引入即可,而Servlet还需要关注版本问题
  2. 调试、发布项目更加方便,无需配置 Tomcat,因为它里面已经内置了
  3. 添加路由更加方便,无需每个访问地址都添加一个类

三、IoC和DI

(一)IoC

  在认识IoC之前,我们要先知道容器地概念,通过百度,我们可以知道容器是用来容纳某种物品的装置,我们之前学过的List是数据存储容器,Tomcat是Web容器

1. 认识IoC

  首先明确一点,Spring也是一个容器,它是一个IoC容器
什么是 IoC?

  IoC = Inversion of Control 翻译成中⽂是“控制反转”的意思,IoC就是控制反转的思想。“控制反转”是两个词,控制和反转。指的是:之前程序的控制权限是在我们自己手上,现在把控制权交出去,我们只需要使用即可

  1. 一般情况下,我们在 A 类 中,想去调用 B 类中的方法,要去 new B 类对象,通过 对象 去调用 B类中的方法。当前 B 的控制权,是我们手上的
  2. 而控制反转,就是将我们手上的权限,交由 Spring 框架来操作
  3. 此时,我们想要 A 类中调用 B 的时候,告诉框架,我要在 A 中调用 B 了。至于 B 的生命周期,和我们没有任何关系。
  4. 因为我们把控制权 “反转给了” Spring 框架。Spring 会帮我们管理所有的对象(Bean)

2. Spring的核心功能

  通过上述关于IoC的介绍,我们知道了Spring的核心功能就是两点:

  1. 将 Bean(对象)存储到 Spring(容器)中
  2. 将 Bean(对象)从 Spring(容器)中取出来

(二)DI

  只要我们说到IoC,就离不开DI,它们俩的关系就像是切菜和菜刀一样,切菜是一种动作,也是一种想法,该如何实现呢?利用菜刀来实现这个想法
  DI 是 Dependency Injection 的缩写,翻译成中⽂是“依赖注⼊”的意思。具体解释就是在 IoC 容器运行期间,动态的将某种依赖关系注入到对象中。就是为了实现 IoC 的思想,所以,IoC 和 DI 的核心都是为了“控制反转”,,但是区别就是IoC是思想,DI是实现

四、Spring项目的创建

(一)使用 Maven 方式创建一个 Spring 项目

  1. 创建一个普通的 Maven 项目(不需要添加web-app模板)
  2. 添加 Spring 框架支持
    (1)在 pom.xml 当中加入依赖
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
    </dependencies>
    
    (2)粘贴完之后,刷新 Maven
  3. 在 Java 源文件中添加一个启动类,并编写 main 方法即可
    添加启动类 & 编写main方法

五、Spring项目的使用

(一) 存储 Bean 对象到容器(Spring)中

  1. 如果第一次存储,先在 spring 项目中添加配置文件
    添加配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     
    </beans>
    
  2. 创建 Bean 对象(Java对象的另一种称呼),和对普通的类实例化一样
    创建bean对象
  3. 在配置文件中将需要保存到容器中的 Bean 对象进行注册,如下图所示,表示将 User 对象以类似字典的形式存入到 Spring 当中,id就是它的标识(通常使用小驼峰),类似于 HashMap 中的key
    注册

(二)从 spring 将 bean 对象读取出来并使用

  1. 得到 spring 上下文对象
  2. 通过上下文对象提供的方法获取自己需要使用的 bean 对象
  3. 使用 bean 对象

从 spring 将 bean 对象读取出来并使用

  除了图上通过 ApplicationContext 来获取 spring 上下文,我们也可以通过 BeanFactory (Bean工厂)来作为 spring 的上下文,代码如下

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

  那么这二者有什么区别呢,这就是一个经典面试题:ApplicationContext VS BeanFactory

相同点:都可以实现从容器中获取bean,都提供了 getBean 方法
不同点:

  1. ApplicationContext 属于 BeanFactory 的子类。BeanFactory 只提供了基础访问 Bean 的方法,而 ApplicationContext 除了拥有 BeanFactory 的所有功能之外,还提供了更多的方法实现,比如对国际化的支持、资源访问的支持、以及事件和传播等方面的支持
  2. 性能方面来说二者不同。BeanFactory 是按需加载 Bean,懒加载;ApplicationContext 是饿汉方式,在创建时会将所有的 Bean 加载起来,以备以后使用

(三)getBean的更多用法

  1. 使用 bean name 获取 bean
User user = (User)context.getBean("user");
  1. 根据 bean type 获取 bean
User user = context.getBean(User.class);

  这个写法虽然简单,但是存在问题,如果两个类对象类名相同,但包不同,同时保存到了 spring 中,那么此时再通过这种方法进行获取 bean ,就会报出类不唯一的异常
3. 根据 bean name 和 bean type 获取 bean

User user = context.getBean("user", User.class);

  这种写法和第一种比较看似只是不用强转,但是如果返回的 bean 是 null,此时进行强转就会直接抛出空引用异常,而第三种方法不会存在这个问题,因此这种写法要比第一种更加健壮,所以更加推荐这种写法

六、Spring更简单的存储和读取对象的方式

  上述存储和读取 bean 对象的方式只是最原始的方式,仍然不够简洁和方便;而在 Spring 中,想要更简单的存储和读取对象的核心是使用注解,这也就是我们下来要介绍的内容

(一)存储 Bean 对象

  我们之前存储 bean 时,是通过在配置文件中添加一行 bean 注册内容,而现在我们只需要一个注解就可以替代之前的操作,不过在此之前,我们要先进行一些准备工作

  1. 前置工作:配置扫描路径(关键
    在 spring 配置文件中设置 bean 的扫描根路径

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:content="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
        <content:component-scan base-package="com.beans"></content:component-scan>
    </beans>
    

    注意:在标签中,base-package表示的就是扫描根路径,这个路径是我们自己设置的,而我们以后要存储的类,都会写入到这个路径的包/子包底下,只要在这个包底下的类加了注解,就表示存储到 spring 中了

  2. 简单的将 bean 存储到容器中

    1. 使用五大类注解实现
      1. Controller(控制器)
        // 必须添加注解
        @Controller
        public class UserController {
            public void hello() {
                System.out.println("hello, UserController!");
            }
        }
        
      2. Service(服务)
      3. Repository(仓库)
      4. Configuration(配置)
      5. Component(组件)
    2. 通过 @Bean 方法注解实现
      注意,@Bean 注解只能添加到方法上,而不能添加到类上;@Bean必须搭配五大类注解使用;读取时 bean name 不是类名,而是方法名(要求:必须完全一致,不再是之前五大类注解的规则)(不一定,可以参考下方第六点)
      // 使用
      // 注意这里的 bean name 是方法名,不是类名
      User user = context.getBean("GetUser", User.class);
      System.out.println(user);
      
      // 保存
      @Component
      public class UserBeans {
          /**
           * 注意:只使用一个 @Bean 是无法将对象存储到容器中的
           * 必须在类上也搭配一个五大类注解,这样做的目的是为了提高效率
           * @return
           */
          @Bean
          public User GetUser() {
              User user = new User();
              user.id = 1;
              user.name = "张三";
              return user;
          }
      }
      
  3. 提出疑问:上述将 bean 存储到容器中,明明五大类注解任何一个都可以,为什么还需要五大类注解?
    解答:
      这里就涉及到软件工程的知识了,如下图所示,我们的五大类注解和下面的软件架构分层一一对应,当我们的 bean 很多时,我们就有必要根据不同的功能使用不同的注解对不同的 bean 进行区分,让代码的可读性提高,让程序猿能够直观的判断当前类的用途。Component 就是用于当 bean 不属于下面四种情况时,作为一个工具来使用时使用 Component 来注释
    软件架构分层

  4. 五大类注解之间的关系,这个问题我们可以直接看底层源码,就会发现其他四个类注解都是继承自 Component,换句话说,Compinent 是其他四个类的父类,以 Controller 为例
    五大注解继承关系

  5. 使用五大类注解产生的 bean name 问题。我们读取 bean 时,这个问题是避不开的,因此需要我们着重注意
    解答:
      这个问题我们需要去看注解 bean name 生成器,即:AnnotationBeanNameGenerator,当我们在这个方法中左拐右拐,最终却定位到了decapitalize.java文件,通过查看文件目录结构,我们发现,这个方法是在 jdk 里自带的,换句话说,通过注解生成 bean name 的规则,实际是 jdk 自带的,接下来我们对这个方法进行源码分析,如下图:
    bean name生成规则
      因此我们说,当类名第一个字符和第二个字符都是大写时,bean name 就是它本身,否则就是第一个字符小写

  6. 使用 @bean 的时候,我们想要读取 Bean 对象,只能使用方法名吗,答案是不一定,我们可以人为的给这个方法返回的 bean 设置一个 name,甚至可以给他起多个 name ,如下方代码

    // 如果只有一个 name ,不需要加"{}"
    @Bean(name = {"userInfo", "user1"})
    public User GetUser() {
        User user = new User();
        user.id = 1;
        user.name = "张三";
        return user;
    }
    

    注意,在这种情况下方法名将无法再使用

(二)读取 Bean 对象

  获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注⼊。对象注入的实现方式有三种:

  1. 属性注入
  2. 构造方法注入
  3. Setter 注入

三种对象注入都可以通过 @Autowired 实现

1. 属性注入

下面我们将 UserService 类注入到 UserController2 类中

// 将 UserService 注入到 UserController2
@Controller
public class UserController2 {
    @Autowired
    private UserService userService;

    public void hello() {
        userService.hello();
    }
}

// 将 UserController2 注入到 App 中并执行
public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController2 userController2 =
                context.getBean("userController2", UserController2.class);
        userController2.hello();
    }
}

运行结果
Autowired属性注入

2. 构造方法注入

我们通过构造方法和@Autowired将 UserService 类注入到 UserController3 类中,如果当前类中只有一个构造方法,@Autowired可以省略

@Controller
public class UserController3 {
    private UserService userService;

    //只有一个构造方法时可以省略@Autowired
    public UserController3(UserService userService) {
        this.userService = userService;
    }

    public void hello() {
        userService.hello();
    }
}

public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController3 userController = context.getBean(UserController3.class);
        userController.hello();
    }
}

运行结果
构造方法注入 Bean 对象

3. Setter 注入

为需要注入的类提供一个set方法

@Controller
public class UserController4 {
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void hello() {
        userService.hello();
    }
}

public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController4 userController4 = context.getBean(UserController4.class);
        userController4.hello();
    }
}

运行结果
Setter注入

4. 使用 @Resource 代替 @Autowired

  @Resource 是 Java 官方提供的,@Autowired 是由 Spring 官方提供的,直接将 @Resource 替换为 @Autowired 即可。但是,@Resource 不支持属性注入因此我们说,注入方式有三种,注入方法有这两种

5. 问题一:@Resource VS @Autowired

相同点:都可以实现将一个对象注入到类当中
不同点:

  1. 实现者不同,@Resource是 Java 官方提供的,@Autowired是 Spring 官方提供的
  2. 用法不同:@Autowired 支持属性注入、构造方法注入和Setter注入,但是 @Resource 不支持属性注入
  3. 支持参数不同:@Resource 支持更多的参数设置,比如name、type设置,而 @Autowired 只支持 required 参数设置

6. 问题二:属性注入、构造方法注入与set方法注入有什么区别

答:
  1. 属性注入写法简单,但只能运行在IoC容器下,其他容器会出现问题
  2. Setter注入:早期 Spring 版本推荐的写法,但 Setter 注入没有构造方法注入通用,其他语言写set方法很麻烦
  3. 构造方法注入:通用性更好,它能确保在使用注入对象之前,此注入对象一定初始化过了

7. 问题三:当我们使用 @Bean 保存了多个相同类的不同对象,此时上述代码就会出现问题,会报出不唯一的异常

如下图:
多次保存问题
多次保存问题
  针对这个问题,我们有如下的解决方案:

  1. 精确的描述 bean 的名称(将注入的名称写对)

解决方案一

  1. 使用 @Resource 设置 name 的方式来重命名注入对象

Resource注解

  1. 如果工作时要求不能使用 @Resource,并且我们业务代码已经写了很多,采用第一种方法改起来很麻烦,我们就可以使用 @Qualifier + @Autowired 来筛选 bean 对象

Qualifier的使用

七、Bean 作用域和生命周期

(一)Bean 作用域的问题

1. 案例

  由上述知识我们知道,Spring 是用来读取和存储 Bean 的,因此 Bean 是 Spring 最核心的操作资源,因此我们需要更深入的了解一下 Bean。其中我们的预期结果是公共的 Bean 经过注入之后可以在各自的类进行修改,但是不能影响到其他的类但是经过测试发现结果并不是这样

  1. 测试类1,注入对象后将将象的 name 设为“王五”,并返回
    测试类1
  2. 测试类2,注入对象后直接返回
    测试类2
  3. 结果
    测试结果

  注意,作者在测试这里的代码时,恰好遇到了一个需要注意的问题,在有 Spring 存在的项目中,Spring 的注入要统一使用,类的一步步引用,要么为全部注入,要么都不注入,否则会出错。代到当前测试例子中,由于作者刚开始进行测试时在 app 类中两个类都是 new 出来的,导致两个类中并没有对 User 类进行注入,在操作时就会报出空指针异常
  言归正传,我们在上面进行测试时,发现结果和预期并不相同,UserTestBean2中对对象进行了修改,居然影响到了UserTestBean1,那么问题是什么呢?

2. 原因分析

  上述问题的原因就是因为 Bean 默认情况下是单例模式(singleton),换句话说所有类使用的是同一个对象,这样做可以很大程度上提高性能

(二)作用域的定义

  限定程序中变量的可⽤范围叫做作⽤域,或者说在源代码中定义变量的某个区域就叫做作⽤域。
  ⽽ Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式,⽐如 singleton 单例作⽤域,就表示 Bean 在整个 Spring 中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个⼈读取到的就是被修改的值

1. Bean 的六种作用域

Spring 容器在初始化一个 Bean 的实例时,同时会指定该实例的作用域。Spring 有六种作用域,最后四种是基于 Spring MVC 生效的:

  1. singleton:单例作用域(Spring默认选择该作用域)
  2. prototype:原型作用域(多例作用域)
  3. request:请求作用域
  4. session:会话作用域
  5. application:全局作用域
  6. websocket:HTTP WebSocket 作用域

使用场景

  1. singleton:通常无状态的 Bean 使用该作用域。无状态表示 Bean 对象的属性状态不需要更新
  2. prototype:通常有状态(即需要进行修改)的 Bean 使用该作用域
  3. request:一次http的请求和相应的共享Bean
  4. session:用户会话的共享Bean,比如记录一个用户的登录信息
  5. application:Web应用的上下文信息,比如:记录一个应用的共享信息
  6. websocket:Websocket的每次会话中,保存了一个Map结构的头信息,将用来包裹客户端消息头,第一次初始化后,直到 WebSocket 结束都是同一个Bean

单例作用域(singleton)VS 全局作用域(application)

  1. singleton 是 Spring Core 的作用域;application 是 Spring Web 中的作用域
  2. singleton 作用于 Ioc 的容器,而 application 作用于 Servlet 容器

2. 设置作用域

  使用 @Scope 标签就可以用来声明 Bean 的作用域。@Scope 标签既可以修饰方法也可以修饰类,@Scope 有两种设置方式:

  1. 直接设置值:@Scope(“prototype”)
  2. 使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

示例:

// @Scope("prototype")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean(name = "user2")
public User getUser2() {
    User user = new User();
    user.setId(2);
    user.setName("李四");
    return user;
}

(三)Spring 执行流程和 Bean 的生命周期

1. Spring 执行流程

  1. 启动 Spring 容器
  2. 根据配置完成 Bean 初始化(分配内存空间)
  3. 注册 Bean 对象到容器中
  4. 装配 Bean 到需要的类中

2. Bean 生命周期

  1. 实例化 Bean (为 Bean 分配内存空间)
  2. 设置属性(Bean 注入和装配)
  3. Bean 初始化
  • 实现了各种 Aware 通知的方法
  • 执行初始化的前置方法,依赖注入操作之后被执行
  • 执行构造方法,两种执行方式,一种是执行 @PostConstruct(优先,注解时代的产物),另一种是执行 init-method 方法(xml时代的产物)
  • 执行初始化的后置方法
  1. 使用 Bean
  2. 销毁 Bean

(1)@PreDestroy
(2)重写 @DisposableBean 接口方法
(3)destroy-method

注意:步骤二与步骤三顺序不能交换,因为在步骤三中的构造方法中可能会用到注入对象的方法

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

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

相关文章

少年与阿童木:一场软件竞技赛背后的智能未来

1961年&#xff0c;手冢治虫创办了虫制作株式会社&#xff0c;带领团队开始尝试将此前的漫画作品进行动画化。1963年的元旦&#xff0c;他们的首部作品一经播出就引发轰动&#xff0c;这部动画的名字叫做——《铁臂阿童木》。 一晃数十年&#xff0c;阿童木已经成为了几代人对A…

2023年6月DAMA-CDGA/CDGP数据治理工程师认证报名及费用

目前6月DAMA-CDGA/CDGP数据治理认证考试开放报名地区有&#xff1a;北京、上海、广州、深圳、长沙、呼和浩特。目前南京、济南、西安、杭州等地区还在接近开考人数中&#xff0c;打算6月考试的朋友们可以抓紧时间报名啦&#xff01;&#xff01;&#xff01; 5月初&#xff0c;…

大数据 | 实验二:文档倒排索引算法实现

文章目录 &#x1f4da;实验目的&#x1f4da;实验平台&#x1f4da;实验内容&#x1f407;在本地编写程序和调试&#x1f955;代码框架思路&#x1f955;代码实现 &#x1f407;在集群上提交作业并执行&#x1f955;在集群上提交作业并执行&#xff0c;同本地执行相比即需修改…

蓝牙耳机怎么挑选?鹏鹏数码盘点2023口碑蓝牙耳机排行榜

大家好&#xff0c;欢迎来到鹏鹏数码频道。 上次测评发布后网友们评论不知道蓝牙耳机怎么挑选&#xff0c;为此我购入了市面上主流品牌的蓝牙耳机共计三十款&#xff0c; 经过两周的地狱式测评&#xff0c;总结了口碑蓝牙耳机排行榜&#xff0c;看看表现最好的是哪几款蓝牙耳机…

Linux操作系统命令大全

Linux是一种操作系统 Operating System 简称 OS &#xff0c;是软件的一部分&#xff0c;它是硬件基础上的第一层软件&#xff0c;是硬件和其它软件沟通的桥梁。 操作系统会控制其他程序运行&#xff0c;管理系统资源&#xff0c;提供最基本的计算功能&#xff0c;如管理及配置…

SSM整合(一) | SSM创建项目配置整合 - 添加功能模块

文章目录 SSM整合SSM配置整合SSM功能模块 SSM整合 SSM配置整合 SSM整合流程: 创建工程SSM整合 Spring SpringConfig MyBatis MybatisConfigJdbcConfigjdbc.properties SpringMVC ServletConfigSpringMvcConfig 创建工程 基于Maven创建项目, 选择webapp模版并补全缺失的目录 …

最优化方法Python计算:一元函数导数的数值计算

定义1 给定连续函数 f ( x ) f(x) f(x)&#xff0c; x ∈ Ω ⊆ R x\in\Omega\subseteq\text{ℝ} x∈Ω⊆R。设 x , x 1 ∈ Ω x,x_1\in\Omega x,x1​∈Ω&#xff0c; Δ x x − x 1 \Delta xx-x_1 Δxx−x1​ 称为变量 x x x的差分。此时&#xff0c; x x 1 Δ x xx_1\De…

黑盒测试过程中【测试方法】详解5-输入域,输出域,猜错法

在黑盒测试过程中&#xff0c;有9种常用的方法&#xff1a;1.等价类划分 2.边界值分析 3.判定表法 4.正交实验法 5.流程图分析 6.因果图法 7.输入域覆盖法 8.输出域覆盖法 9.猜错法 黑盒测试过程中【测试方法】讲解1-等价类&#xff0c;边界值&#xff0c;判定表_朝一…

Linux下实现共享内存的两种机制(附源码)

START Hello 大家好。 今天来讲一下Linux进程通信中重要的通信方式&#xff1a;共享内存作为Linux软件开发攻城狮&#xff0c;进程间通信是必须熟练掌握的重要技能&#xff0c;而共享内存是在程序开发中常用的也是重要的一种进程间通信方式。 下面我们就来聊一聊Linux下进程间…

【C++】string类的深浅拷贝问题

string类的深浅拷贝问题 浅拷贝问题构造/析构函数拷贝构造/赋值运算符重载的多种写法 浅拷贝问题 我们知道&#xff0c;定义一个类的时候&#xff0c;如果我们没有写构造&#xff0c;拷贝构造&#xff0c;赋值运算符重载&#xff0c;析构方法的话&#xff0c;编译器会自动生成。…

Django学习笔记001之创建项目

学习目标&#xff1a; 了解前端后台框架 掌握vs搭建Django环境 学习内容 1.背景学习 优缺点&#xff1a; 2.vs搭建Django开发环境 2.1. 准备vscode工具 可以从github上获取&#xff1a;https://github.com/microsoft/vscode。 2.2. 构建python虚拟环境 使用的命令是pyth…

微分方程数值解法(Runge-Kutta法PLC实现)

微分方程数值解法之欧拉法请参看下面的博客文章: 微分方程数值解法(PID仿真用一阶被控对象库PLC算法实现)_数学微积分算法plc编程实例_RXXW_Dor的博客-CSDN博客微分方程除极特殊情况外,大部分不可能求出它的精确解,只能用各种近似方法得到满足一定精度的近似解,微分方程由…

CTA进网检验要求修订原则和变更说明 SAR新国标在2024年正式实施

《进网检验要求文件》 实行定期及动态更新原则&#xff0c;其中检测项目应能体现进网监管的职责定位。 第一部分 基本功能性能 第二部分 空间性能 SAR 新版进网检验要求细化了各场景的测试距离&#xff1a; SAR新要求的实施日期&#xff1a; 第二部分 空间性能 EMC 第二部分 空…

【MySQL】查询中,NULL值转换为空字符串

系列文章 C#底层库–MySQLBuilder脚本构建类&#xff08;select、insert、update、in、带条件的SQL自动生成&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179216 C#底层库–MySQL数据库操作辅助类&#xff08;推荐阅读&#xff0…

【browserify】一步步教你学会browserify

https://www.cnblogs.com/fsg6/p/13139627.html Browserify browserify的官网是http://browserify.org/&#xff0c;他的用途是将前端用到的众多资源&#xff08;css,img,js,…) 打包成一个js文件的技术。 比如在html中引用外部资源的时候&#xff0c;原来我们可能这样写 &l…

C嘎嘎~~ [类 上篇]

类 上篇 1.面向过程和面向对象的认识2.类的引入3.类的定义4.类的访问限定符和封装4.1封装4.2访问限定符 5.类的作用域 1.面向过程和面向对象的认识 面向过程 和 面向对象的区别: 面向过程关注的是过程, 而面向对象关注的是对象之间的关系, 交互. C语言是面向过程的, 而C是面向对…

webshell gif图片文件绕过

目录页/dev/index. php允许GIF上传。尝试上传不同的文件类型将被拒绝。 这可以通过首先上传合法的GIF文件来绕过。使用了一个小的GIF https://giphy.com/gifs/obi-won-hvE0PhVAnGQAo 下载一个小的字节图片测试 上传文件并使用Burpsuite捕获请求。尝试上传时的请求应类似于下…

淘宝天猫店铺新品如何运营?

新品在店铺运营过程中是十分重要的部分&#xff0c;你知道新品在店铺运营中有何作用&#xff1f;了解新品运营机制吗&#xff1f;今天就来快速了解关于新品的知识点。 新品在店铺运营的角色&#xff1a; 01、商品生命周期有限 商品的普遍生命周期在3个月左右&#xff0c;3个…

Codeforces Round 867 (Div. 3)

Problem - E - Codeforces 思路&#xff1a; 首先&#xff0c;如果n为奇数&#xff0c;中间那个数无法调整&#xff0c;所以只考虑偶数只有26个字母&#xff0c;我们用cnt[]记录每个字母需要交换的对数。设maxn为交换对数最多的字母。显然&#xff0c;如果cnt[maxn]>n/2,显…

速锐得解码奔驰CAN数据应用于海外车联网远程控制与防盗系统

人们常说&#xff0c;奔驰征服一切&#xff0c;你征服奔驰。速锐得帮你征服奔驰的数据。 前日&#xff0c;有个海外客户&#xff0c;问我们做了奔驰哪些数据&#xff0c;他们需要一个车联网的远程控制系统&#xff0c;用于管理他们的车队。客户比较豪横&#xff0c;大多数都是…