springCloud gateway 防止XSS漏洞
springCloud gateway 防止XSS漏洞
- 一.XSS(跨站脚本)漏洞详解
- 1.XSS的原理和分类
- 2.XSS漏洞的危害
- 3.XSS的防御
- 二.Java开发中防范XSS跨站脚本攻击的思路
- 三.相关代码(适用于spring cloud gateway)
- 1.CacheBodyGlobalFilter.java
- 2.XssRequestGlobalFilter.java
- 3.XssResponseGlobalFilter.java
- 4.XssCleanRuleUtils.java
- 5.注意启动类不要忘记加@ComponentScan
- 四.参考文章
一.XSS(跨站脚本)漏洞详解
1.XSS的原理和分类
跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!
XSS分为:存储型 、反射型 、DOM型XSS
-
存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie
-
反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面
-
DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。
2.XSS漏洞的危害
从以上我们可以知道,存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。
3.XSS的防御
XSS防御的总体思路是:对用户的输入(和URL参数)进行过滤,对输出进行html编码。也就是对用户提交的所有内容进行过滤,对url中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。
对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单过滤虽然可以拦截大部分的XSS攻击,但是还是存在被绕过的风险。白名单过滤虽然可以基本杜绝XSS攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。
对输出进行html编码,就是通过函数,将用户的输入的数据进行html编码,使其不能作为脚本运行。
如下,是使用php中的htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体
#使用htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体
$name = htmlspecialchars( $_GET[ 'name' ] );
二.Java开发中防范XSS跨站脚本攻击的思路
-
- 防堵跨站漏洞
阻止攻击者利用在被攻击网站上发布跨站攻击语句不可以信任用户提交的任何内容,首先代码里对用户输入的地方和变量都需要仔细检查长度和对”<”,”>”,”;”,”’”等字符做过滤;其次任何内容写到页面之前都必须加以encode,避免不小心把html tag 弄出来。这一个层面做好,至少可以堵住超过一半的XSS 攻击。
- 防堵跨站漏洞
-
- Cookie 防盗
首先避免直接在cookie 中泄露用户隐私,例如email、密码等等。其次通过使cookie 和系统ip 绑定来降低cookie 泄露后的危险。这样攻击者得到的cookie 没有实际价值,不可能拿来重放。
- Cookie 防盗
-
- 尽量采用POST 而非GET 提交表单
POST 操作不可能绕开javascript 的使用,这会给攻击者增加难度,减少可利用的跨站漏洞。
- 尽量采用POST 而非GET 提交表单
-
- 严格检查refer
检查http refer 是否来自预料中的url。这可以阻止第2 类攻击手法发起的http 请求,也能防止大部分第1 类攻击手法,除非正好在特权操作的引用页上种了跨站访问。
- 严格检查refer
-
- 将单步流程改为多步,在多步流程中引入效验码
多步流程中每一步都产生一个验证码作为hidden 表单元素嵌在中间页面,下一步操作时这个验证码被提交到服务器,服务器检查这个验证码是否匹配。
首先这为第1 类攻击者大大增加了麻烦。其次攻击者必须在多步流程中拿到上一步产生的效验码才有可能发起下一步请求,这在第2 类攻击中是几乎无法做到的。
- 将单步流程改为多步,在多步流程中引入效验码
-
- 引入用户交互
简单的一个看图识数可以堵住几乎所有的非预期特权操作。
- 引入用户交互
-
- 只在允许anonymous 访问的地方使用动态的javascript。
-
- 对于用户提交信息的中的img 等link,检查是否有重定向回本站、不是真的图片等可疑操作。
-
- 内部管理网站的问题
很多时候,内部管理网站往往疏于关注安全问题,只是简单的限制访问来源。这种网站往往对XSS 攻击毫无抵抗力,需要多加注意。安全问题需要长期的关注,从来不是一锤子买卖。XSS 攻击相对其他攻击手段更加隐蔽和多变,和业务流程、代码实现都有关系,不存在什么一劳永逸的解决方案。此外,面对XSS,往往要牺牲产品的便利性才能保证完全的安全,如何在安全和便利之间平衡也是一件需要考虑的事情。
web应用开发者注意事项:
- 1.对于开发者,首先应该把精力放到对所有用户提交内容进行可靠的输入验证上。这些提交内容包括URL、查询关键字、http头、post数据等。只接受在你所规定长度范围内、采用适当格式、你所希望的字符。阻塞、过滤或者忽略其它的任何东西。
- 2.保护所有敏感的功能,以防被bots自动化或者被第三方网站所执行。实现session标记(session tokens)、CAPTCHA系统或者HTTP引用头检查。
- 3.如果你的web应用必须支持用户提供的HTML,那么应用的安全性将受到灾难性的下滑。但是你还是可以做一些事来保护web站点:确认你接收的HTML内容被妥善地格式化,仅包含最小化的、安全的tag(绝对没有JavaScript),去掉任何对远程内容的引用(尤其是样式表和JavaScript)。为了更多的安全,请使用httpOnly的cookie。
三.相关代码(适用于spring cloud gateway)
代码执行顺序
CacheBodyGlobalFilter—>XssRequestGlobalFilter—>XssResponseGlobalFilter
1.CacheBodyGlobalFilter.java
这个过滤器解决body不能重复读的问题(在低版本的spring-cloud不需要这个过滤器),为后续的XssRequestGlobalFilter重写请求body做准备
package com.xxx.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;/*** @Author:* @Description: 这个过滤器解决body不能重复读的问题,为后续的XssRequestGlobalFilter重写post|put请求的body做准备* @Date:* <p>* 没把body的内容放到attribute中去,因为从attribute取出body内容还是需要强转成 Flux<DataBuffer>,然后转换成String,和直接读取body没有什么区别*/
@Component
public class CacheBodyGlobalFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {HttpMethod method = exchange.getRequest().getMethod();String contentType = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);if (method == HttpMethod.POST || method == HttpMethod.PUT) {if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)|| MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType)|| MediaType.APPLICATION_JSON_UTF8_VALUE.equals(contentType)) {return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {DataBufferUtils.retain(dataBuffer);Flux<DataBuffer> cachedFlux = Flux.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {@Overridepublic Flux<DataBuffer> getBody() {return cachedFlux;}};return chain.filter(exchange.mutate().request(mutatedRequest).build());});}}return chain.filter(exchange);}@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}
}
2.XssRequestGlobalFilter.java
自定义防XSS攻击网关全局过滤器。
package com.xxx.gateway.filter;import io.netty.buffer.ByteBufAllocator;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.net.URI;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
/*** @Author:* @Description: 自定义防XSS攻击网关全局过滤器* @Date:*/@Component
public class XssRequestGlobalFilter implements GlobalFilter, Ordered {private Logger logger = LoggerFactory.getLogger(XssRequestGlobalFilter.class);/**** @param exchange* @param chain* @return** get请求参考spring cloud gateway自带过滤器:* @see org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory** post请求参考spring cloud gateway自带过滤器:* @see org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){// grab configuration from Config objectlogger.info("----自定义防XSS攻击网关全局过滤器生效----");ServerHttpRequest serverHttpRequest = exchange.getRequest();HttpMethod method = serverHttpRequest.getMethod();String contentType = serverHttpRequest.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);Boolean postFlag = (method == HttpMethod.POST || method == HttpMethod.PUT) &&(MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType) || MediaType.APPLICATION_JSON_VALUE.equals(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equals(contentType));// get 请求, 参考的是 org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactoryif (method == HttpMethod.GET) {URI uri = exchange.getRequest().getURI();String rawQuery = uri.getRawQuery();if (StringUtils.isBlank(rawQuery)){return chain.filter(exchange);}rawQuery = XssCleanRuleUtils.xssClean(rawQuery);try {URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(rawQuery).build(true).toUri();ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();return chain.filter(exchange.mutate().request(request).build());} catch (Exception e) {logger.error("get请求清理xss攻击异常", e);throw new IllegalStateException("Invalid URI query: \"" + rawQuery + "\"");}}//post请求时,如果是文件上传之类的请求,不修改请求消息体else if (postFlag){// 参考的是 org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory//从请求里获取Post请求体String bodyStr = resolveBodyFromRequest(serverHttpRequest);// 这种处理方式,必须保证post请求时,原始post表单必须有数据过来,不然会报错if (StringUtils.isBlank(bodyStr)) {logger.error("请求异常:{} POST请求必须传递参数", serverHttpRequest.getURI().getRawPath());ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.BAD_REQUEST);byte[] bytes = "{\"code\":400,\"msg\":\"post data error\"}".getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bytes);return response.writeWith(Mono.just(buffer));}bodyStr = XssCleanRuleUtils.xssClean(bodyStr);URI uri = serverHttpRequest.getURI();URI newUri = UriComponentsBuilder.fromUri(uri).build(true).toUri();ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();DataBuffer bodyDataBuffer = stringBuffer(bodyStr);Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);// 定义新的消息头HttpHeaders headers = new HttpHeaders();headers.putAll(exchange.getRequest().getHeaders());// 由于修改了传递参数,需要重新设置CONTENT_LENGTH,长度是字节长度,不是字符串长度int length = bodyStr.getBytes().length;headers.remove(HttpHeaders.CONTENT_LENGTH);headers.setContentLength(length);// 设置CONTENT_TYPEif (StringUtils.isNotBlank(contentType)) {headers.set(HttpHeaders.CONTENT_TYPE, contentType);}// 由于post的body只能订阅一次,由于上面代码中已经订阅过一次body。所以要再次封装请求到request才行,不然会报错请求已经订阅过request = new ServerHttpRequestDecorator(request) {@Overridepublic HttpHeaders getHeaders() {long contentLength = headers.getContentLength();HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.putAll(super.getHeaders());if (contentLength > 0) {httpHeaders.setContentLength(contentLength);} else {// this causes a 'HTTP/1.1 411 Length Required' on httpbin.orghttpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");}return httpHeaders;}@Overridepublic Flux<DataBuffer> getBody() {return bodyFlux;}};//封装request,传给下一级request.mutate().header(HttpHeaders.CONTENT_LENGTH, Integer.toString(bodyStr.length()));return chain.filter(exchange.mutate().request(request).build());} else {return chain.filter(exchange);}}@Overridepublic int getOrder() {return -90;}/*** 从Flux<DataBuffer>中获取字符串的方法* @return 请求体*/private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {//获取请求体Flux<DataBuffer> body = serverHttpRequest.getBody();AtomicReference<String> bodyRef = new AtomicReference<>();body.subscribe(buffer -> {CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());DataBufferUtils.release(buffer);bodyRef.set(charBuffer.toString());});//获取request bodyreturn bodyRef.get();}/*** 字符串转DataBuffer* @param value* @return*/private DataBuffer stringBuffer(String value) {byte[] bytes = value.getBytes(StandardCharsets.UTF_8);NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);buffer.write(bytes);return buffer;}
}
3.XssResponseGlobalFilter.java
重写Response,防止xss攻击。
package com.xxx.gateway.filter;import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.nio.charset.Charset;
import java.util.Arrays;/*** @Author:* @Description: 重写Response,防止xss攻击* @Date:*/
@Component
public class XssResponseGlobalFilter implements Ordered, GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//获取请求urlString path = exchange.getRequest().getPath().toString();//声明带有富文本的接口数组String[] richTextUrls = {"/xxx/findByUnid"};ServerHttpResponse originalResponse = exchange.getResponse();DataBufferFactory bufferFactory = originalResponse.bufferFactory();ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {@Overridepublic Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {String contentType = getDelegate().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);Boolean flag = MediaType.APPLICATION_JSON_VALUE.equals(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equals(contentType);if (body instanceof Flux && flag) {Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;return super.writeWith(fluxBody.map(dataBuffer -> {// probably should reuse buffersbyte[] content = new byte[dataBuffer.readableByteCount()];dataBuffer.read(content);//释放掉内存DataBufferUtils.release(dataBuffer);String result = new String(content, Charset.forName("UTF-8"));//若为带有富文本的接口,走富文本xss过滤if (Arrays.asList(richTextUrls).contains(path)) {result = XssCleanRuleUtils.xssRichTextClean(result);} else {//result就是response的值,对result进行去XSSresult = XssCleanRuleUtils.xssClean(result);}byte[] uppedContent = new String(result.getBytes(), Charset.forName("UTF-8")).getBytes();return bufferFactory.wrap(uppedContent);}));}// if body is not a flux. never got there.return super.writeWith(body);}};// replace response with decoratorreturn chain.filter(exchange.mutate().response(decoratedResponse).build());}@Overridepublic int getOrder() {return -50;}
}
4.XssCleanRuleUtils.java
上面几个过滤器使用的工具类
package com.xxx.gateway.filter;import java.util.regex.Pattern;/*** @Author:* @Description: xss过滤工具* @Date:*/
public class XssCleanRuleUtils {//过滤规则private final static Pattern[] scriptPatterns = {Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)};public static String xssClean(String value) {if (value != null) {value = value.replaceAll("\0|\n|\r", "");for (Pattern pattern : scriptPatterns) {value = pattern.matcher(value).replaceAll("");}value = value.replaceAll("<", "<").replaceAll(">", ">");}return value;}//富文本的过滤规则(不转义"<"、">")//不然会导致富文本无法显示的内容样式)public static String xssRichTextClean(String value) {if (value != null) {value = value.replaceAll("\0|\n|\r", "");for (Pattern pattern : scriptPatterns) {value = pattern.matcher(value).replaceAll("");}}return value;}
}
5.注意启动类不要忘记加@ComponentScan
四.参考文章
【1】spring cloud gateway 过滤器防止跨站脚本攻击(存储XSS、反射XSS)
https://blog.csdn.net/qq_26801767/article/details/106235359?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-4-106235359-blog-128300551.235v40pc_relevant_3m_sort_dl_base1&spm=1001.2101.3001.4242.3&utm_relevant_index=7
【2】XSS(跨站脚本)漏洞详解之XSS跨站脚本攻击漏洞的解决
http://www.uml.org.cn/safe/202203034.asp
【3】SpringCloud微服务实战——搭建企业级开发框架(五十一):微服务安全加固—自定义Gateway拦截器实现防止SQL注入/XSS攻击
https://blog.csdn.net/wmz1932/article/details/129449794
【4】Spring Cloud Gateway 实现XSS、SQL注入拦截
https://www.jianshu.com/p/17613323463d
【5】SpringBoot针对富文本和非富文本添加xss过滤
https://blog.csdn.net/ChOLg/article/details/119949942
【6】详解Xss 及SpringBoot 防范Xss攻击(附全部代码)
https://www.cnblogs.com/blbl-blog/p/17188558.html
相关文章:

