[Java面试题]Java基础面试题解析

题一

知识点:继承

class C {
	    C() {
	        System.out.print("C");
	    }
	}
	 
	class A {
	    C c = new C();
	 
	    A() {
	        this("A");
	        System.out.print("A");
	    }
	 
	    A(String s) {
	        System.out.print(s);
	    }
	}
	 
	class Niuke00 extends A {
		Niuke00() {
	        super("B");
	        System.out.print("B");
	    }
	 
	    public static void main(String[] args) {
	        new Niuke00();
	    }
	}

代码运行结果:CBB

这道题很简单,注意类加载的大概顺序:父类的静态->子类的静态->父类的初始化块->父类的构造方法->子类的初始化块->子类的构造方法

题二

知识点:拆箱与装箱

通俗得讲,基本数据类型转化成包装类是装箱(如: int  -->  Integer)
包装类转化成基本数据类型就是拆箱 (如:Integer  -->  int)
包装类就是引用类型,基本数据类型就是值类型

public class Niuke02 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Integer i01=59;
		int i02=59;
		Integer i03=Integer.valueOf(59);
		Integer i04=new Integer(59);
		
		System.out.println(i01==i02);//true
		System.out.println(i01==i03);//true
		System.out.println(i03==i04);//false
		System.out.println(i02==i04);//true
    }
}

这题也很简单,i03==i04输出false的原因是:i04是通过new关键字创建,new Integer(59)会在堆内存中分配一个新的对象(值为59),而i04是在栈中引用堆中的数据,i03和i04在堆内存中不是同一个[地址],我们知道"=="不仅要比较值还要比较地址,故返回false。大致内存图如下:


题三

知识点:拆箱与装箱

        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        System.out.println(c == d);//true
        System.out.println(e == f);//false
        System.out.println(c == (a+b));//true
        System.out.println(c.equals(a+b));//true
        System.out.println(g == (a+b));//true
        System.out.println(g.equals(a+b));//false

该题中需要注意两个地方:1、"=="和"equals()"的区别,简单的讲,"=="不仅仅比较对象的值还要比较对象所在的内存地址是否相等,相等返回true,否则返回false;而"equals()"方法只比较值的大小 2、“e==f”输出false的原因是,整形池IntegerCache通过valueOf产生包装对象时,如果int参数在-128到127之间,则直接从整型池中获得对象,不在该范围的int类型则通过new生成包装对象。Jdk的源代码如下:

 public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

题四

知识点:参数传递、局部变量

class Value {
	public int i = 15;
}

public class Niuke03 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Niuke03 niuke03 = new Niuke03();
		niuke03.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 v1, int i) {
		i = 0;
		v1.i = 20;
		Value val = new Value();
		v1 = val;
		System.out.println(v1.i + " " + i);
	}
}

上面的代码中为便于理解,我把原题中second的v改为了v1

注意Java由于没有指针这个概念,所以参数传递时都是值传递没有引用传递,可以通过传对象来达到引用传递的效果。在方法的形参中,传入的实参是值传递,只是将原来的地址值赋予了新的引用变量,即形参是一个新的引用变量

在该题中注意调用first()和second()时的内存变化,相关内存如下:



代码最后运行结果:

15 0

20

题五

知识点:replaceAll()

String classFile = "com.jd.".replaceAll(".", "/")+"Myclass.class";
System.out.println(classFile);

代码运行结果:

///////Myclass.class

题六

知识点:递归、位运算

public  class Niuke05{
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Niuke05 niuke5 = new Niuke05();
		System.out.println(niuke5.Sum_Solution(7));
		System.out.println(niuke5.addWithoutArithmetic(5,9));
		//System.out.println(9<<2);
	}
	//不能用關鍵字求1+2+3+..+n的值
	public int Sum_Solution(int n) {
		int sum = n;
		boolean flag = (n>0)&&((sum+=Sum_Solution(n-1))>0); 
		return sum;
	}
	//不能用+,-,*,/求兩個整數的和
	int addWithoutArithmetic(int num1,int num2){
	    if(num2 == 0)
	        return num1;
	    int XORresult = num1 ^ num2;
	    int carry = (num1 & num2)<<1;
	    return addWithoutArithmetic(XORresult,carry);
	}
}

这个需要基础非常好的才能解答,该代码也是参考别人的

题七

知识点:try-catch

public class Niuke07 {
	private static String output = "";
	
	public static void foo(int i){
		try {
			if(i==1){
				throw new Exception();
			}
		} catch (Exception e) {
			// TODO: handle exception
			output +="2";
			return;
		}finally {
			output += "3";
		}
		output += "4";
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		foo(0);
		foo(1);
		System.out.println(output);
	}
}

第一次foo(0)没有捕获到异常,程序运行结束后output=“34”;第二次foo(1)后抛出了一个异常,程序执行catch()中的代码在return前output="342",然后程序并不会马上返回(需要执行完finally代码),即output="3423",此时程序已经返回不在执行output+="4"代码

代码运行结果为:

3423

题八

知识点:Java类中相关构造方法(代码块)加载顺序

class AAA {
	static{
		System.out.println("父類靜態代碼塊");
	}
	public AAA(){
		System.out.println("父類構造方法");
	}
	{
		System.out.println("父類構造塊");
	}
}
public class Niuke08 extends AAA{
	static{
		System.out.println("子類靜態代碼塊");
	}
	public Niuke08(){
		System.out.println("子類構造方法");
	}
	{
		System.out.println("子類構造塊");
	}
	
	public static void main(String[] args) {
		new Niuke08();
	}
}

代码运行结果为:

父類靜態代碼塊
子類靜態代碼塊
父類構造塊
父類構造方法
子類構造塊

子類構造方法

题九

知识点:for()循环

public class Niuke09 {
	static boolean foo(char c){
		System.out.println(c);
		return true;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int i = 0;
		for(foo('A');foo('B')&&(i<2);foo('C')){
			i++;
			foo('D');
		}
	}
}

这个就是演示了for()循环的执行流程,结合概念很容易理解

代码执行结果:

A
B
D
C
B
D
C

B

题十

知识点:参数传递

 public static void add3(Integer i){
    	int val=i.intValue();
    	val +=3;
    	i=new Integer(val);
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	    Integer i=new Integer(0);
	    add3(i);
	    System.out.println(i.intValue());
	}

参考题四,相关内存图就不画了

代码运行结果:

0

题十一

题目描述:编写程序实现字符串反转,比如原始字符串为"happyBirthday"反转后为"yadhtriByppah"

public  String reverse(String originStr) {
        if(originStr == null || originStr.length() <= 1)
            return originStr;
        String sub = originStr.substring(1);
        char cha = originStr.charAt(0);
        //System.out.println(sub+"--"+cha);
        //遞歸
        return reverse(sub)+cha;
    }

注意subString()和charAt()方法

题十二

题目描述:输入年、月、日,计算算该天是这一年中的第几天

代码如下

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()){
            int y = scanner.nextInt();
            int m = scanner.nextInt();
            int d = scanner.nextInt();
            int[] a = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
            int[] b = new int[]{31,29,31,30,31,30,31,31,30,31,30,31};

            int count = 0;
            if(isLeap(y)){
                for(int i=0;i<m-1;i++)
                    count += b[i];
            }else{
                for(int i=0;i<m-1;i++)
                    count += a[i];
            }
            count += d;
            System.out.println(count);
        }
    }
    public static boolean isLeap(int y){
        if(y%4==0&&y%100!=0||y%400==0)
            return true;
        else
            return false;
    }

题十三

题目描述:输入多种材料名称,输出一个数字表示完成所有料理需要多少种不同的材料。例如
输入:
BUTTER FLOUR
HONEY FLOUR EGG
输出:

4

代码如下:

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        HashSet<String> set = new HashSet<>();
        while (scanner.hasNext()){
            String str = scanner.nextLine();
            String[] arr = str.split(" ");
            for(int i=0;i<arr.length;i++)
                set.add(arr[i]);
        }
        System.out.println(set.size());
        set.clear();
    }

题十四

知识点:try-catch

    static public void main(String[] args)  {
        System.out.println(test01.test());
    }
    static int test()
    {
        int x = 1;
        try

        {
            return x;
        } finally
        {
            ++x;
        }
    }

代码运行结果是:

1

这个也是很经典的,因为finally总是在try-catch执行之后执行,而且一定是在return之前执行,更准确的说是在return中执行。finally执行也改变不了return的值,return的值已经是1了,finally执行完后x的值成了2。finally一定会执行?在return前还是return后执行?参考解析Java finally













发布了30 篇原创文章 · 获赞 76 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/a1275302036/article/details/80309182