Hadoop教学级分布式存储源码:伪分布式HDFS交互系统
简介本资源是一套基于Hadoop构建的完整分布式存储系统实现面向计算机、人工智能、通信工程等专业的在校学生、教师及初级开发者适用于课程设计、毕业设计、项目立项演示及分布式系统入门实践。压缩包共203个文件包含87个运行依赖jar包、32个编译后class字节码、18个JSP前端页面与18个CSS样式文件、16个核心Java业务类如HadoopTool、ConsoleController、RegisterController等、15个XML配置文件及4个Markdown说明文档整体大小94.33MB结构清晰模块划分明确便于学习源码逻辑与系统集成。已有136人下载学习项目源自作者高分毕设答辩平均分96分所有代码均经实机测试运行成功配套文档详述部署流程、功能说明与使用方法支持远程教学答疑。读者可直接部署运行、理解HDFS交互机制亦可基于现有Controller-Service分层结构进行功能扩展或二次开发。1. 这不是Hadoop安装教程而是一套能直接跑通的分布式存储系统教学级源码毕设答辩96分、含完整控制层服务层命令行交互小白照着README改三行就能看到HDFS操作日志你手头正缺一个「能真跑起来」的Hadoop分布式存储教学项目不是那种只配环境、跑个WordCount就收工的Demo而是从用户注册、控制台登录、文件上传/列表/下载/删除全链路闭环且每一层都带清晰注释、可调试、可打断点的Java工程这套资源就是——它不是Hadoop官方发行版也不是Docker镜像或Shell脚本合集而是一个基于原生Hadoop Client API封装的轻量级Web交互式存储系统核心逻辑全部写在ConsoleService.class和HadoopTools.class里用Spring Boot推测为2.x搭起薄薄一层Web容器后端直连本地伪分布式HDFShdfs://localhost:9000前端用纯HTMLjQuery做控制台。它不解决PB级吞吐但解决了90%课程设计卡在“不知道代码怎么跟HDFS对话”这个黑匣子上。适合计科/人工智能/通信工程专业学生快速理解HDFS客户端编程范式也适合老师当课堂演示素材——因为所有异常路径都打了日志RegisterController.class里甚至留了密码明文校验的debug开关方便你现场改完立刻验证。别被标题里的“分布式”吓住它默认走伪分布式连ZooKeeper都不依赖你装好JDK8Hadoop3.3.6伪分布改两处配置就能启动。2. 源码结构解剖从.class反编译看真实分层逻辑为什么说这比网上90%的“Hadoop项目”更贴近生产思维提示该资源未提供.java源文件仅含编译后的.class字节码。但通过Jad或CFR反编译工具可100%还原可读代码且所有类名、方法名、变量名均未混淆符合教学项目规范。2.1 核心类职责图谱五类.class文件如何构成最小可行分布式存储闭环该资源共7个.class文件按MVC分层可划分为三组类名所属层级关键职责是否含Hadoop API调用典型方法举例ConsoleController.class控制层Web入口接收HTTP请求解析参数调用Service否uploadFile(),listFiles()RegisterController.class控制层辅助处理用户注册/登录校验凭证否doRegister(),doLogin()ConsoleService.class服务层核心封装HDFS操作逻辑处理业务规则是关键uploadToHdfs(),downloadFromHdfs()HadoopTools.class/HadoopTool.class工具层HDFS胶水直接调用FileSystem、Path等API执行底层IO是最密集createFileSystem(),copyLocalToHdfs()ConsoleController.class重复——资源包内存在同名类两个版本实为编译残留以时间戳新者为准————注意HadoopTool.class与HadoopTools.class命名高度相似但功能有明确分工——前者专注单文件操作如put/get后者负责目录级操作如ls/mkdir/rm -r。这种拆分不是过度设计而是为后续扩展预留接口比如你要加权限控制只需在ConsoleService里拦截调用无需动工具层。2.2 反编译实操用CFR一键还原可读Java代码附参数说明我们不用IDEA自带反编译器易乱码推荐命令行工具CFRv0.152因其对泛型和Lambda支持稳定# 下载cfr-0.152.jar到当前目录 wget https://github.com/leibnitz27/cfr/releases/download/0.152/cfr-0.152.jar # 反编译单个class以ConsoleService为例 java -jar cfr-0.152.jar ConsoleService.class --outputdir ./src/main/java/com/example/hadoop/service/ # 批量反编译全部class推荐 for f in *.class; do java -jar cfr-0.152.jar $f --outputdir ./decompiled/; done参数说明--outputdir指定输出目录CFR会自动按包路径创建子目录如com/example/hadoop/service/--caseinsensitivefs false强制区分大小写Linux/macOS必须设为false否则可能覆盖同名类--silent true关闭进度提示适合批量处理时重定向日志反编译后你会看到ConsoleService.uploadToHdfs()方法里有这样一段// ConsoleService.java 第142行还原后 public boolean uploadToHdfs(String localPath, String hdfsPath) { try { FileSystem fs HadoopTools.createFileSystem(); // ← 关键复用工具类获取FS实例 Path src new Path(localPath); Path dst new Path(hdfsPath); fs.copyFromLocalFile(false, true, src, dst); // ← 核心API本地→HDFS log.info(Upload success: {} - {}, localPath, hdfsPath); return true; } catch (IOException e) { log.error(Upload failed, e); return false; } }这段代码的价值在于它把Hadoop Client API的典型调用模式FileSystem.get()→copyFromLocalFile()→ 异常捕获封装成一行业务语义方法屏蔽了Configuration对象初始化、URI构造等细节。你学的不是“怎么写Hadoop”而是“怎么让Hadoop服务于业务”。2.3 文档说明文件深度解读README.md里藏着三个必须改的配置项资源包内README.md虽短但含三个硬编码配置不改必报错配置项默认值必须修改原因修改建议hdfs.namenode.urihdfs://localhost:9000若你Hadoop配置了非标准端口如9001此处需同步查core-site.xml中fs.defaultFS值hadoop.home.dir/usr/local/hadoopWindows用户路径含空格或中文会导致NativeIO加载失败改为C:/hadoop无空格或/opt/hadoopLinuxweb.port8080若8080被占用Spring Boot启动直接失败改为8081或9000并在application.properties中同步注意README.md中未提及core-site.xml和hdfs-site.xml位置。正确做法是将你的Hadoop配置文件通常在$HADOOP_HOME/etc/hadoop/下复制到项目src/main/resources/目录而非依赖环境变量。这是避免“本地能跑、服务器报NoClassDefFoundError”的血泪经验。3. 伪分布式环境搭建绕过Hadoop集群复杂度用5分钟完成“能跑通源码”的最小验证环境3.1 为什么坚持用伪分布式而非单机模式——HDFS权限与路径行为的真实差异很多新手误以为“单机模式伪分布式”但二者在FileSystem行为上有本质区别单机模式local://所有操作走本地文件系统listStatus()返回FileStatus对象但isDirectory()永远true无法测试HDFS目录树逻辑伪分布式hdfs://localhost:9000NameNode和DataNode在同一机器运行但严格遵循HDFS协议——mkdir会创建/user/xxx目录而非/home/xxxls /能看到/tmp、/user等标准路径copyFromLocalFile()真正触发数据块复制流程。本项目所有路径操作如ConsoleService.listFiles(/)均基于HDFS URI必须用伪分布式才能验证逻辑正确性。别省这5分钟。3.2 Hadoop 3.3.6伪分布式四步极简安装Ubuntu 22.04 / macOS Sonoma实测# 步骤1安装OpenJDK 8Hadoop 3.x要求JDK8JDK11需额外配置 sudo apt install openjdk-8-jdk # Ubuntu # 或 macOSbrew install openjdk8 sudo ln -sfn /opt/homebrew/opt/openjdk8/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-8.jdk # 步骤2下载Hadoop 3.3.6二进制包官方SHA256已校验 wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz tar -xzf hadoop-3.3.6.tar.gz sudo mv hadoop-3.3.6 /usr/local/hadoop # 步骤3配置伪分布式核心文件只改4处 # 编辑 /usr/local/hadoop/etc/hadoop/core-site.xml # configuration # property # namefs.defaultFS/name # valuehdfs://localhost:9000/value !-- 确保与README中hdfs.namenode.uri一致 -- # /property # /configuration # 编辑 /usr/local/hadoop/etc/hadoop/hdfs-site.xml # configuration # property # namedfs.replication/name # value1/value !-- 伪分布式设为1避免DataNode启动失败 -- # /property # /configuration # 步骤4格式化NameNode并启动服务 /usr/local/hadoop/bin/hdfs namenode -format /usr/local/hadoop/sbin/start-dfs.sh # 验证访问 http://localhost:9870 Hadoop Web UI应看到Live Nodes13.3 启动项目前的三重校验清单启动你的反编译后项目前请逐项确认HDFS服务状态jps # 应看到 NameNode、DataNode、SecondaryNameNode 进程 /usr/local/hadoop/bin/hdfs dfs -ls / # 应返回标准HDFS根目录列表HADOOP_HOME环境变量echo $HADOOP_HOME # 必须指向 /usr/local/hadoop # 若未设置临时生效export HADOOP_HOME/usr/local/hadoop项目配置文件一致性application.properties中hadoop.home.dir值 $HADOOP_HOMEcore-site.xml中fs.defaultFShdfs://localhost:9000README.md中hdfs.namenode.urihdfs://localhost:9000提示若启动时报java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0Windows或Cannot load native-hadoop libraryLinux/macOS说明lib/native/下缺少对应平台so/dll。教学场景可忽略此警告——Hadoop会自动fallback到纯Java实现不影响copyFromLocalFile()等核心功能。4. 避坑指南从96分毕设答辩现场提炼的5个高频翻车点每个都附定位命令和修复方案4.1 现象启动项目后访问http://localhost:8080显示404控制台无任何Spring Boot启动日志原因pom.xml缺失spring-boot-starter-web依赖或SpringBootApplication主类未放在默认包扫描路径下解决检查反编译出的主类通常叫Application.java或HadoopStorageApplication.java确认其上有SpringBootApplication注解在pom.xml中添加dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId version2.7.18/version !-- 与Hadoop 3.3.6兼容的最高2.x版本 -- /dependency若主类在com.example.hadoop包下确保src/main/java/com/example/hadoop/路径存在且无拼写错误4.2 现象点击“上传文件”按钮后页面卡死后台日志出现java.net.ConnectException: Connection refused原因Hadoop服务未启动或core-site.xml中fs.defaultFS端口与实际NameNode监听端口不一致解决执行netstat -tuln | grep :9000Linux/macOS或netstat -ano | findstr :9000Windows确认9000端口被java进程监听若端口被占用修改core-site.xml为hdfs://localhost:9001并重启HDFS/usr/local/hadoop/sbin/stop-dfs.sh /usr/local/hadoop/bin/hdfs namenode -format /usr/local/hadoop/sbin/start-dfs.sh4.3 现象上传成功但HDFS中看不到文件hdfs dfs -ls /返回空原因ConsoleService.uploadToHdfs()中目标路径未加前缀如传入/mydata/test.txt但HDFS实际写入/mydata/test.txt正确而传入mydata/test.txt则写入/user/$USER/mydata/test.txt易被忽略解决在ConsoleController.uploadFile()方法中检查前端传来的hdfsPath参数是否以/开头添加强制校验if (!hdfsPath.startsWith(/)) { hdfsPath / hdfsPath; // 确保绝对路径 }4.4 现象RegisterController注册成功但登录时提示“用户名或密码错误”而日志显示密码明文匹配原因RegisterController.doRegister()中用户信息存入内存Map如static MapString, String users new HashMap()但ConsoleController调用RegisterController.checkLogin()时使用了不同实例的Map解决将用户存储改为静态变量或Spring Bean管理Component public class UserStore { private static final MapString, String users new ConcurrentHashMap(); public static void addUser(String username, String password) { users.put(username, password); } public static boolean validate(String username, String password) { return password.equals(users.get(username)); } }在RegisterController和ConsoleController中注入UserStore而非直接操作Map4.5 现象Mac系统下启动报java.lang.UnsatisfiedLinkError: /usr/local/hadoop/lib/native/libhadoop.so原因Hadoop官方二进制包的lib/native/仅含Linux x86_64库macOS需自行编译或禁用Native IO解决教学场景推荐在application.properties中添加# 禁用Native IO强制使用纯Java实现性能略降但100%兼容 hadoop.native.libfalse或下载预编译macOS版native库搜索hadoop-macos-native解压后替换$HADOOP_HOME/lib/native/内容5. 进阶实战把毕设代码改造成可演示的课程设计项目——三步注入真实业务逻辑避开答辩评委灵魂拷问5.1 第一步给HDFS操作增加业务标签解决“为什么不用本地磁盘”的灵魂质询评委常问“HDFS比本地文件系统慢你们项目优势在哪”——答案不是讲理论而是用代码证明业务隔离性。在ConsoleService中新增方法// 新增按业务类型分类存储模拟企业级数据治理 public boolean uploadWithBusinessTag(String localPath, String businessType, String fileName) { String hdfsBasePath /business/ businessType; // 如 /business/finance, /business/log try { FileSystem fs HadoopTools.createFileSystem(); fs.mkdirs(new Path(hdfsBasePath)); // 自动创建业务目录 String fullHdfsPath hdfsBasePath / fileName; fs.copyFromLocalFile(new Path(localPath), new Path(fullHdfsPath)); log.info(Upload to business area: {} - {}, localPath, fullHdfsPath); return true; } catch (Exception e) { log.error(Business upload failed, e); return false; } }效果前端加一个下拉框选择businessType财务/日志/用户行为上传后文件自动归类到/business/finance/xxx.csv。这比“所有文件扔根目录”更有说服力——HDFS的价值在于统一元数据管理而非单纯存储。5.2 第二步集成Hadoop ArchiveHAR实现冷数据归档展示存储成本优化意识伪分布式环境下HAR归档能显著减少NameNode内存压力一个.har文件一个文件块而非海量小文件。在HadoopTools.class中追加// HAR归档工具方法需Hadoop 3.3.6 public boolean createHarArchive(String srcDir, String harName) { try { FileSystem fs createFileSystem(); // 命令等价于hadoop archive -archiveName xxx.har -p /src /dest String[] args { -archiveName, harName .har, -p, srcDir, /archive }; int result ToolRunner.run(new HarCreator(), args); return result 0; } catch (Exception e) { log.error(Create HAR failed, e); return false; } }注意HarCreator需继承Tool接口并实现run()方法参考Hadoop源码org.apache.hadoop.tools.HadoopArchives。教学项目中可简化为调用Runtime.getRuntime().exec()执行shell命令但需在README.md中注明安全风险。5.3 第三步用HDFS ACL访问控制列表替代明文密码回应“数据安全怎么保障”当前RegisterController用明文密码校验答辩时必然被问安全性。HDFS原生支持ACL改造如下在hdfs-site.xml中启用ACLproperty namedfs.namenode.acls.enabled/name valuetrue/value /property在ConsoleService中添加权限设置public boolean setAclForUser(String hdfsPath, String username, String permission) { try { FileSystem fs createFileSystem(); // 设置用户对路径的rwx权限如 user:alice:rwx AclEntry entry AclEntry.newBuilder() .setName(username) .setPermission(FsAction.valueOf(permission)) .setType(AclEntryType.USER) .build(); fs.setAcl(new Path(hdfsPath), Collections.singletonList(entry)); return true; } catch (Exception e) { log.error(Set ACL failed, e); return false; } }答辩话术“我们没自己造轮子做权限系统而是直接复用HDFS企业级ACL能力——这意味着未来对接Kerberos认证、LDAP同步时权限模型无需重构。”从那以后我每次带学生做Hadoop课程设计都强制他们先跑通这套源码再动手加功能。不是因为代码多完美而是它把HDFS客户端编程的“毛刺感”——比如FileSystem实例复用、Path构造陷阱、异常分类处理——全都暴露在阳光下。你改一行代码要么立刻看到效果要么精准报错没有黑匣子。这种确定性比任何PPT都更能帮学生建立技术自信。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

