【Gradle】(三)详细聊聊依赖管理:坐标、依赖配置、依赖传递、依赖冲突
文章目录
- 1.概述
- 2.依赖管理
- 2.1.坐标
- 2.2.依赖的基本概念
- 2.3.依赖配置(Dependency configurations)
- 2.3.1.依赖路径
- 2.3.2.依赖配置与依赖路径的关联
- 2.4.依赖传递
- 2.4.1.准备工作
- 2.4.2.运行时依赖传递
- jar包生成与依赖配置
- 依赖树打印
- 使用 Dependency Analyzer 查看依赖
- 2.4.3.编译时依赖传递
- 2.5.依赖冲突
- 2.5.1.依赖解析(dependency resolution)
- 版本号的组成
- 版本号排序规则
- 2.5.2.排除传递依赖
- 单个排除
- 全局排除
- 2.5.3.强制指定版本号
- 3.总结
1.概述
在前面两篇文章中,我们已通过 Gradle 创建了一个多模块的项目,并介绍了一些常用的核心概念。至此,我们已能够在工作中使用 Gradle 了。
本篇内容主要讲解 Gradle 的依赖管理,旨在让大家对 Gradle 的依赖特性有一定了解,能够处理工作中出现的一系列依赖冲突问题,包含以下内容:
- 讲解坐标的概念
- 介绍依赖范围的概念及选择
- 说明依赖如何传递、如何避免依赖传递
- 阐述依赖冲突的概念、如何确认依赖冲突、如何解决依赖冲突
Gradle历史文章:
《【Gradle】(一)在IDEA中初始化gradle项目及其核心概念解释》
《【Gradle】(二)多模块项目、api推送到Maven私服、及SpringBoot可执行Jar包》
Maven相关文章:
《Maven中的依赖功能特性》
《Maven坐标的概念与规则》
对Maven感兴趣的话,可以看看我的上面两篇Maven文章,里面也介绍了一些依赖的概念,当然,如果不感兴趣的话,本篇文章也会引用这两篇Maven中的部分内容,不影响本篇文章的阅读。
2.依赖管理
2.1.坐标
在 Gradle 中,依赖的版本控制通常基于 Maven 的坐标系统,使用组 ID(groupId)、构件 ID(artifactId)和版本号(version)来唯一标识一个依赖项,这被称为 GAV(坐标)。
例如:implementation "cn.hutool:hutool-all:5.8.18" ,其中 cn.hutool 是组 ID,hutol-all是构件 ID,5.8.18 是版本号。
Gradle的构建一般也是使用的Maven仓库,很多时候在仓库中的jar包是共用的,所以我们在编写坐标时,也应遵循Maven的规范:
groupId:指的是当前构建隶属的实际项目,一般是 公司的网址倒序 + 项目名artifactId:一般是指的当前项目中的其中一个模块version:当前项目的版本号
版本号也不是随便写的,在业界有通用的规则,定义方式如下:
{主版本号}.{次版本号}.{增量版本号}-{里程碑版本}
- 主版本号:一般是指的当前的项目有了重大的架构变动,版本之间几乎完全不兼容,例如:最近出的 SpringBoot3 就已经放弃了Java8,如果不升级 JDK的话,还是只能使用SpringBoot2
- 次版本号:一般是指的项目的迭代版本,这种版本会修复大量的bug,带来一些小的新特性等,但是没有什么架构上的重大变化。
- 增量版本号:一般是用于修复一些紧急bug,改动量很小时,可以使用增量版本号。
- 里程碑版本:就是项目的当前版本处于一个什么样的阶段了,常见的里程碑版本有
SNAPSHOT,alpha,beta,release,GA等。
在里程碑的版本中,标注SNAPSHOT的为开发版,此时会存在大量的代码变动,alpha和beta分别对应的是内测版与公测版这三个版本都是属于不稳定版本,使用的时候非常容易踩坑,所以一般只用的demo体验,在正式环境中不能使用。
release和GA都属于是稳定的正式版本,可以在正式环境中使用。
下面是SpringBoot的一些版本号,可以体验一下:

