Java面试题总结:基础及语法169道

Java面试题总结


⭐️1.Java跨平台原理(字节码文件、虚拟机)
C/C++ 语言都 直接编译成针对指定平台 机器码,如果要跨平台需要重新编译.
Java源程序.java)要先编译成 与平台无关字节码文件( .class),然后 字节码文件再 解释机器码运行。解释是通过 Java虚拟机来执行的。
字节码文件不面向任何具体平台, 只面向虚拟机
Java虚拟机是可运行Java字节码文件的虚拟计算机。 不同平台的虚拟机是不同的,但它们都提供了相同的接口。
Java语言具有 一次编译,到处运行的特点。就是说编译后的 .class可以跨平台运行,前提是该平台具有相应的Java虚拟机。 但是性能比C/C++要低。
Java的跨平台原理决定了其性能没有C/C++高

在这里插入图片描述
⭐️2.Java的安全性
语言层次的安全性主要体现在:
Java取消了强大但又危险的指针,而代之以引用。由于指针可进行移动运算,指针可随便指向一个内存区域,而不管这个区域是否可用,这样做是危险的,因为原来这个内存地址可能存储着重要数据或者是其他程序运行所占用的,并且使用指针也容易数组越界

垃圾回收机制
不需要程序员直接控制内存回收,由垃圾回收器在后台自动回收不再使用的内存。避免程序忘记及时回收,导致内存泄露。避免程序错误回收程序核心类库的内存,导致系统崩溃。

异常处理机制
Java异常机制主要依赖于trycatchfinallythrowthrows五个关键字。

强制类型转换
只有在满足强制转换规则的情况下才能强转成功。

底层的安全性可以从以下方面来说明:
Java在字节码的传输过程中使用了公开密钥加密机制(PKC)

运行环境提供了四级安全性保障机制:
字节码校验器 -类装载器 -运行时内存布局 -文件访问限制

⭐️3. Java三大版本
Java2平台包括标准版(J2SE)、企业版(J2EE)和微缩版(J2ME)三个版本:
Standard Edition(标准版) J2SE 包含那些构成Java语言核心的类。
比如:数据库连接、接口定义、输入/输出、网络编程

Enterprise Edition(企业版) J2EE 包含J2SE 中的类,并且还包含用于开发企业级应用的类。
比如servlet、JSP、XML、事务控制

Micro Edition(微缩版) J2ME 包含J2SE中一部分类,用于消费类电子产品的软件开发。
比如:呼机、智能卡、手机、PDA、机顶盒
他们的范围是:
J2SE包含于J2EE中,J2ME包含了J2SE的核心类,但新添加了一些专有类应用场合,API的覆盖范围各不相同。

⭐️4.什么是JVM?什么是JDK? 什么是JRE?
JVM:
JVMJava Virtual Machine(Java虚拟机)的缩写,它是整个Java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。JVM是Java平台的基础,和实际的机器一
样,它也有自己的指令集,并且在运行时操作不同的内存区域。 JVM通过抽象操作系统和CPU结构,提供了一种与平台无关的代码执行方法,即与特殊的实现方法主机硬件主机操作系统无关。JVM的主要工作是解释自己的指令集(即字节码)CPU的指令集或对应的系统调用,保护用户免被恶意程序骚扰。 JVM对上层的Java源文件是不关心的,它关注的只是由源文件生成的类文件(.class文件)。

JRE:
JREjava runtime environment(java运行环境)的缩写。光有JVM还不能让class文件执行,因为在解释class的时候,JVM需要调用解释所需要的类库lib。在JDK的安装目录里你可以找到jre目录,里面有两个文件夹binlib,在这里可以认为bin里的就是jvmlib中则是jvm工作所需要的类库,而jvm和lib和起来就称为jre。所以,在你写完java程序编译成.class之后,你可以把这个.class文件和jre一起打包发给朋友,这样你的朋友就可以运行你写的程序了(jre里有运行.classjava.exe)。JRE是Sun公司发布的一个更大的系统,它里面就有一个JVM。JRE就与具体的CPU结构和操作系统有关,是运行Java程序必不可少的(除非用其他一些编译环境编译成.exe可执行文件……),JRE的地位就象一台PC机一样,我们写好的Win32应用程序需要操作系统帮我们运行,同样的,我们编写的Java程序也必须要JRE才能运行。
在这里插入图片描述
在这里插入图片描述