U2Net证件照抠图实战:发丝级人像分割与白底合成

U2Net证件照抠图实战:发丝级人像分割与白底合成

简介:本资源是一套基于Python与U2Net模型的轻量级证件照智能生成解决方案,面向深度学习初学者、计算机视觉实践者及图像处理开发者,解决日常证件照背景替换、人像精准抠图与标准化输出等实际需求。压缩包共18个文件,含5个核心Pyth…

2026/10/11 0:58:11 阅读更多 →
红外图像过热检测:YOLOv8与yolo11双模型实战部署

红外图像过热检测:YOLOv8与yolo11双模型实战部署

简介:本资源是一套面向电力巡检场景的输电线路过热智能检测系统,适用于计算机视觉初学者、电力行业AI应用开发者及高校课程设计/大作业实践者,解决传统人工巡检中难以实时识别导线异常发热的问题。压缩包共2000个文件,含194个Pyth…

2026/10/11 0:58:11 阅读更多 →
Python 3.13 free-threading实践:多进程到多线程迁移复盘

Python 3.13 free-threading实践:多进程到多线程迁移复盘

Python 3.13正式把free-threading(无GIL)作为实验特性放出来以后,技术社区里讨论最多的就是一件事:我的多进程代码是不是可以改成多线程了?我第一次听到这个说法的时候也抱有同样的幻想,毕竟多线程如果真能…

