【后端开发】初识Spring IoC与SpringDI、图书管理系统

文章目录

  • 图书管理系统
    • 用户登录
      • 需求分析
      • 接口定义
      • 前端页面代码
      • 服务器代码
    • 图书列表展示
      • 需求分析
      • 接口定义
      • 前端页面部分代码
      • 服务器代码
        • Controller层
        • service层
        • Dao层
        • modle层
  • Spring IoC
    • 定义
    • 传统程序开发
    • 解决方案
    • IoC优势
  • Spring DI
    • IoC &DI使用
    • 主要注解
  • Spring IoC详解
    • bean的存储
      • 五大注解
        • @Controller(控制器存储)
          • getBean()方法
          • 面试:ApplicationContext VS BeanFactory
        • 为什么要这么多类注解
        • 五大注解是否可以混用
        • 程序被Spring管理的条件
    • 方法注解--@Bean
    • 扫描路径
  • Spring DI详解
    • 属性注入
    • 构造方法注入
    • Setter注入
    • 优缺点
    • @Autowired存在的问题
      • @Primary
      • @Qualifier
      • @Resource
    • 面试--@Autowird 与 @Resource的区别

图书管理系统

用户登录

需求分析

账号密码校验接口:根据输入用户名和密码校验登录是否通过。

接口定义

  • url:/user/login
  • type:post
  • 请求参数:name=admin&password=admin
  • 返回:true //账号密码验证成功,false//账号密码验证失败

前端页面代码

<body><div class="container-login"><div class="container-pic"><img src="pic/computer.png" width="350px"></div><div class="login-dialog"><h3>登陆</h3><div class="row"><span>用户名</span><input type="text" name="userName" id="userName" class="form-control"></div><div class="row"><span>密码</span><input type="password" name="password" id="password" class="form-control"></div><div class="row"><button type="button" class="btn btn-info btn-lg" onclick="login()">登录</button></div></div></div><script src="js/jquery.min.js"></script><script>function login() {$.ajax({url: "/user/login",type: "post",data: {userName: $("#userName").val(),password: $("#password").val()},success: function (result) {if (result == "") {location.href = "book_list.html";} else {alert(result)}}})}</script>
</body>

服务器代码

@RequestMapping("/user")
@RestController
public class UserController {@RequestMapping("/login")public String login(String userName, String password, HttpSession session) {//1.校验参数//2.验证密码是否正确//3.返回结果if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {return "用户名或密码为空";}//理论上应该从数据库中读取,暂时先不用//一般正确情况下,会有后续的操作,因此建议将后续操作比较多的情况下放在括号外面if (!"admin".equals(userName) || !"admin".equals(password)) {return "密码错误";}session.setAttribute("userName", userName);return "";}
}

图书列表展示

需求分析

图书列表:提供图书列表信息

接口定义

  • url:/user/login
  • type:post
  • 请求参数:无
  • 返回:
    [{“id”: 1,
    “bookName”:“book1”,
    “author” :“author1”,
    “count”:270,
    “price”: 20”,
    publish":“publish1”,
    “status”: 1,
    “statusCN”:“可借阅”}…]

前端页面部分代码

