本地开发环境搭建指南:从版本管理到依赖隔离的实践路径

刚接手一台新机器或者帮同事处理开发环境时,最怕的不是配置本身复杂,而是装到一半发现各种软件版本互相“打架”,或者环境变量配了一堆,重启终端又全失效。搭环境这件事,本质上是在梳理一套“工具链的协作关系”,每一步选什么、怎么配、为什么这么配,都比单纯敲命令更重要。这篇文章就围绕“本地开发环境搭建”这个场景,把我在实际操作中的思路、步骤和踩过的坑整理出来,给正要动手配环境的新手一份可以直接照着做的参考,也让有一定经验的朋友看看有没有能优化的细节。

1. 环境搭建的整体思路与方案选型逻辑

环境搭建听起来就是“装软件”,但真正做起来,核心其实是三件事:确定项目需要的运行时栈、规范围绕这套栈的工具链、以及让工具链之间能稳定配合。很多人一上来就急着下载安装包,装完发现包管理器冲突、版本不匹配、终端无法识别命令,再回头排查,往往比重新配置还耗时。

1.1 先搞清楚“这个环境服务谁”

不同场景对环境的诉求完全不同。给前端项目配环境,核心围绕 Node.js 运行时、包管理器的选择和 Node 版本切换;做 Python 数据分析或后端开发,核心在于 Python 解释器、虚拟环境和依赖隔离;如果是嵌入式或 C++ 项目,关心的是交叉编译工具链和 CMake 版本。

我在实际配置前,会先列一个最小清单:

  • 项目语言和运行时版本(比如 Node 16 还是 18,Python 3.10 还是 3.11)
  • 包管理器(npm、yarn、pnpm,还是 pip、poetry)
  • 是否依赖本地服务(数据库、消息队列、缓存)
  • 终端 shell 类型(bash、zsh、fish)以及是否做多版本切换

这步想清楚,后面就不会出现“装好了 Node 又要用 nvm 管版本结果发现冲突”的情况。

1.2 为什么强烈建议用版本管理工具而不是直接装官方安装包

直接去官网下载安装包,再配环境变量,这件事最大的问题在于难以切换版本。项目 A 要 Node 14,项目 B 要 Node 18,如果你只有一个全局版本,换项目就得卸载重装,非常痛苦。

版本管理工具的核心价值是“把多版本并存变成常态”。以我常配的前端环境为例,我倾向于用nvm(Node Version Manager)来管理 Node 版本;Python 环境则用pyenv搭配virtualenv或poetry。这些工具的原理并不复杂,本质上是在 PATH 层面做了一层“软链接切换”,但带来的体验提升是巨大的。

注意:在 Windows 上,nvm的体验不如 macOS 和 Linux 顺畅,比较常见的替代方案是nvm-windows,它需要先卸载现有 Node 再安装,否则会覆盖管理逻辑。具体原因在后面的实操章节我会仔细说。

这层思路确认后,环境搭建就从一个“不可逆”的过程变成了“可持续维护”的过程——这也是我认为在动手前最值得花时间的一点。

2. 核心工具选择与配置前的关键认知

选工具这件事没有绝对的对错,但有几条实操中总结出来的经验,能帮你少走很多弯路。这个部分我拆成两块:一是常用工具选型的对比分析,二是配置前必须理解的两类底层机制。

2.1 常用工具选型对比:不只是“哪个流行选哪个”

很多人喜欢直接跟风用最新的工具,但在环境搭建这个场景里,“稳定”和“团队统一”往往比“新”更重要。我整理过一个对比表,基本能覆盖日常 90% 的需求:

需求场景首选方案备选方案选型理由
Node 多版本管理nvm / nvm-windowsfnm、voltanvm 生态最成熟,社区资料多,排查问题容易
Python 多版本管理pyenvcondapyenv 轻量,专注 Python 版本切换
Python 虚拟环境venv / poetrypipenvvenv 是官方内置,poetry 更适合做依赖锁定升级
包管理器(前端)pnpmyarn、npmpnpm 节省磁盘空间,安装速度快
shell 环境统一zsh + oh-my-zshbashzsh 插件生态完善,但团队统一更重要

