目录
访问修饰符 public,private,protected,以及default的 区别
String s = new String("xyz") 创建了⼏个字符串对象?
的属性,并可返回变化后的结果,那么这⾥到底是值传递还是引⽤传递?
抽象类(abstract class)和接⼝(interface)有什么区别
一、Java基础
jvm、jre、jdk之间的关系
访问修饰符 public,private,protected,以及default的 区别
&和&&的区别
注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
String与StringBuffer的区别
String不可变,存值使用了常量的字符数组,并且严格执行了封装,操作时无法直接访问字符数组,只能通过,设计String留下的对外接口进行操作,所以每次字符串改变时,都是开启一个新的空间,和已有的空间不同,原值没有变化因此,字符串是不可变的,StringBuffer可变使用字符数组,内存地址是可变的。
int和Integer的区别
int 基础数据类型,Integer是int对应的包装类,是一个引用类型
int 默认0 ,Integer默认null,Integer 有一个缓冲区 -128 127,
Integer提供一系列方便操作的方法,字符串转换。
== 和 equals 的区别是什么
== 比较内存地址 ,equals 底层也是==,只不过引用类型可以重写Object equals方法自定义比较方式,如String的equals,
==在基础数据类型中,比较的是值,引用类型中比较内存地址
什么是内存泄漏和内存溢出
内存泄漏:指的是 new 一些资源出来,没有及时释放,这部份的资源一直被占用,如connection ,io流没有调用关闭方法,如果大量内存泄漏没有处理,最终会导致内存溢出。
内存溢出:指程序申请内存时,没有足够的内存供申请者使用,导致数据无法正常存储到内存中。也就是说给你个int类型的存储数据大小的空间,但是却存储一个long类型的数据,这样就会导致内存溢出。
下面两个代码块能正常编译和执行吗
// 代码块1
short s1 = 1; s1 = s1 + 1;
// 代码块2
short s1 = 1; s1 += 1;
public class com.joonwhee.open.demo.Convert {
public com.joonwhee.open.demo.Convert();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1 // 将int类型值1⼊(操作数)栈
1: istore_1 // 将栈顶int类型值保存到局部变量1中
2: iload_1 // 从局部变量1中装载int类型值⼊栈
3: iconst_1 // 将int类型值1⼊栈
4: iadd // 将栈顶两int类型数相加,结果⼊栈
5: i2s // 将栈顶int类型值截断成short类型值,后带符号扩展成int类型值⼊栈。
6: istore_1 // 将栈顶int类型值保存到局部变量1中
7: return
}
指出下题的输出结果
public static void main(String[] args) {
Integer a = 128, b = 128, c = 127, d = 127;
System.out.println(a == b);
System.out.println(c == d);
}
String 是 Java 基本数据类型吗?
String 类可以继承吗?
String s = new String("xyz") 创建了⼏个字符串对象?
深拷⻉和浅拷⻉区别是什么?
并发和并⾏有什么区别?
当⼀个对象被当作参数传递到⼀个⽅法后,此⽅法可改变这个对象
的属性,并可返回变化后的结果,那么这⾥到底是值传递还是引⽤传递?
重载(Overload)和重写(Override)的区别
方法的重写和重载都是实现多态的方式,区别在于前者是编译时的多态性,后者是运行时的多态性。
重载:一个类中有多个同名的方法,但是具有不同的参数列表(参数类型不同、参数个数不同或者两者都不同)。
重写:发生在子类与父类之间,子类对父类的方法进行重写,参数都不能改变,返回值类型可以不相同,但必须是父类返回值的派生类,也就是外壳不变,核心重写,重写的好处在于子类可以根据需要定义特定于自己的行为。
为什么不能根据返回类型来区分重载?
// ⽅法1
int test(int a);
// ⽅法2
long test(int a);
Java静态变量与成员变量的区别
public class Demo {
/**
* 静态变量:⼜称类变量,static修饰
*/
public static String STATIC_VARIABLE = "静态变量";
/**
* 实例变量:⼜称成员变量,没有static修饰
*/
public String INSTANCE_VARIABLE = "实例变量";
}
写一下变量的执行顺序
首先,静态变量只会初始化(执行)一次;
当有父类时的完整的初始化顺序为:父类静态变量(静态代码块)-->子类静态变量(静态代码块)-->父类非静态变量(非静态代码块)-->父类构造器-->子类非静态变量(非静态代码块)-->子类构造器。
抽象类(abstract class)和接⼝(interface)有什么区别
1.抽象类只能单继承,接口可以多实现;
2.抽象类可以有构造方法,接口不能有构造方法;3.抽象类中可以有成员变量,接⼝中没有成员变量,只能有常量(默认就是 public static final)
Java中的final关键字有哪些用法
修饰类:该类不能再派生出新的子类,不能作为父类被继承,所以一个类不能被同时声明为abstract和final。
修饰方法:该方法不能被子类重写。
修饰变量:该变量必须在声明时给定初值,而在以后不能修改,只能读取,如果变量是对象则指的是引用不可修改,但是对象的属性还是可以修改的。
public class FinalDemo {
// 不可再修改该变量的值
public static final int FINAL_VARIABLE = 0;
// 不可再修改该变量的引⽤,但是可以直接修改属性值
public static final User USER = new User();
public static void main(String[] args) {
// 输出:User(id=0, name=null, age=0)
System.out.println(USER);
// 直接修改属性值
USER.setName("test");
// 输出:User(id=0, name=test, age=0)
System.out.println(USER);
}
}
阐述 final、finally、finalize 的区别。
二、Java集合
集合框架图
聊一聊Java中容器体系结构
Hashmap底层原理
Hashmap 数组+(单向)链表 1.7,JDK 1.8 数组_链表+红黑树,
hashMap存值,时候先把key hash计算找到数组的位置,数组new出来的时候0,第一次存值时,会设置上默认大小长度16的数组hash计算的就是这个key应该存在你这个数组的那个下标位置,如果该数组位置是的空的就直接存入,如果该数组位置不为空,调用equals方法判断2个key是否为一样,如果不一样就会形成链表,在链表上存,如果是一样的就不存进去,如果数组长度大于64,并且链表大于8就会转为红黑树,当链表小于6的时候重新转为链表结构
只有数组长度大于64,并且链表长度大于8才会转红黑,否则只是链表大于8优先数组扩容
Hashtable和HashMap的区别
Hashtable 线程安全,HashMap线程不安全
hashtable 可以不能为null,hashMap都可以为null
hashtable现在已经不使用,如果需要使用线程安全map,应该使用ConcurrentHashMap
LinkedList底层原理
LinkedList的底层是通过链表来实现的,是一个双向链表结构,对于新增节点和删除节点效率高,Node 里面分别有当前值 上一个值 下一个值因此它的随机访问速度是比较差的,但是它的删除,插入操作会很快。
- LinkedList是基于双向循环链表实现的,除了可以当做链表来操作外,它还可以当做栈、队列和双端队列来使用。
- LinkedList同样是非线程安全的,只在单线程下适合使用。
- LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了Cloneable接口,能被克隆。
HashMap 底层有顺序吗
HashMap 底层存储,没有顺序,存储时,根据key值的hash结果找对应数组下标,所以存储时没有顺序。
HashMap null排在数组的那个位置
当存储null值key的时候,他是无法hash,所以固定存储在数组第一个位置下标0的位置。
HashMap的红黑树,当他链表小于6就一定会转为链表吗?
HashMap的链表并不是 小于6就会转为链表,必须是触发resize方法,并且链表长度小于6才会转为链表。
List、Set和Map的区别,以及各自的优缺点
ArrayList的底层原理
ArrayList作为List的典型实现,完全实现了List的全部接口功能,它是基于数组实现的List类,它封装了一个Object[]类型的数组,长度可以动态的增长。如果在创建ArrayList时没有指定Object[]数组的长度,它默认创建一个长度为10的数组,当新添加的元素已经没有位置存放的时候,ArrayList就会自动进行扩容,扩容的长度为原来长度的1.5倍。它的线程是不安全的。
HashSet的底层原理
- HashSet底层是HashMap,第一次添加时,table的数组扩容到16,临界值(threshold)是16 * 加载因子(loadFactor是0.75)=12
- 如果table数组使用到了临界值12,就会扩容到16 * 2 = 32,新的临界值就是32 * 0.75 = 24,依次类推
- Java8以后,如果一条链表中的元素个数到达TREEIFY_THRESHOLD(默认是8),并且table的大小>=MIN_TREEIFY_CAPACITY(默认64),就会进行数化(红黑树),否则仍然采用数组扩容机制