		<script>//这里需要直接访问到后端的图书列表信息,直接需要访问到后端,所以直接开始就使用ajax,但是为了代码的可读性,将其封装到一个方法里面先getBookList();function getBookList() {$.ajax({url:"/book/getBookList",type:"get",success:function(books){var finalHtml = "";//下面使用单引号的原因是因为html中也有双引号,可能会造成出错for(var book of books){finalHtml += '<tr>';finalHtml += '<td><input type="checkbox" name="selectBook" value="'+book.id+'" id="selectBook" class="book-select"></td>';finalHtml += '<td>'+book.id+'</td>';finalHtml += '<td>'+book.bookName+'</td>';finalHtml += '<td>'+book.author+'</td>';finalHtml += '<td>'+book.num+'</td>';finalHtml += '<td>'+book.price+'</td>';finalHtml += '<td>'+book.publishName+'</td>';finalHtml += '<td>'+book.statusCN+'</td>';finalHtml += '<td>';finalHtml += ' <div class="op">';finalHtml += '<a href="book_update.html?bookId='+book.id+'">修改</a>';finalHtml += '<a href="javascript:void(0)" onclick="deleteBook('+book.id+')">删除</a>';finalHtml += '</div></td></tr>';}$("tbody").html(finalHtml);}})}

服务器代码

Controller层
@RequestMapping("/book")
@RestController
public class BookController {@Autowiredprivate BookService bookService;@RequestMapping("/getBookList")public List<BookInfo> getBookList() {
//        BookService bookService = new BookService();return bookService.getBookList();}
}
service层
@Component
public class BookService {@Autowiredprivate BookDao bookDao;public List<BookInfo> getBookList(){
//        BookDao bookDao = new BookDao();List<BookInfo> bookInfos = bookDao.mockData();for (BookInfo bookInfo : bookInfos) {if (bookInfo.getStatus() == 2){bookInfo.setStatusCN("不可借阅");}else {bookInfo.setStatusCN("可借阅");}}return bookInfos;}
}
Dao层
@Component
public class BookDao {//理论上该方法应该从数据库中获取,当前采用mock方式public List<BookInfo> mockData(){List<BookInfo> bookInfos = new ArrayList<BookInfo>();//mock数据,也就是测试时候所有的模拟数据for (int i = 1; i <= 15; i++) {BookInfo bookInfo = new BookInfo();bookInfo.setId(i);bookInfo.setAuthor("作者" + i);bookInfo.setBookName("图书" + i);bookInfo.setNum(i * 2 + 1);bookInfo.setPrice(new BigDecimal(i*3));bookInfo.setPublishName("出版社" + i);if (i % 5 == 0){bookInfo.setStatus(2);
//                bookInfo.setStatusCN("不可借阅");}else {bookInfo.setStatus(1);
//                bookInfo.setStatusCN("可借阅");}bookInfos.add(bookInfo);}return bookInfos;}
}
modle层
@Data
public class BookInfo {private Integer id;private String bookName;private String author;private Integer num;private BigDecimal price;private String publishName;private Integer status;//1-可借阅  0-不可借阅  这里的数据都是要存放到数据库中的,尽量减少往数据库中存放文字信息private String statusCN;//这个字段不用网数据库中存储,仅是为了与status进行文字与数字的转换
}

Spring IoC

Spring的抽象概念:Spring是包含了众多⼯具⽅法的IoC容器。

定义

IoC 是Spring的核心思想,之前项目在类上添加 @Restcontroller 和@Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时就会加载该类,把对象交给Spring管理,就是loC思想。

loC:Inversion of Control(控制反转),也就是说 Spring是一个"控制反转"的容器。
什么是控制反转呢?也就是控制权反转,什么的控制权发生了反转?
获得依赖对象的过程被反转了也就是说,当需要某个对象时,传统开发模式中需要自己通过 new 创建对象,现在不需要再进行创建,把创建对象的任务交给容器,程序中只需要依赖注入(DependencyInjection, Dl)就可以了这个容器称为:loC容器,Spring是一个loC容器,所以有时Spring 也称为Spring 容器。

传统程序开发

比如开发一个汽车,传统的设计思路为:
先设计轮子(Tire),然后根据轮子的大小设计底盘(Bottom),接着根据底盘设计车身(Framework),后根据车身设计好整个汽车(Car)。

这里就出现了一个"依赖"关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。
也就是Car类依赖Framework类,Framework类依赖Bottom类,Bottom类依赖Tire类。

这样的设计看起来没问题,但是可维护性却很低,接下来需求有了变更:随着对的车的需求量越来越大,个性化需求也会越来越多,我们需要加工多种尺寸的轮胎。

此时,开发一个汽车需要依赖再依赖,直至依赖到轮胎的尺寸,也就是下面的改法。