springCloud gateway 防止XSS漏洞
springCloud gateway 防止XSS漏洞 一.XSS(跨站脚本)漏洞详解1.XSS的原理和分类2.XSS漏洞的危害3.XSS的防御 二.Java开发中防范XSS跨站脚本攻击的思路三.相关代码(适用于spring cloud gateway)1.CacheBodyGlobalFilter.java2.XssRequestGlobalFilter.java…...

美赛摘要写作重点
摘要是论文最重要的部分。竞赛要求每篇论文的首页为摘要页,如果摘要写得不好,即使有好的模型和解答,论文也将难以通过鉴别阶段的初审而进入下一阶段。 根据MCM的竞赛规则,摘要应该包含以下内容: 赛题重述与阐明&#…...

RUST笔记: 动态链接库的创建和使用
生成动态链接库 // https://github.com/vvvm23/funny-shapes # 项目元信息 [package] name "funnyshapes" # 项目名称 version "0.1.0" # 版本号 edition "2021" # Rust语言版本# 更多配置信息可查阅࿱…...

「阿里云」幻兽帕鲁个人服务器已上线,3分钟快速搭建
基于阿里云搭建幻兽帕鲁服务器方法,1到2分钟部署完成,稳定运行无卡顿,阿里云服务器网aliyunfuwuqi.com分享保姆级手把手教程,基于阿里云计算巢、云服务器或无影云桌面都可以: 基于阿里云幻兽帕鲁服务器创建教程 基于…...

