项目二技巧一

目录

nginx实现根据域名来访问不同的ip端口

配置Maven私服

快照版和发布版的区别

快照版本(Snapshot)

发布版本(Release)

 导入发布版的父工程

理清楚授权规则

一.首先浏览器发送/manager/**路径请求

 第二步:构造了TokenGatewayFilter方法,并把myConfig对象和当前过滤器对象作为参数传入

第三步:执行了filter方法并校验是否为放行path

第四步:执行AuthFilter的check方法,检验票据的合法性

第五步:执行AuthFilter的auth方法,进行鉴权

第六步:放行

完整的TokenGateWayFilter类

权限管家的api使用


nginx实现根据域名来访问不同的ip端口

nginx.conf配置文件的内容

在server_name中书写域名的名字,只要访问域名的根路径就会把请求反向代理到

proxy_pass http://127.0.0.1:10880 ip端口上

  1. proxy_set_header Host $host;:这行配置设置了代理请求的Host头部,将其设置为原始请求中的Host头部。

  2. proxy_set_header X-Real-IP $remote_addr;:这行配置设置了X-Real-IP头部,将其设置为客户端的IP地址。

  3. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;:这行配置设置了X-Forwarded-For头部,用于添加客户端的IP地址到现有的X-Forwarded-For头部中,这对于跟踪客户端的真实IP地址在代理环境中非常有用。

http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen       80;server_name  git.sl-express.com;error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}location / {client_max_body_size  1024m;proxy_connect_timeout 300s;proxy_send_timeout 300s;proxy_read_timeout 300s;proxy_pass http://127.0.0.1:10880;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}server {listen       80;server_name  maven.sl-express.com;error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}location / {client_max_body_size  300m;proxy_connect_timeout 300s;proxy_send_timeout 300s;proxy_read_timeout 300s;proxy_pass http://127.0.0.1:8081;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}

这里由于nginx在linux虚拟机上运行,如果我们需要在主机上根据域名来访问虚拟机上的不同ip端口时,需要编写hosts文件的内容

hosts文件所在目录

C:\Windows\System32\drivers\etc

 编写以下内容

192.168.150.101 git.sl-express.com
192.168.150.101 maven.sl-express.com

 这样一来在主机访问git.sl-express.com域名时,就会访问192.168.150.101这个虚拟机的ip,nginx就会根据nginx.conf配置文件的内容反向代理到虚拟机本地的http://127.0.0.1:10880ip端口

配置Maven私服

 Maven 私服(也称为 Maven 仓库管理器)是一个本地的 Maven 仓库,用于存储和管理 Maven 项目依赖的远程仓库中的项目。配置 Maven 私服可以提高构建速度,减少网络延迟,并且可以对依赖进行更好的控制。

配置完成后,当你运行 Maven 构建时,Maven 会首先检查私服中是否有所需的依赖,如果没有,才会从远程仓库下载。

我们可以在私服的 Web 界面中管理依赖,包括上传、下载、删除等操作。

 配置私服

settings.xml文件

在<servers>标签中子标签<server>中配置私服的用户名和密码

<id>sl-releases</id>:这个标签定义了服务器的唯一标识符(ID),在 Maven 的其他配置中,可以通过这个 ID 引用这个服务器配置。例如,在 pom.xml 文件中配置部署或发布时,可以使用这个 ID 来指定要部署到的服务器。
<username>deployment</username>:这个标签定义了访问服务器时使用的用户名。
<password>deployment123</password>:这个标签定义了访问服务器时使用的密码。

<servers>
        <server>
            <id>sl-releases</id>
            <username>deployment</username>
            <password>deployment123</password>
        </server>
        <server>
            <id>sl-snapshots</id>
            <username>deployment</username>
            <password>deployment123</password>
        </server>
    </servers>

mirror镜像,如果私服里没有相关的依赖,就去远程仓库里拉取对应的依赖

 <!-- 使用阿里云maven镜像,排除私服资源库 -->
    <mirrors>
        <mirror>
            <id>mirror</id>
            <mirrorOf>central,jcenter,!sl-releases,!sl-snapshots</mirrorOf>
            <name>mirror</name>
            <url>https://maven.aliyun.com/nexus/content/groups/public</url>
        </mirror>
    </mirrors> 

  1. <profiles> 标签

    • 这个标签是一个容器,用于包含多个 <profile> 配置。
  2. <profile> 配置

    • <id>sl</id>:这个标签定义了配置文件的唯一标识符(ID),在 Maven 命令中可以通过 -P 参数来激活这个 profile。
  3. <properties> 标签

    • 这个标签用于定义一些属性,这些属性可以在 Maven 构建过程中被引用。
  4. <altReleaseDeploymentRepository><altSnapshotDeploymentRepository> 属性

    • 这两个属性分别定义了发布版本和快照版本的部署仓库地址。格式为 <id>::default::<url>
    • <altReleaseDeploymentRepository>:指定了发布版本的部署仓库地址,这里使用的是 sl-releases 这个 ID,对应于 <servers> 配置中的一个服务器配置。
    • <altSnapshotDeploymentRepository>:指定了快照版本的部署仓库地址,这里使用的是 sl-snapshots 这个 ID,同样对应于 <servers> 配置中的一个服务器配置。
  5. <repositories> 标签

    • 这个标签用于定义项目依赖的远程仓库列表。
  6. 第一个 <repository> 配置

    • <id>sl-releases</id>:定义了仓库的唯一标识符(ID),与 <servers> 配置中的 ID 相对应。
    • <url>:指定了发布版本的远程仓库地址。
    • <releases>:指定了对于发布版本的配置,<enabled>true</enabled> 表示启用发布版本的下载。
    • <snapshots>:指定了对于快照版本的配置,<enabled>false</enabled> 表示禁用快照版本的下载。
  7. 第二个 <repository> 配置

    • <id>sl-snapshots</id>:定义了仓库的唯一标识符(ID),与 <servers> 配置中的 ID 相对应。
    • <url>:指定了快照版本的远程仓库地址。
    • <releases>:指定了对于发布版本的配置,<enabled>false</enabled> 表示禁用发布版本的下载。
    • <snapshots>:指定了对于快照版本的配置,<enabled>true</enabled> 表示启用快照版本的下载。

 

<?xml version="1.0" encoding="UTF-8"?>
<settingsxmlns="http://maven.apache.org/SETTINGS/1.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"><!-- 本地仓库 --><localRepository>F:\maven\repository</localRepository><!-- 配置私服中deploy的账号 --><servers><server><id>sl-releases</id><username>deployment</username><password>deployment123</password></server><server><id>sl-snapshots</id><username>deployment</username><password>deployment123</password></server></servers><!-- 使用阿里云maven镜像,排除私服资源库 --><mirrors><mirror><id>mirror</id><mirrorOf>central,jcenter,!sl-releases,!sl-snapshots</mirrorOf><name>mirror</name><url>https://maven.aliyun.com/nexus/content/groups/public</url></mirror></mirrors><profiles><profile><id>sl</id><!-- 配置项目deploy的地址 --><properties><altReleaseDeploymentRepository>sl-releases::default::http://maven.sl-express.com/nexus/content/repositories/releases/</altReleaseDeploymentRepository><altSnapshotDeploymentRepository>sl-snapshots::default::http://maven.sl-express.com/nexus/content/repositories/snapshots/</altSnapshotDeploymentRepository></properties><!-- 配置项目下载依赖的私服地址 --><repositories><repository><id>sl-releases</id><url>http://maven.sl-express.com/nexus/content/repositories/releases/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository><repository><id>sl-snapshots</id><url>http://maven.sl-express.com/nexus/content/repositories/snapshots/</url><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository></repositories></profile></profiles><activeProfiles><!-- 激活配置 --><activeProfile>sl</activeProfile></activeProfiles>
</settings>

配置的内容

http://maven.sl-express.com/nexus/content/repositories/releases

快照版和发布版的区别

在 Maven 中,快照版本(Snapshot)和发布版本(Release)是两种不同类型的版本,它们在版本控制和依赖管理中有着不同的用途和行为:

快照版本(Snapshot)

  • 开发阶段:快照版本通常用于开发阶段,它们表示代码还在积极开发中,可能会频繁变化。
  • 版本号:快照版本的版本号通常会包含时间戳或构建编号,例如 1.0-SNAPSHOT 或 1.0.1-SNAPSHOT
  • 更新频率:快照版本可能会非常频繁地更新,因为它们通常与持续集成(CI)流程相关联。
  • 不稳定性:由于快照版本是开发中的版本,它们可能不稳定,不保证向后兼容性。
  • 依赖更新:在 Maven 项目中,如果依赖了一个快照版本,Maven 会定期检查更新,并在发现新版本时自动更新依赖。

发布版本(Release)

  • 稳定阶段:发布版本用于表示已经稳定的代码,它们是经过测试和验证的,可以用于生产环境。
  • 版本号:发布版本的版本号不包含时间戳或构建编号,例如 1.0 或 1.0.1
  • 更新频率:发布版本的更新频率通常较低,只有在有新功能或修复时才会发布新版本。
  • 稳定性和兼容性:发布版本需要保证稳定性和向后兼容性,以确保依赖它们的项目能够正常运行。
  • 依赖锁定:在 Maven 项目中,如果依赖了一个发布版本,Maven 会锁定该版本的依赖,不会自动更新到新版本,除非显式地更改了版本号。

 导入发布版的父工程

    <parent><groupId>com.sl-express</groupId><artifactId>sl-express-parent</artifactId><version>1.3</version></parent>

快照版的父工程

 

理清楚授权规则

以上是授权路线图,我们需要跟着这幅图来理清楚这个项目的授权规则

一.首先浏览器发送/manager/**路径请求

一般根据请求路径的不同来转发到不同的微服务是由gateway网关来实现的,所以我们去gateway网关的application.yml文件中查看路径断言规则

spring:cloud:nacos:username: nacospassword: nacosserver-addr: 192.168.150.101:8848discovery:namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdcip: 192.168.150.1 #设置本地服务在nacos的地址与虚拟机ip的前三段相同,不然一部分微服务在本地跑,一部分在虚拟机跑#导致在nacos中的ip地址不同,以至于不同的微服务无法互相访问通config:namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdcgateway:globalcors:cors-configurations:'[/**]':allowed-origin-patterns: "*"allowed-headers: "*"allow-credentials: trueallowed-methods:- GET- POST- DELETE- PUT- OPTIONdiscovery:locator:enabled: true #表明gateway开启服务注册和发现的功能,并且spring cloud gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务routes:- id: sl-express-ms-web-manageruri: lb://sl-express-ms-web-managerpredicates:- Path=/manager/**filters:- StripPrefix=1- ManagerToken- AddRequestHeader=X-Request-From, sl-express-gateway

可以发现以/manager开头的路径会被负载均衡到lb://sl-express-ms-web-manager这个微服务中

不过在转发请求之前,还有三个过滤器

StripPrefix=1表示会跳过请求中的第一段在进行转发,即原来的路径会去掉/manager

AddRequestHeader=X-Request-From, sl-express-gateway表示添加请求头,表示请求的来源是gateway转发的

ManagerToken是自定义的过滤器,我们需要去查看这个过滤器的实现

   filters:
            - StripPrefix=1
            - ManagerToken
            - AddRequestHeader=X-Request-From, sl-express-gateway

gateway过滤器默认会省略后面的GatewayFilterFactory后缀,即应该为 ManagerTokenGatewayFilterFactory类

找到这个类

内容:

 该类继承了Gateway的AbstractGatewayFilterFactory<Object>类,表示这是一个过滤器

AuthFilter是自定义的接口,规定了检验token,和鉴权的方法

public interface AuthFilter {/*** 校验token** @param token 请求中的token* @return token中携带的数据*/AuthUserInfoDTO check(String token);/*** 鉴权** @param token        请求中的token* @param authUserInfo token中携带的数据* @param path         当前请求的路径* @return 是否通过*/Boolean auth(String token, AuthUserInfoDTO authUserInfo, String path);}
/*** 后台管理员token拦截处理*/
@Component
public class ManagerTokenGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> implements AuthFilter {@Resourceprivate MyConfig myConfig;@Resourceprivate TokenCheckService tokenCheckService;//从配置文件中加载能访问后台管理的角色ids@Value("${role.manager}")private List<Long>managerRoleIds;@Overridepublic GatewayFilter apply(Object config) {return new TokenGatewayFilter(this.myConfig, this);}@Overridepublic AuthUserInfoDTO check(String token) {try {//校验tokenreturn tokenCheckService.parserToken(token);} catch (AuthSdkException e) {// 校验失败}return null;}@Overridepublic Boolean auth(String token, AuthUserInfoDTO authUserInfoDTO, String path) {//获取AuthTemplate对象AuthTemplate authTemplate = AuthTemplateFactory.get(token);//查询该用户拥有的的角色idList<Long> roleIds = authTemplate.opsForRole().findRoleByUserId(authUserInfoDTO.getUserId()).getData();// 和配置的访问角色 取交集Collection<Long> intersection = CollUtil.intersection(roleIds, managerRoleIds);// 判断是否有交集即可判断出是否有权限return CollUtil.isNotEmpty(intersection);}
}

 第二步:构造了TokenGatewayFilter方法,并把myConfig对象和当前过滤器对象作为参数传入

