我爱学习,学习使我妈快乐,我妈快乐全家快乐
好看请点赞,不喜请轻喷
锲子
一入编程深似海,编程世界Very深。
这里是九神说编程,今天给大家说的是一个顶级大佬闲的无聊,在编程世界已经999级,闲来无事去新手村练小号的故事。
大佬本以为只要拿出0.001%的功力就可以轻松入职升级了,没有想到却遇上了变态面试官!
“看来,我需要使出我1%的功力了!”,大佬明悟道。
介绍一下作者本人,我虽名为九神,但在那场大战中连观战的资格都没有,以下的一切都是大佬小号口传于我的。而我,只是以第一人称口述,记录下了那场对决的万分之一!
面试开始
我看到一个头发浓密,全身西服笔挺的30岁大叔面试官向我走来。
不经意间扫过这位大叔腕上的百达翡丽和标着“LOTOS”字样的眼镜。
看着对方这张好像在我长远记忆中见过的帅气脸庞,我突然意识到——有杀气!
1、你好,我们先来几个简单问题热热身吧,先讲讲Java有哪几种基本类型?
我认真的回答道:大叔你好!在Java中,一共有8种基本类型。分别是:整数类型:byte,short,int,lon;浮点数类型:float,double;字符类型:char;布尔类型:boolean。
注意:遇到面试官一定要礼貌!回答问题要有逻辑,按照种类归类比你一口气说出8种类型好的多。
2、在Java中(2.0-1.1 == 0.9)是true还是false?
是false,因为2.0-1.1最终输出的是0.89999999,而不是0.9。在Java中,(2.0-1.1 < 0.9)才是true。
3、那为什么输出的是0.899999而不是0.9?如何解决?
因为在Java中浮点数值采用二进制表示,而在二进制系统中无法精准表示分数1/10。(就好像十进制没法精准的表示1/3)。
如果想解决这个问题,就需要使用BigDecimal类而不是使用浮点数。
4、嗯,答得不错,那你看看下面这个题的答案是什么?为什么会是这样?
大叔不想说话并向我丢我来一道题目:
答案是true,false,false。
因为Integer n1 = 100;
这种语句实际上是自动装箱,把int类型转换成了int的包装类Integer。在Integer中,Java为了提高运行效率,需要进行自动装箱时,如果数字在一个字节内,也就是-128至127之间时,会直接使用缓存中的对象,而不是重新创建一个对象。
100在这个范围内,所以第一个语句是true;200不在这个范围内,所以第二个语句是false。
Java中Integer自动装箱实际调用的是Integer.valueOf()方法,直接new一个并不是自动装箱,而是新建了一个对象,所以第三个语句是false。
另外,在Java9之后,就不推荐使用new Integer()的做法了。
注意:讲完原有知识点,带出不同Java Version的不同,是很好地加分项。
5、有没有办法更改自动装箱的范围?
可以通过修改JVM参数-XX:AutoBoxCacheMax=size来更改自动装箱池的大小。
额,好像开始有点东西了啊!这是1级难度的问题么?
6、嗯,小伙子看来还可以啊!那么以下语句输出的结果是什么?
我不假思索的回答:第一个是b,第二个是99。
因为'a'在Unicode字符集中的排序位置编码是97,++之后自增+1变成了b,b的编码是98,再调用x+1之后是直接被自动类型转换为int类型,输出99。
1级的题目就问Unicode编码位置了,还好我是小号,这面试官诚心的吧?
7、那基本数据类型中自动类型转换规则是什么?
是从存储范围小的类型到存储范围大的类型,也就是:byte ->short(char)->int->long->float->double这样转换。
8、不错,你刚才讲到了Unicode,Java中char采用的编码方式是哪种?
是UTF-16。
9、那Java为什么会选择UTF-16呢?
因为历史上 Java一开始选择的是 UCS-2,是一个定长的编码,在当时以单个码元能表示所有字符,以下标获取字符的开销基本等同于在数组中索引一个字符,用起来是最方便的,多占用的内存大小也是可以接受的。
到了后来 UCS-2 无法表示所有 Unicode 字符的时候,过渡到了兼容它的 UTF-16 上也是最自然以及迁移成本最低的选择。
好像画风开始不太对头了?这是历史题吧
10、UTF-16是怎么实现Unicode编码的?
问道这题我感受到了面试官一阵杀气,他是想压住我么?感觉1级小号不配全答对么?哈哈哈,幸亏我只是小号!待我用999级超凡的理解予以回击!
于是,我郑重言辞的说道:
这个想法很自然,我先讲讲设计思路。
在2个字节的Unicode字符集中,按道理能存放2的16次方,也就是65536个字符。但是为了扩容,特别的划出了一片区域不存储正常的字符。
这时候,只要拿两个Unicode字符拼在一起形成4个字节,如果第一个Unicode字符对应那片本不应该存储字符的区域,这两个拼起来的Unicode字符就可以看成一个新的大字符。
这样就能成倍数的跨增原有的字符集而不需要对原有的整个字符集做任何改动。还拥有看了首位Unicode字符就能判断属于哪个跨增类型的好处。
我再来说说具体的做法吧。
我们把Unicode中每个字符对应的16进制的值称为代码点(code point),并且加上前缀以示和16进制的区分,比如U+0097代表'a'。我们把扩充后的Unicode字符集划分为17个代码级别(code plane),第一个代码级别称为基本的多语言级别,也就是大家常说的BMP(basic multilingual plane),代码点从U+0000到U+FFFF,其中包括了原有的经典Unicode字符集;其余的16个附加级别,代码点从U+10000到U+10FFFF,这里存放的都是辅助字符,也是扩充的部分。
UTF-16采用可变长度的编码来表示所有Unicode的代码点。在BMP中,每个都是2字节字符,我们称之为代码单元(code unit);而辅助字符采用一对连续的代码单元进行编码,其中第一个代码单元采用的范围正是BMP中空出的代替区域(surrogate area)中的值,即0xD800-0xDFFF这部分。
UTF-16就是通过这种可变长度的办法来对应了Unicode编码集中的每个字符的。
而Java中的char类型用UTF-16编码描述一个代码单元。
哈哈,这波面试官已经被团灭了吧!这个回答,完全超越了教科书的回答啊!先讲了设计思路 ,再谈实现办法,妥妥的向面试官证明自己能搞一套类似的字符集出来啊!这肯定直接拉到面试满分了啊!NICE!
11、如果使用UTF-8,UTF-32代替UTF-16分别有什么利弊?
UTF-8占用的内存空间最小,根据码不一样分别占据1~4个字节;UTF-32占用的内存空间最大,每次都占据4个字节。
对于超过占用1个字节的Unicode码时,UTF-8的因为需要运算所以速度就会比UTF-16和UTF-32慢;对于超过占用2个字节的Unicode码时,UTF-16的因为需要运算所以速度就会比UTF-32慢。
因为我们日常使用的都是BMP中的码,所以UTF-16是一个中庸的选择。
这面试官还不死心么?1级还问选型题?
面试结束
面试官大叔看了一眼手腕上的百达翡丽,说时间不早了,要不先这样吧,让我回去等下次面试的通知。
我问道:那什么时候下次面试呢?
“等你升到2级的时候吧!”,面试官留下这就话就走了。
这面试官如此变态么?全对还要等我升级再面?
后续
那大佬如何才能升级呢?据大佬透漏,需要有人给他的口述点赞达到一定数量方可升级,只有升级到2级,才能进入第二面!
这就是有幸聆听大佬口述,我来执笔写下这篇文章的缘由!
还不给点赞么?没下一篇了啊!
闲话
在面试过程中,一般面试官都会根据面试者做过的项目为引子,引导面试者说出面试者所有会的内容,而并非随机发问打地图炮。一个优秀的面试官往往是在不经意间已经知道你做的项目是否真实和你的水平。类似本文中变态面试官持续高压的提问式常见于年轻的面试官,觉得技术有高低,一定要压到面试者才是胜利。
九神私以为技术只有是否匹配,并无高下之别。
有高下之别的更可能是每个人trouble shooting和理解学习的能力,招聘是case by case的事情,挖掘自身优秀的点就能进入好公司拿到高薪offer哦!
点关注,不迷路
好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是能进大厂的高端人才。
我后面会每周都更新几篇一线互联网大厂面试和常用技术栈相关的文章,非常感谢高端人才们能看到这里,如果这个文章写得还不错,觉得「九神说编程」有点东西的话 求点赞👍 求关注❤️ 求分享👥 对九神来说真的 非常有用!!!
注意:博文会比公号晚一周哦!
白嫖不好,创作不易, 各位的支持和认可,就是我创作的最大动力,我们下篇文章见!