最近,鸭哥的读者被某大厂邀请去面试,他本不打算去的,但,我告诉他,“你不去试一下,你永远不知道你到达了什么段位?”

因此,他才鼓足勇气,决定拼死一战。然而,一面中,却被逻辑运算符给“算计”了~

到底是怎么样的一到题呢?让我慢慢来给他和在坐的小伙伴分析一下。

说实话,这是一份笔试题中的一道选择题,他当时选错了,记忆犹新。后来,他跟这个面试官互加了微信,了解了一下,他们公司专门有一个面试题库,会随机从题库里面,取几道题来,来考查应聘者的基础知识。

好了,切入正题,先来看面试题。

面试题

public class Test{
    public static void main(String[] args){
        int x = 0;
        int y = 0;
        int k = 0;
        for (int z = 0; z < 5; z++) {
            if ((++x > 2) && (++y > 2) && (k++ > 2))
            {
                x++;
                ++y;
                k++;
            }
        }
        System.out.println(x + "" + y + "" + k);
    }
}

上面程序的输出结果为:

A.432    B.531    C.421    D.523

来来来,先选择你心目中的答案,后面揭晓。

考查知识点

首先,我们应该明确题目涉及的知识点,显然,上面的题目考察的是逻辑运算符的知识。

1.png

提到逻辑运算符,我们首先想到的是 &&|| ,即逻辑与和逻辑或,同时不要忘了 逻辑非 ! 。这三个逻辑运算符,逻辑与和逻辑或是二元运算符(所谓的二元运算,是指对两个操作数进行运算),而逻辑非则是一元运算符。

关于 &&|| ,一个常见的疑问或者考点就是,一个表达式是否是短路(short-circuits)的。如果由左端表达式可推算出整个表达式的值,我们称为“短路”,始终执行逻辑运算符两边的表达式称为“非短路”。逻辑与和逻辑或构成的表达式是否具有短路特性呢?我们可以用实例验证。

//需要验证的内容如下:

if(a && b)    //如果 a 为 false, Java还会校验 b 吗?

if(a || b)    //如果 a 为 true, Java还会校验 b 吗?

鸭哥应该给大家讲清楚了吧!

实践出真知

受文章开头题目的设计思路启发,我们可以用下面的例子验证逻辑与和逻辑或运算符的特性:

public class FunnyTest{
    public static void main(String[] args){
        int a = 0;
        int b = 0;
        
        if((a++ > 0) && (b++ > 0)) ;
        
        System.out.println("如果结果为1 0,则逻辑与具有短路特性:" + a +" " + b);
        
        //此时a = 1, b = 0 
        
        if((a++ > 0) || (b++ > 0)) ;
        
        System.out.println("如果结果为2 0,则逻辑或具有短路特性:" + a +" " + b);
    }
}

程序的运行结果为:

2.png

分析:

a, b 的初始值均为 0,

第一个 if 条件执行后, a 的值加 1 ,b 的值不变,说明当 Java 执行 a++ > 0 的结果为 false 后,整个表达式即为 false,不再验证 b++ > 0 的值;

第二个 if 条件也是同样的道理,a = 1, a++ > 0true ,整个表达式为 true ,不再验证 b++ > 0 的值。

所以,&&||组成的表达式都具有短路特性

回归题目

回到文章开头的题目,模拟程序的执行过程如下:

当z=0,执行++x > 2不成立, &&后面不执行,此时 x=1,y=0,k=0;

当z=1,执行++x > 2不成立, &&后面不执行,此时 x=2,y=0,k=0;

当z=2, 执行++x > 2成立, 继续执行 ++y > 2不成立 , &&后面不执行, 此时 x=3,y=1,k=0;

当z=3,执行++x > 2成立,继续执行++y > 2不成立 , &&后面不执行, 此时 x=4,y=2,k=0;

当z=4,执行++x > 2成立,继续执行 ++y > 2成立 , 继续执行k++>2 ,不成立,此时 x=5,y=3,k=1;

(注意:5次循环都没有满足if条件)

当z=5,不满足条件for循环条件,跳出循环。

打印结果: x=5, y = 3, k = 1。 所以,正确答案为 B ,你答对了吗?

引申思考

我们平时工作,很多场景其实都利用了 &&|| 运算符的短路特性,比如字符串的判断及后续处理:

我们可以这样写,

if (str != null && !str.isEmpty()) {
  doSomethingWith(str);
}

也可以这么写,

if (str == null || str.isEmpty()) {
  unusableString();
} else {
  doSomethingWith(str);
}

如果没有短路特性,上述写法是会报异常的。因为若str = null ,执行 str.isEmpty() 时将会报NullPointerException。也就是说,上述两种写法,&& 和 || 左右两侧表达式的顺序不能互换,必须先判断 str 是否为 null , 再执行str.isEmpty().。

这个知识点,你get到了吗?你工作中,因为逻辑运算符踩过什么坑?欢迎在留言区与大家分享!

标签: java, Java面试题, stackoverflow中文版, 逻辑运算符