    public static void main(String[] args) {public static void main(String[] args) {Car car = new Car(20);car.run();}}public class Car {private Framework framework;public Car(int size) {framework = new Framework(size);System.out.println("Car init....");}public void run() {System.out.println("Car run...");}
}public class Framework {private Bottom bottom;public Framework(int size) {bottom = new Bottom(size);System.out.println("Framework init...");}
}public class Bottom {private Tire tire;public Bottom(int size) {this.tire = new Tire(size);System.out.println("Bottom init...");}
}public class Tire {private int size;public Tire(int size) {this.size = size;System.out.println("轮胎尺⼨: " + size);}
}

以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调用链上的所有代码都需要修改,程序的耦合度非常高(修改一处代码,影响其他处的代码修改)。

解决方案

我们尝试换一种思路,先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘来设计轮子。这时候,依赖关系就倒置过来了:轮子依赖底盘,底盘依赖车身,车身依赖汽车。
在这里插入图片描述
可以尝试不在每个类中创建下级类,如果创建下级类就会出现当下级类发生改变操作,自己也要跟着修改。
此时,只需要将原来由自己创建的下级类,改为传递的方式(也就是注入的方式),因为我们不需要在当前类中创建下级类了,所以下级类即使发生变化(创建或减少参数),当前类本身也无需修改任何代码,这样就完成了程序的解耦。

public class Main {public static void main(String[] args) {Tire tire = new Tire(20);Bottom bottom = new Bottom(tire);Framework framework = new Framework(bottom);Car car = new Car(framework);car.run();}
}public class Car {private Framework framework;public Car(Framework framework) {this.framework = framework;System.out.println("Car init....");}public void run() {System.out.println("Car run...");}
}public class Car {private Framework framework;public Car(Framework framework) {this.framework = framework;System.out.println("Car init....");}public void run() {System.out.println("Car run...");}
}public class Framework {private Bottom bottom;public Framework(Bottom bottom) {this.bottom = bottom;System.out.println("Framework init...");}
}public class Bottom {private Tire tire;public Bottom(Tire tire) {this.tire = tire;System.out.println("Bottom init...");}
}public class Tire {private int size;public Tire(int size) {this.size = size;System.out.println("轮胎尺⼨: " + size);}
}

代码经过以上调整,无论底层类如何变化,整个调用链是不用做任何改变的,这样就完成了代码之间的解耦,从而实现了更加灵活、通用的程序设计了。

IoC优势

在传统的代码中对象创建顺序是:Car>Framework->Bottom->Tire
改进之后解耦的代码的对象创建顺序是:Tire->Bottom->Framework ->Car

改进之后的控制权发生的反转,不再是使用方对象创建并控制依赖对象了,而是把依赖对象注入将当前对象中,依赖对象的控制权不再由当前类控制了。
这样的话,即使依赖类发生任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是IoC的实现思想。
在这里插入图片描述

loC容器具备以下优点

  1. 资源集中管理:loC容器会帮助管理一些资源(对象等),需要使用时,只需要从loC容器中去取就可以了。
  2. 解耦合:在创建实例的时候不需要了解其中的细节,降低了使用资源双方的依赖程度,也就是耦合度。

Spring 就是一种loC容器,帮助我们来做了这些资源管理。

Spring DI

Dl:DependencyInjection(依赖注入),容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称之为依赖注入。

程序运行时需要某个资源,此时容器就为其提供这个资源。
从这点来看,依赖注入(DI)和控制反转(l0C)是从不同的角度的描述的同一件事情,就是指通过引入loC容器,利用依赖关系注入的方式,实现对象之间的解耦。

上述代码通过构造函数的方式,把依赖对象注入到需要使用的对象中。

IoC是一种思想,也是"目标",而思想只是一种指导原则,最终还是要有可行的落地方案,而 DI 就属于具体的实现。
所以也可以说,DI是loC的一种实现。

IoC &DI使用

既然 Spring 是一个 loC(控制反转)容器,作为容器,那么它就具备两个最基础的功能:存、取。

Spring 容器管理的主要是对象,这些对象,我们称之为"Bean"。把这些对象交由Spring管理,由Spring来负责对象的创建和销毁,程序只需要告诉Spring,哪些需要存,以及如何从Spring中取出对象。

主要注解

@Component:交给Spring管理
@Autowired:注入运行时依赖的对象

@Component
public class BookService {@Autowiredprivate BookDao bookDao;public List<BookInfo> getBookList(){
//        BookDao bookDao = new BookDao();List<BookInfo> bookInfos = bookDao.mockData();for (BookInfo bookInfo : bookInfos) {if (bookInfo.getStatus() == 2){bookInfo.setStatusCN("不可借阅");}else {bookInfo.setStatusCN("可借阅");}}return bookInfos;}
}

Spring IoC详解

前⾯提到IoC控制反转,就是将对象的控制权交给Spring的IOC容器,由IOC容器创建及管理对象,也就是bean的存储。

bean的存储

五大注解

