Java基础面试题
什么是红黑树
- 每个节点要么是红色,要么是黑色。
- 根节点必须是黑色
- 红色节点不能连续(也即是,红色节点的孩子和父亲都不能是红色)。
- 对于每个节点,从该点至 null(树尾端)的任何路径,都含有相同个数的黑色节点。
Java反射机制
在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法;对于任何一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象属性和方法的功能称为Java语言的反射机制。
什么是B树
B树是红黑树的一个变种,是一颗自平衡的多叉树。结点不再存储一个数据项,而是有多个数据项,数据项中包含key和value。
什么是B+树
B+树在B树之上又做了一层优化,非叶子节点也是存储多个数据项,但是数据项中只包含了key。
Java为什么要有包装类
- 包装类里面有一些很有用的方法和属性,如HashCode,ParseInt。
- 基本类型不能赋null值,某些场合需要。
- 有些地方不能直接用基本类型,比如集合。
什么时候用包装类,什么时候用基本类型?
- 在pojo类中定义的属性用包装类。
- 在rpc方法中定义参数和返回值的类型用包装类。
- 定义局部变量用基本类型。
Java数组与集合区别
- 数组:大小固定,只能存储相同数据类型的数据。
- 集合:大小可动态扩展,可以存储各种类型的数据。
JDK,JRE,JVM有什么区别?
- JDK:Java Development Kit,Java开发工具包,提供了Java的开发环境和运行环境。包含了编译Java源文件的编译器Javac,还有调试和分析的工具。
- JRE:Java Runtime Environment,Java运行环境,包含Java虚拟机及一些基础类库。
- JVM:Java Virtual Machine,Java虚拟机,提供执行字节码文件的能力。
Java中的native关键字
native方法称为本地方法。在java源程序中以关键字”native”声明,不提供函数体。其实现使用C/C++语言在另外的文件中编写,编写的规则遵循Java本地接口的规范(简称JNI)。简而言就是Java中声明的可调用的使用C/C++实现的方法。
你不得不知道的哈希表(知乎)
Object类里面的方法
- getClass():返回此 Object 的运行类
- hashCode():用于获取对象的哈希值
- equals():用于确认两个对象是否相同
- clone():创建并返回此对象的一个副本
- toString():返回该对象的字符串表示
- finalize():当对象不再被任何对象引用时,GC会调用该对象的finalize()方法
运行时异常和检查时异常区别
Java提供了两类主要的异常:runtime exception和checked exception。checked 异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。
但是另外一种异常:runtime exception,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。
出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
如果不想终止,则必须扑捉所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。在这个场景这样处理可能是一个比较好的应用,但并不代表在所有的场景你都应该如此。如果在其它场景,遇到了一些错误,如果退出程序比较好,这时你就可以不太理会运行时异常,或者是通过对异常的处理显式的控制程序退出。
面向对象都有哪些特性
封装、继承、多态、抽象。
浅拷贝和深拷贝的区别
- 浅拷贝拷贝出当前对象的一个副本,这个新对象和当前对象处于不同的堆内存中,两个对象的基本数据类型的值完全一样,但是引用数据类型还是指向同一个对象。
- 深拷贝拷贝出当前对象的一个副本,这个新对象和当前对象处于不同的堆内存中,两个对象的基本数据类型的值完全一样,引用数据类型指向的对象也拷贝出了一份一模一样的副本。
Java 如何重写对象的 equals 方法和 hashCode 方法
https://www.cnblogs.com/yuxiaole/p/9570850.html
String类相关
- String对象的intern()方法会得到字符串对象在常量池中对应的字符串的引用,如果常量池中没有对应的字符串,则该字符串将被添加到常量池中,然后返回常量池中字符串的引用。
- 字符串的+操作其本质是创建了StringBuilder对象进行append操作,然后将拼接后的StringBuilder对象用toString方法处理成String对象。
Java中有几种类型的流
输入流、输出流、字节流、字符流。
字节流如何转为字符流
- 字节输入流转字符输入流通过InputStreamReader实现,该类的构造函数可以传入InputStream对象。
- 字节输出流转字符输出流通过OutputStreamWriter实现,该类的构造函数可以传入OutputStream对象。
字节流和字符流的区别
字节流可以处理所有类型数据,字符流只能处理字符数据。
如何实现对象克隆
- 实现Cloneable接口并重写Object类中的clone()方法。
- 实现Serializable接口,通过对象的序列化和反序列化实现克隆。
写一个ArrayList的动态代理类
| 1 | List<String> list = new ArrayList<>(); | 
动态代理和静态代理的区别
- 静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类。
- 静态代理事先知道要代理的是什么,而动态代理不知道要代理什么,只有在运行时才知道。
JDK动态代理和CGLIB动态代理的区别
- JDk动态代理是实现InvocationHandler接口的invoke方法,代理的是接口,也就是业务类必须要实现接口,通过Proxy里的newProxyInstance得到代理对象。
- CGLIB动态代理代理的是类,不需要业务类实现接口,通过派生的子类来实现代理,通过在运行时,动态修改字节码达到修改类的目的。
Java数组和链表的区别
- 数组一旦初始化,长度就不能改变;链表长度可以改变。
- 数组在内存中是连续存储的,链表不是连续存储的。
- 数组查找快,插入删除慢;链表查找慢,插入删除快。
Java8的Stream中的中间操作方法
- 过滤:filter()
- 截断流:limit()
- 跳过元素:skip(n)
- 筛选:distinct()
- 映射:map() flatMap()
- 排序:sorted()
Comparable和Comparator区别是什么?