当前位置:编程学习 > JAVA >>

java面试题,纠结了半天只做了一半,在线等高手解答!


一个笔试题,补充完整下面的代码,要求是,交换两个数字。
    public static void swap(Integer x, Integer y) {
        
    }

    public static void swap(int x, int y) {
        
    }

我的解答---------------------------

package com.yang.bean;

import java.lang.reflect.Field;



public class Number {

                public static void swap(Integer a, Integer b) {               
                                                Class<?> aType = a.getClass(); 
                                Class<?> bType = b.getClass(); 
                                Integer c = b;                          
                                try {
                                        Field afield = aType.getDeclaredField("value");
                                        afield.setAccessible(true);  
                                        afield.set(a, b);  
                                        Field bfield = bType.getDeclaredField("value");
                                        bfield.setAccessible(true);  
                                        bfield.set(b, c);  
                                } catch (Exception e) {
                                        e.printStackTrace();
                                } 
                        }
  public static void main(String[] args) {
        Integer a = 3;
        Integer b =  5;
        System.out.println(a);
        System.out.println(b);
         Number.swap(a, b);
        System.out.println(a);
        System.out.println(b);
          
  }

}这个方法我试了,输出结果是3 5 5 5
只能把第一个数变成第二个数,而第二个数没变,我考虑了,你要想得到第一个数,而这时第一个数已经被你用第二个数替换了,所以,第一个数就没了。就得到这种结果!你引用地址没变而地址里的内容变了。所以先找个新的吧它寄存起来,可以new一下最后还是没成功!求高手出招 Java 面试题 --------------------编程问答-------------------- 自己先等一下 --------------------编程问答-------------------- 虽然我不知道为什么,但是把field.set改成field.setInt就好了 --------------------编程问答-------------------- 我试了还是原来的结果什么都没变化!
--------------------编程问答-------------------- 1.你的算法错了:c中应该保存a的值。
2.对象和对象的引用没分清楚。
  不要用 Integer c = a,那样a和c就指向同一个对象了。
  应该写成Integer c = new Integer(a),程序就没问题了。
3.反射的概念不清楚。
引用

  一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
  试试下面的代码。
  
public static void swap(Integer a, Integer b) {               
          Class type = a.getClass(); 
          Integer c = new Integer(a);
          try { 
           Field value = type.getDeclaredField("value");
           value.setAccessible(true);  
           value.set(a, b);  
              value.set(b, c);  
          } catch (Exception e) {
                  e.printStackTrace();
          } 
    }
--------------------编程问答-------------------- 这么变态的笔试题啊。
第一题用反射勉强可以实现。
第二题是参数是值传递,方法内部怎么动对调用方都没影响。 --------------------编程问答--------------------
引用 4 楼 pashanhuha 的回复:
1.你的算法错了:c中应该保存a的值。
2.对象和对象的引用没分清楚。
  不要用 Integer c = a,那样a和c就指向同一个对象了。
  应该写成Integer c = new Integer(a),程序就没问题了。
3.反射的概念不清楚。
引用

  一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
  试试下面的代码。
  
public static void swap(Integer a, Integer b) {               
          Class type = a.getClass(); 
          Integer c = new Integer(a);
          try { 
           Field value = type.getDeclaredField("value");
           value.setAccessible(true);  
           value.set(a, b);  
              value.set(b, c);  
          } catch (Exception e) {
                  e.printStackTrace();
          } 
    }

我想通了。我之前的代码是这样:
public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
    Field field = new Integer(5).getClass().getDeclaredField("value");
    field.setAccessible(true);
    int c = a;
    field.setInt(a, b);
    field.setAccessible(true);
    field.setInt(b, c);
  }


当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。

这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。

setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象
--------------------编程问答-------------------- 只能说,这题是个啥表。

如果你改了一个API约定的immutable对象,那就会造成严重后果。比如你把Integer(3)的value改成了5,那以后所有的3装箱之后都变成了5。

至于第二个,传俩int进来,应该是无解的。 --------------------编程问答-------------------- 好难。。 这个事哪个公司的面试。 这么变态。 --------------------编程问答--------------------
引用 7 楼 lcf 的回复:
只能说,这题是个啥表。

如果你改了一个API约定的immutable对象,那就会造成严重后果。比如你把Integer(3)的value改成了5,那以后所有的3装箱之后都变成了5。

至于第二个,传俩int进来,应该是无解的。

赞同!如果我遇到这么恶心的面试题,我当场把出题的人骂死 --------------------编程问答-------------------- 一般公司都是出这种面试题吗? --------------------编程问答-------------------- 我来帮你解决,下面是一个demo:
public void change(int a,int b)
{
   int temp = a;
   a = b;
   b = temp;
  System.out.println("此时的a="+b+"此时的b="+a);
  希望能够帮组你
} --------------------编程问答-------------------- 最经典的答案:
LZ可以把它背下来
public static void swap(int x, int y) {
        x=x+y;
        y=x-y;
        x=x-y;
    } --------------------编程问答-------------------- 好像我想的太简单了。好丢人 --------------------编程问答--------------------

public class SwapTest {
static Integer a;
static Integer b;
int i, j;

public SwapTest(int i, int j) {
this.i = i;
this.j = j;
}

public SwapTest() {

}

public void setX(Integer a) {
this.a = a;
}

public void setY(Integer b) {
this.b = b;
}

public void swap() {
int temp;
temp = i;
i = j;
j = temp;
}

public static void swap(Integer x, Integer y) {
SwapTest swap = new SwapTest();
swap.setX(y);
swap.setY(x);
}

public static void main(String[] args) {

SwapTest st = new SwapTest(1, 2);
st.swap();
System.out.print("x=" + st.i+" ");
System.out.println("y=" + st.j);


a = new Integer(1);
b = new Integer(2);
swap(a, b);
System.out.print("a=" + a.intValue()+" ");
System.out.println("b=" + b.intValue());
}

}
--------------------编程问答-------------------- 额……上面的有个swap方法忘了带参了,随便加两个参数就好了,不影响结果。

public class SwapTest {
static Integer a;
static Integer b;
int i, j;

public SwapTest(int i, int j) {
this.i = i;
this.j = j;
}

public SwapTest() {

}

public void setX(Integer a) {
this.a = a;
}

public void setY(Integer b) {
this.b = b;
}

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

public static void swap(Integer x, Integer y) {
SwapTest swap = new SwapTest();
swap.setX(y);
swap.setY(x);
}

public static void main(String[] args) {

SwapTest st = new SwapTest(1, 2);
st.swap(0,0);
System.out.print("x=" + st.i+" ");
System.out.println("y=" + st.j);


a = new Integer(1);
b = new Integer(2);
swap(a, b);
System.out.print("a=" + a.intValue()+" ");
System.out.println("b=" + b.intValue());
}

}
--------------------编程问答-------------------- static又忘了加了,好吧,我脑子里都是浆糊。

public class SwapTest {
static Integer a;
static Integer b;
static int i, j;

public SwapTest(int i, int j) {
this.i = i;
this.j = j;
}

public SwapTest() {

}

public void setX(Integer a) {
this.a = a;
}

public void setY(Integer b) {
this.b = b;
}

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

public static void swap(Integer x, Integer y) {
SwapTest swap = new SwapTest();
swap.setX(y);
swap.setY(x);
}

public static void main(String[] args) {

SwapTest st = new SwapTest(1, 2);
st.swap(0,0);
System.out.print("x=" + st.i+" ");
System.out.println("y=" + st.j);


a = new Integer(1);
b = new Integer(2);
swap(a, b);
System.out.print("a=" + a.intValue()+" ");
System.out.println("b=" + b.intValue());
}

}
--------------------编程问答-------------------- 除 --------------------编程问答--------------------
引用 6 楼 lcf 的回复:
Quote: 引用 4 楼 pashanhuha 的回复:

1.你的算法错了:c中应该保存a的值。
2.对象和对象的引用没分清楚。
  不要用 Integer c = a,那样a和c就指向同一个对象了。
  应该写成Integer c = new Integer(a),程序就没问题了。
3.反射的概念不清楚。
引用

  一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
  试试下面的代码。
  
public static void swap(Integer a, Integer b) {               
          Class type = a.getClass(); 
          Integer c = new Integer(a);
          try { 
           Field value = type.getDeclaredField("value");
           value.setAccessible(true);  
           value.set(a, b);  
              value.set(b, c);  
          } catch (Exception e) {
                  e.printStackTrace();
          } 
    }

我想通了。我之前的代码是这样:
public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
    Field field = new Integer(5).getClass().getDeclaredField("value");
    field.setAccessible(true);
    int c = a;
    field.setInt(a, b);
    field.setAccessible(true);
    field.setInt(b, c);
  }


当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。

这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。

setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象


这个问题不在set 跟setInt上面,关键看你Integer c 是new出来,重新分配了内存,还是直接是一个引用指向原来A或者B的地址...亲。交换直接C =A ;A =B ; B=C就完事了,把AB指向的地址交换下 --------------------编程问答-------------------- 不知道是不是你们都把问题看复杂了,还是我把问题看简单了。总之,题目的要求我看懂了,你们做题的方法我没能理解。。。
。。我觉得11楼、12楼的答案就很好! --------------------编程问答--------------------
引用 18 楼 qq437562832 的回复:
Quote: 引用 6 楼 lcf 的回复:

Quote: 引用 4 楼 pashanhuha 的回复:

1.你的算法错了:c中应该保存a的值。
2.对象和对象的引用没分清楚。
  不要用 Integer c = a,那样a和c就指向同一个对象了。
  应该写成Integer c = new Integer(a),程序就没问题了。
3.反射的概念不清楚。
引用

  一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
  试试下面的代码。
  
public static void swap(Integer a, Integer b) {               
          Class type = a.getClass(); 
          Integer c = new Integer(a);
          try { 
           Field value = type.getDeclaredField("value");
           value.setAccessible(true);  
           value.set(a, b);  
              value.set(b, c);  
          } catch (Exception e) {
                  e.printStackTrace();
          } 
    }

我想通了。我之前的代码是这样:
public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
    Field field = new Integer(5).getClass().getDeclaredField("value");
    field.setAccessible(true);
    int c = a;
    field.setInt(a, b);
    field.setAccessible(true);
    field.setInt(b, c);
  }


当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。

这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。

setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象


这个问题不在set 跟setInt上面,关键看你Integer c 是new出来,重新分配了内存,还是直接是一个引用指向原来A或者B的地址...亲。交换直接C =A ;A =B ; B=C就完事了,把AB指向的地址交换下


public class Test {

  public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Integer a = 5;

    Field field = a.getClass().getDeclaredField("value");
    field.setAccessible(true);
    field.set(a, 4);

    Integer b = 5;
    System.out.println(b);
  }
}


请问b输出啥?这是我之前讨论的东西 --------------------编程问答--------------------         Integer a = 10;
        Integer b = 11;
        int temp = a.intValue(); 
        a = b.intValue();
        b = temp;
难道我把问题想简单了? --------------------编程问答-------------------- Integer a = 1;
Integer b = 3;

Integer c = 0;
c = a;
a = b;
b = c;

System.out.println(a+":"+b); --------------------编程问答-------------------- 我错了的额额 --------------------编程问答-------------------- 看了大家的回答。。。看不懂了 --------------------编程问答-------------------- 我看看先,在帮你解答 --------------------编程问答-------------------- public static void swap(Integer a,Integer b){
try {
Integer c = new Integer(a);
Field field = a.getClass().getDeclaredField("value");
field.setAccessible(true);
field.set(a, b);

Field field1 = b.getClass().getDeclaredField("value");
field1.setAccessible(true);
field1.set(b, c);

} catch (Exception e) {
e.printStackTrace();
}
} --------------------编程问答--------------------
引用 7 楼 lcf 的回复:
只能说,这题是个啥表。

如果你改了一个API约定的immutable对象,那就会造成严重后果。比如你把Integer(3)的value改成了5,那以后所有的3装箱之后都变成了5。

至于第二个,传俩int进来,应该是无解的。


这么多楼里唯一正解就是你了!
new Integer 在小于128 的时候会重用已有的Integer对象,看SUN JDK的源码可知。
通过反射强行改了值,以后的代码就惨了。所以这样的题目确是很无聊。

第二题倒也不是完全没办法,
可以在方法中呼叫Native方法,或者启动Agent去Hack正在运行JVM,
然后就是C的工作了,找到操作数地址,改之。
坑爹题。

--------------------编程问答--------------------
引用 20 楼 lcf 的回复:
Quote: 引用 18 楼 qq437562832 的回复:

Quote: 引用 6 楼 lcf 的回复:

Quote: 引用 4 楼 pashanhuha 的回复:

1.你的算法错了:c中应该保存a的值。
2.对象和对象的引用没分清楚。
  不要用 Integer c = a,那样a和c就指向同一个对象了。
  应该写成Integer c = new Integer(a),程序就没问题了。
3.反射的概念不清楚。
引用

  一个类只有一个class对象。所以aType和bType其实指向一个对象(afield和bfield也是)。
  试试下面的代码。
  
public static void swap(Integer a, Integer b) {               
          Class type = a.getClass(); 
          Integer c = new Integer(a);
          try { 
           Field value = type.getDeclaredField("value");
           value.setAccessible(true);  
           value.set(a, b);  
              value.set(b, c);  
          } catch (Exception e) {
                  e.printStackTrace();
          } 
    }

我想通了。我之前的代码是这样:
public static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
    Field field = new Integer(5).getClass().getDeclaredField("value");
    field.setAccessible(true);
    int c = a;
    field.setInt(a, b);
    field.setAccessible(true);
    field.setInt(b, c);
  }


当setInt为set的时候,输出的是5 5。我想Java内部应该是在装箱的时候重用了已经存在过的Integer对象。在field.set(b, c)的时候,c是一个值为3的int,要装箱成为值为3的Integer,就重用了a的Integer。然而a却被改成了5,所以c一装箱就变成了5。

这一点可以很容易验证:你把setInt(a, b) 和 setInt(b, c)改成set(a, 5)和set(b, 3),输出的仍然是5,5。

setInt之所以没事是因为它没有经过重新装箱的过程,不会重用Integer对象


这个问题不在set 跟setInt上面,关键看你Integer c 是new出来,重新分配了内存,还是直接是一个引用指向原来A或者B的地址...亲。交换直接C =A ;A =B ; B=C就完事了,把AB指向的地址交换下


public class Test {

  public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Integer a = 5;

    Field field = a.getClass().getDeclaredField("value");
    field.setAccessible(true);
    field.set(a, 4);

    Integer b = 5;
    System.out.println(b);
  }
}


请问b输出啥?这是我之前讨论的东西




这有关系么?输出的4,B跟A指向的是同一块内存,-128到127自动拆装箱只会生成一个对象...你把B= 5换成其他的,你看还会一样么?归根结底就是内存分配的问题 --------------------编程问答-------------------- --------------------编程问答-------------------- 我的的没有那么 复杂.题目就是补充完整下面的代码,要求是,交换两个数字。 能够交换数字不就ok了? --------------------编程问答--------------------  Integer a = 10;
         Integer b = 11;
         int temp = a.intValue(); 
         a = b.intValue();
         b = temp;
难道我把问题想简单了? 
21楼正解! --------------------编程问答--------------------
引用 31 楼 jjk_02027 的回复:
 Integer a = 10;
         Integer b = 11;
         int temp = a.intValue(); 
         a = b.intValue();
         b = temp;
难道我把问题想简单了? 
21楼正解!
一开始只看题目也是这么想的,看了楼主的解答发现忽略了只改形参不能改变实际变量的值……是这个意思吧 --------------------编程问答-------------------- 这个问题很有意思,考的是对象的传递。
public static void swap(Integer x, Integer y)
方法的参数x,与main方法中所声明的变量x虽然都指向了相同的地址,但始终是两个变量。
虽然很多人写了,Integer c = new Integer(x);或是 Integer c = x; 但c始终只是另外一个指向
相同地址的变量,也就是说以下代码:
public static void swap(Integer x, Integer y){
    Integer c = x;
    x = y;
    y = c;
}
只是swap方法内部的变量交互了地址,而不是main方法中的变量交互了地址,无论swap方法如何交换,其实都没main方法变量的事。

还有 29楼的 wei323001 ,你好像还没搞清楚什么是重载。
你的代码明显两次都是调用了public static void swap(int x, int y) 。

当然这问题我也没解决,但看出来,出这考题的人应该是对Java很熟悉的人 --------------------编程问答-------------------- public static void swap(int x,int y){
}
两个int类型的参数能实现交换吗,不是值传递不能改变原参数的吗,求高人指点 --------------------编程问答-------------------- 除
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,