  • 五大类注解:@Controller、@Service、@Repository、@Component、@Configuration 。
  • bean对象:在spring容器中存放的对象。
  • ApplicationContext: 翻译为Spring上下文,指的就是当前的运行环境,也可以看作是⼀个容器。故ApplicationContext的对象中存放了所有与当前的运行环境有关的内容,比如 spring容器中存放的bean对象。
@Controller(控制器存储)

这里仅展示@Controller,其他四个注解与@Controller类似。
将UserControllerTest类用@Controller注解存放到IoC容器中。

@Controller
public class UserControllerTest {public void say(){System.out.println("hello, UserControllerTest");}
}
getBean()方法

这里分别使用三种getBean()方法来获取UserController对象,进行打印测试
在这里插入图片描述

@SpringBootApplication
public class LibraryApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(LibraryApplication.class, args);UserControllerTest bean = context.getBean(UserControllerTest.class);bean.say();System.out.println(bean);UserControllerTest userControllerTest = (UserControllerTest) context.getBean("userControllerTest");userControllerTest.say();System.out.println(userControllerTest);UserControllerTest userControllerTest1 = context.getBean("userControllerTest", UserControllerTest.class);userControllerTest1.say();System.out.println(userControllerTest1);}
}

在这里插入图片描述
结果成功输出也就是获取到了UserControllerTest对象,并且地址一样,说明是一个对象。
获取对象的功能是Application的父类BeanFactory的功能。

面试:ApplicationContext VS BeanFactory

继承关系和功能方面来说:Spring 容器有两个顶级的接口BeanFactory和ApplicationContext。
其中 BeanFactory 提供了基础的访问容器的能力,而ApplicationContext 属于 BeanFactony 的子类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了环境管理支持、资源访问支持、以及事件传播等方面的支持。
从性能方面来说:ApplicationContext 是一次性加载并初始化所有的 Bean 对象,而BeanFactory 是需要那个才去加载那个,因此更加轻量(空间换时间)。

为什么要这么多类注解

与应用分层呼应,让程序员看到类注解之后,就能直接了解当前类的用途。

  • @Controller:控制层,接收请求,对请求进行处理,并进行响应
  • @Servie:业务逻辑层,处理具体的业务逻辑
  • @Repository:数据访问层,也称为持久层,负责数据访问操作
  • @Configuration:配置层,处理项目中的一些配置信息
  • @Component:是一个元注解,也就是说可以注解其他类注解@Controller,@Service,@Repository,@Confiquraion,这些注解被称为@Component 的行生注解,因为这些注解源代码里面都有一个注解@Component。
五大注解是否可以混用

功能上:@Service @Repository @Configuration @Component 可以完全混用,@Controller有自己的特殊性。
规范上:不可以混用。因为我们想要与应用分层呼应。
在这里插入图片描述

程序被Spring管理的条件
  1. 程序要被spring扫描到(默认路径是启动类所在的目录以及子目录),手动设置:@ComponentScan(basePackages = “~”)
  2. 程序需要配置五大注解和@Bean

方法注解–@Bean

@Bean要搭配类注解使用

类注解是添加到某个类上的,但是存在两个问题:

  1. 使用外部包里的类,没办法添加类注解
  2. 一个类,需要多个对象,比如多个数据源

示例1,@Bean要搭配类注解使用

@Configuration
public class UserConfig {public void say(){System.out.println("hi,UserConfig");}@Beanpublic User user(){return new User("张三");}
}

示例2:定义多个对象,使用类的类型扫描

@Service
public class UserService {public void say(){System.out.println("hello, UserService");}@Beanpublic BookInfo user(){return new BookInfo();}@Beanpublic BookInfo user1(){return new BookInfo();}
}@SpringBootApplication
public class LibraryApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(LibraryApplication.class, args);BookInfo bean = context.getBean(BookInfo.class);System.out.println(bean);}
}

通过类的类型扫描,这里出现了报错,通过类的类型扫描,此时容器中有两个User对象,根据类型获取对象,此时Spring不知道要获取哪个对象,所以报错了。
在这里插入图片描述
解决办法:用类的名字扫描。

@SpringBootApplication
public class LibraryApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(LibraryApplication.class, args);BookInfo bean1 = (BookInfo) context.getBean("user");System.out.println(bean1);BookInfo bean2 = (BookInfo) context.getBean("user1");System.out.println(bean2);}
}

