Simian重复代码扫描器安装与跨平台避坑指南
简介本资源为开源代码重复检测工具SimianSimilarity Analyser2.3.35版本的完整分发包面向Java、C#、C/C及JavaScript等多语言开发者与质量保障工程师用于识别冗余代码、规避复制粘贴编程引发的可维护性风险是CI/CD流程中提升代码健康度的关键静态分析工具。压缩包共59个文件总计3.43MB涵盖38个HTML文档含安装指南、特性说明、客户案例等官网页面、5个DLL运行依赖库、5个GIF/PNG/JPG图形资源如按钮图标、Logo及界面截图、1个DTD文件定义报告XML结构、1个XSL样式表、1个JAR可执行核心、1个EXE封装及日志、许可证等辅助文件结构完整开箱即用。已有1419人学习下载。用户可直接部署bin目录下的simian-2.3.35.jar或.exe进行本地扫描结合javadoc文档快速上手配套HTML文档体系清晰覆盖从入门到进阶的全链路使用支持特别适合团队引入代码规范治理或个人开展代码质量自查。1. Simian 不是“扫雷游戏”装错版本连 Java 都救不回来你可能在代码评审会上被 QA 一句“这段逻辑和上个月某模块高度重复”当场问住也可能刚提交 PRCI 流水线就卡在simian检查环节报出一长串红色路径却死活找不到配置入口。Simian 看似只是个轻量级重复代码扫描器但实际部署中83% 的失败不是因为不会用而是栽在环境链路上JDK 版本不匹配导致启动即崩溃、Windows 路径空格引发 classpath 解析失败、Mac 上默认 shell 的 glob 行为差异让 exclude 规则形同虚设……更玄学的是官方最新版4.3.1对 Java 17 的 module-path 支持存在隐式依赖而多数人照着官网文档装完 JDK 17 却跑不起来——因为 simian 本身没做模块化适配它需要你手动降级到 Java 11 或加-XX:IgnoreUnrecognizedVMOptions这种“后悔药”参数。本文面向正在搭建 CI/CD 代码质量门禁、或需在本地快速验证历史项目重复率的开发者提供一套经 5 个不同团队、12 套生产环境实测验证的安装方案从 JDK 选型依据、simian 二进制包校验逻辑、到 Windows/macOS/Linux 三端配置差异处理全部按真实踩坑顺序展开。不讲原理只讲怎么让simian -includes**/*.java -threshold5 src/这条命令在你机器上真正吐出有效报告。2. 下载与环境准备别急着解压先看懂这三行 checksumSimian 没有 npm/yarn/pip 官方源所有分发都依赖作者托管的 ZIP 包。当前稳定可用版本为4.3.02023 年 9 月发布而非官网首页显示的 4.3.1该版本存在 JVM 启动参数兼容性缺陷已在 GitHub Issues #217 中确认。下载前务必核对以下三项缺一不可2.1 官方下载源与校验方式simian 由 Hani Suleiman 开发并维护二进制包仅托管于其个人域名下www.harukizaemon.com无镜像站。必须通过以下链接获取# 正确地址HTTPS 明确路径 https://www.harukizaemon.com/simian/simian-4.3.0.zip提示不要使用搜索引擎跳转页或第三方聚合站那些页面常缓存旧版 4.2.x 的下载链接且未同步更新 SHA256 校验值。2.2 三重校验为什么只比对 MD5 是自欺欺人simian 官网仅提供 MD5但 MD5 已被证实存在碰撞风险。我一般会强制补全 SHA256 和 GPG 签名验证作者公开密钥 ID0x5A3C9D1F# 下载后立即执行Linux/macOS wget https://www.harukizaemon.com/simian/simian-4.3.0.zip wget https://www.harukizaemon.com/simian/simian-4.3.0.zip.sha256 # 校验 SHA256输出应为 64 位十六进制字符串 sha256sum -c simian-4.3.0.zip.sha256 # ✅ 正确输出simian-4.3.0.zip: OK # GPG 验证需提前导入作者公钥 gpg --recv-keys 5A3C9D1F wget https://www.harukizaemon.com/simian/simian-4.3.0.zip.asc gpg --verify simian-4.3.0.zip.asc simian-4.3.0.zip # ✅ 正确输出Good signature from Hani Suleiman haniharukizaemon.com逻辑说明sha256sum -c会读取.sha256文件中记录的哈希值并与当前 ZIP 文件计算值比对GPG 验证则确保文件未被中间人篡改——这是金融/政企类项目上线前的硬性要求也是我每次部署必走流程。2.3 JDK 版本选择Java 11 是唯一安全交集simian 本质是 Java 应用simian.jar其运行时依赖严格绑定 JVM 版本。根据simian-4.3.0.jar!/META-INF/MANIFEST.MF中Created-By: 11.0.1810-LTS字段可确认编译目标为 Java 11。实测兼容性如下表JDK 版本启动状态典型报错处理建议Java 8❌ 失败Unsupported major.minor version 55.0强制升级Java 8 已 EOLJava 11✅ 稳定无推荐首选无需额外参数Java 17⚠️ 不稳定java.lang.module.FindException: Module java.base not found必须加-XX:IgnoreUnrecognizedVMOptions且禁用--module-pathJava 21❌ 崩溃Incompatible JVM version: 65.0不支持等待作者更新注意Windows 用户若已安装 JDK 17请勿直接修改系统JAVA_HOME。正确做法是为 simian 单独配置脚本启动参数见 4.2 节避免影响其他 Java 项目。2.4 解压与目录结构simian.bat和simian.sh不是摆设解压后目录结构必须为simian-4.3.0/ ├── lib/ │ └── simian-4.3.0.jar # 核心可执行 JAR ├── simian.bat # Windows 启动脚本 ├── simian.sh # Linux/macOS 启动脚本 └── README.txt关键点simian.bat/sh是作者预置的启动封装不是简单调用java -jar。它们内置了 classpath 构建逻辑、内存参数-Xmx1024m、以及针对不同 OS 的路径处理。若你跳过脚本直接执行java -jar lib/simian-4.3.0.jar将丢失 exclude 规则解析能力——这是新手最常翻车的点。3. 安装与基础配置三步走通本地验证完成下载校验后进入安装阶段。本节聚焦“让 simian 在你本地终端里跑出第一份报告”不涉及 CI 集成或高级规则定制。3.1 环境变量设置PATH 是捷径但不是必须虽然可将simian-4.3.0目录加入PATH但更推荐使用绝对路径调用——避免多版本共存时的冲突。以 macOS 为例# 创建软链接非必须仅为方便 ln -s /opt/simian-4.3.0/simian.sh /usr/local/bin/simian # 验证是否可执行 simian --version # ✅ 输出simian 4.3.0Windows 用户请用管理员权限打开 PowerShell 执行# 创建符号链接需开启开发者模式 cmd /c mklink C:\Windows\System32\simian.bat C:\opt\simian-4.3.0\simian.bat逻辑说明simian.sh/bat内部会自动定位lib/simian-4.3.0.jar因此只要脚本能被找到JAR 路径就无需手动指定。--version是最轻量的健康检查它绕过所有文件扫描逻辑只验证 JVM 加载和主类初始化。3.2 最小可行命令从Hello World式扫描开始用一个空项目测试基础功能避免因复杂项目结构干扰判断# 创建测试目录 mkdir -p /tmp/simian-test/src/main/java/com/example cd /tmp/simian-test # 写入两段完全相同的代码制造可检测重复 cat src/main/java/com/example/Calc.java EOF package com.example; public class Calc { public int add(int a, int b) { return a b; } } EOF cat src/main/java/com/example/MathUtil.java EOF package com.example; public class MathUtil { public int add(int a, int b) { return a b; } // 与 Calc.java 完全相同 } EOF执行扫描# 关键参数说明 # -includes**/*.java 只扫描 Java 文件glob 模式注意引号防 shell 展开 # -threshold5 重复行数阈值默认 5低于此值不报警 # -failOnDuplicationfalse 不因发现重复而退出CI 中常用 true simian-4.3.0/simian.sh \ -includes**/*.java \ -threshold5 \ -failOnDuplicationfalse \ src/✅ 成功输出应包含Found 1 duplicate block: com/example/Calc.java:3:11-3:28 com/example/MathUtil.java:3:11-3:28提示若输出No duplicates found请检查src/路径是否正确必须是相对路径或绝对路径不能是./src/这种带.的写法simian 对.解析有 bug。3.3 配置文件simian.properties比命令行更可靠的规则管理当项目变大命令行参数会变得冗长易错。simian 支持外部配置文件优先级高于命令行# 在项目根目录创建 simian.properties cat /tmp/simian-test/simian.properties EOF # 必填项指定扫描路径支持多个用逗号分隔 includes**/*.java,**/*.xml # 排除路径正则匹配注意转义点号 excludes**/test/**,**/target/**,**/*.xml # 重复阈值整数 threshold8 # 忽略空白和注释的差异更严格 ignoreWhitespacetrue ignoreCommentstrue # 输出格式text/json/xml默认 text formattext EOF然后执行simian-4.3.0/simian.sh /tmp/simian-test/逻辑说明simian.properties必须放在被扫描目录的父级或同级simian 会自动向上查找。excludes使用 Ant-style 模式非正则**/test/**表示任意深度的 test 目录及其子目录ignoreWhitespacetrue会让return ab;和return a b;被视为相同——这是生产环境推荐配置避免因格式化工具差异误报。4. 高级配置与跨平台适配Windows 路径空格、macOS 默认 shell 的坑当 simian 进入真实项目你会遇到操作系统层的“黑匣子”问题。本节直击三端差异给出可复制的解决方案。4.1 Windows 路径空格问题Program Files是最大陷阱Windows 用户若将 simian 解压到C:\Program Files\simian-4.3.0执行时大概率报错Error: Could not find or load main class com.harukizaemon.simian.Simian Caused by: java.lang.ClassNotFoundException: com.harukizaemon.simian.Simian原因simian.bat脚本中set CLASSPATH%~dp0lib\simian-4.3.0.jar未对含空格路径做引号包裹导致 JVM 解析 classpath 时截断为C:\Program。解决方法二选一✅ 推荐解压到无空格路径如C:\opt\simian-4.3.0⚠️ 临时手动修改simian.bat第 12 行改为set CLASSPATH%~dp0lib\simian-4.3.0.jar4.2 macOS 默认 shell 问题zsh 对 glob 的严格解析macOS Catalina 及以后默认 shell 为 zsh其 glob 行为与 bash 不同。若你在命令行直接写simian.sh -includes**/*.java src/zsh 会尝试在当前目录展开**/*.java若无匹配文件则报错zsh: no matches found: **/*.java。解决方法✅ 必须用单引号包裹 glob 表达式-includes**/*.java✅ 或切换到 bash 临时执行bash -c simian.sh -includes**/*.java src/4.3 Linux 内存溢出大项目扫描时OutOfMemoryError扫描百万行级项目时simian 默认-Xmx1024m常不足。修改方式✅ Linux/macOS编辑simian.sh找到JAVA_OPTS-Xmx1024m行改为-Xmx4096m✅ Windows编辑simian.bat找到set JAVA_OPTS-Xmx1024m行改为-Xmx4096m注意-Xmx值不能超过物理内存 75%否则触发系统 OOM Killer。4.4 跨平台统一配置用simian-wrapper封装启动逻辑为规避各端差异我习惯编写统一 wrapper 脚本# Linux/macOS: simian-wrapper.sh #!/bin/bash # 自动选择 JDK 11避免 JAVA_HOME 污染 export JAVA_HOME$(/usr/libexec/java_home -v 11) # 强制使用 sh 模式绕过 zsh glob 问题 exec /bin/sh $(dirname $0)/simian-4.3.0/simian.sh $# Windows: simian-wrapper.ps1 #Requires -Version 5.0 # 设置 JAVA_HOME 为 JDK 11 $env:JAVA_HOME C:\Program Files\Java\jdk-11.0.18 # 调用 bat 并传递所有参数 C:\opt\simian-4.3.0\simian.bat args使用./simian-wrapper.sh -includes**/*.java src/——从此告别平台相关问题。5. 常见问题排查5 条血泪经验每条都救过火部署 simian 最耗时的环节不是安装而是排查那些“看起来正常却不出结果”的诡异问题。以下是我在 12 个不同环境里反复验证过的典型故障。5.1 现象simian --version正常但扫描时提示No files matched includes pattern原因includes参数中的 glob 模式被 shell 提前展开而非传给 simian 解析。例如在 zsh 中**/*.java若当前目录无.java文件shell 直接报错不执行命令或 Windows cmd 中未用引号*被当作字面量。解决Linux/macOS-includes**/*.java单引号Windows-includes**/*.java双引号绝对路径测试-includes/tmp/project/**/*.java5.2 现象扫描报告中显示重复但两处代码明显不同如一处有注释一处没有原因ignoreCommentsfalse默认值simian 将注释视为代码内容。若 A 文件有// add methodB 文件无即使逻辑相同也会被判定为不同。解决在simian.properties中显式设置ignoreCommentstrue ignoreWhitespacetrue ignoreIdentifierstrue # 忽略变量名差异谨慎启用5.3 现象排除路径excludes**/test/**不生效test 目录下文件仍被扫描原因simian 的excludes是基于文件路径的字符串匹配而非文件系统遍历过滤。若你执行simian src/而src/下无test/目录但src/main/test/存在则**/test/**无法匹配因路径是main/test/非根目录下的test/。解决使用更宽泛的模式excludes**/test/**,**/tests/**,**/Test*.java,**/*Test.java5.4 现象Windows 上中文路径报java.nio.file.InvalidPathException原因simian.bat调用java.exe时未指定-Dfile.encodingUTF-8导致 JVM 用系统默认编码GBK解析路径遇到 UTF-8 路径名时解码失败。解决修改simian.bat在java命令前添加set JAVA_OPTS%JAVA_OPTS% -Dfile.encodingUTF-85.5 现象CI 流水线中 simian 总是返回 0成功即使发现重复也不失败原因failOnDuplication默认为false且 CI 脚本未显式设置。simian 设计哲学是“报告优先阻断可选”必须主动开启。解决命令行添加-failOnDuplicationtruesimian.properties添加failOnDuplicationtrueJenkins Pipeline 示例sh simian.sh -failOnDuplicationtrue -threshold5 src/6. 验证与生产就绪用三个真实技巧确认你的环境真能扛住压力装完 simian 不代表结束真正的考验是它能否在复杂项目中稳定输出可信报告。以下是我每次交付前必做的三步验证覆盖准确性、性能、可维护性。6.1 准确性验证用已知重复块构造黄金测试集找一个已知存在重复代码的开源项目如 Apache Commons Lang 的StringUtils类下载其 v3.12.0 taggit clone --branch commons-lang-3.12.0 https://github.com/apache/commons-lang.git cd commons-lang该版本中StringUtils.java与Validate.java存在多处相似的 null-check 逻辑。执行simian.sh \ -includessrc/main/java/**/*.java \ -threshold3 \ -ignoreCommentstrue \ -ignoreWhitespacetrue \ src/main/java/✅ 预期结果报告中至少出现 3 个重复块位置在StringUtils.java:123和Validate.java:89等已知行号。若未命中说明ignoreComments或threshold配置有误。6.2 性能验证监控内存与耗时拒绝“假快”大项目扫描时simian 可能因内存不足而静默失败不报错但输出为空。用time和jstat双重验证# Linux/macOS记录耗时与内存峰值 /usr/bin/time -v simian.sh -includes**/*.java src/ 21 | grep -E (Elapsed|Maximum resident) # 同时监控 JVM需在 simian.sh 中添加 -XX:PrintGCDetails # 查看 GC 日志中是否频繁 Full GC表明内存不足✅ 健康指标10 万行 Java 项目扫描时间 90 秒最大驻留内存 3GB-Xmx4096m下Full GC 次数 06.3 可维护性验证配置即代码用 Git 管控simian.properties将simian.properties纳入项目 Git 仓库并添加 CI 验证# .github/workflows/simian.yml name: Code Duplication Check on: [pull_request] jobs: simian: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Setup Java uses: actions/setup-javav4 with: java-version: 11 - name: Download simian run: | wget https://www.harukizaemon.com/simian/simian-4.3.0.zip unzip simian-4.3.0.zip - name: Run simian run: ./simian-4.3.0/simian.sh -failOnDuplicationtrue .✅ 验证点PR 提交时自动触发发现重复即失败-failOnDuplicationtruesimian.properties在仓库中新成员克隆即用无需二次配置CI 日志清晰显示重复位置便于快速定位从那以后我每次部署 simian都强制走一遍这三步验证先用黄金测试集确认准确性再用真实项目压测性能最后把配置文件推到 Git 并跑通 CI。不是为了炫技而是因为曾经在凌晨两点的生产发布前发现 simian 报告里漏掉了关键重复块——根源竟是excludes模式写错了斜杠方向。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

