Spring常见面试题知识点总结(三)

在这里插入图片描述

7. Spring MVC:

MVC架构的概念。

MVC(Model-View-Controller)是一种软件设计模式,旨在将应用程序分为三个主要组成部分,以实现更好的代码组织、可维护性和可扩展性。每个组件有着不同的职责,相互之间解耦,使得代码更易于理解和维护。

以下是MVC架构的主要组成部分:

  1. 模型(Model):

    • 模型代表应用程序的数据和业务逻辑。它负责处理数据的存储、检索、更新和计算等任务。模型是应用程序的核心,独立于用户界面和用户输入。
  2. 视图(View):

    • 视图是用户界面的表示,负责将模型的数据呈现给用户。视图通常是用户交互的部分,负责显示数据、接收用户输入,并将用户的操作传递给控制器。视图不包含业务逻辑,仅关注用户界面的呈现。
  3. 控制器(Controller):

    • 控制器是模型和视图之间的中介,负责接收用户输入并相应地更新模型和视图。它包含应用程序的业务逻辑,处理用户的操作,并协调模型和视图之间的交互。控制器将用户的输入转化为对模型的操作,并根据模型的变化更新视图。

MVC的工作流程通常如下:

  1. 用户与视图交互,例如通过界面上的按钮、表单等。
  2. 视图将用户的操作传递给控制器。
  3. 控制器接收用户输入,处理业务逻辑,并相应地更新模型。
  4. 模型的变化被通知给视图。
  5. 视图重新渲染以反映模型的变化,同时等待用户的下一次操作。

MVC的优势在于:

  • 分离关注点(Separation of Concerns): 将数据、业务逻辑和用户界面分离,使得每个组件可以独立开发和测试,提高了代码的可维护性和可扩展性。

  • 代码重用: 模型和视图之间是松耦合的,可以更容易地重用模型和视图的组件。

  • 可测试性: 由于模型、视图和控制器各自独立,可以更轻松地进行单元测试和集成测试。

MVC是一种通用的设计模式,广泛应用于构建各种软件应用,特别是在Web开发中,MVC被广泛应用于构建Web应用框架,例如Spring MVC、Django等。

Spring MVC的主要组件,如控制器、模型、视图解析器等。

Spring MVC是Spring框架中用于构建Web应用的模块,采用了MVC(Model-View-Controller)设计模式。以下是Spring MVC的主要组件:

  1. 前端控制器(DispatcherServlet):

    • 前端控制器是Spring MVC的入口点,负责接收HTTP请求并将请求分发给合适的处理器(Controller)。它可以配置多个拦截器,用于在请求处理前或处理后执行一些共用的逻辑。
  2. 处理器映射(HandlerMapping):

    • 处理器映射负责将请求映射到具体的处理器(Controller)。Spring MVC支持多种处理器映射,包括注解映射、URL映射等。常见的处理器映射有RequestMappingHandlerMappingBeanNameUrlHandlerMapping等。
  3. 处理器(Controller):

    • 处理器负责处理具体的业务逻辑,接收请求并返回相应的响应。在Spring MVC中,处理器可以是一个POJO类,通过@Controller注解标识,并使用@RequestMapping注解定义处理的URL路径。
@Controller
@RequestMapping("/example")
public class ExampleController {@GetMapping("/hello")public String hello() {return "helloPage";}
}
  1. 视图解析器(ViewResolver):
    • 视图解析器负责将逻辑视图名称解析为具体的视图对象。Spring MVC支持多种视图解析器,例如InternalResourceViewResolverThymeleafViewResolver等。配置视图解析器可以在Spring配置文件中进行。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/" /><property name="suffix" value=".jsp" />
</bean>
  1. 视图(View):

    • 视图负责渲染模型数据并生成最终的响应内容。Spring MVC支持多种视图类型,包括JSP、Thymeleaf、FreeMarker等。视图通常由视图解析器根据逻辑视图名称解析而来。
  2. 模型(Model):

    • 模型是处理器方法的参数之一,用于向视图传递数据。在Spring MVC中,模型通常是Model接口的实例,可以通过添加属性来传递数据。
@Controller
@RequestMapping("/example")
public class ExampleController {@GetMapping("/hello")public String hello(Model model) {model.addAttribute("message", "Hello, Spring MVC!");return "helloPage";}
}
  1. 视图解析器(ViewResolver):
    • 视图解析器负责将逻辑视图名称解析为具体的视图对象。Spring MVC支持多种视图解析器,例如InternalResourceViewResolverThymeleafViewResolver等。配置视图解析器可以在Spring配置文件中进行。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/" /><property name="suffix" value=".jsp" />
</bean>
  1. 拦截器(Interceptor):
    • 拦截器是一种可以在请求处理前、处理后以及渲染视图前执行一些逻辑的组件。通过实现HandlerInterceptor接口,可以自定义拦截器,并在配置中注册。
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理前执行逻辑return true; // 继续执行后续操作}
}

以上是Spring MVC的主要组件,它们协同工作以构建灵活且可扩展的Web应用。通过合理配置这些组件,可以实现清晰的代码结构、灵活的业务逻辑处理和可定制的视图渲染。

如何声明和映射请求处理方法。

在Spring MVC中,可以使用@RequestMapping注解声明和映射请求处理方法。这个注解用于标识一个方法可以处理特定URL路径的HTTP请求。以下是一些基本的用法:

  1. 基本的RequestMapping:
    • 使用@RequestMapping标注在方法上,指定处理的URL路径。可以通过valuepath属性来指定路径。
@Controller
@RequestMapping("/example")
public class ExampleController {@RequestMapping("/hello")public String hello() {return "helloPage";}
}
  1. 多个URL映射:
    • 可以使用value属性指定多个URL路径,或者使用path属性,它们可以接受一个字符串数组。
@Controller
@RequestMapping({"/example", "/sample"})
public class ExampleController {@RequestMapping("/hello")public String hello() {return "helloPage";}
}
  1. HTTP方法限定:
    • 可以使用method属性限定处理的HTTP方法,可以是GET、POST等。以下示例限定只处理GET请求。
@Controller
@RequestMapping("/example")
public class ExampleController {@RequestMapping(value = "/hello", method = RequestMethod.GET)public String hello() {return "helloPage";}
}
  1. 请求参数映射:
    • 可以使用params属性指定请求参数的条件。以下示例限定只有带有name参数的请求才会被处理。