在这里插入图片描述

扫描路径

把启动类放到其他的目录下面,再次启动程序,会出错。
在这里插入图片描述
就是因为没有找到对应的bean对象,使用五大注解声明的bean,要想生效,还需要配置扫描路径,让Spring扫描到这些注解也就是通过 @ComponentScan 来配置扫描路径。

@ComponentScan({"com.example.library"})
@SpringBootApplication
public class LibraryApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(LibraryApplication.class, args);}
}

Spring DI详解

DI(依赖注入):依赖注入是一个过程,是指loC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象在上面程序案例中,我们使用了 @Autowired 这个注解,完成了依赖注入的操作简单来说,就是把对象取出来放到某个类的属性中。

在一些文章中,依赖注入也被称之为"对象注入”、"属性装配”,具体含义需要结合文章的上下文来理解。

关于依赖注入, Spring也给我们提供了三种方式:
属性注入(Field Injection)
构造⽅法注入(Constructor Injection)
Setter 注入(Setter Injection)

属性注入

@Controller
public class UserControllerTest {@Autowiredprivate UserService userService;//属性注入public void say(){System.out.println("hello, UserControllerTest");}
}

构造方法注入

只有一个构造方法的时候即使不加@Autowired也可以获取数据,但是要是加一个空的构造方法,会报出空指针异常。
因为程序启动的时候会首先调用无参数的构造方法,如果没有会调用我们写的,但是两个都有的话就会调用无参数的,此时并没有真正new对象,去调用say()方法就会出现空指针异常。
解决办法:就是在想要注入的构造方法中添加@Autowired注解

@Controller
public class UserControllerTest {private UserService userService;@Autowiredpublic UserService(UserService service){this.userService = service;}public void say(){System.out.println("hello, UserControllerTest");}
}

Setter注入

@Controller
public class UserControllerTest {private UserService userService;@Autowiredpublic void setUserService(UserService service){this.userService = service;}public void say(){System.out.println("hello, UserControllerTest");}
}

优缺点

  • 属性注入
    优点:简洁,使用方便
    缺点:只能用于 loC 容器,如果是非 loC 容器不可用,并且只有在使用的时候才会出现 NPE(空指针异常);不能注入一个Final修饰的属性。
  • 构造函数注入(Spring4.x推荐)
    优点:可以注入final修饰的属性;注入的对象不会被修改依赖对象;在使用前一定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法;通用性好,构造方法是JDK支持的,所以更换任何框架都是适用的。
    缺点:注入多个对象时,代码会比较繁琐。
  • Setter注入
    优点:方便在类实例之后,重新对该对象进行配置或者注入。
    缺点:不能注入一个Final修饰的属性;注入对象可能会被改变,因为setter方法可能会被多次调用,就有被修改的风险。

@Autowired存在的问题

Student 实体类

@Data
public class Student {private String name;private Integer id;public Student() {}public Student(String name) {this.name = name;}public Student(String name, Integer id) {this.name = name;this.id = id;}

BeanConfig类

@Configuration
public class BeanConfig {@Beanpublic Student StudentInfo() {return new Student("wh",01);}@Beanpublic Student StudentInfo2() {return new Student("Bob",02);}
}

DomeController类

@Controller
public class DomeController {@Autowiredprivate Student student;public void say(){System.out.println(student);}
}

启动类

@SpringBootApplication
public class SpringIocApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringIocApplication.class, args);DomeController bean = context.getBean(DomeController.class);bean.say();}
}

运行
在这里插入图片描述

报错的原因是,非唯一的 Bean 对象
解释:@Autowired是先按照类型去注入,匹配到多个对象时,再按照名称去注入。

如果明确注入对象的名称,则可以正确打印该学生信息。

@Controller
public class DomeController {@Autowiredprivate Student StudentInfo2;public void say(){System.out.println(StudentInfo2);}
}

那当没有明确注入对象的名称,又想得到正确结果我们可以怎么做?
有以下几种解决方案:

@Primary
@Qualifier
@Resource

@Primary

使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。
直接加到Bean注入的方法上。

@Primary
@Bean
public Student StudentInfo() {return new Student("wh", 01);
}

@Qualifier

