在线视频:尚硅谷Java面试题第4季,最新大厂java面试真题

课程资料:

尚硅谷大厂面试题第四季

尚硅谷Java高频面试闯关秘籍.pdf

阿里巴巴java开发手册

开胃小菜:i++热身

i++++i的区别,以下回答来自gpt-4o-mini

在 Java 中,i++++i 都是自增运算符,用于将变量 i 的值增加 1,但它们的使用方式和效果略有不同。

  1. i++(后置自增):

    • 这个运算符在表达式中使用时,会先返回 i 的当前值,然后再将 i 的值增加 1。
    • 示例:
      1
      2
      int i = 5;
      int a = i++; // a 的值是 5, i 的值变为 6
  2. ++i(前置自增):

    • 这个运算符在表达式中使用时,会先将 i 的值增加 1,然后返回 i 的新值。
    • 示例:
      1
      2
      int i = 5;
      int a = ++i; // i 的值变为 6, a 的值也是 6

总结

  • 如果你只需要增加 i 的值并不在意原始值,可以使用 i++++i,结果是相同的。
  • 如果你在表达式中需要使用 i 的当前值,则选择 i++;如果需要使用增加后的值,则选择 ++i

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
public class Test {
public static void main(String[] args) {
int i = 5;

int a = i++; // a = 5, i = 6
System.out.println("a: " + a + ", i: " + i);

i = 5; // 重置 i
int b = ++i; // b = 6, i = 6
System.out.println("b: " + b + ", i: " + i);
}
}

运行上述代码将输出:

1
2
a: 5, i: 6
b: 6, i: 6

i++(后置自增): 先返回 i 的当前值,然后再将 i 的值增加,即先赋值后自增。
++i(前置自增): 先将 i 的值增加 1,然后返回 i 的新值,即先自增后赋值。

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
int i = 1;
System.out.println("i: " + i);
System.out.println("++i: " + ++i);
System.out.println("i++: " + i++);
System.out.println("i: " + i);
System.out.println("--i: " + --i);
System.out.println("i--: " + i--);
System.out.println("i: " + i);
}

执行结果:

1
2
3
4
5
6
7
i: 1
++i: 2
i++: 2
i: 3
--i: 2
i--: 2
i: 1

高可用指标(几个9)

1年 = 365天 = 8760小时
99% = 8760 * 1% = 8760 * 0.01 = 87.6小时
99.9% = 8760 * 0.1% = 8760 * 0.001 = 8.76小时
99.99% = 8760 * 0.01% = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟
99.999% = 8760 * 0.001% = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟
99.9999% = 8760 * 0.0001% = 8760 * 0.000001 = 0.00876小时 = 0.00876 * 60 = 0.5256分钟 = 31 秒

业界高可用的标准是按照系统宕机时间来衡量的

通俗叫法 可用性级别 年度宕机时间
基本可用 2个9 99% 87.6小时
较高可用 3个9 99.9% 8.76小时
具有故障自动恢复能力的可用性 4个9 99.99% 52.6分钟
极高可用性 5个9 99.999% 5.26分钟
容错可用性 6个9 99.9999% 31 秒

Arraya.asList()避坑

asList 的返回对象是一个 Arrays 内部类, 并没有实现集合的修改方法。 只是重写了add()remove()等修改List结构的方法,并将它们直接抛出UnsupportedOperationException异常,从而禁止了对List结构的修改。

问题演示

1
2
3
4
5
6
7
8
9
10
public class Arrays_BugDemo
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(1,2);
list.add(3);

list.forEach(System.out::println);
}
}

执行异常:

1
2
3
4
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at Arrays_BugDemo.main(Arrays_BugDemo.java:11)

阿里手册

阿里巴巴Java开发规范中指出,使用工具类 Arrays.asList() 方法把数组转换成集合时,不能使用其修改集合相关的方法。因为它的 add()remove()clear() 方法会抛出 UnsupportedOperationException()

image-20240727123424096

源码分析

Arrays.ArrayList类继承自AbstractList,实现了List接口。它重写了add()remove()等修改List结构的方法,并将它们直接抛出UnsupportedOperationException异常,从而禁止了对List结构的修改。具体来说,Arrays.asList()方法返回的是Arrays类中的一个私有静态内部类ArrayList,它继承自AbstractList类,实现了List接口。

image-20240727132514557

解决方案

CodeGeeX 给出的修复建议

错误原因:在尝试向一个不可变的列表(由Arrays.asList()创建的列表)中添加元素时,抛出了UnsupportedOperationException

修复建议:要修复这个问题,您需要使用一个可变的列表,如ArrayList。您可以将Arrays.asList()替换为new ArrayList<>(Arrays.asList(1, 2)),这样创建一个包含两个元素的ArrayList实例。然后,您可以使用add()方法向列表中添加元素。

1
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2));