2:数据类型、控制流与异常处理
在这一任务中,你将从“会写语法”逐步走到“会组织逻辑、会设计数据、会处理异常”,具备继续深入 Java 后端的基础能力☆: .。. o(≧▽≦)o .。.:☆
- Task 1、Task 2较为基础。
- Task 3、Task 4 更偏进阶。
- 本题重视“思路说明”。不要只贴最终代码,尽量说明你为什么这样写。
Task 1. 数据类型与运算基础
Section titled “Task 1. 数据类型与运算基础”请先完成下面几组基础问题:
- Java 的八种基本数据类型分别是什么?
- 四种整型类型各占多少字节,表示范围大致是多少?
- 解释基本类型与引用类型的区别。
观察并回答下面这段代码:
int a = 4;char c = '0';int b = a + c;- 这里发生的是隐式类型转换还是显式类型转换?
- b 的值是多少?请解释为什么。
再执行下面这段代码:
int a = 5;int b = 7;int c = (++a) + (b++);System.out.println(c);System.out.println(a + " " + b);- 写出运行结果,并解释每一步计算过程。
- 为什么“两个正数相加结果可能变成负数”?请从二进制存储和溢出的角度解释。
- float 为什么可能出现精度问题?你可以简单说明,不要求推导完整标准。
如果你愿意进一步挑战,可以再解释一下包装类和缓存池:
Integer x = new Integer(18);Integer y = new Integer(18);System.out.println(x == y);
Integer z = Integer.valueOf(18);Integer k = Integer.valueOf(18);System.out.println(z == k);
Integer m = Integer.valueOf(300);Integer p = Integer.valueOf(300);System.out.println(m == p);Task 2. 控制流与基础算法
Section titled “Task 2. 控制流与基础算法”程序不是顺着一行一行机械执行就够了,我们还需要控制它“在什么条件下做什么事”。
你一定见过以下流程图:
流程图是对现实问题解决方案的抽象,一个操作有了流程图,就能被写成程序,为了能控制程序如何运行,我们需要学习流程控制。
2.1 if-else 与 switch
Section titled “2.1 与 ”请补全下面的函数:
// 判断传入年份是否为闰年boolean isLeapYear(int year) {
}完成后请再回答:
- switch-case 和 if-else 的适用场景分别是什么?
- 有人说 switch-case 是 if-else 的“语法糖”,你是否同意?请说出你的理由。
2.2 循环
Section titled “2.2 循环”请补全下面的函数,打印一个高度为 n 的空心菱形,保证 n 为奇数:
// 例如 n = 5 时,输出:// *// * *// * *// * *// *void print(int n) {
}2.3 递归与迭代
Section titled “2.3 递归与迭代”请分别用递归和迭代两种方式实现斐波那契数列:
int fibonacci(int n) {
}并回答:
- 递归和迭代的核心区别是什么?
- 为什么很多场景下更偏好迭代?
- 循环是否总能被递归取代?如果能,代价是什么?
如果你想继续挑战,可以尝试完成汉诺塔:
通过if-else,for-while等等能够对程序进行简单的流程控制,下面的问题是一个名为汉诺塔的游戏。现在有A,B,C三个柱子,在A柱上有n块铁饼,现在要把A柱上的n块铁饼都移动到C柱上,请补全函数,使得函数打印出移动的过程。要求给出你代码的具体思路,可以写在文档或者代码注释中(这题对初学的同学可能会有一定挑战性,可以先跳过等后回来做)
// n = 3 时,输出:// A->C// A->B// C->B// A->C// B->A// B->C// A->Cvoid hanoi(int n) {
}Task 3. 异常处理与程序健壮性
Section titled “Task 3. 异常处理与程序健壮性”当你写好了代码 IDE检查没有语法错误 仔细检查过没有bug 程序一开始也能正常运行 是否就意味着万事大吉了呢?
当然不是 程序在运行的过程中会遇到很多不确定的情况 比如程序试图打开一个不存在的文件 程序遇到了网络连接问题 程序在运算时把0作为了除数 等等等等
请先回答两个概念问题:
- Error 和 Exception 的区别是什么?面对它们时,程序的处理态度应该有什么不同?
- checked exception 和 unchecked exception 的区别是什么?它们通常分别由什么原因引起?
然后完成下面这道题:
题目:读取文件并计算平均值
Section titled “题目:读取文件并计算平均值”编写一个 Java 程序,完成以下功能:
- 从当前目录下读取一个名为 data.txt 的文本文件。(PS:这里涉及到些许io流的相关知识,点击查看 Java05 内容)
- 文件中每一行包含一个整数,程序需要计算这些整数的平均值。
- 需要正确处理以下异常情况:
- 文件不存在
- 文件为空
- 文件中出现无法解析为整数的内容
- 无论是否发生异常,都要保证文件资源被正确关闭。
要求:
- 创建自定义异常类 EmptyFileException。
- 使用 try-with-resources 或 finally 管理资源。
- 给出合理的异常提示,不要让程序无声失败。
如果你已经学过方法设计,可以把逻辑拆成多个方法,而不是全部写在 main 里。
Task 4. Stream 流
Section titled “Task 4. Stream 流”Stream流可以帮我们更便捷的筛选和获取数据 体现了函数式的编程风格 代码更加简洁 Stream流的方法大致分为下面三类
-
获取Stream流
我们可以通过Collection的静态方法 从集合创建流 也可以使用Arrays工具类的stream方法 从数组创建流 等等等等
-
中间方法
创建了流之后 我们可以通过中间方法对元素进行转换 过滤等操作 有趣的是 这些方法的返回值仍然为流 就像一条流水线一样 我们可以不断使用中间方法 返回新的流 经过层层筛选 最后只在流上保留你需要的元素 filter map sorted等都是常见的中间方法
-
终结方法
常见的终结方法有forEach遍历 count计数 collect收集 等等
先观察这段代码:
List<String> strings = List.of("I", "am", "a", "list", "of", "Strings");Stream<String> stream = strings.stream();Stream<String> limit = stream.limit(4);System.out.println("limit = " + limit);- 直接打印 limit,会得到什么类型的结果?
- 为什么它不会直接把流里的元素打印出来?
然后完成下面的题目:
public class Student { String name; int score;
public Student(String name, int score) { this.name = name; this.score = score; }
public String getName() { return name; }
public int getScore() { return score; }}public class Main { public static void main(String[] args) { List<Student> students = Arrays.asList( new Student("Alice", 85), new Student("Bob", 58), new Student("Charlie", 90), new Student("David", 45), new Student("Eve", 72), new Student("Frank", 60), new Student("Grace", 55), new Student("Heidi", 95) );
List<String> passingStudents = students.stream() // 在这里补充你的流操作 ;
System.out.println(passingStudents); }}要求你完成:
- 过滤分数大于等于 60 的学生。
- 把姓名转换成大写。
- 按姓名字母顺序排序。
- 收集成 List<String> 并打印结果。
请至少提交以下内容:
- Task 1、Task 2、Task 3 、 Task 4 的代码与文字说明。
- 关键题目的运行结果截图或输出结果。
- 你在做题过程中遇到过的一个问题,以及你是怎么解决的。
本题提交方式
Section titled “本题提交方式”出题人联系方式
Section titled “出题人联系方式”出题人:
coco
QQ:3916627528