使⽤@Qualifier注解:指定当前要注⼊的bean对象。 在@Qualifier的value属性中,指定注⼊的bean 的名称。
@Qualifier注解不能单独使⽤,必须配合@Autowired使用。

@Controller
public class DomeController {@Qualifier("StudentInfo2")@Autowiredprivate Student student;public void say(){System.out.println(student);}
}

@Resource

本身就是依赖注入注解,是按照bean的名称进行注入。

@Controller
public class DomeController {@Resource(name = "StudentInfo")private Student student;public void say(){System.out.println(student);}
}

面试–@Autowird 与 @Resource的区别

  1. @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解。
  2. @Autowired 默认是按照类型注入,而@Resource是按照名称注入,相比于 @Autowired 来说, @Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。

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

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

相关文章

通付盾风控智能体(RiskAgent): 神烦狗(DOGE)

在数字化业务高速发展的今天&#xff0c;风控系统已成为企业抵御黑产、欺诈、保障交易安全的核心防线。然而传统风控面临人力依赖高与策略滞后性等挑战&#xff0c;数据分析师需每日从海量数据中手动提炼风险特征、设计防护规则&#xff0c;耗时费力&#xff1b;新策略从发现到…

大模型论文:Language Models are Unsupervised Multitask Learners(GPT2)

大模型论文&#xff1a;Language Models are Unsupervised Multitask Learners(GPT2) 文章地址&#xff1a;https://storage.prod.researchhub.com/uploads/papers/2020/06/01/language-models.pdf 摘要 自然语言处理任务&#xff0c;例如问答、机器翻译、阅读理解和摘要&am…

分布式ID生成方案的深度解析与Java实现

在分布式系统中&#xff0c;生成全局唯一的ID是一项核心需求&#xff0c;广泛应用于订单编号、用户信息、日志追踪等场景。分布式ID不仅需要保证全局唯一性&#xff0c;还要满足高性能、高可用性以及一定的可读性要求。本文将深入探讨分布式ID的概念、设计要点、常见生成方案&a…

记 etcd 无法在docker-compose.yml启动后无法映射数据库目录的问题

1、将etcd 单独提取 Dockerfile&#xff0c;指定配置文件和数据目录 #镜像 FROM bitnami/etcd:3.5.11 #名称 ENV name"etcd" #重启 ENV restart"always" #运行无权限 ENV ALLOW_NONE_AUTHENTICATION"yes" #端口 EXPOSE 2379 2380 #管理员权限才…

怎样才不算干扰球·棒球1号位

在棒球运动中&#xff0c;"干扰球"&#xff08;Interference&#xff09;是指球员或场外人员非法影响了比赛的正常进行。以下情况通常 不构成干扰&#xff0c;属于合法行为或无需判罚&#xff1a; 1. 击跑员&#xff08;Batter-Runner&#xff09;合法跑垒 跑垒限制…

PyTorch实现多输入输出通道的卷积操作

本文通过代码示例详细讲解如何在PyTorch中实现多输入通道和多输出通道的卷积运算&#xff0c;并对比传统卷积与1x1卷积的实现差异。 1. 多输入通道互相关运算 当输入包含多个通道时&#xff0c;卷积核需要对每个通道分别进行互相关运算&#xff0c;最后将结果相加。以下是实现…

深入解析 MySQL 中的日期时间函数:DATE_FORMAT 与时间查询优化、DATE_ADD、CONCAT

深入解析 MySQL 中的日期时间函数&#xff1a;DATE_FORMAT 与时间查询优化 在数据库管理和应用开发中&#xff0c;日期和时间的处理是不可或缺的一部分。MySQL 提供了多种日期和时间函数来满足不同的需求&#xff0c;其中DATE_FORMAT函数以其强大的日期格式化能力&#xff0c;…

SSH配置优化:提升本地内网Linux服务器远程连接速度与稳定性

文章目录 引言一. 理解SSH连接过程与影响因素二. 服务器端SSH配置优化三. 客户端SSH配置优化四. 高级技巧五. 内网穿透突破公网IP限制总结 引言 SSH (Secure Shell) 是一种网络协议&#xff0c;用于加密的网络服务&#xff0c;常用于远程登录和管理Linux服务器。对于本地内网的…

BERT - MLM 和 NSP

