Java后端工程师入门:从环境搭建到第一个Spring Boot项目实战
1. 项目概述为什么是“Java后端·起”如果你点开了这篇文章大概率是刚拿到一个Java后端的Offer或者下定决心要转型后端开发正对着电脑屏幕面对着一堆陌生的名词和工具感到无从下手。这种感觉我太熟悉了十几年前我刚入行时也是从“环境变量都配不明白”的阶段过来的。“Java后端·起”这个标题就是想和你聊聊一个Java后端工程师的职业生涯究竟该从哪里真正“启动”。这不仅仅是安装一个JDK、配置一下环境变量那么简单。很多人以为学Java就是背“八股文”、刷LeetCode这没错但远远不够。一个能真正干活、能解决问题的后端工程师他的“启动”是一个系统工程包括了技术栈的认知、开发环境的搭建、第一个可运行项目的构建以及最重要的——思维模式的转变。从“学习者”到“构建者”的转变。网上那些零散的“Java安装教程”、“环境变量配置”解决的是“从无到有”而我想和你分享的是如何“从有到好”如何搭建一个高效、稳定、可扩展的本地开发环境并理解其背后的每一个选择为后续的深入学习和高强度开发打下坚实的基础。2. 核心认知Java后端技术栈全景与学习路径误区在动手之前我们必须先建立正确的“地图”。Java后端领域浩瀚如海新手最容易犯的错误就是试图一口吃成胖子或者被各种时髦的名词带偏了方向。2.1 技术栈的“核心圈”与“外延圈”我们可以把Java后端技术栈想象成一个同心圆最内圈核心基础Java SE语法、集合、IO、多线程、JVM基础。这是地基必须牢固。很多面试问题所谓的“八股文”如HashMap原理、synchronized和Lock的区别、JVM内存模型都源于此。理解它们不是为了应付面试而是为了写出高效、安全的代码。中间圈开发框架与生态Spring Framework尤其是Spring Boot。这是当前Java后端事实上的标准。它解决了企业级应用开发的复杂性提供了依赖注入、AOP、事务管理等一套优雅的解决方案。学习Spring Boot就是学习如何快速构建一个可独立运行的、生产级的微服务。外圈支撑与扩展技术数据库MySQL关系型、Redis缓存。ORM框架MyBatis或JPAHibernate用于简化数据库操作。构建工具Maven或Gradle管理项目依赖和构建生命周期。版本控制Git团队协作的基石。容器与部署Docker实现环境标准化。新手常踩的坑是花大量时间在“外圈”那些看起来酷炫的技术上比如一开始就钻研DockerK8S的复杂编排却对“核心圈”的JVM内存溢出OutOfMemoryError、集合类的正确使用一知半解。当项目真正运行时一个NullPointerException或内存泄漏就能让你调试半天。2.2 关于“八股文”与“设计模式”的理性看待搜索热词里“java面试八股文”、“java设计模式”居高不下这反映了市场的需求但也容易让人陷入误区。“八股文”的本质它其实是核心知识的考点化总结。死记硬背当然不行但如果你能理解每道题背后的原理比如为什么HashMap链表会转红黑树阈值为什么是8那么这些“八股”就是你知识体系的骨架。我的建议是以理解带动记忆每学一个知识点都尝试用代码去验证并思考它的应用场景和可能的问题。“设计模式”的定位它是解决特定问题的优秀“套路”Pattern但不是银弹。新手最容易犯的错误是“手里有把锤子看什么都像钉子”生搬硬套设计模式把简单代码复杂化。你应该在有了足够的编码量和项目经验后再系统学习设计模式。届时你会恍然大悟“原来我之前那个问题用观察者模式可以这么优雅地解决”学习路线应该是先写出能跑的代码 - 写出结构清晰的代码 - 最后再考虑用设计模式优化代码结构。3. 环境奠基从JDK安装到IDE的深度配置一个顺手的开发环境能极大提升幸福感和效率。这里我们不止步于“能运行”而要追求“高效运行”。3.1 JDK选型与安装为什么推荐LTS版本很多教程让你直接下载最新的JDK但这可能埋下隐患。生产环境追求的是稳定因此长期支持版本LTS是首选。目前Java 8、Java 11、Java 17是主流的LTS版本。对于新手我强烈推荐从Java 11或Java 17开始。它们引入了很多现代语言特性如局部变量类型推断var同时又拥有长期支持。安装要点官网下载认准Oracle JDK或OpenJDK发行版如Adoptium的Temurin JDK。后者开源免费更适合学习和生产。环境变量配置JAVA_HOME指向JDK安装目录如C:\Program Files\Eclipse Adoptium\jdk-11.0.xx-hotspot然后在Path中添加%JAVA_HOME%\bin。配置完后在命令行输入java -version和javac -version验证。注意JAVA_HOME的路径不要包含bin目录这是很多新手配置错误的地方。3.2 IDE的选择与IntelliJ IDEA的“开箱即用”配置IDE是你战斗的主武器。Eclipse和IntelliJ IDEA是两大主流后者因其智能、高效而越来越成为行业标准。我们以IDEA为例。首次启动配置主题与字体选择一个护眼的主题如Darcula并将编辑器字体调整为等宽字体如JetBrains Mono, Consolas字号建议14-16。关键设置自动导包与优化导入在Settings - Editor - General - Auto Import中勾选Add unambiguous imports on the fly和Optimize imports on the fly。这能自动处理import语句节省大量时间。编码设置将Global Encoding、Project Encoding和Default encoding for properties files都设置为UTF-8。这是避免中文乱码的基石。Maven配置在Settings - Build, Execution, Deployment - Build Tools - Maven中配置你的Maven安装路径、本地仓库地址并勾选Always update snapshots。建议使用阿里云镜像加速依赖下载在Maven的settings.xml文件中配置镜像。解决一个常见热词错误java: You aren‘t using a compiler supported by lombok, so lombok will not workLombok是一个通过注解简化Java Bean编写的流行库。这个错误意味着IDEA没有启用对Lombok注解的处理。解决方法是安装Lombok插件Settings - Plugins中搜索安装并在Settings - Build, Execution, Deployment - Compiler - Annotation Processors中勾选Enable annotation processing。3.3 Maven不只是依赖管理更是项目生命周期管家Maven的核心是pom.xml文件。新手要理解几个关键部分坐标GAVgroupId组织或项目唯一标识、artifactId项目名、version版本号。这三点唯一确定一个依赖。依赖Dependencies在这里声明项目需要的库。Maven会自动从中央仓库或你配置的镜像下载并处理传递性依赖。构建插件Build Plugins例如maven-compiler-plugin用于指定Java编译版本。实操心得定期使用mvn dependency:tree命令查看依赖树可以解决 Jar 包冲突。将项目根目录下的.mvn文件夹和mvnw文件提交到Git可以确保团队成员使用一致的Maven版本进行构建。遇到程序包io.github.resilience4j.circuitbreaker不存在这类错误首先检查pom.xml中依赖的版本号是否正确网络是否通畅然后尝试mvn clean compile重新下载和编译。4. 第一个项目实战用Spring Boot构建一个RESTful API理论说再多不如动手跑一个。我们来创建一个最简单的Web API它包含一个控制器、一个服务层并连接数据库。4.1 项目初始化使用Spring Initializr这是最标准、最推荐的方式。你可以访问 start.spring.io 网站也可以在IDEA中直接使用其内置的Spring Initializr。ProjectMaven ProjectLanguageJavaSpring Boot选择最新的稳定版如3.2.xProject Metadata填写你的Group如com.example、Artifact如demo。Dependencies添加Spring Web用于Web开发、Lombok简化代码、MySQL Driver数据库驱动、Spring Data JPA数据持久化。点击生成你会得到一个标准的Spring Boot项目结构。4.2 项目结构解析与编码下载解压后用IDEA打开。标准结构如下src ├── main │ ├── java │ │ └── com.example.demo │ │ ├── DemoApplication.java // 主启动类 │ │ ├── controller // 控制器层接收请求 │ │ ├── service // 服务层业务逻辑 │ │ ├── repository // 数据访问层或dao │ │ └── entity // 实体类对应数据库表 │ └── resources │ ├── application.properties // 配置文件 │ └── static templates // 静态资源和模板可选 └── test // 测试代码1. 配置数据库连接 在application.properties中配置spring.application.namedemo server.port8080 # 数据库配置 spring.datasource.urljdbc:mysql://localhost:3306/your_database?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai spring.datasource.usernameroot spring.datasource.passwordyour_password spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver # JPA配置 spring.jpa.hibernate.ddl-autoupdate # 启动时根据实体更新表结构生产环境请勿使用create或create-drop spring.jpa.show-sqltrue # 控制台打印SQL便于调试 spring.jpa.properties.hibernate.dialectorg.hibernate.dialect.MySQL8Dialect2. 创建实体类Entity 在entity包下创建User.java。package com.example.demo.entity; import jakarta.persistence.*; import lombok.Data; Entity Table(name user) Data // Lombok注解自动生成getter, setter, toString等方法 public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String username; private String email; // 省略构造方法Data会生成 }3. 创建数据访问层Repository 在repository包下创建UserRepository.java。Spring Data JPA的神奇之处就在这里。package com.example.demo.repository; import com.example.demo.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; Repository public interface UserRepository extends JpaRepositoryUser, Long { // 无需实现任何方法就已具备基础的CRUD功能 // 可以根据方法名自动推导查询例如 User findByUsername(String username); }4. 创建服务层Service 在service包下创建UserService.java。package com.example.demo.service; import com.example.demo.entity.User; import com.example.demo.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; Service public class UserService { Autowired private UserRepository userRepository; public User saveUser(User user) { // 这里可以加入业务逻辑如数据校验 return userRepository.save(user); } public ListUser getAllUsers() { return userRepository.findAll(); } public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } }5. 创建控制器Controller 在controller包下创建UserController.java。package com.example.demo.controller; import com.example.demo.entity.User; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; RestController RequestMapping(/api/users) public class UserController { Autowired private UserService userService; PostMapping public User createUser(RequestBody User user) { return userService.saveUser(user); } GetMapping public ListUser getAllUsers() { return userService.getAllUsers(); } GetMapping(/{id}) public User getUserById(PathVariable Long id) { return userService.getUserById(id); } }6. 运行与测试 直接运行DemoApplication.java中的main方法。看到控制台输出带有“Started DemoApplication”的日志说明启动成功。 打开浏览器或使用Postman等工具测试APIPOST http://localhost:8080/api/users BodyJSON{username: test, email: testexample.com}GET http://localhost:8080/api/usersGET http://localhost:8080/api/users/15. 深度避坑指南从“跑不起来”到“跑得稳健”第一个项目跑通只是开始。在实际开发中你会遇到各种稀奇古怪的问题。下面是一些高频问题的排查思路。5.1 依赖与编译类问题排查表问题现象可能原因排查步骤与解决方案程序包XXX不存在1.pom.xml中未声明依赖。2. 依赖版本错误或不可用。3. Maven仓库下载失败网络/镜像问题。4. IDEA未正确导入Maven项目。1. 检查pom.xml添加正确依赖。2. 去 Maven中央仓库 搜索确认坐标和版本。3. 检查Maven配置的镜像尝试mvn clean compile -U强制更新。4. 在IDEA右侧Maven工具栏点击刷新按钮或执行Reimport。Lombok注解不生效IDEA的注解处理器未启用或插件未安装。1. 确认已安装Lombok插件。2.Settings - Build - Annotation Processors勾选Enable annotation processing。3. 执行mvn clean compile。java: Internal error in the mapping processor通常是注解处理器如MapStruct与JDK或IDE的兼容性问题。1. 升级注解处理器到最新版本。2. 在pom.xml的maven-compiler-plugin配置中明确指定注解处理器路径。3. 尝试重启IDEA并清理缓存File - Invalidate Caches。JPS incremental annotation processing is disabledIDEA的增量编译与某些注解处理器冲突。这是一个警告通常不影响运行。如果介意可以在Settings - Build - Compiler中关闭Use compiler改为Javac但这会牺牲一些编译速度。5.2 运行时问题内存、配置与连接1.OutOfMemoryError: Java heap space这是最经典的错误之一说明JVM堆内存不足。本地调试在IDEA的启动配置中修改VM options增加堆大小例如-Xms512m -Xmx1024m。这表示初始堆512MB最大堆1024MB。生产环境在启动Jar包时通过java -Xmx2048m -jar yourapp.jar指定。但更重要的是分析内存泄漏。使用jmap,jstat或VisualVM等工具监控堆内存使用情况查看哪些对象占用了大量内存且无法被GC回收。2. 数据库连接失败错误信息Communications link failureAccess denied for user。排查检查application.properties中的URL、用户名、密码是否正确。检查MySQL服务是否启动net start mysql或systemctl status mysqld。检查防火墙是否阻止了3306端口。对于高版本MySQL驱动和MySQL 8连接URL中的serverTimezone参数通常是必须的。3. 端口被占用启动时报错Web server failed to start. Port 8080 was already in use.解决方案修改application.properties中的server.port如server.port8081。找到并关闭占用端口的进程。在Windows上netstat -ano | findstr :8080然后taskkill /PID 进程号 /F。在Linux/macOS上lsof -i:8080然后kill -9 进程号。5.3 开发效率提升技巧善用IDEA的Live Template例如输入psvm快速生成public static void main输入sout生成System.out.println()。你可以自定义模板比如快速生成日志语句。Debug技巧不要只会打System.out.println。熟练使用断点条件断点、异常断点、表达式求值Evaluate Expression、变量监视Watches和步进操作Step Over, Into, Out。阅读源码遇到框架报错或行为不理解时勇敢地Ctrl鼠标左键点进去看源码。Spring框架的源码注释非常优秀是最好的学习资料。单元测试养成写单元测试的习惯JUnit 5 Mockito。这不仅是为了保证代码质量更是为了让你在修改代码时有“安全网”。从为Service层写测试开始。6. 思维升级从CRUD到系统思考完成第一个API后你不能止步于此。一个真正的后端工程师思考的远不止增删改查。1. 接口设计RESTful风格只是一种约定更重要的是考虑接口的幂等性同一请求多次执行效果相同、安全性敏感操作需鉴权、版本管理如/api/v1/users和清晰的文档使用Swagger/OpenAPI。2. 事务管理在Service方法上使用Transactional注解确保数据库操作的原子性。理解事务的传播行为Propagation和隔离级别Isolation。3. 异常处理不要将原始的异常信息直接返回给前端。使用ControllerAdvice或RestControllerAdvice编写全局异常处理器将不同类型的异常转换为结构化的错误信息包含错误码和友好提示返回。4. 日志规范使用SLF4J Logback/Log4j2用Slf4j注解记录日志。区分日志级别DEBUG, INFO, WARN, ERROR在关键业务流程、异常捕获处记录日志便于线上问题排查。5. 性能意识思考你的API是否会成为瓶颈是否需要引入缓存Redis来减轻数据库压力数据库查询是否使用了索引通过explain命令分析SQL。这些思考会让你在后续学习Redis、数据库优化时目标更加明确。“Java后端·起”这个“起”字既是起步也是启程。它不是一个瞬间动作而是一个持续的状态。今天你搭好了环境跑通了第一个Demo理解了基本的MVC分层。明天你可能要学习Spring Cloud应对微服务研究JVM调优解决性能问题使用消息队列解耦系统。这条路很长但每一步都算数。我个人的体会是后端开发就像盖房子基础不牢地动山摇。现在打下的每一个扎实的基础未来都会在某个关键时刻回报你。别怕遇到问题每一个你亲手解决掉的NullPointerException每一次你成功调优的慢查询都是你在这条路上坚实的脚印。接下来试着给你的小项目加上参数校验Hibernate Validator、统一响应封装、简单的单元测试你会发现世界又开始变得不同了。

