一、什么是数组
数组就是存储一组相同类型元素的集合。打个比方吧:比如此刻的你正座在高考考场里面偷看笔者的博客,那么你所在的考场就可以看成一个数组,每个考试就是数组中的一个元素,并且考场的总人数是固定的,最多那么多个,只能有人缺考。数组也是一样的,在数组声明的时候必须确定好数组的长度,并且一经确定不能修改。数组声明语法:Test [] tests = new Test[4] 或 Test tests [] = new Test[4]
,推荐使用第一种,不知道为什么,别问,问就去看阿里编程规约。
二、数组在内存中的存放位置以及注意项
直接上图,图中解释。
三、面试题
- 执行
Test [] tests = new Test[4]
时Test类会被加载吗?
不会,这里要注意,创建数组时并不会初始化类! - 为什么数组一旦声明长度就不可变
在第二点中数组注意事项的第四点讲了。 - 数组在内存中是如何分配的
领悟第二点的图吧。
四、与数组相关的面试题
- 各种排序算法(拿冒泡举例,应该很清楚了,就不重复,这里讲一下用多种方法交换两个变量的位置吧,以int类举例)
// 方法一,依赖第三方变量
int num1 = 1;
int num2 = 2;
int num3 = num2;
num2 = num1;
num1 = num3;
System.out.printf("num1=%d,num2=%d%n", num1, num2);
// 方法二,依赖第三方变量、加减法
int num1 = 1;
int num2 = 2;
int num3 = num2 + num1;
num2 = num3 - num2;
num1 = num3 - num1;
System.out.printf("num1=%d,num2=%d%n", num1, num2);
// 方法三,不依赖第三方变量,异或运算
int num1 = 1;
int num2 = 2;
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;
System.out.printf("num1=%d,num2=%d%n", num1, num2);
// 方法四,一行代码搞定
int num1 = 1;
int num2 = 2;
num1 = num1 + num2 - (num2 = num1);
System.out.printf("num1=%d,num2=%d%n", num1, num2);
- 阿里面试题:如何随机的输出1-1000W不重复的随机数,主体代码不超过10行。代码执行时间少于300毫秒。
此处想到了上学时老师用的点名系统,也是点过名的学生不会再出现。具体思路和代码见下面代码:
public class Test {
public static void main(String[] args) {
/**
* 具体思路:
* (1)声明一个1000W长度的数组,循环赋值一次
* (2)声明一个随机数范围值randomRange,初始化为1000W
* (3)每次随机到一个下标后输出该下标对应的元素,并将该下标的元素与randomRange下标对应的元素交换位置,
* 并且randomRange减1,直至randomRange=0为止结束程序
* (4)时间复杂度O(2n),空间复杂度O(n)
*/
int count = 10000000;
int randomRange = count;
int[] arr = new int[count];
Random random = new Random();
long beginTime = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
arr[i] = i + 1;
}
while (randomRange > 0) {
int index = random.nextInt(randomRange);
// 8核16G机器,如果执行输出代码,花费16毫秒,不执行输出语句,花费时间低于0毫秒
System.out.print(arr[index] + "\t");
arr[index] = arr[index] + arr[randomRange - 1] - (arr[randomRange - 1] = arr[index]);
randomRange--;
}
System.out.println("共花费" + (System.currentTimeMillis() - beginTime) / 1000 + "毫秒");
}
}