您当前的位置:首页 > 电脑百科 > 程序开发 > 程序员

最近我面了12个人,发现这个JAVA基础题都答得不好

时间:2022-03-04 09:39:58  来源:  作者:程序员阿远

你好,我是 阿远。

一般面试我都会问一两道很基础的题目,来考察候选人的“地基”是否扎实,有些是操作系统层面的,有些是 JAVA 语言方面的,还有些…

最近我都拿一道 Java 语言基础题来考察候选人:

不用反射,能否实现一个方法,调换两个 String 对象的实际值?

String yesA = "a";
String yesB = "b";
//能否实现这个 swap 方法
// 让yesA=b,yesB=a?
swap(yesA, yesB);

别小看这道题,其实可以考察好几个点:

1.明确 yesA 和 yesB 是啥

2.Java 只有值传递

3.String 是不可变类

4.字符串常量池

5.intern 的理解

6.JVM内存的划分与改变

基于上面这几个点,其实还能发散出很多面试题,不过今天咱们这篇文章就不发散了,好好消化上面这几个点就可以了。

我们需要明确答案:实现不了这个方法。

按照题意,我相信你很容易能写出以下的 swap 方法实现:

void swap(String yesA, String yesB){
String temp = yesA;
yesA = yesB;
yesB = temp;
}

首先,我们要知道 String yesA = "a"; 这行代码返回的 yesA 代表的是一个引用,这个引用指向堆里面的对象 a。

最近我面了12个人,发现这个JAVA基础题都答得不好

 

也就是说变量 yesA 存储的只是一个引用,通过它能找到 a 这个对象,所以表现出来好像 yesA 就是 a,实际你可以理解 yesA 存储是一个“地址”,Java 通过这个地址就找到对象 a。

因此,我们知道了, yesA 存储的值不是 a,是引用(同理,yesB也一样)。

然后,我们都听过 Java 中只有值传递,也就是调用方法的时候 Java 会把变量 yesA 的值传递到方法上定义的 yesA(同理 yesB 也是一样),只是值传递。

根据上面我们已经知道 yesA 存储的是引用,所以我们得知,swap方法 里面的 yesA 和 yesB 拿到的是引用。

最近我面了12个人,发现这个JAVA基础题都答得不好

 

然后调用了 swap 方法,调换了 yesA 和 yesB 的值(也就是它的引用)

最近我面了12个人,发现这个JAVA基础题都答得不好

 

请问,swap 里的跟我外面的 yesA 和 yesB 有关系吗?显然,没有关系。

因此最终外面的 yesA 指向的还是 a,yesB 指向的还是 b。

不信的话,我们看下代码执行的结果:

最近我面了12个人,发现这个JAVA基础题都答得不好

 

现在,我们明确了,Java 只有值传递

看到这,可能会有同学疑惑,那 int 呢,int 不是对象呀,没引用啊,其实一样的,记住Java 只有值传递。

我们跑一下就知道了:

最近我面了12个人,发现这个JAVA基础题都答得不好

 

很显然, int 也无法交换成功,道理是一样的。

外面的 yesA 和 yesB,存储的值是 1 和 2(这里不是引用了,堆里也没有对象,栈上直接分配值)。

调用 swap 时候,传递的值是 1 和 2,你可以理解为拷贝了一个副本过去。

所以 swap 里的 yesA 和 yesB 实际上是副本,它的值也是 1 和 2,然后副本之间进行了交换,那跟正主有关系吗?

显然没有。

像科幻电影里面有克隆人,克隆人死了,正主会死吗?

不会。

记住,Java 只有值传递

再回到这个面试题,你需要知道 String 是不可变类。

那什么是不可变类呢?

我在之前的文章说过,这边我引用一下:

不可变类指的是无法修改对象的值,比如 String 就是典型的不可变类,当你创建一个 String 对象之后,这个对象就无法被修改。

因为无法被修改,所以像执行s += “a”; 这样的方法,其实返回的是一个新建的 String 对象,老的 s 指向的对象不会发生变化,只是 s 的引用指向了新的对象而已。

看下面这幅图应该就很清晰了:

最近我面了12个人,发现这个JAVA基础题都答得不好

 

如图所示,每次其实都是新建了一个对象返回其引用,并不会修改以前的对象值,所以我们常说不要在字符串拼接频繁的场景不要使用 + 来拼接,因为这样会频繁的创建对象,影响性能。

而一般你说出 String 是不可变类的时候,面试官一般都会追问:

