1.JDK和JRE的区别?
- JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。
- JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。
2.==和equals的区别?
- 基本类型:比较的是值是否相同;
- 引用类型:比较的是引用是否相同;
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2);//true
String str3 =newString("abc");
String str4 =newString ("abc");
System.out.println(str3==str4);//false
System.out.println(str3.equals(str4));//true
解析:equals 本质上就是 ==,只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较。
PS:
Integer i1 = 100, i2 = 100;
Integer i3 = 1000, i3 = 1000;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//false
解析:在整数的包装类当中,在第一次创建Integer 类的对象的时候,都会首先创建好缓存数组。当需要包装的 值是在IntegerCache数组当中的元素的时候,就会返回数组当中的Integer 对象。JVM 默认就会设置数组的范围为-128 ~ 127 。如下:
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
3.Java基本数据类型
byte short int long float double char boolean, String属于对象。
4.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不对,两个对象的 hashCode()相同,equals()不一定 true。
5. final 在 java 中有什么作用?
- final 修饰的类叫最终类,该类不能被继承。
- final 修饰的方法不能被重写。
- final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
6. java 中的 Math.round(-1.5) 等于多少?
等于 -1,因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 是往上取整,负 0.5 是直接舍弃。
7.String、StringBuffer、StringBuilder的区别?
String是字符串常量,final修饰;StringBuffer字符串变量(线程安全);StringBuilder 字符串变量(线程不安全).此外StringBuilder和StringBuffer实现原理一样,都是基于数组扩容来实现的.
StringBuffer和StringBuilder的实现原理一样,其父类都是AbstractStringBuilder.StringBuffer是线程安全的,StringBuilder是JDK 1.5新增的,其功能和StringBuffer类似,但是非线程安全.因此,在没有多线程问题的前提下,使用StringBuilder会取得更好的性能.
8. String str="i"与 String str=new String("i")一样吗?
不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String("i") 则会被分到堆内存中。
9. 如何将字符串反转?
1)使用 StringBuilder 或者 StringBuffer 的 reverse() 方法。
String str = "abcdefg";
StringBuffer stringBuffer = new StringBuffer(str);
StringBuilder stringBuilder = new StringBuilder(str);
System.out.println(stringBuffer.reverse());
System.out.println(stringBuilder.reverse());
2)使用String对象的toCharArray()方法,将字符串转换为char[]数组,然后逆向遍历并拼接。
String str = "abcdefg";
StringBuilder strNew =new StringBuilder();
char[] chars = str.toCharArray();
for(int i = chars.length -1; i >= 0; i--){
strNew.append(chars[i]);
}
3)使用String对象的charAt方法逐个获取字符,正向遍历,逆向拼接
String str = "abcdefg";
StringBuilder strNew =new StringBuilder();
for (int i = 0; i < str.length(); i++) {
strNew.insert(0, str.charAt(i));
}
10.String类的常用方法有哪些?
- indexOf():返回指定字符的索引。
- charAt():返回指定索引处的字符。
- replace():字符串替换。
- trim():去除字符串两端空白。
- split():分割字符串,返回一个分割后的字符串数组。
- getBytes():返回字符串的 byte 类型数组。
- length():返回字符串长度。
- toLowerCase():将字符串转成小写字母。
- toUpperCase():将字符串转成大写字符。
- substring():截取字符串。
- equals():字符串比较。
11.普通类和抽象类的区别?抽象类可以用final修饰吗?抽象类和接口的区别?
1)普通类不能有抽象方法,抽象类可以有也可以没有抽象方法,抽象类不能直接实例化,普通类可以。
2)抽象类不能用final修饰,因为抽象类的定义就是为了被继承。
3)抽象类和接口的区别:
抽象类使用extends继承,接口使用implements实现;
抽象类可以有构造函数,接口不能有;
抽象类可以有非抽象接口,接口不能有(java8之后可以有了)
类可以实现多个接口,但是只能继承一个类;
接口中的方法默认使用public访问修饰符,抽象类中的方法可以任意访问修饰符(抽象方法不能使用private)
12.Java中的IO流分为几种?
- 按功能划分:输入流、输出流;
- 按类型划分:字节流、字符流,字节流按8为传输以字节为单位,字符流按16为传输以字符为单位;
13.BIO、NIO、AIO有什么区别?
- BIO:Block IO同步阻塞式IO,即传统IO,特点是使用简单,并发处理能力低。
- NIO:Non IO同步非阻塞IO,传统IO的升级,客户端和服务端通过Channel通讯,实现了多路复用。
- AIO:Asynchronous IO是NIO的升级,也叫NIO2,实现了异步非阻塞IO,异步IO的操作基于事件和回调机制。
14.Files的常用方法都有哪些?
- Files.exists():检测文件路径是否存在;
- Files.createFile():创建文件;
- Files.createDirectory():创建文件夹;
- Files.delete():删除一个文件或目录;
- Files.copy():复制文件;
- Files.move():移动文件;
- Files.size():查看文件个数;
- Files.read():读取文件;
- Files.write():写入文件;
15.面向对象的特征
封装、继承、多态
16.父类的静态方法能否被子类重写
不能.重写只适用于实例方法,不能用于静态方法,而子类当中含有和父类相同签名的静态方法。
17.什么是不可变对象?好处是什么?
不可变对象指对象一旦被创建,状态就不能再改变,任何修改都会创建一个新的对象,如 String、Integer及其它包装类.不可变对象最大的好处是线程安全.
18.静态变量和实例变量的区别?
静态变量存储在方法区,属于类所有.实例变量存储在堆当中,其引用存在当前线程栈.需要注意的是从JDK1.8开始用于实现方法区的PermSpace被MetaSpace取代了.
19.java 创建对象的几种方式
- new创建新对象
- 通过反射机制
- 采用clone机制
- 通过序列化机制
PS:前两者都需要显式地调用构造方法. 对于clone机制,需要注意浅拷贝和深拷贝的区别,对于序列化机制需要明确其实现原理,在java中序列化可以通过实现Externalizable或者Serializable来实现.
20.Object中有哪些公共方法?
equals(),clone(),getClass(),notify(),notifyAll(),wait(),toString()
21.& 和 &&的区别
基础的概念不能弄混:&是位操作,&&是逻辑运算符.需要记住逻辑运算符具有短路特性,而&不具备短路特性.
22.在.java文件内部可以有多少类(非内部类)?
在一个java文件中只能有一个public公共类,但是可以有多个default修饰的类.
23.如何正确的退出多层嵌套循环?
- 使用标号和break;
- 通过在外层循环中添加标识符
24.final,finalize()和finally{}的不同之处
三者没有任何相关性,遇到有问着问题的面试官就拖出去砍了吧.
- final是一个修饰符,用于修饰变量,方法和类.如果 final 修饰变量,意味着该变量的值在初始化后不能被改变.
- finalize()方法是在对象被回收之前调用的方法,给对象自己最后一个复活的机会.但是该方法由Finalizer线程调用,但调用时机无法保证.
- finally是一个关键字,与 try和catch一起用于异常的处理,finally{}一定会被执行,在此处我们通常用于资源关闭操作.
25.clone()是哪个类的方法?
java.lang.Cloneable 是一个标示性接口,不包含任何方法.clone ()方法在 Object 类中定义的一个Native方法:
protected NativeObject clone() throws CloneNotSupportedException;
26.深拷贝和浅拷贝的区别是什么?
- 浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.
- 深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的对象都复制了一遍.
27.64位的JVM当中,int的长度是多少?
Java中数据类型所占用的位数和平台无关,在 32 位和64位 的Java 虚拟机中,int 类型的长度都是占4字节.
PS:short(2)、int(4)、long(8)、float(4)、double(8)
28.int和Integer的区别?
Integer是int的包装类型,在拆箱和装箱中,二者自动转换.int是基本类型,直接存数值;而integer是对象;用一个引用指向这个对象.由于Integer是一个对象,在JVM中对象需要一定的数据结构进行描述,相比int而言,其占用的内存更大一些.
29.String s = new String("abc")创建了几个String对象?
2个.一个是字符串字面常数,在字符串常量池中;另一个是new出来的字符串对象,在堆中.
30.请问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引用的是同一个字符串常量.
31.以下代码中,s5==s2返回值是什么?
String s1="ab";
String s2="a"+"b";
String s3="a";
String s4="b";
String s5=s3+s4;
返回false.在编译过程中,编译器会将s2直接优化为"ab",将其放置在常量池当中;而s5则是被创建在堆区,相当于s5=new String(“ab”);
32.你对String对象的intern()熟悉么?
Stirng中的intern()是个Native方法,它会首先从常量池中查找是否存在该常量值的字符串,若不存在则先在常量池中创建,否则直接返回常量池已经存在的字符串的引用.
33.什么是编译器常量?使用它有什么风险?
公共静态不可变,即public static final修饰的变量就是我们所说的编译期常量.这里的public可选的.实际上这些变量在编译时会被替换掉,因为编译器明确的能推断出这些变量的值(如果你熟悉C++,那么这里就相当于宏替换).
编译器常量虽然能够提升性能,但是也存在一定问题:你使用了一个内部的或第三方库中的公有编译时常量,但是这个值后面被其他人改变了,但是你的客户端没有重新编译,这意味着你仍然在使用被修改之前的常量值.
34. 3*0.1==0.3返回值是什么
false,因为有些浮点数不能完全精确的表示出来.
35.java当中使用什么类型表示价格比较好?
如果不是特别关心内存和性能的话,使用BigDecimal.否则使用预定义精度的 double 类型.
36.如何将byte转为String
可以使用String接收 byte[] 参数的构造器来进行转换,注意要使用的正确的编码,否则会使用平台默认编码.这个编码可能跟原来的编码相同.也可能不同.
String str = new String("abc".getBytes(), StandardCharsets.UTF_8);
37.可以将int强转为byte类型么?会产生什么问题?
可以做强制转换,但是Java中int是32位的而byte是8 位的.如果强制转化int类型的高24位将会被丢弃,byte 类型的范围是从-128到128.
38.a=a+b与a+=b有什么区别吗?
+=操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而a=a+b则不会自动进行类型转换.如:
39.了解泛型么?简述泛型的上界和下界?
有时候希望传入的类型有一个指定的范围,从而可以进行一些特定的操作,这时候就需要通配符了?在Java中常见的通配符主要有以下几种:
- <?>: 无限制通配符;
- <? extends E>: extends 关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类;
- <? super E>: super关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类;
它们的目的都是为了使方法接口更为灵活,可以接受更为广泛的类型; - <? extends E>: 用于灵活读取,使得方法可以读取 E 或 E 的任意子类型的容器对象;
- <? super E>: 用于灵活写入或比较,使得对象可以写入父类型的容器,使得父类型的比较方法可以应用于子类对象;
用简单的一句话来概括就是为了获得最大限度的灵活性,要在表示生产者或者消费者的输入参数上使用通配符,使用的规则就是:生产者有上限(读操作使用extends),消费者有下限(写操作使用super).