002.最新java基础面试题
String s = new String("abc")
创建了几个String对象?
2个.一个是字符串字面常数,在字符串常量池中;另一个是new出来的字符串对象,在堆中.
请问s1==
s3是true还是false,s1==
s4是false还是true?s1==
s5呢?
String s1 = "abc"; String s2 = "a"; String s3 = s2 + "bc"; String s4 = "a" + "bc"; String s5 = s3.intern();
s1==
s3返回false,s1==
s4返回true,s1==
s5返回true.
“abc"这个字符串常量值会直接方法字符串常量池中,s1是对其的引用.由于s2是个变量,编译器在编译期间无法确定该变量后续会不会改,因此无法直接将s3的值在编译器计算出来,因此s3是堆中"abc"的引用.因此s1!=s3.对于s4而言,其赋值号右边是常量表达式,因此可以在编译阶段直接被优化为"abc”,由于"abc"已经在字符串常量池中存在,因此s4是对其的引用,此时也就意味s1和s4引用了常量池中的同一个"abc".所以s1==s4.String中的intern()会首先从字符串常量池中检索是否已经存在字面值为"abc"的对象,如果不存在则先将其添加到字符串常量池中,否则直接返回已存在字符串常量的引用.此处由于"abc"已经存在字符串常量池中了,因此s5和s1引用的是同一个字符串常量.
以下代码中,s5==
s2返回值是什么?
返回false.在编译过程中,编译器会将s2直接优化为"ab",将其放置在常量池当中;而s5则是被创建在堆区,相当于s5=new String(“ab”);
你对String对象的intern()熟悉么?
Stirng中的intern()
是个Native方法,它会首先从常量池中查找是否存在该常量值的字符串,若不存在则先在常量池中创建,否则直接返回常量池已经存在的字符串的引用. 比如
String s1="aa"; String s2=s1.intern(); System.out.print(s1==s2);
上述代码将返回true.因为在"aa"会在编译阶段确定下来,并放置字符串常量池中,因此最终s1和s2引用的是同一个字符串常量对象.
String,StringBuffer和StringBuilder区别?
String是字符串常量,final修饰;StringBuffer字符串变量(线程安全);StringBuilder 字符串变量(线程不安全).此外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会取得更好的性能.
3*0.1==
0.3返回值是什么
false,因为有些浮点数不能完全精确的表示出来.
java当中使用什么类型表示价格比较好?
如果不是特别关心内存和性能的话,使用BigDecimal.否则使用预定义精度的 double 类型.
如何将byte转为String
可以使用String接收 byte[] 参数的构造器来进行转换,注意要使用的正确的编码,否则会使用平台默认编码.这个编码可能跟原来的编码相同.也可能不同.
可以将int强转为byte类型么?会产生什么问题?
可以做强制转换,但是Java中int是32位的而byte是8 位的.如果强制转化int类型的高24位将会被丢弃,byte 类型的范围是从-128到128.
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;
+=操作符会对右边的表达式结果强转匹配左边的数据类型,所以没错.
了解泛型么?简述泛型的上界和下界?
有时候希望传入的类型有一个指定的范围,从而可以进行一些特定的操作,这时候就需要通配符了?在Java中常见的通配符主要有以下几种:
<?>
: 无限制通配符<? extends E>
: extends 关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类<? super E>
: super关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类
它们的目的都是为了使方法接口更为灵活,可以接受更为广泛的类型.
< ? extends E>
: 用于灵活读取,使得方法可以读取 E 或 E 的任意子类型的容器对象。< ? super E>
: 用于灵活写入或比较,使得对象可以写入父类型的容器,使得父类型的比较方法可以应用于子类对象。
用简单的一句话来概括就是为了获得最大限度的灵活性,要在表示生产者或者消费者的输入参数上使用通配符,使用的规则就是:生产者有上限(读操作使用extends),消费者有下限(写操作使用super).
进程,线程相关
说说进程,线程之间的区别?
简而言之,进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程.进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高.线程是进程的一个实体,是cpu调度和分派的基本单位,是比程序更小的能独立运行的基本单位.同一进程中的多个线程之间可以并发执行.在Linux中,进程也称为Task.
守护线程是什么?它和非守护线程有什么区别
程序运行完毕,jvm会等待非守护线程完成后关闭,但是jvm不会等待守护线程.守护线程最典型的例子就是GC线程.
什么是多线程上下文切换
多线程的上下文切换是指CPU控制权由一个已经正在运行的线程切换到另外一个就绪并等待获取CPU执行权的线程的过程.