基于grpc从零开始搭建一个准生产分布式应用(2) - 工程构建

news2024/12/28 10:34:03

开始本章之前默认读者已经配置好了以下环境:Intellij IDEA 2022.1.2、JDK 1.8.0_144、Maven 3,另外也建议大家在一些免费代码托管平台开个帐号,这样就可以免费使用git做版本处理了,笔者自己私人使用的是阿里云的云效平台。因为此专题涉及到代码,所以笔者暂时把工程名称定为【base-grpc-framework】。

本章代码任务:1、构建工程目录;2、完成springboot集成模块;

一、为什么工程结构需要设计?

工程的构建工作一般很容易被忽略,通常认为只是创建几个目录存储代码用而已。其实不然,工程目录结构合理与否除了直接会影响工程打包和上线流程,还会影响开发效率以及重构。

工程目录设计除了符合系统架构外,还要符合小组成员的开发习惯。所以在开发新项目或是优化祖传代码时一定要把这件事做为一件非常重要的事来对待,否则过程中重构工程结构的代价会非常大,想想N多代码需要迁移、多个分支在开发、还要大量的回归测试等等。

二、两种典型的工程目录结构

2.1、普通的分布式工程结构

大多数项目组都会采用这种格式(在这个系列专题中笔者用到的是这种结构),这种结构一般比较适用单体应用或是不太复杂的分布式应用,其特点是把API定义和API实现隔离开。其它模块都可看成是辅助模块被包装或是被引用,其结构如下:

其调用关系大致如下,比较简单不再详细描述了,同学们理解下就可以:

2.2、组件化的分布式工程结构

这种应用比较复杂,一般是为了满足一套代码多地部署而设计的。其特点是多地部署时其核心代码在逻辑上存在差别。比如电商中的结算流程,在不同国家都有法律上的明确要求。

结算流程在中国需要遵守二分帐期的法规要求,但这个法规只局限于中国,比如在泰国就没有。在用同一套代码实现时就需要在部署泰国时把二分这个逻辑拿掉,一般有两种方案:1、维护两套源码;2、把差异点隔离出来,按需打包;在综合考虑成本时一般在维护大型系统时一般都会采用第2套方案。下同给出两个例子,这两个例子可以组合使用以适应更多场景。

 这种方式不在本专题内容范畴内,所以只简单介绍下,感觉举的读者可在笔者写的《DDD领域驱动设计》专题中了解。

上图红框内的模块区分了国别,承载了不同国家的定制化业务代码,cn-中国,id-印尼,th-泰国。

上图红框内的模块区分了业务,承载了不同业务方的定制化代码,比如虚拟商品区别于实物商品的物流和仓储流程。

综上:如果在建设中台系统或是跨国系统时可以采用2.2节中的工程设计,建设普通的业务类系统或单体应用时可采用2.1节中的工程设计。

三、工程详细

3.1、总体结构

为了有个全局视角,笔者把后续需要用到的模块一次性全创建了,如下图所示,这里只需了解下全貌即可,后续章节笔者会带着大家一点点填内容:

  • pom.xml:项目主maven文件,主要定义公共的配置以及版本控制;
  • .gitignore:用git时忽略的提供文件配置;
  • base-grpc-framework-common:项目工具包;
  • base-grpc-framework-api:项目接口定义;
  • base-grpc-framework-core:接口业务实现;
  • base-grpc-framework-dao:数据库存储实现;
  • base-grpc-framework-application:项目启动包装应用;
  • base-grpc-framework-client:web客户端;

四、创建过程

本节中我们要实现上一节中提到的工程结构,在特殊的地方笔者会详细说明,通用的地方大家按图示自行创建即可在后续实现代码时再完善其内容。因此专题的代码笔者一直在写,部分源码已早于文档内容并可能存在错误,所以暂时先不共享了,在此专题结束时会统一放出来。实在有需要的同学可以私信笔者,不过笔者强烈建议大家随着笔者一起来动手。

笔者用的是IDE是idea,建议大家使用2022的版本,优化了很多便捷的操作。必要的插件可参考笔者的 ​​https://blog.51cto.com/arch/5277533​​ 一文,先安装即可后续应该全会用到了。完整的工程目录下如:

4.1、创建root工程