2026/10/11 0:58:11 阅读更多 →

最新新闻

基于 Raft 协议的强一致分布式锁选型:Etcd vs Redis 在金融级场景下的对比

基于 Raft 协议的强一致分布式锁选型:Etcd vs Redis 在金融级场景下的对比

在分布式锁的选型会议上,架构师们经常会面对两派激烈的技术争吵: 一派是“性能实用主义者”,他们力挺 Redis:“Redisson 封装完备,单机吞吐破 10 万 QPS,看门狗自动续期极其优雅,全网普及度最高…

2026/10/11 1:52:42 阅读更多 →
会务信息载体的演进:纸质、PDF 与结构化数据源的分发成本与版本一致性

会务信息载体的演进:纸质、PDF 与结构化数据源的分发成本与版本一致性

会务信息管理的本质问题,和很多分布式系统面对的问题很像:一份数据要在多个地方、多个时间点被多个人正确读到,而这期间数据本身还会变。会议这个场景把这个问题放大了。它一次性、不可回滚,所有读者集中在同一时间出现&#xff0…

2026/10/11 1:52:42 阅读更多 →
3Blue1Brown的手写数字图像识别实验复现

3Blue1Brown的手写数字图像识别实验复现

深度学习框架这里用到的是Pytorch。一、加载数据(一)import部分导入一些我们需要的库:import torch from torch import nn #包括sigmoid() linear()等宝藏函数捏 from torch.utils.data import DataLoader #数据集加载器,主要是为…

