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

【学习笔记】手写一个简单的 Spring MVC

目录

一、什么是Spring MVC ?

Spring 和 Spring MVC 的区别?

Spring MVC 的运行流程?

二、实现步骤

1. DispatcherServlet

1. 创建一个中央分发器

拦截所有请求

测试

2. 接管 IOC 容器

1. 创建配置文件

2. 修改 web.xml 配置文件

3. 启动 IOC 容器

2. HandlerMapping

1. 添加映射

1. 创建 RequestMapping 注解

2. 创建映射Bean

3. 使用 RequestMapping 注解

4. 添加映射

2. 处理映射

1. 创建 ResponseBody 注解

2. 创建一个 HTML 文件

3. 使用 ResponseBody 注解

4. 处理映射

3. 测试


一、什么是Spring MVC ?

Spring MVC 是 Spring 的模块之一,Spring MVC 实现了MVC 的设计思想,并继承了 Servlet API 的WEB 框架。当用户在游览器地址栏上输入 url 后,Spring MVC就可以处理用户的请求

Spring 和 Spring MVC 的区别?

Spring 是一个框架,这个框架由不同的模块组成,其中一个模块 就是Spring MVC,Spring 核心是IOC 控制反转,IOC 容器负责对象的创建和依赖注入。

Spring MVC 是基于 MVC 设计来开发web 应用,Spring MVC 将前端发送的请求分发给适当的控制器 Controller,然后根据结果选择合适的视图进行渲染返回

Spring MVC 的运行流程?

  1. 用户发送HTTP请求
  2. 请求到达服务器后,Spring MVC 的中央分发器拦截请求
  3. 中央分发器根据 请求的路径找到对应的 HandlerMapping,确定由哪个 Controller 控制器处理
  4. HandlerMaping 根据请求信息映射到对应的 Controller ,然后返回给中央分发器
  5. 中央分发器把请求交给对应的Controller 控制器,Controller 是Spring MVC的一个组件,它负责处理请求以及响应结果
  6. Controller 控制器调用合适的业务层或 Mapper 层获取数据
  7. Controller 把数据封装成一个ModelAndView对象,然后返回给中央分发器
  8. 中央分发器把ModelAndView对象传给 ViewResolver
  9. ViewResolver 根据视图名称解析出一个 View 对象,然后返回给中央分发器
  10. 中央分发器把 view 对象渲染出来返回给客户端

在 手写 Spring IOC 的基础上再进行扩展,手写一个 Spring MVC

二、实现步骤

1. DispatcherServlet

1. 创建一个中央分发器

package com.shao.MVC;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class DispatcherServlet extends HttpServlet {@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("dispatcherServlet 初始化");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet 开始执行任务了");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet doPost");}}

拦截所有请求

在 Tomcat 的 web.xml 配置文件中配置自定义的中央分发器,拦截所有请求

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>com.shao.MVC.DispatcherServlet</servlet-class></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

测试

在地址栏随便输入一个请求,中央分发器会进行拦截,然后执行初始化和相关方法,初始化只会执行一次

2. 接管 IOC 容器

在 手写 spring IOC 的时候,为了方便测试是在 Servlet 的 doGet 方法中初始化 IOC 容器,现在改为在中央分发器初始化的时候启动 IOC 容器

1. 创建配置文件

在配置文件中配置扫描包路径,然后启动中央分发器的时候把配置文件传过去

2. 修改 web.xml 配置文件

3. 启动 IOC 容器

在中央分发器的初始化方法中启动 IOC 容器

