当前位置: 首页 > news >正文

[Spring] SpringMVC 简介(一)

目录

一、SpringMVC 简介

1、什么是 MVC

2、什么是 SpringMVC

3、SpringMVC 实现原理

4、SpringMVC 的特点

二、简单案例

1、引入依赖

2、在 web.xml 中配置前端控制器 DispatcherServlet

3、创建 SpringMVC 的配置文件

 4、创建请求控制器

5、测试页面

6、访问不到 Controller

7、修改项目结构

三、@RequestMapping

1、@RequestMapping 注解的功能

2、@RequestMapping 注解的位置

3、@RequestMapping 的 value 属性

4、@RequestMapping 的 method 属性

5、SpringMVC 支持 ant 风格的路径

6、@RequestMapping 中的占位符(@PathVariable 重点)

四、SpringMVC 获取请求参数

1、通过 ServletAPI 获取

2、通过设置方法形参名与请求参数名一致

3、通过 POJO 获取请求参数

4、解决中文乱码


一、SpringMVC 简介

1、什么是 MVC

记住一句话:SpringMVC 封装了 Servlet

(1)MVC

M:Model,模型层,指工程中的JavaBean,作用是处理数据

JavaBean分为两类:

  • 一类称为实体类Bean:专门存储业务数据的,如 Student、User 等
  • 一类称为业务处理 Bean:指 Service 或 Dao 对象,专门用于处理业务逻辑和数据访问。

V:View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据

C:Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器

(2)工作流程

用户通过视图层发送请求到服务器,在服务器中请求被 Controller 接收,Controller 调用相应的 Model 层处理请求,处理完毕将结果返回到 Controller,Controller 再根据请求处理的结果找到相应的 View 视图,渲染数据后最终响应给浏览器。

2、什么是 SpringMVC

(1)三层架构

我们通过浏览器访问前端页面,前端页面通过异步提交的方式,发送请求到后端服务器,后端服务器采用 web层(servlet)、业务层(service)、数据层(dao)的三层架构形式进行开发,其中数据的交互使用 json 来传输。

  • 我们最开始在数据层使用的是 Jdbc 技术,而 MyBatis 就是对 Jdbc 技术的又一层封装,也可以称之为数据层框架。
  • 现在所讲的 SpringMVC,在 web 层中与 servlet 的关系,就好比 Jdbc 与 MyBatis 的关系,也就是一个表现层的框架。

(2)SpringMVC 是一种基于 Java 实现 MVC 模型的轻量级 Web 框架

  • 框架:半成品软件,加速开发过程。
  • 相比较 Servlet,使用更简单,开发更便捷,更灵活

3、SpringMVC 实现原理

(1)用户发送请求到前端控制器 DispatcherServlet

  • DispatcherServlet的作用:接收请求,调用其它组件处理请求,响应结果,相当于转发器、中央处理器,是整个流程控制的中心

(2)DispatcherServlet 收到请求后调用处理器映射器 HandlerMapping

  • 处理器映射器 HandlerMapping 找到 Controller 的具体方法(可以根据 xml 配置或注解进行查找),并将该方法返回给 DispatcherServlet;

(3)DispatcherServlet 调用处理器适配器 HandlerAdapter

(3-1)HandlerAdapter 经过适配调用具体的 Controller 的方法;(Controller--> service --> Dao --> 数据库)

  • Controller 执行完成后返回 ModelAndView;
  • Model:模型数据,即 Controller 处理的结果,是一个 Map
  • View:逻辑视图名,即 负责展示结果的 html 页面的名字

(3-2)HandlerAdapter 将 Controller 执行的结果 ModelAndView 返回给 DispatcherServlet

(4)DispatcherServlet 将执行的结果 ModelAndView 传给视图解析器 ViewReslover

  • 视图解析器 ViewReslover 根据逻辑视图 View 解析后返回具体 html 页面

(5)DispatcherServlet 根据 Model 对 View 进行渲染(将模型数据填充至视图中)

  • DispatcherServlet 将填充了数据的网页响应给用户

4、SpringMVC 的特点

  • Spring 家族原生产品,与 IOC 容器等基础设施无缝对接
  • 基于原生的Servlet,通过了功能强大的前端控制器DispatcherServlet,对请求和响应进行统一处理(不在需要自己编写 Servlet 处理请求)
  • 代码清新简洁,大幅度提升开发效率
  • 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
  • 性能卓著,尤其适合现代大型、超大型互联网项目要求