JDK:JDKjava development kit(java开发工具包)的缩写。每个学java的人都会先在机器上装一个JDK,那 让我们看一下JDK的安装目录。在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的是以下四个文件夹:bin、include、lib、jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE包含JVM。

bin: 最主要的是编译器(javac.exe)
include: java和JVM交互用的头文件
lib类库
jre: java运行环境
(注意:这里的bin、lib文件夹和jre里的bin、lib是不同的
总的来说JDK是用于java程序的开发,而jre则是只能运行class而没有编译的功能。eclipse、idea等其他IDE有自己的编译器而不是用JDK bin目录中自带的,所以在安装时你会发现他们只要求你选jre路径就ok了。

JDK,JRE,JVM三者关系概括如下:
JDK是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境。JRE是JAVA程序运行时需要的运行环境,就是说如果你光是运行JAVA程序而不是去搞开发的话,只安装JRE就能运行已经存在的JAVA程序了。JDKJRE内部都包含JAVA虚拟机JVMJAVA虚拟机内部包含许多应用程序的类的解释器类加载器等等

⭐️5. Java三种注释类型
共有单行注释多行注释文档注释3种注释类型

单行注释

//类成员变量

多行注释

/*
System.out.println("a"); 
System.out.println("b"); 
System.out.println("c"); 
*/

文档注释

/** 
* @author Mark 
* @descripted blog:https://blog.csdn.net/MARK19960120
*/

⭐️6.八种基本数据类型及其字节数

在这里插入图片描述
虚拟机中不存在boolean类型,boolean类型在编译后会使用其他数据类型来示,boolean类型的值只有truefalse两种逻辑值,在编译后会使用10来表示,这两个数在内存中只需要1位(bit)即可存储,位是计算机最小的存储单位.也可以说boolean一个字节,理由是虽然编译后1和0只需占用1位空间,但计算机处理数据的最小单位是1个字节,1个字节等于8位,实际存储的空间是:用1个字节的最低位存储,其他7位用0填补,如果值是true的话则存储的二进制为:0000 0001,如果是false的话则存储的二进制为:0000 0000。《Java虚拟机规范》一书中的描述:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个boolean元素占8位”。这样我们可以得出boolean类型占了单独使用是4个字节,在数组中又是1个字节。

⭐️7. i++和++i的异同之处
共同点:
1、i++++i都是变量自增1,都等价于i=i+1
2、如果i++,++i是一条单独的语句,两者没有任何区别
3、i++和++i的使用仅仅针对变量。 5++和++5会报错,因为5不是变量。

不同点:
如果i++,++i不是一条单独的语句,他们就有区别

int x=5;
int y=x++:
System.out.println(x);//输出 6
System.out.println(y);//输出 5
int x=5;
int y=++x:
System.out.println(x);//输出 6
System.out.println(y);//输出 6

⭐️8.&和&& , |和|| 的区别和联系
&和&&的联系(共同点)&&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定。
操作数1&操作数2,操作数1&&操作数2,
表达式1&表达式2,表达式1&&表达式2,

情况1:当上述的操作数boolean类型变量时,&和&&都可以用作逻辑与运算符。
情况2:当上述的表达式结果是boolean类型变量时,**&和&&都可以用作逻辑与运算符。**表示逻辑与(and),当运算符两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。

&和&&的区别(不同点):

  1. & 称为逻辑与运算符,&& 称为短路与运算符,也可叫逻辑与运算符。
    对于&:无论任何情况,&两边的操作数或表达式都会参与计算。
    对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。
    综上所述,如果逻辑与运算的第一个操作数是false或第一个表达式的结果为false时,对于第二个操作数或表达式是否进行运算,对最终的结果没有影响,结果肯定是false。推荐平时多使用&&,因为它效率更高些。
  2. &还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。

|和||的区别和联系与&和&&的区别和联系类似

⭐️9.用最有效率的方法算出2乘以8等于多少
使用位运算来实现效率最高。位运算符是对操作数以二进制比特位为单位进行操作和运算,操作数和结果都是整型数
对于位运算符“<<”, 是将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,位运算是cpu直接支持的,效率最高。所以,2乘以8等于几的最效率的方法是2 << 3

⭐️10.基本数据类型的类型转换规则
基本类型转换分为自动转换强制转换
自动转换规则
容量小的数据类型 可以自动转换成容量大的数据类型,也可以说低级自动向高级转换。这儿的容量指的不是字节数,而是指类型表述的范围
在这里插入图片描述
强制转换规则:
高级变为低级需要强制转换。
如何转换:

  1. 赋值运算符“=”右边的转换,先自动转换成表达式中级别最高的数据类型,再进行运算。
  2. 赋值运算符“=”两侧的转换,若左边级别>右边级别,会自动转换;若左边级别 = 右边级别,不用转换;若左边级别 < 右边级别,需强制转换
  3. 可以将整型常量直接赋值给byte, short, char等类型变量,而不需要进行强制类型转换,前提是不超出其表述范围,否则必须进行强制转换

⭐️11.if和switch的异同之处
相同之处:
都是分支语句,多超过一种的情况进行判断处理。
不同之处:
switch更适合用于多分支情况,就是有很多种情况需要判断处理,判断条件类型单一,只有一个入口,在分支执行完后(如果没有break跳出),不加判断地执行下去; 而if—else if—else多分枝主要适用于分支较少的分支结构,判断类型不是单一,只要一个分支被执行后,后边的分支不再执行。switch为等值判断(不允许比如>= <=),而if为等值和区间都可以,if的使用范围大。

⭐️12. while和do-while循环的区别
while先判断后执行,第一次判断为false , 循环体一次都不执行。
do while先执行后判断,最少执行1次。
如果while循环第一次判断为true, 则两种循环没有区别。

⭐️13. break和continue的作用
break: 结束当前循环并退出当前循环体。break还可以退出switch语句
continue: 循环体中后续的语句不执行,但是循环没有结束,继续进行循环条件的判断(for循环还会i++)。continue只是结束本次循环。

⭐️14. 请使用递归算法计算n!

public class Recursion { 
//阶乘算法 
public int factorial(int num){ 
   if (num==0 || num== 1){ 
          return 1; 
      }else{
         return num*factorial(num-1); 
      } 
      }
public static void main(String[] args) { 
    Recursion recursion = new Recursion(); 
    int n = 0; 
    int factorial = recursion.factorial(n); 
    System.out.println(factorial); } 
} 

⭐️15. 递归的定义和优缺点
递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点局部变量等开辟了来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

⭐️16. 数组的特征
数组是(相同类型数据)的(有序)(集合
数组会在内存中开辟一块连续的空间,每个空间相当于之前的一个变量,称为数组的元素element
元素的表示 数组名[下标或者索引] scores[7] scores[0] scores[9]
索引从0开始
每个数组元素有默认值 double 0.0; boolean false; int 0
数组中可以存储基本数据类型,可以存储引用数据类型;但是对于一个数组而言,数组的类型是固定的,只能是一个length:数组的长度.数组的长度是固定的,一经定义,不能再发生变化(数组的扩容)

⭐️17. 请写出冒泡排序代码
在这里插入图片描述

public class Bubble {

    public static void sort(Comparable[] a){
        for(int i=a.length-1;i>0;i--){
            for(int j=0;j<i;j++){
                //比较索引j和索引j+1处的值
                if (greater(a[j],a[j+1])){
                    exch(a,j,j+1);
                }
            }
        }
    }

    //比较v元素是否大于w元素
    private static  boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }

    //数组元素i和j交换位置
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}

⭐️18. 请写出选择排序的代码
在这里插入图片描述

public class Selection {

    public static void sort(Comparable[] a){
        for(int i=0;i<=a.length-2;i++){
           //定义一个变量,记录最小元素所在的索引,默认为参与选择排序的第一个元素所在的位置
            int minIndex = i;
            for(int j=i+1;j<a.length;j++){
                //需要比较最小索引minIndex处的值和j索引处的值;
                if (greater(a[minIndex],a[j])){
                    minIndex=j;
                }
            }
            //交换最小元素所在索引minIndex处的值和索引i处的值
            exch(a,i,minIndex);
        }
    }

    /*
        比较v元素是否大于w元素
     */
    private static  boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }

    /*
    数组元素i和j交换位置
     */
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}

