《项目实战》构建SpringCloud alibaba项目

文章目录

  • 1、概要
  • 2、整体架构流程
    • 2.1、技术结构组成部分
  • 3、技术名词解释
  • 4、技术细节
    • 4.1、构建父工程
      • 4.1.1、选择构建Maven项目
      • 4.1.2、修改父工程文件
      • 4.1.3、修改父工程pom.xml配置
        • 4.1.3.1、添加springboot支持
        • 4.1.3.2、修改JDK版本、编码、springboot版本配置
        • 4.1.3.3、添加Spring Cloud、Spring Cloud alibaba版本规范配置
        • 4.1.3.4、增加lombok依赖配置
        • 4.1.3.5、增加build配置,整个工程使用maven打包
    • 4.2、构建公共子工程
      • 4.2.1、添加子工程store-common
      • 4.2.2、修改文件
      • 4.2.3、添加统一返回类
      • 4.2.4、添加token辅助类
    • 4.3、构建网关子工程
      • 4.3.1、修改pom.xml配置
      • 4.3.2、修改application.yml配置
      • 4.3.3、网关解决跨域问题
      • 4.3.4、网关增加鉴权功能AuthService
      • 4.3.5、增加网关登录验证拦截GatewayWebFilter
    • 4.3、构建微服务鉴权子工程store-authority-service
    • 4.4、构建微服务提供服务方子工程store-api
    • 4.5、构建微服务调用方子工程store-user-service
  • 小结

1、概要

本章节讲解如何构建SpringCloud alibaba项目,以父子工程形式搭建。

  • 父工程规范Springboot版本、SpringCloud版本、SpringCloud alibaba版本;
  • 子工程包括公共方法库(公共的DTO、http统一返回类(枚举code码等)),Gateway网关(集成Sentinel)、内网微服务统一接口层、内网微服务发布方、内网微服务调用方等;

2、整体架构流程

2.1、技术结构组成部分

在这里插入图片描述
此次框架选型是对Spring Cloud Netflix 框架组件的升级与替换。
Spring Cloud alibaba组件包括:Nacos (discovery、config)、Sentinel
Spring Cloud 组件包括:OpenFeign+ LoadBalancer 、Sleuth、Gateway
其他组件:RabbitMQ 、redis、mybatis-plus、knife4j、JWT、ShardingSphere-jdbc

3、技术名词解释

例如:

  • Nacos discovery: 英文全称为 Dynamic Naming and Configuration Service,是一个由阿里巴巴团队使用 Java 语言开发的开源项目,有注册中心、服务注册、发现功能。
  • Nacos config: 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。
  • Sentinel:是由阿里巴巴中间件团队开发的开源项目,是一种面向分布式微服务架构的轻量级高可用流量控制组件
  • Sleuth:可以将一次分布式请求还原成调用链路,进行日志记录,性能监控并将一次分布式请求的调用情况集中展示。
  • OpenFeign: 全称 Spring Cloud OpenFeign,它是 Spring 官方推出的一种声明式服务调用与负载均衡组件。我们可以像调用本地方法一样来调用远程服务,而完全感觉不到这是在进行远程调用,结合LoadBalancer 一起使用。
  • RabbitMQ:RabbitMQ整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。常用于系统解耦、削峰使用,常见于微服务、业务活动等场景。
  • mybatis-plus:数据库操作工具;
  • knife4j:基于swagger升级的文档管理工具。
  • JWT:JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案,基于JSON的开发标准,用户信息加密到token里,服务器不保存任何用户信息。
  • Apache ShardingSphere : 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强

4、技术细节

4.1、构建父工程

4.1.1、选择构建Maven项目

在这里插入图片描述

4.1.2、修改父工程文件

  • 删除src目录及底下的所有文件
  • 保留pom.xml
    在这里插入图片描述

4.1.3、修改父工程pom.xml配置

4.1.3.1、添加springboot支持

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.10</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  
  <groupId>com.kelvin</groupId>
  <artifactId>onlinestore</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