二、简单案例

1、引入依赖

即将使用 Thymeleaf 视图模板技术,因此引入了相关依赖。

<dependencies><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.1</version></dependency><!-- Spring5和Thymeleaf整合包 --><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring5</artifactId><version>3.0.12.RELEASE</version></dependency>
</dependencies>

2、在 web.xml 中配置前端控制器 DispatcherServlet

<servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

(1)标签中使用 / 和 /* 的区别

  • /:匹配浏览器向服务器发送的所有请求,不包括 jsp;
  • /*:匹配浏览器向服务器发送的所有请求,包括 jsp;

JSP 是通过 Tomcat 的 JspServlet 来处理的,然后 JspServlet 将响应结果回传给页面,所以 DispatcherServlet 处理不了 jsp 页面。

  • 因此 DispatcherServlet 要使用 /,而不能用 /*。
  • 在使用过滤器时,若需要对所有请求进行过滤,就需要使用 /* 的写法。

3、创建 SpringMVC 的配置文件

(1)SpringMVC 的配置文件的默认地址和名称:

  • 地址:在 WEB-INF 目录下;
  • 名称:<servlet-name>-servlet.xml;(<servlet-name> 是 web.xml 内 DispatcherServlet 的值,比如 DispatcherServlet-servlet.xml)

实际开发中,通常将 SpringMVC 的配置文件放在 resource 目录下

(2)Thymeleaf 模板文件路径

  • 物理视图:视图前缀 + 逻辑视图 + 视图后缀;
  • 逻辑视图:把物理视图中的视图前缀和视图后缀去掉,得到的就是逻辑视图;

我们通常在 WEB-INF 目录下建立一个 templates 目录,用来存放视图模板。而访问 WEB-INF 目录下的资源,需要服务器端进行请求转发,所以逻辑视图就被用上了。 

(3)配置文件

<?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:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 配置Thymeleaf视图解析器 --><bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/> <!-- 优先级 --><property name="characterEncoding" value="UTF-8"/><property name="templateEngine"> <!-- 模板引擎 --><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"> <!-- 模板解析器 --><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!-- 视图前缀 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 视图后缀 --><property name="suffix" value=".html"/><!-- 以 html5 作为模板 --><property name="templateMode" value="HTML5"/><property name="characterEncoding" value="UTF-8" /></bean></property></bean></property></bean></beans>

 4、创建请求控制器

(1)@Controller

由于 DispatcherServlet 已经对浏览器发送的请求进行了统一的处理,所以我们不需要自己创建 Servlet 去处理请求。

但是具体的请求有不同的处理过程,因此需要创建处理具体请求的类,即请求控制器

package com.demo.controller;import org.springframework.stereotype.Controller;@Controller
public class HelloController {}

SpringMVC 的控制器由一个 POJO(普通的Java类)担任,因此需要通过 @Controller 注解将其标识为一个控制层组件,交给 Spring 的 IOC 容器管理,此时 SpringMVC 才能够识别控制器的存在。

(2)@RequestMapping

请求映射:把浏览器发送的请求,映射到具体方法去处理。

(2-1)其中的 value 属性值,填写的是方法的路径:

  • /:代表该路径为绝对路径;
  • / 由服务器解析:代表 http://ip:port/工程名;
  • / 由浏览器解析:代表当前服务器路径,http://ip:port;

当 value 的值,与浏览器发送的请求路径是一样的,说明这个方法就是用来处理该请求的方法。

(2-2)方法返回值

前面我们说到,服务器端进行请求转发需要用到逻辑视图,那么怎么用呢?

其实我们返回的字符串,就是所谓的逻辑视图。紧接着 web.xml 中配置的视图解析器,就会将这个返回值用视图前缀和视图后缀组装起来,最终形成了请求转发的地址。

package com.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class HelloController {@RequestMapping("/")public String index() {System.out.println("index");// 返回逻辑视图return "index";}@RequestMapping("/hello")public String hello() {return "hello";}}

5、测试页面

注意:测试页面使用了 Thymeleaf 的语法。

(1)index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1> index 页面 </h1><a th:href="@{/hello}"> 测试 SpringMVC </a><br/><a href="/hello"> 测试绝对路径</a>
</body>
</html>

(2)hello.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1> hello </h1>
</body>
</html>

(3)项目结构

6、访问不到 Controller

SpringMVC 访问不到 Controller,网上有很多解决方法,如果再尝试之后都没有办法解决(比如我),那么可以尝试删除当前工件,新建一个该项目的工件。

有关更多项目结构问题,可以查看:https://www.bilibili.com/video/BV1Ry4y1574R?p=15 

按照其中的步骤,设置 web 目录即可。

7、修改项目结构

将 DispatcherServlet-servlet.xml 文件,放到 resource 目录下,然后在 web.xml 文件中作如下修改:

<servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:SpringMVC.xml</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

(1)contextConfigLocation

这是正常项目中 Spring 配置文件放置在 resource 目录下的写法。

(2)<load-on-startup>

由于 DispatcherServlet 需要初始化的内容非常地多,因此将其放在服务器启动期间去初始化,可以节省页面访问的时间。

三、@RequestMapping

1、@RequestMapping 注解的功能

  • @RequestMapping 注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。
  • SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。

2、@RequestMapping 注解的位置

  • @RequestMapping 仅仅标识了方法,那么可以直接访问到这个方法;
  • @RequestMapping 标识了类,那么想要访问方法,请求路径就必须添加标识类上面写的路径;

如下面代码所示:

@Controller
@RequestMapping("/manager")
public class ManagerController {@RequestMapping("/user")public String user() {return "user";}
}

请求路径为:

http://ip:port/工程路径/manager/user
  • 而如果在两个不同的 Controller 里面有相同的 @RequestMapping,那么会直接报错。
  • 但是对于同一个资源,只要请求路径不同,那么就不会报错,比如:/manager/hello 和 /hello,都可以访问到 hello.html。

3、@RequestMapping 的 value 属性

一个 Servlet 可以处理多个请求(在 url-pattern 中设置),同样的,value 属性值为数组的时候,就可以接收多个请求。

@Controller
@RequestMapping("/manager")
public class ManagerController {@RequestMapping({"/hello", "/also_hello"})public String hello() {return "hello";}
}

4、@RequestMapping 的 method 属性

  • method 属性通过请求的请求方式(get 或 post)匹配请求映射。
  • method 属性是一个 RequestMethod 类型的数组,表示该请求映射能够匹配多种请求方式的请求。

若当前请求的请求地址满足请求映射的 value 属性,但是请求方式不满足 method 属性,则浏览器报错 405。

@RequestMapping(value = {"/hello"},method = {RequestMethod.GET, RequestMethod.POST}
)
public String hello() {return "hello";
}

(1)对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解

  • 处理get请求的映射–>@GetMapping
  • 处理post请求的映射–>@PostMapping
  • 处理put请求的映射–>@PutMapping
  • 处理delete请求的映射–>@DeleteMapping

(2)常用的请求方式有get,post,put,delete

  • 但是目前浏览器只支持 get 和 post,若在 form 表单提交时,为 method 设置了其他请求方式的字符串(put 或 delete),则按照默认的请求方式 get 处理
  • 若要发送 put 和 delete 请求,则需要通过 spring 提供的过滤器 HiddenHttpMethodFilter,在 RESTful 部分会讲到

5、SpringMVC 支持 ant 风格的路径

ant 风格的路径是指:

  • ?:表示任意的单个字符
  • *:表示任意的0个或多个字符
  • **:表示任意的一层或多层目录

在 @RequestMapping 中,value 属性值可以包含上面三种格式。

@RequestMapping("/a?a/test/ant")
public String testAnt() {return "hello";
}
@RequestMapping("/a?a/*/ant")
public String testAnt2() {return "hello";
}
@RequestMapping("**ant")
public String testAnt3() {return "hello";
}