@Controller
@RequestMapping("/example")
public class ExampleController {@RequestMapping(value = "/hello", params = "name")public String hello() {return "helloPage";}
}
  1. 路径变量(PathVariable):
    • 可以在方法参数上使用@PathVariable注解获取路径中的变量值。路径变量是用花括号{}括起来的。
@Controller
@RequestMapping("/example")
public class ExampleController {@RequestMapping("/hello/{name}")public String hello(@PathVariable String name) {// 使用路径中的变量值return "helloPage";}
}

这些是一些常用的@RequestMapping注解的用法,还有其他属性和注解,用于处理更复杂的场景。在实际开发中,可以根据需要合理配置@RequestMapping以及其他相关的注解,以实现灵活的请求处理。

拦截器的使用。

拦截器(Interceptors)是Spring MVC中的一种强大的机制,允许在处理器方法执行前后、渲染视图前进行自定义的操作。拦截器提供了一种全局的、可重用的方式来处理横切关注点,比如日志记录、权限检查、性能监控等。以下是在Spring MVC中使用拦截器的基本步骤:

  1. 定义拦截器类:
    • 创建一个实现HandlerInterceptor接口的拦截器类,实现其中的方法。通常,preHandle在处理器方法执行前被调用,postHandle在处理器方法执行后,视图渲染前被调用,afterCompletion在整个请求完成后被调用。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在处理器方法执行前执行,返回 true 表示继续执行后续操作,返回 false 表示中断请求处理return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在处理器方法执行后,视图渲染前执行}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在整个请求完成后执行}
}
  1. 配置拦截器:
    • 在Spring MVC配置文件(通常是ServletContext.xmlWebApplicationConfig.java)中配置拦截器。可以使用<mvc:interceptors>元素进行配置。
<mvc:interceptors><mvc:interceptor><mvc:mapping path="/secure/**" /><bean class="com.example.MyInterceptor" /></mvc:interceptor>
</mvc:interceptors>

