最后
资料过多,篇幅有限
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。
在Java中共有八种基本数据类型,它们分别是以下几种类型:
注意:char的数据范围不是0 - 65535(图中错误),因为Java中的char类型由两个字节即十六位来表示,因为是无符号数,所以为2的16次方,数值范围就为:0 - 2^16-1;
3.2 引用数据类型
在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。引用变量一旦声明后,类型就不能被改变了。Java中的引用类型共有三种,分别是类,数组,接口这些引用类型的默认值都是null
3.3 基本类型与引用类型区别
基本数据类型和引用类型的区别主要在于基本数据类型是分配在栈上的,而引用类型是分配在堆上的
3.4 数据类型之间的转换
整型、常量和字符型数据可以混合运算。不同类型数据转换为同一类型再运算,由低到高转换。
低------------------------------------------------------>高
byte,short,char -> int -> long -> float -> double
转换规则
- Boolean不能转换
- 对象类型不能转换为不相关类的对象
- 容量大的类型转换为容量小的类型需使用强制类型换换
- 转换可能导致溢出或损失精度
- 浮点数到整数是舍弃小数得到的
自动数据类型转换:
满足转换前数据类型位数要低于转换后数据类型位数
强制类型转换:
转换的数据类型必须是兼容的
总览:
4、面试中常见的数据类型问题(一)
4.1 int 与 Integer 的区别
定义:
int 是java的基本数据类型;
Integer 继承了Object类,是对象类型,是 int 的包装类。
区别:
1、值的存储
int 存储在栈中
Integer 对象的引用存储在栈空间中,对象的数据存储在堆空间中。
2、初始化
int 初始化值为0。
Integer 初始化值为null。
3、传参
int 是值传递,栈中的数据不可变。
Integer 对象是引用传递,引用不可变,但是引用指向的堆空间地址中的值是可以改变的。
4、泛型支持
泛型不支持int,但是支持Integer。
5、运算
int 可以直接做运算,是类的特性。
Integer 的对象可以调用该类的方法,但是在拆箱之前不能进行运算,需要转化为基本类型int。
拓展:
相同值下的 int 和 Integer 的比较结果
两个通过new生成的变量,结果为false。
int 和 Integer 的值比较,若两者的值相等,则为true。
(注意:在比较时,Integer会自动拆箱为int类型,然后再做比较。)
new 生成的Integer变量 和 非new 生成的Integer变量比较,,结果为false。
(注意:new 生成的Integer变量的值在堆空间中,非new 生成的Integer变量的值在在常量池中。)
(注意:非new生成的Integer变量,会先判断常量池中是否有该对象,若有则共享,若无则在常量池中放入该对象;也叫享元模式。)
两个非new 生成的Integer对象比较,则结果为true。
(注意:此处需要一个前提:值的范围在 -128 ~ 127 之间。
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2);//true
System.out.println(f3 == f4);//false
4.2 short s1 = 1; s1 = s1 + 1; 有错吗?short s1 = 1; s1 += 1 有错吗?
答案:前者错!后者对!
对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int 型,需要强制转换类型才能赋值给 short 型。
而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1; 相当于 s1 = (short)(s1 + 1); 其中有隐含的强制类型转换。
4.3 String、StringBuffer、StringBuilder的区别?
String是字符串常量,final修饰;StringBuffer字符串变量(线程安全);StringBuilder 字符串变量(线程不安全).此外StringBuilder和StringBuffer实现原理一样,都是基于数组扩容来实现的.
可变不可变
String:字符串常量,在修改时不会改变自身;若修改,等于重新生成新的字符串对象。
StringBuffer:在修改时会改变对象自身,每次操作都是对 StringBuffer 对象本身进行修改,不是生成新的对象;使用场景:对字符串经常改变情况下,主要方法:append(),insert()等。
● 线程是否安全
String:对象定义后不可变,线程安全。
StringBuffer:是线程安全的(对调用方法加入同步锁),执行效率较慢,适用于多线程下操作字符串缓冲区大量数据。
StringBuilder:是线程不安全的,适用于单线程下操作字符串缓冲区大量数据。
● 共同点
StringBuilder与StringBuffer有公共父类 AbstractStringBuilder(抽象类)。
StringBuilder、StringBuffer 的方法都会调用 AbstractStringBuilder 中的公共方法,如 super.append(…)。只是 StringBuffer 会在方法上加 synchronized 关键字,进行同步。最后,如果程序不是多线程的,那么使用StringBuilder 效率高于 StringBuffer。
String和StringBuffer的区别?
String和StringBuffer主要区别是性能:String是不可变对象,每次对String类型进行操作都等同于产生了一个新的String对象,然后指向新的String对象.所以尽量不要对String进行大量的拼接操作,否则会产生很多临时对象,导致GC开始工作,影响系统性能.
StringBuffer是对象本身操作,而不是产生新的对象,因此在有大量拼接的情况下,我们建议使用StringBuffer(线程安全).
需要注意现在JVM会对String拼接做一定的优化,比如
String s="This is only "+ "simple" +"test";
以上代码在编译阶段会直接被优化成会`String s=“This is only simple test”.
StringBuffer和StringBuilder
StringBuffer和StringBuilder的实现原理一样,其父类都是AbstractStringBuilder.StringBuffer是线程安全的,StringBuilder是JDK 1.5新增的,其功能和StringBuffer类似,但是非线程安全.因此,在没有多线程问题的前提下,使用StringBuilder会取得更好的性能.
4.3 3*0.1==0.3返回值是什么
false,因为有些浮点数不能完全精确的表示出来.
4.4 如何将byte转为String
可以使用String接收 byte[] 参数的构造器来进行转换,注意要使用的正确的编码,否则会使用平台默认编码.这个编码可能跟原来的编码相同.也可能不同.
4.5 可以将int强转为byte类型么?会产生什么问题?
可以做强制转换,但是Java中int是32位的而byte是8 位的.如果强制转化int类型的高24位将会被丢弃,byte 类型的范围是从-128到128.
4.6 a=a+b与a+=b有什么区别吗?
+=操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而a=a+b则不会自动进行类型转换.如:
byte a = 127;
byte b = 127;
b = a + b; // 报编译错误:cannot convert from int to byte
b += a;
以下代码是否有错,有的话怎么改?
short s1= 1;
s1 = s1 + 1;
有错误.short类型在进行运算时会自动提升为int类型,也就是说s1+1的运算结果是int类型,而s1是short类型,此时编译器会报错.
以下代码是否有错,有的话怎么改?
short s1= 1;
s1 += 1;
+=操作符会对右边的表达式结果强转匹配左边的数据类型,所以没错.
4.7 String类可以被继承吗?
答案:不能!!! String类在声明时使用final关键字修饰,被final关键字修饰的类无法被继承。
为什么Java语言的开发者,把String类定义为final的呢?
因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。因为不可变对象不能更改,它们可以在多个线程之间自由共享。
因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
从内存角度来看:字符串常量池的要求:创建字符串时,如果该字符串已经存在于池中,则将返回现有字符串的引用,而不是创建新对象。多个String变量引用指向同一个内地地址。如果字符串是可变的,用一个引用更改字符串将导致其他引用的值错误。这是很危险的。
缓存Hashcode:字符串的Hashcode在java中经常配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。不可变的特性保证了hashcode永远是相同的。不用每次使用hashcode就需要计算hashcode。这样更有效率。因为当向集合中插入对象时,是通过hashcode判别在集合中是否已经存在该对象了(不是通过equals方法逐个比较,效率低)。
方便其它类使用:其他类的设计基于string不可变,如set存储string,改变该string后set包含了重复值。
安全性:String被广泛用作许多java类的参数,例如网络连接、打开文件等。如果对string的某一处改变一不小心就影响了该变量所有引用的表现,则连接或文件将被更改,这可能导致严重的安全威胁。
总结 :由于效率和安全性的原因,字符串被设计为不可变。
final关键字除了修饰类之外,还有哪些用法呢?
final修饰的变量,一旦赋值,不可重新赋值;
final修饰的方法无法被覆盖;
final修饰的实例变量,必须手动赋值,不能采用系统默认值;
final修饰的实例变量,一般和static联用,用来声明常量;
注意:final不能和abstract关键字联合使用。
总之,final表示最终的、不可变的。\
4.8 String s = “Hello”;s = s + " world!";这两行代码执行后,原始的 String 对象中的内容变了没有?
答案:没有!!!
因为 String被设计成不可变类,所以它的所有对象都是不可变对象。(说白了,就是 final 关键字在起作用)
在这段代码中,s原先指向一个 String 对象,内容是 “Hello”,然后我们对 s 进行了“+”操作,那么 s 所指向的那个对象是否发生了改变呢?
答案是没有。这时s不指向原来那个对象了,而指向了另一个 String 对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用 String 来代表字符串的话会引起很大的内存开销。因为 String 对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个 String 对象来表示。这时,应该考虑使用 StringBuffer/StringBuilder类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都 new 一个 String。
4.9 char类型变量能不能储存⼀个中⽂的汉⼦,为什么?
char类型变量是⽤来储存Unicode编码的字符的,unicode字符集包含了汉字,所以char类型当然可以存储汉字的,还有⼀种特殊情况就是某
个⽣僻字没有包含在
unicode编码字符集中,那么就char类型就不能存储该⽣僻字。
5、面试中常见的数据类型问题(二)
5.1 switch语句能否作⽤在byte上,能否作⽤在long上,能否作⽤在string上?
byte的存储范围⼩于int,可以向int类型进⾏隐式转换,所以switch可以作⽤在byte上
long的存储范围⼤于int,不能向int进⾏隐式转换,只能强制转换,所以switch不可以作⽤在long上
string在1.7版本之前不可以,1.7版本之后switch就可以作⽤在string上了。
5.2 java 中 3*0.1 == 0.3 将会返回什么?true 还是 false?
答:false,因为浮点数不能完全精确的表⽰出来,⼀般都会损失精度。
5.3 java 中 float f = 3.4; 是否正确?
答:不正确,3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于向下转型(down-casting,也称为窄化)会造成精度损
失,因此需要强制类型转换 float f = (float)3.4; 或者写成 float f = 3.4F; 才可以。
5.4 &和&&的区别?
答:&运算符有两种⽤法:(1)按位与;(2)逻辑与。&&运算符是短路与运算。逻辑与跟短路与的差别是⾮常巨⼤的,虽然⼆者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进⾏运算。很多时候我们可能都需要⽤&&⽽不是&,例如在验证⽤户登录时判定⽤户名不是null⽽且不是空字符串,应当写为:username != null &&!username.equals(“”),⼆者的顺序不能交换,更不能⽤&运算符,因为第⼀个条件如果不成⽴,根本不能进⾏字符串的equals⽐较,否则会产⽣NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
5.5 java中 1.0 - 0.9 == 0…1将会返回什么?true还是false
答案: fasle, 浮点数不能精确的表示出来,因此造成不等,浮点数比较大小应该采用范围的形式,比如:
1.0 - 0.9< 0.00001
5.6 int 类型最大值是 2147483647 ,当最大值+1后的结果?
问题来了为什么int 类型最大值+1后会变成负数?
这是因为整数在内存中使用的是补码的形式表示,最高位是符号位,0表示正数,1表示负数。
5.7 自动拆箱和装箱扩展
与自动拆箱和装箱有关的其他面试题:
public class AutoUnboxingTest {
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3;
int c = 3;
System.out.println(a==b);
System.out.println(a==c);
}
}
请根据以上示例代码,判断出两个输出结果分别为什么?
正确答案:false和true
快看看你答对了吗?如果不对,请查看下面的解析过程
代码分析:
文末
逆水行舟不进则退,所以大家要有危机意识。
同样是干到35岁,普通人写业务代码划水,榜样们深度学习拓宽视野晋升管理。
这也是为什么大家都说35岁是程序员的门槛,很多人迈不过去,其实各行各业都是这样都会有个坎,公司永远都缺的高级人才,只用这样才能在大风大浪过后,依然闪耀不被公司淘汰不被社会淘汰。
为了帮助大家更好温习重点知识、更高效的准备面试,特别整理了《前端工程师核心知识笔记》电子稿文件。
内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。
269页《前端大厂面试宝典》
包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
前端面试题汇总
器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。
269页《前端大厂面试宝典》
包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
前端面试题汇总