以上代码,下面三种请求路径都能访问到 hello.html: 

6、@RequestMapping 中的占位符(@PathVariable 重点)

@RequestMapping 修饰的方法想要使用请求参数的方法有很多,其中一种就是在 @RequestMapping 的 value 属性中使用“占位符{ }”。

(1)书写格式

假设请求路径 /func 可以访问到目标方法,通常我们添加参数,请求路径会这么写:

/func?id=1&name=admin

而如果使用 @RequestMapping,那么应该这么写:

/func/1/admin

(2)对应地,在代码中要怎么获取到这两个参数呢?

@RequestMapping("/func/{id}/{name}")
public String func(@PathVariable("id") String id, @PathVariable("name") String name) {System.out.println("id: " + id);System.out.println("name: " + name);return "index";
}

(3)请求路径:

(4)输出结果:

四、SpringMVC 获取请求参数

1、通过 ServletAPI 获取

如果要使用 servlet 相关的方法,那么给方法的参数列表添加 request 等参数即可。

(1)测试代码

(1-1)controller(success.html 可以自己写)

@RequestMapping("/login")
public String login(HttpServletRequest req) {System.out.println("username: " + req.getParameter("username"));System.out.println("password: " + req.getParameter("password"));return "success"; // return 相当于请求转发
}

