第一部分:程序执行流程概述
1. 程序的三种基本结构
Q: 程序的三种基本执行结构是什么?各自的特点和应用场景是什么?
A:
| 结构 | 特点 | 应用场景 |
|---|---|---|
| 顺序结构 | 代码从上到下依次执行 | 默认执行方式 |
| 分支结构 | 根据条件选择执行不同代码 | 需要判断决策的场景 |
| 循环结构 | 重复执行某段代码 | 需要重复操作的场景 |
// 顺序结构:默认执行方式
System.out.println("第一步");
System.out.println("第二步"); // 必须等第一步执行完才执行
// 分支结构:根据条件选择
int age = 20;
if (age >= 18) {
System.out.println("成年人"); // 条件满足才执行
} else {
System.out.println("未成年人");
}
// 循环结构:重复执行
for (int i = 0; i < 3; i++) {
System.out.println("第" + i + "次执行"); // 重复3次
}
第二部分:分支结构
2. if分支的三种格式
Q: if分支有哪三种格式?各自的语法和执行流程是什么?
A:
格式1:单分支(只做判断,不满足就跳过)
if (条件表达式) {
语句体; // 条件为true时执行
}
格式2:双分支(二选一)
if (条件表达式) {
语句体1; // 条件为true时执行
} else {
语句体2; // 条件为false时执行
}
格式3:多分支(多选一)
if (条件表达式1) {
语句体1;
} else if (条件表达式2) {
语句体2;
} else if (条件表达式3) {
语句体3;
} else {
语句体n+1; // 以上都不满足时执行
}
public class IfDemo {
public static void main(String[] args) {
// 格式1:体温监测
double temp = 37.5;
if (temp > 37.3) {
System.out.println("体温异常,需要隔离"); // 满足条件才执行
}
// 格式2:发红包判断
double money = 99;
if (money >= 90) {
System.out.println("发红包成功");
} else {
System.out.println("余额不足"); // 99<90,执行这里
}
// 格式3:绩效评级(多分支)
int score = 85;
if (score >= 90 && score <= 100) {
System.out.println("A级");
} else if (score >= 80 && score < 90) {
System.out.println("B级"); // 85满足这个条件
} else if (score >= 60 && score < 80) {
System.out.println("C级");
} else {
System.out.println("D级");
}
}
}
3. if语句的注意事项
Q: 使用if语句时有哪些常见注意事项?
A:
| 注意事项 | 说明 | 示例 |
|---|---|---|
| if后不能加分号 | if();会导致条件失效 |
if (a > 0); { ... } // 错误! |
| 单语句可省略大括号 | 只有一行代码时可以省略 | if (a > 0) System.out.println("正数"); |
| 多条件注意范围顺序 | 范围判断要从大到小或从小到大 | 先判断>=90,再判断>=80 |
public class IfNotice {
public static void main(String[] args) {
// 错误示例1:if后加分号
int a = 10;
// if (a > 5); { // 分号导致if语句结束,大括号变成独立代码块
// System.out.println("这行总会执行");
// }
// 正确写法
if (a > 5) {
System.out.println("a大于5");
}
// 单语句可省略大括号(不推荐,易出错)
if (a > 5)
System.out.println("a大于5"); // 只有这一行属于if
// 多条件顺序问题(错误示例)
int score = 95;
// 错误顺序:先判断>=60,95满足,直接输出C,不会判断后面的
// if (score >= 60) { System.out.println("C"); }
// else if (score >= 80) { System.out.println("B"); }
// else if (score >= 90) { System.out.println("A"); }
// 正确顺序:从大到小
if (score >= 90) {
System.out.println("A"); // 95满足,正确输出A
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 60) {
System.out.println("C");
}
}
}
4. switch分支结构
Q: switch分支的语法格式是什么?与if分支有什么区别?
A: switch语法:
switch (表达式) {
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
默认语句体;
}
switch vs if:
| 特性 | switch | if |
|---|---|---|
| 判断方式 | 等值判断(==) | 范围判断、等值判断都可以 |
| 表达式类型 | byte/short/int/char/String/枚举 | 任意boolean表达式 |
| 可读性 | 多等值判断时更清晰 | 通用性更强 |
| 性能 | 底层有优化(跳转表) | 逐个条件判断 |
public class SwitchDemo {
public static void main(String[] args) {
// switch适合做等值判断
String week = "周三";
switch (week) {
case "周一":
System.out.println("埋头苦干,解决bug");
break;
case "周二":
System.out.println("请求大牛程序员帮忙");
break;
case "周三":
System.out.println("今晚啤酒、龙虾、小烧烤"); // 匹配这个
break;
case "周四":
System.out.println("主动帮助新来的程序员");
break;
case "周五":
System.out.println("今晚吃鸡");
break;
case "周六":
case "周日":
System.out.println("休息打游戏");
break;
default:
System.out.println("输入不合法");
}
}
}
5. switch的注意事项与case穿透
Q: switch有哪些注意事项?什么是case穿透?如何利用穿透特性?
A: 注意事项:
- 表达式类型只能是
byte、short、int、char、String(JDK7+)、枚举 - 不支持:
long、float、double、boolean - case值必须是字面量,不能是变量,且不能重复
- 不要忘记
break,否则会出现穿透现象
case穿透:没有break时,会继续执行下一个case,直到遇到break或switch结束。
public class SwitchNotice {
public static void main(String[] args) {
// 错误示例:不支持double
// double d = 1.5;
// switch (d) { } // 编译报错!
// 错误示例:case值不能是变量
int a = 10;
int b = 10;
// switch (a) {
// case b: // 编译报错!case必须是字面量
// }
// case穿透现象(忘记break)
int num = 1;
switch (num) {
case 1:
System.out.println("一"); // 会执行
case 2:
System.out.println("二"); // 也会执行(穿透)
case 3:
System.out.println("三"); // 也会执行(穿透)
break; // 这里才停止
case 4:
System.out.println("四"); // 不会执行
}
// 输出:一 二 三
// 利用穿透特性简化代码(多个case执行相同逻辑)
String week = "周二";
switch (week) {
case "周一":
System.out.println("工作日-解决bug");
break;
case "周二":
case "周三":
case "周四": // 周二、三、四都执行同一个逻辑
System.out.println("工作日-请求大牛帮忙");
break;
case "周五":
System.out.println("工作日-准备下班");
break;
case "周六":
case "周日": // 周六、日都执行同一个逻辑
System.out.println("休息日-打游戏");
break;
}
}
}
6. if与switch的选择原则
Q: 什么时候用if,什么时候用switch?
A:
| 场景 | 推荐 | 原因 |
|---|---|---|
| 范围判断(如成绩等级、年龄分段) | if | switch只能做等值判断 |
| 等值判断且值不多(如星期、月份、菜单选项) | switch | 代码更清晰,性能更好 |
| 复杂条件(多个条件组合) | if | switch无法表达复杂条件 |
public class ChooseDemo {
public static void main(String[] args) {
// 场景1:范围判断 - 必须用if
int score = 85;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
}
// 不能用switch,因为score是一个范围,不是固定值
// 场景2:等值判断 - 推荐用switch
int month = 3;
switch (month) {
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
}
// 用if也可以,但switch更清晰
// if (month == 3 || month == 4 || month == 5) { ... }
}
}
第三部分:循环结构
7. for循环
Q: for循环的语法格式和执行流程是什么?适用场景是什么?
A: 语法格式:
for (初始化语句; 循环条件; 迭代语句) {
循环体; // 重复执行的代码
}
执行流程:
- 执行初始化语句(只执行1次)
- 判断循环条件,为true则执行循环体,为false则结束循环
- 执行循环体
- 执行迭代语句
- 回到第2步,重复直到条件为false
适用场景:已知循环次数的场景
public class ForDemo {
public static void main(String[] args) {
// 基础示例:输出5次HelloWorld
for (int i = 0; i < 5; i++) {
System.out.println("HelloWorld " + i);
}
// 执行流程:
// i=0, 0<5为true, 输出HelloWorld 0, i变成1
// i=1, 1<5为true, 输出HelloWorld 1, i变成2
// i=2, 2<5为true, 输出HelloWorld 2, i变成3
// i=3, 3<5为true, 输出HelloWorld 3, i变成4
// i=4, 4<5为true, 输出HelloWorld 4, i变成5
// i=5, 5<5为false, 循环结束
// IDEA快捷键:
// 5.fori 生成:for (int i = 0; i < 5; i++)
// 5.forr 生成:for (int i = 5; i > 0; i--) 倒序
// 实际应用:求1-100的和
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i; // 累加
}
System.out.println("1-100的和:" + sum); // 5050
}
}
8. for循环案例:求奇数和(两种方案)
Q: 如何用for循环求1-10的奇数和?两种方案有什么区别?
A:
方案1:遍历所有数,判断奇偶
int sum = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 != 0) { // 判断是否为奇数
sum += i;
}
}
方案2:直接遍历奇数(性能更好)
int sum = 0;
for (int i = 1; i <= 10; i += 2) { // 每次加2,直接得到奇数
sum += i;
}
public class OddSumDemo {
public static void main(String[] args) {
// 方案1:遍历判断(循环10次)
int sum1 = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 == 1) { // 奇数判断
sum1 += i;
}
}
System.out.println("方案1结果:" + sum1); // 25
// 方案2:直接遍历奇数(循环5次,性能更好)
int sum2 = 0;
for (int i = 1; i <= 10; i += 2) { // i=1,3,5,7,9
sum2 += i;
}
System.out.println("方案2结果:" + sum2); // 25
// 结论:方案2循环次数少,性能更好
}
}
9. for循环案例:水仙花数
Q: 什么是水仙花数?如何用程序找出所有水仙花数?
A: 水仙花数:一个三位数,其个位、十位、百位的数字立方和等于原数。
例如:153 = 1³ + 5³ + 3³ = 1 + 125 + 27 = 153
数字拆分公式:
- 个位:
num % 10 - 十位:
num / 10 % 10 - 百位:
num / 100
public class NarcissisticDemo {
public static void main(String[] args) {
// 遍历所有三位数(100-999)
for (int i = 100; i <= 999; i++) {
// 拆分各位数字
int ge = i % 10; // 个位
int shi = i / 10 % 10; // 十位
int bai = i / 100; // 百位
// 判断是否为水仙花数
// 方式1:直接计算
if (ge * ge * ge + shi * shi * shi + bai * bai * bai == i) {
System.out.print(i + " "); // 153 370 371 407
}
// 方式2:使用Math.pow(更优雅)
// if (Math.pow(ge, 3) + Math.pow(shi, 3) + Math.pow(bai, 3) == i) {
// System.out.print(i + " ");
// }
}
// 输出:153 370 371 407
}
}
10. while循环
Q: while循环的语法格式是什么?与for循环有什么区别?
A: 语法格式:
初始化语句;
while (循环条件) {
循环体;
迭代语句;
}
while vs for:
| 特性 | for | while |
|---|---|---|
| 适用场景 | 已知循环次数 | 未知循环次数(条件控制) |
| 结构 | 三要素(初始化、条件、迭代)在一起 | 三要素分散 |
| 可读性 | 次数明确时更清晰 | 条件复杂时更清晰 |
public class WhileDemo {
public static void main(String[] args) {
// 基础示例:输出5次HelloWorld
int i = 0; // 初始化
while (i < 5) { // 条件判断
System.out.println("HelloWorld " + i);
i++; // 迭代
}
// 经典场景:未知次数的循环(复利计算)
// 本金10万,年利率1.7%,多少年能翻倍?
double money = 100000;
double target = 200000;
double rate = 0.017;
int year = 0;
while (money < target) { // 不知道要循环几次,用while
money = money * (1 + rate);
year++;
}
System.out.println(year + "年后本金翻倍,达到:" + money);
// 输出:42年后本金翻倍...
}
}
11. do-while循环
Q: do-while循环的语法和特点是什么?与while有什么区别?
A: 语法格式:
初始化语句;
do {
循环体;
迭代语句;
} while (循环条件); // 注意分号!
核心特点:先执行,后判断 → 循环体至少执行1次
do-while vs while:
| 特性 | while | do-while |
|---|---|---|
| 执行顺序 | 先判断,后执行 | 先执行,后判断 |
| 最少执行次数 | 0次(条件不满足) | 1次(至少执行一次) |
| 使用频率 | 更常用 | 较少使用 |
public class DoWhileDemo {
public static void main(String[] args) {
// 基础示例:输出5次HelloWorld
int i = 0;
do {
System.out.println("HelloWorld " + i);
i++;
} while (i < 5);
// 关键区别:条件不满足时也会执行一次
int a = 10;
while (a < 5) {
System.out.println("while不会执行");
}
do {
System.out.println("do-while会执行一次"); // 这行会输出!
} while (a < 5);
// 应用场景:至少执行一次的菜单选择
// Scanner sc = new Scanner(System.in);
// int choice;
// do {
// System.out.println("1.查询 2.添加 3.退出");
// choice = sc.nextInt();
// // 处理选择...
// } while (choice != 3); // 选择3才退出,至少显示一次菜单
}
}
12. 三种循环的选择与对比
Q: for、while、do-while三种循环如何选择?
A:
| 循环类型 | 选择原则 | 典型场景 |
|---|---|---|
| for | 已知循环次数 | 遍历数组、累加1-100、打印9行数据 |
| while | 未知循环次数,可能0次 | 猜数字游戏、等待用户输入、复利计算 |
| do-while | 至少执行1次 | 菜单选择、至少执行一次的业务逻辑 |
public class LoopCompare {
public static void main(String[] args) {
// for:已知次数(打印9*9乘法表)
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + (i*j) + "\t");
}
System.out.println();
}
// while:未知次数(猜数字直到猜中)
Random random = new Random();
int target = random.nextInt(100) + 1;
Scanner sc = new Scanner(System.in);
int guess;
while (true) { // 不知道要猜几次
System.out.print("请输入猜测:");
guess = sc.nextInt();
if (guess == target) {
System.out.println("猜中了!");
break;
}
}
// do-while:至少执行一次
String password;
do {
System.out.print("请输入密码(至少6位):");
password = sc.next();
} while (password.length() < 6); // 密码不足6位,重新输入
}
}
13. 死循环
Q: 什么是死循环?常见的死循环写法有哪些?什么场景下会使用死循环?
A: 死循环:循环条件永远为true,循环永远不会自动结束。
常见写法:
for (;;) { } // for死循环
while (true) { } // while死循环(最常用)
do { } while (true); // do-while死循环
使用场景:需要一直运行直到满足特定退出条件(如用户选择退出、程序中断等),通常配合 break使用。
public class DeadLoopDemo {
public static void main(String[] args) {
// 猜数字游戏:不知道要猜几次,用死循环+break
Random random = new Random();
int target = random.nextInt(100) + 1;
Scanner sc = new Scanner(System.in);
while (true) { // 死循环
System.out.print("请输入猜测(1-100):");
int guess = sc.nextInt();
if (guess > target) {
System.out.println("猜大了");
} else if (guess < target) {
System.out.println("猜小了");
} else {
System.out.println("猜对了!");
break; // 猜中后跳出死循环
}
}
// 服务器程序:一直运行提供服务
// while (true) {
// 接收客户端请求();
// 处理请求();
// // 除非服务器关闭,否则一直运行
// }
}
}
14. 嵌套循环
Q: 什么是嵌套循环?执行流程是怎样的?
A: 嵌套循环:一个循环体内包含另一个循环。
执行流程:外层循环执行1次,内层循环执行完整的一轮。
public class NestedLoopDemo {
public static void main(String[] args) {
// 基础示例:外层3次,内层5次,共输出15次
for (int i = 0; i < 3; i++) { // 外层循环
System.out.println("--- 外层第" + i + "次 ---");
for (int j = 0; j < 5; j++) { // 内层循环
System.out.println("内层第" + j + "次");
}
}
// 执行流程:
// i=0: 输出"外层第0次",然后j从0到4执行5次
// i=1: 输出"外层第1次",然后j从0到4执行5次
// i=2: 输出"外层第2次",然后j从0到4执行5次
// 经典案例:打印4行5列的矩形
for (int row = 1; row <= 4; row++) { // 控制行
for (int col = 1; col <= 5; col++) { // 控制列
System.out.print("* "); // 打印星星,不换行
}
System.out.println(); // 每行结束换行
}
// 输出:
// * * * * *
// * * * * *
// * * * * *
// * * * * *
// 经典案例:九九乘法表
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) { // 内层循环到i,形成三角形
System.out.print(j + "*" + i + "=" + (i*j) + "\t");
}
System.out.println();
}
}
}
第四部分:跳转关键字
15. break和continue
Q: break和continue的作用是什么?有什么区别?
A:
| 关键字 | 作用 | 使用场景 |
|---|---|---|
| break | 结束当前所在循环或switch分支 | 找到结果后提前退出、满足条件终止循环 |
| continue | 结束本次循环,进入下一次循环 | 跳过某些特定条件的迭代 |
public class BreakContinueDemo {
public static void main(String[] args) {
// break示例:找到第一个能被7整除的数
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0) {
System.out.println("第一个能被7整除的数:" + i); // 7
break; // 找到后立即退出循环,不再继续
}
}
// continue示例:打印1-10,跳过4
for (int i = 1; i <= 10; i++) {
if (i == 4) {
continue; // 跳过i=4的这次循环,直接进入i=5
}
System.out.print(i + " "); // 1 2 3 5 6 7 8 9 10
}
System.out.println();
// 组合使用:打印1-10,跳过4,遇到8停止
for (int i = 1; i <= 10; i++) {
if (i == 4) {
continue; // 跳过4
}
if (i == 8) {
break; // 遇到8,结束循环
}
System.out.print(i + " "); // 1 2 3 5 6 7
}
}
}
第五部分:综合案例
16. Random随机数生成
Q: Java中如何生成随机数?如何生成指定范围的随机数?
A: 两种方式:
- Random类(推荐):
random.nextInt(bound)生成[0, bound)的整数 - Math.random():生成
[0.0, 1.0)的double
指定范围公式:[m, n]范围的随机数 = random.nextInt(n - m + 1) + m
import java.util.Random;
public class RandomDemo {
public static void main(String[] args) {
Random random = new Random();
// 方式1:Random类
int num1 = random.nextInt(100); // [0, 100) 包含0,不包含100
int num2 = random.nextInt(100) + 1; // [1, 101) 即 [1, 100]
// JDK17+支持直接指定范围 [1, 100)
// int num3 = random.nextInt(1, 100);
// 生成[65, 90]的随机数(ASCII码A-Z)
int ascii = random.nextInt(26) + 65; // [0, 26) + 65 = [65, 91) = [65, 90]
System.out.println((char) ascii); // 随机输出A-Z
// 方式2:Math.random() [0.0, 1.0)
double d = Math.random(); // 0.0 <= d < 1.0
// 转换为[1, 100]
int num3 = (int)(Math.random() * 100) + 1;
// Math.random() * 100 -> [0.0, 100.0)
// (int) -> [0, 99]
// + 1 -> [1, 100]
}
}
17. 猜数字游戏(综合案例)
Q: 如何实现一个完整的猜数字游戏?涉及哪些知识点?
A: 涉及知识点:
- Random生成随机数
- Scanner接收用户输入
- while死循环持续猜测
- if分支判断大小
- break退出循环
import java.util.Random;
import java.util.Scanner;
public class GuessNumberGame {
public static void main(String[] args) {
// 1. 生成1-100的随机数
Random random = new Random();
int target = random.nextInt(100) + 1; // [1, 100]
Scanner sc = new Scanner(System.in);
int count = 0; // 记录猜测次数
System.out.println("=== 猜数字游戏 ===");
System.out.println("我已经想好了一个1-100之间的数字,请猜!");
// 2. 死循环让用户一直猜
while (true) {
System.out.print("请输入你的猜测:");
int guess = sc.nextInt();
count++;
// 3. 判断猜测结果
if (guess > target) {
System.out.println("猜大了!再试试");
} else if (guess < target) {
System.out.println("猜小了!再试试");
} else {
System.out.println("恭喜你,猜对了!");
System.out.println("你一共猜了" + count + "次");
break; // 猜对后退出循环
}
}
sc.close();
}
}
18. Debug调试技术
Q: 什么是Debug?如何使用IDEA进行Debug调试?
A: Debug(调试):通过工具控制程序逐行执行,观察变量值变化,帮助发现和修复问题。
IDEA Debug步骤:
- 设置断点:在代码行号左侧单击,出现红色圆点
- Debug启动:点击Debug按钮(绿色甲虫图标)
- 单步执行:
- Step Over (F8):执行当前行,不进入方法
- Step Into (F7):进入方法内部
- Step Out (Shift+F8):跳出当前方法
- Resume (F9):运行到下一个断点
public class DebugDemo {
public static void main(String[] args) {
// 在此行设置断点,观察sum的变化过程
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i; // 设置断点,观察每次循环sum和i的值
// i=1, sum=1
// i=2, sum=3
// i=3, sum=6
// i=4, sum=10
// i=5, sum=15
}
System.out.println("最终结果:" + sum);
// Debug技巧:
// 1. 在循环内设置断点,观察每次迭代的变化
// 2. 使用条件断点(右键断点设置条件,如 i == 3)
// 3. 查看Variables面板,实时监控所有变量
}
}