2.2.依赖的基本概念
在软件开发中,依赖是指一个项目或模块对其他项目或模块的需求。例如,如果一个项目需要使用某个第三方库来实现某些功能,那么这个项目就对该第三方库存在依赖。
假设现在有 A、B、C 三个构件,如下图中表示的就是A依赖B和C

通过坐标定义:
dependencies {implementation "com.ls:B:1.0.0"implementation "com.ls:C:1.0.0"
}
2.3.依赖配置(Dependency configurations)
在这个章节会了解到Gradle中的几种常用的依赖路径,以及依赖配置和依赖范围的对应关系《官方参考文档》
2.3.1.依赖路径
从宏观的角度来看,常用的依赖类型有两种:编译路径(CompileClasspath)和运行时路径(RuntimeClasspath),在这两个概念的基础上,又加入了测试代码和非测试代码的区分,概念如下:
CompileClasspath:编译类路径,在编译项目时需要的依赖路径。RuntimeClasspath:运行时类路径,在运行项目时需要的依赖路径。TestCompileClasspath:测试代码编译类路径,是在编译测试代码时所需的依赖路径。TestRuntimeClasspath:测试代码运行时类路径,用于运行测试代码时所需的依赖路径。
除此之外,还有一种特殊的路径annotationProcessor,它也是一种依赖配置,在编译时生效。主要是用于将某些注解添加到依赖路径中,启用对注解的支持。在上篇文章中提到的lombok的注解支持就是这种类型:
dependencies {compileOnly "org.projectlombok:lombok:$lombokVersion"annotationProcessor "org.projectlombok:lombok:$lombokVersion"
}
说的更直白一点,所谓的编译时路径,就是写代码的时候可以直接Import使用的路径,运行时路径就是写代码的时候无法引入,但在程序运行的时候能够访问到(常见于间接依赖中)。
2.3.2.依赖配置与依赖路径的关联
- implementation:添加直接依赖包到编译时和运行时环境
- api:添加直接依赖包和间接依赖包到编译时和运行时环境,即向上层传递内部依赖关系
- compileOnly:添加依赖包,不添加到运行时路径
- runtimeOnly :不添加到编译时路径,添加运行时路径
- annotationProcessor:添加到注解处理器的类路径,不添加到运行时路径
更多依赖配置对应的依赖路径关系如下表所示:
| 依赖配置 | Compile Classpath | Runtime Classpath |
|---|---|---|
| api | √ | √ |
| implementation | √ | √ |
| compileOnlyApi | √ | × |
| compileOnly | √ | × |
| runtimeOnly | × | √ |
| testImplementation | √ | √ |
| testCompileOnly | √ | × |
| testRuntimeOnly | × | √ |
| annotationProcessor | √ | × |
在上面的表格中,有test前缀的依赖配置,只会在test任务中生效。
此外,可以看到还多了一个api,这也是一个可能会使用到的功能,主要是用在依赖传递中,在下面会讲解。
2.4.依赖传递
我们上面提到了编译时和运行时两种依赖路径,依赖传递也分为编译时依赖传递和运行时依赖传递,其中编译时依赖传递还依赖于api这个依赖配置,要使用这个配置,还需要额外引入java-library插件。下面就通过一个demo案例来体验一下两种依赖传递,同时,会介绍IDEA中自带的一种依赖查看工具 Dependency Analyzer。
2.4.1.准备工作
需要创建3个子模块进行模拟,分别是a-demo,b-demo,c-demo,同时需要将它们打包到本地Maven仓库中。
创建子模块:

创建3个子模块,并修改每个子模块的build.gradle,里面只放入version = 1.0.0,其他配置由根项目进行配置。