(1-2)index.html

<form th:action="@{/login}" method="post"><input type="text" name="username"/> <br/><input type="password" name="password"/> <br/><input type="submit" value="submit"/>
</form>

 (2)输出结果

2、通过设置方法形参名与请求参数名一致

在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参。

(1)测试代码

(1-1)controller

@RequestMapping("/login/param")
public String loginParam(String username, String password) {System.out.println("username: " + username);System.out.println("password: " + password);return "success";
}

(1-2)index.html(改了 action)

<form th:action="@{/login/param}" method="post"><input type="text" name="username"/> <br/><input type="password" name="password"/> <br/><input type="submit" value="submit"/>
</form>

(2)输出结果

 (3)@RequestParam

  • 如果在请求参数名方法参数名不一致,那么就会导致方法获取不到值,值为 null。

为了保证一定能获取到对应值,可以使用 @RequestParam:

public String loginParam(@RequestParam(value = "username", required = true) String username, String password)
  • value = "userName":设置从 userName 请求参数获取值,并且方法参数名不再需要与请求参数名一致
  • required = true:设置没有该请求参数,则不能发送请求;(默认就是 true)
  • required = false:设置可以不传该请求参数,若不传递,则值为 null
  • defaultValue:设置未传递参数时的默认值;(与 required 无关)

(4)@RequestHeader

  • 将请求头信息与控制器方法的参数进行绑定,当为方法参数加上 @RequestHeader,那么该参数就不再对应请求参数,而是对应请求头信息。

用法与 @RequestParam 一致。

@RequestMapping("/login/param")
public String loginParam(@RequestParam(value = "username") String name,String password,@RequestHeader(value = "referer") String refer) {System.out.println("username: " + name);System.out.println("password: " + password);System.out.println("referer: " + refer);return "success";
}

(5)@CookieValue

  • 将 cookie 数据与控制器方法的参数进行绑定,因为一开始还没有 JSESSIONID 的 cookie,因此需要先调用一次 request.getSession() 来创建 JSESSIONID 的 cookie。

用法与 @RequestParam 一致。

@RequestMapping("/login")
public String login(HttpServletRequest req) {HttpSession session = req.getSession();System.out.println("创建 JSESSIONID: " + session.getId());return "index"; // return 相当于请求转发
}@RequestMapping("/login/param")
public String loginParam(@RequestParam(value = "username") String name,String password,@RequestHeader(value = "referer") String refer,@CookieValue(value = "JSESSIONID") String sessionId) {System.out.println("username: " + name);System.out.println("password: " + password);System.out.println("referer: " + refer);System.out.println("JSESSIONID: " + sessionId);return "success";
}

(5-1)先访问 /login,使服务器创建 JSESSIONID

(5-2)输入 username、password,点击登录,观察控制台输出

3、通过 POJO 获取请求参数

通常情况下,我们会有非常多的方法参数需要设置/获取请求参数值,如果都用 @RequestParam 这几个注解来获取,也非常麻烦。

(1)解决方法

  • 我们可以用一个 pojo 类当作方法的参数,让这个 pojo 类的成员变量名,与请求参数名一致,就可以将请求参数值,封装到 pojo 类的成员变量。
@RequestMapping("/login/pojo")
public String pojo(User user) {System.out.println(user);return "success";
}

(2) 输出结果

4、解决中文乱码

因为没有 request 和 response,所以无法用这两个变量设置。

并且就算使用 request 和 response,其实也无法设置,因为其他参数都是已经从请求中获取到了,再设置也没有用了。

注意:

  • Tomcat 7.0 的 get 和 post 请求都有乱码;Tomcat 8.0 以上 get 请求没有乱码,post 请求会乱码。

(1)解决方法

解决获取请求参数的乱码问题,可以使用 SpringMVC 提供的编码过滤器 CharacterEncodingFilter,再所有 servlet 处理之前,拦截所有请求,然后设置编码。

