1. Spring的xml,注解和Java Config的区别
xml配置相对于其他两种方式来说,几乎没有什么优势,唯一的优势就是修改后不需要重新编译,因此对于一些经常切换实现类的对象,可以采用xml的方法进行配置。还有就是由于xml是Spring一开始提供的配置方式,因此许多旧代码还是采用xml,所以在维护旧代码时会免不了用到xml。
注解用起来非常地简洁,代码量十分少,因此是项目的第一选择。只有当需要注入代码不是自己维护的第三包jar包中的类时,或者需要更为灵活地注入,比如说需要调用某个接口时,查询数据,然后把这个数据赋值给要注入的对象,那么这时候就需要用到Java Config。
2. 什么是悲观锁和乐观锁?
乐观锁对应生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好与另一种人。
悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其他线程阻塞,用完后再把资源转让给其他线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新操作的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供类似于write-condition机制,其实都是提供乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现CAS算法实现的。
3. 线程的几种状态以及转换
线程在一定条件下,状态会发生改变。线程一共有以下几种状态:
1. 新建状态(new):新建一个线程对象。
2. 就绪状态(runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于"可运行线程池中",变得可运行,只等待获取CPU的使用权。即在就绪状态的进程出CPU之外,其他的运行所需资源都已全部获得。
3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码
4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃使用CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
阻塞的情况分为三种:
(1),等待阻塞:运行的线程执行wait()方法,该线程会释放锁占用的所有资源,JVM会把线程放入“等待池”中。进入这个状态是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能唤醒
(2),同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。
(3),其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把线程设置为阻塞状态。当sleep()状态超时,join()等待线程终止或者超时,或者I/O处理完毕时,线程重写进入就绪状态。
注:拿到对象的锁标记,即为获得了对该对象(临界区)的使用权限。即该线程获得了运行所需的资源,进入“就绪状态”,只需获得CPU,就可以运行。因为当调用wait()后,线程会释放掉它所占有的“锁标志”,所以线程只有在此获取资源才能进入就绪状态。
4. 非关系型数据库和关系型数据库有什么区别?
1. 关系型数据库通过外键关联建立表与表之间的关系,
2. 非关系型数据库提供指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定的。
非关系型数据库中,我们查询一条数据,结果出来一个数组,关系型数据库中,查询一条数据结构是一个对象。
注1:数据库事务必须具有ACID特性,ACID是Atomic原子性,Consistency一致性,Isolation隔离性,Durablility持久性
注2.:数据的持久存储,尤其是海量数据的持久存储,还需要一种关系数据库。