@ 代码随想录算法训练营第6周(C语言)|Day36(贪心)
代码随想录算法训练营第6周(C语言)|Day36(贪心) Day36、贪心(包含题目 ● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间 ) 435. 无重叠区间 题目描述 给定一个区间的集合,找到需要…...

数组打印杨辉三角
签名:但行好事,莫问前程。 文章目录 前言一、杨辉三角的概念二、二维数组打印杨辉三角1、创建二维数组2、使用for循环,初始化外层元素3、给数组赋值3.1给数组每行首末元素赋值为13.1给数组每行非首末元素赋值 三、杨辉三角全代码总结 前言 记…...

【操作系统·考研】文件系统
1.概述 文件系统(File System)提供高效和便捷的磁盘访问,以便允许存储、定位、提取数据。 严格来说,VFS并不是一种实际的FS,它只存在于内存中,不存在与任何外存空间中。 VFS在系统启动时建立,在系统关闭时消亡。 2.结…...

中国传媒网CEO徐晓艺荣膺第九届金鸥奖“2023年度最佳创新人物”殊荣
2023年是不平凡的一年,风云变幻。大国经济有韧性,离不开顶层设计、宏观政策的指挥,也离不开千百万求新求变的企业和企业家们的辛勤耕耘。在经历了三年疫情严峻考验的当下,中国号巨轮迎风搏浪心如磐石,无惧险阻屹立潮头,这不仅是中国红的底色,也是中国企业家的坚守和倔强。2023年…...

