习题集

来源:互联网 发布:淘宝担保交易流程 编辑:程序博客网 时间:2024/05/01 15:06

一、基础

1.LinkedList和ArrayList的区别?

(想象ArrayList是一个存放数据的数组,想象LinkedList是一个存放数据指针的数组)

LinkedList是Sequence List,实现双向队列Deque接口,内部有一个map,用来保存指向数据的指针。从中间删除和插入数据,只会引起前后两个指针的变化,效率较高。而查询的话,是依次从开始到结尾查的,如果队列太大,效率会很差。

ArrayList是RandomAccess List,实现随机访问RandomAccess接口。对于大容量的随机访问,效率较LinkedList高。而插入删除数据,会导致之后所有的数据的移位,效率较低。

LinkedList适用于插入删除操作,而ArrayList适合随机访问。LinkedList使用迭代器的遍历,效率较高,而ArrayList使用for循环遍历的效率较高

在我的工作中,ArrayList使用的更多,因为一般对队列的操作是遍历和队尾插入。


2.delete和truncate的区别

delete语句是dml数据库管理语句,删除的每一行记录都会放在事务中,执行后不提交,可以回滚(在hibernate中使用dml语句,你会发现如果不把sql放到事务中执行,sql是不会被提交的)。

truncate是ddl数据定义语句,只记录删除执行后立即提交(PostgreSQL和sql server除外,可以回滚)。不能跟where从句。有外键的表不能truncate,truncate不会触发触发器。有些数据库,truncate后重置表标识列的种子值(就是自增值)。truncate会释放表空间,降低高水线。


3.堆和栈的区别

栈是线程私有的,堆是线程共享的。所以不同线程的栈对堆的操作,会相互影响线程得到的堆的值。


4.打印语句时,printf格式化,%d和%05d的区别?

%05d表示,输出的int类型至少要占5个位,高位用0补足(右对齐);


5.数据结构

http://blog.csdn.net/u010947402/article/details/51878166

数据结构,数据存储的方式,又叫java集合框架(java collection framework),是一种容器对象。容器就是可以存放其他对象(数据或元素)的对象。

数据结构支持两种容器:集合(Collection)和图(Map)

集合分为规则集(Set)、线性表(List)、队列(Queue),

java集合框架的所有接口和类都在java.util包中,都实现了Collonable和Serializable接口,可复制可序列化

规则集的客座率,指这个集合的饱满程度。实际容量=容量*客座率。当袁术个数超过实际容量时,集合的容量就会翻倍。客座率默认0.75.

规则集Set=Collection+去重

链式散列集linkedHashSet=散列集HashSet+有序

树形集TreeSet=set+可比较Comparable

sortedSet接口提供lower、floor、celing、higher方法,分别表示小于、小于等于、大于大于、大于

List=Collection+有序

数组线性表ArrayList=List+数组存储元素

链式线性表LinkedList=List+数组存储元素的引用=List+deque

Vector=ArrayList+同步

stack是Vector的扩展,Enumeration接口被Iterator接口替代


队列Queue=Collection+插入+取出+检验

优先队列PriorityQueue=Queue+优先级


图分散列图HashMAp、链式散列图LinkedHashMap、树形图TreeMap

hashTable=hashMap+同步


集合和线性表的静态方法



6.算法

算法复杂度T(n),时间复杂度O(n)

时间复杂度为O(log n)的算法,称为对数算法(无底数)。其他还有,二次算法,指数算法、线性算法



二、多线程

1.Thread.start()与Thread.run()有什么区别?

start是native方法,由jvm(基于c++或其他的编程语言)实现多线程,并调用run方法(方法体)。直接调用run方法是无法实现多线程的。


2.ThreadLocal

ThreadLocal是用于保存当前线程变量的类,作用是线程间共享变量,实质上是一个用当前线程实例做key的map存储机制


3.在静态方法上使用同步时会发生什么事?

线程监视器会获取该静态方法所在类的锁,导致其他线程不能使用该类的任何静态方法。