需要注意的是,CharacterEncodingFilter 必须在 web.xml 中进行注册:

  • init-param 设置 encoding = utf-8,相当于 request.CharacterSetEncoding("UTF-8");
  • init-param 设置 forceEncoding = true,会把 request 和 response 都设置成 encoding(前面那个);

(2)web.xml 配置文件

<!--配置springMVC的编码过滤器-->
<filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceResponseEncoding</param-name><param-value>true</param-value></init-param>
</filter>
<filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

(3)输出结果

相关文章:

[Spring] SpringMVC 简介(一)

目录 一、SpringMVC 简介 1、什么是 MVC 2、什么是 SpringMVC 3、SpringMVC 实现原理 4、SpringMVC 的特点 二、简单案例 1、引入依赖 2、在 web.xml 中配置前端控制器 DispatcherServlet 3、创建 SpringMVC 的配置文件 4、创建请求控制器 5、测试页面 6、访问不到 …...

机器学习基础之《回归与聚类算法(2)—欠拟合与过拟合》

一、背景 1、上一篇说正规方程的时候&#xff0c;实际情况中使用很少&#xff0c;主要原因它不能解决过拟合。 2、训练集上表现的好&#xff0c;测试集上表现不好—过拟合 二、欠拟合和过拟合 1、欠拟合 训练集&#xff1a;有3个训练集&#xff0c;告诉机器都是天鹅 机器学…...

flutter dio 请求封装(空安全)