我们来看一下MyConfig类是什么

可以看到与配置文件中的sl属性继续映射

@Data
@Component
@Configuration
@ConfigurationProperties(prefix = "sl")
public class MyConfig {private String[] noAuthPaths;}

这个属性规定了不需要权限就可以直接访问的所有接口 

sl:noAuthPaths:- /courier/login/account- /courier/swagger-ui.html- /courier/webjars/- /courier/swagger-resources- /courier/v2/api-docs- /courier/doc.html- /customer/user/login- /customer/swagger-ui.html- /customer/webjars/- /customer/swagger-resources- /customer/v2/api-docs- /customer/doc.html- /driver/login/account- /driver/swagger-ui.html- /driver/webjars/- /driver/swagger-resources- /driver/v2/api-docs- /driver/doc.html- /manager/login- /manager/webjars/- /manager/swagger-resources- /manager/v2/api-docs- /manager/doc.html- /manager/captcha
@Slf4j
public class TokenGatewayFilter implements GatewayFilter, Ordered {private MyConfig myConfig;private AuthFilter authFilter;public TokenGatewayFilter(MyConfig myConfig, AuthFilter authFilter) {this.myConfig = myConfig;this.authFilter = authFilter;}
}

第三步:执行了filter方法并校验是否为放行path

如果是不需要授权的路径就直接放行,并从 Authorization请求头中获取token票据信息,如果票据信息为空,就禁止访问