上述配置表示将/secure/**路径下的请求交给MyInterceptor拦截器处理。

  1. 拦截器执行顺序:
    • 拦截器的执行顺序与它们在配置文件中的顺序有关。可以通过在<mvc:interceptor>元素中使用order属性指定拦截器的执行顺序,数值小的先执行。
<mvc:interceptor><mvc:mapping path="/secure/**" /><bean class="com.example.MyInterceptor" /><mvc:order value="1" />
</mvc:interceptor>
  1. 使用preHandle进行逻辑判断:
    • preHandle方法中,可以进行一些逻辑判断,如果返回false,则后续的请求处理将被中断。
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在处理器方法执行前执行,返回 true 表示继续执行后续操作,返回 false 表示中断请求处理if (!userIsAuthenticated(request)) {response.sendRedirect("/login");return false;}return true;
}

上述示例中,如果用户未认证,将重定向到登录页面,并中断请求处理。

拦截器的使用使得我们能够在请求处理的不同阶段插入自定义逻辑,提高了代码的可重用性和可维护性。

RESTful风格的控制器。

在Spring MVC中,可以通过使用@RestController注解创建RESTful风格的控制器。@RestController@Controller@ResponseBody的组合,表示这是一个处理REST请求的控制器,并且方法的返回值将直接作为响应体返回给客户端。

以下是一个简单的例子,演示如何创建RESTful风格的控制器:

import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/books")
public class BookController {// GET请求,获取所有图书@GetMappingpublic List<Book> getAllBooks() {// 返回所有图书的列表}// GET请求,根据ID获取单个图书@GetMapping("/{id}")public Book getBookById(@PathVariable Long id) {// 返回指定ID的图书}// POST请求,添加新图书@PostMappingpublic ResponseEntity<Book> addBook(@RequestBody Book book) {// 处理添加图书的逻辑// 返回201 Created状态码和新添加的图书对象return ResponseEntity.status(HttpStatus.CREATED).body(savedBook);}// PUT请求,更新图书信息@PutMapping("/{id}")public ResponseEntity<Book> updateBook(@PathVariable Long id, @RequestBody Book book) {// 处理更新图书的逻辑// 返回200 OK状态码和更新后的图书对象return ResponseEntity.ok(updatedBook);}// DELETE请求,删除图书@DeleteMapping("/{id}")public ResponseEntity<Void> deleteBook(@PathVariable Long id) {// 处理删除图书的逻辑// 返回204 No Content状态码,表示删除成功return ResponseEntity.noContent().build();}
}

在上述例子中:

  • @RestController注解标识这是一个RESTful控制器。
  • @RequestMapping("/api/books")指定了控制器处理的基本路径。
  • @GetMapping@PostMapping@PutMapping@DeleteMapping分别标识处理GET、POST、PUT、DELETE请求的方法。
  • @PathVariable用于获取URL中的路径变量。
  • @RequestBody用于接收请求体中的JSON数据,通常用于POST和PUT请求。

此外,方法的返回值类型为List<Book>Book等,Spring MVC会自动将它们转换为JSON格式,并作为响应体返回给客户端。

这样的RESTful风格的控制器使得API设计更加清晰,并符合REST原则,使得客户端与服务端之间的通信更加简洁明了。

8. Spring Boot:

Spring Boot的目标和设计原则。

Spring Boot 的主要目标是简化 Spring 应用程序的开发和部署,通过提供约定大于配置的方式,让开发者更专注于业务逻辑的实现而不必过多关注框架配置。

Spring Boot 的设计原则包括:

  1. 约定大于配置(Convention Over Configuration):

    • Spring Boot采用了许多默认配置,遵循约定大于配置的原则。这意味着在大多数情况下,开发者无需进行繁琐的配置,只需按照约定的方式组织代码和资源,Spring Boot就能自动识别和配置。
  2. 快速开发(Rapid Development):

    • Spring Boot旨在提供快速的开发体验,通过自动配置和快速开发的特性,使得开发者可以更迅速地构建应用程序。
  3. 自动配置(Auto-Configuration):

    • Spring Boot利用自动配置机制,根据项目的依赖和项目结构自动配置应用程序。如果开发者愿意,也可以覆盖或扩展这些自动配置。
  4. 嵌入式Web服务器(Embedded Web Server):

    • Spring Boot支持嵌入式Web服务器(如Tomcat、Jetty、Undertow),这意味着应用程序可以作为独立的JAR文件运行,无需外部Web服务器。这简化了应用程序的部署和维护。
  5. 微服务支持(Microservices):

    • Spring Boot适用于构建微服务架构,提供了一些特性和工具,如Spring Cloud,来简化微服务应用程序的开发和部署。
  6. 开箱即用(Out-of-the-Box):

    • Spring Boot提供了一系列的“启动器”(Starters),这是预配置的Maven或Gradle项目,包含了特定功能的依赖关系。这使得开发者可以轻松地添加常用的库和框架,例如数据库、消息队列等。
  7. 无代码生成(No Code Generation):

    • Spring Boot不需要代码生成,通过利用注解和约定,可以在不生成大量XML配置的情况下完成很多工作。
  8. 健康检查和监控(Health Check and Metrics):

    • Spring Boot提供了用于健康检查和监控的端点,使得应用程序的运行状态更容易监控。

总体而言,Spring Boot的设计原则旨在提供一种简化和快速开发的方式,使得开发者可以更专注于业务逻辑的实现,而不必花费过多的精力在框架的配置和集成上。

如何创建和配置Spring Boot应用。

创建和配置Spring Boot应用通常涉及以下步骤:

步骤1:创建Spring Boot项目

  1. 使用Spring Initializr:

    • 使用Spring Initializr网站或在集成开发环境(IDE)中选择Spring Boot项目模板,填写项目的基本信息,选择需要的依赖关系,然后生成项目。
  2. 使用命令行工具:

    • 使用Spring Boot提供的命令行工具(Spring Boot CLI),执行spring init命令生成项目。

步骤2:项目结构和文件

创建项目后,你将得到一个基本的项目结构,其中包含主要的Java源代码、资源文件和配置文件。

步骤3:配置应用程序

  1. application.propertiesapplication.yml

    • src/main/resources目录下创建一个application.propertiesapplication.yml文件,用于配置应用程序的属性。你可以在这里设置数据库连接、端口号、日志级别等。
    # application.yml 示例
    server:port: 8080spring:datasource:url: jdbc:mysql://localhost:3306/mydatabaseusername: rootpassword: secretjpa:hibernate:ddl-auto: update
    
  2. 其他配置文件:

    • 除了application.propertiesapplication.yml外,你还可以创建其他自定义的配置文件,并通过@PropertySource注解加载这些文件。

步骤4:创建Spring Boot应用

  1. 主应用类:

    • src/main/java目录下创建一个主应用类,通常带有@SpringBootApplication注解。这个类包含main方法,是启动应用程序的入口。
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
    public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
    }
    
  2. 添加业务代码:

    • 根据项目需求,在src/main/java下创建业务逻辑的代码,包括控制器、服务、实体等。

步骤5:运行应用程序

  1. 使用IDE:

    • 在集成开发环境(IDE)中,可以直接运行主应用类的main方法。
  2. 使用命令行:

    • 在项目的根目录下执行mvn spring-boot:run命令,或者使用java -jar运行打包好的JAR文件。
  3. 访问应用:

    • 应用程序启动后,默认端口是8080,可以在浏览器中访问http://localhost:8080查看应用程序的响应。

这些步骤覆盖了Spring Boot应用的创建和基本配置。随着项目的发展,你可能需要更详细的配置,包括数据库配置、安全配置、日志配置等。Spring Boot提供了丰富的配置选项和自动配置机制,使得这些配置变得简单和灵活。

自动配置和约定优于配置的原则。

自动配置和约定优于配置是Spring Boot框架的两个核心设计原则,它们旨在简化和加速应用程序的开发和部署过程。

1. 自动配置(Auto-Configuration):

Spring Boot通过自动配置机制尽可能地减少了对应用程序配置的需求。在使用自动配置时,框架会根据项目的依赖和项目结构,自动完成许多常见的配置工作。主要的特点包括:

  • 智能推断: Spring Boot能够根据应用程序的上下文和环境,智能地推断出合理的默认配置。例如,如果项目中存在H2数据库的依赖,Spring Boot会自动配置一个嵌入式H2数据库。

  • 条件化配置: 自动配置是条件化的,即只有在满足特定条件的情况下才会生效。这可以通过使用@Conditional注解来实现,确保只有在满足条件时才会应用配置。

  • 启动器(Starters): Spring Boot提供了一系列预先配置好的“启动器”,这是一组常用库和框架的依赖关系。通过使用这些启动器,开发者可以快速添加对数据库、消息队列、缓存等的支持,而无需手动配置。

  • 自定义扩展: 开发者可以根据自己的需求添加自定义的自动配置。通过实现@Configuration注解的类,可以在Spring Boot启动时进行自定义配置。

2. 约定优于配置(Convention Over Configuration):

约定优于配置是一种开发范式,它依赖于制定良好的约定,从而减少开发者需要做的配置工作。在Spring Boot中,采用了以下约定:

  • 项目结构: Spring Boot建议使用一种标准的项目结构,这样它可以根据约定来自动扫描和配置组件。例如,将主应用程序类放在src/main/java目录下。

  • 命名规范: 框架遵循一些命名规范,例如在application.propertiesapplication.yml中使用特定的属性名,以便自动配置能够按照约定进行解析。

  • 默认值: Spring Boot为许多配置属性提供了合理的默认值,这使得大多数应用程序可以使用默认配置而无需额外配置。

  • 注解和接口: 使用注解和接口来约定一些功能的实现方式,例如@Controller注解用于标识控制器,@Service用于标识服务等。

这两个原则共同作用,使得Spring Boot应用程序更易于开发、维护和部署。通过减少手动配置的需求,开发者可以更专注于业务逻辑的实现,同时保持了足够的灵活性,以适应特定场景的自定义配置。

Spring Boot Starter的概念。

Spring Boot Starter 是 Spring Boot 框架的一个核心概念,它是一种预先配置好的依赖关系集合,用于简化项目的依赖管理和配置。Starter 使得添加对特定功能的支持变得非常简单,开发者可以通过添加适当的 Starter 来引入对数据库、消息队列、Web 开发等方面的支持。

Spring Boot Starter 具有以下特点:

  1. 自包含性: Starter 是自包含的,它包含了特定功能的所有依赖关系。例如,如果你想要使用 Spring Boot Starter Data JPA 来支持数据库访问,只需添加该 Starter 作为依赖,Spring Boot 会自动配置所需的所有库和设置。

  2. 约定优于配置: Starter 遵循约定优于配置的原则,它对依赖关系和配置进行了默认约定,让开发者可以更专注于业务逻辑的实现。

  3. 简化配置: Starter 预配置了一组常用的配置选项,使得在项目中使用特定功能变得更加简单。开发者无需手动添加复杂的配置,只需引入 Starter 并进行必要的定制。

  4. 模块化: Spring Boot Starter 是模块化的,你可以根据项目的需要选择性地引入不同的 Starter。每个 Starter 都关注于特定的功能领域,如 Web、数据访问、安全等。

  5. 简化版本管理: Spring Boot 提供了一种简化版本管理的方式。通过使用 Spring Boot Parent 作为项目的父项目,可以避免手动管理各个 Starter 的版本,框架会自动管理版本兼容性。

一些常见的 Spring Boot Starter 包括:

  • spring-boot-starter-web:用于构建 Web 应用程序的 Starter。
  • spring-boot-starter-data-jpa:用于支持使用 JPA 访问数据库的 Starter。
  • spring-boot-starter-security:用于添加安全性支持的 Starter。
  • spring-boot-starter-amqp:用于支持使用 RabbitMQ 的 Starter。
  • spring-boot-starter-test:用于支持单元测试的 Starter。

使用 Spring Boot Starter 是创建和管理 Spring Boot 项目的一种推荐方式,它使得项目的依赖关系清晰、可维护,并提供了一致的开发体验。

9. Spring中的注解:

常用注解的含义和用法,如@Component@Autowired@Controller@Service@Repository等。

Spring 框架提供了一系列注解,用于简化配置、实现依赖注入和定义组件等。以下是一些常用注解的含义和用法:

  1. @Component

    • 含义: 用于将一个类标识为 Spring 组件,表示它会被 Spring 自动扫描并纳入到应用上下文中。
    • 用法: 在类上加上 @Component 注解,例如 @Component("myComponent") 可以指定组件的名称。
  2. @Autowired

    • 含义: 用于进行依赖注入,自动连接到 Spring 上下文中匹配的 bean。
    • 用法: 可以用在构造方法、Setter 方法、字段上,示例:@Autowired private MyService myService;
  3. @Controller

    • 含义: 用于标识一个类是 Spring MVC 控制器,处理 HTTP 请求。
    • 用法: 在类上加上 @Controller 注解。
  4. @Service

    • 含义: 用于标识一个类是业务逻辑层的服务组件。
    • 用法: 在类上加上 @Service 注解。
  5. @Repository

    • 含义: 用于标识一个类是数据访问层的仓库组件,通常用于与数据库交互。
    • 用法: 在类上加上 @Repository 注解。
  6. @Configuration

    • 含义: 用于定义配置类,替代 XML 配置文件。被注解的类内部包含有一个或多个带有 @Bean 注解的方法。
    • 用法: 在类上加上 @Configuration 注解。
  7. @Bean

    • 含义: 用于定义在配置类中创建的 Bean 对象,Spring 容器会管理这些 Bean。
    • 用法: 在配置类的方法上加上 @Bean 注解。
  8. @RequestMapping

    • 含义: 用于映射 HTTP 请求到处理方法上,指定 URL 路径和请求方法。
    • 用法: 在处理方法上加上 @RequestMapping 注解。
  9. @PathVariable

    • 含义: 用于获取 URL 中的路径变量的值。
    • 用法: 在方法参数上加上 @PathVariable 注解。
  10. @RequestParam

  • 含义: 用于获取请求参数的值。
  • 用法: 在方法参数上加上 @RequestParam 注解。
  1. @ResponseBody
  • 含义: 表示方法的返回结果直接写入 HTTP 响应体中,而不是跳转到视图。
  • 用法: 在方法上加上 @ResponseBody 注解。
  1. @RestController
  • 含义:@Controller@ResponseBody 的组合注解,用于标识一个控制器类,并且所有方法都以 JSON 形式返回响应。
  • 用法: 在类上加上 @RestController 注解。

这些注解是 Spring 框架中常用的一部分,通过使用它们,可以简化配置和开发过程,提高代码的可读性和可维护性。

自定义注解的创建和使用。

在 Java 中,你可以通过使用 @interface 关键字创建自定义注解。以下是自定义注解的创建和使用步骤:

创建自定义注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD) // 指定注解可以用于方法上
@Retention(RetentionPolicy.RUNTIME) // 指定注解会保留在运行时
public @interface MyCustomAnnotation {// 定义注解的属性String value() default ""; // 注解属性可以有默认值int count() default 0;
}

上述代码定义了一个名为 MyCustomAnnotation 的自定义注解,该注解可以用于方法上,有两个属性:valuecount

使用自定义注解:

public class MyClass {@MyCustomAnnotation(value = "Hello", count = 5)public void myMethod() {// 方法实现}
}

在上述示例中,MyClass 类的 myMethod 方法上使用了自定义注解 @MyCustomAnnotation,并指定了注解属性的值。

读取注解信息:

你可以使用反射来读取方法上的自定义注解及其属性值:

import java.lang.reflect.Method;public class AnnotationReader {public static void main(String[] args) {MyClass myClass = new MyClass();Method[] methods = MyClass.class.getDeclaredMethods();for (Method method : methods) {if (method.isAnnotationPresent(MyCustomAnnotation.class)) {MyCustomAnnotation annotation = method.getAnnotation(MyCustomAnnotation.class);System.out.println("Value: " + annotation.value());System.out.println("Count: " + annotation.count());}}}
}

在上述代码中,使用 getDeclaredMethods 获取类的所有方法,然后通过 isAnnotationPresent 判断方法是否使用了 @MyCustomAnnotation 注解,最后通过 getAnnotation 获取注解实例并读取注解的属性值。

自定义注解可以为代码添加元数据,提高代码的可读性和可维护性,同时允许开发者在不改变代码逻辑的情况下,通过注解进行一些特定的处理。

元注解的了解,如@Target@Retention等。

元注解是用于注解其他注解的注解,它们提供了对注解自身的元数据信息,如适用范围、生命周期等。Java 中有一些预定义的元注解,其中两个常用的是 @Target@Retention

@Target 注解:

@Target 用于指定注解可以应用的程序元素类型,即注解可以放在哪里。它接收一个 ElementType 类型的数组作为参数,表示注解可以用于以下位置之一或多个:

  • ElementType.TYPE: 类、接口或枚举声明
  • ElementType.FIELD: 字段声明(包括枚举常量)
  • ElementType.METHOD: 方法声明
  • ElementType.PARAMETER: 参数声明
  • ElementType.CONSTRUCTOR: 构造方法声明
  • ElementType.LOCAL_VARIABLE: 局部变量声明
  • ElementType.ANNOTATION_TYPE: 注解类型声明
  • ElementType.PACKAGE: 包声明

示例:

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation {// 注解内容
}

上述示例中,@MyAnnotation 注解可以应用于类、接口或枚举声明,以及方法声明。

@Retention 注解:

@Retention 用于指定注解的生命周期,即注解在什么级别保存。它接收一个 RetentionPolicy 类型的参数,有三个值可选:

  • RetentionPolicy.SOURCE: 注解仅在源代码中存在,编译时丢弃。
  • RetentionPolicy.CLASS: 注解在编译时保留,但不会被加载到 JVM 中运行。
  • RetentionPolicy.RUNTIME: 注解在运行时保留,可以通过反射读取。

示例:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)
public @interface MyRuntimeAnnotation {// 注解内容
}

上述示例中,@MyRuntimeAnnotation 注解在运行时保留,可以通过反射读取。

这两个元注解常常一起使用,例如,你想要定义一个在运行时保留的注解,可以使用 @Target 指定它可以应用于的元素类型,然后使用 @Retention 指定它在运行时保留。

10. Spring Security:

Spring Security的目标和功能。

Spring Security 是一个基于 Spring 的安全性框架,旨在为 Java 应用程序提供全面的身份验证、授权和其他安全性特性。其目标是简化和加强应用程序的安全性,提供一套强大而灵活的工具,帮助开发者构建安全可靠的应用。

Spring Security 的目标:

  1. 全面的安全性支持: 提供一系列全面的安全性特性,包括身份验证、授权、防护攻击、会话管理等,以满足不同应用的安全需求。

  2. 简化安全配置: 提供简单的配置选项和默认配置,使得开发者能够轻松地集成安全性功能而无需深入理解底层机制。

  3. 与 Spring 生态系统集成: 与 Spring 框架无缝集成,能够与 Spring Boot、Spring MVC、Spring Data 等组件协同工作。

  4. 灵活的扩展性: 提供灵活的扩展机制,允许开发者通过自定义过滤器、拦截器、身份验证提供者等来适应特定的业务需求。

  5. 支持多种身份验证方式: 支持常见的身份验证方式,包括用户名密码认证、LDAP 认证、OAuth 2.0、OpenID Connect 等。

  6. 强调应用程序级别的安全性: 强调在应用程序级别实现安全性,而不仅仅是在基础设施或网络层次上。

Spring Security 的功能:

  1. 身份验证(Authentication): 提供了多种身份验证方式,包括基本身份验证、表单登录、OAuth 2.0、OpenID Connect 等。支持定制化身份验证过程。

  2. 授权(Authorization): 提供基于角色和权限的授权机制,支持细粒度的访问控制。可以通过注解或配置进行权限控制。

  3. 攻击防护(Attack Protection): 防护常见的安全攻击,包括 CSRF(跨站请求伪造)防护、点击劫持防护等。

  4. 会话管理(Session Management): 提供会话管理机制,包括限制同时登录的设备数、会话超时控制等。

  5. 单点登录(Single Sign-On,SSO): 支持单点登录,可以集成其他身份验证提供者,如 OAuth 2.0、OpenID Connect。

  6. 安全事件与审计日志(Security Events and Auditing): 记录安全事件和审计日志,便于监控和分析系统的安全性。

  7. 密码编码(Password Encoding): 提供密码编码和加密机制,确保用户密码的安全性。

  8. Remember-Me 功能: 支持 Remember-Me 功能,使用户在一定时间内无需重新登录。

  9. 跨域资源共享(Cross-Origin Resource Sharing,CORS): 支持跨域资源共享配置,用于处理跨域请求。

总体而言,Spring Security 提供了一套全面、灵活、易于使用的安全性工具,帮助开发者在应用程序中轻松实现复杂的安全性需求。

如何配置基本的身份验证和授权。

在 Spring Security 中配置基本的身份验证和授权通常包括以下步骤:

步骤 1: 添加 Spring Security 依赖

在项目的 Maven 或 Gradle 配置文件中添加 Spring Security 依赖:

<!-- Maven 项目 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
// Gradle 项目
implementation 'org.springframework.boot:spring-boot-starter-security'

步骤 2: 配置身份验证

在 Spring Boot 项目中,Spring Security 的基本身份验证已经默认启用。你可以通过在 application.propertiesapplication.yml 文件中设置用户名和密码来进行简单的身份验证:

# application.yml
spring:security:user:name: userpassword: password

如果你希望使用自定义的用户名和密码,你可以通过编写配置类来实现:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.core.userdetails.UserDetailsService;@Configuration
public class SecurityConfig {@Beanpublic UserDetailsService userDetailsService() {// 提供自定义的 UserDetailsService 实现// 返回一个包含用户名、密码和角色的 UserDetails 对象}@Beanpublic PasswordEncoder passwordEncoder() {// 使用 BCryptPasswordEncoder 进行密码加密return new BCryptPasswordEncoder();}
}

步骤 3: 配置授权

如果你希望对不同的请求路径进行授权,可以通过配置 HttpSecurity 实现。以下是一个简单的示例:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/public/**").permitAll() // 不需要身份验证的路径.anyRequest().authenticated() // 其他路径需要身份验证.and().formLogin().loginPage("/login") // 指定自定义的登录页面.permitAll().and().logout().permitAll();}
}

在上述示例中,antMatchers 用于配置不需要身份验证的路径,authenticated 表示其他路径都需要身份验证。formLogin 配置了登录页面,logout 配置了登出。

步骤 4: 启用 CSRF 保护(可选)

Spring Security 默认启用了 CSRF 保护,以防止跨站请求伪造攻击。如果你的应用需要使用 CSRF 保护,可以添加以下配置:

@Override
protected void configure(HttpSecurity http) throws Exception {http// ... 其他配置 ....and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}

上述示例中,使用 CookieCsrfTokenRepository 配置了 CSRF 保护,并设置了 withHttpOnlyFalse(),以允许 JavaScript 访问 CSRF 令牌。

以上是一个简单的 Spring Security 配置示例,你可以根据具体需求进行定制和扩展。如果需要更高级的身份验证和授权功能,你可能需要实现自定义的 UserDetailsServiceAuthenticationProvider 或其他相关接口。

自定义身份验证和授权逻辑。

要自定义身份验证和授权逻辑,你可以扩展 Spring Security 提供的相关类,并覆盖适当的方法。以下是一个简单的示例,展示了如何自定义身份验证和授权。

自定义用户详情服务(UserDetailsService)

首先,你可以实现自定义的 UserDetailsService 接口,该接口用于从数据库或其他数据源加载用户信息。

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;@Service
public class CustomUserDetailsService implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 从数据库或其他数据源加载用户信息// 这里简单起见,创建一个 UserDetails 对象返回return org.springframework.security.core.userdetails.User.withUsername(username).password("{noop}password") // 使用 "{noop}" 表示密码不加密.roles("USER").build();}
}

自定义身份验证提供者(AuthenticationProvider)

接下来,你可以实现自定义的 AuthenticationProvider 接口,该接口用于处理身份验证逻辑。

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {// 自定义身份验证逻辑// 在这里检查用户提供的凭证是否有效// 如果有效,返回一个包含用户信息和权限的 Authentication 对象// 如果无效,抛出 AuthenticationException// 示例中简单地返回传入的 Authentication 对象return authentication;}@Overridepublic boolean supports(Class<?> authentication) {// 返回 true 表示该身份验证提供者支持传入的 Authentication 类型// 通常,这里可以检查传入的类型是否为自定义的某个 Authentication 类型return true;}
}

配置 Spring Security

最后,你需要在 Spring Security 配置中使用这些自定义的服务和提供者。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
@EnableWebSecurity
public class SecurityConfig {@Autowiredprivate UserDetailsService userDetailsService;@Autowiredprivate CustomAuthenticationProvider customAuthenticationProvider;@Beanpublic PasswordEncoder passwordEncoder() {// 这里使用 NoOpPasswordEncoder,实际中应该使用更安全的密码编码方式return NoOpPasswordEncoder.getInstance();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 使用自定义的 UserDetailsService 进行身份验证auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());// 添加自定义的 AuthenticationProviderauth.authenticationProvider(customAuthenticationProvider);}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}
}

上述示例中,CustomAuthenticationProviderCustomUserDetailsService 被注入到了 SecurityConfig 配置类中,并在 configure 方法中进行了配置。这样,Spring Security 就会使用你自定义的身份验证和用户详情服务了。请注意,这只是一个简单的示例,实际中可能需要更复杂的逻辑和更安全的密码编码方式。

使用@Secured@PreAuthorize注解进行方法级别的安全控制。

@Secured@PreAuthorize 是 Spring Security 提供的两个常用注解,用于在方法级别进行安全控制。

@Secured 注解

@Secured 注解可以直接在方法上使用,用于声明该方法的访问需要具备哪些角色。例如:

import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;@Service
public class MySecureService {@Secured("ROLE_USER")public String securedMethod() {return "This method is secured.";}
}

上述例子中,securedMethod 方法被 @Secured("ROLE_USER") 注解保护,只有具备 “ROLE_USER” 角色的用户才能访问。

@PreAuthorize 和 @PostAuthorize 注解

@PreAuthorize@PostAuthorize 注解更加灵活,可以使用 SpEL(Spring Expression Language)来定义更复杂的安全表达式。

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;@Service
public class MySecureService {@PreAuthorize("hasRole('USER') and #username == authentication.name")public String preAuthorizeMethod(String username) {return "This method is secured using @PreAuthorize.";}
}

上述例子中,preAuthorizeMethod 方法使用 @PreAuthorize 注解,其中的 SpEL 表达式要求用户具备 “USER” 角色并且提供的 username 参数与当前认证的用户名相匹配。

配置启用方法级别的安全控制

要在 Spring Security 配置中启用方法级别的安全控制,需要在配置类上使用 @EnableGlobalMethodSecurity 注解,并指定相应的注解类型,如 @Secured@PreAuthorize 等:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class MethodSecurityConfig {// 配置启用方法级别的安全控制
}

上述配置中,@EnableGlobalMethodSecuritysecuredEnabled 参数用于启用 @Secured 注解,prePostEnabled 参数用于启用 @PreAuthorize@PostAuthorize 注解。

这样配置后,你就可以在方法上使用 @Secured@PreAuthorize 等注解进行方法级别的安全控制了。

11. 异常处理:

Spring中异常处理的概念。

在 Spring 中,异常处理是一个重要的概念,它允许你在应用程序中捕获、处理和传播异常。Spring 提供了多种方式来处理异常,其中包括声明式和编程式两种方式。

以下是 Spring 中异常处理的主要概念:

  1. 异常处理流程: 在 Spring 应用中,异常处理的流程通常包括抛出异常、捕获异常、处理异常和传播异常。这个流程可以通过配置和编程的方式来实现。

  2. 声明式异常处理: Spring 提供了声明式异常处理的方式,其中最常见的是通过 @ExceptionHandler 注解实现方法级别的异常处理。你可以在控制器类中定义一个或多个带有 @ExceptionHandler 注解的方法,用于处理特定类型的异常。

    @Controller
    public class MyController {@ExceptionHandler(MyCustomException.class)public String handleCustomException(MyCustomException ex) {// 处理 MyCustomExceptionreturn "error-page";}
    }
    
  3. 全局异常处理器: 你还可以配置全局的异常处理器,通过实现 HandlerExceptionResolver 接口或扩展 SimpleMappingExceptionResolver 等类来捕获并处理所有异常。这种方式可以用于定义全局的错误页面或返回通用的错误信息。

    @Configuration
    public class MyExceptionHandler implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {// 全局异常处理逻辑return new ModelAndView("error-page");}
    }
    
  4. @ControllerAdvice @ControllerAdvice 注解用于定义全局控制器建议,其中可以包含 @ExceptionHandler@InitBinder@ModelAttribute 方法。这样的类可以用于集中管理应用程序中的异常处理。

    @ControllerAdvice
    public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public String handleException(Exception ex) {// 全局异常处理逻辑return "error-page";}
    }
    
  5. @ResponseStatus 通过 @ResponseStatus 注解,你可以指定控制器方法处理异常后的 HTTP 响应状态码。

    @Controller
    public class MyController {@ExceptionHandler(MyCustomException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public String handleCustomException(MyCustomException ex) {// 处理 MyCustomExceptionreturn "error-page";}
    }
    

通过合理的异常处理,你可以提高应用程序的稳定性和可维护性,同时为用户提供更好的用户体验。在实际开发中,根据项目的需求选择合适的异常处理方式是很重要的。

@ExceptionHandler注解的使用。

@ExceptionHandler 注解用于在 Spring MVC 控制器中处理特定类型的异常。当控制器方法抛出指定类型的异常时,@ExceptionHandler 注解的方法将会被调用来处理异常。

以下是 @ExceptionHandler 注解的基本使用方法:

  1. 在控制器类中定义异常处理方法:

    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;@ControllerAdvice
    public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public String handleException(Exception ex, Model model) {// 处理异常逻辑model.addAttribute("errorMessage", "An error occurred: " + ex.getMessage());return "error-page";}
    }
    

    上述代码中,@ControllerAdvice 注解表明这是一个全局控制器建议类,@ExceptionHandler(Exception.class) 注解表示该方法用于处理所有类型的异常。

  2. 传递异常信息到视图:

    在异常处理方法中,你可以使用 Model 对象将异常信息传递到视图。

    model.addAttribute("errorMessage", "An error occurred: " + ex.getMessage());
    

    在视图中,你可以通过 ${errorMessage} 来获取异常信息。

  3. 指定处理特定类型的异常:

    如果你只想处理特定类型的异常,可以在 @ExceptionHandler 注解中指定异常的类型。

    @ExceptionHandler(MyCustomException.class)
    public String handleCustomException(MyCustomException ex, Model model) {// 处理自定义异常逻辑model.addAttribute("errorMessage", "Custom exception occurred: " + ex.getMessage());return "error-page";
    }
    

    这样,handleCustomException 方法就只会处理 MyCustomException 类型的异常。

  4. 返回适当的视图或响应:

    在异常处理方法中,你可以返回一个适当的视图名,Spring MVC 将渲染该视图。你还可以返回 JSON 数据或其他响应,具体取决于你的需求。

    @ExceptionHandler(MyCustomException.class)
    public ResponseEntity<String> handleCustomException(MyCustomException ex) {// 处理自定义异常逻辑return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Custom exception occurred: " + ex.getMessage());
    }
    

    上述代码中,使用 ResponseEntity 可以返回定制的 HTTP 响应。

通过使用 @ExceptionHandler 注解,你可以集中处理应用程序中的异常,并提供一致的错误处理逻辑。

全局异常处理器的配置。

全局异常处理器可以通过实现 HandlerExceptionResolver 接口或者使用 @ControllerAdvice 注解来配置。下面分别介绍这两种方式。

实现 HandlerExceptionResolver 接口

通过实现 HandlerExceptionResolver 接口,你可以自定义全局异常处理器。以下是一个简单的例子:

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyExceptionHandler implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) {ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("errorMessage", "An error occurred: " + ex.getMessage());modelAndView.setViewName("error-page");return modelAndView;}
}

然后,在 Spring 配置文件中进行配置:

<!-- 注册全局异常处理器 -->
<bean id="exceptionResolver" class="com.example.MyExceptionHandler" />

使用 @ControllerAdvice 注解

通过 @ControllerAdvice 注解,你可以在一个类中集中管理全局异常处理逻辑。以下是一个使用 @ControllerAdvice 注解的例子:

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public String handleException(Exception ex, Model model) {model.addAttribute("errorMessage", "An error occurred: " + ex.getMessage());return "error-page";}
}

@ControllerAdvice 注解使得 GlobalExceptionHandler 类成为全局控制器建议,处理整个应用程序的异常。在这个类中,@ExceptionHandler(Exception.class) 注解用于处理所有类型的异常。

配置多个全局异常处理器

如果你想要配置多个全局异常处理器,可以通过多次注册不同的 HandlerExceptionResolver 或使用多个带有 @ControllerAdvice 注解的类。

<!-- 注册多个全局异常处理器 -->
<bean id="exceptionResolver1" class="com.example.MyExceptionHandler1" />
<bean id="exceptionResolver2" class="com.example.MyExceptionHandler2" />

或者使用 @ControllerAdvice 注解:

@ControllerAdvice
public class GlobalExceptionHandler1 {// 处理异常逻辑
}@ControllerAdvice
public class GlobalExceptionHandler2 {// 处理异常逻辑
}

以上两种方式都可以根据需求灵活配置全局异常处理器。全局异常处理器可以帮助你集中处理应用程序中的异常,提供一致的错误处理逻辑。

使用@ControllerAdvice进行全局异常处理。

使用 @ControllerAdvice 注解可以方便地实现全局异常处理。@ControllerAdvice 注解被用于定义一个类,该类可以包含多个 @ExceptionHandler 方法来处理不同类型的异常。以下是一个简单的例子:

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public String handleException(Exception ex, Model model) {model.addAttribute("errorMessage", "An error occurred: " + ex.getMessage());return "error-page";}@ExceptionHandler(NullPointerException.class)public String handleNullPointerException(NullPointerException ex, Model model) {model.addAttribute("errorMessage", "NullPointerException occurred: " + ex.getMessage());return "error-page";}// 添加其他 @ExceptionHandler 方法处理不同类型的异常
}

上述代码中,GlobalExceptionHandler 类使用 @ControllerAdvice 注解,然后定义了两个 @ExceptionHandler 方法,分别处理 ExceptionNullPointerException 类型的异常。这两个方法接收异常对象和 Model 对象,将异常信息放入 Model 中,然后返回一个指定的错误页面。

在这个例子中,handleException 方法处理所有类型的异常,而 handleNullPointerException 方法专门处理 NullPointerException 异常。你可以根据需要添加更多的 @ExceptionHandler 方法来处理其他类型的异常。

在实际应用中,通过 @ControllerAdvice 注解,你可以集中处理应用程序中的异常,提供一致的错误处理逻辑。这样可以提高代码的可维护性和一致性。

在这里插入图片描述

关注公众号 洪都新府笑颜社,发送 “面试题” 即可免费领取一份超全的面试题PDF文件!!!!

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

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

相关文章

YOLO算法

YOLO介绍 YOLO&#xff0c;全称为You Only Look Once: Unified, Real-Time Object Detection&#xff0c;是一种实时目标检测算法。目标检测是计算机视觉领域的一个重要任务&#xff0c;它不仅需要识别图像中的物体类别&#xff0c;还需要确定它们的位置。与分类任务只关注对…

【矩阵】【方向】【素数】3044 出现频率最高的素数

作者推荐 动态规划的时间复杂度优化 本文涉及知识点 素数 矩阵 方向 LeetCode 3044 出现频率最高的素数 给你一个大小为 m x n 、下标从 0 开始的二维矩阵 mat 。在每个单元格&#xff0c;你可以按以下方式生成数字&#xff1a; 最多有 8 条路径可以选择&#xff1a;东&am…

安装 Ubuntu 22.04.3 和 docker

文章目录 一、安装 Ubuntu 22.04.31. 简介2. 下载地址3. 系统安装4. 系统配置 二、安装 Docker1. 安装 docker2. 安装 docker compose3. 配置 docker 一、安装 Ubuntu 22.04.3 1. 简介 Ubuntu 22.04.3 是Linux操作系统的一个版本。LTS 版本支持周期到2032年。 系统要求双核 C…

代码随想录 二叉树第二周

目录 101.对称二叉树 100.相同的树 572.另一棵树的子树 104.二叉树的最大深度 559.N叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数 110.平衡二叉树 257.二叉树的所有路径 101.对称二叉树 101. 对称二叉树 已解答 简单 相关标签 相关企业 给你一…

《求生之路2》服务器如何选择合适的内存和CPU核心数,以避免丢包和延迟高?

根据求生之路2服务器的实际案例分析选择合适的内存和CPU核心数以避免丢包和延迟高的问题&#xff0c;首先需要考虑游戏的类型和对服务器配置的具体要求。《求生之路2》作为一款多人在线射击游戏&#xff0c;其服务器和网络优化对于玩家体验至关重要。 首先&#xff0c;考虑到游…

Java应用程序注册成Linux系统服务后,关闭Java应用程序打印系统日志

Java应用程序有自己的日志框架&#xff0c;有指定位置的日志文件&#xff0c;不需要在系统日志里记录&#xff0c;占用磁盘空间。 1.Linux系统文件目录 /etc/systemd/system/ 找到要修改的Java应用程序服务配置 比如bis-wz-80.service 2.设置不打印日志 StandardOutputnull S…

centos7 搭建 harbor 私有仓库

一、下载安装 1.1、harbor 可以直接从 github 上下载&#xff1a;Releases goharbor/harbor GitHub 这里选择 v2.10.0 的版本 wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz 1.2、解压 tar zxvf harbor-offlin…

L2 网络 Mint Blockchain 正式对外发布测试网

Mint Blockchain 是由 NFTScan Labs 发起的聚焦在 NFT 生态的 L2 网络&#xff0c;致力于促进 NFT 资产协议标准的创新和 NFT 在现实商业应用场景中的大规模采用。 Mint Blockchain 于 2024 年 2 月 28 号正式对外发布测试网&#xff0c;开始全面进入生态开发者测试开发阶段。 …

Springboot项目集成短信验证码(超简单)

操作流程 注册验证码平台创建验证码模版开始集成&#xff08;无需引入第三方库&#xff09; 注册并登陆中昱维信验证码平台 获取AppID和AppKey。 创建验证码模版 创建验证码模版&#xff0c;获取验证码模版id 开始集成 创建controller import org.springframework.web.bi…

MATLAB环境下基于随机游走拉普拉斯算子的快速谱聚类方法

古人有云&#xff0c;物以类聚&#xff0c;在面临信息爆炸问题的今天&#xff0c;对信息类别划分的价值日益显现&#xff0c;并逐步成为学者们的研究热点。分类和聚类是数据挖掘的重要工具&#xff0c;是实现事物类别划分的左右手&#xff0c;聚类又是分类一种特殊的方式。所谓…

CodeWhisperer安装教导--一步到位!以及本人使用Whisperer的初体验。

CodeWhisperer是亚马逊出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。类似 Cursor 和Github AWS CodeWhisperer 亚马逊科技的CodeWhisperer是Amazon于2021年12月推出的一款代码补全工具&#xff0c;与GitHub Copilot类似。主要的功能有:代码补全注释…

猫毛过敏养猫人士的必备养猫好物-宠物空气净化器品牌分享

许多猫奴在与猫相处一段时间后突然对猫毛过敏&#xff0c;这真是令人难受。一些人认为对猫咪过敏是因为它们在空气中飘浮的毛发引起的&#xff0c;但实际上大部分人之所以过敏是因为对猫身上一种微小的蛋白质过敏。这种导致过敏的蛋白质附着在猫咪的一些皮屑上。我们都知道猫咪…

Linux 下安装Jupyter

pip3 install jupyter pip3 install ipython -------------------------------------------- pip3 install jupyterlab jupyter lab pip3 list | grep jupyterlab 启动&#xff1a; python3 -m jupyter lab 2.安装朱皮特 pip3 install -i https://pypi.douban.com/simpl…

高性能的key-value数据库Redis 介绍

Redis 是一个高性能的key-value数据库。 Redis是一个开源的键值存储系统&#xff0c;通常用于缓存和消息传递。它支持多种类型的数据结构&#xff0c;如字符串、列表、集合、散列表和有序集合等。Redis的特点是提供了高性能、灵活性和可伸缩性。 Redis的主要特点包括&#xff…

Pytorch学习 day02(加载数据)

加载数据 * Dataset提供一种方式&#xff1a;来获取数据及其label&#xff0c;给数据进行编号 * Dataloader为神经网络提供不同的数据形式 Dataset的组织形式有很多种&#xff0c;例如&#xff1a; 将label放在文件夹名上&#xff0c;如下&#xff1a; #Dateset # --train #…

Python算法题集_组合总和

Python算法题集_组合总和 题39&#xff1a;组合总和1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【值传递回溯】2) 改进版一【引用传递堆栈回溯】3) 改进版二【过程值列表缓存遍历后检索】 4. 最优算法5. 相关资源 本文为Python算法题集之一的…

.halo勒索病毒的最新威胁:如何恢复您的数据?

尊敬的读者&#xff1a; 随着科技的发展&#xff0c;网络安全已经成为我们日常生活中不可忽视的重要议题。其中&#xff0c;勒索病毒是当前网络安全威胁中的一大挑战&#xff0c;而“.halo”勒索病毒更是近期备受关注的恶意软件之一。本文将介绍关于“.halo”勒索病毒的背景知…

AI新工具(20240227) StickerBaker文本生成贴纸的工具;Mistral Large;Rewind等

StickerBaker - 基于Replicate和Fly.io技术&#xff0c;100%开源的制作贴纸的工具 StickerBaker是一个基于人工智能的贴纸创作工具&#xff0c;允许用户通过输入特定的提示语句生成独特的贴纸。这个工具使用了Replicate平台来生成贴纸&#xff0c;同时依托于Fly.io作为其基础设…

算法项目外包的收费方式

针对算法研究性项目的收费方式和注意事项&#xff0c;这取决于项目的具体性质、规模和所涉及的技术领域。以下是一些常见的收费方式和需要注意的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 收…

Python学习DAY09_文件和异常

文件和异常 实际开发中常常会遇到对数据进行持久化操作的场景&#xff0c;而实现数据持久化最直接简单的方式就是将数据保存到文件中。 在 Python 中实现文件的读写操作其实非常简单&#xff0c;通过 Python 内置的 open 函数&#xff0c;我们可以指定文件名、操作模式、编码信…