ElementUI Form:Switch 开关
ElementUI安装与使用指南 Switch 开关 点击下载learnelementuispringboot项目源码 效果图 el-switch.vue (Switch 开关)页面效果图 项目里el-switch.vue代码 <script> export default {name: el_switch,data() {return {value: true,value1: …...

通俗易懂理解注意力机制(Attention Mechanism)
重要说明:本文从网上资料整理而来,仅记录博主学习相关知识点的过程,侵删。 一、参考资料 大话注意力机制(Attention Mechanism) 注意力机制(Attention Mechanism) 深度学习中的注意力机制 注意力机制 二、注意力…...

git的分支的使用,创建分支,合并分支,删除分支,合并冲突,分支管理策略,bug分支,强制删除分支
GIT | 分支 文章目录 GIT | 分支创建分支合并分支删除分支合并冲突分支管理策略bug分支强制删除分支 创建分支 查看当前本地仓库中有哪些分支 git branchHEAD所指向的分支就是当前正在工作的分支 cat .git/HEAD创建一个分支 git branch dev创建好了,但是目前还是…...

【leetcode100-081到090】【动态规划】一维五题合集1
【爬楼梯】 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 思路: 【状态】 dp[i];//爬i级台阶有几种方法 【初始】 dp[0] 1;//爬0级1种(不爬)dp[1] 1;/…...

数据结构-顺序表详解专题
目录 顺序表 1.简单了解顺序表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 2.3typedef命名作用 3.动态顺序表的实现 SeqList.h SeqList.c test.c 顺序表 1.简单了解顺序表 顺序表是线性表的一种,线性表是在逻辑上是线性结构,在物理逻辑上并…...

对商业知识和思维的一些小体会
用途:个人学习笔录,欢迎指正 前言: 小生拙见,我认为商业知识和商业思维的理解对于每一个行业都有潜在的帮助,因为每个人的生活都离不开商业,生意、工作都是交换,用自身提供的价值换取薪酬。因此…...

【笔记】计算文件夹的大小
目标:遍历文件夹,计算文件夹下包含文件和文件夹的大小。将这些结果存入python自带的数据库。 用大模型帮我设计并实现。 Step1 创建一个测试用的目录结构 创建目录结构如下所示: TestDirectory/ │ ├── EmptyFolder/ │ ├── SmallF…...

机器学习_常见算法比较模型效果(LR、KNN、SVM、NB、DT、RF、XGB、LGB、CAT)
文章目录 KNNSVM朴素贝叶斯决策树随机森林 KNN “近朱者赤,近墨者黑”可以说是 KNN 的工作原理。 整个计算过程分为三步: 计算待分类物体与其他物体之间的距离;统计距离最近的 K 个邻居;对于 K 个最近的邻居,它们属于…...

外包干了8个月,技术退步明显...
先说一下自己的情况,大专生,18年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…...

opencv#41 轮廓检测
轮廓概念介绍 通常我们使用二值化的图像进行轮廓检测,对轮廓以外到内进行数字命名,如下图,最外面的轮廓命名为0,向内部进行扩展,遇到黑色白色相交区域,就是一个新的轮廓,然后依次对轮廓进行编号…...

Websocket基本用法
1.Websocket介绍 WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。 应用场景: 视频弹幕网页聊天体育实况更新股票基金…...

node.js与express.js创建项目以及连接数据库
搭建项目 一、技术准备 node版本:16.16.0 二、安装node成功后,安装express,命令如下: npm install -g express 或者: npm install --locationglobal express 再安装express的命令工具: npm install --location…...

【Tomcat与网络8】从源码看Tomcat的层次结构
在前面我们介绍了如何通过源码来启动Tomcat,本文我们就来看一下Tomcat是如何一步步启动的,以及在启动过程中,不同的组件是如何加载的。 一般,我们可以通过 Tomcat 的 /bin 目录下的脚本 startup.sh 来启动 Tomcat,如果…...

Java Agent Premain Agentmain
概念 premain是在jvm启动的时候类加载到虚拟机之前执行的 agentmain是可以在jvm启动后类已经加载到jvm中了,才去转换类。 这种方式会转换会有一些限制,比如不能增加或移除字段。 具体的做法,两者的实际做法是差不多的: premain 定义个静…...

Python实现设计模式-策略模式
策略模式是一种行为型设计模式,它定义了一系列算法或策略,并将它们封装成独立的类,使得它们可以相互替换,而不影响客户端的使用。 在策略模式中,算法或策略被封装在单独的策略类中,这些策略类实现了相同的…...

详解SpringCloud微服务技术栈:深入ElasticSearch(4)——ES集群
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:详解SpringCloud微服务技术栈:深入ElasticSearch(3)——数据同步(酒店管理项目&a…...

AlmaLinux上安装Docker
AlmaLinux上安装Docker 文章目录 AlmaLinux上安装Docker一、前言二、具体步骤1、Docker 下载更新系统包索引:添加Docker仓库:安装Docker引擎: 2、Docker服务启动启动Docker服务:设置Docker开机自启: 3、Docker 安装验证…...

熟悉MATLAB 环境
一、问题描述 熟悉MATLAB 环境。 二、实验目的 了解Matlab 的主要功能,熟悉Matlab 命令窗口及文件管理,Matlab 帮助系统。掌握命令行的输入及编辑,用户目录及搜索路径的配置。了解Matlab 数据的特点,熟悉Matlab 变量的命名规则&a…...

【数据库数据恢复】Oracle数据库ASM磁盘组数据恢复案例
oracle数据库故障&分析: oracle数据库ASM磁盘组掉线,ASM实例不能挂载。数据库管理员尝试修复数据库,但是没有成功。 oracle数据库数据恢复过程: 1、将oracle数据库所涉及磁盘以只读方式备份。后续的数据分析和数据恢复操作都…...

STM32CubeMX教程31 USB_DEVICE - HID外设_模拟键盘或鼠标
目录 1、准备材料 2、实验目标 3、模拟鼠标实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.0、工程基本配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.0、配置Project Manager页面 3.2.1、设初始化调用流程 3.2.2、外设中…...

知道Wi-Fi名称和密码之后自动连接
这里写自定义目录标题 有Wi-Fi名称和密码自动连接Wi-Fi主Activity服务类 WIFIStateReceiver工具类 WIFIConnectionManager 有Wi-Fi名称和密码自动连接Wi-Fi 主Activity public class MainActivity extends AppCompatActivity implements View.OnClickListener{private static…...

本地搭建Plex私人影音网站并结合内网穿透实现公网远程访问
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...