根项目配置
根项目中需要配置的有三个,插件配置、仓库配置、发布配置,配置的含义在本系列的前两篇文章中已经讲过了,这里就不再赘述了,根项目完整的配置如下,
plugins {id 'java'id 'org.springframework.boot' version "$springBootVersion" apply falseid 'io.spring.dependency-management' version "$springDenpendencyVersion" apply false
}allprojects {repositories {mavenLocal()maven {url 'https://maven.aliyun.com/repository/public'}mavenCentral()}
}subprojects {apply plugin: 'java'apply plugin: 'maven-publish'apply plugin: 'java-library'sourceCompatibility = JavaVersion.VERSION_1_8java {withSourcesJar()}publishing {publications {demo(MavenPublication) {from components.java}}repositories {maven {name = "mavenNexus"allowInsecureProtocol = truedef releasesRepoUrl = 'http://192.168.200.101:8081/repository/maven-releases/'def snapshotsRepoUrl = 'http://192.168.200.101:8081/repository/maven-snapshots/'url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrlcredentials {username 'admin'password 'admin123'}}}}dependencies {compileOnly "org.projectlombok:lombok:$lombokVersion"annotationProcessor "org.projectlombok:lombok:$lombokVersion"}}
gradle.properties配置
资源文件中需要配置项目整体的groupId和默认的version。
group=com.ls
version=1.0.0
2.4.2.运行时依赖传递
jar包生成与依赖配置
要感受到依赖传递,需要依次对c-demo,b-demo 两个依赖打包,首先是对c进行打包和推送到本地Maven仓库。

推送完成后修改b-demo的build文件,再按同样的方式打包:

最后,在a-demo中引入b-demo,并刷新Gradle引用。

依赖树打印
这里有两种方式可以查看依赖关系,一种是gradle自带的依赖树打印功能gradlew dependencies,另一种则是使用IDEA中的 Dependency Analyzer工具。
我们先看看第一种方式,要看a-demo的依赖关系,首先打开终端控制台,进入a-demo模块,然后再利用根目录的gradlew文件执行打印依赖树指令:
cd a-demo
../gradlew dependencies

在上图中,我们可以看到编译时路径和运行时路径 的依赖关系。
- 编译时路径中:
有b-demo和lombok,其中 b-demo 的依赖配置是implementation,上面提到了,这种依赖配置会将jar包添加到编译时和运行时两种依赖路径中,lombok是在根项目中配置的compileOnly,每个子模块都继承了这个配置,所以可以看到在编译时路径中会存在,也正是因为在编译时存在,在代码中才可以直接使用。
可以看到的是,目前的配置中,编译时并没有发生依赖传递(即没有出现间接依赖)。 - 运行时路径中:
我们可以看到的是,在运行时路径中除了b-demo这个直接依赖以外,还有c-demo这个间接依赖,这是因为implementation可以实现包在运行时路径上传递。
使用 Dependency Analyzer 查看依赖
如果觉得上面这种打印依赖树的方式有点繁琐,还可以使用IDEA的自带工具(好像是2022以上版本就有了)。如下图,可以直观的看到编译时和运行时的依赖关系,和上面打印出的结果是一致的。

如果想看到更详细的信息,可以选择红框中的任意一个包,右键选择Analyze Dependencies进入到工具弹窗中。


通过这里的一系列操作就可以查看到自己想看的依赖关系了,举个例子:假如我现在想看a-demo的运行时依赖关系,通过树状展示,可以这么做。

2.4.3.编译时依赖传递
编译时依赖传递需要通过api这个依赖配置实现,通过java-library插件引入。在根项目的subprojects中已经设置了apply plugin: 'java-library',这里可以直接使用。
现在我希望将b-demo中引入的c-demo包,在编译时和运行时都通过,通过间接依赖的形式传递给a-demo,只需要修改B模块中的build文件,将 implementation 修改为 api,修改完成后重新打包。在a-demo里面引入b。
- b-demo:
version = '1.0.1'dependencies {api 'com.ls:c-demo:1.0.0' } - a-demo:
version = '1.0.0'dependencies {implementation 'com.ls:b-demo:1.0.1' }
最后的结果是,两种路径的依赖都传递了:

2.5.依赖冲突
简单的说,依赖冲突就是在一个项目中引入了 groupId 和 ArtifactId 一样,但 version 不一样的jar包,程序在使用时不能确定要使用哪一个包。
《依赖解析官网文档》
2.5.1.依赖解析(dependency resolution)
不管是Maven还是Gradle都有处理依赖冲突的“调解机制”,在Gradle中叫“依赖解析(dependency resolution)”机制,两者之间还是有一定的区别,在工作中需要注意,不能混为一谈。
- Maven的处理方式是通过“就近原则”,即选择依赖路径中最近的那个版本,详情可以看这篇文章《Maven坐标的概念与规则》
- Gradle使用的是“最新版本优先”策略,在有多个版本冲突时,Gradle 默认选择最高的版本。
在判断多个版本的高低时,是通过定义好的版本排序机制来处理的,如果想对这个排序机制有比较详细的了解,可以去看看《版本排序官方文档》,下面先聊一下版本号的组成规则,再解释一下这个排序机制。
版本号的组成
版本号实际上是由两部分组成的:BaseVersion+Qualifier。
- BaseVersion:基础版本号,规范的情况下由
x.y.z3个数字组成,但也有其他字母组成的情况。 - Qualifier:限定符,规范的情况下有
beta,SNAPSHOT,RELEASE,GA等,也可能是其他不规则的符号,或者没有限定符。
下面的官网提供的例子,如何分解基础版本号与限定符:

在版本号里面有.,+,-,_这样的分隔符,以及字母和数字之间有一个空串分隔符,出现这些分隔符的时候会找第一个不是.的分隔符,左侧就是基础版本号,右侧就是限定符。
版本号排序规则
- 第一步:通过分隔符将版本号拆分成不同的组成部分
通过.,+,-,_这几个符号进行拆分,同时,如果有字母和数字的组合,也会拆解成不同的部分。
例如:1a1,1.a.1,1-a-1不管分隔符是什么,都会拆分成[1,a,1]三个部分。 - 第二步:分别对比每个部分的值
就像字符串的对比那样,从左到右,一个一个的对比,其大小规则为:2 > 1 > 0 > b > a > B > Am遇到多个部分组合比较的时候,还要注意一个规则:1.1.0 > 1.1 > 1.1.a - 第三步:特殊含义的限定符比较
比较规范的版本号中,右侧的限定符一般是用来标识当前的jar包状态的,例如是开发状态,还是发布状态,是测试版,还是稳定版等等。
这种情况也有优先级顺序:1.0-dev < 1.0-alpha < 1.0-zeta < 1.0-rc < 1.0-snapshot < 1.0-final < 1.0-ga < 1.0-release < 1.0-sp < 1.0
上面的规则比较多,不太方便记忆,但是也没关系,在大多数情况下版本号都是比较规范的,只需要比较数字的大小就可以了。
2.5.2.排除传递依赖
我们在引入多种三方jar包的时候,通过依赖传递的特性,可能会间接引入了某一个jar包的多个版本,但我们并不想使用Gradle自动指定的最高版本,这时候我们就可以通过排除传递依赖的方式,把最高版本的包排除掉。《排除传递依赖官方文档》
单个排除
语法也比较简单,在implementation引入依赖的时候,通过exclue排除依赖就可以了(需要将语法由空格隔开,调整为用小括号包裹)。exclue的参数常用的有4种组合,分别对应不同的功能:
-
排除所有传递依赖
artifactId在exclue的参数中使用module标记。implementation("com.ls:demo-api:1.0.0") {exclude(group: '*') }implementation("com.ls:demo-api:1.0.0") {exclude(module: '*') } -
指定排除某个
groupId的依赖implementation("com.ls:demo-api:1.0.0") {exclude(group: 'org.slf4j') } -
指定排除某个构件
implementation("com.ls:demo-api:1.0.0") {exclude(module: 'log4j') } -
指定排除某个
groupId下的某个构件依赖implementation("com.ls:demo-api:1.0.0") {exclude group: 'com.ls', module: 'c-demo' }
全局排除
除了一个一个的排除以外,有时候我们还想一次排除项目中的所有指定的传递依赖,例如前两年的log4j包出现了安全问题,需要把它从全局排除掉。
以上面多个子模块的demo项目为例,先查依赖找到log4j包:

// 根项目的 build.gradle 文件
subprojects {configurations.configureEach {exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j'exclude group: 'org.apache.logging.log4j', module: 'log4j-api'}
}
说明:configurations.configureEach 表示在所有的依赖配置中都排除掉,是Gradle6以后得功能,旧版本里面可以使用configurations.all,排除后的结果如下图。

如果只想排除一定的依赖配置,可以通过下面的语法来实现:
// 根项目的 build.gradle 文件
subprojects {configurations {compileOnly.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j'implementation.exclude group: 'org.apache.logging.log4j', module: 'log4j-api'}
}
2.5.3.强制指定版本号
可以通过force来强制使用某个版本号,这个功能也是在configurations 中进行配置,平时使用的不多,这里就简单提一下:
configurations.all {resolutionStrategy {force 'com.ls:c-demo:1.0.1'}
}
指定了之后,就不会管依赖传递中c-demo的版本号了,通通使用1.0.1版本。
3.总结
本文着重针对 Gradle 的依赖管理展开了全方位且极为详尽的介绍。在此过程中,清晰明确地提及了诸如坐标、依赖的基础概念、依赖配置、依赖传递还有依赖冲突等相关特性。在充分熟知并掌握了这些特性之后,于后续开展的工作当中,就能够更加精确、细致地对依赖进行管理,并且可以妥善、有效地处理由依赖冲突所引发的各种各样的问题。
相关文章:
【Gradle】(三)详细聊聊依赖管理:坐标、依赖配置、依赖传递、依赖冲突
文章目录 1.概述2.依赖管理2.1.坐标2.2.依赖的基本概念2.3.依赖配置(Dependency configurations)2.3.1.依赖路径2.3.2.依赖配置与依赖路径的关联 2.4.依赖传递2.4.1.准备工作2.4.2.运行时依赖传递jar包生成与依赖配置依赖树打印使用 Dependency Analyzer…...
C#数据类型:object、var和dynamic的比较与应用
在C#中,object、var和dynamic虽然常被提及为可以处理多种数据类型的“万能”方式,但它们各自有不同的应用场景、特性和优缺点。下面我将用通俗易懂的方式结合示例来详细说明这三者的区别与应用。 1. object 定义与应用场景:object是C#中所有…...
【面试题】MySQL(第一篇)
1. MySQL是什么? MySQL是一种开源的关系型数据库管理系统(RDBMS),它使用结构化查询语言(SQL)进行数据管理。MySQL具有高性能、可靠性、可扩展性和兼容性等特点,广泛应用于Web应用开发中。 2. …...
SQL Server集成服务(SSIS):数据集成的瑞士军刀
SQL Server集成服务(SSIS):数据集成的瑞士军刀 在数据仓库和大数据处理领域,SQL Server集成服务(SSIS)扮演着至关重要的角色。作为微软SQL Server套件的一部分,SSIS提供了一套强大的工具&#…...
鸿蒙开发HarmonyOS NEXT (三) 熟悉ArkTs (上)
一、自定义组件 1、自定义组件 自定义组件,最基础的结构如下: Component struct Header {build() {} } 提取头部标题部分的代码,写成自定义组件。 1、新建ArkTs文件,把Header内容写好。 2、在需要用到的地方,导入…...
值传递与引用传递:理解Java中的参数传递机制
值传递与引用传递:理解Java中的参数传递机制 1、值传递(Call by Value)2、引用传递(Call by Reference)3、总结 💖The Begin💖点点关注,收藏不迷路💖 值传递和引用传递的…...
Qt常用基础控件总结—带边框的部件(QFrame和QLabel)
带边框的部件 框架控件QFrame类 QFrame类介绍 QFrame 类是带有边框的部件的基类,带边框部件的特点是有一个明显的边框,QFrame类就是用来实现边框的不同效果的(把这种效果称为边框样式),所有继承自 QFrame 的子类都可以使用 QFrame 类实现的效果。 部件通常是矩形的(其他…...
太多项会毁了回归
「AI秘籍」系列课程: 人工智能应用数学基础 人工智能Python基础 人工智能基础核心知识 人工智能BI核心知识 人工智能CV核心知识 多项式回归的过度拟合及其避免方法 通过添加现有特征的幂,多项式回归可以帮助你充分利用数据集。它允许我们甚至使用简…...
python的魔法方法
python类中的self是什么? 对象的方法都会有一个self参数,类比于c,self就相当于c的this指针。 由一个类可以生成无数个对象,当一个对象的方法被调用时,对象会讲自身的引用作为第一个参数传给该方法,那么pyt…...
[Vue3 + TS + Vite] 获取网页选中内容的字符串格式或HTML格式
获取网页选中内容的字符串格式 let selected_text_by_mouse: any// 获取选中的文字 const mouse_selected_text(event:MouseEvent)>{const selection window.getSelection();if(selection && selection.rangeCount > 0){const content selection.toString();s…...
线程安全的原因及解决方法
什么是线程安全问题 线程安全问题指的是在多线程编程环境中,由于多个线程共享数据或资源,并且这些线程对共享数据或资源的访问和操作没有正确地同步,导致数据的不一致、脏读、不可重复读、幻读等问题。线程安全问题的出现,通常是…...
微信零钱明细删除了还能恢复吗?图文教程解析
在日常使用微信支付的过程中,查看零钱明细是管理个人财务的一项重要操作。然而,有时候我们可能会不小心删除了这些明细,导致无法追踪资金流动和消费记录。那么,微信零钱明细删除了还能恢复吗?这是许多用户关心的问题。…...
mp4视频太大怎么压缩不影响画质,mp4文件太大怎么变小且清晰度高
在数字化时代,我们常常面临视频文件过大的问题。尤其是mp4格式的视频,文件大小往往令人望而却步。那么,如何在不影响画质的前提下,有效地压缩mp4视频呢?本文将为您揭秘几种简单实用的压缩技巧。 在分享和存储视频时&am…...
【线程同步-2】
同步方法及同步块 接上期三大不安全案例,本期将介绍同步方法和同步块,以期达到安全的目的。 车站买票:加入了synchronized 同步方法 package syn; //不安全的买票 //线程不安全,有负数 public class UnsafeBuyTicket {publi…...
【别再为可视化工具付费了!】财务报表免费制作软件,这款免费可视化工具的功能超乎想象
会计工作中,关键一步就是把那些繁杂的财务数据整理成清晰易懂的财务报表,这就像是把一堆拼图块变成一幅完整的图画。山海鲸可视化这款免费工具,支持实时数据刷新,能够随时随地更新你的财务数据,确保你拿到的永远是最新…...
【HTML入门】第五课 - 加粗和倾斜的字体们
这一小节,我们说一些常用的HTML文本格式化的标签知识。可能你会觉得HTML知识比较零散,有好多标签。没错,就是比较零散,标签比较多。正式这些形形色色的HTML标签们,组成了丰富多彩的网页元素。 但是在刚学习的时候&…...
解决树形表格 第一列中文字没有对齐
二级分类与一级分类的文字没有对齐 <el-table:data"templateStore.hangyeList"style"width: 100%"row-key"id":tree-props"{ children: subData, hasChildren: hasChildren }" ><el-table-column prop"industryCode&quo…...
三级_网络技术_09_IP地址规划技术
1.某企业产品部的IP地址块为211.168.15.192/26,市场部的为211.168.15.160/27,财务部的为211.168.15.128/27,这三个地址块经聚合后的地址为()。 211.168.15.0/25 211.168.15.0/26 211.168.15.128/25 211.168.15.128/26 2.若某大学分配给计…...
力扣1878.矩阵中最大的三个菱形和
力扣1878.矩阵中最大的三个菱形和 斜前缀和 遍历矩阵元素,同时求当前点左下右下两位置的前缀和枚举每个菱形中心,遍历边长 int sum1[101][101];int sum2[101][101];class Solution {public:vector<int> getBiggestThree(vector<vector<in…...
ELB和VPC是云计算领域中的两个术语,通常与Amazon Web Services (AWS)相关联
ELB 和 VPC 是云计算领域中的两个术语,通常与亚马逊云服务(AWS)相关: 1. **ELB (Elastic Load Balancer)**: - 这是AWS提供的一种服务,用于自动分配进入应用程序的流量,以实现高可用性和容错…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...