⭐️19.请写出插入排序的代码
包括:直接插入排序二分插入排序(又称折半插入排序)链表插入排序希尔排序(又称缩小增量排序)。属于稳定排序的一种(通俗地讲,就是两个相等的数不会交换位置) 。稳定排序还有:
在这里插入图片描述

public class Insertion {

    public static void sort(Comparable[] a){
        for(int i=1;i<a.length;i++){
            for(int j=i;j>0;j--){
                //比较索引j处的值和索引j-1处的值,如果索引j-1处的值比索引j处的值大,则交换数据,如果不大,那么就找到合适的位置了,退出循环即可;
                if (greater(a[j-1],a[j])){
                    exch(a,j-1,j);
                }else{
                    break;
                }
            }

        }
    }

    /*
        比较v元素是否大于w元素
     */
    private static  boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }

    /*
    数组元素i和j交换位置
     */
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}

⭐️20.可变参数的作用和特点
总结1:可变参数
1.可变参数的形式...
2.可变参数只能是方法的形参
3.可变参数对应的实参可以0,1,2…n个,也可以是一个数组
4.在可变参数的方法中,将可变参数当做数组来处理
5.可变参数最多有一个,只能是最后一个
6.可变参数好处:方便 简单 减少重载方法的数量
7.如果定义了可变参数的方法,不允许同时定义相同类型数组参数的方法