root工程,只有一个pom.xml文件,主要为了控制版本和一些公共的配置(可查看下面的源码注释),打包为pom类型。文档中所有的代码都是经过笔者测试过的,可复制后直接使用,完整代码如下:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--工程定义-->
    <groupId>com.zd</groupId>
    <artifactId>base-grpc-framework-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <!--引入springboot框架-->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.2.2.RELEASE</version>
    </parent>

    <!--版本定义:插件相关、配置相关、工具框架、grpc、数据库、其它杂项-->
    <properties>
        <java.version>1.8</java.version>
        <maven.compile.source>1.8</maven.compile.source>
        <maven.compile.target>1.8</maven.compile.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <maven.kr.motd>1.6.2</maven.kr.motd>
        <maven.org.xolstice>0.6.1</maven.org.xolstice>

        <nacos.version>0.2.8</nacos.version>
        <junit.test.version>4.12</junit.test.version>

        <hutool.version>5.7.21</hutool.version>
        <lombok.version>1.18.20</lombok.version>
        <guava.version>30.1-jre</guava.version>
        <mapstruct.version>1.4.2.Final</mapstruct.version>

        <grpc.version>2.13.0.RELEASE</grpc.version>
        <io.grpc.version>1.42.1</io.grpc.version>
        <protobuf.java.version>3.19.1</protobuf.java.version>

        <mybatisplus.version>3.4.1</mybatisplus.version>
        <mysql.version>8.0.23</mysql.version>
        <druid.version>1.1.22</druid.version>

        <commons-lang3.version>3.9</commons-lang3.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--nacos应用配置-->
            <dependency>
                <groupId>com.alibaba.boot</groupId>
                <artifactId>nacos-config-spring-boot-starter</artifactId>
                <version>${nacos.version}</version>
            </dependency>

            <!--公共的工具类-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>

            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <scope>compile</scope>
            </dependency>

            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct</artifactId>
                <version>${mapstruct.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${mapstruct.version}</version>
            </dependency>

            <!--grpc相关-->
            <!--用于生成源代码的辅助类,供API模块使用-->
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-stub</artifactId>
                <version>${io.grpc.version}</version>
            </dependency>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-protobuf</artifactId>
                <version>${io.grpc.version}</version>
            </dependency>

            <!--用于服务端和客户端引用-->
            <dependency>
                <groupId>net.devh</groupId>
                <artifactId>grpc-server-spring-boot-starter</artifactId>
                <version>${grpc.version}</version>
            </dependency>
            <dependency>
                <groupId>net.devh</groupId>
                <artifactId>grpc-client-spring-boot-starter</artifactId>
                <version>${grpc.version}</version>
            </dependency>

            <!--proto生成java代码的工具库,建议三端都引用-->
            <dependency>
                <groupId>com.google.protobuf</groupId>
                <artifactId>protobuf-java</artifactId>
                <version>${protobuf.java.version}</version>
            </dependency>
            <dependency>
                <groupId>com.google.protobuf</groupId>
                <artifactId>protobuf-java-util</artifactId>
                <version>${protobuf.java.version}</version>
            </dependency>

            <!--数据库相关-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus</artifactId>
                <version>${mybatisplus.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatisplus.version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons-lang3.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.test.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!--三方仓库-->
    <repositories>
        <repository>
            <id>central</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <modules>
        <module>base-grpc-framework-common</module>
        <module>base-grpc-framework-api</module>
        <module>base-grpc-framework-core</module>
        <module>base-grpc-framework-dao</module>
        <module>base-grpc-framework-application</module>

        <module>base-grpc-framework-client</module>
    </modules>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${maven.compile.source}</source>
                    <target>${maven.compile.target}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

4.2、创建.gitignore免提交git控制文件

建议用git做为版本控制工具,文件内容如下:

# Folder
/target/
*/target/*
*.jar
/logs
/out/
*.log
!.mvn/wrapper/maven-wrapper.jar

# Ide and OS
.idea
*.iws
*.iml
*.ipr
*.DS_Store

# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*


# sts
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

4.3、创建base-grpc-framework-application服务启动模块

这个模块主要集成了springboot用于启动应用,没有任何业务逻辑,依赖core模块。隔离出来的原因是为了在更改部署和启动方式时不需要更改业务代码,比如可以再创建一个tomcat模块,用于在tomcat环境下部署。工程结构如下:

4.3.1、pom.xml配置

springboot的版本有时很容易出现jar包冲突和不兼容的问题,尤其和其它框架集成时。在官网上给了一些基线配置,读者可自行查阅,笔者用的是2.2.2.RELEASE版本(在本专题中不建议读者升级,因为后续集成其它框架时可能会带来冲突)。

在引入spring-boot-starter包时,如果后续要使用更高版本的log4j做为日志框架时,需排队logging模块,否则会有包冲突问题,如下所示:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>base-grpc-framework-parent</artifactId>
        <groupId>com.zd</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>base-grpc-framework-application</artifactId>
    <packaging>jar</packaging>

    <properties>
        <swagger.version>1.9.0.RELEASE</swagger.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.zd</groupId>
            <artifactId>base-grpc-framework-core</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!--生产环境建议去掉或封掉swagger功能-->
        <dependency>
            <groupId>com.spring4all</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
            <version>${swagger.version}</version>
        </dependency>

    </dependencies>
</project>

4.3.2、BaseFrameworkApplication启动类

注意@SpringBootApplication注解中的属性,笔者的类路径是是com.zd开头的。类路径:

/**
 * @Title: com.zd.baseframework.BaseFrameworkApplication
 * @Description 启动类,此类注解的值内容可以从外部的配置系统中配置
 * @author liudong
 * @date 2022/6/13 10:41 PM
 */
@SpringBootApplication(scanBasePackages = {"com.zd.baseframework", "cn.hutool.extra.spring"})
@MapperScan({"com.zd.baseframework"})
@EnableSwagger2
@EnableConfigurationProperties
public class BaseFrameworkApplication {
    public static void main(String []args){
        SpringApplication.run(BaseFrameworkApplication.class, args);
    }
}

4.3.3、SwawggerConfig框架

笔者为了偷懒一下,集成swawagger了框架只是为了测试Restful接口用,建议在线上环境中不要集成这个框架。开发测试时可以使用postman软件或是idea插件,源码如下,注意下.apis(basePackage("com.zd"))中的配置,笔者的类路径是是com.zd开头的:

/**
 * @Title: com.zd.baseframework.config.SwaggerConfig
 * @Description 用于swagger测试:访问地址:http://localhost:8080/swagger-ui.html
 * @author liudong
 * @date 2022/6/15 6:07 PM
 */
@Configuration
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        // 添加head参数start
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();
        tokenPar.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        pars.add(tokenPar.build());

        // 配置swagger
        Docket result = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(basePackage("com.zd.baseframework.core.controller.core"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(pars);
        result.enable(true);

        return result;
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Swagger-api文档")
                .description("用于开发测试,线上环境需要删除掉")
                .termsOfServiceUrl("http://localhost:15103")
                .version("1.0")
                .build();
    }

    public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
    }

    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return input -> {
            // 循环判断匹配
            for (String strPackage : basePackage.split(";")) {
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        };
    }

    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }
}

