1-Java基础篇
1. Final 有什么用?
被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变,
被final修饰不可变的是变量的引用,而不是引用指向的内容, 引用指向的内容是可以改变的
2. 什么是重载(Overload)和重写(Override) ?
重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与 方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分
重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于 父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中 就不能重写。
3. 重载的方法能否根据返回类型进行区分?
方法重载不可以根据返回类型区分
4. == 和 equals 的区别是什么
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数 据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。
5. 什么是反射机制?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任 意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法 的功能称为java语言的反射机制。
6. 反射机制优缺点
优点: 运行期类型的判断,动态加载类,提高代码灵活度。
缺点: 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要 慢很多
7. 在你进行项目开发的过程中有没有用到过反射
在我们的项目中经常会使用反射 + 自定义注解的方式去实现一些功能 , 例如 :
1在前后端交互的时候, 后端Long类型返回前端后会产生精度丢失 , 我们的处理方式就是在服务端, 通过配置修改Jackson的序列化规则, 将一些Long类型字段转化为字符串返回给前端, 这个时候我们自定义了一个@IdEncrpt注解 , 通过反射获取类的属性, 判断属性上是否添加了@IdEncrpt注解, 如果添加了 , 就会通过反射获取属性值, 转化为字符串
2在整合EMQ的时候 , 为了能够方便的接收订阅消息, 我们自定义了一个@Topic注解 , 作用在类上 , 之后我们通过反射获取类的字节码, 并且获取类上的@Topic注解, 读取到里面定义的主题 , 通过策略模式将不同主题的消息分发到不同的处理器中
3除了上述之外, 在我们项目开发中经常使用的一些框架, 例如 : Mybatis , Spring , SpringMVC 等, 以及一些常用的工具库 common-utils , hutool工具库等都大量使用到了反射机制
8. String和StringBuffer、StringBuilder的区别是什么?
可变性 : String类中使用字符数组保存字符串,所以string对象是不可变 的。
StringBuilder与StringBuffer这两种对象都是可变的。
线程安全性 : String中的对象是不可变的,也就可以理解为常量,线程安全。StringBuffer对方法加了同步锁或者对调用的方法加了同 步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
性能 : 每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对 象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引 用。
StirngBuilder 相比使用StringBuffer而言效率更高
9. java常见的集合类有哪些
Map接口和Collection接口是所有集合框架的父接口:
1Collection接口的子接口包括:Set接口和List接口
2Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及 Properties等
3Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
4List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
10. 常用的线程安全的类有哪些 ?
Plain Text
复制代码
1
2
3
4
5
1. Vector:就比Arraylist多了个 synchronized (线程安全),因为效率较低,现在已经不太建议使 用。
2. hashTable:就比hashMap多了个synchronized (线程安全),不建议使用。
3. ConcurrentHashMap:是Java5中支持高并发、高吞吐量的线程安全HashMap实现
11. ArrayList 和 LinkedList 的区别是什么?
1数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实 现。
2随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数 据存储方式,所以需要移动指针从前往后依次查找。
3增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其他数据的下标。
4内存空间占用:LinkedList 比 ArrayList 更占内存,因为 LinkedList 的节点除了存储数据,还存储 了两个引用,一个指向前一个元素,一个指向后一个元素。
5线程安全:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;
12. 说一下HashMap的实现原理?
HashMap的数据结构: HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
HashMap 基于 Hash 算法实现的
1当我们往HashMap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数 组中的下标
2存储时,如果出现hash值相同的key,此时有两种情况。
a如果key相同,则覆盖原始值;
b如果key不同(出现冲突),则将当前的key-value放入链表中
3获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
HashMap JDK1.8之前
JDK1.8之前采用的是拉链法。拉链法:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。
HashMap JDK1.8之后
相比于之前的版本,jdk1.8在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8) 时,将链表转化为红黑树,以减少搜索时间。扩容 resize( ) 时,红黑树拆分成的 树的结点数小于等于临界值6个,则退化成链表。