票据信息是登录认证时,后端给前端发布的一个票据,包含了用户用户的基本信息和用户拥有的角色id,因为我们设置了获取验证码和登录是不需要验证鉴权的接口,所以可以直接访问然后获取该用户对应的票据信息

 - /manager/login
    - /manager/captcha

    @Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String path = exchange.getRequest().getPath().toString();if (StrUtil.startWithAny(path, myConfig.getNoAuthPaths())) {//无需校验,直接放行return chain.filter(exchange);}//获取header的参数String token = exchange.getRequest().getHeaders().getFirst("Authorization");if (StrUtil.isEmpty(token)) {//没有权限exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}
}

第四步:执行AuthFilter的check方法,检验票据的合法性

 //校验tokenAuthUserInfoDTO authUserInfoDTO = null;try{ //捕获token校验异常authUserInfoDTO = this.authFilter.check(token);}catch (Exception e){log.error("权限校验失败,e:",e);}if (ObjectUtil.isEmpty(authUserInfoDTO)) {//token失效 或 伪造exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}

会去调用AuthFilter的实现类ManagerTokenGatewayFilterFactory的check方法,因为已经把这个类的实例通过TokenGateWayFilter的构造方法传入,因此可以进行回调。

我们来看一下ManagerTokenGatewayFilterFactory的check方法

