Java语言有哪些特点
简单易学、提供丰富的类库
面向对象、高内聚低耦合
与平台无关、JVM跨平台
可靠安全、支持多线程
面向对象和面向过程的区别
面向过程:是分析解决问题的步骤,然后用函数把这些步骤一步步实现,然后在使用的时候一起调用即可,性能较高,所以单片机嵌入式开发都是采用面向过程来实现。
面向对象:是把构成问题的事务分解成各个对象,建立对象是描述某个事务在解决问题中所发生的行为,面向对象有 封装、继承、多态 的特性,所以易维护、易复用、易扩展。可以设计出低耦合的系统,从性能上来说,要比面向过程要低。
八种基本数据类型及封装类
int 是基本数据类型,Integer是int的封装类型,是引用类型,int的默认值是0,Integer的默认值是 null ,在任何引用对象使用前,必须为其指定一个对象,否则会报错。
基本数据类型在声明时系统会自动分配空间,而引用对象只是分配了引用空间,必须实例化开启数据空间才可赋值。数组对象也是引用操作,数组赋值只是赋值了引用,修改对其中一个数组也可见。
boolean这种数据类型,在java虚拟机中没有对boolean提供专业的字节码指令,编译后用int来代替,高效存取的特点。
instanceof关键字的作用
用来测试一个对象是否为一个类的实例
boolean result = obj instanceof Class ;
编译器会检查obj 能否转换成右边的class对象,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时情况。
Java自动装箱与拆箱
装箱:自动将基础类型装换成封装类型(int -> Integer)
拆箱:自动将封装类型转换成基础类型 (Integer -> int)
如果述职在 [ -128,127] 之间,便直接返回cache中已经存在的引用对象,否则创建一个新的对象。
Integer c = new Integer(100); Integer d = new Integer(100);
如果 单独进行对象创建 则 c==d 为 false
Integer i = 1; int ii = 1; System.out.println(i == ii);
上面代码 输出 也为 true ,因为包装类型会自动拆箱转化成int进行比较。
重写和重载的区别
重写(override):从字面意思上看,就是把父类方法重写一遍的意思,子类继承了原有父类的方法,在参数列表,返回类型都相同的情况下,进行一个重写。发生在父类与子类之间,方法名、参数列表、返回类型 必须相同。
重载(overload):在一个类中,同名的方法如果有不同的参数(参数类型不同、参数个数不同、参数顺序不同)则视为重载,同时,重载对返回类型没有要求。重载是一个类中多态的一种表现。
equals与==的区别
== :比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象地址是否相等,指是否是同一个对象,比较的真正意义是指针的操作。比较的是操作符两端的操作数是否是同一个对象。比较的是地址的指针指向。
equals:比较两个对象的内容是否相等,适用于所有对象,如果没有重写该方法时调用的还是Object中的equals方法。而Object判断已然采用 == 来进行判断。
hashcode的作用
java的集合有两类:List(有序可重复)、set(无序不重复)
set在插入的时候判断集合中是否存在该元素,如果采用equals方法的话,效率过低,于是有了hash算法来提高集合中查找元素的效率。
hashcode是根据内存地址换算出一个值,这样一来要添加新元素时,先调用hashcode方法,这样能快速定位物理地址,如果没有这个元素则直接进行存储,如果有进行equals进行比较。
String、StringBuffer、StringBuilder的区别
String是一个对象,是一个final的字符数组,所以一经定义无法修改,每次都会产生一个新的String对象。
StringBuffer、StringBuilder 底层都是可变的字符数组,频繁的字符串操作时建议采用StringBuffer,采用了同步锁,线程安全
ArrayList 和 LinkedList的区别
Array数组是基于索引(index)数据结构,在搜索和读取速度非常快,删除的开销比较大,因为需要索引重排序,数组需要初始化长度。
List是一个有序的集合,可以包含重复的元素,提供按索引的访问方式,它继承至Collectio
ArrayList看作是能够自动增长容量的数组,底层实现是数组。
LinkList 是一个双链表,地址是任意的,所以在开辟内存空间时不需要等待一个连续的地址,在添加和删除时有更好的性能,在获取方面弱于ArrayList。
使用场景:当需要对数据进行随机访问首选ArrayList,需要对数据进行多次修改和删除首选LinkedList,
如果容量固定,并且只会添加到尾部,不会引起扩容,优先采用ArrayList。
有了数组为什么还要有ArrayList
数组容量初始化是定死的,ArrayList可以动态扩容,也就是动态数组。
HashMap 和 HashTable的区别 ConcurrentHashMap
安全性不同:HashMap是非线程安全的,在多线程的情况下,可能产生死锁,需要我们自己解决多线程安全问题,
HashTable是线程安全的,因为采用了同步锁,可直接用于多线程情况。
虽然HashMap非线程安全,但是效率远高于HashTable,需要多线程安全使用ConcurrentHashMap,使用了分段锁,并不是对整个数据进行锁定。
对null的支持不同,HashTable 对key和value都不能为null,key可以为null,但只允许存在一个,对于value可以有多个null。
HashMap 如果key为null,则hashcode为0,至于value为null,则没有进行判断。
ConcurrentHashMap 1.7 的数据结构和底层原理:默认分为16个桶,如 get 、put、remove只锁住当前用到的桶,原来只能一个线程进入,现在可以同时16个线程进入。Segment继承了ReentrantLock
ConcurrentHashMap :锁分段技术,首先讲数据分成一段一段存储,然后给每一段数据配一把锁,当一个线程占用其中一段锁时,其他数据也能被其他线程访问到。
ConcurrentHashMap 1.7 查找需要两次hash操作,第一次是定位到Segment,第二次是定位到所在链表的头部。
ConcurrentHashMap 1.8采用:CAS+Synchronized保证线程安全 ,Synchronized锁粒度降低,Synchronized 基于JVM原生实现,优化粒度比较大。
Collection 和 Conllections包的区别
Cllection是集合类的父类,子接口有Set、List、ArrayList、LinkedList等
Conllections是一个集合类的帮助类,类似于一个工具类。
四种引用:强弱软虚
强:平时用的最多,即使OOM也不会被回收。
弱:只要JVM垃圾回收器发现即进行回收。
软:内存不足时,则被回收。
虚:JVM发现即回收,虚引用创建时必须带 ReferenceQueue。
Java创建对象的方式有几种
new、反射、序列化、clone
有没有两个不相等的对象产生相同的HashCode
有可能,产生hash冲突的时候,一般采用一下方式来处理
再哈希,页脚双哈希法,有多个不同的hash函数,当发生冲突时,使用第二个、第三个进行地址计算,直到没有冲突
开放地址法:寻找下一个空的散列地址,只要散列空间足够大,就能找到并进行记录。
深拷贝和浅拷贝
浅拷贝:引用指向原对象
深拷贝:复制的对象引用对象都复制一遍。
final关键字有哪些用法
final修饰的类不可以被继承
fianl修饰的方法不可以被重写
final修饰的常量在编译启动阶段会纳入常量池
static有哪些用法
可以用于修饰静态类和静态方法
也多用于初始化操作
OOM遇到过哪些,SOF遇到过哪些
OutOfMemoryError异常
Java Heap溢出
运行时常量池溢出:PermGenspace
SOF:堆栈溢出 StackOverflow(大量递归、大量循环、死循环、数组数量过大)
Java序列化中如果有些字段不想被虚拟化,怎么办
transient关键字进行修饰,只修饰变量,不能修饰类和方法。
Java的反射作用及原理
反射机制是在运行时,对于任何一个类,都能知道这个类属性和方法
动态获取的信息或动态调用对象的方法叫Java的发射
加载mysql 的驱动类 Class.forName(‘com.mysql.jdbc.Driver.class’);
反射机制的优缺点:能够动态获取类的实例和方法,提高灵活性;使用反射性能较低,需要解析字节码,关闭安全校验,提升反射速度;相对不安全,破坏了封装性。
List、Map、Set的区别
List:存储一组不唯一(可以有多个引用相同的对象),有序的对象。
Set:不允许重复的集合,不会有多个元素引用相同的对象。
Map:通过键值对进行存储,key不能重复,但是key可以引用两个相同的对象。
HashMap中的key可以是任意定义的类吗
如果重写了equals方法,也必须重写hashCode方法
类所有的实例都必须遵循equeals和hashCode的规则
HashMap 与 ConcurrentHashMap 的异同
都是采用key-value存储数据
HashMap是非线程安全的、ConcurrentHashMap是线程安全的
HashMap底层数据结构是 数组+链表(1.8之前)1.8之后采用 数组+链表+红黑树,当链表元素个数达到8时,链表自动转化为红黑树,查询速度更快。
HashMap初始化大小为16,当出现扩容的时候,以0.75*数组大小进行扩容
1.8之后采用乐观锁来实现,Compare And Swap cas进行比对,如果相等则表示没有被修改过,是线程安全的。
链表扩容,头插法和尾插法,头插法改变链表顺序,性能低;尾插法不改变顺序,性能高。
红黑树的特征
根节点是黑色
每个节点是红色或者黑色
如果一个叶子节点是红色,那么其子节点必须是红色
每个叶子结点都是黑色