查看原文
其他

这次面试被逻辑运算符给“算计”了,读者:我想哭~

The following article is from 鸭哥聊Java Author 鸭哥

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


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


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


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


好了,切入正题。


# 面试题


先来看面试题,如下:

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

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


# 考查知识点


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

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


关于 `&&` 和 `||` ,一个常见的疑问或者考点就是,一个表达式是否是短路(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); }}


程序的运行结果为:


分析:


a, b 的初始值均为 0,


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


第二个 if 条件也是同样的道理,a = 1,  `a++ > 0` 为 `true` ,整个表达式为 `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到了吗?你工作中,因为逻辑运算符踩过什么坑?欢迎在评论区与大家分享!


热门推荐:
: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存