4.3.4、application.yml应用配置文件

springboot启动时默认读取名为application.yml文件。一般开发时都会有多个环境,自然也就存在了多个配置文件,笔者在这里只配置了开发和发布两个配置文件,内容暂时保持一致。

文件目录:src/main/resources/application-dep.yml和application-dev.yml

# http配置
server:
  compression:
    enabled: true
    mime-types: application/json,application/octet-stream

# spring配置
spring:
  application:
    name: GrpcFramework-Server-APP

4.3.5、启动测试

配置启动类为dev,如下图所示:如果没有环境变量(E)街面,可先点选【修改选项】勾上环境变量一项:

运行BaseFrameworkApplication.java类,不出意外的话可以在控制台看到如下输出。

打开浏览器,测试swawgger是否可正常访问,如下图所示:


此至本章主要内容就完成了,后面几个小节是为了后面内容做准备,建议大家先把工程创建了。

4.4、创建base-grpc-framework-api接口定义模块

在本专题中用proto来进行接口定义,优点是可以跨语言。其原理也比较简单,就是在编码期间通过插件编译成所需要的语言,proto是本系列一个非常重要的知识点后面会详细说明,本章只创建一个模块目录即可:

pom.xml配置如下:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>base-grpc-framework-parent</artifactId>
        <groupId>com.zd</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>base-grpc-framework-api</artifactId>
    <packaging>jar</packaging>
 <project>

4.5、创建base-grpc-framework-core模块

本章只创建一个模块目录即可,如下图所示:

pom.xml配置如下:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>base-grpc-framework-parent</artifactId>
        <groupId>com.zd</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>base-grpc-framework-core</artifactId>
    <packaging>jar</packaging>
 <project>

