NestJS——多环境配置方案(dotenv、config、@nestjs/config、joi配置校验)
个人简介
👀个人主页: 前端杂货铺
🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🎨100个小功能 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒Three.js🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧
文章目录
- 多环境配置方案
- dotenv
- config
- @nestjs/config
- 增加环境配置 .env 文件
- 增加环境配置 .yml 文件
- Joi 校验配置文件
- 总结
多环境配置方案
测试项目的参考目录:
安装相关依赖:
npm i dotenv config js-yaml
创建 index.js 文件,用于后续测试。
dotenv
Dotenv
Dotenv 是一个零依赖模块,可将环境变量从 .env 文件加载到 process.env 中。
创建 .env 文件:
TOKEN_SECRET=your-long-random-secretUSERNAME=zahuopu
PASSWORD="mypassword-long-random-secret"DATABASE_USERNAME=USERNAME
DATABASE_PASSWORD=PASSWORD
在 index.js 文件中添加如下代码:
require("dotenv").config();
console.log(process.env);
终端执行 node index.js
即可得到如下输出:
config
Node-config
Node-config 为我们的应用程序部署组织分层配置。它允许我们定义一组默认参数,并将其扩展到不同的部署环境(开发、质量保证、测试、生产等)。
创建 default.json 文件,默认文件。
{"token_secret": "long-secret","db": {"host": "localhost","port": 27017,"username": "zahuopu","password": "example"}
}
创建 production.json 文件
{"db": {"host": "zahuopu.com","port": 9000}
}
创建 development.json 文件
{"db": {"host": "qiandaun.com","port": 3000}
}
在 index.js 文件中添加如下代码
const config = require("config");
const dbConfig = config.get("db");console.log(dbConfig);
安装 cross-env
第三方库(cross-env是一个运行在 Node.js 环境中的工具包,它的主要作用是让我们可以在命令行中设置环境变量,而不必担心跨操作系统的兼容问题)
npm i cross env
修改 pageage.json
文件的如下内容
"scripts": {"dev": "cross-env NODE_ENV=development node index.js","prod": "cross-env NODE_ENV=production node index.js"},
此外,还支持 yaml
格式,即可以进行下面的写法:
使用 development.yaml 文件替换 .json
文件
db:host: "qianduan.com"port: 3000,
使用 production.yaml 文件替换 .json
文件
db:host: "zahuopu.com"port: 9000,
其效果是一样的。
@nestjs/config
@nestjs/config 是 NestJS 官方提供的一个模块,用于帮助开发者更轻松地管理和加载应用程序的配置。它基于流行的 Node.js 库 dotenv,但提供了更强大、更 NestJS 风格的功能。
GitHub 提交记录
打开我们之前创建的 nestjs-demo
项目,安装 config
pnpm i --save @nestjs/config
在 app.module.ts
文件中,添加 Config 配置
import { Module } from "@nestjs/common";
import { UserModule } from "./user/user.module";
// 新加的内容
import { ConfigModule } from "@nestjs/config";@Module({imports: [// 新加的内容ConfigModule.forRoot({isGlobal: true, // 将配置模块声明为全局模块,所有其他模块均可直接注入 ConfigService}),UserModule,],controllers: [],providers: [],
})
export class AppModule {}
在 src
目录下创建 enum
文件夹,并在新创建的文件夹中创建 config.const.ts
文件,在此文件中我们定义一些枚举值,用于配置
export enum ConfigEnum {DB = "DB",DB_HOST = "DB_HOST",
}
在 user.controller.ts
中进行测试
import { Controller, Get, Post } from "@nestjs/common";
import { UserService } from "./user.service";
// 新增的引入
import { ConfigService } from "@nestjs/config";
import { ConfigEnum } from "src/enum/config.const";@Controller("user")
export class UserController {constructor(private userService: UserService,private configService: ConfigService) {}@Get()getUsers(): any {// 新增的测试内容 ---------------------------------const db = this.configService.get(ConfigEnum.DB);const host = this.configService.get(ConfigEnum.DB_HOST);console.log("db", db);console.log("host", host);// ----------------------------------------------return this.userService.getUsers();}
}
启动项目后,访问 http://localhost:3000/api/user
网址,即可在终端得到如下输出。
增加环境配置 .env 文件
GitHub提交记录
安装 cross-env、dotenv。
cross-env
作用:
跨平台环境变量设置
cross-env 是一个解决不同操作系统(Windows/macOS/Linux)环境变量设置语法差异的工具。它允许你在 package.json 的脚本中统一设置环境变量,无需关心底层操作系统的差异。
dotenv
作用:
从 .env 文件加载环境变量
dotenv 是一个零依赖的库,用于将 .env 文件中的键值对注入到 Node.js 的 process.env 中,使得应用可以方便地读取配置。
为什么需要它?
分离敏感配置:避免将数据库密码、API 密钥等硬编码在代码中。
pnpm i -D cross-env
pnpm i dotenv
修改 package.json
文件
"start:dev": "cross-env NODE_ENV=development nest start --watch",
"start:prod": "cross-env NODE_ENV=production node dist/main",
创建 .env.development 文件,进行开发环境下 DB 及 DB_HOST 的配置。
DB=mysql-dev
DB_HOST=127.0.0.1
创建 .env.production 文件,进行生产环境下 DB 及 DB_HOST 的配置。
DB=mysql-prod
DB_HOST=127.0.0.1
修改 .env 文件内容
# 公共配置文件
DB=mysql
DB_HOST=127.0.0.1# 新增内容
DB_URL=https://zahuopu.blog.csdn.net/
修改 app.module.ts
文件
import { Module } from "@nestjs/common";
import { UserModule } from "./user/user.module";
import { ConfigModule } from "@nestjs/config";
// 导入 dotenv 库,用于解析 .env 文件
import * as dotenv from "dotenv";/*** 动态生成环境变量文件路径:* - 如果系统环境变量 `NODE_ENV` 存在(如 production、development、test),则加载对应的 `.env.[NODE_ENV]` 文件* - 默认使用 `.env.development` 文件*/
const envFilePath = `.env.${process.env.NODE_ENV || "development"}`;@Module({imports: [ConfigModule.forRoot({isGlobal: true, // 将配置模块声明为全局模块,所有其他模块均可直接注入 ConfigServiceenvFilePath, // 指定环境变量文件路径(根据 NODE_ENV 动态加载)// 自定义配置加载器:显式加载默认的 .env 文件(作为兜底配置)// 注:如果同时存在 envFilePath 和此配置,envFilePath 的变量会覆盖 .env 的重复键load: [() => dotenv.config({ path: ".env" })],}),UserModule,],controllers: [],providers: [],
})
export class AppModule {}
在 user.controller.ts
文件中做验证
import { Controller, Get, Post } from "@nestjs/common";
import { UserService } from "./user.service";
import { ConfigService } from "@nestjs/config";
import { ConfigEnum } from "src/enum/config.const";@Controller("user")
export class UserController {constructor(private userService: UserService,private configService: ConfigService) {}@Get()getUsers(): any {const db = this.configService.get(ConfigEnum.DB);const host = this.configService.get(ConfigEnum.DB_HOST);console.log("db", db);console.log("host", host);// 新添加的内容-------------------------const url = this.configService.get("DB_URL");console.log("url", url);//------------------------------------return this.userService.getUsers();}}
}
增加环境配置 .yml 文件
GitHub 提交记录
安装 js-yaml、@types/js-yaml、lodash
js-yaml
作用:
YAML 解析与序列化
js-yaml 是一个 JavaScript 库,用于解析 YAML(一种人类友好的数据序列化格式)文件或字符串,并将其转换为 JavaScript 对象,同时也支持将 JavaScript 对象序列化为 YAML 格式。
典型使用场景:
读取配置文件(如 .yaml 或 .yml 文件)。
在前后端通信中处理 YAML 格式的数据(虽然 JSON 更常见,但某些场景如 Kubernetes 配置依赖 YAML)。
@types/js-yaml
作用:
TypeScript 类型定义
@types/js-yaml 是 js-yaml 的 TypeScript 类型声明文件(通过 DefinitelyTyped 维护),为 js-yaml 提供类型支持,使得在 TypeScript 项目中调用 js-yaml 时可以获得代码补全和类型检查。
为什么需要它?
如果你在 TypeScript 项目中使用 js-yaml,直接安装 js-yaml 会导致类型错误(因为它是纯 JavaScript 库)。
通过 @types/js-yaml,TypeScript 能识别 yaml.load()、yaml.dump() 等方法的参数和返回值类型。
lodash
lodash 是一个提供高效、模块化的工具函数库,用于简化常见的数据操作(如数组、对象、字符串处理等)。
pnpm i js-yaml
pnpm i -D @types/js-yaml
pnpm i lodash
创建 config
文件夹,在此文件夹中创建三个文件。
在 config.yml 文件中进行 公有配置
db:mysql1:host: 127.0.0.1name: test-nameport: 3306mysql2:host: 127.0.0.1name: test-name1port: 3306
在 config.development.yml 文件中进行 开发环境 配置
db:mysql1:name: mysql-devmysql2:name: mysql-dev1
在 config.production.yml 文件中进行 生产环境 配置
db:mysql1:name: mysql-prodmysql2:name: mysql-prod1
创建 configuration.ts 配置文件,添加如下代码
import { readFileSync } from "fs"; // 用于同步读取文件内容
import * as yaml from "js-yaml"; // 用于解析 YAML 文件
import { join } from "path"; // 用于处理文件路径
import * as _ from "lodash"; // 用于对象的深度合并等操作// 定义通用配置文件的文件名
const YAML_COMMON_CONFIG_FILENAME = "config.yml";// 构建通用配置文件的路径
const filePath = join(__dirname, "../config", YAML_COMMON_CONFIG_FILENAME);// 根据当前环境(NODE_ENV)构建环境配置文件的路径,默认为 "development"
const envPath = join(__dirname,"../config",`config.${process.env.NODE_ENV || "development"}.yml`
);// 加载通用配置文件内容
const commonConfig = yaml.load(readFileSync(filePath, "utf8"));// 加载环境配置文件内容
const envConfig = yaml.load(readFileSync(envPath, "utf8"));// 导出一个函数,返回合并后的配置对象
export default () => {// 使用 lodash 的 merge 方法,将通用配置和环境配置深度合并return _.merge(commonConfig, envConfig);
};
修改 app.module.ts
,更改配置
import { Module } from "@nestjs/common";
import { UserModule } from "./user/user.module";
import { ConfigModule } from "@nestjs/config";
// 新增内容--------------------------------
import Configuration from "./configuration";
// ---------------------------------------@Module({imports: [ConfigModule.forRoot({isGlobal: true, // 将配置模块声明为全局模块,所有其他模块均可直接注入 ConfigService// 修改的内容-----------------load: [Configuration],// -------------------------}),UserModule,],controllers: [],providers: [],
})
export class AppModule {}
在 user.controller.ts
文件中做测试
import { Controller, Get, Post } from "@nestjs/common";
import { UserService } from "./user.service";
import { ConfigService } from "@nestjs/config";@Controller("user")
export class UserController {constructor(private userService: UserService,private configService: ConfigService) {}@Get()getUsers(): any {// 新增内容--------------------------------const data = this.configService.get("db");console.log("data", data);// ---------------------------------------return this.userService.getUsers();}
}
Joi 校验配置文件
Joi模式验证器官网
我们可以使用 Joi 来校验我们的配置文件
安装 joi
pnpm install --save joi
GitHub 提交记录
我们基于 dotenv 的配置方式在 app.module.ts
文件中使用它
import { Module } from "@nestjs/common";
import { UserModule } from "./user/user.module";
import { ConfigModule } from "@nestjs/config";
import * as dotenv from "dotenv"; // 导入 dotenv 库,用于解析 .env 文件
import * as Joi from "joi"; // 用于验证环境变量的库/*** 动态生成环境变量文件路径:* - 如果系统环境变量 `NODE_ENV` 存在(如 production、development、test),则加载对应的 `.env.[NODE_ENV]` 文件* - 默认使用 `.env.development` 文件*/
const envFilePath = `.env.${process.env.NODE_ENV || "development"}`;@Module({imports: [ConfigModule.forRoot({isGlobal: true, // 将配置模块声明为全局模块,所有其他模块均可直接注入 ConfigServiceenvFilePath, // 指定环境变量文件路径(根据 NODE_ENV 动态加载)/*** 自定义配置加载器:* - 显式加载默认的 `.env` 文件,作为兜底配置* - 如果 `envFilePath` 和 `.env` 文件中存在相同的变量,`envFilePath` 的变量会覆盖 `.env` 中的值*/load: [() => dotenv.config({ path: ".env" })],/*** 使用 Joi 验证环境变量:* - 定义环境变量的结构和默认值* - 确保环境变量的值符合预期(如类型、范围等)*/validationSchema: Joi.object({NODE_ENV: Joi.string().valid("development", "production", "test") // 限制 NODE_ENV 的合法值.default("development"), // 默认值为 "development"DB_PORT: Joi.number().default(3306), // 数据库端口,默认值为 3306DB_URL: Joi.string().domain(), // 数据库 URL,必须是合法的域名DB_HOST: Joi.string().ip(), // 数据库主机地址,必须是合法的 IP 地址}),}),UserModule, // 导入用户模块],controllers: [], // 控制器(当前为空)providers: [], // 服务提供者(当前为空)
})
export class AppModule {}
下面我们进行验证一下,如果我们在 .env.development
文件中把 DB_PORT=xxx
DB=mysql-dev
DB_HOST=127.0.0.1
DB_PORT=xxxDB_URL=www.baidu.com
那么启动项目时会发现:
总结
本篇文章,我们学习了多环境配置方案,包括:dotenv、config及在 nestjs 项目中的使用等。此外,我们还认识了配置校验工具joi,保障配置符合规范等。
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- DeepSeek
- NestJS 从入门到实战
相关文章:
NestJS——多环境配置方案(dotenv、config、@nestjs/config、joi配置校验)
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…...
RAGFlow在Docker中运行Ollama直接运行于主机的基础URL的地址
基础Url http://host.docker.internal:11434...
python 库 下载 ,整合在一个小程序 UIUIUI
上图 import os import time import threading import requests import subprocess import importlib import tkinter as tk from tkinter import ttk, messagebox, scrolledtext from concurrent.futures import ThreadPoolExecutor, as_completed from urllib.parse import…...
【MySQL】数据库约束
个人主页:♡喜欢做梦 欢迎 👍点赞 ➕关注 ❤️收藏 💬评论 目录 ✨一、数据库的约束 🌟二、数据库约束的分类 🌍 1.非空约束(NOT NULL) 1.定义 2.格式 3.示例: 列的信息可…...
Firewalld防火墙
目录 Firewald 防火墙概述 Firewalld 简介 firewalld 与 iptables service的区别 Firewalld 网络区域 Firewalld 防火墙图形配置方法 服务选项 端口号 协议选项 源端口选项 伪装选项 端口转发 ICMP过滤器 防火墙的配置运行状态 运行时和永久有什么区别 Firewalld 防火墙 firewa…...
使用 TensorFlow 和 Keras 构建 U-Net
U-Net是图像分割领域中最为著名的架构之一。U-Net 因其形状而得名,它是一种全卷积架构,首先将图像收缩,然后将其扩展为输出结果。虽然这种收缩路径构建了一个学习特征的层次结构,但跳过连接有助于在扩展路径中将这些特征转换回相关…...
【网络篇】TCP vs UDP底层区别+网络编程概念
大家好呀 我是浪前 今天讲解的是网络篇的第三章:网络编程概念和TCP&UDP的区别 网络编程概念TCP和UDP的区别 跨主机通信:网络编程插座:网络编程的本质: 网络编程的重要概念:客户端和服务器: 客户端和服务器的交互模…...
如何保存服务器mysql数据库的数据到本地文件
打开mysql命令行如图1 图1 mysql命令行 修改文件保存路径。 在mysql安装目录下,找到my.ini文件,找到secure-file-priv变量配置的地方,修改对应的值,然后重启mysql,此时把文件放到指定路径,再执行导入导出…...
Flutter学习 滚动组件(2):ListView进阶使用
目录 前言:一、实现复杂的ListView列表:1.1 Item布局封装1.2 ListView的使用1.3 增加分割线 二、实现ListView下拉刷新:三、实现上拉加载更多:四、实现下拉刷新、上拉加载更多:五、ListView滚动方向和控制:…...
linux oracle 19c 静默安装
oracle数据库有个比较很抓瞎的事情,不同的版本搭建的大致流程是一样的,但是在实操细节上会有不同,比如操作的脚本位置和配置项等等,这些会变,所以需要时常积累不同版本的文档 这里有一点要说明,之所以使用…...
中间件--ClickHouse-11--部署示例(Linux宿主机部署,Docker容器部署)
一、Linux宿主机部署 1、环境准备 操作系统:推荐使用 CentOS 7/8 或 Ubuntu 18.04/20.04。硬件要求: 至少 2 核 CPU 和 4GB 内存。足够的磁盘空间(根据数据量评估)。CPU需支持SSE4.2指令集(可通过以下命令检查&#…...
AI调试工具有哪些?
一、深度学习框架专用调试工具 TensorBoard • 功能:实时监控训练指标(损失值、准确率)、可视化神经网络结构、分析参数分布和梯度信息 • 适用框架:TensorFlow、PyTorch(通过插件) • 特点:支持…...
Warcraft Logs [Classic] [WCL] BOSS ID query
Warcraft Logs [Classic] [WCL] BOSS ID query 所有副本BOSSID查询 https://wowpedia.fandom.com/wiki/DungeonEncounterID#Retail IDNameMapInstanceIDPatch227High Interrogator GerstahnBlackrock Depths230228Lord RoccorBlackrock Depths230229Houndmaster GrebmarBlackro…...
MySQL——事务
一、什么是事务? 事务(Transaction) 是数据库操作的最小逻辑单元,它由一组不可分割的SQL操作组成。事务的核心目标是确保多个操作要么全部成功,要么全部失败,从而维护数据的完整性。例如,银行转…...
spring Ai---向量知识库(一)
在一些垂直领域以及公司内部信息相关或者实时性相关的大模型应用,就无法直接使用chatGPT。 这个时候,向量知识库就进入了。 通过坐标向量最接近的即为匹配相关答案。 向量模型定义:将文档向量化,保证内容越相似的文本,…...
MACOS 上的 快捷指令怎么用,有哪些分享资源可以用
一、快捷指令的基本概念与历史 快捷指令(Shortcuts)是苹果生态中的自动化工具,最初以第三方应用Workflow(2014年推出)的形式出现,2017年被苹果收购后更名为Shortcuts,并深度集成到iOS、iPadOS和macOS系统中。从macOS Mojave(10.14)开始,快捷指令正式登陆Mac平台,并…...
最长子序列长度(LIS)--个数遍历的二分+贪心优化
B3637 最长上升子序列 - 洛谷 #include<bits/stdc.h> #include<string> using namespace std; #define N 100011 typedef long long ll; typedef pair<int,int> pii; int n; int g[N]; int dp[N]; int ma0; int main() { cin>>n; memset(g,0x3f,sizeo…...
RenderStage::runCameraSetUp
文章目录 RTTosg::Camera::_bufferAttachmentMapRenderStage::BufferComponent和RenderStage::_bufferAttachmentMapCamera::attach(BufferComponent buffer, GLenum internalFormat)Camera::attach(BufferComponent buffer, osg::Texture* texture.....Camera::attach(BufferC…...
突破速率瓶颈:毫米波技术如何推动 5G 网络迈向极限?
突破速率瓶颈:毫米波技术如何推动 5G 网络迈向极限? 引言 5G 网络的普及,已经让我们告别了“加载中”时代,实现了更快的数据传输、更低的延迟和更高的设备连接密度。而在 5G 技术的核心中,毫米波(mmWave&…...
前端面试真题集合(一)
一、Vue的响应式原理 Vue的响应式系统通过数据劫持和依赖追踪实现,核心流程如下: 数据劫持 • Vue 2.x:使用Object.defineProperty递归遍历数据对象,将属性转换为getter/setter,拦截属性的读取和修改操作。 • Vue 3.x:改用Proxy代理对象,支持动态属性添加和数组变化监听…...
聊聊Spring AI Alibaba的ElasticsearchDocumentReader
序 本文主要研究一下Spring AI Alibaba的ElasticsearchDocumentReader ElasticsearchDocumentReader community/document-readers/spring-ai-alibaba-starter-document-reader-elasticsearch/src/main/java/com/alibaba/cloud/ai/document/reader/es/ElasticsearchDocumentR…...
【网络技术_域名解析DNS】三、DNS 中间件实践应用与优化策略
一、DNS 中间件在典型行业的实践应用 1.1 金融行业:保障交易安全与服务稳定 金融行业对网络服务的安全性和稳定性要求极高,DNS 中间件在此领域发挥着不可替代的作用。以某银行线上支付系统为例,在 CentOS 7 环境下部署 DNS 中间件时&…...
Node.js 异步I/O与事件循环深度优化
Node.js 的核心魅力在于其异步、非阻塞I/O模型,这使得它在处理高并发、I/O密集型应用(如Web服务器、API网关、实时通信服务)时表现出色。然而,这种强大的能力并非凭空而来,它深深植根于其独特的**事件循环(…...
npm 常用操作和配置
一、npm 核心操作 1. 初始化项目 npm init # 交互式创建 package.json npm init -y # 跳过提问,直接生成默认 package.json2. 安装依赖 npm install <package> # 安装包到本地 node_modules(生产依赖) npm in…...
嵌入式芯片中的 低功耗模式 内容细讲
电源域与运行级别概述 电源域(Power Domain) 核心域(Core Domain):包括 CPU 核心和关键架构模块(如 NVIC、CPU 内核寄存器)。 外设域(Peripheral Domain):…...
React-请勿在循环或者条件语句中使用hooks
这是React Hooks的首要规则,这是因为React Hooks 是以单向循环链表的形式存储,即是有序的。循环是为了从最后一个节点移到一个节点的时候,只需通过next一步就可以拿到第一个节点,而不需要一层层回溯。React Hooks的执行࿰…...
React-memo (useMemo, useCallback)
在react中,当我们setState之后,若值发生变化,则会重新render当前组件以及其子组件 (默认情况下),在必要的时候,我可使用memo (class组件则对应shouldComponentUpdate、PureComponent)进行优化,来减少无效渲…...
点云数据处理开源C++方案
一、主流开源库对比 库名称特点适用场景开源协议活跃度PCL功能最全,算法丰富科研、工业级应用BSD★★★★★Open3D现代API,支持Python绑定快速开发、深度学习MIT★★★★☆CGAL计算几何算法强大网格处理、高级几何运算GPL/LGPL★★★☆☆PDAL专注于点云…...
android测试依赖
Android 项目中常用的测试相关库 1. androidx.arch.core:core-testing:2.2.0 作用: 提供与 Android Architecture Components(如 LiveData、ViewModel)相关的测试工具。主要用于测试基于 LiveData 的异步操作。 常见功能: 即时…...
Gradle与Idea整合
文章目录 1. Groovy 简介2. Groovy 安装[非必须]3. 在idea中创建java工程 1. Groovy 简介 在某种程度上,Groovy可以被视为Java的一种脚本化改良版,Groovy也是运行在JVM上,它可以很好地与Java代码及其相关库进行交互操作。它是一种成熟的面向对象编程语言…...
【数据结构】励志大厂版·初阶(复习+刷题)单链表
前引:此篇文章作为小编复习的记录,将快速回忆单链表的知识点,讲解单链表增删查找的实现,每个细节之处要注意的地方,解释为何这样设计。文章末尾包含了单链表算法题, 同样解释详细,借助题目再次巩…...
前端面试宝典---参数解构+默认值的面试题
重点要义 对于函数参数要解构,且参数有默认值的,一律用Object.assign的思路去合并参。 看不懂这句话没关系,看下面的例子\ 例子1 function fn ({ x 1, y } { y: 10 }) {console.log(x, y) } fn() // 1 10没有传递实参,你就把{ …...
【开发心得】筑梦上海:项目风云录(16)
目录 代码反面案例 李青与诺基亚的兴衰 并行项目下的利益纠葛与团队协作 未完待续。。。 今天分享的是一个反面案例,也算是一个避坑指南了。 代码反面案例 今天分享的代码是一个反面案例,当时由于项目人员变动频繁,经常是新人看不太懂旧…...
Neovim插件深度解析:mcphub.nvim如何用MCP协议重构开发体验
在AI与工具链深度融合的今天,Neovim 作为现代开发者的生产力工具,正通过插件生态不断突破边界。mcphub.nvim 作为一款基于 MCP(Model Context Protocol) 协议的插件,重新定义了Neovim与智能工具的交互方式。它不仅简化了MCP服务器的集成与管理,更通过直观的UI和生态整合,…...
Qt UDP 通信的详细实现步骤和示例代码
在 Qt 中实现 UDP 通信主要使用 QUdpSocket 类。以下是 UDP 通信的详细实现步骤和示例代码: 一、UDP 通信基础 无连接协议:不需要建立持久连接数据报模式:以独立数据包(datagram)形式发送适用场景:实时性要…...
(二)Trae 配置C++ 编译
Trae配置c编译 零 CMake 编译C0.1 下载安装0.2 安装设置0.3 三种编译方式(见 下文 一 二 三)0.4 调试 (见 下文四) 一 使用MSVC方式编译1.1 安装编译环境1.2安装插件1.3 设置文件 二 使用GCC方式2.1 安装编译环境2.1.1下载:[MinGw](https://gcc-mcf.lhmouse.com/)2.1.2安装:(以…...
动态规划算法的欢乐密码(一):斐波那契数模型
专栏:算法的魔法世界 个人主页:手握风云 目录 一、动态规划 二、例题讲解 2.1. 第 N 个泰波那契数 2.2. 三步问题 2.3. 使用最小花费爬楼梯 2.4. 解码方法 一、动态规划 动态规划是一种将复杂问题分解为更小的子问题,并利用子问题的解来…...
【FreeRTOS进阶】优先级翻转现象详解及解决方案
【FreeRTOS进阶】优先级翻转现象详解及解决方案 接下来我们聊聊优先级翻转这个经典问题。这个问题在实时系统中经常出现,尤其是在任务较多的场景下,而且问题定位起来比较麻烦。 什么是优先级翻转? 优先级翻转的核心定义很简单:…...
解决 IntelliJ IDEA 项目启动时端口冲突问题
1.问题 Description: The Tomcat connector configured to listen on port 8082 failed to start. The port may already be in use or the connector may be misconfigured. Action: Verify the connectors configuration, identify and stop any process thats listening…...
笔试专题(十一)
文章目录 添加字符(暴力枚举)题解代码 城市群数量(dfs)题解代码 判断是不是平衡二叉树(递归)题解代码 最大子矩阵(二维前缀和)题解代码 小葱的01串 (固定区间大小的滑动窗…...
C++11新增语法:列表初始化
前言: 接下来我们将要讲解,相较于c98,c11中新增的语法以及如何使用~。我们首先来讲解:列表初始化。 下文预告:右值引用和移动语义 C98中传统的{} 在c98中的{},仅能初始化数组和结构体 #include<iostrea…...
Linux:基础IO---动静态库
文章目录 1. 动静态库前置知识1.1 动静态库知识回顾1.2 什么是动静态库 2. 动静态库2.1 站在库的制作者的角度2.2 站在库的使用者的角度2.3 动态库是怎么被加载的(原理) 序:上一篇文章我们从认识到理解,从理解到实现场景ÿ…...
从裸仓库到GitLab全解析
Git服务器搭建与使用指南:从裸仓库到GitLab全解析 前言 在团队协作开发中,版本控制系统是必不可少的工具。虽然GitHub提供了优秀的代码托管服务,但企业级项目往往需要更安全的私有化部署方案。本文将手把手教你两种主流的Git服务器搭建方式…...
OzGIS:地理信息分析与处理软件
大家好,今天为大家介绍的软件是OzGIS:一款地理信息分析与处理软件。下面,我们将从软件的主要功能、支持的系统、软件官网等方面对其进行简单的介绍。 OzGIS官网网址为:https://ozgis.sourceforge.io/。 OzGIS是一款开源软件&#…...
PHP异常处理__Throwable
在 PHP 里,Throwable 是一个极为关键的接口,自 PHP 7 起被引入。它为错误和异常处理构建了一个统一的框架。下面会详细介绍 Throwable 的相关内容。 1. 基本概念 Throwable 是 Exception 和 Error 的父接口。在 PHP 7 之前,异常(…...
PHP异常处理__Exception类
以下是对 PHP 中 Exception 类的详细解释: 一、Exception 类概述 Exception 是 PHP 中所有异常类的基类。它提供了一个通用的异常处理机制,用于处理程序执行过程中可能出现的错误情况。当程序中出现异常时,可以创建 Exception 的实例并将其…...
C++中动态多态类别浅析
非抽象类继承和虚函数 #include <iostream> using namespace std;class Base { public:virtual void func() { // 虚函数,支持动态绑定cout << "Base::func()" << endl;} };class Derived : public Base { public:void func() overrid…...
游戏引擎学习第234天:实现基数排序
回顾并为今天的内容设定背景 我们今天继续进行排序的相关,虽然基本已经完成了,但还是想收尾一下,让整个流程更完整。其实这次排序只是个借口,主要是想顺便聊一聊一些计算机科学的知识点,这些内容在我们项目中平时不会…...
系分架构论文《论高并发场景的架构设计和开发方法》
系统分析师论文范文系列 【摘要】 2022年8月,我司承接了某知名电商平台“秒杀系统架构优化”项目,我作为系统分析师主导了整体架构设计与技术选型工作。该平台在促销活动中面临瞬时流量超过50万QPS的挑战,原有架构存在数据库崩溃、服务响应延…...
最新得物小程序sign签名加密,请求参数解密,响应数据解密逆向分析
点击精选,出现https://app.dewu.com/api/v1/h5/index/fire/index 这个请求 直接搜索sign的话不容易定位 直接搜newAdvForH5就一个,进去再搜sign,打上断点 可以看到t.params就是没有sign的请求参数, 经过Object(a.default)该函数…...