一、添加依赖 dio: ^5.3.2二、请求封装 class HttpHelper {static Dio? mDio;static BaseOptions? options;static HttpHelper? httpHelper;CancelToken cancelToken CancelToken();static const String GET get;static const String POST post;static const String PU…...

chatgpt GPT-4V是如何实现语音对话的

直接上代码 https://chat.openai.com/voice/get_token 1. 请求内容 Request:GET /voice/get_token HTTP/1.1 Host: ios.chat.openai.com Content-Type: application/json Cookie: _puiduser***Fc9T:16962276****Nph%2Fb**SU%3D; _uasid"Z0FBQUF***nPT0"; __cf_bmBUg…...

C++项目-求水仙花数

求水仙花数 #include <iostream> using namespace std;int main() {int n 100;do {int a 0;int b 0;int c 0;a n % 10; //个位b n / 10 % 10; //十位c n / 100 % 10; //百位if (a * a * a b * b * b c * c * c n) {cout << n << endl;}…...

从零开始基于LLM构建智能问答系统的方案

本文首发于博客 LLM应用开发实践 一个完整的基于 LLM 的端到端问答系统&#xff0c;应该包括用户输入检验、问题分流、模型响应、回答质量评估、Prompt 迭代、回归测试&#xff0c;随着规模增大&#xff0c;围绕 Prompt 的版本管理、自动化测试和安全防护也是重要的话题&#x…...

Android---Synchronized 和 ReentrantLock

Synchronized 基本使用 1. 修饰实例方法 public class SynchronizedMethods{private int sum 0;public synchronized void calculate(){sum sum 1;} } 这种情况下的锁对象是当前实例对象&#xff0c;因此只有同一个实例对象调用此方法才会产生互斥效果&#xff1b;不同的…...

【解题报告】牛客挑战赛70 maimai

题目链接 这个挑战赛的 F F F是我出的&#xff0c;最后 zhoukangyang 爆标了。。。orzorz 记所有有颜色的边的属性集合 S S S 。 首先在外层容斥&#xff0c;枚举 S ∈ [ 0 , 2 w ) S\in [0,2^w) S∈[0,2w)&#xff0c;计算被覆盖的的边中不包含 S S S 中属性&#xff0c…...

算启新程 智享未来 | 紫光展锐携手中国移动共创数智未来

10月11日-13日&#xff0c;2023年中国移动全球合作伙伴大会在广州举行&#xff0c;此次大会以“算启新程 智享未来”为主题&#xff0c;与合作伙伴一起共商融合创新&#xff0c;共创数智未来。作为中国移动每年规模最大、最具影响力的盛会&#xff0c;吸引了数百家世界500强企业…...

thinkphp5.1 获取缓存cache(‘cache_name‘)特别慢,php 7.0 unserialize 特别慢

thinkphp5.1 获取缓存cache(‘cache_name’)特别慢&#xff0c;php 7.0 unserialize 特别慢 场景&#xff1a; 项目中大量使用了缓存&#xff0c;本地运行非常快&#xff0c;二三百毫秒&#xff0c;部署到服务器后 一个表格请求就七八秒&#xff0c;最初猜想是数据库查询慢&am…...

【Linux】UNIX 术语中,换页与交换的区别和Linux 术语中,换页与交换的区别?

UNIX换页和交换的区别 在UNIX中&#xff0c;换页&#xff08;Paging&#xff09;是一种内存管理技术&#xff0c;用于在程序运行时动态地将其代码和数据从磁盘加载到内存中。当程序需要访问的页面不在内存中时&#xff0c;就会发生页错误&#xff08;page error&#xff09;&a…...

零基础学python之集合

文章目录 集合1、创建集合2、集合常见操作方法2、1 增加数据2、2 删除数据2、3 查找数据 3、总结 集合 目标 创建集合集合数据的特点集合的常见操作 1、创建集合 创建集合使用{}或set()&#xff0c; 但是如果要创建空集合只能使用set()&#xff0c;因为{}用来创建空字典。 …...

PromptScript:轻量级 DSL 脚本,加速多样化的 LLM 测试与验证

TL&#xff1b;DR 版本 PromptScript 是一个轻量级的 Prompt 调试用的 DSL &#xff08;Yaml&#xff09;脚本&#xff0c;以用于快速使用、构建 Prompt。 PromptScript 文档&#xff1a;https://framework.unitmesh.cc/prompt-script Why PromptScript &#xff1f; 几个月前&…...

强化学习(Reinforcement Learning)与策略梯度(Policy Gradient)

写在前面&#xff1a;本篇博文的内容来自李宏毅机器学习课程与自己的理解&#xff0c;同时还参考了一些其他博客(懒得放链接)。博文的内容主要用于自己学习与记录。 1 强化学习的基本框架 强化学习(Reinforcement Learning, RL)主要由智能体(Agent/Actor)、环境(Environment)、…...

JUC之ForkJoin并行处理框架

ForkJoin并行处理框架 Fork/Join 它可以将一个大的任务拆分成多个子任务进行并行处理&#xff0c;最后将子任务结果合并成最后的计算结果&#xff0c;并进行输出。 类似于mapreduce 其实&#xff0c;在Java 8中引入的并行流计算&#xff0c;内部就是采用的ForkJoinPool来实现…...

【牛客面试必刷TOP101】Day8.BM33 二叉树的镜像和BM36 判断是不是平衡二叉树

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;牛客面试必刷TOP101 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&…...

CSS padding(填充)

CSS padding&#xff08;填充&#xff09;是一个简写属性&#xff0c;定义元素边框与元素内容之间的空间&#xff0c;即上下左右的内边距。 padding&#xff08;填充&#xff09; 当元素的 padding&#xff08;填充&#xff09;内边距被清除时&#xff0c;所释放的区域将会受到…...

C语言达到什么水平才能从事单片机工作

C语言达到什么水平才能从事单片机工作 从事单片机工作需要具备一定的C语言编程水平。以下是几个关键要点&#xff1a;基本C语言知识&#xff1a; 掌握C语言的基本语法、数据类型、运算符、流控制语句和函数等基本概念。最近很多小伙伴找我&#xff0c;说想要一些C语言学习资料&…...

Java架构师理解SAAS和多租户

目录 1 云服务的三种模式1.1 IaaS(基础设施即服务)1.2 PaaS(平台即服务)1.3 SaaS(软件即服务)1.4 区别与联系2 SaaS的概述2.1 Saas详解2.2 应用领域与行业前景2.3 Saas与传统软件对比3 多租户SaaS平台的数据库方案3.1 多租户是什么3.2 需求分析3.3 多租户的数据库方案分析…...

关于Java线程池相关面试题

【更多面试资料请加微信号&#xff1a;suns45】 https://flowus.cn/share/f6cd2cbe-627a-435f-a6e5-1395333f92e8 【FlowUs 息流】&#x1f4e3;suns-Java资料 访问密码&#xff1a;【请加微信号&#xff1a;suns45】 ————线程相关的面试题———— 0&#xff1a;创建线…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...

麒麟系统使用-进行.NET开发

文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的&#xff0c;如果需要进行.NET开发&#xff0c;则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET&#xff0c;所以要进…...