不可变类有什么好处?

来,我也为你准备好答案了:

最主要的好处就是安全,因为知晓这个对象不可能会被修改,在多线程环境下也是线程安全的(你想想看,你引用的对象是一个不可变的值,那么谁都无法修改它,那它永远就是不变的,别的线程也休息动它分毫,你可以放心大胆的用)。

然后,配合常量池可以节省内存空间,且获取效率也更高(如果常量池里面已经有这个字符串对象了,就不需要新建,直接返回即可)。

所以这里就提到 字符串常量池了。

例如执行了 String yesA = "a" 这行代码,我们现在知道 yesA 是一个引用指向了堆中的对象 a,再具体点其实指向的是堆里面的字符串常量池里的对象 a。

如果字符串常量池已经有了 a,那么直接返回其引用,如果没有 a,则会创建 a 对象,然后返回其引用。

这种叫以字面量的形式创建字符串。

还有一种是直接 new String,例如:

String yesA = new String("a")

这种方式又不太一样,首先这里出现了字面量 “a”,所以会判断字符串常量池里面是否有 a,如果没有 a 则创建一个 a,然后会在堆内存里面创建一个对象 a,返回堆内存对象 a 的引用,也就是说返回的不是字符串常量池里面的 a

我们从下面的实验就能验证上面的说法,用字面量创建返回的引用都是一样的,new String 则不一样

最近我面了12个人,发现这个JAVA基础题都答得不好

 

至此,你应该已经清晰字面量创建字符串和new String创建字符串的区别了。

讲到这,经常还会伴随一个面试题,也就是 intern

以下代码你觉得输出的值各是啥呢?你可以先思考一下

String yesA = "aaabbb";
String yesB = new String("aaa") + new String("bbb");
String yesC = yesB.intern();
System.out.println(yesA == yesB);
System.out.println(yesA == yesC);

好了,公布答案:

最近我面了12个人,发现这个JAVA基础题都答得不好

 

第一个输出是 false 应该没什么疑义,一个是字符串常量的引用,一个是堆内的(实际上还是有门道的,看下面)。

第二个输出是 true 主要是因为这个 intern 方法。

intern 方法的作用是,判断下 yesB 引用指向的值在字符串常量里面是否有,如果没有就在字符串常量池里面新建一个 aaabbb 对象,返回其引用,如果有则直接返回引用。

在我们的例子里,首先通过字面量定义了 yesA ,因此当定义 yesC 的时候,字符串常量池里面已经有 aaabbb 对象(用equals()方法确定是否有对象),所以直接返回常量池里面的引用,因此 yesA == yesC

你以为这样就结束了吗?

我们把上面代码的顺序换一下:

String yesB = new String("aaa") + new String("bbb");
String yesC = yesB.intern();
String yesA = "aaabbb"; // 这里换了
System.out.println(yesA == yesB);
System.out.println(yesA == yesC);

把 yesA 的定义放到 yesC 之后,结果就变了:

最近我面了12个人,发现这个JAVA基础题都答得不好

 

是不是有点懵?奇了怪了,按照上面的逻辑不应该啊。

实际上,我最初画字符串常量池的时候,就将其画在堆内,也一直说字符串常量池在堆内,这是因为我是站在 JDK 1.8 的角度来说事儿的。

在 JDK 1.6 的时候字符串常量池是放在永久代的,而 JDK 1.7 及之后就移到了堆中。

最近我面了12个人,发现这个JAVA基础题都答得不好

 

这区域的改变就导致了 intern 的返回值有变化了。

在这个认知前提下,我们再来看修改顺序后的代码具体是如何执行的:

1.String yesB = new String("aaa") + new String("bbb");

此时,堆内会新建一个 aaabbb 对象(对于 aaa 和 bbb 的对象讨论忽略),字符串常量池里不会创建,因为并没有出现 aaabbb 这个字面量。

2.String yesC = yesB.intern();

此时,会在字符串常量池内部创建 aaabbb 对象?

关键点来了。

在 JDK 1.6 时,字符串常量池是放置在永久代的,所以必须新建一个对象放在常量池中。

但 JDK 1.7 之后字符串常量池是放在堆内的,而堆里已经有了刚才 new 过的 aaabbb 对象,所以没必要浪费资源,不用再存储一份对象,直接存储堆中的引用即可,所以 yesC 这个常量存储的引用和 yesB 一样。

3.String yesA = "aaabbb";