4.1.3.2、修改JDK版本、编码、springboot版本配置

  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-boot.version>2.7.10</spring-boot.version>
  </properties>

4.1.3.3、添加Spring Cloud、Spring Cloud alibaba版本规范配置

<dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>2021.0.5</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--spring cloud alibaba 依赖-->
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>2021.0.4.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

    </dependencies>
  </dependencyManagement>

4.1.3.4、增加lombok依赖配置

 <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>compile</scope>
        </dependency>
    </dependencies>

4.1.3.5、增加build配置,整个工程使用maven打包

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
        </plugins>

    </build>

4.2、构建公共子工程

在这里插入图片描述

4.2.1、添加子工程store-common

在这里插入图片描述

4.2.2、修改文件

  • 删除test文件夹
  • pom.xml去掉junit

4.2.3、添加统一返回类

package com.kelvin.common.http;

/***
 * @title HttpStatusInfoInterface
 * @desctption HTTP状态信息接口
 * @author Administrator
 * @create 2023/5/18 10:28
 **/
public interface HttpStatusInfoInterface {

    int getCode();

    String getMessage();

}

package com.kelvin.common.http;

/***
 * @title HttpStatusEnum
 * @desctption Http状态码
 * @author Administrator
 * @create 2023/5/18 10:30
 **/
public enum HttpStatusEnum implements HttpStatusInfoInterface{

    //定义状态枚举值
    SUCCESS(200 , "成功!"),
    NOROLE(300 , "权限不足!"),
    USER_TOKEN_NOT_EXISTS(301 , "无效的token信息!"),
    PRODUCT_STOCK_NOT_ENOUGH(302 , "商品的库存不足!"),

    BODY_NOT_MATCH(400 , "数据格式不匹配!"),
    NOT_FOUND(404 , "访问资源不存在!"),
    FLOW_LIMIT(490 , "接口流量已超出,限制访问!"),

    INTERNAM_SERVER_ERROR(500 , "服务器内部错误!"),
    SERVER_BUSY(503 , "服务器正忙,请稍后再试!"),
    REQUEST_METHOD_SUPPORT_ERROR(10001 , "当前请求方法不支持!"),
    REQUEST_DATA_NULL(10002 , "当前请求参数为空!"),
    USER_NOT_EXISTS(10003 , "该用户不存在!"),
    USER_INVALID(10004 , "当前登录信息已失效,请重新登录!"),
    PASSWORD_ERROR(10005 , "密码错误!"),
    USER_NAME_LOCK(10006 , "该账号已被锁定!")



    ;


    //状态码
    private int code;

    //提示信息
    private String message;

    HttpStatusEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }

    @Override
    public int getCode() {
        return this.code;
    }

    @Override
    public String getMessage() {
        return this.message;
    }
}

package com.kelvin.common.http;

import lombok.Data;

/***
 * @title ResultDTO
 * @desctption 控制器的统一返回类
 * @author Administrator
 * @create 2023/5/16 9:48
 **/
@Data
public class ResultDTO<T> {

    private Integer code ;
    private String message;
    private T data;

    public ResultDTO() {
    }