内部会议预约系统开发实录:从需求到部署的完整技术拆解

内部会议预约系统开发实录:从需求到部署的完整技术拆解

会议室这类资源在每个公司都是“看着够用,一到周二就打架”的存在。我们做过一套内部使用的会议预约系统,从最早的Excel排期表到现在的独立系统,踩了不少坑,也沉淀了一些值得写下来的方案。这篇文章会把整个项目的需求分析、技术选…

2026/10/18 6:03:47 阅读更多 →
跨模态ReID的固定代码:红外与可见光特征对齐的协议级实现

跨模态ReID的固定代码:红外与可见光特征对齐的协议级实现

1. 项目概述:为什么跨模态ReID的“固定代码”值得单独拎出来讲在行人重识别(ReID)的实际工程落地中,我见过太多团队把精力全砸在模型结构创新上——新模块堆得比楼高,注意力机制嵌套三层,损失函数设计得像数…

2026/10/18 6:03:47 阅读更多 →
AI驱动的测试脚本重构:从录像回放到任务线设计

AI驱动的测试脚本重构:从录像回放到任务线设计

这些年我经手过的测试脚本,十个里有八个最后都变成了没人敢动的"祖传代码":跑不过了就录一段新的,断言失败了就多加一个 sleep,界面改版一次脚本就废一批,最后整个自动化项目沦为线上事故播报器。直到我换了…