总结2: 数组做形参可变参数做形参联系和区别
联系:
1.实参都可以是数组;
2.方法体中,可变参数本质就是当做数组来处理

区别:
1.个数不同 可变参数只能有一个,数组参数可以多个
2.位置不同 可变参数只能是最后一个 数组参数位置任意
3.实参不同 可变参数实参可以0,1,2…个,也可以是一个数组,数组的实参只能是数组

private static int sum(int... values) { 
    int sum = 0; 
    for (int i = 0; i < values.length; i++) { 
        sum += values[i]; 
    }
    return sum; 
    }

⭐️21. 类和对象的关系
类是对象的抽象,而对象是类的具体实例。 类是抽象的,不占用内存,而对象是具体的,占用存储空间。 类是用于创建对象的蓝图,类就是一个带方法和变量的特定类型类和对象好比图纸和实物的关系,模具和铸件的关系。

⭐️22. 面向过程和面向对象的区别
两者都是软件开发思想,先有面向过程,后有面向对象。在大型项目中,针对面向过程的不足推出了面向对象开发思想。
在这里插入图片描述
比喻:
面向过程是蛋炒饭,面向对象是盖浇饭。盖浇饭的好处就是“菜”“饭”分离,从而提高了制作盖浇饭的灵活性。饭不满意就换饭,菜不满意换菜。用软件工程的专业术语就是“可维护性”比较好,“饭” 和“菜”的耦合度比较低。蛋炒饭就不行了, 如果不满意就要丢掉重做;

区别:
编程思路不同: 面向过程以实现功能的函数开发为主,而面向对象要首先抽象出类、属性及其方法,然后通过实例化类、执行方法来完成功能
封装性:都具有封装性,但是面向过程是封装的是功能,而面向对象封装的是数据功能
面向对象具有继承性多态性,而面向过程没有继承性和多态性.
方法重载和方法重写(覆盖)的区别:
在这里插入图片描述⭐️23. this和super关键字的作用
this对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题;this可以调用成员变量,不能调用局部变量this也可以调用成员方法,但是在普通方法中可以省略this在构造方法中不允许省略,必须是构造方法的第一条语句。而且在静态方法当中不允许出现this关键字。
super代表对当前对象的直接父类对象的引用,super可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问private成员)super可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访问private成员);super可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。

⭐️24. static关键字的作用
static可以修饰变量方法代码块内部类
static属性属于这个类所有,即由该类创建的所有对象共享同一个static属性。可以对象创建后通过对象名.属性名类名.属性名两种方式来访问。也可以在没有创建任何对象之前通过类名.属性名的方式来访问。

static变量非static变量的区别(都是成员变量,不是局部变量)

  1. 在内存中份数不同
    不管有多少个对象,static变量只有1份。对于每个对象,实例变量都会有单独的一份.static变量是属于整个类的,也称为类变量。而非静态变量是属于对象的,也称为实例变量
  2. 在内存中存放的位置不同
  3. 静态变量存在方法区中, 实例变量存在堆内存中

在这里插入图片描述

  1. 访问的方式不同
    实例变量: 对象名.变量名 stu1.name="小明";
    静态变量对象名.变量名 stu1.schoolName="西二旗小学"; 不推荐如此使用
    类名.变量名Student.schoolName="东三旗小学"; 推荐使用
    4.在内存中分配空间的时间不同
    实例变量:创建对象的时候才分配了空间
    静态变量:第一次使用类的时候

static代码块 :当类被第一次使用时(可能是调用static属性和方法,或者创建其对象)执行静态代码块,且只被执行一次,主要作用是实现static属性的初始化。
static内部类:属于整个外部类,而不是属于外部类的每个对象。不能访问外部类的非静态成员(变量或者方法),可以访问外部类的静态成员

未完待续 4.29

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值