# 程序流程图详解 - 从高中数学到实际开发
## 一、认识流程图符号
### 📐 基本图形符号
| 图形 | 名称 | 含义 | 示例 |
|------|------|------|------|
| ○ 椭圆 | **起止框** | 表示程序开始或结束 | "开始"、"结束" |
| ▭ 矩形 | **处理框** | 表示执行操作、计算 | "sum = sum + i"、"i++" |
| ◇ 菱形 | **判断框** | 表示条件判断,有多个分支 | "i <= 5?" |
| ▱ 平行四边形 | **输入输出框** | 表示数据输入或结果输出 | "打印结果"、"读取文件" |
| → 箭头 | **流程线** | 表示执行顺序 | ↓ → ← ↑ |
---
## 二、三种基本控制结构
### 1️⃣ **顺序结构** - 从上到下依次执行
```
┌─────────┐
│ 开始 │
└────┬────┘
↓
┌─────────┐
│ step1 │
└────┬────┘
↓
┌─────────┐
│ step2 │
└────┬────┘
↓
┌─────────┐
│ 结束 │
└─────────┘
```
**代码对应:**
```java
// 顺序执行
int sum = 0;
sum = sum + 1;
sum = sum + 2;
System.out.println(sum);
```
---
### 2️⃣ **选择结构(分支结构)** - 根据条件走不同路径
#### (1) 单分支:if
```
┌─────────┐
│ 条件? │
└────┬────┘
│
┌─────┴─────┐
│ │
Yes No
│ │
↓ │
┌──────┐ │
│ 执行 │ │
└──┬───┘ │
│ │
└────┬─────┘
↓
┌──────┐
│ 继续 │
└──────┘
```
**代码对应:**
```java
if (age >= 18) {
System.out.println("成年人");
}
// 不管是否成年,都会继续往下执行
```
#### (2) 双分支:if-else
```
┌─────────┐
│ 条件? │
└────┬────┘
│
┌─────┴─────┐
│ │
Yes No
│ │
↓ ↓
┌──────┐ ┌──────┐
│ 执行 A│ │ 执行 B│
└──┬───┘ └──┬───┘
│ │
└────┬─────┘
↓
┌──────┐
│ 继续 │
└──────┘
```
**代码对应:**
```java
if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
```
#### (3) 多分支:if-else if-else
```
┌──────────────┐
│ score >= 90? │
└──────┬───────┘
│
┌──────────┼──────────┐
Yes │ No
│ │ │
↓ │ ↓
┌──────────┐ │ ┌─────────────┐
│ 优秀 A │ │ │ score>=60? │
└────┬─────┘ │ └──────┬──────┘
│ │ │
│ ┌────┴─────┐ │
│ Yes No │
│ │ │ │
│ ↓ │ │
│ ┌──────────┐ │ │
│ │ 及格 C │ │ │
│ └────┬─────┘ │ │
│ │ │ │
│ │ ┌────┴─────┐
│ │ Yes No
│ │ │ │
│ │ ↓ ↓
│ │ ┌────────┐ ┌────────┐
│ │ │良好 B │ │不及格 D│
│ │ └────────┘ └────────┘
│ │ │ │
└──────┴─────┴───────────┘
↓
┌────────┐
│ 结束 │
└────────┘
```
**代码对应:**
```java
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else if (score >= 70) {
grade = "C";
} else if (score >= 60) {
grade = "D";
} else {
grade = "F";
}
```
---
### 3️⃣ **循环结构** - 重复执行某段代码
#### (1) while 循环(先判断后执行)
```
┌─────────┐
│ 开始 │
└────┬────┘
↓
┌─────────┐
┌───│ 条件? │
│ └────┬────┘
│ │
│ ┌────┴────┐
│ Yes No
│ │ │
│ ↓ │
│ ┌──────┐ │
│ │ 执行 │ │
│ └──┬───┘ │
│ │ │
└────┴────────┘
↓
┌──────┐
│ 结束 │
└──────┘
```
**代码对应:**
```java
while (i <= 5) {
sum += i;
i++;
}
```
#### (2) do-while 循环(先执行后判断)
```
┌─────────┐
│ 开始 │
└────┬────┘
↓
┌─────────┐
│ 执行 │
└────┬────┘
│
↓
┌─────────┐
┌───│ 条件? │
│ └────┬────┘
│ │
│ ┌────┴────┐
│ Yes No
│ │ │
└───┘ │
↓
┌──────┐
│ 结束 │
└──────┘
```
**代码对应:**
```java
do {
sum += i;
i++;
} while (i <= 5);
```
#### (3) for 循环(计数器循环)
```
┌──────────┐
│ 初始化 i │
└────┬─────┘
↓
┌──────────┐
┌───│ 条件判断 │
│ └────┬─────┘
│ │
│ ┌────┴────┐
│ Yes No
│ │ │
│ ↓ │
│ ┌──────┐ │
│ │ 执行 │ │
│ └──┬───┘ │
│ │ │
│ ↓ │
│ ┌──────┐ │
│ │ i++ │────┘
│ └──────┘
│
└─────────────┘
```
**代码对应:**
```java
for (int i = 0; i <= 5; i++) {
sum += i;
}
```
---
## 三、经典例题解析
### 例题 1:判断闰年
**需求:** 输入一个年份,判断是否为闰年
**流程图:**
```
┌──────────┐
│ 开始 │
└────┬─────┘
↓
┌──────────┐
│ 输入 year │
└────┬─────┘
↓
┌──────────────┐
│year%4==0? │
└──────┬───────┘
│
┌──────┴──────┐
Yes No
│ │
↓ │
┌─────────────┐ │
│year%100==0? │ │
└──────┬──────┘ │
│ │
┌────┴────┐ │
Yes No │
│ │ │
↓ │ │
┌─────────┐ │ │
│year%400?│ │ │
└────┬────┘ │ │
│ │ │
┌──┴──┐ │ │
Yes No │ │
│ │ │ │
↓ │ │ │
┌────┐ │ │ │
│是 │ │ │ │
└─┬──┘ │ │ │
│ ↓ ↓ ↓
│ ┌─────┐ ┌─────┐ ┌─────┐
│ │不是 │ │是 │ │不是 │
│ └─────┘ └─────┘ └─────┘
│ │ │ │
└─────┴──────┴──────┘
↓
┌─────────┐
│ 输出结果 │
└────┬────┘
↓
┌─────────┐
│ 结束 │
└─────────┘
```
**代码实现:**
```java
public class LeapYear {
public static void main(String[] args) {
int year = 2024;
if (year % 4 == 0) {
if (year % 100 == 0) {
if (year % 400 == 0) {
System.out.println(year + " 是闰年");
} else {
System.out.println(year + " 不是闰年");
}
} else {
System.out.println(year + " 是闰年");
}
} else {
System.out.println(year + " 不是闰年");
}
}
}
```
---
### 例题 2:计算 1-100 的和
**流程图:**
```
┌──────────┐
│ 开始 │
└────┬─────┘
↓
┌──────────┐
│ sum = 0 │
│ i = 1 │
└────┬─────┘
↓
┌──────────┐
┌───│ i <= 100?│
│ └────┬─────┘
│ │
│ ┌────┴────┐
│ Yes No
│ │ │
│ ↓ │
│ ┌──────────┐│
│ │sum=sum+i││
│ └────┬─────┘│
│ ↓ │
│ ┌──────────┐│
│ │ i = i+1 ││
│ └────┬─────┘│
│ │ │
└──────┴──────┘
↓
┌──────────┐
│输出 sum │
└────┬─────┘
↓
┌──────────┐
│ 结束 │
└──────────┘
```
**代码实现:**
```java
public class Sum1To100 {
public static void main(String[] args) {
int sum = 0;
int i = 1;
while (i <= 100) {
sum = sum + i;
i = i + 1;
}
System.out.println("1 到 100 的和:" + sum);
}
}
```
---
### 例题 3:成绩等级评定(综合应用)
**需求:**
- 90-100 分:优秀
- 80-89 分:良好
- 70-79 分:中等
- 60-69 分:及格
- 60 分以下:不及格
**流程图:**
```
┌──────────┐
│ 开始 │
└────┬─────┘
↓
┌──────────┐
│输入分数 s │
└────┬─────┘
↓
┌──────────┐
│ s > 100? │
└────┬─────┘
│
┌──────┴──────┐
Yes No
│ │
↓ ↓
┌─────────┐ ┌──────────┐
│输入错误 │ │ s >= 90? │
└────┬────┘ └────┬─────┘
│ │
│ ┌────┴────┐
│ Yes No
│ │ │
│ ↓ │
│ ┌─────────┐ │
│ │ 优秀 A │ │
│ └────┬────┘ │
│ │ │
│ │ ┌────┴────┐
│ │ Yes No
│ │ │ │
│ │ ↓ │
│ │ ┌─────────┐ │
│ │ │ 良好 B │ │
│ │ └────┬────┘ │
│ │ │ │
│ │ │ ┌──┴──┐
│ │ │ Yes No
│ │ │ │ │
│ │ │ ↓ │
│ │ │ ┌──────┐│
│ │ │ │... ││
│ │ │ └──────┘│
│ │ │ │ │
└────────┴──────┴────┴────┘
↓
┌─────────┐
│ 输出等级 │
└────┬────┘
↓
┌─────────┐
│ 结束 │
└─────────┘
```
**代码实现:**
```java
public class GradeEvaluator {
public static void main(String[] args) {
int score = 85;
String grade;
// 数据验证
if (score < 0 || score > 100) {
System.out.println("输入的成绩无效!");
return;
}
// 多分支判断
if (score >= 90) {
grade = "优秀 A";
} else if (score >= 80) {
grade = "良好 B";
} else if (score >= 70) {
grade = "中等 C";
} else if (score >= 60) {
grade = "及格 D";
} else {
grade = "不及格 F";
}
System.out.println("成绩等级:" + grade);
}
}
```
---
## 四、实际开发中的应用场景
### 🎯 场景 1:用户登录验证
```java
public boolean login(String username, String password) {
// 1. 验证输入是否为空
if (username == null || username.isEmpty()) {
System.out.println("用户名不能为空");
return false;
}
// 2. 验证密码长度
if (password.length() < 6) {
System.out.println("密码长度不能少于 6 位");
return false;
}
// 3. 查询数据库
User user = userDao.findByUsername(username);
if (user == null) {
System.out.println("用户不存在");
return false;
}
// 4. 验证密码
if (!user.getPassword().equals(password)) {
System.out.println("密码错误");
return false;
}
// 5. 检查账户状态
if (user.getStatus() == 0) {
System.out.println("账户已被冻结");
return false;
}
// 6. 登录成功
System.out.println("登录成功");
return true;
}
```
---
### 🎯 场景 2:订单状态流转
```java
public void processOrder(Order order) {
// 根据订单状态执行不同逻辑
switch (order.getStatus()) {
case PENDING: // 待支付
if (order.getPaymentTime() != null) {
order.setStatus(PAID);
sendNotification("支付成功");
}
break;
case PAID: // 已支付
if (order.getStock() > 0) {
order.setStatus(SHIPPED);
reduceStock(order.getProductId());
} else {
order.setStatus(REFUNDED);
refundPayment(order);
}
break;
case SHIPPED: // 已发货
if (order.getConfirmTime() != null) {
order.setStatus(COMPLETED);
addPoints(order.getUserId());
}
break;
default:
System.out.println("未知订单状态");
}
}
```
---
### 🎯 场景 3:权限校验(多层判断)
```java
public boolean checkPermission(User user, String resource) {
// 第一层:是否登录
if (user == null) {
return false;
}
// 第二层:是否激活
if (!user.isActive()) {
return false;
}
// 第三层:是否是管理员
if (user.isAdministrator()) {
return true; // 管理员拥有所有权限
}
// 第四层:检查具体权限
List<String> permissions = user.getPermissions();
if (permissions.contains(resource)) {
return true;
}
// 第五层:检查角色权限
for (Role role : user.getRoles()) {
if (role.hasPermission(resource)) {
return true;
}
}
return false;
}
```
---
## 五、画流程图的实用工具
### 1. **在线工具**
- **ProcessOn** - 国产在线画图工具,模板丰富
- **Draw.io** - 免费开源,功能强大
- **Lucidchart** - 专业流程图工具
### 2. **桌面软件**
- **Visio** - 微软出品,功能最全
- **XMind** - 思维导图为主,也支持流程图
- **亿图图示** - 国产软件,易上手
### 3. **代码生成工具**
```java
// 使用 PlantUML 在代码中画流程图
@startuml
start
:输入年份;
if (能被 4 整除?) then
if (能被 100 整除?) then
if (能被 400 整除?) then
:是闰年;
else
:不是闰年;
endif
else
:是闰年;
endif
else
:不是闰年;
endif
stop
@enduml
```
---
## 六、实战练习
### 练习 1:画出这个程序的流程图
```java
public int calculate(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
if (i % 2 == 0) {
sum += i;
} else {
sum -= i;
}
}
return sum;
}
```
### 练习 2:根据流程图写代码
```
┌──────────┐
│ 开始 │
└────┬─────┘
↓
┌──────────┐
│ i = 100 │
└────┬─────┘
↓
┌──────────┐
┌───│ i >= 1? │
│ └────┬─────┘
│ │
│ ┌────┴────┐
│ Yes No
│ │ │
│ ↓ │
│ ┌──────────┐│
│ │ 打印 i ││
│ └────┬─────┘│
│ ↓ │
│ ┌──────────┐│
│ │ i = i-2 ││
│ └────┬─────┘│
│ │ │
└──────┴──────┘
↓
┌──────────┐
│ 结束 │
└──────────┘
```
**问题:** 这个程序会输出什么?
---
## 七、面试常见问题
### Q1: 如何向非技术人员解释复杂业务逻辑?
**回答技巧:**
> "我会先画出流程图,用图形化的方式展示整个业务流程。流程图中的菱形代表判断点,矩形代表操作步骤,这样即使不懂技术的人也能看懂业务是如何流转的。比如在电商系统中,订单从创建到完成会经历哪些状态变化,每个状态需要什么条件,通过流程图一目了然。"
### Q2: 设计一个复杂的业务逻辑,你会怎么做?
**满分回答:**
> "我的步骤是:
> 1. **需求分析**:明确输入、输出和处理规则
> 2. **绘制流程图**:先用图形梳理清楚逻辑分支
> 3. **伪代码编写**:用注释写出大致框架
> 4. **逐步实现**:按照流程图逐个实现每个分支
> 5. **测试验证**:覆盖所有分支路径
>
> 比如之前做过的一个权限系统,有用户、角色、资源三层关系,我先画了完整的状态流转图,再编码实现,最后测试覆盖了所有 27 种组合场景,确保没有遗漏。"
---
## 八、快速记忆口诀
```
椭圆表示开始停,矩形处理做事情
菱形判断分岔路,平行四边输和出
箭头连接指示向,从上到下不能忘
顺序选择和循环,三种结构走天下
```
---
## 九、总结提升
### ✅ **掌握要点**
1. **认识符号** - 5 种基本图形的含义
2. **三种结构** - 顺序、选择、循环
3. **看图写码** - 能将流程图转为代码
4. **画图设计** - 能用流程图设计业务逻辑
### 🎯 **进阶建议**
1. **多画图** - 遇到复杂逻辑先画流程图
2. **多练习** - 找一些经典题目反复练习
3. **多思考** - 看别人的代码时,尝试画出它的流程图
4. **多应用** - 在实际项目中用流程图做设计文档
---
**记住:** 流程图是程序员的基本功,掌握了它,你的逻辑思维能力和代码设计能力都会有质的飞跃!加油!💪