1.Java面向对象编程三大特征:封装 继承 多态

封装

封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。

继承

继承时使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便的复用以前的代码。

关于继承的三点:

1.子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问的,只是拥有
2.子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
3.子类可以用自己的方式实现父类的方法

多态

所谓多态就是指程序中定义的应用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定的,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须由程序运行期间才能决定。

在Java中有两种形式可以实现多态:继承和接口

2.String StringBuffer 和 StringBuilder的区别是什么?String为什么是不可变的

可变性

简单的来说:String 类中使用的final关键字修饰字符数组保存字符串,private final char value[],所以String对象是不可变的。

补充:在Java9之后,String类的实现改用byte数组存储字符串 private final byte[] value

而StringBuilder 与 StringBuffer 都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串char[] value 但是没有用final关键字修饰,所以这两种对象都是可变的,

线程安全性

String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

性能

每次对String类型进行改变的时候,都会产生一个新的String对象,然后将指针指向新的String对象。StringBuffer 每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并未改变对象的引用。相同情况下使用StringBuilder相比使用StringBuffer仅能获得10%~15%左右的性能提升,但却要冒线程不安全的风险。

对于三者的使用总结:

  1. 操作少量的数据:使用String
  2. 单线程下操作大量数据:使用StringBuilder
  3. 多线程下操作大量数据:使用StringBuffer

2.Java集合框架

Collection

  1. List
  • ArrayList Object数组
  • Vector Object数组
  • LinkedList 双向链表(jdk1.6之前为循环,jdk1.7取消了循环)
  1. Set
  • HashSet (无需且唯一):基于HashMap实现的,底层采用HashMap来保存元素
  • LinkedHashSet:LinkedHashSet继承于HashSet,并且其内部是通过LinkedHashMap来实现的。
  • TreeSet(有序唯一)

Vector是Java早期早期提供的线程安全的动态数组,如果不是线程安全,并不建议选择,毕竟同步是有额外开销的。Vector内部是使用对象数组来保存数据,可以根据需要自动的增加容量,当数组已满时,会创建新的数组,并拷贝原有数组数据。

ArrayList是应用更加广泛的动态数组实现,他本身不是线程安全的,所以性能要好很多。与Vector近似,ArrayList也是可以根据需要调整容量(默认容量为10),不过两者的逻辑有所区别,Vector扩容时会提高1倍,而ArrayList则是增加50%。

LinkedList顾名思义是Java提供双向链表,所以它不需要上面两种那样调整容量,他也不是线程安全的。