原则:能写代码是入门,能交付上线是合格,能自动化是优秀。 Git + Docker + CI/CD = 现代软件工程的三根支柱。
一、Git 版本控制(★★★★★)
1.1 Git Flow 工作流
分支模型:
main / master → 生产环境代码(只接受 merge,不直接 commit)
develop → 开发主线
feature/xxx → 功能分支(从 develop 分出,完成后 merge 回 develop)
release/x.x.x → 发布分支(从 develop 分出,bugfix 后合入 main + develop)
hotfix/xxx → 紧急修复(从 main 分出,修复后合入 main + develop)1.2 merge vs rebase
merge:
main ← feature
保留完整分支历史,产生一个 merge commit
历史图:分叉 → 合并点
rebase:
feature 的提交"嫁接"到 main 最新提交之后
历史变成一条直线,更整洁
不要 rebase 已推送的公共分支(黄金法则)
场景选型:
- 合并公共分支到当前分支 → rebase(保持历史干净)
- 合并 feature 到公共分支 → merge(保留上下文,方便追溯)1.3 高级操作
git cherry-pick <commit-hash>
挑选特定提交应用到当前分支(修了一个 Bug 要同步到多个版本分支)
git stash
暂存当前修改,切换分支处理紧急任务,回来 git stash pop 恢复
git rebase -i HEAD~3
交互式合并最近 3 个提交(squash/fixup:合并小提交为大提交)
git reflog
查看所有 HEAD 操作记录(找回误删的分支/commit)
git bisect
二分查找引入 Bug 的提交(自动化定位问题 commit)1.4 团队协作规范
Commit Message 规范(Conventional Commits):
<type>(<scope>): <subject>
类型:
- feat: 新功能
- fix: Bug 修复
- refactor: 重构(不改变功能)
- docs: 文档变更
- test: 测试相关
- chore: 构建/工具变更
示例:
feat(order): 添加订单超时取消功能
fix(auth): 修复 JWT Token 刷新时的并发问题
refactor(user): 提取用户校验逻辑到 UserValidator
Code Review 要点:
- 每个 PR 保持 < 400 行变更
- 关注逻辑正确性 > 代码风格(风格交给 linter)
- 提问代替指责:"这里考虑过 XX 情况吗?"二、Docker 容器化(★★★★☆)
2.1 Dockerfile 最佳实践
# 多阶段构建:编译阶段 + 运行阶段分离
FROM maven:3.8-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline # 利用缓存,只下载依赖
COPY src ./src
RUN mvn package -DskipTests
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
USER 1000 # 非 root 用户运行
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]优化要点:
- 多阶段构建:编译阶段用大镜像,运行阶段用最小镜像(alpine/slim)
- 分层缓存:先 COPY 不常变的文件(如 pom.xml),再 COPY 源码
.dockerignore:排除 target/、.git/ 等无关文件- 非 root 用户运行:减少安全风险
2.2 Docker Compose
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7-alpine
ports:
- "6379:6379"
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydb
SPRING_REDIS_HOST: redis
volumes:
mysql_data:2.3 Kubernetes 核心概念
Pod:最小部署单元(1 个或多个容器共享网络/存储)
Deployment:管理 Pod 副本数 + 滚动更新 + 回滚
Service:为 Pod 提供稳定的网络入口(ClusterIP/NodePort/LoadBalancer)
ConfigMap:非敏感配置的外部化
Secret:敏感信息(密码/Token)的外部化
Ingress:HTTP/HTTPS 路由到 Service
滚动更新:新版本 Pod 逐步替换旧版本,保证服务不中断
maxSurge=25%:最多额外创建 25% 新 Pod
maxUnavailable=25%:最多 25% Pod 不可用三、CI/CD 持续集成(★★★☆☆)
3.1 Jenkins Pipeline(声明式)
pipeline {
agent any
stages {
stage('Checkout') {
steps { git url: 'https://github.com/xxx/project.git' }
}
stage('Build') {
steps { sh 'mvn clean compile' }
}
stage('Test') {
steps { sh 'mvn test' }
}
stage('Static Analysis') {
steps { sh 'mvn sonar:sonar' }
}
stage('Package') {
steps { sh 'mvn package -DskipTests' }
}
stage('Docker Build & Push') {
steps {
sh 'docker build -t registry.example.com/app:${BUILD_NUMBER} .'
sh 'docker push registry.example.com/app:${BUILD_NUMBER}'
}
}
stage('Deploy') {
steps {
sh 'kubectl set image deployment/app app=registry.example.com/app:${BUILD_NUMBER}'
}
}
}
post {
failure { emailext to: '[email protected]', subject: 'Pipeline Failed' }
}
}3.2 Maven 依赖管理
依赖冲突解决:
mvn dependency:tree 查看完整依赖树
<exclusions> 排除传递依赖中的冲突包
版本管理:
<dependencyManagement> 统一声明版本,子模块不写版本号
BOM(Bill of Materials)Spring Boot 的 spring-boot-dependencies
多模块项目:
parent-module/
├── pom.xml(packaging: pom)
├── common-module/
├── service-module/
└── web-module/四、代码质量
4.1 SonarQube 质量门禁
默认质量门禁(Quality Gate):
- 新增代码覆盖率 < 80% → 不通过
- 新增代码重复率 > 3% → 不通过
- 阻断级别的 Bug > 0 → 不通过
- 安全漏洞评级 A 以下 → 不通过
本地检查插件:SonarLint(IDE 内实时提示)4.2 单元测试策略
测试金字塔:
/\
/E2E\ 少量端到端测试(关键流程)
/------\
/集成测试\ 中等数量(API + 数据库)
/----------\
/ 单元测试 \ 大量(每个方法/分支)
/--------------\
JUnit 5 + Mockito 核心用法:
- @Mock:创建 Mock 对象
- @InjectMocks:将 Mock 注入到被测试对象
- when().thenReturn():定义 Mock 行为
- verify():验证 Mock 方法被调用
- assertThrows():验证异常抛出
Mock 原则:
- 不 Mock 值对象(DTO/Entity)
- 不 Mock 不属于自己的类
- Mock 外部依赖(数据库、RPC、MQ)面试自查清单
□ Git merge vs rebase 的区别 + rebase 黄金法则
□ Docker 镜像分层缓存原理(为什么先 COPY pom.xml)
□ K8s Deployment 滚动更新 maxSurge/maxUnavailable 的含义
□ 多阶段构建的价值(编译镜像 vs 运行镜像大小对比)
□ SonarQube 质量门禁包含哪几项指标
□ 单元测试金字塔各层的比例和关注点
□ Maven dependencyManagement 和 dependencies 的区别