不合法就返回null

    @Overridepublic AuthUserInfoDTO check(String token) {try {//校验tokenreturn tokenCheckService.parserToken(token);} catch (AuthSdkException e) {// 校验失败}return null;}

第五步:执行AuthFilter的auth方法,进行鉴权

 authUserInfoDTO是解析token时解析出来的用户的基本信息

        //鉴权Boolean result = false;try { //捕获鉴权异常result = this.authFilter.auth(token, authUserInfoDTO, path);}catch (Exception e){log.error("鉴权失败,e:",e);}if (!result) {//没有权限exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);return exchange.getResponse().setComplete();}

回调的ManagerTokenGatewayFilterFactory的auth方法

配置的可以访问的角色id是可以访问/manger开头接口的角色id,如果没有这些角色id就拒绝访问

这个配置文件在nacos配置中心中 

   //从配置文件中加载能访问后台管理的角色ids@Value("${role.manager}")private List<Long>managerRoleIds;
#角色id
role.manager = 986227712144197857,989278284569131905,996045142395786081,996045927523359809
    @Overridepublic Boolean auth(String token, AuthUserInfoDTO authUserInfoDTO, String path) {//获取AuthTemplate对象AuthTemplate authTemplate = AuthTemplateFactory.get(token);//查询该用户拥有的的角色idList<Long> roleIds = authTemplate.opsForRole().findRoleByUserId(authUserInfoDTO.getUserId()).getData();// 和配置的访问角色 取交集Collection<Long> intersection = CollUtil.intersection(roleIds, managerRoleIds);// 判断是否有交集即可判断出是否有权限return CollUtil.isNotEmpty(intersection);}

所以,如果该用户可以访问就返回true,反之

第六步:放行

并添加了两个请求头,把用户的基本信息序列化成json格式,并把票据加上token请求头中 

    //增加参数exchange.getRequest().mutate().header("userInfo", JSONUtil.toJsonStr(authUserInfoDTO));exchange.getRequest().mutate().header("token", token);//校验通过放行return chain.filter(exchange);

完整的TokenGateWayFilter类

@Slf4j
public class TokenGatewayFilter implements GatewayFilter, Ordered {private MyConfig myConfig;private AuthFilter authFilter;public TokenGatewayFilter(MyConfig myConfig, AuthFilter authFilter) {this.myConfig = myConfig;this.authFilter = authFilter;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String path = exchange.getRequest().getPath().toString();if (StrUtil.startWithAny(path, myConfig.getNoAuthPaths())) {//无需校验,直接放行return chain.filter(exchange);}//获取header的参数String token = exchange.getRequest().getHeaders().getFirst("Authorization");if (StrUtil.isEmpty(token)) {//没有权限exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}//校验tokenAuthUserInfoDTO authUserInfoDTO = null;try{ //捕获token校验异常authUserInfoDTO = this.authFilter.check(token);}catch (Exception e){log.error("权限校验失败,e:",e);}if (ObjectUtil.isEmpty(authUserInfoDTO)) {//token失效 或 伪造exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}//鉴权Boolean result = false;try { //捕获鉴权异常result = this.authFilter.auth(token, authUserInfoDTO, path);}catch (Exception e){log.error("鉴权失败,e:",e);}if (!result) {//没有权限exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);return exchange.getResponse().setComplete();}//增加参数exchange.getRequest().mutate().header("userInfo", JSONUtil.toJsonStr(authUserInfoDTO));exchange.getRequest().mutate().header("token", token);//校验通过放行return chain.filter(exchange);}@Overridepublic int getOrder() {return Integer.MIN_VALUE;}
}

权限管家的api使用

依赖

    <dependency><groupId>com.itheima.em.auth</groupId><artifactId>itcast-auth-spring-boot-starter</artifactId></dependency>
@SpringBootTest(properties = "spring.main.web-application-type = reactive")
public class AuthTemplateTest {@Resourceprivate AuthTemplate authTemplate;@Resourceprivate TokenCheckService tokenCheckService;@Autowiredprivate AuthorityProperties authorityProperties;@Testpublic void testLogin() {//登录,生成tokenResult<LoginDTO> result = this.authTemplate.opsForLogin().token("hhh", "123456");//得到tokenString token = result.getData().getToken().getToken();System.out.println("token为:" + token);//得到用户的消息UserDTO user = result.getData().getUser();System.out.println("user信息:" + user);//查询这个用户拥有的角色iddResult<List<Long>> resultRole = AuthTemplateFactory.get(token).opsForRole().findRoleByUserId(user.getId());System.out.println(resultRole);}@Testpublic void checkToken() {//上面方法中生成的tokenString token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxMzEyNDQ2OTcwNjUyMDAyODQ5IiwiYWNjb3VudCI6ImhoaCIsIm5hbWUiOiLkvZUiLCJvcmdpZCI6MTAyNTEwMzE3Njk0NjM5NTU4NSwic3RhdGlvbmlkIjoxMDI0NzA1NDg5NDM2NDk0NzIxLCJhZG1pbmlzdHJhdG9yIjpmYWxzZSwiZXhwIjoxNzMyOTk2NzI5fQ.lkOPgWXwOJ6OUuBiw4ctOyU7gl9sypxsYn2Sca4waHOFfxkQcVtSFzcKt-aieBS3Dn-vWfKx2YVQXkmggXOYIg";AuthUserInfoDTO authUserInfo = this.tokenCheckService.parserToken(token);System.out.println(authUserInfo);System.out.println(JSONUtil.toJsonStr(authUserInfo));}
}

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

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

相关文章

详解SpringCloud集成Camunda7.19实现工作流审批(二)

本章将分享的是camunda流程设计器--Camunda Modeler的基本使用&#xff08;对应camunda版本是7.19&#xff09;&#xff0c;包括bpmn流程图画法&#xff0c;各种控件使用以及一些日常业务场景的流程图的实现 参考资料&#xff1a; Camunda BPMN 基础组件-CSDN博客 Camunda: Exe…

webpack(react)基本构建

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。它的主要功能是将各种资源&#xff08;如 JavaScript、CSS、图片等&#xff09;视为模块&#xff0c;并将它们打包成一个或多个输出文件&#xff0c;以便…

html select下拉多选 修改yselect.js插件实现下拉多选,搜索,限制选中,默认回显等操作

需求&#xff1a;要在select标签实现下拉多选&#xff0c;搜索&#xff0c;限制选中&#xff0c;默认回显等操作&#xff0c;之前同事用的yselect.js&#xff0c;网上用的简直是寥寥无几&#xff0c;找了半天没找到限制选中的方法&#xff0c;看了源代码才发现根本没有&#xf…

c++哈希表(原理、实现、开放寻址法)适合新手

c系列哈希的原理及实现&#xff08;上&#xff09; 文章目录 c系列哈希的原理及实现&#xff08;上&#xff09;前言一、哈希的概念二、哈希冲突三、哈希冲突解决3.1、开放寻址法3.2、删除操作3.3、负载因子四、代码实现 总结 前言 红黑树平衡树和哈希有不同的用途。 红黑树、…

了解HTTPS以及CA在其中的作用

在这个信息爆炸的时代&#xff0c;每一次指尖轻触屏幕&#xff0c;都是一次数据的旅行。但您是否真正了解&#xff0c;这些数据在通往目的地的旅途中&#xff0c;是如何被保护的呢&#xff1f; HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;是一种安全的网…

Flink学习连载文章8--时间语义

Time的分类 (时间语义) EventTime:事件(数据)时间,是事件/数据真真正正发生时/产生时的时间 IngestionTime:摄入时间,是事件/数据到达流处理系统的时间 ProcessingTime:处理时间,是事件/数据被处理/计算时的系统的时间 EventTime的重要性 假设&#xff0c;你正在去往地下停…

sizeof和strlen区分,(好多例子)

sizeof算字节大小 带\0 strlen算字符串长度 \0之前

Simulink的SIL软件在环测试

以基于模型的设计&#xff08;MBD&#xff09;的软件开发时&#xff0c;需要进行SIL&#xff08;软件在环测试&#xff09;。SIL测试就是在PC上验证模型是否与代码功能一致。在项目开展中&#xff0c;用在需要将控制器生成移植到硬件前&#xff0c;把控制器的模块生成代码&…

浅谈js中onmouseleave和onmouseout的区别

同步发布于我的网站 &#x1f680; 背景介绍基本概念区别详解 无子元素的情况有子元素的情况 实际应用场景 使用 onmouseleave使用 onmouseout 注意事项总结 背景介绍 在前端开发中&#xff0c;我们经常需要为元素绑定鼠标事件&#xff0c;以实现各种交互效果。onmouseleave…

【Git系列】利用 Bash 脚本获取 Git 最后一次非合并提交的提交人

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

36 基于单片机的电磁炉系统设计

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;通过DS18B20温度传感器检测温度&#xff0c;通过八位数码管显示&#xff0c; 如果温度超过阈值&#xff0c;则蜂鸣器报警&#xff0c;红灯亮起&#xff1b;若不超过阈值&…

『 Linux 』数据链路层 - ARP协议及数据链路层周边问题

文章目录 ARP协议ARP欺骗RARP协议 DNS服务ICMP协议ping 命令正向代理服务器反向代理服务器 ARP协议 博客『 Linux 』数据链路层 - MAC帧/以太网帧中提到,当数据需要再数据链路层进行无网络传输时需要封装为MAC帧,而MAC帧的报文结构如下: 帧头部分存在两个字段分别为 “目的地址…

MySQL(数据库)

1.数据库? 数据库是管理数据(增删改查CRUD)的软件 MySQL(开源&免费) 是一个数据库软件 (客户端-服务器)结构的软件 客户端服务器通过网络进行通信 客户端(Client):主动发起请求的一方,客户端给服务器发起的数据称为请求(request) 服务器(Server):被动接受请求的一方,…

vue3----API

组合式API 1.setup 定义的数据和方法必须return出去才能够被使用 不使用this,this指向了undefined <script> export default {setup () {console.log(setup)const message this is messageconst logmessage ()>{console.log(message)}return {message,logmessag…

服务器遭受DDoS攻击后如何恢复运行?

当服务器遭受 DDoS&#xff08;分布式拒绝服务&#xff09;攻击 后&#xff0c;恢复运行需要快速采取应急措施来缓解攻击影响&#xff0c;并在恢复后加强防护以减少未来攻击的风险。以下是详细的分步指南&#xff1a; 一、应急处理步骤 1. 确认服务器是否正在遭受 DDoS 攻击 …

【maven-5】Maven 项目构建的生命周期:深入理解与应用

1. 生命周期是什么 ​在Maven出现之前&#xff0c;项目构建的生命周期就已经存在&#xff0c;软件开发人员每天都在对项目进行清理&#xff0c;编译&#xff0c;测试及部署。虽然大家都在不停地做构建工作&#xff0c;但公司和公司间&#xff0c;项目和项目间&#xff0c;往往…

【机器学习】CatBoost 模型实践:回归与分类的全流程解析

一. 引言 本篇博客首发于掘金 https://juejin.cn/post/7441027173430018067。 PS&#xff1a;转载自己的文章也算原创吧。 在机器学习领域&#xff0c;CatBoost 是一款强大的梯度提升框架&#xff0c;特别适合处理带有类别特征的数据。本篇博客以脱敏后的保险数据集为例&#x…

lua download

https://www.lua.org/ https://www.lua.org/versions.html#5.4

基于大数据python 房屋价格数据分析预测可视化系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度&#xff08;部分学校只有一次答辩机会 没弄好就延迟…

pikachu文件上传漏洞通关详解

声明&#xff1a;文章只是起演示作用&#xff0c;所有涉及的网站和内容&#xff0c;仅供大家学习交流&#xff0c;如有任何违法行为&#xff0c;均和本人无关&#xff0c;切勿触碰法律底线 目录 概念&#xff1a;什么是文件上传漏洞一、客户端check二、MIME type三、getimagesi…