核心类库

1.数组(Array) 和列表(ArrayList) 有什么区别?

Array:它是数组,申明数组的时候就要初始化并确定长度,长度不可变,而且它只能存储同一类型的数据,比如申明为String类型的数组,那么它只能存储S听类型数据。
ArrayList:它是一个集合,需要先申明,然后再添加数据,长度是根据内容的多少而改变的,ArrayList可以存放不同类型的数据,在存储基本类型数据的时候要使用基本数据类型的包装类当能确定长度并且数据类型一致的时候就可以用数组,其他时候使用ArrayList。

2.ArrayList 和 Vector 的区别

ArrayList与Vector的区别主要包括两个方面:.

(1)同步性:

​ Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它 的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程 安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编 写线程安全的代码。

(2)数据增长:

​ ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需 要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存 储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原 来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。 ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提 供设置增长空间的方法。

总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。

3.HashMap,TreeMap,HashTable 的区别?

​ HashMap、HashTable和TreeMap都是map接口的子类,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。这就是我们平时说的键值对。put时有相同的key,会覆盖该key对应的值。

​ HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。

​ HashMap 非线程安全 HashTable 线程安全 TreeMap 非线程安全。

4.HashMap 的工作原理是什么?

Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合/从集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)。

1.hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
2.hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
3.hashMap允许空键值,而hashTable不允许

5.什么是序列化,如何实现序列化?

​ 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化(将对象转换成二进制)。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间,序列化是为了解决在对对象流进行读写操作时所引发的问题。把对象转换为字节序列的过程称为对象的序列化把字节序列恢复为对象的过程称为对象的反序列化

​ 序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implementsSerializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

6.进程和线程有什么区别?

进程

​ 是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间

线程

​ 是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行. 一个进程最少有一个线程

​ 线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分成若干个线程

7.java 当中如何实现线程呢?

​ 实现Runnable和继承Thread

分时调度

​ 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。

抢占式调度

​ 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为

抢占式调度

​ CPU使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核新而言,某个时刻,只能执行一个线程,而 CPU的在多个线程间切换速度相对我们的感觉要快,看上去就是 在同一时刻运行。 其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的 使用率更高。

8.说说线程的生命周期

  • New(初始化状态)
  • Runnable(就绪状态)
  • Running(运行状态)
  • Blocked(阻塞状态)
  • Terminated(终止状态)

9.多线程并发或线程安全问题如何解决?

1:通过volatile 关键字修饰变量,可以实现线程之间的可见性,避免变量脏读的出现,底层是通过限制jvm指令的重排序来实现的适用于一个线程修改,多个线程读的场景
2:通过synchronized锁(任意对象)来实现线程同步,自动锁的思想,底层实现原理:当有线程进入同步代码块之后,利用jvm的计数器将锁的标记置为1,当别的线程再想进入的时候,发现锁的标记为1,该线程就去锁池等待,当第一个线程出来之后,锁的标记会置为0,之后cpu会随机分配一个线程再次进入同步代码块.
3:通过lock锁的机制,进行手动lock,和unlock,但是这种很容易出现死锁。注意加锁以及解锁的顺序,就可以避免死锁

4:通过线程安全的集合类,可以解决并发问题4
ConcurrentHashMap
CopyonWriteArrayList
5:使用并发包下面的原子类,底层使用的是cas机制(乐观锁),可以解决并发问题 atomicInteger 线程安全的原子整型类
6:使用线程池来创建和管理线程,也可以一定程度上解决并发问题
7:使用ThreadLocal来修饰变量,可以解决并发问题ThreadLocal底层是怎么实现的?多个线程会复制一份threadLocao变量的副本进行操作,互不影响,来保证线程安全的

10.synchronized 和 ReentrantLock 的区别

相似点:

这两种同步方式有很多相似之处,它们都是加锁方式同步,而且都是阻塞式的同步,也就是说当如果一个线程获得了对象锁,进入了同步块,其他访问该同步块的线程都必须阻塞在同步块外面等待,而进行线程阻塞和唤醒的代价是比较高的(操作系统需要在用户态与内核态之间来回切换,代价很高,不过可以通过对锁优化进行改善)。

区别:

​ 这两种方式最大区别就是对于Synchronized来说,它是java语言的关键字,是原生语法层面的互斥,需要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值