Java中的经典面试题

1.如何结束一个死循环?

        

public class Demo01 {
    public static void main(String[] args) {
        /**
         * 结束死循环。用最多的方式
         */
        while(true){
            System.out.println("怎样结束死循环");
            //方法1
            //break;

            //方法2
            //return ;

            //方法3
            //System.exit(0);

            //方法4
            throw new RuntimeException("结束死循环");
        }
    }
}

2.判断下面输出语句的输出结果

public class Demo02 {
    public static void main(String[] args) {
        //System.out.println(1/0);//抛出ArithmeticException异常

        //System.out.println(1/0.0);//Infinity 无穷的意思

        //System.out.println(0==0.0); //true

        System.out.println(0.0/0.0);//NaN -> Not a Number 不是一个数字
    }
}

 3.简述java语言中的保留字

        答:有goto和const

4.java中的基本类型有几个。

        答:9个。

                分别是:byte,short,int ,long,char,float,double,boolean,void

        注意:怎么验证一个数据类型是基本类型

package cn.dong;

public class Demo01 {
    /**
     * 测试数据类型是否为基本类型
     */
    public static void main(String[] args) {
        Class c1 = byte.class;//利用反射得到对应的字节码文件
        boolean b1 = c1.isPrimitive();//判断是否为基本类型的方法
        System.out.println("byte是否为基本类型:" + b1);

        Class c2 = short.class;//利用反射得到对应的字节码文件
        boolean b2 = c2.isPrimitive();//判断是否为基本类型的方法
        System.out.println("short是否为基本类型:" + b2);

        Class c3 = int.class;//利用反射得到对应的字节码文件
        boolean b3 = c3.isPrimitive();//判断是否为基本类型的方法
        System.out.println("int是否为基本类型:" + b3);

        Class c4 = long.class;//利用反射得到对应的字节码文件
        boolean b4 = c4.isPrimitive();//判断是否为基本类型的方法
        System.out.println("long是否为基本类型:" + b4);

        Class c5 = float.class;//利用反射得到对应的字节码文件
        boolean b5 = c5.isPrimitive();//判断是否为基本类型的方法
        System.out.println("float是否为基本类型:" + b5);

        Class c6 = double.class;//利用反射得到对应的字节码文件
        boolean b6 = c6.isPrimitive();//判断是否为基本类型的方法
        System.out.println("double是否为基本类型:" + b6);

        Class c7 = char.class;//利用反射得到对应的字节码文件
        boolean b7 = c7.isPrimitive();//判断是否为基本类型的方法
        System.out.println("char是否为基本类型:" + b7);

        Class c8 = boolean.class;//利用反射得到对应的字节码文件
        boolean b8 = c8.isPrimitive();//判断是否为基本类型的方法
        System.out.println("boolean是否为基本类型:" + b8);

        Class c9 = void.class;//利用反射得到对应的字节码文件
        boolean b9 = c9.isPrimitive();//判断是否为基本类型的方法
        System.out.println("void是否为基本类型:" + b9);
    }
}

5.java中char能否表示一个汉字?

        答:能,java中一个char占16位,而一个汉字也是占16位。

        补充:char中汉字的Unicode编码的起始和终止分别为4e00~9fa5(十六进制)

package cn.dong;

import java.io.FileWriter;
import java.io.IOException;

