大数据常见面试题之Java基础

一.HashMap

jdk7:数组+链表

jdk8:数组+链表+红黑树

HashMap中维护了Node类型的数组table,初始为null
1.创建对象时,将加载因子loadFactor初始化为0.75,其他成员保持默认值
2. 添加元素时,相当于putVal方法,需要先将元素的key哈希值取出来,并且运算得出在数组中存放索引
如果该索引出没有其他元素,则直接存放
若该索引处有其他元素,需要先判断是否相等,若相等则覆盖,若不相等则继续判断是否为树结构或链表结构,根据不同结构进行不同处理
3.如果需要扩容,则进行相应的扩容
如果第一次添加,则扩容table的capacity为16临界值threshold为12
若其他次扩容,则扩容table的capacity为2倍,临界值threshold为2倍
4.当链表节点数>=7&&capacity>=64则将链表变成树结构

jdk7和jdk8的对比如下

版本 结构 table数据类型 初始容量
jdk7 数组+链表 Entry 16
jdk8 数组+链表+红黑树 Node 0

jdk7中创建对象时,则初始化table容量为16(饿汉式)
jdk8中创建对象时并没有初始化,而是第一次添加元素初始化table容量为16(懒汉式)

二.面向对象的特征

1.继承

继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.
对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类).派生类可以从他的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要.

2.封装

封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治,封装的对象,这些对象通过一个受保护的接口访问其他对象

3.多态

多态性是指允许不同类的对象对同一消息做出响应,多态性包括参数化多态性和包含多态性.多态性语言具有灵活,抽象,行为共享,代码的优势,很好的解决了应用程序函数同名问题,基础是方法重写

三.Error和Exception的区别

首先Exception和Error都继承自Throwable类,在Java中只有Throwable类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型.Exception和Error体现了java这门语言对于异常处理的两种方式.Exception是java程序运行中可预知的异常情况,可获取到这种异常,并且对这种异常进行业务外的处理.Error是Java程序中不可预料的异常情况,这种异常发生后会直接导致JVM不可处理或者不可恢复的情况.所以这种异常不可能抓取到,比如OutOfMemoryError,NoClassDefoundError等.其中Exception又分为检查性异常和运行时异常(RunTImeException).两个根本的区别在于检查性异常必须在编写代码时使用try catch捕获比如(IOexception).运行时异常在代码编写时,可以忽略捕获操作,这种异常是在代码编写或者使用过程中通过规范可以避免发生的

四.说明Java中反射的实现过程和作用分别是什么

Java语言编译之后会生成一个*.class文件,反射就是通过字节码文件找到一个类,类中的方法和属性等.反射的实现主要借助一下四个类: Class:类的对象,Constructor:类的构造方法,Field:类中的属性对象,Method:类中的方法对象
作用:反射机制指的是程序在运行时能够获取自身的信息,在Java中,只要给定类的名字,那么就可以通过反射机制来壶球类的所有信息

五.HashMap和HashTable区别

  • HashMap:线程不安全,key和value可以是null
  • HashTable:线程安全,key和value不可谓null

六.TreeSet和HashSet区别

HashSet是采用hash表来实现的,其中的元素没有按顺序排列,add(),remove()和contains()方法都是复杂度为O(1)的方法
TreeSet是采用树结构实现(红黑树算法).元素是按顺序进行排列,但是add(),remove(),和contains()等方法都是复杂度为O(log n)的方法,它还提供了一些方法来处理排序的Set,如first(),last(),headSet(),tailSet()等

七.StringBuffer和StringBuilder的区别

StringBuffer与StringBuilder中的方法和功能完全是等价的
只是StringBuffer中的方法大都采用了synchronized关键字修饰,因此是线程安全的,而StringBuilder没有这个修饰,可以被认为线程不全
在单线程程序下,StringBuilder效率更快,因为他不需要加锁,不具备多线程安全而StringBuffer则每次都需要判断锁,效率比相对更低

八.关键字final,finally,finalize区别

1.final

final修饰符有三种用法
如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词
将变量声明为final,可以保证他们再使用中不被改变,被声明为final的变量必须在声明变量时给定初始值,而在以后的引用中只能读取不能修改
被声明为final的方法也同样只能使用,不能在子类中被重写

2.finally

通常放在try catch的后面构造总是执行的代码块,这就意味着程序无论正常执行还是
发生异常,这里的代码只要JVM不关闭都能够执行,可以将释放外部资源的代码写在finally块中

3.finalize

Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作,这个方法时由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作

九.==和equals区别

  • == 如果比较的是基本数据类型,那么比较的是变量的值
  • == 如果比较的是引用数据类型,那么比较的是地址值(两个对象是否都指向同一块内存)
  • equals 如果没有重写equals方法,比较的是两个对象的地址值,若重写方法后往往比较的是对象中属性内容
  • equals方法是从Object类中继承的,默认的实现就是使用==

十.Java支持的数据类型有哪些?什么是自动拆装箱

Java支持8种基本数据类型:byte short int long float double boolean char
自动装箱时Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化,即基本数据类型–>对象包装类型,比如int转化成Integer,反之就是自动拆箱

十一.方法覆盖与方法重载

方法覆盖是说子类重新定义了父类的方法.方法覆盖必须有有相同的方法名,参数列表和返回类型,覆盖着可能不会限制它所覆盖的方法的访问,方法重写又称为方法覆盖.若子类种方法与父类中某一方法具有相同的方法名,如需父类的方法,可使用super关键字该关键字引用了当前类的父类
Java中的方法重载发生在同一个类里面两个或多个方法的方法名相同但是参数列表不同的情况,调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法,返回类型可以相同也可不同,无法以返回类型作为重载的区分标准

十二.接口和抽象类的区别

接口所有的方法隐含的都是抽象的,而抽象类则可以同时包含抽象和非抽象的方法
类可以实现多个接口,但是只能继承一个抽象类
类如果要实现一个接口,必须实现接口所有的方法,但是类可以不实现抽象类所有的方法,当然在这种情况类也必须是抽象的
抽象类可以在不提供接口方法实现的情况下实现接口
Java接口声明的变量默认都是final的,抽象类可以包含非final的变量
Java接口中方法默认是public abstract的,而抽象类则没有这个限制
接口是绝对抽象的,不可被实例化,抽象类也不可以被实例化,但是如果它包含main方法是可以被调用的

猜你喜欢

转载自blog.csdn.net/sun_0128/article/details/107618502