本节代码将实现BERT模型的两个主要预训练任务&#xff1a;掩码语言模型&#xff08;Masked Language Model, MLM&#xff09; 和 下一句预测&#xff08;Next Sentence Prediction, NSP&#xff09;。 1. create_nsp_dataset 函数 这个函数用于生成NSP任务的数据集。 def cr…

“实时滚动”插件:一个简单的基于vue.js的无缝滚动

1、参考连接&#xff1a; 安装 | vue-seamless-scroll 2、使用步骤&#xff1a; 第一步&#xff1a;安装 yarn add vue-seamless-scroll 第二步&#xff1a;引入 import vueSeamlessScroll from vue-seamless-scroll/src 第三步&#xff1a;注册 components: { vueSeamless…

【蓝桥杯】赛前练习

1. 排序 import os import sysn=int(input()) data=list(map(int,input().split(" "))) data.sort() for d in data:print(d,end=" ") print() for d in data[::-1]:print(d,end=" ")2. 走迷宫BFS import os import sys from collections import…

pyTorch-迁移学习-学习率衰减-四种天气图片多分类问题

目录 1.导包 2.加载数据、拼接训练、测试数据的文件夹路径 3.数据预处理 3.1 transforms.Compose数据转化 3.2分类存储的图片数据创建dataloader torchvision.datasets.ImageFolder torch.utils.data.DataLoader 4.加载预训练好的模型(迁移学习) 4.1固定、修改预训练…

第十四届蓝桥杯大赛软件赛国赛Python大学B组题解

文章目录 弹珠堆放划分偶串交易账本背包问题翻转最大阶梯最长回文前后缀贸易航线困局 弹珠堆放 递推式 a i a i − 1 i a_ia_{i-1}i ai​ai−1​i&#xff0c; n 20230610 n20230610 n20230610非常小&#xff0c;直接模拟 答案等于 494 494 494 划分 因为总和为 1 e 6 1e6…

Python 和 JavaScript两种语言的相似部分-由DeepSeek产生

Python 和 JavaScript 作为两种流行的编程语言&#xff0c;虽然在设计目标和应用场景上有差异&#xff08;Python 偏向后端和脚本&#xff0c;JavaScript 偏向前端和动态交互&#xff09;&#xff0c;但它们的语法存在许多相似之处。以下是两者在语法上的主要共同点及对比&…

改善 Maven 的依赖性

大家好&#xff0c;这里是架构资源栈&#xff01;点击上方关注&#xff0c;添加“星标”&#xff0c;一起学习大厂前沿架构&#xff01; 建议使用mvn dependency:analyze命令来摆脱已声明但未使用的依赖项&#xff1a; 还有另一个用例&#xff0c; mvn dependency:analyze 它可…

【SQL】子查询详解(附例题)

子查询 子查询的表示形式为&#xff1a;(SELECT 语句)&#xff0c;它是IN、EXISTS等运算符的运算数&#xff0c;它也出现于FROM子句和VALUES子句。包含子查询的查询叫做嵌套查询。嵌套查询分为相关嵌套查询和不想关嵌套查询 WHERE子句中的子查询 比较运算符 子查询的结果是…

Stable Diffusion 扩展知识实操整合

本文的例子都是基于秋叶整合包打开的webui实现的 一、ADetailer——改善人脸扭曲、恶心 After detailer插件可以自动检测生成图片的人脸&#xff0c;针对人脸自动上蒙版&#xff0c;自动进行重绘&#xff0c;整个流程一气呵成&#xff0c;因此可以避免许多重复的操作。除此之…

freertos内存管理简要概述

概述 内存管理的重要性 在嵌入式系统中&#xff0c;内存资源通常是有限的。合理的内存管理可以确保系统高效、稳定地运行&#xff0c;避免因内存泄漏、碎片化等问题导致系统崩溃或性能下降。FreeRTOS 的内存管理机制有助于开发者灵活地分配和释放内存&#xff0c;提高内存利用…

按规则批量修改文件扩展名、删除扩展名或添加扩展名

文件的扩展名是多种多样的&#xff0c;有些不同文件的扩展名之间相互是可以直接转换的。我们工作当中最常见的就是 doc 与 docx、xls 与 xlsx、jpg 与 jpeg、html 与 htm 等等&#xff0c;这些格式在大部分场景下都是可以相互转换 能直接兼容的。我们今天要介绍的就是如何按照一…

热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索

654.最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大…