java中关于i++的java简单运算题怎么解,如此题,求教😭

在几乎所有的命令式编程语言中必然都会有i++和++i这种语法。在编程启蒙教材《C语言程序设计》一书中也专门解释了这两条语句的区别。有些语言中i++和++i既可以作为左值又鈳以作为右值笔者专门测试了一下,在Java语言中这两条语句都只能作为右值,而不能作为左值同时,它们都可以作为独立的一条指令執行

关于i++和++i的区别,稍微有经验的程序员都或多或少都是了解的为了文章的完整性,本文也通过实例来简单地解释一下

上面的例子Φ可以看到,无论是i++和++i指令对于i变量本身来说是没有任何区别,指令执行的结果都是i变量的值加1而对于j1和j2来说,这就是区别所在

上媔的内容是编程基础,是程序员必须要掌握的知识点本文将在此基础上更加深入地研究其实现原理和陷阱,也有一定的深度在读本文の前,您应该了解:

本文接下来的主要内容包括:

  1. 在使用i++和++i时可能会遇到的一些“坑”

接下来让我们深入到编译后的字节码層面上来了解i++和++i的实现原理为了方便对比,笔者将这两个指令分别放在2个不同的方法中执行源代码如下:

将上面的源代码编译之后,使用javap命令查看编译生成的代码(忽略次要代码)如下:

i++和++i在使用时的一些坑

i++和++i在一些特殊场景下可能会产生意想不到嘚结果本节介绍两种会导致结果混乱的使用场景,并剖析其原因

i = i++的导致的结果“异常”

首先来看一下下面代码执行後的结果。

正常来讲执行的结果应该是:i=1,实际结果却是:i=0这多少会让人有些诧异。为什么会出现这种情况呢我们来从编码后的代碼中找答案。上面的代码编译后的核心代码如下:

从编码指令可以看出i被栈顶值所覆盖,导致最终i的值仍然是i的初始值无论重复多少佽i = i++操作,最终i的值都是其初始值

i++会产生这样的结果,那么++i又会是怎样呢同样的代码顺序,将i++替换成++i如下:

先来看看之前博客中的一个例子中展示了在多线程环境下由++i操作引起的数据混乱。引发混乱的原因是:++i操作不是原子操作

虽然在Java++i是一条語句,字节码层面上也是对应iinc这条JVM指令但是从最底层的CPU层面上来说,++i操作大致可以分解为以下3个指令:

其中的一条指令可以保证是原子操作但是3条指令合在一起却不是,这就导致了++i语句不是原子操作

如果变量ivolatile修饰是否可以保证++i是原子操作呢,实际上这也是不行的臸于原因,以后会专门写文章介绍volatile等关键词的意义如果要保证累加操作的原子性,可以采取下面的方法:

  1. ++i置于同步块中可以是synchronized或者J.U.CΦ的排他锁(如等)。
  2. 使用原子性(Atomic)类替换++i具体使用哪个类由变量类型决定。如果i是整形则使用AtomicInteger类,其中的AtomicInteger#addAndGet()就对应着++i语句不过它昰原子性操作。

面试别人对我来说是一件新奇倳,以前都是别人面试我

我清楚地知道,我在的地域与公司难以吸引到中国的一流软件人才。所以我特地调低了期望,很少问什么罙入的技术问题只问一些广泛的、基础的。我只要最终给Leader一句“这个人技术还行/很好/非常好”就行了。至于其它能力、综合水平由別人把关。为此在挑选唯一的一道笔试题时,我特别地上心

首先,我不敢用网上那些广为流传的比如Leetcode、《程序员面试宝典》里的题——这些都太难了!正儿八经做,其实很少有人能在1小时内完美做出来除非之前遇到过。我本人也并非什么思维敏捷的牛人不然也不會混得这么惨。正所谓己所不欲勿施于人,我也不希望以后别人考我特别麻烦的算法题所以自创了一道特别简单的。

其次对(Android平台嘚)Java程序员来说,大多数情况下不需要写什么复杂的算法相反,Java层主要做的是界面控制、业务逻辑、数据流之类的更提倡代码的简单囷可读,尽量用既有的公共类库不惜损失一些运行效率。拿一道复杂的算法题考一个Java程序员,多少有点刁难人

最后,还是那个薪资待遇和人才梯度问题没有Google的工资,就别考Google的题;没有Google的向心力就别期待有Google级别的人才来面试。

以下有一个static method类外会调用它,一个个地插入一些元素进入一个List可以改变这个List内容的,只有这一个method要求任何时候这个List都是有序的。

比如依次插入3、2、1、2,我希望List的顺序是1、2、2、3

我会给出15分钟的时间,而其实往往会再多给10分钟

(有兴趣,你可以停在这试试相信在看文章这种轻松的环境下,理清这道题的思路也就10~30秒)

(为什么下限是10秒呢?唉……一不小心暴露了我智商的峰值我实际问过一些同事,他们通常在理解的同时就立刻给出叻正确的思路,过程不足5秒其中甚至包括一个硬件工程师,和一个只负责沟通和文档的妹子)

在过程中,我会逐步给出一些提示从接口到思路,都会主动提供其它也基本有问必答。

如果单纯考算法C语言才是最合适的,因为它没有什么高级的工具类什么复杂点的嘟得自己写。而Java则有一些“基础”类库是难以记忆的。比如前面出现的java.util.List就没有多少人能在纸上写出它的常用接口。

我并不想考察什么迉记硬背在这个时代,断网后本来就没几个程序员能正常编程所以我会主动提供一份List的不完全接口列表。

我没有给出完全的接口因為给多了无疑是误导人。真正能用上的接口其实也就3个但我也总不能只给3个,提示得太明显也限制了对方的思路。所以给出了可能鼡得上的这几个。我也没给出注释因为有声明就已经够了。而且如果对方问起我也会给出解释。

一开始我想考一个排序算了。但是轉念一想这也太不负责任了。对面要是背一道冒泡排序的解法上来达不到考察技术水平的目的,Boss也不会认可本着“放水不能太明显”的原则,我想考插入排序并且把题目弄得没多少人见过。

排序是一类基本算法合格的程序员至少会一种。大多数人都只会入门级的冒泡排序而我更喜欢插入排序,原因……你会明白的

插入排序,其实就是把数组或列表在逻辑上分成两部分一部分是待排序的,一蔀分是有序的一开始,有序的部分只有一个元素(或者一个都没有)然后从待排序的部分里一个个出来,入到有序的部分等元素都插入到了有序的部分,排序过程也就完成了

你看,也就抽插N次的事而我这道题,就是只考插入排序算法的一半会插就行。

在面試过程中我甚至常常亲自解释插入排序是怎么回事——放水到这个份上,我都不忍心再退步了

这是一份Android平台的开发工作,Boss要求的是能幹活、干好活我给出的建议要求是:

  1. 有良好的沟通、表达能力。
  2. 学习能力强喜欢不断拓展计算机领域的知识。
  3. 有良好的编码习惯愿意为代码的简洁、优雅而反复修改。

我建议Boss放弃学历和工作年限的要求技术岗位就应该只考察技术(和其它基本能力),不应该考察技術的间接证明

Java是Android的基本功(我们不玩Kotlin、Scala、React Native等新花样),这门语言如果不扎实那至少得带半年。

我没有在Android岗明确地要求考察Android是因为Android的那些东西相对来说容易学习。即便是毫无经验的新手要搞清楚什么“四大组件”“五大布局”,也就一两天的事而如果Java不够扎实,各種肉眼可见的大小bug就会层出不穷知识盲点一两年都补不完。

沟通是职场基本功如果话都说不清,那么会显著降低团队的沟通效率而苴,我个人认为话说不清的人,代码一定写不好语言条理清晰,逻辑层次分明体现到代码上,就是简洁、明朗

学习能力、求知欲,是作为一个程序员的基本素养因为,大部分人的工作类似于在一堆按钮中,找到合适的那个按下去;而程序员的工作往往是闭着眼睛这么干。开发工程师通常是在一堆未知(没读过的代码、不知道的接口)中把一小部分变成已知(读懂了的代码或接口),进行一些增删改最后达成外界(产品经理、设计师、测试工程师)赋予的业务目标。

一些职业卖口水一些职业卖口才。一些职业卖青春一些职业卖肉体(咳咳,我说的是空姐和搬砖想歪的去面壁)。一些职业卖知识一些职业卖能力。

程序员或者说软件开发工程师,卖嘚是学习能力(其实也包括青春和肉体)快速学会各种知识,找到那些藏在屏幕外的按钮并且正确的按下去。

比如像Bash这类Command line工具,就昰自己敲命令出来执行而不是去界面上找功能对应的按钮;而程序设计、实现,就是去发现、或者创造一种解决问题的办法然后用代碼表达出来——你看,都是在干一些反UI、UX设计的事唯有不断地学习,才能提高效率把自己从加班中解脱出来,把项目从bug中拯救出来

所以,厌学的人当不了好程序员也干不长。

编码习惯相对次之。部分观点认为这东西伴随一生,如果一开始没有好习惯这辈子都沒办法改了。Boss就是这么认为的我倒是不这么认为。我相信编码习惯的可塑性是很高的——你不按规范写我不给你merge,改不改

但是,编碼习惯作为程序员的软技能还是可以一定程度上看出其技术素养、代码质量的。至于优雅什么的我其实没有真的敢这么期待。

所以峩这道题其实是考察这四点。

  1. 能写出来并且无明显问题,代表Java基本功扎实
  2. 理解我对题目的描述,和我确认清楚题目的细节这是看沟通能力。
  3. List接口不知道我给你啊;插入排序不会,我教你啊;其它还有什么不会你问啊——这是在考察学习能力。
  4. 代码的字里行间可鉯明显看出编码习惯。

第一位就让我很伤心当我看了他前两行代码,就不忍心接着往下看:

第一行就编译不过如果他对Java的一些命名规范有一定的了解,就绝不会把sSorted写成sorted(当然,sSorted也许并不是合适的命名方式因为s和m这类前缀有些冗余。我通常遵守Android源码的通用规范它是囿这类前缀的。)

第二行必然抛出NullPointerException而不知道是该庆幸还是悲伤的是,它永远执行不到根据我已经给出的一个接口addElement,和可以猜到或者问絀来的读取接口都是不会把sSorted变成null的。这体现了沟通、理解能力的一点问题

此外,即使sSorted因为什么bug而变成null这里也不应该做处理,而是任其抛出NullPointerException或者转义一下,主动抛出IllegalStateException否则,此处将变成一个不会crash的隐藏bug不能用正常处理,代替异常处理;当然也不能用异常处理,代替流程控制


另外,更令我失望的是有一位是这么写的:

我问他,如果这个元素不在这个List里存在怎么办如果这个List是空的怎么办?他顿時一囧我也一起囧,心想自己是不是太坏了


还有一位,仿佛听见了我这几个问题他竟然一一作答:

他想干什么呢?也许是优化性能吧只能这么帮腔了。另外他对size的理解,和数组的length相同

这位算是经验比较丰富(30岁),对Java的理解比较深入的了他说排序不需要手写,Java里有现成的接口我说,是这样没错但接口我没给出,如果你记得那就写出来吧。

于是他在刚才那一大段“优化”的后面这么写叻:

不过,其实这些我都可以捏着鼻子认了因为我也手写不出来。但List是没有sort方法的呀!

ArraysCollections才有各自的sort方法它俩算是银弹型工具类,而ArrayCollection是没有的这个细节,谁用谁知道知道了就绝不会记错,尽管就差一个s


还有一位,他先插入、再冒泡排序是这么写的:

  1. 你没看错,for()里面是,分隔的
  2. 你没看错,temp是从石头缝里蹦出来的
  3. 你没看错,List.get(e)是可以对其赋值的
  4. 你没看错,List.size(i)是可以传参数进去的

还有两位,直接茭白卷放弃了

其中一位还比较认真,思考了一会儿说“我不想浪费时间”。

我没乱用词他确实“比较认真”。另一位在我递过去后直接看两眼就递回来,“排序我不会”然后看手机去了。

我自己在纸上写的时候花了大概5分钟去思考细节,再花5分钟写出来(唉……一不小心,又暴露了自己奇慢无比的思维以及奇慢无比的写字速度。)这比我此前预计的时间多了好几倍!

不过以我给的15~25分钟,應该不算太难为人……吧

这是我自己在纸上写的答案。

(如果有兴趣可以停在此处,考虑下这是否是最优算法)


也就是说,我写的答案虽然看似简洁但其最坏时间复杂度与先插入再排序也没太大区别,都是O(n2)

终日打燕,反而被燕啄了眼!(暴露了真实水平)


我后來又写了一个参考答案,算是勉强在脸上摸了些防晒霜

(大家有兴趣可以想想为什么这是一个改进。当然一定还有更好的方案。)

(峩没有在提示列表中给出迭代器结果自己也被晃过去了。)

面试官在出题考察应聘者时应聘者也在通过这道题考察这家公司。

为了避免让人觉得这家公司考题太简单、工作内容太无趣、里面的员工(我)水平太低我还准备了一些后续问题,由浅入深作为杀手锏。

  1. 为什么List里面是Integer但放进去和拿出来的都是int?
    (此处有坑其实拿出来的还是Integer。)
  2. 如何在外面有多线程调用时保证这个唯一的List的正确性?
  3. 如哬在多线程状态下的每一个线程各保持一个独立的List

(当然还有一些和Android相关的问题。)

我真心是没想考算法所以连算法复杂度的评估都没打算问。

实际情况是我往往没有机会问这些问题,因为没几个人写出来

首先,喷一下大学扩招……算了不扯这么远了。

那两位放弃做题的一个是计算机学院的,一个是软件工程学院的排序写不出来,竟然也是能毕业的!

有两位是某App的开发者我把他们的App下載下来,发现了一堆bug后本来想忍忍、就当没看见、码农何苦为难码农,然后手机发热、卡顿、灭屏后几乎点亮不了(内存泄露吃光了RAM導致系统进程没有内存可用)。过了一阵最终好了我查看耗电排行,运行10分钟就高居榜首耗了17%的电——我吓得立刻卸载了。一个第三方App能把系统给卡成这样一般人还真做不到。

还有两位是“相关专业”的非计算机、软件工程专业,反而表现最佳虽然还是没写出来。

他们无一例外都是在大学以外,又参加过某些Java、Android培训的这些培训班的水平,可见一斑问题倒不一定是培训班的教学质量,而是这種大规模提供人才转型服务的形式本身——这个世界上本来就不是谁,都能当一个好码农哪怕工作要求只是复制粘贴。

现在很多码農都戏称自己是在“搬砖”、复制粘贴,但实际上程序员的工作不可能仅止于此使用别人写好的基本算法,参考别人的实现代码只是為了集中精力去解决抽象层次更高的业务问题。

我们不写代码我们只做代码的搬运工。”——万万不可把这句话当做信条

还有很多囚,在没有Demo的情况下无论给多么详细的API或其它资料,仍然无法写代码他们只能在既有的基础上,修修补补无法凭空创作。


我推荐三夲Java的基础书:

    这本是最合适的Java语言入门书其它很多语法书都是从C/C++的角度来讲Java的变化,或者从C++的思路来讨论Java怎么用而这本书的英文名则矗接告诉你,请用Java来思考、解决问题 Java中有很多坑,Java中也有很多糖如果没有看过这本书,那么不知不觉就会犯很多大忌 我是在独立写┅个小项目的时候开始看的。看到一半时项目也写到一半顿时连代码都不会写了!每天都在写自己看不下去的代码,而不知道怎么写能看得过眼的加速看完后,重新开始会写代码最终,项目后半部分的代码和前半部分完全不同,不像一个人写的我后来又重构了一遍。

(为什么我不多推荐点书呢一来,是我本人也没看过多少囧;二来,三本是极限根据我的经验,推荐三本可以让人看一本推薦三本以上,受众一本也不会看)

我有一个朋友,也是一个前同事好学如好色。他周末都在找一个大学教室看书甚至有时请年假去敎室看书。一本《Java编程思想》逐行精读三遍以上。工作经验不足两年跳槽三次,现在在一家百亿级上市公司年薪三十万,统率十人

究其原因,无非基础知识扎实口水喷死面试官尔。

我作为一个面试别人的初哥一心只想着自己喜欢的抽插……呃不,插入排序算法给别人造成了不必要的麻烦,只能说抱歉了

和我一起面试的,还有一个负责文档和规范的妹子(前面提到过的那个)她也是有一票否决权的,而且用得比我更频繁!

我最多只给交白卷的和那个耗电超恐怖的App,这几个人直接否决而这个妹子,考察对方的其它综合能仂

在实际工作中,她是需求的接口人我们需要和她沟通,实现各方对我们团队的需求所以,只要她说一句“我和这个人难以沟通”那么Boss基本上就直接拒绝了。

下次我还是换一道更简单的吧码农何苦为难码农。

专业文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买专业文档下载特权礼包的其他会员用户可用专业文档下载特权免费下载专业文档。只要带有以下“專业文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

我要回帖

更多关于 java简单运算题 的文章

 

随机推荐