    public ResultDTO(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

package com.kelvin.common.http;

/***
 * @title HttpResultGenerator
 * @desctption <TODO description class purpose>
 * @author Administrator
 * @create 2023/5/18 10:43
 **/
public class HttpResultGenerator {

    //正常返回时调用方法
    public static ResultDTO success(Object data) {
        return new ResultDTO(HttpStatusEnum.SUCCESS.getCode() , "接口调用成功!" , data);
    }


    //失败时调用方法(入参是异常枚举)
    public static ResultDTO fail(HttpStatusEnum httpStatusEnum) {
        return new ResultDTO(httpStatusEnum.getCode() , httpStatusEnum.getMessage() , null);
    }

    //失败时调用方法(提供给GlobalExceptionHandler类使用)
    public static ResultDTO fail(int code ,  String message) {
        return new ResultDTO(code , message , null);
    }

}

4.2.4、添加token辅助类

package com.kelvin.common.dto;

import lombok.Data;

/***
 * @title TokenDTO
 * @desctption <TODO description class purpose>
 * @author Administrator
 * @create 2023/6/8 10:01
 **/
@Data
public class TokenDTO {

    private String token;

}

4.3、构建网关子工程

在这里插入图片描述

4.3.1、修改pom.xml配置

修改父工程指向

   <parent>
        <groupId>com.kelvin</groupId>
        <artifactId>onlinestore</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
<dependencies>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>1.8.5</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
            <version>1.8.6</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.kelvin</groupId>
            <artifactId>store-common</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

4.3.2、修改application.yml配置

server:
  port: 80
spring:
  main:
    web-application-type: reactive
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848  #Nacos server 的地址
    gateway: #网关路由配置
      routes:
        #将 drp-user-service 提供的服务隐藏起来,不暴露给客户端,只给客户端暴露 API 网关的地址 80
        - id: user-api_routh   #路由 id,没有固定规则,但唯一,建议与服务名对应
          uri: lb://user-api      #匹配后提供服务的路由地址
          predicates:
            #以下是断言条件,必选全部符合条件
            - Path=/user/**               #断言,路径匹配 注意:Path 中 P 为大写
            - Method=GET,POST #只能时 GET 请求时,才能访问
          metadata:
            connect-timeout: 10
            #单位毫秒
            response-timeout: 10000
        - id: authority-service_routh   #路由 id,没有固定规则,但唯一,建议与服务名对应
          uri: lb://auth-service     #匹配后提供服务的路由地址
          predicates:
            #以下是断言条件,必选全部符合条件
            - Path=/auth/**               #断言,路径匹配 注意:Path 中 P 为大写
            - Method=GET,POST #只能时 GET 请求时,才能访问
          metadata:
            connect-timeout: 10
            #单位毫秒
            response-timeout: 10000

    sentinel:
      transport:
        #配置 Sentinel dashboard 地址
        dashboard: localhost:8080
        #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719
        #开启除了controller层其他链路调用
      web-context-unify: false

4.3.3、网关解决跨域问题

package com.kelvin.storegateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Arrays;

@Configuration
public class WebConfig {
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
        configuration.setAllowedHeaders(Arrays.asList("content-type","token"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    public CorsWebFilter corsWebFilter(CorsConfigurationSource corsConfigurationSource) {
        return new CorsWebFilter(corsConfigurationSource);
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("*")
                        .allowedMethods("*")
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}


4.3.4、网关增加鉴权功能AuthService

package com.kelvin.storegateway.service;

import com.kelvin.common.dto.TokenDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;


/***
 * @title AuthService
 * @desctption <TODO description class purpose>
 * @author Administrator
 * @create 2023/6/8 10:04
 **/
@Component
@FeignClient(value = "auth-service")
public interface AuthService {

    @PostMapping("auth/isTokenExpiration")
    public Boolean validateToken(TokenDTO token);

}


4.3.5、增加网关登录验证拦截GatewayWebFilter

package com.kelvin.storegateway.filter;

import com.kelvin.common.dto.TokenDTO;
import com.kelvin.storegateway.service.AuthService;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.stream.Collectors;

/***
 * @title DrfGlobalFilter
 * @desctption 登录验证
 * @author Administrator
 * @create 2023/5/15 14:17
 **/
@Component
public class GatewayWebFilter implements GlobalFilter {

    @Resource
    private AuthService authService;

    @Bean
    @ConditionalOnMissingBean
    public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
        return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        //如果登录请求,不用验证token
        String path = request.getURI().getPath();
        if(!path.contains("login")) {
            HttpHeaders headers = request.getHeaders();
            String token =  headers.getFirst("token");
            if(StringUtils.isEmpty(token)) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            } else {
                TokenDTO tokenDTO = new TokenDTO();
                tokenDTO.setToken(token);

                //token验证不通过,返回给前端401
                Boolean aBoolean = authService.validateToken(tokenDTO);
                if(aBoolean){
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    return response.setComplete();
                }
            }
        }
        return chain.filter(exchange);
    }
}