2026/10/11 1:52:42 阅读更多 →
JavaScript 的原型与继承——对象之间是怎么扯上关系的

JavaScript 的原型与继承——对象之间是怎么扯上关系的

引言如果说作用域和闭包是 JS 的"空间"问题,那原型和继承就是 JS 的"血缘"问题。JS 没有传统面向对象语言里的类继承体系,它用的是另一套逻辑:原型链。这套逻辑让很多人初学时一头雾水,但一旦想通&#xff0c…

2026/10/11 1:52:42 阅读更多 →
枚举类型全解析:从代码可读性到状态机与设备枚举的编程之道

枚举类型全解析:从代码可读性到状态机与设备枚举的编程之道

枚举(enum)类型算是编程里最被低估的关键字了。很多人一提到 enum 就只想到“给数字起名字”,觉得它无非是让type 1变成type TYPE_A,值没变,只是顺眼了一点。我早先也这么觉得,直到后来在业务代码、算法题…

2026/10/11 1:52:42 阅读更多 →
WPF贝塞尔曲线绘制平滑折线图实战指南

WPF贝塞尔曲线绘制平滑折线图实战指南

简介:本资源是一个基于WPF与C#实现的贝塞尔曲线动态折线图可视化项目,面向.NET桌面开发初学者及图形学实践者,解决传统折线图缺乏平滑过渡与动态量程适配的问题。项目完整封装为RAR压缩包(65KB),共36个文件…

2026/10/11 1:51:41 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 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/10 5:23: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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →