JAVA经典面试题,祝你面试无阻

1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程。Java 源文件被编译成能被 Java 虚拟机执行的字节码文件。
java所谓的跨平台就是在不同平台上安装了不同的jvm,而在不同平台上生成的.class文件都是一样的,而.class文件再由对应平台的jvm解释成对应平台的机器码执行。
2.JDK和JRE的区别是什么?
JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。
JDK顾名思义是java开发工具包,是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的文档和demo例子程序。
在这里插入图片描述
3.”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
  static是表示静态的意思,它可用来修饰成员变量和成员函数,被静态修饰的成员函数只能访问静态成员,不能访问非静态成员。静态是随着类的加载而加载,因此可以直接用类进行访问。
Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
java中盖private方法也不可以覆,因为private修饰的变量和方法只能在当前类中使用,如果是其他的类继承当前类是不能访问到private变量或方法的,当然也不能覆盖。
4.是否可以在static环境中访问非static变量?
因为静态的成员属于类,随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例,就不可以访问非静态的成员。

5.执行如下程序代码

char chr = 127;
int sum = 200;
chr += 1;
sum += chr;
后,sum的值是 ; ( )
A.72
B.99
C.328
D.327
java中只有byte, boolean是一个字节, char是两个字节, 所以对于java来说127不会发生溢出, 输出328
但是对于c/c++语言来说, char是一个字节, 会发生溢出, 对127加一发生溢出, 0111 1111 --> 1000 0000, 1000 0000为补码-128, 所以结果为200-128=72
6.Java中的方法覆盖(Overriding)和方法重载(Overload)是什么意思?
Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。
方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。
7.Java支持多继承么?
java只支持单继承,这是由于安全性的考虑,如果子类继承的多个父类里面有相同的方法或者属性,子类将不知道具体要继承哪个,而接口可以多实现,是因为接口只定义方法,而没有具体的逻辑实现,多实现也要重新实现方法。
8.Java支持的数据类型有哪些?什么是自动拆装箱?
java支持8个基本数据类型:字符型Char(2字节)数值型:byte(1字节 ),short(2字节),int(4字节),long(8个字节),浮点类型:float(4字节),double(8字节)布尔型:boolean(1字节)
String和Integer是引用数据类型,引用数据类型转基本数据类型叫做拆箱,基本数据类型转为引用类型叫做装箱。
9.接口和抽象类的区别是什么?
首先需要了解的是抽象类是用来捕捉子类的通用特性的,而接口则是抽象方法的集合;抽象类不能被实例化 ,只能被用作子类的超类,是被用来创建继承层级里子类的模板,而接口只是一种形式,接口自身不能做任何事情。
其次,抽象类可以有默认的方法实现,子类使用extends关键字来继承抽象类,如果子类不是抽象类的话,它需要提供抽象类中所有声明方法的实现。而接口完全是抽象的,它根本不存在方法的实现,子类使用关键字implements来实现接口,它需要提供接口中所有声明方法的实现。
抽象类可以有构造器,除了不能实例化抽象类之外,它和普通Java类没有任何区别,抽象方法可以有public、protected和default这些修饰符。而接口不能有构造器,是完全不同的类型,接口方法默认修饰符是public,不可以使用其它修饰符。
10.下面的程序将来打印什么?()


public class TestIncr {
    public static void main(String args[]) {
        int i = 0;
        i = i++ + i;
        System.out.println("I =" +i);
    }
}

A.I = 1 B.I = 2 C.I = 3 D.编译出错
解析:i++是先使用在自增 ++i是先自增在使用,所以0+0=0然后i自增答案选择A;
11.在java中为什么很多人说有值传递和引用传递?引用传递的本质是什么?
值引用就是将储存单元的值传递不会修改内存中的数据,引用传递本质是传递存储数据内存单元的地址。说白了,值传递就是传递一个复制品你在怎么修改也不会损害原值,引用传递相当于把地址暴露给函数了直接就可以修改原值了。
12.Java中,什么是构造方法?什么是构造方法重载?
Java中的构造函数是为了初始化对象的,构造函数的函数名和类名一致,默认的构造函数没有参数,没有返回值,构造函数的函数体内,没有内容。 构造函数的重载是函数名与类名相同,参数类型不同,参数不同。同样的作用也是为了初始化对象的。
13.外部类,:成员内部类,局部内部类,匿名内部类,静态内部类分别有哪些访问权限?
1、外部类前可以修饰:public、default、abstract、final
2、内部类前可以修饰:内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限
3、局部内部类前可以修饰:abstract、final
4、匿名内部类:是不能有访问修饰符和static修饰符的
5、内部静态类:不能使用外部类的非static成员变量或者方法。
其中:访问修饰符(public、protected、default、private),其他都是非访问修饰符
13.下面代码是否有错,如有错,请指出并阐述错误原因。

	class  testB{
string  aa = “I’m testB”;
}
	interface  testA{
string  aa = “I’m testA”;
}  class  testC  extends  testB  implemets  testA{
	public  void  cc(){
System.out.println(aa);
}
	public  static  void  main(String[] args){
new testC().cc();
}
}

1.String首字母要大写
2. implemets拼写错误,是implements
3.System.out.println(aa);语义含糊,没有指明到底是testA的aa还是testB的aa
4.如果是testA的aa可以正常输出,但是如果是testB的aa则不能通过,因为不能在静态方法中调用非静态的变量
运行结果:将上述语法问题改正后结果:“I’m testB”,跟了一下debug根本没有进到testA因为继承testB所以直接aa是有值的。
14.进程和线程的区别是什么?
进程是运行中的程序,线程是进程的内部的一个执行序列
进程是资源分配的单元,线程是执行单元
进程间切换代价大,线程间切换代价小
进程拥有资源多,线程拥有资源少
多个线程共享进程的资源
运行QQ是一个进程,QQ中发送文字传输图片都是一个线程,一个进程运行多个线程
15.以下程序执行后,错误的结果是()

public class Test {
    private String name = "abc";
    public static void main(String[] args) {
        Test test = new Test();
        Test testB = new Test();
        String result = test.equals(testB) + ",";
        result += test.name.equals(testB.name) + ",";
        result += test.name == testB.name;
        System.out.println(result);
    }
}

答案:false,true,true
在这里插入图片描述
16.Java语言中,下面哪个语句是创建数组的正确语句?( )
A. float f[][] = new float[6][6];
B. float []f[] = new float[6][6];
C. float f[][] = new float[][6];
D. float [][]f = new float[6][6];
E. float [][]f = new float[6][];
ABDE都是正确答案,创建数组在java中第一维一定要有,长度可以不确定。
17.以下说法错误的是()
A.其他选项均不正确
B.java线程类优先级相同
C.Thread和Runnable接口没有区别
D.如果一个类继承了某个类,只能使用Runnable实现线程

B选项,在java中线程是有分优先等级的所以优先级不能相同,错误
C选项,Thread实现了Runnable接口是一个类不是接口,错误
D选项,实现多线程的三种方式,一种是继承Thread类使用此方式就不能继承其他的类了。还有两种是实现Runnable接口或者实现Callable接口
,所以说法错误的是 BCD,小伙伴是不是入坑了呢,问题都是坑呢,一定要仔细审题
18.下列方法中哪个是线程执行的方法? (A)
A.run()B.start()C.sleep()D.suspend()
run()方法用来执行线程体中具体的内容
start()方法用来启动线程对象,使其进入就绪状态
sleep()方法用来使线程进入睡眠状态
suspend()方法用来使线程挂起,要通过resume()方法使其重新启动
是线程执行不是执行线程的方法。
19.下面程序的输出结果为( )

public class Demo {
 public static String sRet = "";
 public static void func(int i)
 {
 try
 {
 if (i%2==0)
 {
 throw new Exception();
 }
 }
 catch (Exception e)
 {
 sRet += "0";
 return;
 }
 finally
 {
 sRet += "1";
 }
 sRet += "2";
 }
 public static void main(String[] args)
 {
 func(1);
 func(2);
 System.out.println(sRet);
 }
 }

答案:1201,第一遍func的if不成立所以不抛出异常但是必须进入finally中没有return所以拼接“12”,第二次进入if条件成立抛出异常进入catch中得“120”虽然有return但是还需要进入finally中得“1201”因为有return所以不向下执行直接返回结果。
20.假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么?

public class Base
{
   public void methodOne()
   {
      System.out.print("A");
      methodTwo();
   }
 
   public void methodTwo()
   {
      System.out.print("B");
   }
}
 
public class Derived extends Base
{
   public void methodOne()
   {
      super.methodOne();
      System.out.print("C");
   }
 
   public void methodTwo()
   {
      super.methodTwo();
      System.out.print("D");
   }
}

答案:ABDC,因为new Derived所以执行它的methodOne方法,通过super执行父类中的方法所以打印A,methodTwo因为子类中已经重写了这个方法所以执行Derived中的methodTwo,通过super执行父类中的methodTwo打印B,然后返回到子类methodTwo中打印D,methodOne方法未执行完所以退到方法中打印C
21.给出以下代码,输出结果是什么?

class Value{
    public int i=15;
}
public class Test{
    public static void main(String argv[]){
        Test t=new Test( );
        t.first( );
    }
 
public void first( ){
    int i=5;
    Value v=new Value( );
    v.i=25;
    second(v,i);
    System.out.println(v.i);
}
 
public void second(Value v,int i){
    i = 0;
    v.i = 20;
    Value val = new Value( );
    v = val;
    System.out.println(v.i+" "+i);
   }
}

A. 15 0 20 B. 15 0 15 C. 20 0 20 D. 0 15 20
答案选择A,考察的是值传递与引用传递,Java中原始数据类型都是值传递,执行first方法时修改值v为25,将v传给second在second中修改first中的v的值为20所以变量i还是0 ,在second中新new了一个value值是15,将15复制给了v(复制给v而不是v.i如果是v.i修改的还是first中的)所以打印 15 0退出second打印first中的v.i(在second中改为了20)所以打印20
22.以下代码的输出结果是?

public class B
{
    public static B t1 = new B();
    public static B t2 = new B();
    {
        System.out.println("构造块");
    }
    static
    {
        System.out.println("静态块");
    }
    public static void main(String[] args)
    {
        B t = new B();
    }
}