4.3、构建微服务鉴权子工程store-authority-service

4.4、构建微服务提供服务方子工程store-api

4.5、构建微服务调用方子工程store-user-service

小结

通过上述操作可以轻松搭建出微服务架构,扩展十分容易。

父子工程构建已可用,持续更新中…

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

完美解决 RabbitMQ 可视化界面中 Overview 不显示图形的问题

&#x1f4a7; 记录一下今天遇到的 b u g \color{#FF1493}{记录一下今天遇到的bug} 记录一下今天遇到的bug&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 数据结构与算法…

拷贝构造函数

拷贝构造函数 以值传递的方式调用函数时&#xff0c;如果实参为对象&#xff0c;会调用拷贝构造函数。函数以值的方式返回对象时&#xff0c;可能会调用拷贝构造函数&#xff08;VS会调用&#xff0c;Linux不会&#xff0c;g编译器做了优化&#xff09;浅拷贝存在的问题 类似于…

反射---getattr,hasattr,setattr,delattr加插播enumerate

什么是反射&#xff1f; 用字符串数据类型的变量名来访问这个变量的值 反射的方法&#xff1a;getattr&#xff0c;hasattr&#xff0c;setattr&#xff0c;delattr 类&#xff1a;(通过类名反射类名空间里面的内容的) 类&#xff1a;静态属性&#xff0c;类方法&#xff0c;静…

【python】flask+pymysql 实现Web端操作数据库!

Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug &#xff0c;模板引擎则使用 Jinja2 。Flask使用 BSD 授权。 Flask也被称为 “microframework” &#xff0c;因为它使用简单的核心&#xff0c;用 extension 增加其他功能。Flask没有默认使用…

Qt5.15.10+msvc2019_x86+qwebengine(含mp4)源码编译

系统要求: win10 64bit 英文版(或者把“区域”->“管理”->“非Unicode程序中所使用的当前语言”->改为"英语(美国)") 内存16g够用,cpu性能越高越好,硬盘在安装环境、下载源码后,至少还有100g可用空间 下载源码: https://download.qt.io/archiv…

大话设计模式之——单例模式

单例&#xff08;Singleton&#xff09; Intent 确保一个类只有一个实例&#xff0c;并提供该实例的全局访问点。 Class Diagram 使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。 私有构造函数保证了不能通过构造函数来创建对象实例&#xff0c;只能…

Python零基础入门(二)——IDE介绍以及Python+PyCharm的安装

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python入门专栏&#xff1a;《Python入门》欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; 码字不易&#xff0c;如果觉得文章不…

路径规划算法:基于适应度相关优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于适应度相关优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于适应度相关优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能…

Unity基础4——LineRenderer

一、参数面板 二、参数介绍 Loop&#xff1a;是否首尾相连 Positions&#xff1a;线段的点 Width&#xff1a;线段宽度曲线的调整 Color&#xff1a;颜色变化 需要搭配材质才有效果 Corner Vertices&#xff1a;角顶点、圆角 此属性指&#xff0c;在一条线中绘制角时使用了…

一文读懂功率信号源(信号发生器)

功率信号源是一种用于产生高功率信号的电子设备&#xff0c;它广泛应用于各个领域&#xff0c;在生产、测试和调试中起着重要的作用。下面就让安泰将介绍功率信号源的基本概念、工作原理、分类以及应用。 功率信号源是一种能够产生稳定输出功率的设备。它通常由一个稳压电源和一…

红帽认证常见答疑(二):电脑配置、实验环境和考试环境、可以自学吗