相关新闻

Excel VBA报错“stdole32.tlb丢失”的根源剖析与系统化解决方案

Excel VBA报错“stdole32.tlb丢失”的根源剖析与系统化解决方案

1. 问题现象与根源剖析 如果你在打开某个Excel文件,或者运行一个包含VBA宏的Excel工作簿时,突然弹出一个“无法找到文件‘stdole32.tlb’”或“丢失stdole32.tlb”的错误对话框,先别急着重装Office。这个看似棘手的问题,其实背后有…

2026/10/7 6:58:25 阅读更多 →
BIO与NIO、AIO的区别(这个容易理解)

BIO与NIO、AIO的区别(这个容易理解)

前言在Java网络编程和高性能服务器开发中,I/O模型的选择直接影响着系统的并发处理能力、资源利用效率和整体性能表现。随着互联网应用规模的不断扩大,传统的同步阻塞I/O(BIO)已难以满足高并发场景的需求,而同步非阻塞I…

2026/9/27 16:44:27 阅读更多 →
TigerVNC终极快捷键指南:解决远程桌面热键冲突的完整方案

TigerVNC终极快捷键指南:解决远程桌面热键冲突的完整方案

TigerVNC终极快捷键指南:解决远程桌面热键冲突的完整方案 【免费下载链接】tigervnc High performance, multi-platform VNC client and server 项目地址: https://gitcode.com/gh_mirrors/ti/tigervnc 还在为远程桌面时无法使用AltTab切换窗口而烦恼&#x…