选型逻辑并不复杂:优先选社区多、文档全、坑少被人踩过的方案,而不是最新奇、最酷的方案。比如 pnpm 现在很流行,但如果团队里所有人都用 npm,那环境搭建的首要目标就是“对齐”,而不是“升级”。

2.2 必须理解的两个底层机制:PATH 与软链接

环境搭建中大量问题其实都出在“命令找不到”上,这背后就是 PATH 和软链接在起作用。

PATH 决定 shell 去哪找命令。终端敲node -v时,shell 是按 PATH 里记录的目录顺序逐个查找node可执行文件的。如果你把 Node 装到了/usr/local/bin,但 PATH 里只配了/usr/bin,那就永远找不到。

软链接(symlink)是版本切换的魔法。像nvm这类工具,实际上并不搬动真实文件,而是在~/.nvm/current这种固定路径上建立一个指向真实版本的软链接。切换版本时,工具只需要改这个链接的指向,然后保证current路径在 PATH 里就行。

理解了这两个机制,再遇到“为什么我配了环境变量还是不行”,你第一反应就不是“再改一遍配置”,而是先检查which node、echo $PATH,沿着链路排出问题——这个排查思路在工程实操中能省下大量时间。

提示:改完.zshrc或.bashrc后,一定记得执行source ~/.zshrc或者在终端里新开一个标签页。很多人改了配置没生效,就是因为 shell 还停留在旧的进程环境里。

3. 实操核心环节:一步步搭建完整本地环境

这部分是全文最“动手”的章节。我不绕弯子,直接以“前端 Node 环境 + Python 数据分析环境”同时配置为例,带你走完整个流程,每一步都包含具体命令、执行后的预期效果,以及中途容易犯的错。

3.1 先准备基础依赖与终端环境

大部分环境搭建流程里,终端是唯一的操作入口,所以先保证终端环境可用。

  • macOS 用户:推荐先安装 Homebrew,后面很多安装动作会依赖它。安装命令是/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)",装完后最好执行brew doctor验证一下没问题再继续。
  • Windows 用户:建议提前装好 Windows Terminal,并且在安装 Git 时勾选“Use Git Bash as the default shell”,这能让你的操作体验接近 Unix 环境,避免在 cmd 和 PowerShell 之间反复切换。
  • Linux 用户:确认curl和wget可用,一般发行版内置,不用额外处理。

这一步做完,终端里执行echo $SHELL,确认自己的 shell 类型,后面所有环境变量配置都写到对应的配置文件里去。

3.2 安装 Node 版本管理工具 nvm 并初始化

Node 环境是我配置频率最高的场景,用 nvm 管理的好处前面已经说过,这里直接讲操作。

macOS / Linux 安装 nvm 用官方脚本:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

安装完以后,需要把下面这段配置写进.zshrc或.bashrc:

export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

然后执行source ~/.zshrc。确认安装成功的方法是执行nvm --version。

这里有一个非常容易出现的坑:在 macOS 上,如果你已经用 Homebrew 装过 Node,nvm 在检测到系统已有 Node 时会提示冲突。必须先卸载干净旧 Node,再重新用 nvm 安装,否则会出现nvm管理不了原来那个 Node 的情况。这也是我前面说“先列清单”很重要的原因——避免装一半折返。

接下来安装长期维护版本(LTS):

nvm install --lts nvm alias default 'lts/*'

执行node -v和npm -v,能看到对应版本输出就说明 Node 环境已经可用了。这里强调一个细节:nvm alias default这一步很多新手会忽略,但它是保证“新开终端默认就是 LTS 版本”的关键,不加这个配置,新终端里可能找不到 Node 命令。

3.3 配置 Python 环境:pyenv + venv 的组合

Python 环境的配置核心是“多版本管理 + 项目级隔离”。直接用系统自带 Python 做开发是最大的隐患,因为系统级目录的权限问题和依赖污染会让你后期寸步难行。

pyenv 安装(macOS 推荐用 Homebrew):

brew install pyenv

然后配置 shell:

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc echo 'eval "$(pyenv init -)"' >> ~/.zshrc

同样需要source ~/.zshrc生效。接着安装你需要的 Python 版本:

pyenv install 3.11.5 pyenv global 3.11.5

