java基础面试
1 什么又是面向对象?
面向过程就是分析出实现需求所需要的步骤,一步一步实现这些步骤。
面向对象是把整个需求按照功能特点划分,将这些存在共性的部分封装成类,创建实例对象
2.JDK、JRE、JVM三者间的联系与区别
JDK(Java SE Development Kit),Java标准开发包,包括Java编译器、Java运行时环境,以及常用的Java类库等。
JRE( Java Runtime Environment) 、Java运行环境,用于解释执行Java的字节码文件。普通用户而只需要安装 JRE(Java Runtime Environment)来运行 Java 程序。
JVM(Java Virtual Mechinal),Java虚拟机,是JRE的一部分。是整个java实现跨平台的最核心部分,负责解释执行字节码文件,所有平台的上的JVM向编译器提供相同的接口,而编译器只需要生成虚拟机能识别的代码,然后由虚拟机来解释执行。
区别与联系
- JDK 用于开发,JRE 用于运行java程序 ;如果只是运行Java程序,可以只安装JRE,无序安装JDK。
- JDk包含JRE,JDK 和 JRE 中都包含 JVM。
- JVM 是 java 编程语言的核心并且具有平台独立性。
==和equals的区别
1.两者的区别
== 为运算符
equal 为String数据类型的比较方法
2.两者的比较范围
==可用比较基础类型,也可用比较引用类型,比较基础类型的时候,比较的是值是否相同,比较引用类型,比较的是地址是否相同
equal 只能用来比较引用类型,equals继承Object类,比较的是是否是同一个对象,即对象的引用地址是否一样,如果自己重写了equal方法则比较的是对象里面的属性值。
final关键字的基本用法
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。
修饰变量 ,必须赋予初始值且不能被改变,修饰引用变量时,该引用变量不能再指向其他对象。
当用final修饰一个类时,表明这个类不能被继承。
方法前面加上final关键字,代表这个方法不可以被子类的方法重写。
string和stringbuffer和stringbuilder的区别
String
String的值是不可变的字符串类,这就每次拼接会产生新的对象,不仅效率低下,而且浪费大量的内存空间
StringBuffer是可变类,和线程安全的字符串操作类,可以自动增加容量 ,多线程操作字符串
stringbuilder的是可变类,速度更快,可以自动增加容量,线程不安全的
重载和重写的区别
重载:在类中可以创建多个方法,具有相同的名字,但具不同的参数类型和参数个数,参数顺序,体现了多态性
重写:子类继承父类或者实现接口,重写方法;
接口和抽象类的区别
抽象类:在Java中被abstract关键字修饰的类称为抽象类,被abstract关键字修饰的方法称为抽象方法,抽象方法只有方法的声明,没有方法体。
a、抽象类不能被实例化只能被继承;
b、包含抽象方法的一定是抽象类,但是抽象类不一定含有抽象方法;
c、抽象类中的抽象方法的修饰符只能为public或者protected,默认为public;
d、一个子类继承一个抽象类,则子类必须实现父类抽象方法,否则子类也必须定义为抽象类;
e、抽象类可以包含属性、方法、构造方法,但是构造方法不能用于实例化,主要用途是被子类调用。
接口:Java中接口使用interface关键字修饰,特点为:
a、接口可以包含变量、方法;变量被隐士指定为public static final,方法被隐士指定为public abstract(JDK1.8之前);
b、接口支持多继承,即一个接口可以extends多个接口,间接的解决了Java中类的单继承问题;
c、一个类可以实现多个接口;
聊聊list和set
继承了collection
(1)重复对象
list方法可以允许重复的对象,而set方法不允许重复对象
(2)null元素
list可以插入多个null元素,而set只允许插入一个null元素
(3)容器是否有序
list是一个有序的容器,保持了每个元素的插入顺序。而set方法是无序容器,无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序
(4)常用的实现类
list方法常用的实现类有ArrayList、LinkedList 和 Vector。
Set方法中最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。
ArrayList、LinkedList
ArrayList底层是动态数组的数据结构,可以进行动态的扩容
LinkedList基于链表的数据结构,是一个双向列表,保存着首节点和尾节点的地址。
这是两种截然不同的实现技术,这也决定了它们将适用于完全不同的工作场景。
ArrayList用于查询,LinkedList用于新增,删除。
hashMap和hashTable的区别?
1.线程安全性不同,Hashtable 线程安全,因为它每个方法中都加入了Synchronize。HashMap是线程不安全的。
2、继承的父类不同,HashTable继承Dictionary类,而hashMap继承了AbstractMap类,但是二者都实现了map接口。
3.部分api不同,HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey。Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。
4.两个遍历方式的内部实现上不同: Hashtable、HashMap都使用了 Iterator,Hashtable还使用了Enumeration的方式
5.hash值不同,HashMap是自定义的哈希, Hashtable直接用key的hashCode()。
6.内部实现使用的数组初始化和扩容方式不同,HashMap默认初始化容量为16,扩容方式要求一定为2的整数次幂。 Hashtable默认初始化容量为11,扩容方式要求为2的整数次幂+1;
7.HashMap的key和value是允许null,Hashtable不允许。
hashMap底层实现:数组+链表实现
jdk开始链表的高度到8,数组的长度超过64,链表转为红黑色,元素以内部类Node节点存在
存元素的步奏
先计算key的hash值,然后二次hash对数组长度取模,得到数组对应的下标,判断hashcode对应的下标位置有没有元素,如果没有元素为空,直接存放元素,此时没有链表。如果有元素,会出现hash冲突,在进行equals比较,如果equals相等证明是同一个元素,说明key值重复,则取代该元素。如果equals不同,就会维护一个线性链表存储,如果hash冲突过多,链表的高度到8,数组的长度超过64,链表转为红黑色,长度低于6红黑树又会转化为链表。
key为null,放在下标为0的位置
数组扩容和Arraylist一样,到达一定条件,先创建一个新的数组,设置对应长度,将旧数组的值复制到新数组中。
ConcurrentHashMap
如何实现一个ioc容器
1.写一个配置文件,配置包的扫描路径
定义一些注解,分别表示访问控制层,业务层,持久层,依赖注入注解,获取配置文件注解。
2.递归包扫描获取.class文件:从配置文件中获取扫描的包路径,获取当前路径下的文件和文件夹信息,将所有.class结尾的文件添加到一个set集合中存储
3.反射,确定需要交给ioc管理的类:遍历set集合,获取类上有指定注解的类,交给ioc,定义一个安全的map用来存储这些对象
4.对需要注入的类进行依赖注入:遍历ioc容器,获取每个类的实例,判断里面是否有依赖其他类的实例,然后进行递归注入
Java的异常体系
Java把异常作为一种类,当做对象来处理。
所有异常类的基类是Throwable类,两个子类分别是Error和Exception。Error是错误,无法处理,一旦出现,程序被迫停止运行。
Exception异常分为RuntimeException(运行时异常)和CheckedException(编译时异常)。
线程的生命周期和线程的几种状态
线程的生命周期包含5个阶段,包括:新建、就绪、运行、阻塞和死亡状态。
阻塞分为三种:
1.等待阻塞,运行的线程执行了object的wait方法,jvm会把该线程放到“等待池中”,不能自动唤醒,必须依靠其他线程调用notify或者notifyall方法
2.同步阻塞,运行的线程在获取同步锁Synchronized时,同步锁被其他线程占用,jvm会把该线程放到“锁池中”
3.其他阻塞,运行线程调用了sleep方法或者join方法,或者发出I/O请求,jvm会把线程设置为阻塞状态,当sleep超时,join终止或者超时,I/O处理完毕,线程会重新转到就绪状态。sleep是thread类方法。

浙公网安备 33010602011771号