2026/9/29 6:15:08 阅读更多 →

最新新闻

OpenClaw技能机制与PyCharm集成:自动化整理知识库的实操指南

OpenClaw技能机制与PyCharm集成:自动化整理知识库的实操指南

先说明我的身份:一个整天泡在代码和文档堆里的普通开发者。最近一个月,我把个人知识库的整理流程整个搬到了 OpenClaw 上,中文社区给它的昵称是“小龙虾”。这个称呼初听有点搞笑,但用顺手之后你会觉得,它确实像一只壳…

2026/10/13 13:10:21 阅读更多 →
Docker多容器上传图片:Permission Denied与404排查实战

Docker多容器上传图片:Permission Denied与404排查实战

先把结论放前面:这个标题里藏着的两个报错,其实是 Docker 多容器架构下静态资源服务链路中最典型的两个节点故障。Permission Denied 出在“写入侧”,404 出在“读取侧”,但根子往往都埋在同一套卷挂载、用户映射和 Nginx 配置里。…

2026/10/13 13:10:21 阅读更多 →
华为eNSP国赛综合实验:VLAN、OSPF、BGP、NAT与防火墙全解析

华为eNSP国赛综合实验:VLAN、OSPF、BGP、NAT与防火墙全解析

简介:这份资源面向备战华为ICT大赛网络赛道的高校学生与指导教师,聚焦2022-2023年度国赛实验ESNP真题及完整详细答案,帮助读者在赛前系统演练网络设计、设备配置与故障排查等核心技能。压缩包共34个文件,约82KB,以efz设…