package com.shao.MVC;import com.shao.IOC.ApplicationContext;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Properties;public class DispatcherServlet extends HttpServlet {// 存储 IOC 容器private ApplicationContext applicationContext;private Properties Prop = new Properties();/*** 初始化*/@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("dispatcherServlet 初始化");// 获取传过来的配置文件String configLocation = config.getInitParameter("contextConfigLocation");String fileName = configLocation.replace("classpath:", "");// 调用 loadConfig 方法,传入配置文件名,返回扫描包路径String packagePath = loadConfig(fileName);try {// 启动 IOC 容器applicationContext = new ApplicationContext(packagePath);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet 开始执行任务了");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet doPost");}/*** 加载配置文件,解析配置文件,返回扫描包路径*/public String loadConfig(String path) {// 以流的方式加载配置文件InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(path);String basePackage = "";try {// 解析配置文件中的属性,以键值对的方式存储到 Prop 中Prop.load(resourceAsStream);basePackage = Prop.getProperty("basePackage");} catch (IOException e) {e.printStackTrace();}return basePackage;}}

2. HandlerMapping

HandlerMapping 根据注解的值映射到对应的 Controller 和方法

将 url 和 controller 里面的方法进行映射,存到 HashMap 中,key 是 url ,value 是一个对象,这个对象有 url 对应的 controller 对象和对应的方法

1. 添加映射

1. 创建 RequestMapping 注解

2. 创建映射Bean

package com.shao.MVC;import java.lang.reflect.Method;public class RequestMappingBean {/*** controller 对象*/private Object controller;/*** controller 的方法*/private Method method;public RequestMappingBean(Object controller, Method method) {this.controller = controller;this.method = method;}/*** 获取** @return controller*/public Object getController() {return controller;}/*** 设置** @param controller*/public void setController(Object controller) {this.controller = controller;}/*** 获取** @return method*/public Method getMethod() {return method;}/*** 设置** @param method*/public void setMethod(Method method) {this.method = method;}public String toString() {return "RequestMappingBean{controller = " + controller + ", method = " + method + "}";}
}

3. 使用 RequestMapping 注解

4. 添加映射
package com.shao.MVC;import com.shao.Annotation.Controller;
import com.shao.Annotation.RequestMapping;
import com.shao.IOC.ApplicationContext;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Properties;public class DispatcherServlet extends HttpServlet {// 存储 IOC 容器private ApplicationContext applicationContext;private Properties Prop = new Properties();private HashMap<String, RequestMappingBean> mappingMap = new HashMap<>();/*** 初始化*/@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("dispatcherServlet 初始化");// 获取传过来的配置文件String configLocation = config.getInitParameter("contextConfigLocation");String fileName = configLocation.replace("classpath:", "");// 调用 loadConfig 方法,传入配置文件名,返回扫描包路径String packagePath = loadConfig(fileName);try {// 启动 IOC 容器applicationContext = new ApplicationContext(packagePath);} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 添加映射AddRequestMapping();}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet 开始执行任务了");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet doPost");}/*** 加载配置文件,解析配置文件,返回扫描包路径*/public String loadConfig(String path) {// 以流的方式加载配置文件InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(path);String basePackage = "";try {// 解析配置文件中的属性,以键值对的方式存储到 Prop 中Prop.load(resourceAsStream);basePackage = Prop.getProperty("basePackage");} catch (IOException e) {e.printStackTrace();}return basePackage;}/*** 添加映射* 1. 从 IOC 容器中获取所有带 RequestMapping 注解的 Controller 对象* 2. 获取 Controller 对象中带 RequestMapping 注解的方法* 3. 将 Controller 对象和方法封装为 RequestMappingBean 对象* 4. 构建映射关系,key 是 url,value 是 映射Bean 对象,包括 Controller 对象和方法*/public void AddRequestMapping() {// 获取 IOC 容器的 Bean MapHashMap<String, Object> beanMap = applicationContext.getBeanMap();for (Object bean : beanMap.values()) {// 获取 bean 的 Class 对象Class<?> aClass = bean.getClass();// 判断是否有 @Controller 注解if (!aClass.isAnnotationPresent(Controller.class)) {continue;}// 判断是否有 @RequestMapping 注解if (!aClass.isAnnotationPresent(RequestMapping.class)) {continue;}// 获取类的 @RequestMapping 注解的值String basePath = aClass.getAnnotation(RequestMapping.class).value();// 获取 Controller 对象中的所有方法Method[] methods = aClass.getDeclaredMethods();for (Method method : methods) {// 判断方法上有没有带 @RequestMapping 注解if (!method.isAnnotationPresent(RequestMapping.class)) {continue;}String path = method.getAnnotation(RequestMapping.class).value();// 封装为 映射Bean 对象RequestMappingBean mappingBean = new RequestMappingBean(bean, method);// 构建映射,添加到 Map 中mappingMap.put(basePath + path, mappingBean);}}System.out.println("映射添加完成");System.out.println(mappingMap);}}

2. 处理映射

1. 创建 ResponseBody 注解

2. 创建一个 HTML 文件

3. 使用 ResponseBody 注解

4. 处理映射

为了方便测试,只处理了 GET 方法的映射

package com.shao.MVC;import com.alibaba.fastjson2.JSON;
import com.shao.Annotation.Controller;
import com.shao.Annotation.RequestMapping;
import com.shao.Annotation.ResponseBody;
import com.shao.IOC.ApplicationContext;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Properties;public class DispatcherServlet extends HttpServlet {// 存储 IOC 容器private ApplicationContext applicationContext;private Properties Prop = new Properties();private HashMap<String, RequestMappingBean> mappingMap = new HashMap<>();/*** 初始化*/@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("dispatcherServlet 初始化");// 获取传过来的配置文件String configLocation = config.getInitParameter("contextConfigLocation");String fileName = configLocation.replace("classpath:", "");// 调用 loadConfig 方法,传入配置文件名,返回扫描包路径String packagePath = loadConfig(fileName);try {// 启动 IOC 容器applicationContext = new ApplicationContext(packagePath);} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 添加映射AddRequestMapping();}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet 开始执行任务了");// 处理请求HandlerMapping(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("dispatcherServlet doPost");}/*** 加载配置文件,解析配置文件,返回扫描包路径*/public String loadConfig(String path) {// 以流的方式加载配置文件InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(path);String basePackage = "";try {// 解析配置文件中的属性,以键值对的方式存储到 Prop 中Prop.load(resourceAsStream);basePackage = Prop.getProperty("basePackage");} catch (IOException e) {e.printStackTrace();}return basePackage;}/*** 添加映射* 1. 从 IOC 容器中获取所有带 RequestMapping 注解的 Controller 对象* 2. 获取 Controller 对象中带 RequestMapping 注解的方法* 3. 将 Controller 对象和方法封装为 RequestMappingBean 对象* 4. 构建映射关系,key 是 url,value 是 映射Bean 对象,包括 Controller 对象和方法*/public void AddRequestMapping() {// 获取 IOC 容器的 Bean MapHashMap<String, Object> beanMap = applicationContext.getBeanMap();for (Object bean : beanMap.values()) {// 获取 bean 的 Class 对象Class<?> aClass = bean.getClass();// 判断是否有 @Controller 注解if (!aClass.isAnnotationPresent(Controller.class)) {continue;}// 判断是否有 @RequestMapping 注解if (!aClass.isAnnotationPresent(RequestMapping.class)) {continue;}// 获取类的 @RequestMapping 注解的值String basePath = aClass.getAnnotation(RequestMapping.class).value();// 获取 Controller 对象中的所有方法Method[] methods = aClass.getDeclaredMethods();for (Method method : methods) {// 判断方法上有没有带 @RequestMapping 注解if (!method.isAnnotationPresent(RequestMapping.class)) {continue;}String path = method.getAnnotation(RequestMapping.class).value();// 封装为 映射Bean 对象RequestMappingBean mappingBean = new RequestMappingBean(bean, method);// 构建映射,添加到 Map 中mappingMap.put(basePath + path, mappingBean);}}System.out.println("映射添加完成");System.out.println(mappingMap);}/*** 处理请求,根据 url 找到对应的映射对象,调用对应的方法,返回结果*/public void HandlerMapping(HttpServletRequest req, HttpServletResponse resp) throws IOException {// 获取请求的路径,这个请求路径中有项目名称String requestURI = req.getRequestURI();// 获取项目名String contextPath = req.getContextPath();// 去掉项目名String url = requestURI.replace(contextPath, "");// 获取 url 对应的映射对象RequestMappingBean mappingBean = mappingMap.get(url);Object controller = mappingBean.getController();Method method = mappingBean.getMethod();Object res = null;try {// 调用映射对象中的方法res = method.invoke(controller);} catch (Exception e) {e.printStackTrace();}// 判断方法是否有返回内容if (res == null) {return;}// 判断方法是否有 @ResponseBody 注解if (method.isAnnotationPresent(ResponseBody.class)) {resp.setContentType("application/json;charset=utf-8");// 响应数据resp.getWriter().write(JSON.toJSONString(res));} else {// 获取编译后的项目根目录String path = this.getClass().getClassLoader().getResource("../../").getPath();// 路径前面有一个 /,比如: /D:/xxx,需要去掉,然后拼接静态资源名称String filePath = path.substring(1) + res;try {// 解码,如果路径有空格或者中文,会出现 16 进制的字符filePath = URLDecoder.decode(filePath, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 获取静态资源内容byte[] fileContents = StaticResourceHandler.getFileContents(filePath);// 获取文件媒体类型String mimeType = StaticResourceHandler.getFileMimeType(filePath);resp.setContentType(mimeType + ";charset=utf-8");// 响应内容resp.getWriter().write(new String(fileContents));}}
}

3. 测试

如果显示乱码可以添加以下命令试一下

-Dfile.encoding=UTF-8

相关文章:

【学习笔记】手写一个简单的 Spring MVC

目录 一、什么是Spring MVC &#xff1f; Spring 和 Spring MVC 的区别&#xff1f; Spring MVC 的运行流程&#xff1f; 二、实现步骤 1. DispatcherServlet 1. 创建一个中央分发器 拦截所有请求 测试 2. 接管 IOC 容器 1. 创建配置文件 2. 修改 web.xml 配置文件 …...

编程究竟难在哪里?

目录 一、将现实问题转化为代码二、应对需求的不断变化三、设计新算法的挑战结语 编程之难&#xff0c;常被概括为三个方面&#xff1a;首先&#xff0c;是将现实世界的问题转化为计算机语言的挑战&#xff1b;其次&#xff0c;是需求不断变化所带来的适应性难题&#xff1b;最…...

C#医学影像分析源码,医院影像中心PACS系统源码

医学影像系统源码&#xff0c;影像诊断系统PACS源码&#xff0c;C#语言&#xff0c;C/S架构的PACS系统全套源代码。 PACS系统是医院影像科室中应用的一种系统&#xff0c;主要用于获取、传输、存档和处理医学影像。它通过各种接口&#xff0c;如模拟、DICOM和网络&#xff0c;以…...

WooCommerce与wordpress是什么关系

WooCommerce与WordPress之间的关系非常紧密&#xff0c;因为WooCommerce实际上是一个为WordPress设计的插件。WordPress是一个内容管理系统(CMS)&#xff0c;广泛用于创建各种类型的网站&#xff0c;包括博客、企业网站等。而WooCommerce则是一个免费且开源的电子商务插件&…...

Web常见的攻击方式及防御方法

Web常见的攻击方式及防御方法如下&#xff1a; 1. 跨站脚本&#xff08;XSS&#xff09; 攻击方式&#xff1a;恶意代码被注入到网页中&#xff0c;用户浏览时执行该代码&#xff0c;导致窃取用户信息、伪造页面等。防御&#xff1a; 对用户输入严格过滤、转义。使用安全的编…...

基于STM32的超声波测距仪设计

引言 本项目将基于STM32微控制器设计一个超声波测距仪&#xff0c;通过超声波传感器实现距离测量&#xff0c;并将结果显示在液晶屏上。该项目展示了STM32微控制器与超声波传感器、LCD显示器的接口通信&#xff0c;以及信号处理和距离计算的过程。 环境准备 1. 硬件设备 ST…...

【数据库】Java 集成mongodb— MongoTemplate 详解

MongoTemplate 是 Spring Data MongoDB 提供的核心类&#xff0c;用于简化与 MongoDB 数据库的交互。它封装了许多常见的数据库操作&#xff0c;使开发者能够轻松执行 CRUD&#xff08;创建、读取、更新、删除&#xff09;操作&#xff0c;处理复杂查询和聚合等。本文将详细介绍…...

腿和脚的动作透露出你的内心“世界”

离大脑越近的部位越容易受大脑控制&#xff0c;而腿脚离大脑最远&#xff0c;想要在第一时间进行伪装是很难的。当危险靠近时&#xff0c;我们的双腿会自然而然地进入戒备状态&#xff0c;产生一些不自觉的动作。因此&#xff0c;观察一个人的腿脚&#xff0c;可以帮助我们了解…...

Oracle架构之用户,权限,角色讲解

文章目录 1 用户1.1 简介1.1.1 定义1.1.2 用户相关信息1.1.2.1 用户默认表空间1.1.2.2 用户临时表空间1.1.2.3 用户资源文件1.1.2.4 用户表空间限额1.1.2.5 用户管理有关的数据字典 1.1.3 用户、模式、模式对象1.1.4 实例模式 SCOTT1.1.5 各个角色区别 1.2 用户管理1.2.1 创建用…...

Unity_Obfuscator Pro代码混淆工具_学习日志

Unity_Obfuscator Pro代码混淆工具_学习日志 切勿将密码或 API 密钥存储在您附带的应用程序内。 混淆后的热更新暂时没有想到怎么办 Obfuscator 文档 https://docs.guardingpearsoftware.com/manual/Obfuscator/Description.html商店链接Obfuscator Pro&#xff08;大约$70&a…...

已解决:org.springframework.web.HttpMediaTypeNotAcceptableException

文章目录 写在前面问题描述报错原因分析&#xff1a; 解决思路解决办法1. 确保客户端请求的 Accept 头正确2. 修改 Controller 方法的 produces 参数3. 配置合适的消息转换器4. 检查 Spring 配置中的媒体类型5. 其他解决方案 总结 写在前面 在开发过程中&#xff0c;Spring 框…...

C/C++简单编译原理

我们写的头文件和.cpp文件究竟是如何在电脑中运行的&#xff1f; 先明确几个文件类型&#xff1a; 1、头文件&#xff08;.h .hpp&#xff09; 第三方头文件、系统头文件、自编头文件…… 2、编译单位&#xff08;.cpp .c cu&#xff09; 自己写的脚本文件 3、目标文件&…...

文件处理不再难:带你轻松攻克C语言文件操作

嘿嘿,家人们,今天咱们来详细剖析C语言中的文件操作,好啦,废话不多讲,开干! 目录 1:为什么使用文件 2:文件的概念 2.1:程序文件 2.2:数据文件 2.3:文件名 3:二进制文件与文本文件 4:文件的打开与关闭 4.1:流与标准流 4.1.1:流 4.1.2:标准流 4.2:文件指针 4.3:文件的…...

Unity3D 单例模式

Unity3D 泛型单例 单例模式 单例模式是一种创建型设计模式&#xff0c;能够保证一个类只有一个实例&#xff0c;提供访问实例的全局节点。 通常会把一些管理类设置成单例&#xff0c;例如 GameManager、UIManager 等&#xff0c;可以很方便地使用这些管理类单例&#xff0c;…...

解析TMalign文本文件中的转换矩阵

TM-align 将两个蛋白质结构通过旋转和位移对齐后&#xff1a; TMalign test1.pdb test2.pdb -m mtx.txt 输出转换矩阵&#xff0c;文件内容为&#xff1a; ------ The rotation matrix to rotate Chain_1 to Chain_2 ------ m t[m] u[m][0] u[…...

vue.js组建开发

Vue.js是一个用于构建用户界面的渐进式JavaScript框架。它采用了组件化的开发方式&#xff0c;将UI界面拆分成多个可重用的组件&#xff0c;通过组合这些组件来构建复杂的应用程序。在本文中&#xff0c;我们将探讨Vue.js组件开发的相关概念和技术。 一、组件化开发的优势 组件…...

D29【python 接口自动化学习】- python基础之输入输出与文件操作

day29 格式化输出 学习日期&#xff1a;20241006 学习目标&#xff1a;输入输出与文件操作&#xfe63;-41 格式化输出&#xff1a;如何将执行结果通过屏幕输出&#xff1f; 学习笔记&#xff1a; 三种常用的格式化输出方式 百分号方式 format函数方式 总结 1. 格式化输出…...

jQuery——平滑翻页

平滑翻页 param next true&#xff1a;下一页 false&#xff1a;下一页 本文分享到此结束&#xff0c;欢迎大家评论区相互讨论学习&#xff0c;下一篇继续分享jQuery中循环翻页的学习。...

二叉树--DS

1. 树 1.1 树的定义 树是一种非线性的数据结构&#xff0c;它是由n (n > 0)个有限结点组成的一个具有层次关系的集合。之所以将它称为“树”&#xff0c;是因为它像一颗倒挂起来的树&#xff0c;也就是说它是根朝上&#xff0c;叶子在下的。 参考上面的图片&#xff0c;…...

State of ChatGPT ---- ChatGPT的技术综述

声明&#xff1a;该文总结自AI菩萨Andrej Karpathy在youtube发布的演讲视频。 原视频连接&#xff1a;State of GPT | BRK216HFS 基础知识&#xff1a; Transformer原文带读与代码实现https://blog.csdn.net/m0_62716099/article/details/141289541?spm1001.2014.3001.5501 H…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...