学习红帽需要配置什么样的电脑&#xff1f; RHCE推荐学员自己的电脑内存在16G左右&#xff0c;RHCA推荐学员电脑内存在32-64G&#xff0c;且最好配置128G以上的固态硬盘&#xff0c;如果自己没有该配置的电脑&#xff0c;誉天可以提供远程学习环境&#xff0c;可以随时随地连接…

Java实现的五子棋游戏 ~java.awtjava.swing

文章目录 Java实现的五子棋游戏1.实现效果2.实现源码2.1运行主函数main.java2.2 棋盘布局Chessboard.java3.Algorithm算法 点击下载链接&#xff1a;Java实现的五子棋游戏源码下载 Java实现的五子棋游戏 作业要求&#xff1a; &#xff08;1&#xff09;课题代号&#xff1a; …

【裸机开发】使用汇编清除 .bss 段

目录 1、为什么要清除 .bss 段 2、使用汇编清除 .bss 段 1、为什么要清除 .bss 段 .bss 段保存的是 未被初始化 或者 初始化为0 的全局/静态变量。在编译器看来&#xff0c;这些东西是多余的&#xff0c;实际并不会给他们分配空间。因此&#xff0c;编译生成目标文件的时候&…

提升安全性与合规性的关键工具ADAudit Plus

在当今数字化时代&#xff0c;企业对于安全性和合规性的要求越来越高。特别是在Active Directory&#xff08;AD&#xff09;域中&#xff0c;作为组织的核心身份验证和访问管理系统&#xff0c;审计活动的重要性变得前所未有。为了满足这一需求&#xff0c;ADAudit Plus成为了…

A Survey of Large Language Models

本文是LLM系列的第一篇文章&#xff0c;针对《A Survey of Large Language Models》的翻译。 大语言模型综述 摘要1 引言2 概述2.1 LLM的背景2.2 GPT系列模型 的技术演化 3 LLMs的资源3.1 公开可用的模型检查点或APIs3.2 常用的语料库3.3 库资源 4 预训练4.1 数据收集4.1.1 数…

深入剖析 Python 函数参数传递机制及高级应用

前言 在本篇文章中&#xff0c;笔者将带你深入探讨 Python 函数传参的进阶主题。 通过阅读本篇文章&#xff0c;你可以深入了解 Python 函数传参的进阶主题&#xff0c;掌握更多高级的函数技巧&#xff0c;提升你的 Python 编程能力。 前面分享了Python 函数传参基础篇&#xf…

嵌入式Linux应用开发笔记:串口

文章目录 目的基础说明开发准备设备树应用程序 应用程序与演示代码演示 总结设备树文件 目的 串口&#xff08;UART&#xff09;是嵌入式设备中比较常用的功能。这篇文章将记录下应用程序中串口操作相关内容。 这篇文章中内容均在下面的开发板上进行测试&#xff1a; 《新唐N…

中介者模式(二十一)

相信自己&#xff0c;请一定要相信自己 上一章简单介绍了观察者模式(二十), 如果没有看过, 请观看上一章 一. 中介者模式 引用 菜鸟教程里面中介者模式介绍: https://www.runoob.com/design-pattern/mediator-pattern.html 中介者模式&#xff08;Mediator Pattern&#xff…

Django-带参数的路由编写(一)【不用正则表达式匹配的简单带参数路由】

在某urls.py文件有如下的路由配置语句&#xff1a; urlpatterns [path(app2/show/<int:id>/,views.show_id), ]语句&#xff1a; path(app2/show/<int:id>/,views.show_id),中的<int:id>就是带参数的URL中的参数部分&#xff0c;其语法格式如下&#xff1a…

Vue中如何进行图片识别与物体检测

Vue中如何进行图片识别与物体检测 随着人工智能技术的发展&#xff0c;图像识别和物体检测已经成为了很多应用场景的必备功能。在Vue中如何使用百度AI或腾讯AI等云服务实现图片识别和物体检测呢&#xff1f;本文将为您介绍一些基本概念和示例代码&#xff0c;帮助您快速入门。…