【SpringBoot】笔记2
文章目录
- 45、web实验-抽取公共页面
- 46、web实验-遍历数据与页面bug修改
- 47、视图解析-【源码分析】-视图解析器与视图[暂时没看]
- 48、拦截器-登录检查与静态资源放行
- 49、拦截器-【源码分析】-拦截器的执行时机和原理
- 50、文件上传-单文件与多文件上传的使用
- 51、文件上传-【源码流程】文件上传参数解析器
- 52、错误处理-SpringBoot默认错误处理机制
- 53、错误处理-【源码分析】底层组件功能分析【看了但是自己没有理解】
- 54、错误处理-【源码流程】异常处理流程【没看,打算看文档的时候再一起看,现在看不懂】
- 55、错误处理-【源码流程】几种异常处理原理【没看,打算看文档的时候再一起看,现在看不懂】
- 56、原生组件注入-原生注解与Spring方式注入
- 使用原生的注解
- Spring方式注入
- 57、原生组件注入-【源码分析】DispatcherServlet注入原理
- 58、嵌入式Servlet容器-【源码分析】切换web服务器与定制化【没看】
- 定制Servlet容器
- 59、定制化原理-SpringBoot定制化组件的几种方式(小结)
- 定制化的常见方式
- 原理分析套路
- 60、数据访问-数据库场景的自动配置分析与整合测试
- 导入JDBC场景
- 相关数据源配置类
- 修改配置项
- 单元测试数据源
- 61、数据访问-自定义方式整合druid数据源
- Druid是什么?
- 自定义方式
- 62、数据访问-druid数据源starter整合方式
- 63、数据访问-整合MyBatis-配置版
- 小结
- 64、数据访问-整合MyBatis-注解配置混合版
- 65、数据访问-整合MyBatisPlus操作数据库
- MyBatisPlus是什么
- 66、数据访问-CRUD实验-数据列表展示
- 67、数据访问-CRUD实验-分页数据展示
- 68、数据访问-CRUD实验-删除用户完成
- 69、数据访问-准备阿里云Redis环境
- 70、数据访问-Redis操作与统计小实验
- 71、单元测试-JUnit5简介
- 72、单元测试-常用测试注解
- 73、单元测试-断言机制
- 简单断言
- 数组断言
- 组合断言
- 异常断言
- 超时断言
- 快速失败
- 74、单元测试-前置条件
- 75、单元测试-嵌套测试
- 76、单元测试-参数化测试
- 迁移指南
- 77、指标监控-SpringBoot Actuator与Endpoint
- 如何使用
- 78、指标监控-常使用的端点及开启与禁用
- 常使用的端点
- Health Endpoint
- Metrics Endpoint
- 开启与禁用Endpoints
- 暴露Endpoints
- 79、指标监控-定制Endpoint
- 定制 Health 信息
- 定制info信息
- 定制Metrics信息
- 定制Endpoint
- 80、指标监控-Boot Admin Server
- 81、高级特性-Profile环境切换
- @Profile条件装配功能
- 82、高级特性-配置加载优先级
- 外部化配置
- 83、高级特性-自定义starter细节
- starter启动原理
- 自定义starter
- 84、原理解析-SpringApplication创建初始化流程
- SpringBoot启动过程
- 85、原理解析-SpringBoot完整启动过程
- 86、原理解析-自定义事件监听组件
- 87、后会有期
45、web实验-抽取公共页面
官方文档 - Template Layout
中文文档
复习Template 语法,把链接放上来
- 公共页面
/templates/common.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><!--注意要添加xmlns:th才能添加thymeleaf的标签-->
<head th:fragment="commonheader"><!--common-->...
</head>
<body>
<!-- left side start-->
<div id="leftmenu" class="left-side sticky-left-side">...<div class="left-side-inner">...<!--sidebar nav start--><ul class="nav nav-pills nav-stacked custom-nav"><li><a th:href="@{/main.html}"><i class="fa fa-home"></i> <span>Dashboard</span></a></li>...<li class="menu-list nav-active"><a href="#"><i class="fa fa-th-list"></i> <span>Data Tables</span></a><ul class="sub-menu-list"><li><a th:href="@{/basic_table}"> Basic Table</a></li><li><a th:href="@{/dynamic_table}"> Advanced Table</a></li><li><a th:href="@{/responsive_table}"> Responsive Table</a></li><li><a th:href="@{/editable_table}"> Edit Table</a></li></ul></li>...</ul><!--sidebar nav end--></div>
</div>
<!-- left side end--><!-- header section start-->
<div th:fragment="headermenu" class="header-section"><!--toggle button start--><a class="toggle-btn"><i class="fa fa-bars"></i></a><!--toggle button end-->...</div>
<!-- header section end--><div id="commonscript"><!-- Placed js at the end of the document so the pages load faster --><script th:src="@{/js/jquery-1.10.2.min.js}"></script><script th:src="@{/js/jquery-ui-1.9.2.custom.min.js}"></script><script th:src="@{/js/jquery-migrate-1.2.1.min.js}"></script><script th:src="@{/js/bootstrap.min.js}"></script><script th:src="@{/js/modernizr.min.js}"></script><script th:src="@{/js/jquery.nicescroll.js}"></script><!--common scripts for all pages--><script th:src="@{/js/scripts.js}"></script>
</div>
</body>
</html>
/templates/table/basic_table.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"><meta name="description" content=""><meta name="author" content="ThemeBucket"><link rel="shortcut icon" href="#" type="image/png"><title>Basic Table</title><div th:include="common :: commonheader"> </div><!--将common.html的代码段 插进来-->
</head><body class="sticky-header"><section>
<div th:replace="common :: #leftmenu"></div><!-- main content start--><div class="main-content" ><div th:replace="common :: headermenu"></div>...</div><!-- main content end-->
</section><!-- Placed js at the end of the document so the pages load faster -->
<div th:replace="common :: #commonscript"></div></body>
</html>
Difference between th:insert
and th:replace
(and th:include
)
46、web实验-遍历数据与页面bug修改
控制层代码:
@GetMapping("/dynamic_table")
public String dynamic_table(Model model){//表格内容的遍历List<User> users = Arrays.asList(new User("zhangsan", "123456"),new User("lisi", "123444"),new User("haha", "aaaaa"),new User("hehe ", "aaddd"));model.addAttribute("users",users);return "table/dynamic_table";
}
页面代码:
<table class="display table table-bordered" id="hidden-table-info"><thead><tr><th>#</th><th>用户名</th><th>密码</th></tr></thead><tbody><tr class="gradeX" th:each="user,stats:${users}"><td th:text="${stats.count}">Trident</td><td th:text="${user.userName}">Internet</td><td >[[${user.password}]]</td></tr></tbody>
</table>
47、视图解析-【源码分析】-视图解析器与视图[暂时没看]
ctrl+b进入代码
视图解析原理流程:
- 目标方法处理的过程中(阅读
DispatcherServlet
源码),所有数据都会被放在ModelAndViewContainer
里面,其中包括数据和视图地址。 - 方法的参数是一个自定义类型对象(从请求参数中确定的),把他重新放在
ModelAndViewContainer
。 - 任何目标方法执行完成以后都会返回
ModelAndView
(数据和视图地址)。 processDispatchResult()
处理派发结果(页面改如何响应)render(mv, request, response);
进行页面渲染逻辑- 根据方法的
String
返回值得到View
对象【定义了页面的渲染逻辑】
- 所有的视图解析器尝试是否能根据当前返回值得到
View
对象 - 得到了
redirect:/main.html --> Thymeleaf new RedirectView()
。 ContentNegotiationViewResolver
里面包含了下面所有的视图解析器,内部还是利用下面所有视图解析器得到视图对象。view.render(mv.getModelInternal(), request, response);
视图对象调用自定义的render进行页面渲染工作。
RedirectView
如何渲染【重定向到一个页面】- 获取目标url地址
response.sendRedirect(encodedURL);
- 根据方法的
视图解析:
- 返回值以 forward:
开始: new InternalResourceView(forwardUrl);
--> 转发request.getRequestDispatcher(path).forward(request, response);
- 返回值以 redirect:
开始: new RedirectView()
--> render就是重定向
- 返回值是普通字符串:new ThymeleafView()
—>
阅读源码:最好自己在IDE,打断点,且Debug模式运行实例,这样比较没那么沉闷。
48、拦截器-登录检查与静态资源放行
需要复习一些request,response,session等知识点,把复习链接放在这里
-
编写一个拦截器实现
HandlerInterceptor
接口 -
拦截器注册到容器中(实现
WebMvcConfigurer
的addInterceptors()
) -
指定拦截规则(注意,如果是拦截所有,静态资源也会被拦截】
编写一个实现HandlerInterceptor
接口的拦截器:
package edu.gdpu.config;import edu.gdpu.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class AdminWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()) //拦截器注册到容器中.addPathPatterns("/**") //所有请求都被拦截包括静态资源.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");
// ?静态资源这里还可以这样子写的,在/static/**全部发现,需要在application.yml配置
// # 静态资源访问前缀//#spring://# mvc://# static-path-pattern: /res/** 麻烦的是css,js等静态资源都要加上/static才会被访问到}
}
拦截器注册到容器中 && 指定拦截规则:
@Configuration
public class AdminWebConfig implements WebMvcConfigurer{@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor())//拦截器注册到容器中.addPathPatterns("/**") //所有请求都被拦截包括静态资源.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行的请求
}
49、拦截器-【源码分析】-拦截器的执行时机和原理
看了老师那么多源码解析,我都是懵懵懂懂的,就是没听,这次认真学习IDEA的debug调试,附上链接
- 根据当前请求,找到
HandlerExecutionChain
(可以处理请求的handler以及handler的所有 拦截器) - 先来顺序执行 所有拦截器的
preHandle()
方法。- 如果当前拦截器
preHandle()
返回为true
。则执行下一个拦截器的preHandle()
- 如果当前拦截器返回为
false
。直接倒序执行所有已经执行了的拦截器的afterCompletion();
。
- 如果当前拦截器
- 如果任何一个拦截器返回
false
,直接跳出不执行目标方法。 - 所有拦截器都返回
true
,才执行目标方法。 - 倒序执行所有拦截器的
postHandle()
方法。 - 前面的步骤有任何异常都会直接倒序触发
afterCompletion()
。 - 页面成功渲染完成以后,也会倒序触发
afterCompletion()
。
DispatcherServlet
中涉及到HandlerInterceptor
的地方:
public class DispatcherServlet extends FrameworkServlet {...protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;...//该方法内调用HandlerInterceptor的preHandle()if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());...//该方法内调用HandlerInterceptor的postHandle()mappedHandler.applyPostHandle(processedRequest, response, mv);} processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {//该方法内调用HandlerInterceptor接口的afterCompletion方法triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {//该方法内调用HandlerInterceptor接口的afterCompletion方法triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {...}}private void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, Exception ex) throws Exception {if (mappedHandler != null) {//该方法内调用HandlerInterceptor接口的afterCompletion方法mappedHandler.triggerAfterCompletion(request, response, ex);}throw ex;}private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {...if (mappedHandler != null) {//该方法内调用HandlerInterceptor接口的afterCompletion方法// Exception (if any) is already handled..mappedHandler.triggerAfterCompletion(request, response, null);}}}
public class HandlerExecutionChain {...boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {for (int i = 0; i < this.interceptorList.size(); i++) {HandlerInterceptor interceptor = this.interceptorList.get(i);//HandlerInterceptor的preHandle方法if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);return false;}this.interceptorIndex = i;}return true;}void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)throws Exception {for (int i = this.interceptorList.size() - 1; i >= 0; i--) {HandlerInterceptor interceptor = this.interceptorList.get(i);//HandlerInterceptor接口的postHandle方法interceptor.postHandle(request, response, this.handler, mv);}}void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {for (int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = this.interceptorList.get(i);try {//HandlerInterceptor接口的afterCompletion方法interceptor.afterCompletion(request, response, this.handler, ex);}catch (Throwable ex2) {logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);}}}}
50、文件上传-单文件与多文件上传的使用
- 页面代码
/static/form/form_layouts.html
<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data"><div class="form-group"><label for="exampleInputEmail1">邮箱</label><input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"></div><div class="form-group"><label for="exampleInputPassword1">名字</label><input type="text" name="username" class="form-control" id="exampleInputPassword1" placeholder="Password"></div><div class="form-group"><label for="exampleInputFile">头像</label><input type="file" name="headerImg" id="exampleInputFile"></div><div class="form-group"><label for="exampleInputFile">生活照</label><input type="file" name="photos" multiple></div><div class="checkbox"><label><input type="checkbox"> Check me out</label></div><button type="submit" class="btn btn-primary">提交</button>
</form>
Html中label标签
input标签的multiple,多文件上传
复习request、response
POST提交表单时EnType设置问题
- 控制层代码
@Slf4j
@Controller
public class FormTestController {@GetMapping("/form_layouts")public String form_layouts(){return "form/form_layouts";}@PostMapping("/upload")public String upload(@RequestParam("email") String email,@RequestParam("username") String username,@RequestPart("headerImg") MultipartFile headerImg,@RequestPart("photos") MultipartFile[] photos) throws IOException {log.info("上传的信息:email={},username={},headerImg={},photos={}",email,username,headerImg.getSize(),photos.length);if(!headerImg.isEmpty()){//保存到文件服务器,OSS服务器String originalFilename = headerImg.getOriginalFilename();headerImg.transferTo(new File("H:\\cache\\"+originalFilename));}if(photos.length > 0){for (MultipartFile photo : photos) {if(!photo.isEmpty()){String originalFilename = photo.getOriginalFilename();photo.transferTo(new File("H:\\cache\\"+originalFilename));}}}return "main";}
}
文件上传相关的配置类:
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
文件大小相关配置项:
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB
51、文件上传-【源码流程】文件上传参数解析器
文件上传相关的自动配置类MultipartAutoConfiguration
有创建文件上传参数解析器StandardServletMultipartResolver
。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class })
@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(MultipartProperties.class)
public class MultipartAutoConfiguration {private final MultipartProperties multipartProperties;public MultipartAutoConfiguration(MultipartProperties multipartProperties) {this.multipartProperties = multipartProperties;}@Bean@ConditionalOnMissingBean({ MultipartConfigElement.class, CommonsMultipartResolver.class })public MultipartConfigElement multipartConfigElement() {return this.multipartProperties.createMultipartConfig();}@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)@ConditionalOnMissingBean(MultipartResolver.class)public StandardServletMultipartResolver multipartResolver() {//配置好文件上传解析器StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());return multipartResolver;}}
//文件上传解析器
public class StandardServletMultipartResolver implements MultipartResolver {private boolean resolveLazily = false;public void setResolveLazily(boolean resolveLazily) {this.resolveLazily = resolveLazily;}@Overridepublic boolean isMultipart(HttpServletRequest request) {return StringUtils.startsWithIgnoreCase(request.getContentType(), "multipart/");}@Overridepublic MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {return new StandardMultipartHttpServletRequest(request, this.resolveLazily);}@Overridepublic void cleanupMultipart(MultipartHttpServletRequest request) {if (!(request instanceof AbstractMultipartHttpServletRequest) ||((AbstractMultipartHttpServletRequest) request).isResolved()) {// To be on the safe side: explicitly delete the parts,// but only actual file parts (for Resin compatibility)try {for (Part part : request.getParts()) {if (request.getFile(part.getName()) != null) {part.delete();}}}catch (Throwable ex) {LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex);}}}}
public class DispatcherServlet extends FrameworkServlet {@Nullableprivate MultipartResolver multipartResolver;private void initMultipartResolver(ApplicationContext context) {...//这个就是配置类配置的StandardServletMultipartResolver文件上传解析器this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);...}protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;//最后finally的回收flag...try {ModelAndView mv = null;Exception dispatchException = null;try {//做预处理,如果有上传文件 就new StandardMultipartHttpServletRequest包装类processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);// Determine handler for the current request.mappedHandler = getHandler(processedRequest);...// Determine handler adapter for the current request.HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());...// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());}....finally {...if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {...return this.multipartResolver.resolveMultipart(request);...}}protected void cleanupMultipart(HttpServletRequest request) {if (this.multipartResolver != null) {MultipartHttpServletRequest multipartRequest =WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class);if (multipartRequest != null) {this.multipartResolver.cleanupMultipart(multipartRequest);}}}
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
跳到以下的类
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapterimplements BeanFactoryAware, InitializingBean {@Overrideprotected ModelAndView handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ModelAndView mav;...mav = invokeHandlerMethod(request, response, handlerMethod);...return mav;}@Nullableprotected ModelAndView invokeHandlerMethod(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ServletWebRequest webRequest = new ServletWebRequest(request, response);try {WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);if (this.argumentResolvers != null) {//关注点invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);}...invocableMethod.invokeAndHandle(webRequest, mavContainer);...return getModelAndView(mavContainer, modelFactory, webRequest);}finally {webRequest.requestCompleted();}}}
this.argumentResolvers
其中主角类RequestPartMethodArgumentResolver
用来生成
public class ServletInvocableHandlerMethod e
相关文章:

【SpringBoot】笔记2
文章目录 45、web实验-抽取公共页面46、web实验-遍历数据与页面bug修改47、视图解析-【源码分析】-视图解析器与视图[暂时没看]48、拦截器-登录检查与静态资源放行49、拦截器-【源码分析】-拦截器的执行时机和原理50、文件上传-单文件与多文件上传的使用51、文件上传-【源码流程…...

Spring事务传播机制详细讲解
文章目录 一、事务传播机制1. REQUIRED:2. SUPPORTS:3. MANDATORY:4. REQUIRES_NEW:5. NOT_SUPPORTED:6. NEVER:7. NESTED: 二、事务传播机制分类1. 支持当前事务的传播机制:REQUIRE…...

kubernetes 集群搭建(kubeadm 方式)
目前生产部署 Kubernetes 集群主要有两种方式: (1) kubeadm Kubeadm 是一个 Kubernetes 官方提供的命令行工具,可以用来部署和管理 Kubernetes 集群。它主要用于在新的 Kubernetes 环境中初始化集群、添加或删除节点等操作。 K…...

基于ARM+FPGA的驱控一体机器人控制器设计
目前市场上工业机器人,数控机床等多轴运动控制系统普遍采用运动控制器加 伺服驱动器的分布式控制方式。在这种控制方式中,控制器一方面完成人机交互,另 一方面进行 NC 代码的解释执行,插补运算,继而将计算出来的位…...

docker 安装 字体文件
先说一下我当前的 场景 及 环境,这样同学们可以先评估本篇文章是否有帮助。 环境: dockerphp8.1-fpmwindows 场景: 来了个需求,有一个默认背景图,可以理解为背景图是一个 "相框",相框里面就会放…...
Vue.js与ASP.NET的结合,实现企业级应用的开发和部署
在当今快速发展的互联网技术领域,企业级应用的开发和部署变得越来越重要。Vue.js和ASP.NET是两个在前端和后端开发中广泛使用的技术,将它们结合起来可以为企业级应用的开发和部署带来诸多优势。本文将通过代码示例介绍如何使用Vue.js和ASP.NET进行企业级…...

Uncaught SyntaxError: ‘‘ string literal contains an unescaped line break
今天在修改前端页面的时候,页面报错了,提示了这个信息 Uncaught SyntaxError: string literal contains an unescaped line break 问题指向这行代码,这就是通过JS渲染一个easyui的搜索框,仔细确认之后,发现没有任何问…...

Vue3+Vite+TypeScript常用项目模块详解
目录 1.Vue3ViteTypeScript 概述 1.1 vue3 1.1.1 Vue3 概述 1.1.2 vue3的现状与发展趋势 1.2 Vite 1.2.1 现实问题 1.2 搭建vite项目 1.3 TypeScript 1.3.1 TypeScript 定义 1.3.2 TypeScript 基本数据类型 1.3.3 TypeScript语法简单介绍 2. 项目配置简单概述 2.…...

数字电路(一)
1、例题 1、进行DA数模转换器选型时,一般要选择主要参数有( A)、转换精度和转换速度。 A、分辨率 B、输出电流 C、输出电阻 D、模拟开关 2、下图所示电路的逻辑功能为( B) A、与门 B、或门 C、与非门 D、或非门 分析该…...
Oracle也有回收站
在数据库管理中,数据的删除是一个常见的操作。然而,有时候我们可能会意外地删除了一些重要的数据。幸运的是,Oracle数据库提供了一个类似于回收站的功能,可以帮助我们恢复被删除的数据。本文将介绍Oracle数据库中的回收站功能以及…...

投稿注意!APA格式超全示例详解,原本28天能录用,可能要拖延2个月
为什么同一本期刊有论文28天录用,有论文10个月才录用?结合近期征稿的这本经管类SSCI期刊,小编(Unionpub学术)整理了部分影响录用的几个因素,准备提交此期刊的作者可自查参考下: (参…...

【Python】Web学习笔记_flask(1)——模拟登录
安装flask pip3 install flask 第一部分内容: 1、主页面输出hello world 2、根据不同用户名参数输出用户信息 3、模拟登录 from flask import Flask,url_for,redirectappFlask(__name__)app.route(/) def index():return hello worldapp.route(/user/<uname…...
css单行文本省略号多行文本省略号
设置单行文本省略号的写法 : 先设置宽固定的宽度 :width: 300px; 设置不换行 :white-space:nowrap; 设置省略号:text-overflow: ellipsis; 裁剪多余的内容/溢出的内容:overflow: hidden; width: 200px; white-space:…...

信号槽中的函数重载
信号槽中的函数重载 QT4的方式QT5的方式函数指针重载函数QT5信号函数重载解决方案 总结 QT4的方式 Qt4中声明槽函数必须要使用 slots 关键字, 不能省略。 信号函数: 槽函数: mainwondow: cpp文件: #include "mainwindow.h"…...

计算机视觉(五)深度学习基础
文章目录 深度学习基础卷积神经网络与传统神经网络区别深度学习与神经网络的区别 目标函数选择合适的目标函数Softmax层 改进的梯度下降梯度消失的直观解释激活函数学习步长SGD的问题Momentum动量Nesterov MomentumAdagradRMSpropAdam 各种梯度下降算法比较关于算法选择的建议B…...
ES6学习-Generator
Generator 种异步编程解决方案 函数会返回一个遍历器对象语法上:Generator 函数是一个状态机,封装了多个内部状态。形式上:Generator 函数是一个普通函数;有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部…...

Flowable-服务-微服务任务
目录 定义图形标记XML内容界面操作 定义 Sc 任务不是 BPMN 2.0 规范定义的官方任务,在 Flowable 中,Sc 任务是作为一种特殊的服务 任务来实现的,主要调用springcloud的微服务使用。 图形标记 由于 Sc 任务不是 BPMN 2.0 规范的“官方”任务…...
opencv03-补充-vector的操作
opencv03-补充-vector的操作 参考:https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html 构造方法(具体介绍看API文档) class Student {public:private:string name;};int main() {vector<int>();vector<int> v1;vector<Student&g…...

二叉树(C语言)
文章目录 1.树1.1概念1.2相关定义1.3 表示(左孩子右兄弟) 2.二叉树2.1概念2.2特殊的二叉树1. 满二叉树:2. 完全二叉树: 2.3二叉树的性质2.4练习 3.二叉树的存储结构1. 顺序存储2. 链式存储 4.完全二叉树的代码实现4.1堆的介绍1.堆…...
介绍下Django中的表单(forms)模块中的类forms.CharField
在Django中,forms.CharField() 是用于定义表单字段的类,它属于 Django 的表单(forms)模块。CharField 是用于处理字符型数据的表单字段类。它允许用户在表单中输入文本数据,并对该数据进行验证和处理。 forms.CharFie…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...

快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...