公司的一个java面试题

  第一次在博客园写文章还有点小紧张。

  我公司里最近在招java开发工程师,我看了同事出的一份面试题,总体还比较简单,考查的都是基础,没有什么奇怪的算法。其中一个题虽然描述很短,但放在了最后一道,同事说还比较经典。我一看还确实是个坑。

题目描述:

  交换两个数。

分析:

  用java实现交换两个数应该是比较经典而又坑的题目,使用过C/C++都知道C/C++的函数可以通过取地址值的方法操作实参,如

void swap(int &a,int &b)
{
    int temp;
    temp=a;
    a=b;
    b=temp;
}

  但使用java的方法就出现问题了:java方法的形参分两种情况,一种是基本类型的参数,这类参数是传值,方法的调用不影响实参,另一种是引用类型,直接传递的是对象。于是问题来了,如何用java实现swap方法。

public class Solution {

    public static void main(String[] args) {
        int a=9;
        int b=4;
        System.out.println("------swap执行前------");
        System.out.println("a:"+a);
        System.out.println("b:"+b);
        swap(a,b);
        System.out.println("------swap执行后------");
        System.out.println("a:"+a);
        System.out.println("b:"+b);
    }

    public static void swap(int a, int b) {
        int temp;
        temp=a;
        a=b;
        b=temp;
    }

}

  结果自然不尽如人意:

------swap执行前------
a:9
b:4
------swap执行后------
a:9
b:4

  这个题如果有人这么回答,结果自然是再见。其实只要像下面这样就可以通过这道题,再向面试官或者在试卷上说明为什么不能写成静态方法,当然面试官满不满意要看他的心情。

public class Solution {

	public static void main(String[] args) {
		int a=9;
		int b=4;
		System.out.println("------swap执行前------");
		System.out.println("a:"+a);
		System.out.println("b:"+b);
		int temp;
	        temp=a;
	        a=b;
	        b=temp;
		System.out.println("------swap执行后------");
		System.out.println("a:"+a);
		System.out.println("b:"+b);
	}

}

  再装逼点就用异或实现数据交换,写成下面这样:

public class Solution {

	public static void main(String[] args) {
		int a=9;
		int b=4;
		System.out.println("------swap执行前------");
		System.out.println("a:"+a);
		System.out.println("b:"+b);
		a=a^b;
		b=a^b;
		a=a^b;
		System.out.println("------swap执行后------");
		System.out.println("a:"+a);
		System.out.println("b:"+b);
	}

}

  或者是:

a=a+b;
b=a-b;
a=a-b;

  或者直接用下面一句:

b=(a+b)-(a=b);

  但绕半天那个问题还是没有解决,那如何是好呢?

  思路一:使用数组交换数据的封装

public class Solution {

    public static void main(String[] args) {
        int a=9;
        int b=4;
        System.out.println("------swap执行前------");
        System.out.println("a:"+a);
        System.out.println("b:"+b);
        int[] arr=new int[]{a,b};
        swap(arr);
        System.out.println("------swap执行后------");
        System.out.println("a:"+arr[0]);
        System.out.println("b:"+arr[1]);
    }

    public static void swap(int[] arr) {
        if(arr.length==2){
            int temp=arr[0];
            arr[0]=arr[1];
            arr[1]=temp;
        }
    }

}

  思路二:自己写一个封装类

public class Solution {
    public int a;
    public int b;
    public Solution(int a,int b){
        this.a=a;
        this.b=b;
    }

    public static void main(String[] args) {
        int a=9;
        int b=4;
        System.out.println("------swap执行前------");
        System.out.println("a:"+a);
        System.out.println("b:"+b);
        Solution s=new Solution(a,b);
        swap(s);
        System.out.println("------swap执行后------");
        System.out.println("a:"+s.a);
        System.out.println("b:"+s.b);
    }

    public static void swap(Solution s) {
        int temp=s.a;
        s.a=s.b;
        s.b=temp;
    }

}

  思路三:定义时候使用包装类Integer(不可行!)

  解释:String,基本类型,包装类型都是值传递。

  

  思路四(实际开发解决方案):开发中我们要交换两个数,直接写三行或者一行代码比调方法效率更高。再者说,开发人员为什么要交换a和b,在下面的代码中直接要什么用什么就好了。实际上,此类问题最常见的步骤是调用工具类后就能直接使用,实际上许多原生的api都有swap()方法,特别是使用集合的工具类Collections进行swap操作就更加方便。

API:  

  public static void swap(List<?> list,int i, int j)

  在指定列表的指定位置处交换元素。(如果指定位置相同,则调用此方法不会更改列表。)

参数:
list - 进行元素交换的列表。
i - 要交换的一个元素的索引。
j - 要交换的另一个元素的索引。
抛出:
IndexOutOfBoundsException - 如果 ij 超出范围 (i < 0 || i >= list.size() || j < 0 || j >= list.size())。
从以下版本开始:
1.4 

  

  思路五(拓展思路):我们能否定义一个工具类SwapUtil,我们自己完善这个工具类后,以后就拿来用就好?

 

  总结:java中的内存分为堆内存(heap)和栈内存(stack),堆就是用来存放对象的,而栈则是存放一些数据基本类型的值。java中一切都是对象!

  另:搞半天我也没有个对象,用java写swap的静态方法问题也是无解。

posted @ 2015-11-18 14:07  鑫大王爷  阅读(227)  评论(0编辑  收藏  举报