Java复习

一、COllections.sort内部原理

Collection.sort()排序通过泛化实现对所有类型的排序,对于基础类型如int,string,按照字符表,数字大小排序。对于自定义类型,通过实现Comparable接口,重写comparableTo()方法自定义比较大小的方式。也可以使用Comparator外比较器,Comparable接口的方式比实现Comparator接口的耦合性要强一些。

Collection.sort内部调用的是Arrays.sort方法,对于Arrays类,有两个sort方法,sort(Object)和sort(int),前者使用归并排序,后者使用快排。

import java.util.*;
class xd{
    int a;
    int b;
    xd(int a,int b){
        this.a=a;
        this.b=b;
    }
}
public class Main(){
    public static void main(String[] args){
        xd a=new xd(2,3);
        xd b=new xd(4,1);
        xd c=new xd(1,2);
        ArrayList<xd> list=new ArrayList<>();
        array.add(a);
        array.add(b);
        array.add(c);
        Collections.sort(array,new Comparator<xd>(){
            @Override
            public int compare(xd o1,xd o2){
                if(o1.a>o2.a)
                    return 1;
                else if(o1.a<o2.a)
                    return -1;
                return 0;
            }
        });
        for(int i=0;i<array.size();i++)
            System.out.println(array.get(i).a);
        for(int i=0;i<array.size();i++)
            System.out.println(array.get(i).b);
    }
}

二、TreeMap和TreeSet

TreeMap和TreeSet都是Java Collection Framework的两个重要成员,其中TreeMap实现了Map接口,TreeSet实现了set接口。TreeSet底层是通过TreeMap来实现的。二者的实现方式完全一样,而TreeMap的实现就是红黑树算法。

  • TreeMap和TreeSet都是有序的集合,它们存储的值都是排好序的
  • TreeMap和TreeSet都是非同步的集合,他们不能再多线程之间共享,不过可以使用Collections.synchronizedMap()来实现同步
  • 运行速度都比Hash集合慢,时间复杂度为O(logN)。而HashMap/HashSet则为O(1)。
  • TreeSet实现了Set接口而TreeMap实现了Map接口。
  • TreeSet只存储一个对象,而TreeMap存储两个对象key和Value。
  • TreeSet中不能有重复对象,而TreeMap可以有重复对象。

三、集合和有序集合有什么区别?

有序集合里的元素可以根据key或index访问,有序集合在属性的增加、删除、修改中拥有较好的性能。

无序集合里的元素只能遍历。

  • 无序集:set
  • 有序集:List

凡是实现set的AbstractSet、CopyOnWriteArraySet、EnumSet、HashSet、LinkedHashSet、TreeSet都是无序的

凡是实现List的AbstractList、ArrayList、LinkedList、Stack、Vector都是有序的

  • Map:Map可以根据key来访问,从这个角度将,Map也是有序的 

四、Set是无序的,怎么保证有序

Set是无序的,但是TreeSet可以保证有序。

五、Java集合框架

Java集合大致可以分为Set、List、Queue和Map四种体系。其中Set代表无序,不可重复的集合。List代表有序,可以重复的集合。Map代表映射关系的集合。Java5又增加了Queue体系,代表一种队列集合实现。

 Java集合和数组的区别:

数组元素在初始化时指定,意味着只能保存定长的数据。而集合可以保存数量不确定的数据。数组元素既可以保存基本类型的值,也可以是对象。集合里只能保存对象。基本数据类型要转换成对应的包装类才能放入集合类中。

Java集合类之间的继承关系:Java的集合类主要由两个接口派生而出:Collection和Map。

Map实现类用于保存具有映射关系的数据。Map保存的每项数据都是key-value对,也就是由key和value两个值组成。

六、Iterator和ListIterator的区别是什么

Iterator可以用来遍历Set和List集合,但是ListIterator只能遍历List。Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。

七、快速失败和安全失败的区别是什么

Iterator的安全失败是基于对底层集合做拷贝,它不受源集合上修改的影响。Java.concurrent包下面的所有类都是安全失败的。而快速失败受到源集合修改的影响,Java.util包下面的所有集合类都是快速失败的。快速失败的迭代器会抛出ConcurrentModificationException异常,而安全失败的迭代器不会抛出此异常。

八、Java哪些类是线程安全的

Vector:比ArrayList多了个同步机制(Synchronized)

HashTable:HashMap的线程安全版本

Stack:Stack也是线程安全的,继承与Vector

九、Volatile和synchronized区别

  • 加锁机制既可以保证可见性又可以保证原子性,而volatile只能确保可见性,不能保证原子性
  • volatile不会进行加锁操作。volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作。也就不会使线程阻塞,因此volatile是一种比Synchronized更轻量级的同步机制。
  • volatile不如synchronized安全。

十、Volatile

volatile关键字保证了内存可见性,防止指令重排序。volatile并不保证原子性。

  • volatile保证内存可见性的原理是每次访问变量时都会进行一次刷新,因此每次访问都是主内存中最新的版本。所以volatile关键字的作用之一就是保证变量修改的实时可见性。
  • 由于volatile屏蔽掉了JVM中必要的代码优化,所以在效率上比较低。

十一、Java编写一个会导致死锁的程序

public static void main(String[] args){
    final Object a=new Object();
    final Object b=new Object();
    Thread threadA=new Thread(new Runnable(){
        @Override
        public void run(){
            synchronized(a){
                try{
                    Thread.sleep(5000);
                    synchronized(b){
                        Thread.sleep(1000);
                        System.out.println("锁住b");
                    }
                 }
                catch(Exception e){
                     e.printStackTrace();
                }
            }
        });


    Thread threadB=new Thread(new Runnable(){
        @Override
        public void run(){
            synchronized(b){
                try{
                   Thread.sleep(5000);
                   Synchroninzed(a){
                        Thread.sleep(1000);
                        System.out.println(“锁住A”);
                }catch(Exception e){
                  e.printStackTrace();
                    }
            });

     ThreadA.start();
     ThreadB.start();
}

十二、自旋锁、偏向锁、轻量级锁、重量级锁

阻塞操作会导致在用户态和内核态之间切换,严重影响性能。在很多场景下,同步资源的锁定时间很短,为了这一小段时间去切换线程可能会偿失,可以让线程“稍微等待一会”,这就是自旋锁。

无锁、偏向锁、轻量级锁、重量级锁都是针对synchronized的。synchronized是悲观锁,在操作同步资源之前需要给同步资源加锁,这把锁就存在Java对象头里面。

一个线程访问:在大多数情况下,锁总是由一个线程获得,不存在多线程竞争,所以出现了偏向锁。其目标就是在只有一个线程执行同步代码块的情况下能够提高性能

轻量级锁:两个线程交替访问,锁升级,升级为轻量级锁。

重量级锁:多个线程访问,竞争激烈,升级了重量级锁。

十三、

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值