public class Demo02 {
    /**
     * 掌握汉字的起始和结束,Unicode编码中表示汉字的范围是4e00~9fa5
     */
    public static void main(String[] args) {
        try {
            FileWriter fw = new FileWriter("d:\\a.txt");
            for (char c = '\u4e00'; c < '\u9fa5'; c++) {
                fw.write(c);
            }
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

a.txt

 6.简述java语言的后缀有几个。

        答:三个。           

                l或L:给long型。 

                f或F:给float型

                d或D:给double型

7.判断下面语句是否正确,如果不正确,用三种方法进行修改。

package cn.dong;

public class Demo07 {
    public static void main(String[] args) {
        /**
         * 判断下面语句是否正确,若不正确,用三种方法进行修改
         */
        float f = 3.14; //错误

        //方法一 将数据类型改为double
        double f1 = 3.14;

        //方法二 加上f后缀
        float f2 = 3.14f;

        //方法三 强制类型转换
        float f3 = (float) 3.14;

    }
}

7.用效率最高的方式完成除2操作。

        答:是向右移位操作(x>>1);而不是x/2.

        注意:移位操作的效率高于乘除。

8.简述while和do-while的区别?

        (1)格式不同:

                while(条件){

                        语句;

                }

                do{

                        语句;

                }while(条件);

        (2)如果条件为true,则两者没有任何区别;

        (3)如果条件为false,那么do-while至少比while多执行一次。

9.简述一下封装。

        答:从结构上看:类体中包含属性和方法,换言之,类体将属性和方法封装了起来。

        从访问权限看:如果一个类的属性或方法是私有的(private),外类不能访问,即使你使用"."也不行。这样做的好处就是防止外类给这个对象的属性赋非法值。我们只能通过公有方法给私有属性赋值。我们可以在共有方法内部添加条件语句,来判断输入的值是否合法,而有选择的给属性赋值。进而保护了属性。

10.构造器的特点

        (1)是一个方法;

        (2)没有返回类型

        (3)方法名必须跟类名相同

        (4)可以用public,protected,默认,private(3p+默认)来进行修饰,但不能使用static,final,abstract来修饰

        (5)可以有return;

        (6)可以抛出异常

11.方法的覆盖和重载

        (1)方法的覆盖

                规则:

                    

         (2)方法的重载:一个类中方法名相同但方法的参数不同,则称为方法的重载。

               注意:参数不同是指参数的个数不同或者是参数类型不同;跟参数名无关,也跟方法的返回值和修饰符无关。

代码演示:

package cn.dong.demo;

public class Demo01 {
    /**
     * 方法的重载
     *      一个类中方法名相同,但参数不同方法叫做方法的重载。
     *      注意:参数不同是指参数的类型不同或者参数的个数不同;
     *      与方法的返回值和参数名无关
     */

    public void aaa(int a,double b){

    }
    public int aaa(int a,int b){
        return 0;
    }
    public double aaa(double a,int b){

        return 0;
    }
    public void aaa(int a,int b,int c){

    }

}

12.super关键字

        用法1:super.方法名(),在子类中调用父类的构造方法。

        用法2:super.属性名,在子类中调用父类的属性。

        用法3:super(参数列表),在子类的构造器中调用父类的构造器。

用法3的实例:

        G.java

package cn.dong.demo1;

public class G {

    public G(){
        System.out.println("G()构造器");
    }

    public G(String s){
        System.out.println("G(String)构造器");
    }

        F.java

package cn.dong.demo1;

public class F extends G{

    public F() {
        //super();
        System.out.println("F()构造器");
    }

    public F(String s) {
        //super();
        System.out.println("F(String)构造器");
    }
}

        S.java

package cn.dong.demo1;

public class S extends F{

    public S(){
        //子类构造器中默认调用父类的默认(无参)构造器
        //super();
        System.out.println("S()构造器");
    }

    public S(String s){
        System.out.println("S(String)构造器");
    }

    public static void main(String[] args) {
        S s = new S();
    }
}

        运行S.java中的主方法的结果为:

        

 当S.java中主方法的调用有参的构造器创建对象时,即

package cn.dong.demo1;

public class S extends F{

    public S(){
        //子类构造器中默认调用父类的默认(无参)构造器
        //super();
        System.out.println("S()构造器");
    }

    public S(String s){
        System.out.println("S(String)构造器");
    }

    public static void main(String[] args) {
        S s = new S("lll");
    }
}

        运行的结果为:

      

 13.Object类的父类是什么

        答:Object类没有父类。

                那么,怎样求一个类的父类,我们可以用反射的知识来演示

                

package cn.dong.demo04;

public class Test {

    public static void main(String[] args) {
        /**
         * 用反射判断一个类的父类
         * getClass():返回类的字节码对象
         * getSuperclass():返回该类父类的字节码对象
         */
        S s = new S();
        Class c = s.getClass();//得到s的字节码对象

        Class sc = c.getSuperclass();
        System.out.println(sc.getName());//cn.dong.demo04.F

        Class scc = sc.getSuperclass();
        System.out.println(scc);//class java.lang.Object

        Class sccc = scc.getSuperclass();
        System.out.println(sccc);//null

    }
}

class F{

}
class S extends F{

}

13.final关键字:final表示最终的,可以用来修饰变量,方法和类;

        (1)修饰一个变量时,由于这个变量值不能改变,这个变量就变成了一个常量;

        (2)修饰一个方法时,这个方法是最终方法,不能被子类覆盖;

        (3)修饰一个类时,这个类是最终类,不能被其他类继承。

14.哪些情况下一个一个类没有子类?

        答:(1)用final修饰的类没有子类

                (2)一个类中的所有构造器都是私有的类不能被继承

15.接口的父类是Object类?

        答:错。接口没有父类,可以通过反射来验证。

public class Demo01 {
    //验证接口的父类是否是Object
    public static void main(String[] args) {
        Class c = Area.class;
        Class su = c.getSuperclass();//得到接口父类的字节码对象
        System.out.println(su);//null
    }
}

16.接口也具有继承性,但它不像类,它可以有多个父接口

        代码演示:

public interface Area {
    double getArea();
}

public interface Period {
    double getPeriod();
}

public interface Common extends Area,Period{
    //一个接口可以继承多个接口
    //接口也具有继承性,但它不像类,它可以有多个父接口。
    void show();
}

17.判断下面程序的输出结果。

public class Demo06 {
    public static void main(String[] args) {
        String s = "i love java";
        String s1 = s.replace('l', 'i');
        System.out.println(s==s1);//false

        String s2 = s.replace('l','l');
        System.out.println(s==s2);//true

    }
}

【注意】第二条输出语句的结果为true,为什么呢?我们通过源码来分析

public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

18.比较String类,StringBuffer类和StringBuilder类的异同.

        首先我们来看看这三个类的定义:

String类:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

}

StringBuffer类:

public final class StringBuffer extends AbstractStringBuilder implements         java.io.Serializable, CharSequence
{

}

StringBuilder类:

public final class StringBuilder extends AbstractStringBuilder implements         java.io.Serializable, CharSequence
{

相同点:

        1.这三个类都是用final修饰,都属于最终类,没有子类;

        2.它们都实现了Serializable接口和CharSequence接口;

        3.StringBuffer和StringBuilder中的定义,构造器,方法都一样;

不同点:

        1.String类在创建对象时,其对象是不会改变的,而StringBuffer和StringBuilder是可变的;

        2.StringBuffer类是线程安全的,因为该类中的许多方法都是用synchronized修饰的;而StringBuilder类是线程不安全的,但是StringBuilder类的效率要远远大于StringBuffer类;

        3.StringBuilder类中的大多数的方法都是返回自身,所以StringBuilder适用于链式编程。

19.比较java.lang.Error和java.lang.Exception的异同?

        答:

         相同:它们的父类都是Throwable类.

         不同点:Exception类是可以从任何标准Java类方法中抛出的基本类型异常,也是程序员需要处理的; Error代表编译期和系统错误,不需要程序员处理。

20.比较RuntimeException和Exception类的异同,并举出至少5个RuntimeException的子类。

答:Exception分为RuntimeException和其他Exception异常,RuntimeException异常(又称不受检查异常)是由Java虚拟机抛出的,不需要程序员处理;而其他Exception(又称受检查异常)必须由程序员处理,处理的方式有两种,一种是try-catch,另一种是用throws抛出异常。

        RuntimeException的子类:

                ArithmeticException类

                ArrayIndexOutBoundsException类

                IllegalArgumentException类

                NumberFormatException类

                ClassCastException类

                NegativeArraySizeException类

                StringIndexOutBoundsException类

                

 21.关于异常的一些问题   

1.异常类中都没有自己特有的方法,为什么还要定义那么多异常类型?
    答:为了根据不同的异常类型,处理不同的特殊情况。
    如果所有的异常都是用Exception类型,那么我们就无法针对特定的异常做出特定的处理。
    不能用message来判断异常的类型,message是字符串的表示形式,用来判断异常类型不严谨,而异常类是唯一的,能够很方便的判断异常的类型。
    
2.jdk中有那么多异常类型,为什么还要自定义异常?
    答:
    (1)因为jdk中的异常类型还是有点笼统,不详细
    (2)有些情况,在jdk中不算一个异常,而在具体的业务开发中,这种情况不能发生,这时候我们就要自定义异常。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值