答案:构造块 构造块 静态块 构造块,链接:
开始时JVM加载B.class,对所有的静态成员进行声明,t1 t2被初始化为默认值,为null,又因为t1 t2需要被显式初始化,所以对t1进行显式初始化,初始化代码块→构造函数(没有就是调用默认的构造函数),咦!静态代码块咋不初始化?因为在开始时已经对static部分进行了初始化,虽然只对static变量进行了初始化,但在初始化t1时也不会再执行static块了,因为JVM认为这是第二次加载类B了,所以static会在t1初始化时被忽略掉,所以直接初始化非static部分,也就是构造块部分(输出’‘构造块’’)接着构造函数(无输出)。接着对t2进行初始化过程同t1相同(输出’构造块’),此时就对所有的static变量都完成了初始化,接着就执行static块部分(输出’静态块’),接着执行,main方法,同样也,new了对象,调用构造函数输出(‘构造块’)
23.关于Java的一些概念,下面哪些描述是正确的:( b )
A.所有的Java异常和错误的基类都是java.lang.Exception, 包括java.lang.RuntimeException
B.通过try … catch … finally语句,finally中的语句部分无论发生什么异常都会得到执行
C.java中所有的数据都是对象
D.Java通过垃圾回收回收不再引用的变量,垃圾回收时对象的finallize方法一定会得到执行
E.Java是跨平台的语言,无论通过哪个版本的Java编写的程序都能在所有的Java运行平台中运行
F.Java通过synchronized进行访问的同步,synchronized作用非静态成员方法和静态成员方法上同步的目标是不同的
解析:A.Error和Exception都是集成Throwable,其中Exception又被IOException和RuntimeException继承/n B.finally语句是无论发生什么异常都会执行的,并且如果try、catch中有return语句,且finally中也有return语句,则finally会覆盖前面的return。值得注意的是,如果try catch中有System.exit(0)的话,就会提前退出 C.java中有基本数据类型,如int,boolean,他们的包装对象是Integer和Boolean,所以不是万物皆对象 D.首先,垃圾回收的优先级相当低。另外,即使垃圾回收器工作,finalize()也不一定得到执行,这是由于程序中的其他线程的优先级远远高于执行finalize()函数线程的优先级。或者说,如果是等待清理队列中如果又被调用,则不会执行finallize()。所以说:Java通过垃圾回收回收不再引用的变量,垃圾回收时对象的finallize()不一定会得到执行。 E.java是跨平台的语言,这个主要是由于有针对不同平台的JVM,而JVM可以无差别的执行字节码(.class文件).但是,平台无关并不意味着版本无关,对于高版本编译器编写的java程序可能无法在低版本的java平台中运行。 F.Synchroized修饰非静态方法,是对调用该方法的对象加锁,Synchroized修饰静态方法,是对类加锁(因为类会调用它,)
24.创建线程有几种不同的方式?你喜欢哪一种?为什么?
第一种:继承Thread类
第二种:实现Runnable接口
第三种:实现Callable接口
第四种:Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。:
*①避免点继承的局限,一个类可以继承多个接口。
*②适合于资源的共享
25.下面这段程序的输出结果是()

public class Main {
    public static void main(String[] args) {
        split(12);
    }
    public static int split(int number) {
        if (number > 1) {
            if (number % 2 != 0)
             System.out.print(split((number + 1) / 2));
               System.out.print(split(number / 2));
            }
        return number;
       }
}

A.12136 B.63121 C.61213 D.11236
split(12/2)进栈
split(6/2)进栈
split((3+1)/2)进栈
split(2/2)进栈
split(2/2)出栈,输出1
split((3+1)/2)出栈,输出2
split(2/2)进栈
split(2/2)出栈,输出1
split(6/2)出栈,输出3
split(12/2)出栈,输出6
26.概括的解释下线程的几种可用状态。
新建状态NEW:
线程创建,但没有启动
可运行状态(就绪状态)RUNNABLE: 代表线程正在运行或者不处于阻塞、等待状态的可以被运行的状态。线程创建后或脱离阻塞、等待状态后进入可运行状态。
阻塞状态BLOCKED:
代表线程尝试获得一个锁时无法对锁占用,进入阻塞状态;当该线程能够获得锁时脱离阻塞状态。
等待状态WAITING:
等待线程主动进入等待条件达成的状态,可以使用join、wait、sleep方法。
计时等待状态TIMED_WAITING:
等待状态添加计时器,当等待条件达成或计时器耗尽时脱离等待状态。
中断状态(终止状态)TERMINATED:
线程任务结束或手动设置中断标记
27.运行代码,结果正确的是:
Boolean flag = false;
if(flag = true){
System.out.println(“true”);
}else{

System.out.println(“false”);
}
A.编译错误
B.TRUE
C.FALSE
D.什么也没有输出
当然是true了,=号是赋值,==才是 比较,相当于把true赋值给flag,if为真然后执行输出语句
28.下面的Java赋值语句哪些是有错误的 ()
A.int i =1000;
B.float f = 45.0;
C.char s = ‘\u0639’;
D.Object o = ‘f’;
F.String s = “hello,world\0”;
E.Double d = 100;
选择BF,如果是float需要加f不加f默认就是double类型,F选项考的是拆箱,Double Integer Long Float只接受自己基础类型的数据(double int long float)
29.以下代码段执行后的输出结果为