同理,在 1.7 中 yesA 得到的引用与 yesC 和 yesB 一致,都指向堆内的 aaabbb 对象。

4.最终的答案都是 true

现在我们知晓了,在 1.7 之后,如果堆内已经存在某个字符串对象的话,再调用 intern 此时不会在字符串常量池内新建对象,而是直接保存这个引用然后返回。

你看这面试题坑不坑,你还得站在不同的 JDK 版本来回答,不然就是错的,但是面试官并不会提醒你版本的情况。

其实很多面试题都是这样的,看似抛给你一个问题,你好像能直接回答,如果你直接回答,那就错了,你需要先声明一个前提,然后再回答,这样才正确。

最后

你看,就这么一个小小的基础题就可以引出这么多话题,还能延伸到 JVM 内存的划分等等。

这其实很考验基础,也能看出来一个人学习的知识是否串起来,因为这些知识都是有关联性的,给你一个点,就能扩散成面,这样的知识才成体系。

欢迎关注我~



Tags:JAVA基础   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
17道Java基础面试题!收藏吃灰!
java中,final, finally, finalize 的区别在Java编程语言中,final、finally和finalize是三个具有不同含义和用途的关键字。1、 final: final是一个修饰符,它可以修饰类、方法和变...【详细内容】
2023-08-05  Search: JAVA基础  点击:(332)  评论:(0)  加入收藏
Java基础文档,你了解多少?
Java作为一门常用的编程语言,其基础知识的学习是非常重要的。而Java基础文档则是学习这门语言的必备资料之一。那么,Java基础文档内容一般包括什么呢?一、概述Java基础文档的概...【详细内容】
2023-07-03  Search: JAVA基础  点击:(445)  评论:(0)  加入收藏
Java基础入门篇—Java虚拟机和运行环境
1992年Oak相关操作系统、类库等完成,11月,“Green计划”被转化成“FirstPerson有限公司”(致力高度互动的设备),关于机顶盒的交易屡败,Green项目几乎接近夭折。一、Java的发展简史...【详细内容】
2023-03-06  Search: JAVA基础  点击:(198)  评论:(0)  加入收藏
最近我面了12个人,发现这个JAVA基础题都答得不好
你好,我是 阿远。一般面试我都会问一两道很基础的题目,来考察候选人的“地基”是否扎实,有些是操作系统层面的,有些是 Java 语言方面的,还有些…最近我都拿一道 Java 语言...【详细内容】
2022-03-04  Search: JAVA基础  点击:(347)  评论:(0)  加入收藏
Java基础系列-final、finally关键字
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  Search: JAVA基础  点击:(526)  评论:(0)  加入收藏
大数据开发基础之JAVA基础-JDBC基础知识
本期给大家带来的是JAVA基础中的JDBC,JDBC全称:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库,说白了就是用Java语言来操作数据库。在大数据开发基础中也是...【详细内容】
2021-03-16  Search: JAVA基础  点击:(403)  评论:(0)  加入收藏
Java基础之集合与泛型
一、集合概述当我们在使用java进行编程开发时,经常会遇到一些需要集中存放的多个数据,这时我们可以选择“数组”或者“集合”,关于数组的知识可以参考上一篇文章,今天我们主要讲...【详细内容】
2020-08-14  Search: JAVA基础  点击:(219)  评论:(0)  加入收藏
Java基础一文搞懂Session和Cookie的用法及区别
1. Session、Cookie是什么1.1 概念理解要了解session和cookie是什么,先要了解以下几个概念。1.1.1 无状态的HTTP协议协议:是指计算机通信网络中两台计算机之间进行通信所必须...【详细内容】
2019-09-26  Search: JAVA基础  点击:(650)  评论:(0)  加入收藏
Java基础之数组
(1)数组:存储同一种数据类型的多个元素的容器(注意和集合的区别 后面的总结之中有)。 (2)特点:每一个元素都有编号,从0开始,最大编号是长度-1。编号的专业叫法:索引。 (3)定义格式...【详细内容】
2019-09-24  Search: JAVA基础  点击:(682)  评论:(0)  加入收藏
Java基础--RMI
RMI (Remote Method Invocation,远程方法调用)是Java一组拥护开发分布式应用程序的API,用于不同虚拟机间的通信,核心是远程对象RMI通信模型: 1、客户端调用辅助对象stub上方法2、...【详细内容】
2019-08-15  Search: JAVA基础  点击:(975)  评论:(0)  加入收藏
▌简易百科推荐
雷军:10年编程路,给程序员的几点建议
随着小米SU7的火热发售,雷军凭借“跨界灭霸”称号又一战封神。作为中国互联网历史上极富传奇色彩的连续创业者,他向大家生动地诠释了“人生在于奋斗”的真谛。雷军作为中国第...【详细内容】
2024-04-15    dbaplus社群  Tags:雷军   点击:(2)  评论:(0)  加入收藏
AI程序员上岗 垂类大模型应用迎来井喷期
能自动写代码的“AI员工”、逐渐告别不够好用的智能客服,无需费时费力开发的工业AI控制器……随着人工智能大模型能力开始深入多个行业,IT、工业生产、金融、服务...【详细内容】
2024-04-07    千龙网  Tags:AI程序员   点击:(5)  评论:(0)  加入收藏
首个AI程序员上岗,码农们暂且不必过度焦虑
“AI程序员上岗”或许是噱头,但淘汰焦虑仍然近在咫尺,需要积极面对。全文2418字,阅读约需7分钟 撰稿 / 马尔文(媒体人)编辑 / 何睿 校对 / 张彦君▲随着相关技术的突飞猛进,AI也在...【详细内容】
2024-04-07    新京报  Tags:AI程序员   点击:(5)  评论:(0)  加入收藏
为何大语言模型不会取代码农?
译者 | 布加迪审校 | 重楼生成式人工智能(GenAI)会取代人类程序员吗?恐怕不会。不过,使用GenAI的人类可能会取代程序员。但是如今有这么多的大语言模型(LLM),实际效果不一而足。如...【详细内容】
2024-03-21    51CTO  Tags:大语言模型   点击:(26)  评论:(0)  加入收藏
AI程序员Devin:通过了面试,但不一定适合职场
昨天,AI圈上演了第一场“大男主爽文”:一个少年成名的编程天才,组建起仅有10人的编程界奥林匹克“梦之队”,在全球瞩目的科技风暴正中心创办了一家公司。成立不到两个月,其推出的...【详细内容】
2024-03-18    甲子光年  Tags:AI程序员   点击:(16)  评论:(0)  加入收藏
微软AI程序员登场,10倍AI工程师真来了?996自主生成代码,性能超GPT-4 30%
新智元报道编辑:桃子 润【新智元导读】全球首个AI程序员Devin诞生之后,让码农纷纷恐慌。没想到,微软同时也整出了一个AI程序员——AutoDev,能够自主生成、执行代码等...【详细内容】
2024-03-18    新智元  Tags:AI程序员   点击:(23)  评论:(0)  加入收藏
李彦宏称程序员职业将不复存在,周鸿祎:程序员热十年内不会减弱,AI时代更需要程序员
李彦宏称程序员职业将不复存在,周鸿祎:程序员热十年内不会减弱,AI时代更需要程序员3月10日,360创始人周鸿祎在社交平台上发文称,“大模型将替代程序员?未来不用学编程了么?我认为,程...【详细内容】
2024-03-11    九派新闻  Tags:程序员   点击:(31)  评论:(0)  加入收藏
李彦宏最新发声,“程序员”职业将不复存在!
在3月9日央视的《对话》·开年说节目上,百度创始人、董事长兼CEO李彦宏表示,以后不会存在“程序员”这种职业了,因为只要会说话,人人都会具备程序员的能力。“未来的编程...【详细内容】
2024-03-11    红星新闻  Tags:程序员   点击:(26)  评论:(0)  加入收藏
编程二十年,38岁谷歌程序员的16条建议,涉创业、技术淘汰、拿大厂offer……
以能够让项目自负盈亏,并在这一约束下优化其增长的方式来管理和调整项目,这是这个世上最厉害的本事。距离我正式开始编程的工作已经过去二十年了。在这些年里,我有以下收获: 获...【详细内容】
2024-03-10    CSDN  Tags:程序员   点击:(7)  评论:(0)  加入收藏
鸿蒙开发岗平均月薪超1.8万,成为计算机人才和程序员的求职新选择!
智联招聘发布的《2024年春招市场行情周报(第一期)》显示,2023年9-12月,鸿蒙相关职位数同比增速从33.8%攀升至216.1%,鸿蒙相关职位的投递人数同比增速从132.1%攀升至380.1%。春节...【详细内容】
2024-02-26  晓枫侃科技    Tags:鸿蒙开发   点击:(28)  评论:(0)  加入收藏
站内最新
站内热门
站内头条