4.6、创建base-grpc-framework-dao模块

数据库实现,暂时只按如下方式创建即可。

pom.xml配置如下:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>base-grpc-framework-parent</artifactId>
        <groupId>com.zd</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>base-grpc-framework-dao</artifactId>
    <packaging>jar</packaging>
 <project>

4.7、创建base-grpc-framework-common模块

只按如下方式创建即可。后面再填加内容:

pom.xml配置如下:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>base-grpc-framework-parent</artifactId>
        <groupId>com.zd</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>base-grpc-framework-common</artifactId>
    <packaging>jar</packaging>
 <project>

五、GPRC的测试方法

5.1、grpcurl命令行测试

brew install grpcurl
//查看GRPC服务所有的服务列表
grpcurl --plaintext 127.0.0.1:9898 list
输出如下:
/*grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection
net.devh.boot.grpc.example.MyService
*/
  
//查看某一个接口提供的服务接口
grpcurl --plaintext 127.0.0.1:9898 list net.devh.boot.grpc.example.MyService
输出如下:
/*net.devh.boot.grpc.example.MyService.SayHello*/
 
//模拟访问
grpcurl --plaintext -d '{"name": "test"}' 127.0.0.1:9898 net.devh.boot.grpc.example.MyService/sayHello

5.2、grpcui图形化测试(推荐)

brew install grpcui  #安装
grpcui -plaintext 127.0.0.1:9898  #运行

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

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

相关文章

【Lua基础入门】解密世界上最快的脚本语言

文章目录 前言一、Lua简介二、Lua功能三、安装LuaUbuntu LinuxWindows安装Lua 四、第一个Lua程序总结 前言 Lua是一种轻量级、快速且可嵌入的脚本语言&#xff0c;广泛应用于游戏开发、嵌入式系统、脚本扩展等领域。它的设计目标是简单、高效、可定制和易于集成。本文将介绍Lu…

射频入门知识-1

信号源 示波器 综合测试仪 功率计 噪声测试仪 频谱分析仪 频谱分析仪: 放大器的噪声系数测试 放大器增益测试 噪声和增益是放大器的最关键指标&#xff0c;学学怎么用频谱仪做放大器的噪声测试 那个 hbf740 输入和输出阻抗匹配具体怎么搞 《ADS2011射频电路设计与…

iOS Epub阅读器改造记录

六个月前在这个YHEpubDemo阅读器的基础上做了一些优化&#xff0c;这里做一下记录。 1.首行缩进修复 由于分页的存在&#xff0c;新的一页的首行可能是新的一行&#xff0c;则应该缩进&#xff1b;也可能是前面一页段落的延续&#xff0c;这时候不应该缩进。YHEpubDemo基于XDS…

Cenos7 搭建Minio集群部署服务器(一)

------> 道 | 法 | 术 | 器 | 势 <------ 多台服务器间免密登录|免密拷贝 Cenos7 搭建Minio集群部署服务器(一) 企业级开源对象存储(看看官网吹的牛B) 开源为云提供动力。开源为企业提供动力。开源为 MinIO 提供支持。每天都有成千上万的客户和社区成员信任 Mi…

Spring Boot @Validated 验证注解的使用

1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency> 2、使用 2.1、非对象参数 参数如果是非对象格式&#xff0c;需要在controller类上面添…

cf暑假训练 1700-1800 day1

cf暑假训练 1700-1800 day1 1852B Imbalanced Arrays1850H. The Third Letter1833G Ksyusha and Chinchilla1833F Ira and Flamenco&#xff08;补完线段树来看&#xff09;1809D Binary String Sorting1780D Bit Guessing Game&#xff08;这题真的好难&#xff0c;我只能说我…

yolov5、YOLOv7、YOLOv8改进:注意力机制CA

论文题目&#xff1a;《Coordinate Attention for Efficient Mobile NetWork Design》论文地址&#xff1a; https://arxiv.org/pdf/2103.02907.pdf 本文中&#xff0c;作者通过将位置信息嵌入到通道注意力中提出了一种新颖的移动网络注意力机制&#xff0c;将其称为“Coordin…

msvcp120.dll丢失的解决方法?分享三种常见解决方法

msvcp120.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C Redistributable包中的一个组成部分。它是用于支持C编程语言的运行时库文件之一。它包含了许多标准库函数、容器类、算法和其他与C语言相关的功能。这些功能包括内存管理、字符串处理、数学计算、文件操作…