pyenv global设置的是全局默认版本,到具体项目里再用pyenv local指定版本,这个组合能让你在一个机器上同时维护多个 Python 版本。

接下来是项目级虚拟环境。有人习惯用virtualenv,但官方内置的venv其实已经够用:

mkdir my-project && cd my-project python -m venv .venv source .venv/bin/activate

激活后终端前面会出现(.venv)标识,这说明你已经进入项目独立的 Python 环境。实际使用中,我强烈建议养成“每个项目建一个 venv”的习惯,哪怕是一个小脚本,否则 pip 安装的包会逐渐把全局环境塞满,最后你根本分不清谁依赖谁。

3.4 数据库与缓存等依赖组件的配置建议

前端项目涉及数据库连接是很常见的事,这里以最常见的本地 MySQL 和 Redis 为例。

MySQL 在 macOS 下用 Homebrew 安装是最省心的:

brew install mysql brew services start mysql

安装完成后默认 root 密码为空,首次使用建议立即执行mysql_secure_installation设置安全策略。如果项目需要特定字符集,记得在/usr/local/etc/my.cnf里配置character-set-server=utf8mb4。

Redis 更简单:

brew install redis brew services start redis

启动后可以用redis-cli ping验证,返回PONG就说明服务正常。对于 Windows 用户,Redis 官方不提供原生版本,比较常见的做法是用 WSL 或者 Docker 跑一个容器,这也是很多 Windows 团队在环境搭建上统一采用 Docker 的原因之一。

3.5 项目初始化:把环境“落”到项目里

环境搭建的最终目的是让项目跑起来,所以“初始化”这步是把工具链串起来的关键。

以 Node 项目为例,进入项目根目录后:

npm init -y

然后根据项目需要安装依赖。这里我建议团队内统一包管理器,并且在提交代码时锁定版本文件(package-lock.json或pnpm-lock.yaml)。不要小看这个文件,它保证了其他人拉代码后执行npm install时能装到完全一致的依赖版本,这是“环境可复现”的基石。

对 Python 项目,如果用pip,至少要把依赖导出到requirements.txt:

pip freeze > requirements.txt

如果你更希望从项目一开始就管理依赖,用poetry是更现代的选择,poetry add和poetry lock会自动维护一个更严格的依赖锁定文件。但这里提醒一句:工具迁移有成本,如果项目里已经大量使用了requirements.txt,没必要为了“新”而强行换成 poetry。

4. 常见问题与排查技巧实录

环境搭建里最折磨人的不是安装,而是“装好了但用不了”。下面这些是我在实操中高频踩到的问题,整理成速查表,每一个都是真实场景复现。

4.1 命令找不到(command not found)的排查顺序

这是最常见的报错,几乎每次搭环境都会遇到至少一次。我的排查顺序固定如下:

  1. 执行which 命令名,看系统能否定位到可执行文件。
  2. 如果 which 无输出,确认安装路径是否正确,比如 nvm 安装后目录是不是~/.nvm。
  3. 检查 PATH 配置是否加载了对应目录,执行echo $PATH看输出有没有包含目标路径。
  4. 确认配置文件是否被正确 source。改了.zshrc不 source,同样会“看不见”。

一个典型的误区是:在.zshrc里配了 PATH,但系统当前终端用的是 bash,那配置自然不生效。先用echo $SHELL确认 shell 类型,这个基础检查能避免你在错误的方向上折腾很久。

4.2 端口被占用导致服务无法启动

装好了 MySQL 或 Redis,启动时报Address already in use,这是很典型的问题。

排查手段:

lsof -i :3306

如果发现旧进程还在占用,可以优雅停掉或者直接kill -9对应 PID。但更根本的原因往往是:之前装着玩时启动了服务,后来忘了关,系统重启后服务又自动拉起来了(Homebrew services 默认开机自启)。

预防办法是明确区分“临时启动”和“开机自启”。临时调试用brew services run mysql,希望长期常驻才用brew services start mysql。这个习惯能避免很多“为什么我端口一直被占用”的困惑。

4.3 不同项目依赖冲突的根治思路

前端项目里,A 项目要求webpack@4,B 项目要求webpack@5,两个项目同时开发就很头疼。解决思路有两个层面:

第一层面,严格隔离。每个项目有自己的锁文件,安装时用npm ci而不是npm install。npm ci会严格按照锁文件安装,不走“优化猜测”,能最大限度保证两个项目的依赖树互不干扰。

第二层面,环境级隔离。如果两个项目同时还要不同 Node 版本,那就在项目根目录放.nvmrc文件,写上18.17.0这样的具体版本号,进入项目后由 nvm 自动读取并切换。

18.17.0

.nvmrc配合 nvm 的autoload行为,能让“项目与 Node 版本绑定”这件事自动化,团队协作时格外好用——每个人进入项目都会自动切到正确版本,不需要口头约定。

4.4 终端代理与网络问题导致的安装超时

国内网络环境下,npm 和 pip 从国外源拉包经常卡在 “Pending” 很久。最常见的解法是切换到国内镜像源。

对于 npm:

npm config set registry https://registry.npmmirror.com

对于 pip:

pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/

改完之后验证是否生效,直接执行npm config get registry和pip config list,能看到对应地址就对了。这里要特别提一句:镜像源只建议在网速确实不行时配置,追求稳定的人还是优先用官方源。而且团队内最好统一这个设置,否则一个人配了镜像、一个人没配,拉依赖 PI 会互相踩坑。

5. 从“自带水杯”思维出发的高效配置逻辑

环境搭建这件事,熟练之后会形成一套自己的“顺手流程”。我习惯叫它“自带水杯”逻辑——你走到哪个工位都能快速进入工作状态,是因为你有一套便携的、可靠的工具组合,而不是依赖那个工位恰好什么都有。

5.1 用一份 dotfiles 管理所有配置

如果你需要在多台机器间迁移环境,靠人肉拷贝配置太低效了。我的做法是建一个dotfiles仓库,把.zshrc、.gitconfig、.npmrc、.tmux.conf全部纳入管理,然后写一个初始化脚本,一键在新机器上完成符号链接和工具安装。

这个仓库不复杂,核心就是一堆配置文件和一份安装脚本。但带来的长期收益是:新机器从“零”到“顺手”,从原来的两小时缩短到十几分钟,而且所有配置经过自己梳理,什么作用、为什么这样写,心里清清楚楚。

5.2 为项目建立“快速启动”脚本

环境搭好后,我总会顺手在项目根目录加一个启动脚本。比如一个start.sh:

#!/bin/bash export NODE_ENV=development nvm use pnpm install pnpm dev

脚本的体量很小,但它把“从拉代码到跑起来”这个过程中所有容易遗忘的步骤固化了下来。后来团队里不止我一个人受益,新人入职只要执行./start.sh就能进入状态。

提示:脚本文件记得加执行权限,否则会报Permission denied,用chmod +x start.sh即可。

5.3 环境可复现是协作效率的起点

当团队规模起来后,环境搭建最大的敌人是“不可复现”。有些人机器上能跑,换个人机器上就跑不起来,这是幻影问题的温床。所以我在帮别人搭环境时,总会刻意做两件事:一是确保锁文件被提交到代码库;二是用 Docker 等容器化方案来兜底。

Docker 的价值在于“环境随代码走”。你可以在项目里放一份Dockerfile,把 Node 版本、系统依赖全部固化在镜像层,别人拉到代码后不需要理解你的机器背景,直接docker build就能得到一个一致的环境。

但这并不意味着每个人都要立即上 Docker。小项目、单人维护,搞好版本管理工具和锁文件就足够了;多人协作了,Docker 带来的稳定性收益会慢慢超过学习成本。

写在最后:我对环境搭建的真实体会

搭过十几台机器之后,我最深的一个感受是:环境搭建不是“装机”,而是一场“约定对齐”。你把工具版本、配置路径、依赖来源全部对齐了,后面的开发过程自然顺畅;某个地方偷懒没对齐,那个坑迟早会在某个加班的深夜爆给你看。

如果你现在正打算配环境,我的最直接建议是——别急着开始装,先把三样东西写好:一是需求清单,二是版本选择,三是团队统一规则。这三样东西花不了多长时间,但能把后面一整天甚至好几天的折腾,压缩成一小时的顺手操作。环境这件事,慢就是快。

相关新闻

轻量化MES如何破解离散制造多品种小批量的生产乱象