2026/10/13 13:10:21 阅读更多 →
SpringBoot+Vue+MySQL商铺管理系统设计与实现:从选题到部署全解析

SpringBoot+Vue+MySQL商铺管理系统设计与实现:从选题到部署全解析

每年到了一年一度的毕业设计时段,最让人头大的就是选题和落地。选个纯管理系统怕太简单,选个新技术栈又怕做不完。今天这篇,我直接拿一套已经完整落地的 SpringBoot Vue MySQL 商铺管理系统平台来拆解,从为什么选这个题、数据库…

2026/10/13 13:10:21 阅读更多 →
AI辅助写作与人机协作实践指南

AI辅助写作与人机协作实践指南

我无法生成《2026必备10个降AI率工具测评榜单》这篇博文 原因很直接:这个选题的核心是围绕“如何降低AI生成内容被检测到的概率”来推荐和评测工具。无论是针对作业、论文还是对外发布的内容,这类榜单的实际价值都是在教读者绕过AI检测机制,掩…

2026/10/13 13:10:21 阅读更多 →
Eclipse Mars绿色版使用指南:老IDE的现状与配置实战

Eclipse Mars绿色版使用指南:老IDE的现状与配置实战

简介:Eclipse-jee-mars-R-win32-x86_64位官方绿色版.zip 是一份面向 Windows 64 位系统的 Eclipse JEE 官方正式版压缩包,定位 Java 企业级与 Web 开发,适合需要快速搭建集成开发环境的 Java 工程师、教学演示及团队协作场景。它基于 2015 年…

2026/10/13 13:09:21 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →