目录
1. String 、StringBuilder 、StringBuffer 的区别?
10.final有什么用? 和 finally finalize 有什么区别?
12.break , continue , return的区别及作用?
14.static修饰的方法能调用非Static修饰的变量和方法吗?
15.局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?
16.重载(Overload) 和 重写(Override) 的区别?
19.String str="abc"与 String str=new String("abc")的定义方法一样吗?
9. List、Map、Set三个接口,存取元素时,各有什么特点?
13.Collection 和 Collections 的区别?
14.ConcurrentHashMap的如何保证线程安全?
16.HashMap是线程安全的吗?如何得到一个线程安全的Map?
19.HashMap为什么要求key重写hashCode和equals方法
2.不会存在内存溢出(JAVA虚拟机规范 规定 计数器不溢出)
2.虚拟机栈(Java Virtual Machine Stacks)(线程私有)
2.1 栈内存溢出(java.lang.StackOverflowError)
4.2 堆内存溢出(异常: java.lang.OutOfMemoryError: Java heap space)
4.讲一下synchronized关键字的底层原理?(高频)
10.notify() 和 notifyAll()有什么区别?
Java基础语法部分:
1. String 、StringBuilder 、StringBuffer 的区别?
- String为字符串常量,内容可以修改,但是Spring对象创建之后,Spring对象是不能更改的。String是只读字符串,引用的字符串内容是不能被改变的。
- 运行速度上的区别: StringBuilder > StringBuffer > String
- 线程安全的区别: StringBuffer的许多方法都带有 synchronized 关键字,所以可以保证线程的安全性。 StringBuilder没有带此关键字,所以不能保证线程的安全,有可能会出现一些错误操作,所以使用单线程的开发环境的话,使用StringBuilder, 多线程的话,使用StringBuffer会更加安全。
2.equals() 与 == 的区别?
- ==号: 如果比较的两个元素是基本数据类型,此时比较的就是两个元素的数值。 如果比较的两个元素是引用数据类型,此时比较的就是两个元素的地址值。
- equals() 只能比较引用数据类型的元素,如果创建实体类的时候,没有重写equals()方法,此时比较的就是两个元素的地址值,如果重写了equals()方法,就按照重写的规则来进行比较
3 是否可以继承String类? 为什么用final修饰?
- 是不能继承String类的,因为String类被final关键字所修饰,被final修饰的类是最终类,不能被继承!
- final修饰的原因是: 1. 把方法锁定,防止任何继承关系修改它的原本类的意义和功能方法的实现。 2. 具有比较高的效率,编译器在遇到final修饰的方法时候,会转入 内嵌机制, 极大的提高了效率。
- 内嵌机制: 当代码调用到final方法时,这个方法会自动展开,而不是函数调用的形式,从而提高了函数运行效率。
- String类之所以不能被继承的根本原因是为了安全和效率。
1.只有字符串是不可变的,字符串池才有可能实现。
2.只有字符串是不可变的,所以多线程是安全的,同一个字符串实例可以被多个线程共享。
3.因为字符串是不可变的,所以在被创建的时候就已经被hashcode缓存了,不需要重新计算,使得字符串很适合做map集合中的 键
4.字符串如果是可变的,会引起很严重的安全问题。
4.什么是面向对象编程?
- 面向对象编程,以建立模型体现出来的抽象思维过程和面向对象的方法,利用类 方法的继承封装多态等概念来进行程序设计的思想称为面向对象编程。
5. 面向对象的三大特征
- 继承:子类继承父类可以使子类拥有父类所有的行为和属性,还可以追加行为和属性,增加了程序的扩展性,继承只支持单继承,但不支持多继承(多个爸爸),但是支持多层继承(孙,父,爷爷)。
- 封装:是指一种将抽象性函数式接口的实现细节部分包装、隐藏起来的方法。防止该类的代码和数据被外部类定义的代码随机访问,合理隐藏实现细节,让程序员更去关注数据的传递,而不用关注方法本身的实现逻辑。
- 父类引用指向子类实现,实现多态的前提条件:必须要继承,重写,向上转型三个条件
6.JDK,JRE,JVM
- JDK:Java开发工具包,包含了JRE 和 JVM。
- JRE: 开发环境,包含JVM和核心类库
- JVM: Java虚拟机
7.Java基本数据类型
- 整型:byte short int(默认) long
- 浮点型: float double(默认)
- 布尔型: boolean
- 字符型:char
8.什么是方法签名?
- 方法的名称和参数列表组成 称为 方法签名
9.Java中的访问修饰符
- private default protected public
10.final有什么用? 和 finally finalize 有什么区别?
- final称为最终的意思,被final修饰的类不能被继承,修饰的方法不能被重写,修饰的变量为常量,不能被重新赋值。
- finally 一般用在try catch 结构中,作用为:不管是否出现异常,都会执行fianlly里面的语句。通常用于释放资源、关闭连接等操作。
- finalize 是object类的方法,用于垃圾回收器中。表示对象在被垃圾回收前执行的方法,通常用于释放非内存资源,如文件句柄、网络连接等。但是,由于finalize方法的执行时间不确定,且可能会影响垃圾回收的效率,因此不建议过多地使用。
11.this 和 super的区别
- this指向的是自身的一个对象,代表对象本身。this()调用的是本类的其他构造方法
- super指向的是自己的一个超类对象,这个超类对象是最近的一个父类。super()调用的是父类的构造方法
12.break , continue , return的区别及作用?
- break: 跳出当前循环
- continue: 结束当前循环进行下一次循环
- return :结束整个方法
13.抽象类能被final修饰吗?
- 不能,final修饰的类不能被继承,而抽象类本身就是用来被继承的,相悖所以不能。
14.static修饰的方法能调用非Static修饰的变量和方法吗?
- 不能,因为静态方法创建出来的时候,非静态资源还没有创建出来,所以静态方法只能调用静态方法和变量。但是,非静态方法可以调用静态方法和变量。
15.局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?
- 因为生命周期不一致,局部变量保存在栈中,当方法结束后,非final修饰的变量会被销毁,而局部内部类对局部变量的引用仍然存在,调用局部变量的时候就会出错。
16.重载(Overload) 和 重写(Override) 的区别?
- 重载:在同一个类中,方法名相同,参数列表不同,构成的方法重载。参数列表不同分为:参数个数, 参数类型, 参数顺序。
- 重写: 在继承的条件下,方法名参数必须相同的情况下,构成了方法的重写 @Override 注解来规范方法重写,如果不是重写方法,会报错。抛出的异常小于父类,访问修饰符大于等于父类。
17.构造器(constructor)是否可被重写??
- 构造器不能被继承,所以不能被重写,但是构造器可以被重载。
18.Java中创建对象的方式有哪些?
- 使用关键字 new
- 使用Class类的newInstance方法
- 使用Constructor类的newinstance方法
- 使用clone方法
- 使用反序列化 (将字节流转换成对象)
19.String str="abc"与 String str=new String("abc")的定义方法一样吗?
不一样
String str = "abc" ; 是在常量池中创建一个字符串对象abc
String str = new String("abc"); 创建了两个对象,"abc"字符串对象在常量池中,new String("")在堆内存中又创建了一个新的对象。
深入回答: 首先这个代码里面有一个 new 关键字, 这个关键字是在程序运行的时候,根据已经加载的系统类String在堆内存里面去实例化一个字符串对象.然后在这个String的构造方法里面呢 传递了一个 "abc"的一个字符串,因为String里面的字符串成员变量是一个final修饰的,所以他是一个字符串常量,所以接下来JVM会去拿字面量"abc"去字符串常量池里面去试图找到对应它的一个String的对象引用,如果拿不到,就会在堆内存里面去创建一个"abc"的String对象,并且把引用保存到字符串常量池里面,后续如果再有字面量"abc"的一个定义,因为字符串常量池里面,已经存在字面量"abc"的引用 所以只需要从常量池里面获取对应的引用就可以了,不需要再去创建
20.BIO、NIO、AIO 有什么区别?(高频)
- BIO的英语全称是Block IO, 同步阻塞式 IO,就是平常经常使用的传统 IO,特点是简单方便,但并发处理能力低。
- NIO,叫New IO, 同步非阻塞 IO,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用(由一个线程管理多个通道默认管理的通道数量为1024个。
- AIO,Asynchronous IO, 是 NIO 的升级,实现了异步非堵塞 IO ,它是基于事件和回调机制。
Java集合相关:
1.ArrayList 和 LinkedList的区别?
ArrayList查询速度快,但是不准确,尾部增删快,头部增删慢,随机访问速度快。
LinkedList头尾增删速度快,中间不高,性能远比Arraylist差,不适合做查询,真想查询用hashmap
- 是否保证线程安全:ArrayList 和 LinkedList 都不保证线程安全; (Vector就比Arraylist多一个同步优化机制,所以线程安全)
- 底层数据结构:ArrayList 底层使用的是数组; LinkedList底层使用的是双向链表;
- 插入和删除是否受元素位置的影响
ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。
LinkedList采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响。
4.是否支持快速随机访问:LinkedList 不支持高效的随机元素访问,ArrayList实现了RandomAccess接口,所以有随机访问功能。
5.内存空间占用:
ArrayList的空间浪费主要结尾会预留一定的容量空间。
LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间。
2.ArrayList底层原理
- 创建集合时候,底层创建长度为0的数组
- 添加第一个元素的时候,再创建长度为10的数组
- 当存储的元素数遇到阈值的时候,自动扩容,创建长度为老数组的1.5倍的新数组,将老数组的元素拷贝到新数组当中。
- 批量添加元素的时候,会以实际长度为准创建新数组
3.LinkedList底层原理
- 添加首元素时,先创建节点对象Node(null,本节点元素值,null)
- 再添加元素时,再创建节点对象Node(上节点地址值,本节点元素值,null),同时将本节点的地址值,赋值给上节点的下节点地址值
4.HashSet底层原理
- 底层先创建出长度为16的数组,table
- 添加每个元素时候,先通过hashCode()方法获取该元素的hash值,对hashCode再调用hashMap的hash方法进行二次hash运算(将hash的分布更均匀),对数组长度取余计算元素存储的位置。
- 判断该位置元素是否为null, 如果为null直接存储; 不为null,再调用元素的equals()方法比较值
- 值相等: 不存。 值不相等:1.8将新元素挂载在老元素下面,以链表形式
- 如果该链表长度 > 8 并且数组长度 >= 64 会将该链表转为红黑树结构
5.HashMap底层结构
- JDK8以前:数组 + 双链表
- JDK8以后:数组 + 双链表 + 红黑树
6.HashMap 的自动扩容原理
- 初始化容量为16,达到阈值进行扩容。阈值 = 最大容量 * 负载因子(0.75),扩容每次2倍,总是2的n次方。
- 扩容机制:使用一个容量更大的数组替代已有的容量小的数组,transfer()方法将原有的Entry数组的元素拷贝到新的Entry数组里。
7.HashMap你经常用在那个地方
-
电子商务的应用中使用HashMap作为缓存。
-
金融领域出于性能的考虑非常多的运用HashMap和ConcurrentHashMap。
-
controller层向前台返回数据可以用map封装数据
-
mybatis中的map可以作为参数或者封装结果集
8.HashMap和Hashtable的区别?
- HashMap去掉了 HashTable 的 contains 方法,但是加上了 containsValue() 和 containsKey() 方法。
- HashTable 同步的,而HashMap是非同步的,效率上比HashTable要高。
- HashMap允许空键值,而HashTable不允许。
9. List、Map、Set三个接口,存取元素时,各有什么特点?
- List有序可重复
- Set无序不可重复
- Map一般都是键值对 Key-Value值, value可多值
- 通过元素的两个方法 hashcode() 和 equals() 方法来完成的
11.TreeSet怎么对集合中的元素进行排序?
- TreeSet底层数据结构是二叉树
- 让元素自身具备比较性,需要元素对象实现 Comparable接口,重写 compareTo方法
- 让集合自身具备比较性,需要定义一个实现了C