Java后端各种小知识点


1、ArrayList和LinkedList的比较

ArrayList实现了List接口,它是以数组的方式来实现的,数组的特性是可以使用索引的方式来快速定位对象的位置,因此对于快速的随机取得对象的需求,使用ArrayList实现执行效率上会比较好. 
LinkedList是采用链表的方式来实现List接口的,它本身有自己特定的方法,如: addFirst(),addLast(),getFirst(),removeFirst()等. 由于是采用链表实现的,因此在进行insert和remove动作时在效率上要比ArrayList要好得多!适合用来实现Stack(堆栈)与Queue(队列),前者先进后出,后者是先进先出.


在删除可插入对象的动作时,为什么ArrayList的效率会比较低呢?

解析: 因为ArrayList是使用数组实现的,若要从数组中删除或插入某一个对象,需要移动后段的数组元素,从而会重新调整索引顺序,调整索引顺序会消耗一定的时间,所以速度上就会比LinkedList要慢许多. 相反,LinkedList是使用链表实现的,若要从链表中删除或插入某一个对象,只需要改变前后对象的引用即可!


2、String 、String Buffer、String Builder的区别

这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。

(1)首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String

  String最慢的原因:

  String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

String str="abc"+"de"和String str="abcde"是等效的,如果分行写的话就会出现垃圾回收,降低速度。

(2)在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的,因为它加了一些锁。

(3)总结一下

  String:适用于少量的字符串操作的情况

  StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

  StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

3、Singleton和prototype的区别

默 认情况下,从bean工厂所取得的实例为Singleton(bean的singleton属性) 

Singleton: Spring容器只存在一个共享的bean实例,默认的配置。 那么Spring IoC容器中只会存在一个共享的bean实,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。

Prototype: 每次对bean的请求都会创建一个新的bean实例(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法--只有getbean才会在容器中生成一个bean)

二者选择的原则:有状态的bean都使用Prototype作用域,而对无状态的bean则应该使用 singleton作用域。

spring Bean的作用域:

scope=singleton(默认,单例,生成一个实例) 不是线程安全,性能高

scope=prototype(多线程, 生成多个实例)

4、有状态对象和无状态对象

有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。其实就是有数据成员的对象。

无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象。不能保存数据,是不变类,是线程安全的。具体来说就是只有方法没有数据成员的对象,或者有数据成员但是数据成员是可读的对象。

/**
 * 有状态bean,有state,user等属性,并且user有存偖功能,是可变的。
 */
public class StatefulBean {

    public int state;
    // 由于多线程环境下,user是引用对象,是非线程安全的
    public User user;

/**
 * 无状态bean,不能存偖数据。因为没有任何属性,所以是不可变的。只有一系统的方法操作。
 */
public class StatelessBeanService {

    // 虽然有billDao属性,但billDao是没有状态信息的,是Stateless Bean.
    BillDao billDao;

5、列出集中JDK并发容器

Collection.synchronizedMap();

Collection.synchronizedList();

CopyOnWriteArrayList:提供高效地读取操作,使用在读多写少的场景。CopyOnWriteArrayList读取操作不用加锁,且是安全的;写操作时,先copy一份原有数据数组,再对复制数据进行写入操作,最后将复制数据替换原有数据,从而保证写操作不影响读操作。

ConcurrentLinkedQueue:使用链表作为数据结构,它采用无锁操作,可以认为是高并发环境下性能最好的队列。

ConcurrentSkipListMap:SkipList(跳表)是一种随机性的数据结构,用于替代红黑树,因为它在高并发的情况下,性能优于红黑树。跳表实际上是以空间换取时间。ConcurrentSkipListMap的实现就是实现了一个无锁版的跳表,主要是利用无锁的链表的实现来管理跳表底层,同样利用CAS来完成替换。

ConcurrentHashMap:实现了HashTable的所有功能,线程安全,但却在检索元素时不需要锁定,因此效率更高。

6、ConcurrentHashMap和Hashtable的区别

它们都可以用于多线程的环境,但是当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。因为ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,而其它的线程不需要等到迭代完成才能访问map。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。



猜你喜欢

转载自blog.csdn.net/sinat_27143551/article/details/80214461
今日推荐