public class Test {
public static void main(String[] args) {
System.out.println(test());
 
}
private static int test() {
int temp = 1;
try {
System.out.println(temp);
return ++temp;
} catch (Exception e) {
System.out.println(temp);
return ++temp;
} finally {
++temp;
System.out.println(temp);
}
}
}

A. 1,2,2
B. 1,2,3
C. 1,3,3
D. 1,3,2
答案 D
输出try里面的初始temp:1;
temp=2;
保存return里面temp的值:2;
执行finally的语句temp:3,输出temp:3;
返回try中的return语句,返回存在里面的temp的值:2;
输出temp:2。
30.下列代码输出结果为( )

class Animal{
    public void move(){
        System.out.println("动物可以移动");
    }
}
class Dog extends Animal{
    public void move(){
        System.out.println("狗可以跑和走");
    }
    public void bark(){
        System.out.println("狗可以吠叫");
    }
}
public class TestDog{
    public static void main(String args[]){
        Animal a = new Animal();
        Animal b = new Dog(); 
        a.move();
        b.move();
        b.bark();
    }
}

A. 动物可以移动 狗可以跑和走 狗可以吠叫
B. 动物可以移动 动物可以移动 狗可以吠叫
C. 运行错误
D. 编译错误
解析:选择B,编译看左边,运行看右边。 父类型引用指向子类型对象,无法调用只在子类型里定义的方法
31.最后输出什么?
public void test() {
int a = 10;
System.out.println(a++ + a–);
}
解析:结果是21,因为++a是先自增在赋值,a++是先赋值在自增,所以第一次a++,a=10,a–的时候a已经自增完了所以是11 ,10+11=21,此时a自减是10
32.设m和n都是int类型,那么以下for循环语句的执行情况是( )
for (m = 0, n = -1; n = 0; m++, n++)
n++;
A. 循环体一次也不执行
B. 循环体执行一次 是无限循环
C. 有限次循环
D. 循环结束判断条件不合法
解析:选择D,这里面第二个表达式(两个分bai号之间,这du里是n=0)是循环结束条件。n=0的值是zhi0,也就是说条件一直为FALSE,但是for 循环的结束判定条件 是 boolean型 n = 0 是 int 类型 会有编译异常
33.下面程序的运行结果()

   Object obj=new Object();
        List aList=new ArrayList();
        List bList=new LinkedList();
         
        long t1=System.currentTimeMillis();
        for(int i=0;i<50000;i++){
            aList.add(0,obj);
        }
        long t2=System.currentTimeMillis()-t1;
         
        t1=System.currentTimeMillis();
        for(int i=0;i<50000;i++){
            bList.add(0,obj);
        }
        long t3=System.currentTimeMillis()-t1; 

A. t2 B. t2=t3 C. 不确定 D. t2>t3
解析:选择D,ArrayList内部是动态数组实现,在增加空间时会复制全部数据到新的容量大一些的数组中。而LinkedList内部为双向链表,可以按需分配空间,扩展容量简单,因此LinkedList用时少。
34.以下对异常的描述不正确的有()
A.异常分为Error和Exception
B. Throwable是所有异常类的父类
C. Exception是所有异常类父类。
D. Exception包括RuntimeException和RuntimeException之外的异常。
解析:Throwable应该说是错误类(error)和异常(Exception)的父类
35.如下代码,执行结果为:

def f(x):
    if x == 0:
        return 0
    elif x == 1:
        return 1
    else:
        return (x*f(x-1))
print(f(5))

解析:120,递归运算54321,到1的时候return所以退出递归

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值