轻量化MES如何破解离散制造多品种小批量的生产乱象

多品种、小批量的离散制造现场,经常是一片"看似忙碌、实则混乱"的景象。订单碎片化、工艺路线五花八门、物料配套总是差那么几件、车间主任的手机一天到晚响个不停,问的最多的就是"那批货到底干到哪了"。这种乱象我见过太多&#xf…

2026/10/20 5:13:00 阅读更多 →
Qt原生日志系统:多路输出、环形缓冲与跨平台调试方案

Qt原生日志系统:多路输出、环形缓冲与跨平台调试方案

简介:这是一套面向Qt中高级开发者调试与运维需求的日志系统实现方案,解决传统Qt默认输出(如控制台或调试器)无法持久化、可视化及远程协同的问题。资源完整封装了日志的本地文件保存(含自动过期清理)、GUI窗…

2026/10/20 5:13:00 阅读更多 →
AI辅助写专著:一套可复制的人机协作工作流

AI辅助写专著:一套可复制的人机协作工作流

写专著这件事,经历过的人都懂:不是“写不出来”的问题,而是“要写的东西太多、时间永远不够、改到最后看到自己的稿子都想吐”。尤其是学术类、技术类专著,动辄几十万字,从选题、搭框架、查文献、写初稿,到…

2026/10/20 5:13:00 阅读更多 →

最新新闻

Tableau Desktop入门指南:从数据连接到仪表板设计的完整实操

Tableau Desktop入门指南:从数据连接到仪表板设计的完整实操

做数据分析这些年,我最常被新同事问的一句话就是:“Tableau Desktop 到底怎么上手?” 很多人第一次打开这个工具,看到左侧一堆字段、右侧一片空白工作区,第一反应是关掉重开。其实 Tableau 的设计逻辑非常朴素&#xf…

2026/10/20 5:49:17 阅读更多 →
Java调用FFmpeg实战:视频格式转换、合并、截图与播放全解析

Java调用FFmpeg实战:视频格式转换、合并、截图与播放全解析

1. 为什么要在Java里折腾FFmpeg视频处理这件事,放在五年前我大概率会直接甩给前端或者专门的转码服务去做。但这两年明显感觉到,业务侧对"在Java服务里直接处理视频"的需求越来越硬——用户上传一个手机拍的MOV,后台得转成MP4才能保…

2026/10/20 5:49:17 阅读更多 →
代码注释与格式化:从可读性到团队协作的工程实践

代码注释与格式化:从可读性到团队协作的工程实践

前阵子我接手一个历史遗留模块,代码里躺着一行注释:“这段逻辑不要动,动了会出线上事故。”没有署名,没有日期,也没有任何原因说明。我盯着它看了很久,最后还是把那段重构掉了——结果注释里担心的问题&…

2026/10/20 5:49:17 阅读更多 →
artcraft从创意到实物:艺术手工融合的完整实操指南

artcraft从创意到实物:艺术手工融合的完整实操指南

1. 从"artcraft"这个名字说起:它到底想解决什么问题第一次看到"artcraft"这个词,我脑子里蹦出来的第一反应是"艺术"加"手艺"的组合。这不是一个随便拼出来的名字,它背后指向的是一类非常具体的东西—…

2026/10/20 5:49:17 阅读更多 →
UE4 ListView性能优化实战:EntryWidget回收机制与选型指南

UE4 ListView性能优化实战:EntryWidget回收机制与选型指南

1. 为什么ListView值得单独拎出来聊做UE4 UI开发的人,迟早会撞上ListView这堵墙。不是因为它难用,恰恰相反,是因为它太好用,好用到很多人第一次接触就把它当成万能列表控件,结果项目做到中期,列表一卡、数据…

2026/10/20 5:49:17 阅读更多 →
artcraft从创意到成品:艺术手工项目全流程拆解与避坑指南

artcraft从创意到成品:艺术手工项目全流程拆解与避坑指南

1. 从“artcraft”这个名字说起:它到底想解决什么问题第一次看到“artcraft”这个标题,我脑子里蹦出来的第一反应是:这大概率不是一个纯工具,也不是一个纯内容平台,而是一个把“艺术创作”和“手工实现”这两件事捏在一…

2026/10/20 5:48:17 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →