一道简单的java面试题

题目很简单,完成代码,判断一个整数是否是奇数:

public boolean isOdd(int i)

这道笔试题好多答案都长这样(换做是我,我第一反应应该也是这样了...):

public boolean isOdd(int i) {
    if (i % 2 == 1) {
        System.out.println("是奇数");
    } else {
        System.out.println("是偶数");
    }
}

然后编译一下,发现错误了再改成这样(报错是因为缺少返回类型):

public boolean isOdd(int i) {
    if (i % 2 == 1) {
        return true;
    } else {
        return false;
    }
}

进行引导:

“这个函数的定义要求返回一个什么类型的值?”

“布尔类型。”

“那么,你if后面的括号里面的表达式的值是一个什么类型的?”

“也是布尔类型。”

遂能够把代码优化成这样:

public boolean isOdd(int i) {
    return i % 2 == 1;
}

继续进行引导:

“那我传进来一个-1呢?”

“从小被教导只有自然数才有奇数偶数之分,负数没有奇偶这一说。”

“是吗?”

有的人能接受这个设定,就会把代码改成这样:

public boolean isOdd(int i) {
    return i % 2 == 1 || i % 2 == -1;
}

//并且在提示之后优化成这样:
public boolean isOdd(int i) {
    return i % 2 != 0;
}

继续引导:

“有更好的办法吗?”

“?”

“我觉得取模操作比较慢,有更快的解决方案吗?”

除了少数人能自己想想就想出来了之外,绝大部分表示没有或者不知道,于是进行下一步提示:

“奇数和偶数转换成二进制有什么区别?”

奇数最后一位是1,偶数最后一位是0。

“然后呢?”

这里很奇怪,大部分能聊到这里来的候选人会想起来移位操作,但不知道是为什么,虽然这道题确实可以有这种操作(但这个根根本不是重点好吧!):

public boolean isOdd(int i) {
    return i >> 1 << 1 != i;
}

应该是写成下面这样的:

public boolean isOdd(int i) {
    return (i & 1) == 1;
}

“这样是不是比上面取模运算要快?”

“那当然了,位运算肯定快啊。”

“但是我们实际代码测试过,发现上面的按位与操作和取模操作,实际运行的时间是差不多的,为什么呢?”

“编译器会将对2的指数的取模操作,优化成位运算操作。”

补充按位与的操作原理:

查看更多位运算原理     &&  文章转载出处 

猜你喜欢

转载自blog.csdn.net/Steriles_/article/details/88218316