前端包管理器的发展以及Npm、Yarn和Pnpm对比
在现代前端开发中,包管理器是不可或缺的核心工具。随着 JavaScript 生态的快速发展,开发者经历了从 npm 一统天下到 Yarn 挑战格局,再到 pnpm 创新突破的技术演进。这里将对三种主流包管理器(npm/Yarn/pnpm)进行全方位对比,分析其设计原理、性能表现和适用场景。
剖析package.json
现代前端工程中不管使用那种打包工具,都一定有一个该项目的描述文件,这个文件就是package.json,这个文件有很多描述当前工程的字段,我将其汇总如下图展示:
如上面图示,必填的字段有name和version,这两个属性组成一个npm模块的唯一标识
npm install原理详解
npm的发展
npm@2
在早期的npm(npm2)安装依赖时,处理方式非常的简单粗暴,就是以递归的形式,严格按照package.json的结构以及子依赖包的package.json结构进行安装,直至子依赖包不在依赖其他模块。比如说有一个项目要-app依赖了两个模块moduleA 和moduleB,而模块A是一个纯js模块不依赖其他模块,但moduleB又依赖了moduleB1和moduleB2那最后的目录结构就是这样的:
这样的方式优点是层级结构明显,node_module的结构和package.json的目录结构一致,并且可以保证每次安装的目录结构都是一样的。但是如果我们的项目非常的庞大,依赖的模块很多很复杂,那么嵌套的层就会非常的深,如下图所示
除此之外,如果不同层级的模块依赖了相同的模块,就会导致大量的冗余。在windows系统中,文件路径的最大长度是260个字符,如果层级过深就会导致不可预知的问题。
npm@3
为了解决上面的问题,NPM在3.x版本中做了一次比较大的更新。将嵌套的结构改成扁平的结构,安装模块时不管是直接依赖还是子依赖的依赖,优先将其安装在node_module目录下。还是上面的例子,安装之后我们会得到下面的目录结构
如果此时我们有新的模块依赖了moduleB2的某个版本此时就会检查,如果当前的moduleB2的版本符合我们的要求就会跳过,否则就会在当前模块下的node_module下安装新的moduleB2的模块。如下图所示:
这样不仅没有完全解决老的问题(依赖还是会嵌套的越来越深)并且还会引入一个新的问题,由于在执行npm install
时是按照package.json
的依赖顺序依次解析的,如果moduleA
和moduleB
的解析顺序就决定了目录结构,如果此时先解析了moduleA
那么目录结构可能是这样的:
此外,我们在实际开发中有时为了使用最新版本只会锁定大的版本,这就导致某些依赖的小版本更新后也会造成依赖的改动,这种依赖结构的不确定性可能会给程序带来不可预知的问题。
npm@5+
为了解决npm install
不确定性的问题,在npm@5
的这个版本中新增了一个package-lock.json
文件,而安装的方式还是沿用了之前npm3
的扁平方式。但是因为有了package-lock.json
可以锁定依赖结构的,只要项目目录下有这个文件,每次执行npm install
后生成的node_module
结构一定都是相同的。
package.lock.json
的结构如下:
最外面的两个属性 name 、version 同 package.json 中的 name 和 version ,用于描述当前包名称和版本。
dependencies 是一个对象,对象和 node_modules 中的包结构一一对应,对象的 key 为包名称,值为包的一些描述信息:
- version:包版本 —— 这个包当前安装在 node_modules 中的版本;
- resolved:包具体的安装来源;
- integrity:包 hash 值,基于 Subresource Integrity 来验证已安装的软件包是否被改动过、是否已失效;
- requires:对应子依赖的依赖,与子依赖的 package.json 中 dependencies的依赖项相同。;
- dependencies:结构和外层的 dependencies 结构相同,存储安装在子依赖 node_modules 中的依赖包‘’
这里注意,并不是所有的子依赖都有 dependencies 属性,只有子依赖的依赖和当前已安装在根目录的 node_modules 中的依赖冲突之后,才会有这个属性。
其他npm6+
在这之后npm也一直在更新,比如npm6引入的npm audit,npm7的workspaces和peer依赖自动安装,这里汇总后续的每个npm的特点如下:
版本 | 最大特点 |
---|---|
npm 5 | 引入 package-lock.json,提升安装速度和稳定性 |
npm 6 | npm audit 引入安全性检查,支持 npm ci,提升性能 |
npm 7 | 引入工作空间支持、自动安装 peerDependencies,全新锁文件格式 |
npm 8 | 性能优化、错误处理改进、增强的安全性功能 |
npm 9 | 性能提升、增强的工作空间支持、npm exec 命令和更好的漏洞检测 |
使用建议
所以我们一般在项目应用开发中一般把package-lock.json
文件提交,固定项目的文件结构,以避免带来不必要的麻烦。
当我们开发一个npm
工具包时,我们开发的npm
包是要被其他应用系统集成进去的,就像上面我们说到的扁平机制,如果锁定了依赖包的版本就没有办法和其他模块的依赖包共享符合版本号的依赖了,就会造成不必要的冗余,所以此时不应该把package-lock.json
发布出去(npm默认也是不会吧package-lock.json
发布出去就是这个原因)
npm缓存机制
当我们执行npm install
或npm update
命令下载依赖后,如果这台机器第一次安装这个模块,除了会将依赖包安装在node_module
中之外,也会在本地的缓存目录中缓存一份。我们可以通过npm config get cache
查询缓存目录,比如在mac下可以看到如下:
在这个目录下又存在两个目录:content-v2、index-v5,content-v2 目录用于存储 tar包的缓存,而index-v5目录用于存储tar包的 hash。
npm也提供了一些命令来管理缓存数据
- npm cache add:官方解释说这个命令主要是 npm 内部使用,但是也可以用来手动给一个指定的 package 添加缓存;
- npm cache clean:删除缓存目录下的所有数据,为了保证缓存数据的完整性,需要加上 --force 参数;
- npm cache verify:验证缓存数据的有效性和完整性,清理垃圾数据;
基于缓存数据,npm 提供了离线安装模式,分别有以下几种: - –prefer-offline: 优先使用缓存数据,如果没有匹配的缓存数据,则从远程仓库下载;
- –prefer-online: 优先使用网络数据,如果网络数据请求失败,再去请求缓存数据,这种模式可以及时获取最新的模块;
- –offline: 不请求网络,直接使用缓存数据,一旦缓存数据不存在,则安装失败;
文件完整性
在我们下载依赖包结束时会进行文件完整性的校验,以此来确保我们下载的包是完整的。那这个过程是怎样的呢?
在下载依赖包之前,一般都会拿到npm对该依赖包计算的hash值,我们可以通过npm info
来查看某个文件包的hash
值,比如我们查看一下axios
的信息:
当用户下载完成时,会在本地计算一次文件的hash
值如果两个hash
值相同则说明下载的依赖包是完整的,如果不同就会重新下载。
完整流程
-
检查 .npmrc 文件:优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc文件 > npm 内置的 .npmrc 文件;
-
检查项目中有无 lock 文件;
-
无 lock 文件:
- 从 npm 远程仓库获取包信息;
- 根据 package.json 构建依赖树,构建过程:
- 构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 node_modules 根目录;
- 当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node_modules 下放置该模块;
- 注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包;
- 在缓存中依次查找依赖树中的每个包
- 不存在缓存:
- 从 npm 远程仓库下载包;
- 校验包的完整性;
- 校验不通过:
- 重新下载;
- 校验通过:
- 将下载的包复制到 npm 缓存目录;
- 将下载的包按照依赖结构解压到 node_modules;
- 存在缓存:将缓存按照依赖结构解压到 node_modules;
- 不存在缓存:
- 将包解压到 node_modules;
- 生成 lock 文件;
-
有 lock 文件:
- 检查 package.json 中的依赖版本是否和 package-lock.json 中的依赖有冲突;
- 如果没有冲突,直接跳过获取包信息、构建依赖树过程,开始在缓存中查找包信息,后续过程相同
整个过程如下图所示:
Yarn
yarn (Yet Another Resource Navigator)是 Facebook 开发的一个新的包管理器。它的开发是为了提供 NPM 当时缺乏的更高级的功能(例如版本锁定,但后续的功能npm都补充上了),同时也使其更安全、更可靠和更高效。
Yarn 现在更像是 NPM 的替代品,由于 Yarn 没有预装 Node.js,因此需要显式安装:
npm install yarn -g
yarn的特点:
- 即插即用:从 Yarn 版本 2 开始,不再使用 node_modules 文件夹。相反,它会生成一个映射项目依赖关系的 .pnp.cjs 文件。这会导致更优化的依赖树和更快的项目启动和包安装;
- 零安装:此功能与 Plug’n’Play 结合使用,后者使用.pnp.cjs 文件来映射离线缓存中的包。这使您可以快速检索和安装已保存的软件包;
- 检查器:Yarn 带有一个内置的检查器,用于下载和安装包;
yarn
在下载时使用了并行安装项目依赖,这在大型应用中的安装速度显著的快很多。
比如看一个简单的yarn4初始化的项目
可以看到这个项目中安装了axios
模块但没有使用node_module
进行管理,而是使用了一个.pnp.cjs的文件进行管理
Yarn 和 NPM 的区别
Yarn | NPM |
---|---|
使用 yarn add 命令来安装依赖项 | 使用 npm install 命令安装依赖项 |
使用并行安装依赖项 | 按顺序安装依赖项 |
使用yarn.lock作为锁定文件 | 使用package-lock.json作为锁定文件 |
支持即插即用功能,它会生成一个 .pnp.cjs 文件,其中包含项目的依赖关系图 | 不支持 |
在安装大文件时更快 | 安装大文件时更慢 |
支持零安装功能,允许您离线安装依赖项,几乎没有延迟 | 不支持 |
在下载包时,它会利用包的许可信息在后台运行安全检查,以避免下载危险的脚本或导致依赖问题 | 在 NPM 的早期版本中,安全性是一个主要问题。从版本 6 开始,每次安装包时,NPM 都会进行安全审计以避免漏洞并确保没有不兼容的依赖项 |
校验和验证包 | 使用存储在 package-lock.json 文件中的 SHA-512 进行验证 |
Yarn 也支持 NPM 创建的 package-lock.json 文件,方便将版本数据从 NPM 迁移到 Yarn
yarn和npm3+的问题
在npm@3+ 和 yarn中,通过扁平化处理,解决依赖无法被共用,依赖层级太深的问题,所有的依赖都被平铺在node_modules中的一级目录。但是多个版本的包只有一个(最先安装的一个) 被提升上来,其余版本的包还是会嵌套安装到各自的依赖当中,之前提到的路径过长和重复安装的问题没有彻底解决。除此之外还有幽灵依赖的问题。比如本地没有显实的依赖axios
这个模块,但是依赖了其他模块二其他模块依赖了axios
这个模块,这就导致也会将axios
模块安装到用户的node_module
下,这导致用户在代码中实际也能使用axios
模块的功能,显然这和我们的预期是不符合的。这就是幽灵依赖
Pnpm
pnpm,即performant npm,高性能的npm。相比起目前主流的包管理器,pnpm是速度快、节省磁盘空间的包管理器。
Pnpm性能对比
我们先看一下官网提供的性能对比数据:
可以看出,与目前主流的包管理器npm、yarn相比,无论有无cache、有无lockfile、有无node_modules,pnpm的安装速度都有明显的优势
Pnpm在磁盘中的存储
pnpm
之所以这么快的最主要的原因是,pnpm通过hard link(硬连接)机制,节省磁盘空间并提升安装速度。
hard link
(硬链接):多个文件名指向同一索引节点(Inode)。硬链接的作用 之一是允许一个文件拥有多个有效路径名,这样用户就可以建 立硬链接到重要的文件,以防止“误删”源数据
如果原始文件被删除,只要硬链接还存在,数据仍然可访问,文件并没有真正被删除。只有所有的硬链接都删除后,文件数据才会被清除
举个例子,如果有100各项目都依赖同一个三方模块,如果使用npm
或者是yarn
的话
那这个模块要被重复安装100次相同的“副本”。而使用 pnpm,package将被存放在一个统一的位置(如 Mac是 ~/.pnpm-store )。当安装软件包时,其包含的所有文件都会硬链接自此位置,而不会占用额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的package。因此,不会有上面提到的重复安装相同包的问题了。
当我们使用pnpm
在本地一个项目安装axios
时可以发现有个reused字段表之前已经安装过相同的包了。
而当安装版本不同的同名软件包时,仅会添加版本之间不同 的文件到存储器中,而不会因为一个文件的修改而保存package的所有文件。
同时该命令提供了一个选项,使用方法为pnpm store prune,它提供了一种用于删除一些不被全局项目所引用到的package的功能。如果需要,开发者可以用这个命令来管理已有的package。
Pnpm对node_Module的优化
除了节省磁盘空间,pnpm还有另一个重要特点是,建立非扁平的node_modules目录,并在引用依赖的时候通过sybolic link机制找到对应.pnpm目录的地址。我们看一下使用pnpm
管理项目的node_module
的目录结构
可以看到在node_module
中都是平铺的形式管理三方依赖的模块,并且axios
和lodash
在node_module
中这两个文件夹的右侧都有一个小箭头,这是一个软连接实际是链接到了.pnpm下这样的路径:.pnpm中对应的模块。
sybolic link(软链接,也叫符号链接):类似于windows系统中的快捷方式,与硬链接不同,软链接就是一个 普通文件,只是数据块内容有点特殊,文件用户数据块中存放的内容是另一文件的路径名的指 向,通过这个方式可以快速定位到软连接所指向的源文件实体。
这样,pnpm 实现了相同模块不同版本之间隔离和复用。而且,node_modules目录是非扁平的,不存在由于提升带来的幽灵依赖问题。比如我们可以看在.pnpm
目录下的axios
和lodash
都有各自的node_module
小结
- pnpm 通过 hard link 在全局里面搞个 store 目录来存储 node_modules 依赖里面的 hard link 地址。这样节省了磁盘空间,并提升安装速度
- node_modules目录是非扁平的,在引用依赖的时候,则是通过 sybolic link 去找到对应虚拟磁盘目录下(.pnpm 目录)的依赖地址。这样,避免了之前npm和yarn扁平/非扁平安装带来的一系列问题;
整个流程如下图所示:
对比
特性 | npm | yarn | pnpm |
---|---|---|---|
安装方式 | 自动随 Node.js 安装 | 需要单独安装 | 需要单独安装 |
包缓存 | 支持缓存,但缓存机制较为简单 | 支持缓存,安装时从缓存中获取加速 | 支持强大的磁盘缓存机制,避免重复下载和浪费空间 |
安装速度 | 相对较慢,尤其在大量依赖时 | 更快,尤其是有缓存时 | 更快,采用硬链接方式减少重复依赖的存储 |
依赖管理 | 使用 node_modules 存储依赖 | 使用 node_modules 存储依赖,优化了依赖的管理方式 | 使用硬链接和符号链接来创建依赖树,提高存储效率 |
工作空间(Workspaces) | 从 npm 7 开始支持工作空间 | 原生支持工作空间,用于管理 monorepos | 支持工作空间,适用于 monorepos 项目 |
锁文件 | package-lock.json | yarn.lock | pnpm-lock.yaml |
安装依赖的精确性 | 有时依赖版本可能不一致(尤其在没有锁文件的情况下) | 确保锁文件的精确性,安装一致 | 高精度的依赖版本控制,确保每个开发环境一致 |
并发下载 | 支持并发下载,但效率较低 | 支持并发下载,速度更快 | 使用并发下载并且非常高效 |
兼容性 | 与大多数现有工具兼容 | 高度兼容 npm,支持较多工具 | 兼容 npm 和 Yarn,支持多种工具 |
安装的存储优化 | 存储空间相对浪费,所有模块都存储在 node_modules 下 | 有一定优化,减少重复存储 | 使用硬链接存储,节省磁盘空间,避免重复依赖存储 |
社区支持 | 最大,几乎所有 JavaScript 项目都支持 | 良好,尤其在 Facebook 和 JavaScript 社区中受欢迎 | 较新,但支持增长迅速,逐渐得到许多大项目的青睐 |
Monorepo项目选择包管理器
Monorepo的思想是严格统一,多个项目放在一个仓库里面。比较知名的像Antd、babel、npm7都是在用Monorepo方式进行管理的。Monorepo常见目录结构如下
- packages- project1- src- index.ts- package.json- project2- src- index.ts- package.json- project3- src- index.ts- package.json
- package.json
- tsconfig.json
这样有以下几点好处:
- 统一工作流:由于所有的项目放在一个仓库当中,复用起来非常方便,如果有依赖的代码变动,那么用到这个依赖的项目当中会立马感知到。并且所有的项目都是使用最新的代码,不会产生其它项目版本更新不及时的情况,对开发调试而言都带来了方便
- 降低基建成本:所有项目复用一套标准的工具和规范,无需切换开发环境,如果有新的项目接入,也可以直接复用已有的基建流程,比如 CI 流程、构建和发布流程。这样只需要很少的人来维护所有项目的基建,维护成本也大大减低
- 团队协作也更加容易 ,一方面大家都在一个仓库开发,能够方便地共享和复用代码,方便检索项目源码,另一方面,git commit 的历史记录也支持以功能为单位进行提交,之前对于某个功能的提交,需要改好几个仓库,提交多个 commit,现在只需要提交一次,简化了 commit 记录,方便协作
当我们开发维护一个monorepo
的项目时比较合适的包管理工具是pnpm
,因为pnpm
具有npm
和yarn
没有的独特优势,具体有以下几点:
4. 支持 Workspaces:pnpm 原生支持 workspaces,可以自动管理多个子项目的依赖,确保所有的 package 依赖关系正确无误。
- 高效的存储机制:pnpm 采用硬链接和符号链接来存储依赖,而不是像 npm 或 yarn 那样直接复制 node_modules,从而极大地节省了磁盘空间。例如:
如果多个 package 依赖相同的 react,pnpm 只会在全局存储中保存一份,而不同的 package 只会创建指向它的链接。
这样比 npm 和 yarn 节省磁盘空间,并且加快安装速度。 - 自动处理 package 之间的依赖:pnpm 能够自动解析 monorepo 内部的依赖,例如 package-a 依赖 package-b,pnpm 可以直接链接,而不需要手动指定路径。
避免了手动 npm link 或 yarn workspaces run 这样的复杂操作。 - 严格的依赖管理:pnpm 的 node_modules 采用严格模式,避免了 npm 和 yarn 可能导致的幽灵依赖问题(即 package.json 没有声明依赖但仍然可以使用)。
如何在 pnpm 中启用 Workspaces
需要使用pnpm
管理多包项目非常简单。只需要按照下面步骤即可
创建 pnpm Monorepo
在根目录下创建 pnpm-workspace.yaml:
packages:- "packages/*" # 这里会自动识别 packages 目录下的所有子项目
然后在 package.json 中启用 workspaces:
{"name": "my-monorepo","private": true,"devDependencies": {"pnpm": "^8.0.0"}
}
创建多个子项目
创建 packages/package-a/package.json:
{"name": "package-a","version": "1.0.0","main": "index.js","dependencies": {"lodash": "^4.17.21"}
}
创建 packages/package-b/package.json,并让 package-b 依赖 package-a:
{"name": "package-b","version": "1.0.0","main": "index.js","dependencies": {"package-a": "workspace:*"}
}
安装依赖
pnpm install
pnpm 会自动解析 workspace:* 依赖,确保 package-b 能够正确依赖 package-a。
依赖会被存储在 node_modules/.pnpm 下,并通过符号链接管理。
对比各包管理器在monorepo下的作用
特性 | pnpm workspaces | yarn workspaces | npm workspaces |
---|---|---|---|
存储方式 | 硬链接+符号链接(节省空间) | 直接安装在 node_modules 里 | 直接安装在 node_modules 里 |
安装速度 | 🚀 最快 | 中等 | 最慢 |
依赖隔离 | 严格(无幽灵依赖) | 可能有幽灵依赖 | 可能有幽灵依赖 |
支持 workspace:* 语法 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
自动解析内部依赖 | ✅ 自动解析 | ✅ 自动解析 | ✅ 自动解析 |
适合 Monorepo | ✅ 非常适合 | ✅ 适合 | ✅ 适合 |
缓存机制 | 强大的缓存机制,避免重复安装依赖 | 默认缓存,效率较高 | 默认缓存,效率较低 |
依赖版本控制 | 高精度版本控制,严格管理依赖 | 高精度版本控制 | 高精度版本控制 |
硬链接优化 | ✅ 高效硬链接管理 | ❌ 不支持 | ❌ 不支持 |
相关文章:
前端包管理器的发展以及Npm、Yarn和Pnpm对比
在现代前端开发中,包管理器是不可或缺的核心工具。随着 JavaScript 生态的快速发展,开发者经历了从 npm 一统天下到 Yarn 挑战格局,再到 pnpm 创新突破的技术演进。这里将对三种主流包管理器(npm/Yarn/pnpm)进行全方位…...
城电科技| 光伏太阳花:让绿色能源随处绽放
在追求绿色可持续发展的今天,清洁能源设备不断涌现,城电科技的光伏太阳花便是其中的佼佼者。它不仅造型独特美观,更凭借出色的性能,在多个场景中都能发挥重要作用。那么,这款神奇的光伏太阳花究竟适合安装在哪里呢&…...
LVS集群(DR/NAT)
特性NAT 模式DR 模式工作原理Director 修改请求/响应的 IP 地址和端口,流量双向经过 DirectorDirector 仅修改请求的 MAC 地址,响应由 Real Server 直接返回客户端性能较低(需处理双向流量,易成瓶颈)高(仅处…...
保姆级GitHub大文件(100mb-2gb)上传教程
GLF(Git Large File Storage)安装使用 使用GitHub desktop上传大于100mb的文件时报错 The following files are over 100MB. lf you commit these files, you will no longer beable to push this repository to GitHub.com.term.rarWe recommend you a…...
【Jenkins流水线搭建】
Jenkins流水线搭建 01、SpringBoot项目 - Jenkins基于Jar持续集成搭建文档基于手动方式发布项目基于dockerfile基于jenkins + dockerfile + jenkinsfile +pieline基于jenkins + jar方式的发布01、环境说明01、准备项目02、准备服务器03、安装git04、安装jdk1.805、安装maven依赖…...
linux 安装ftp
1、安装vsftpd sudo yum install -y vsftpd 2、运行以下命令,启动FTP服务,并设置开机自启动。 sudo systemctl start vsftpdsudo systemctl enable vsftpd 3、运行以下命令,查看FTP服务监听的端口。 sudo netstat -antup | grep ftp 出现…...
DDoS技术解析
这里是Themberfue 今天我们不聊别的,我们聊聊著名的网络攻击手段之一的 DDoS,看看其背后的技术细节。 DoS 了解 DDoS 前,先来讲讲 DoS 是什么,此 DoS 而不是 DOS 操作系统啊。1996年9月6日,世界第三古老的网络服务提供…...
移远通信边缘计算模组成功运行DeepSeek模型,以领先的工程能力加速端侧AI落地
近日,国产大模型DeepSeek凭借其“开源开放、高效推理、端侧友好”的核心优势,迅速风靡全球。移远通信基于边缘计算模组SG885G,已成功实现DeepSeek模型的稳定运行,并完成了针对性微调。 目前,该模型正在多款智能终端上进…...
Linux | 进程相关概念(进程、进程状态、进程优先级、环境变量、进程地址空间)
文章目录 进程概念1、冯诺依曼体系结构2、进程2.1基本概念2.2描述进程-PCB2.3组织进程2.4查看进程2.5通过系统调用获取进程标识符2.6通过系统调用创建进程-fork初识fork の 头文件与返回值fork函数的调用逻辑和底层逻辑 3、进程状态3.1状态3.2进程状态查看命令3.2.1 ps命令3.2.…...
站群服务器和普通服务器有哪些不同之处?
站群服务器是一个集中管理工具,可以允许网站管理员同时管理多个网站,但是不要管理员登录每一个网站的后台,在站群模式下,网站管理员通过一个或者多个服务器来托管大量的子站点,可以支持大规模网站的集中管理和优化。 普…...
百度千帆平台对接DeepSeek官方文档
目录 第一步:注册账号,开通千帆服务 第二步:创建应用,获取调用秘钥 第三步:调用模型,开启AI对话 方式一:通过API直接调用 方式二:使用SDK快速调用 方式三:在千帆大模…...
DeepSeek帮助解决Oracle死锁问题
最近在生产上遇到一个死锁问题,Oracle 抛出了 ORA-000060 异常。 业务场景:程序按行读取一个上游系统送的文件数据(大概有几万行),读取到数据后,每 500 行分配给一个线程去批量更新数据库(使用…...
MySQL无法连接到本地localhost的解决办法2024.11.8
问题描述:我的MySQL可以远程连接服务器,但无法连接自己的localhost。 错误提示: 2003 - Cant connet to MySQL server on localhost(10061 "Unknown error")查找问题原因: 1. 检查环境变量是否正确:发现没…...
Nginx之rewrite重写功能
目录 一、rewrite概述 1、rewrite功能 2、跳转场景 二、标准配置指令 1、rewrite日志记录指令 2、未初始化变量告警日志记录指令 3、rewrite 指令 3.1 正则表达式 三、rewrite模块使用实例 1.基于域名的跳转 2.基于客户端 IP 访问跳转 3.?基于旧域名跳转到新域名后…...
Selenium WebDriver自动化测试(扩展篇)--Jenkins持续集成
文章目录 一、引言二、Jenkins简介三、安装部署Jenkins安装部署四、集成Git与Maven安装必要的插件配置Git配置Maven五、创建Job创建自由风格的项目配置源码管理配置构建触发器配置构建环境配置构建步骤配置Post-build Actions六、触发构建示例:GitHub Webhook触发构建七、封装…...
MyBatis拦截器终极指南:从原理到企业级实战
在本篇文章中,我们将深入了解如何编写一个 MyBatis 拦截器,并通过一个示例来展示如何在执行数据库操作(如插入或更新)时,自动填充某些字段(例如 createdBy 和 updatedBy)信息。本文将详细讲解拦…...
DeepSeek4j 已开源,支持思维链,自定义参数,Spring Boot Starter 轻松集成,快速入门!建议收藏
DeepSeek4j Spring Boot Starter 快速入门 简介 DeepSeek4j 是一个专为 Spring Boot 设计的 AI 能力集成启动器,可快速接入 DeepSeek 大模型服务。通过简洁的配置和易用的 API,开发者可轻松实现对话交互功能。 环境要求 JDK 8Spring Boot 2.7Maven/Gr…...
linux 板子的wifi模块连上路由器后,用udhcpc给板子wifi分配ip,udhcpc获取到ip,但没有写入wlan0网卡上
linux 板子的wifi模块连上路由器后,用udhcpc给板子wifi分配ip,udhcpc获取到ip,但没有写入wlan0网卡上 这里的问题是 /usr/share/udhcpc/default.script脚本有问题 用下面正确脚本,即可写进去 #!/bin/sh# udhcpc script for busybox # Copyr…...
【工业安全】-CVE-2022-35555- Tenda W6路由器 命令注入漏洞
文章目录 1.漏洞描述 2.环境搭建 3.漏洞复现 4.漏洞分析 4.1:代码分析 4.2:流量分析 5.poc代码: 1.漏洞描述 漏洞编号:CVE-2022-35555 漏洞名称:Tenda W6 命令注入 威胁等级:高危 漏洞详情࿱…...
twisted实现MMORPG 游戏数据库操作封装设计与实现
在设计 MMORPG(大规模多人在线角色扮演游戏)时,数据库系统是游戏架构中至关重要的一部分。数据库不仅承担了游戏中各种数据(如玩家数据、物品数据、游戏世界状态等)的存储和管理任务,还必须高效地支持并发访…...
【MySQL】基础篇
1. MySQL中的NULL值是怎么存放的? MySQL的compact行格式中会用【NULL值列表】来标记值为NULL的列,NULL值不会存储在行格式中的真实数据部分。 NULL值列表会占用1字节空间,当表中所有字段都被定义成NOT NULL,行格式中就不会有NULL值…...
【自学笔记】机器学习基础知识点总览-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 机器学习重点知识点总览一、机器学习基础概念二、机器学习理论基础三、机器学习算法1. 监督学习2. 无监督学习3. 强化学习 四、机器学习处理流程五、机器学习常见问…...
记录阿里云CDN配置
网站接入CDN全流程,共4步!-阿里云开发者社区 1、开通阿里云CDN服务 2、添加加速域名 3、验证域名归属权 4、域名添加CDN生成的CNAME解析 按照官网描述增加。细节点: 1. 域名和泛域名区别 2.开启https,要用nginx的证书,和项…...
同为科技智能PDU助力Deepseek人工智能和数据交互的快速发展
1 2025开年,人工智能领域迎来了一场前所未有的变革。Deepseek成为代表“东方力量”的开年王炸,不仅在国内掀起了技术热潮,并且在全球范围内引起了高度关注。Deepseek以颠覆性技术突破和现象级应用场景席卷全球,这不仅重塑了产业格…...
聚铭网络入围2025年度江苏省政府采购信息安全设备协议供货名单
近日,2025年度江苏省党政机关、事业单位及团体组织信息安全设备框架协议采购项目入围结果公布。聚铭网络凭借自身专业实力和技术优势脱颖而出,成功入围22个分包。 此次采购项目是江苏省政府采购领域级别最高、覆盖面最广的项目之一。从资格评选到后期材料…...
【Linux】--- 基础开发工具之yum/apt、vim、gcc/g++的使用
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: Linux网络编程 本篇博客我们来认识一下Linux中的一些基础开发工具 --- yum,vim,gcc/g。 🏠 yum 🎸 什么是yum 当用户想下载软…...
leetcode 297. 二叉树的序列化与反序列化
题目如下 我们常常说单独先序遍历不能完整的表示一棵树是有前提条件的。 为什么?先序遍历是按 根节点 左子树 右子树的方向遍历树且遇到空子树直接返回,这样会造成我们并不知道某个节点的左右子树存在与否,故我们无法确定树的形状。但是如果…...
OpenAI 放王炸,将发布整合多项技术的 GPT-5,并免费无限使用,该模型有哪些技术亮点
对于 ChatGPT 的免费用户,将可以无限制地访问 GPT-5,但仅限于标准的智能级别。该级别会设定滥用限制,以防止不当使用(意思就是你得付费嘛)。 OpenAI CEO Sam Altman 今天在 X 上透露了 GPT-4.5 和 GPT-5 的最新发展计划。 OpenAI 将发布代…...
Ubuntu22.04 使用useradd 创建用户时,没有创建家目录时,如何手动创建家目录
测试案例: 使用useradd不加参数创建test目录 如下可以看出使用 useradd 创建用户的时候默认不会创建家目录 rootlocal:~# useradd test rootlocal:~# id test uid1001(test) gid1001(test) groups1001(test) rootlocal:~# cat /etc/passwd | grep test test:x:1001:…...
浅聊Docker使用、部署
在Java面试中,当被问到关于Docker中间件的使用、部署及在实际项目中的考虑时,可以按照以下结构和内容来详细回答: 一、Docker中间件的使用 1. Docker是什么? Docker是一个开源平台,允许开发者将应用程序及其依赖项打…...
Java面试第一山!《集合》!
一、引言 在 Java 编程的世界里,数据的存储和处理是非常重要的环节。Java 集合框架就像是一个功能强大的工具箱,为我们提供了各种各样的数据结构来高效地存储和操作数据。今天,跟随小编一起来深入了解 Java 集合框架,这不仅有助于…...
力扣-二叉树-257 二叉树的所有路径
思路 除去根节点,每一层添加->val,然后使用前序遍历的顺序 代码 class Solution { public:vector<string> res;void getTreePaths(string s, TreeNode* root){s "->";s to_string(root->val);if(root->left nullptr &…...
异构计算架构助力智能座舱实现高效低耗体验
摘要: 随着智能汽车的飞速发展,智能座舱作为人车交互的核心区域,对算力、功耗及延迟等性能指标提出了严苛要求。异构计算架构凭借在硬件、软件与系统层面的深度优化,能显著提升智能座舱的算力利用率,降低功耗与延迟,为用户打造高效、低能耗的智能座舱体验。本文深入剖析…...
【vscode】VScode Remote SSH配置
VScode使用remote ssh 到服务器上的Docker容器中 1. 配置远程服务器docker容器的端口映射,例如将服务器的2222端口映射到container的22端口(默认) 1.1 在容器系统的sshd_config文件中配置参数 #配置文件 vim /etc/ssh/sshd_config #打开端口号 Port 221.2 建立容…...
急停信号的含义
前言: 大家好,我是上位机马工,硕士毕业4年年入40万,目前在一家自动化公司担任软件经理,从事C#上位机软件开发8年以上!我们在开发C#的运动控制程序的时候,一个必要的步骤就是确认设备按钮的急停…...
【Azure 架构师学习笔记】- Azure Databricks (11) -- UC搭建
本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (10) – UC 使用 前言 由于ADB 的更新速度很快,在几个月之后重新搭建ADB 时发现UC 已经更新了很多,为了后续做ADB 的功…...
MYSQL批量UPDATE的两种方式
工作中遇到批量更新的场景其实是比较常见的。 但是该如何正确的进行批量UPDATE,很多时候往往有点头大。 这里列2种可用的方式,供选择(请选择方式一,手动狗头。)。 如果使用了MyBatis增强组件MyBatisPlus 如果使用了MyBatisPlus,…...
百度宣布:免费!
2月13日,百度大模型文心一言在官网宣布,随着文心大模型的迭代升级和成本不断下降,文心一言将于4月1日起全面免费,所有PC端和APP端用户均可体验文心系列最新模型。 同时,文心一言将上线深度搜索功能,具备更…...
计算机毕业设计SpringBoot+Vue.js医院住院管理系统(源码+lw文档+PPT+讲解视频)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Anaconda +Jupyter Notebook安装(2025最新版)
Anaconda安装(2025最新版) Anaconda简介安装1:下载anaconda安装包2: 安装anaconda3:配置环境变量4:检查是否安装成功5:更改镜像源6:更新包7:检查 Jupyter Notebook一.Jup…...
人工智能任务21-飞蛾火焰优化算法(MFO)在深度学习中的应用
大家好,我是微学AI,今天给大家介绍一下人工智能任务21-飞蛾火焰优化算法(MFO)在深度学习中的应用。飞蛾火焰优化算法(Moth-Flame Optimization, MFO)是一种受自然界中飞蛾向光源趋近行为启发的新型群体智能优化算法。在自然界中&a…...
渗透测试工具:SQLmap安装教程及使用
在渗透测试的世界里,SQL注入攻击无疑是最常见且最具威胁的安全漏洞之一。幸运的是,SQLmap 这个强大的自动化工具,能够帮助我们快速识别和利用这些漏洞。如果你也想了解如何用 SQLmap 进行渗透测试,那么这篇文章就是为你准备的&…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十四节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(CommunicationControl_0x28服务) 作者:车端域控测试工程师 更新日期:2025年02月14日 关键词:UDS协议、0x28服务、通信控制、ISO 14229-1:2023、ECU测试 一、服务功能概述…...
WEB安全--SQL注入--INTO OUTFILE
一、INTO OUTFILE 函数语法: SELECT column1, column2, INTO OUTFILE file_path FROM your_table WHERE your_conditions; 使用此方式在SQL注入的过程中可以: 1、上传shell得到数据库的后端的操作权限 2、爆出数据库的信息 二、使用该函数的条件&#…...
【C语言 】C语言 桌游开发数字竞拍(源码)【独一无二】
👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 【C语言 】C语言 桌游开发数字竞拍(源码…...
开源赋能,智造未来:Odoo+工业物联网,解锁智能工厂新范式——以真实案例解读制造业数字化转型的降本增效密码
工业物联网的机遇与挑战:为什么企业需要Odoo? 《中国智能制造发展研究报告2023》指出,85%的制造企业已启动数字化转型,但超60%面临“数据孤岛、系统割裂、成本高企”的痛点[1]。传统ERP系统难以实时对接产线设备,而定…...
在分布式场景下可以使用synchronized加锁么?
首先说结论,在分布式系统中,单纯使用 Java 中的 synchronized 关键字是无法满足需求的,下面从 synchronized 的作用原理、在分布式场景下的局限性以及替代方案等方面详细分析。 一、synchronized 的作用原理 在 Java 中,synchron…...
DeepSeek从入门到精通:提示词设计的系统化指南
目录 引言:AIGC时代的核心竞争力 第一部分 基础篇:提示词的本质与核心结构 1.1 什么是提示词? 1.2 提示词的黄金三角结构 第二部分 类型篇:提示词的六大范式 2.1 提示语的本质特征 2.2 提示语的类型 2.2.1 指令型提示词 …...
C# 运算符
总目录 前言 在C#中,运算符是用于执行特定操作的符号。它们可以用于处理变量、常量或其他表达式。C# 提供了丰富的运算符集合,用于执行各种操作,如算术运算、逻辑判断、位操作等。了解这些运算符及其使用方式对于编写高效且功能强大的C#程序…...
duckdb导出Excel和导出CSV速度测试
运行duckdb数据库 D:>duckdb v1.2.0 5f5512b827 Enter “.help” for usage hints. Connected to a transient in-memory database. Use “.open FILENAME” to reopen on a persistent database. 生成模拟数据,10个列,100万行数据; --…...