4.Java中Runnable和Callable有什么不同?

Runnable从jdk1.1开始就有了,Callable从jdk1.5开始。

不同于Runnable的run(),接口方法为call();Callable有返回值


5. wait和await的区别

wait是native方法,使当前线程等待,是Object的方法,线程等待时持续持有锁 ,持有该锁的其他线程不能执行

await非native方法,是Condition的方法,一个锁lock可以对应多个Condition,为每个对象提供等待线程的集合(可以区分具体是哪个线程)


6.Java中CyclicBarrier 和 CountDownLatch有什么不同?

看过jdk api的话,就可以知道这两个类的方法并不多。

两者均为控制线程执行顺序的类,两者均要在构造函数中指定成员线程数。

CyclicBarrier 在await()的线程数getNumberWaiting()达到成员线程数的时候,自动让全部await()的线程全部继续执行,否则全部中断抛异常;

CountDownLatch 需要每次在await()前手动调用countDown()来为成员线程数getCount()减数,当count==0,全部线程继续执行。


public class Example {static CyclicBarrier cb = new CyclicBarrier(10, new Runnable() {@Overridepublic void run() {System.out.println("我是山腰");}});public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(10);for (int i = 0; i < 10; i++) {pool.execute(new Worker());}}static class Worker implements Runnable {@Overridepublic void run() {try {System.out.println("我是线程" + Thread.currentThread().getId() + ",我到达山腰了");cb.await();System.out.println("线程" + Thread.currentThread().getId() + "继续爬山");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}}}

输出:

我是线程10,我到达山腰了
我是线程14,我到达山腰了
我是线程12,我到达山腰了
我是线程13,我到达山腰了
我是线程16,我到达山腰了
我是线程11,我到达山腰了
我是线程17,我到达山腰了
我是线程15,我到达山腰了
我是线程18,我到达山腰了
我是线程19,我到达山腰了
我是山腰
线程19继续爬山
线程10继续爬山
线程13继续爬山
线程12继续爬山
线程14继续爬山
线程15继续爬山
线程17继续爬山
线程11继续爬山
线程16继续爬山
线程18继续爬山

注意:CyclicBarrier的成员线程数不能大于实际运行的线程数,否则线程会一直等待一个不存在的线程。


7.对象锁、类锁、方法锁?

方法锁和对象锁都是持有实例

方法锁:synchronized 修饰非静态方法

对象锁:synchronized 修饰非静态方法或代码块

synchronized 修饰静态方法或代码块


8.内存模型(原子性、可见性、一致性)

每个线程都有自己的一个工作内存,所有线程共享主内存。

线程每次执行,会先从主内存中拷贝数据到工作内存,执行完毕后再把数据回写到主内存。

volatile要求程序对变量的每次修改,都写回主内存,这样便对其它线程可见,解决了可见性的问题。


9.Executor.newFixedThreadPool(),Executor.newFixedThreadPool,Executor.newFixedThreadPool

newFixedThreadPool:创建一个固定大小的线程池,超过大小时,新创建的线程会在队列中等待,无界队列

newWorkStealingPool:创建一个于参数等级对应的足够大小的线程池,但不保证执行顺序

newSingleThreadExecutor:创建单个线程,无界队列,线程封闭

newCachedThreadPool:创建一个随需求增加大小的线程池


10.竞态条件、线程安全

多个线程共享同一个内存,线程间竞争共享资源,线程按不确定的顺序执行,会导致不确定的结果。


11.ArrayBlockingQueue和LinkedBlockingQueue的区别

ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和消费用的是同一个锁,生产和消费不能同时进行;

LinkedBlockingQueue实现的队列中的锁是分离的,即生产用的是putLock,消费是takeLock

ArrayBlockingQueue实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的;
LinkedBlockingQueue实现的队列中在生产和消费的时候,需要把枚举对象转换为Node<E>进行插入或移除,会影响性能

ArrayBlockingQueue效率更高,


0 0
原创粉丝点击