Java 基础简单十问
1.JVM、JRE 和 JDK 的关系
2. Java 的跨平台性和其实现原理
3. & 与 && 的区别
4. 最有效率的方法计算 2 乘以 8
6. 判断正误-1
7. 判断正误-2
8. 实现冒泡排序和快速排序
9. 实现打印指定行数的空心菱形的功能
10. 打印扫雷的地图
1. JVM、JRE 和 JDK 的关系
JVM 是可以直接处理 Java 字节码的虚拟计算机系统,本质是一种软件系统,它使得 Java 语言具有了跨平台的特性;
JRE 是 Java 软件包运行所需的最低软件配置环境,它拥有直接运行 Java 字节码的能力,但是没有编译 Java 源码的能力;
JDK 是开发测试 Java 源码的一套软件工具,包含了从开发、编译和运行的所有工具。
三者的关系是:JDK 包含 JRE,JRE 包含 JVM。
2. Java 的跨平台性和其实现原理
Java 语言具 “有一次编写,到处执行” 的特性,即在任意一种操作系统平台上编写的代码或编译完成的字节码可以放到其他任意一种操作系统上直接运行。这就是所谓的跨平台性。
Java 的跨平台性的实现是依靠 JVM 完成的。所有的 Java 字节码先经过 JVM 处理,通过 JVM 调用操作系统的资源,从而实现了代码与系统的分离。因此,不同的操作系统所安装的 JVM 也是不同的。
3. & 与 && 的区别
两者都是逻辑与运算。& 会首先计算它两边每个布尔表达式的值,然后根据逻辑与的法则得到最终的运算结果;而 && 具有短路特性,即它会首先判断其左边表达式的值是否为 true,如果满足,则直接返回 true,如不满足则再计算其右边的表达式值然后合并两边的计算结果。因此再做逻辑判断时,&& 比 & 更加高效。
4. 最有效率的方法计算 2 乘以 8
2 << 3
每左移一位,数据变为原来的两倍,所以左移三位相当于乘以 8。
5. 不使用临时变量交换两个整数变量的值a=m, b=n
:
方式一
a = a + b;
b = a - b;
a = a - b;
方式二
a = a ^ b;
b = a ^ b;
a = a ^ b;
6. 判断正误-1
short s1 = 1; s1 = s1 + 1;
有错吗?short s1 = 1; s1 += 1;
有错吗?
第一种情况会出错,原因是 1 默认为 int 类型,与 short 类型的 s1 相加并赋值给 short 类型的 s1时,int 类型的 1 需要转换为 short 类型,但这是不被 Java 语法允许的,因此编译不会通过。
第二种情况可以通过编译。因为 += 在赋值过程中做了强制转换的操作,但是要注意保证相加的结果不会超出相应数据类型的取值范围,否则会得到错误的结果。例如,
byte s = 1;
s += 127;
System.out.println(s); // 结果为 -128
7. 判断正误-2
float f=3.4;
是否正确?
错误。3.4 是 double 类型,不能直接转换为 float 类型,所以这样的赋值操作是不允许的。
8. 实现冒泡排序和快速排序
// 冒泡排序
public static void bubbleSort(int[] arr) {
int temp = 0;
for (int i=0; i<arr.length-1; i++) {
for (int j=0; j<arr.length-i-1; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
// 快速排序
public static void quickSort(int[] arr) {
quickSorting(arr, 0, arr.length-1);
}
public static void quickSorting(int[] arr, int left, int right) {
if (left > right) return;
int pivot = left, index = left+1;
int temp;
for (int i=index; i<=right; i++) {
if (arr[pivot] <= arr[i]) continue;
if (index != i) swap(arr, index, i);
index++;
}
swap(arr, pivot, --index);
pivot = index;
quickSorting(arr, left, pivot-1);
quickSorting(arr, pivot+1, right);
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
9. 实现打印指定行数的空心菱形的功能
public static void printHollowDiamond(int raws) {
int rBottom = raws / 2;
int rTop = raws - rBottom;
int numSpace = 0;
for(int i=0; i<rTop; i++) {
for(int j=0; j<rTop-i-1; j++) System.out.print(" ");
System.out.print("*");
numSpace = 2 * i - 1;
while(numSpace-- > 0) System.out.print(" ");
if (numSpace == -1) System.out.print("*");
System.out.println();
}
String leadSpace = rTop == rBottom ? "" : " ";
for(int i=0; i<rBottom; i++) {
System.out.print(leadSpace);
for(int j=0; j<i; j++) System.out.print(" ");
System.out.print("*");
numSpace = 2 * (rBottom-i-1) - 1;
while(numSpace-- > 0) System.out.print(" ");
if (numSpace == -1) System.out.print("*");
System.out.println();
}
}
10. 打印扫雷的地图
```java
public static void mineClearanceMap(int mapWidth, int mapLength, int numOfMines) {
// 在实际的扫雷地图外面加了一圈空格子,方便遍历操作,不需要考虑边界问题
char[][] map = new char[mapWidth+2][mapLength+2];
// 随机埋地雷
Random rand = new Random();
while (numOfMines-- > 0) {
int x = 0, y = 0;
while (true) {
x = rand.nextInt(mapWidth)+1;
y = rand.nextInt(mapLength)+1;
if (map[x][y] == '*') continue;
map[x][y] = '*';
break;
}
}
// 生成地图中的数字
for (int x = 1; x < mapWidth + 1; x++) {
for (int y = 1; y < mapLength + 1; y++) {
if (map[x][y] == '*') continue;
map[x][y] = '0';
for (int i=x-1; i<x+2; i++)
for (int j=y-1; j<y+2; j++)
if (map[i][j] == '*')
map[x][y] += 1;
}
}
//打印地图
for (int i = 1; i < mapWidth + 1; i++) {
for (int j = 1; j < mapLength + 1; j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
```