每日一题 206反转链表

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a; …

浅谈XML配置实现逻辑

XML简介 什么是XML&#xff1f; xml是可扩展的标记语言 XML的作用 主要作用&#xff1a; 1.用来保存数据&#xff0c;而且这些数据具有自我描述性 2.他可以作为项目或者模块的配置文件 3.还可以作为网络传输数据的格式&#xff08;现在JSON为主&#xff09; 第一个实例 命…

计算机组成原理-笔记-汇总

&#x1f4da; 前言 本人在备考408&#xff0c;王道讲得的确不错&#xff0c;本人之前也看过哈工大【刘宏伟老师】的课&#xff0c;两者对比下来。 王道——更加基础&#xff0c;对小白更加友好哈工大——偏实践偏硬件&#xff08;会将更多的代码硬件设计&#xff09; PS&#…

SpringBoot2-Tomcat部署

1.排除内置 Tomcat 在pom.xml文件中的下添加以下代码&#xff0c;用于排除SpringBoot内置Tomcat <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion&…

什么是CSS中的渐变(gradient)?如何使用CSS创建线性渐变和径向渐变?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 渐变&#xff08;Gradient&#xff09;在CSS中的应用⭐ 线性渐变&#xff08;Linear Gradient&#xff09;语法&#xff1a;示例&#xff1a; ⭐ 径向渐变&#xff08;Radial Gradient&#xff09;语法&#xff1a;示例&#xff1a; ⭐ 写…

Kotlin和Java互操作时的可空性

注&#xff1a;文中demo的kt版本是1.7.10 一、kotlin语言中的可空性设计 在Java语言中的NPE&#xff08;NullPointerException&#xff09;可以说非常常见&#xff0c;而且诟病已久。 kotlin做为后起之秀&#xff0c;在空指针的问题上进行了升级&#xff0c;即&#xff1…

day9 10-牛客67道剑指offer-JZ66、19、20、75、23、76、8、28、77、78

文章目录 1. JZ66 构建乘积数组暴力解法双向遍历 2. JZ19 正则表达式匹配3. JZ20 表示数值的字符串有限状态机遍历 4. JZ75 字符流中第一个不重复的字符5. JZ23 链表中环的入口结点快慢指针哈希表 6. JZ76 删除链表中重复的结点快慢指针三指针如果只保留一个重复结点 7. JZ8 二…

HttpRunner自动化工具之设置代理和请求证书验证

httprunner设置代理&#xff1a; httprunner 库本身没有提供设置代理的接口&#xff0c;但是底层使用了urllib.requests 等库&#xff0c;可以设置HTTP_PROXY 和HTTPS_PROXY 环境变量&#xff0c;常用的网络库会自动识别这些环境变量。 日常调试使用代理&#xff08;如charles…

SQL-每日一题【】

题目 Employees 表&#xff1a; EmployeeUNI 表&#xff1a; 展示每位用户的 唯一标识码&#xff08;unique ID &#xff09;&#xff1b;如果某位员工没有唯一标识码&#xff0c;使用 null 填充即可。 你可以以 任意 顺序返回结果表。 返回结果的格式如下例所示。 示例 1&a…

使用ip2region获取客户端地区

目录 从gitee拉取ip2region.xdb资源文件 写测试类 注意要写对资源路径 本地测试结果 ​编辑 远端测试结果 从gitee拉取ip2region.xdb资源文件 git clone https://gitee.com/lionsoul/ip2region.git 将xdb放入resources资源文件夹 写测试类 private Searcher searcher;GetMap…

funbox3靶场渗透笔记

funbox3靶场渗透笔记 靶机地址 https://download.vulnhub.com/funbox/Funbox3.ova 信息收集 fscan找主机ip192.168.177.199 .\fscan64.exe -h 192.168.177.0/24___ _/ _ \ ___ ___ _ __ __ _ ___| | __/ /_\/____/ __|/ __| __/ _ |/ …

数据结构-栈的实现(C语言版)

前言 栈是一种特殊的线性表&#xff0c;只允许在固定的一端进行插入和删除的操作&#xff0c;进行数据插入和删除的一端叫做栈顶&#xff0c;另一端叫做栈底。 栈中的数据元素遵循后进先出的的原则。 目录 1.压栈和出栈 2. 栈的实现 3.测试代码 1.压栈和出栈 压栈&#xff…