跳转到内容

2:数据类型、控制流与异常处理

后端Banner

在这一任务中,你将从“会写语法”逐步走到“会组织逻辑、会设计数据、会处理异常”,具备继续深入 Java 后端的基础能力☆: .。. o(≧▽≦)o .。.:

  • Task 1Task 2较为基础。
  • Task 3Task 4 更偏进阶。
  • 本题重视“思路说明”。不要只贴最终代码,尽量说明你为什么这样写。

请先完成下面几组基础问题:

  1. Java 的八种基本数据类型分别是什么?
  2. 四种整型类型各占多少字节,表示范围大致是多少?
  3. 解释基本类型与引用类型的区别。

观察并回答下面这段代码:

int a = 4;
char c = '0';
int b = a + c;
  1. 这里发生的是隐式类型转换还是显式类型转换?
  2. b 的值是多少?请解释为什么。

再执行下面这段代码:

int a = 5;
int b = 7;
int c = (++a) + (b++);
System.out.println(c);
System.out.println(a + " " + b);
  1. 写出运行结果,并解释每一步计算过程。
  2. 为什么“两个正数相加结果可能变成负数”?请从二进制存储和溢出的角度解释。
  3. 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);

程序不是顺着一行一行机械执行就够了,我们还需要控制它“在什么条件下做什么事”。

你一定见过以下流程图:

流程图是对现实问题解决方案的抽象,一个操作有了流程图,就能被写成程序,为了能控制程序如何运行,我们需要学习流程控制。

img

2.1 if-elseswitch

Section titled “2.1 与 ”

请补全下面的函数:

// 判断传入年份是否为闰年
boolean isLeapYear(int year) {
}

完成后请再回答:

  1. switch-caseif-else 的适用场景分别是什么?
  2. 有人说 switch-caseif-else 的“语法糖”,你是否同意?请说出你的理由。

请补全下面的函数,打印一个高度为 n 的空心菱形,保证 n 为奇数:

// 例如 n = 5 时,输出:
// *
// * *
// * *
// * *
// *
void print(int n) {
}

请分别用递归和迭代两种方式实现斐波那契数列:

int fibonacci(int n) {
}

并回答:

  1. 递归和迭代的核心区别是什么?
  2. 为什么很多场景下更偏好迭代?
  3. 循环是否总能被递归取代?如果能,代价是什么?

如果你想继续挑战,可以尝试完成汉诺塔:

通过if-elsefor-while等等能够对程序进行简单的流程控制,下面的问题是一个名为汉诺塔的游戏。现在有A,B,C三个柱子,在A柱上有n块铁饼,现在要把A柱上的n块铁饼都移动到C柱上,请补全函数,使得函数打印出移动的过程。要求给出你代码的具体思路,可以写在文档或者代码注释中(这题对初学的同学可能会有一定挑战性,可以先跳过等后回来做)

// n = 3 时,输出:
// A->C
// A->B
// C->B
// A->C
// B->A
// B->C
// A->C
void hanoi(int n) {
}

当你写好了代码 IDE检查没有语法错误 仔细检查过没有bug 程序一开始也能正常运行 是否就意味着万事大吉了呢?

当然不是 程序在运行的过程中会遇到很多不确定的情况 比如程序试图打开一个不存在的文件 程序遇到了网络连接问题 程序在运算时把0作为了除数 等等等等

请先回答两个概念问题:

  1. ErrorException 的区别是什么?面对它们时,程序的处理态度应该有什么不同?
  2. checked exceptionunchecked exception 的区别是什么?它们通常分别由什么原因引起?

然后完成下面这道题:

编写一个 Java 程序,完成以下功能:

  1. 从当前目录下读取一个名为 data.txt 的文本文件。(PS:这里涉及到些许io流的相关知识,点击查看 Java05 内容)
  2. 文件中每一行包含一个整数,程序需要计算这些整数的平均值。
  3. 需要正确处理以下异常情况:
    • 文件不存在
    • 文件为空
    • 文件中出现无法解析为整数的内容
  4. 无论是否发生异常,都要保证文件资源被正确关闭。

要求:

  • 创建自定义异常类 EmptyFileException
  • 使用 try-with-resourcesfinally 管理资源。
  • 给出合理的异常提示,不要让程序无声失败。

如果你已经学过方法设计,可以把逻辑拆成多个方法,而不是全部写在 main 里。

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);
  1. 直接打印 limit,会得到什么类型的结果?
  2. 为什么它不会直接把流里的元素打印出来?

然后完成下面的题目:

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);
}
}

要求你完成:

  1. 过滤分数大于等于 60 的学生。
  2. 把姓名转换成大写。
  3. 按姓名字母顺序排序。
  4. 收集成 List<String> 并打印结果。

请至少提交以下内容:

  1. Task 1Task 2Task 3Task 4 的代码与文字说明。
  2. 关键题目的运行结果截图或输出结果。
  3. 你在做题过程中遇到过的一个问题,以及你是怎么解决的。

提交点这里

出题人:出题人头像  coco

QQ:3916627528

邮箱:3916627528@qq.com