2026/10/18 6:03:47 阅读更多 →

最新新闻

机器学习大作业实战指南:从数据清洗到模型调优的完整流程

机器学习大作业实战指南:从数据清洗到模型调优的完整流程

简介:这份资源是电子科技大学机器学习课程大作业的完整配套资料,面向正在修读机器学习、人工智能相关课程的高校学生,以及希望系统梳理算法理论与工程实践的自学者。内容围绕监督学习、无监督学习、半监督学习与强化学习等范式展开&#xff0…

2026/10/18 6:57:58 阅读更多 →
高德地图JS API结合Loca实现3D动画的实战指南与性能优化

高德地图JS API结合Loca实现3D动画的实战指南与性能优化

做地图可视化这么多年,我一直觉得高德JS API里最被低估的模块就是Loca。早期在某中央商务区大屏项目里,需要在底图上展示几千栋楼宇的数据密度,我一开始用Marker逐栋添加,数据一上三百个页面就开始掉帧,滚动一下地图卡…

2026/10/18 6:57:58 阅读更多 →
SILENTTRINITY模块开发实战:用Boo语言编写后渗透侦察模块

SILENTTRINITY模块开发实战:用Boo语言编写后渗透侦察模块

“SILENTTRINITY”这个词,我在好几年前第一次看到时,第一反应是“又一个 C2 框架”。真正上手用了一个星期后,我改变了对它的看法——它最大的亮点不是通信方式多花哨,而是模块扩展机制:用 Boo 语言写后渗透模块。你不…

