Java面试题-1.基础
目录
6.short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
1.JVM、JRE 和 JDK 的关系
答案整理自:https://www.cnblogs.com/zhangzongxing01/p/5559126.html
JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。Java Runtime Environment(JRE)是运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。JVM是Java Virtual Machine(Java虚拟机)的缩写,是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。
金字塔结构 JDK=JRE+JVM+其它 运行Java程序一般都要求用户的电脑安装JRE环境(Java Runtime Environment);没有jre,java程序无法运行;而没有java程序,jre就没有用武之地。
JDK(Java Development Kit)
JDK是Java开发工具包,是Sun Microsystems针对Java开发员的产品。
JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。
JDK是整个JAVA的核心,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。
①SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。
②EE(J2EE),enterprise edition,企业版,使用这种JDK开发J2EE应用程序,从JDK 5.0开始,改名为Java EE。
③ME(J2ME),micro edition,主要用于移动设备、嵌入式设备上的java应用程序,从JDK 5.0开始,改名为Java ME。
Java Runtime Environment(JRE)
是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。
JRE中包含了Java virtual machine(JVM),runtime class libraries和Java application launcher,这些是运行Java程序的必要组件。
与大家熟知的JDK不同,JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器),只是针对于使用Java程序的用户。
JVM(java virtual machine)
就是我们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。
也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。
只有JVM还不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。
JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
2.什么是跨平台性?原理是什么?
答案整理自:https://www.cnblogs.com/fanweisheng/p/11130355.html
所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行。
实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序。(注意不是能在所有的平台上运行,关键是该平台是否能安装相应的虚拟机)。
3.&和&&的区别?
同为逻辑运算符时:
对于:& -- > 只要左右两边有一个为false,则为false;只有全部都为true的时候,结果为true
对于:&& -- > 只要符号左边为false,则结果为false;当左边为true,同时右边也为true,则结果为true
此外,&还表示二进制的与运算。
4.用最有效率的方法计算 2 乘以 8
https://blog.csdn.net/lihaiyun718/article/details/6881164
2 << 3,
因为将一个数左移n 位,就相当于乘以了2 的n 次方,那么,一个数乘以8 只要将其左移3 位
即可,而位运算cpu 直接支持的,效率最高,所以,2 乘以8 等於几的最效率的方法是2 << 3。举个栗子:
//计算2*8=2*23
System.out.println(2<<3);//8=2的3次方为8
//计算2*16=2*24
System.out.println(2<<4);//16=2的4次方为16
//计算3*8=2*23
System.out.println(3<<3);//8=2的3次方为8
//计算5*8=5*23
System.out.println(5<<3);//8=2的3次方为8
//计算6*4=6*22
System.out.println(6<<2);//4=2的2次方为4
5.在没有使用临时变量的情况如何交换两个整数变量的值?
public class Sum{
public static void main(String[] args){
int a = 3;
int b = 1;
System.out.println("a="+a+",b="+b);
a = a + b;
b = a - b;
a = a - b;
System.out.println("a="+a+",b="+b);
}
}
除了加减法,还可以通过乘除法、异或法得到。
6.short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
7.float f=3.4;是否正确?
错误,float f=3.4f; float类型的数据后置要加f。此外,long型的数据后置要加L。l和f大小写都可以,但L最好大写。
8.手动实现一下冒泡排序(快速排序)
/*
原理:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
*/
/*
升序排列的口诀:
N个数字来排队
两两相比小靠前,
外层 循环length-1
内层循环length-i-1
降序排序的口诀:
N个数字来排队
两两相比大靠前,
外层 循环length-1
内层循环length-i-1
*/
public static void main(String[] args) {
int[] nums = {20,15,18,13,30,60};
int temp;
//外层循环控制的是, 比较的轮数。
//外层循环次数: length-1
for(int i=0;i<nums.length-1;i++) {
//内层循环控制的是,每轮比较的次数
//第i轮(i从0开始计算), 比较次数为:length-i-1
for(int j=0;j<nums.length-i-1;j++) {
if(nums[j]>nums[j+1]) {
//两两相比, 满足移动条件
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
9.手动实现一下二分法查找
/*
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,二分查找要求数组数据必须采用顺序存储结构有序排列。
首先,假设数组中元素是按升序排列,将数组中间位置的数据与查找数据比较,如果两者相等,则查找成功;否则利用中间位置记录将数组分成前、后两个子数组,如果中间位置数据大于查找数据,则进一步查找前子数组,否则进一步查找后子数组。
重复以上过程,直到找到满足条件的数据,则表示查找成功,直到子数组不存在为止,表示查找不成功。
*/
/**
* 二分查找(折半查找)
*/
public static void main(String[] args) {
int[] nums = {10,20,30,40,50,60,70,80,90};
//要查找的数据
int num = 20;
//关键的三个变量:
//1. 最小范围下标
int minIndex = 0;
//2. 最大范围下标
int maxIndex = nums.length-1;
//3. 中间数据下标
int centerIndex = (minIndex+maxIndex)/2;
while(true) {
System.out.println("循环了一次");
if(nums[centerIndex]>num) {
//中间数据较大
maxIndex = centerIndex-1;
}else if(nums[centerIndex]<num) {
//中间数据较小
minIndex = centerIndex+1;
}else {
//找到了数据 数据位置:centerIndex
break;
}
if(minIndex > maxIndex) {
centerIndex = -1;
break;
}
//当边界发生变化, 需要更新中间下标
centerIndex = (minIndex+maxIndex)/2;
}
System.out.println("位置:"+centerIndex);
}
10.实现打印指定行数的空心菱形的功能
package lxh.test;
import java.util.Scanner;
public class LingXing {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = -1;
//菱形的行数:奇数且大于等于3
while (true){
System.out.println("请输入菱形的行数:奇数且大于等于3;输入 0 退出 ");
if(sc.hasNextInt()){
n = sc.nextInt();
if(n == 0) break;
if(n < 0 || n > 0&n <= 3 || (n % 2) == 0){
System.out.println("输入有误!");
continue;
}
}else{
break;//输入的不是数字就退出程序。
}
/*else{
System.out.println("输入错误,请输入数字");
continue;
}*/
for(int i = 0;i < n;i++){
//分两类:上下两顶点与中间
if(i == 0 || i == n-1){
//顶点:先打印n/2个空格
for(int j = 0;j < n/2;j++){
System.out.print(" ");
}
//打印顶点
System.out.print("o");
//有要求的就打印顶点后的空格
/*
//打印n/2个空格
for(int j = 0;j < n/2;j++){
System.out.print(" ");
}
*/
//换行
System.out.println();
continue;
}
//中间从n/2处分开
if(i <= n/2){
//0-(n/2)行,包含 n/2
//打印空格 n/2-i 个:随行数增加,空格数-1(中学题)
for(int j = 0;j < n/2-i;j++){
System.out.print(" ");
}
//打印点
System.out.print("o");
//打印空格 2*i-1 个
for(int j = 0;j < 2*i-1;j++){
System.out.print(" ");
}
//打印点
System.out.print("o");
}else{
//n/2 行之后
//打印空格 i-n/2 个
for(int j = 0;j < i-n/2;j++){
System.out.print(" ");
}
//打印点
System.out.print("o");
//打印空格 2*n-2*i-3 个
for(int j = 0;j < 2*n-2*i-3;j++){
System.out.print(" ");
}
//打印点
System.out.print("o");
}
//换行
System.out.println();
}
}
}
}