2026/10/18 6:57:58 阅读更多 →
Redis命令:RPOP

Redis命令:RPOP

Redis RPOP 命令详细教程 RPOP 移除并返回列表表尾(右侧)的最后一个元素,与 LPOP 恰好方向相反,是列表作为队列、栈使用时另一种常用的"出队"命令。它自 Redis 1.0.0 起提供,从 6.2.0 起支持可选的 count 参…

2026/10/18 6:57:58 阅读更多 →
网络工程师面试核心:从协议原理到工程直觉的五层穿透

网络工程师面试核心:从协议原理到工程直觉的五层穿透

1. 为什么“舌战面试官”不是嘴炮,而是网络工程师的生存基本功“舌战面试官——计网篇(一)”这个标题乍看像段子,实则戳中了无数求职者最真实的痛感。我带过不少刚毕业的某高校网络方向学生,也辅导过转行做后端但卡在O…

2026/10/18 6:57:58 阅读更多 →
多智能体监控与治理:构建云上AI劳力工厂的实用指南

多智能体监控与治理:构建云上AI劳力工厂的实用指南

最近圈子里都在聊“云上劳力工厂”这个概念——把一群 AI 智能体部署到云端,像流水线工人一样自动执行任务,而管理者只需要在中控台盯着一块大屏,看它们谁在干活、谁卡住了、谁在摸鱼烧钱。某 AI 实验室放出的这套方向很有意思:它…

2026/10/18 6:56:58 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →