集合与多线程面试

 集合

Java中集合和数组的区别?

一、集合和数组的区别
区别1:
数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值。

集合只能存储引用数据类型(对象)。集合也能存储基本数据类型(有点矛盾,看后句),但是在存储的时候会自动装箱变成对象。

区别2:
数组长度是固定的,不能自动增长。

集合的长度是可变的,可以根据元素的增长而增长。

二、集合和数组什么时候用
 1、如果元素个数是固定的推荐用数组,效率高。

 2、如果元素个数不是固定的推荐用集合

三、集合和数组什么时候用的原因
  部分集合内部是用数组实现(当然还有是哈希,二叉树等),当每次创建一个集合对象是,默认创建10个长度的数组。当添加到第11个时,它会按照原数组1.5倍创建,在把原来的数组值复制过去,原来10长度的数组将变成垃圾被回收。当添加到16或者更多,以后都是按照原数组1.5倍创建,复制这个过程。所以,当固定长度为100的时候,你选择了集合就是低效率,选择数组就是高效率,因为集合里面有很多创建,复制,销毁过程。

集合类了解吗?知道哪些集合?说说他们的继承关系

参考:https://www.cnblogs.com/youngao/p/12518875.html

数组和链表的区别,读写这块链表和数组的区别

内存:数组连续,链表不一定;数组随机访问效率高,链表插入效率高,数组插入会进行复制。

hash扩容,给定一个长度为1000的hashmap,存放900个元素会不会扩容、750个呢?

与负载因子有关,默认为0.75,参考:https://www.cnblogs.com/youngao/p/12518967.html

ArrayList底层怎么实现,怎么扩容,复制的话有更好的方法吗,ArrayList去除重复元素? 

底层:动态数组;扩容:左移,1.5倍;后面两个问题的解决思路还不清楚

ArrayList 相应的线程安全容器,两者底层区别

线程安全:Vector;区别:参考两者底层源码分析

ArrayList和LinkedList的区别,底层分别是怎么实现的

一个是基于动态数组实现的,一个是基于链表实现的。动态数组随机索引的特点,读和改快,增删慢,链表增删快,读慢。

Java对有序的ArrayList查找是否会优化?

否,参考:https://www.cnblogs.com/youngao/p/12517410.html 2.4 遍历部分

hash算法知道吗?介绍一下你知道的hash算法,hash冲突知道吗?
怎么解决hash冲突呢,讲一下开放地址法、怎么确定开放地址的位置

参考:https://www.cnblogs.com/youngao/p/12599603.html 2 hash冲突

HashMap的底层数据结构及作用,为什么线程不安全并举例,如何改进能让线程安全?

数组+链表+红黑树;

1、put的时候导致的多线程数据不一致。
这个问题比较好想象,比如有两个线程A和B,首先A希望插入一个key-value对到HashMap中,首先计算记录所要落到的桶的索引坐标,然后获取到该桶里面的链表头结点,此时线程A的时间片用完了,而此时线程B被调度得以执行,和线程A一样执行,只不过线程B成功将记录插到了桶里面,假设线程A插入的记录计算出来的桶索引和线程B要插入的记录计算出来的桶索引是一样的,那么当线程B成功插入之后,线程A再次被调度运行时,它依然持有过期的链表头但是它对此一无所知,以至于它认为它应该这样做,如此一来就覆盖了线程B插入的记录,这样线程B插入的记录就凭空消失了,造成了数据不一致的行为。

2、另外一个比较明显的线程不安全的问题是HashMap的get操作可能因为resize而引起死循环(cpu100%),具体分析如下:

下面的代码是resize的核心内容:

void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> next = e.next; if (rehash) { e.hash = null == e.key ? 0 : hash(e.key); } int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } } } 

这个方法的功能是将原来的记录重新计算在新桶的位置,然后迁移过去。

 
多线程HashMap的resize

我们假设有两个线程同时需要执行resize操作,我们原来的桶数量为2,记录数为3,需要resize桶到4,原来的记录分别为:[3,A],[7,B],[5,C],在原来的map里面,我们发现这三个entry都落到了第二个桶里面。
假设线程thread1执行到了transfer方法的Entry next = e.next这一句,然后时间片用完了,此时的e = [3,A], next = [7,B]。线程thread2被调度执行并且顺利完成了resize操作,需要注意的是,此时的[7,B]的next为[3,A]。此时线程thread1重新被调度运行,此时的thread1持有的引用是已经被thread2 resize之后的结果。线程thread1首先将[3,A]迁移到新的数组上,然后再处理[7,B],而[7,B]被链接到了[3,A]的后面,处理完[7,B]之后,就需要处理[7,B]的next了啊,而通过thread2的resize之后,[7,B]的next变为了[3,A],此时,[3,A]和[7,B]形成了环形链表,在get的时候,如果get的key的桶索引和[3,A]和[7,B]一样,那么就会陷入死循环。

如果在取链表的时候从头开始取(现在是从尾部开始取)的话,则可以保证节点之间的顺序,那样就不存在这样的问题了。

综合上面两点,可以说明HashMap是线程不安全的。

ConcurrentHashMap,怎么保证线程安全,JDK1.7 和 JDK1.8的区别

 

1. HashMap了解吗,说一下

这里就不详细说了,大致思路是jdk7和jdk8的实现原理及区别(重点有实现的数据结构,存储单元从Entry到Node的转变,加载因子,什么时候扩容,jdk1.8扩容的具体实现方式等等),HashMap和HashTable的区别,HahsMap和HashSet的关系。要结合源码说。

 

 实现HashMap 【不考虑红黑树】

 HashMap和TreeMap区别

4.hashmap在1.8引入了红黑树,那为什么要引入红黑树?

5.你能说说concurrenthashmap和hashmap的put过程吗?

6.红黑树你能介绍下吗?它的左旋右旋是怎么样的?为什么要左旋右旋呢?红黑树便于查找元素吗?

HashTable和HashMap的区别,有没有更高效的线程安全HashMap

hashmap线程不安全的原因是啥,结合1.7和1.8说说?你觉得1.7当中的那个死循环是导致它不安全的原因嘛?

List、Set、Map的区别、Map底层原理、Set的底层原理、TreeMap的底层结构?

 

 

2.说了我自己的研究方向,面试官感觉不太了解,就没问,说你觉得你有啥擅长的地方?我。。。我觉得我基础还不错。。。哈哈干笑两声缓解尴尬,面试官:那你了解数组吗?
确实挺基础,回答了数组之后面试官让我写个可变数组的add方法
3.你写的add安全吗,不安全,什么办法让他安全,volatile关键词的作用和原理,还知道什么安全的类
4.知道环形数组吗?写个环形数组。(此处我墨迹了半天因为脑子里全是循环队列,给他整了一个循环数组rear  head判断了半天)。面试官看不下去了说你讲个思路吧,我看你这还有个rear是干啥的?我说头尾指针啊,他说为啥需要这个,我说因为前面的元素如果被取出来那就会空出来了啊,面试官说为啥前面的元素会被取出来,你给我整个不取出来的,我恍然大悟原来不要循环队列啊。。。。(菜鸡落泪,脑子真的不好使)

 

 

hashmap了解吗?hashmap还能怎么优化?

15.

3.hashmap扩容的时候,链表尾部的节点怎么处理的?(答重新计算一下位置,因为长度是2的整数次幂,要么在原位置,要么在原位置+oldLength的位置)
4.重新计算位置?确定吗?(这个真不知道啊……想了一下,答是)

 

ConcurrentHashMap的原理,为什么是线程安全的,让你设计怎么实现读写安全

 

问了HashMap,为啥选用HashMap而不选用TreeMap,(回到效率相关的问题)时间复杂度是多少。HashMap(o(1)),TreeMap(O(logn))

  •  

hashmap的put操作concurrentHashMap的put操作,读操作会加锁么?

 

 

作者:废纸
链接:https://www.nowcoder.com/discuss/394497
来源:牛客网

进程线程的区别,线程状态转换,乐观锁和悲观锁,线程池参数含义,cpu密集型任务用什么线程池

线程池的参数有哪些,线程池满了咋办 

 

 

sleep和wait的区别,sleep和wait在调用的时候会不会出让CPU的时间片

35.线程和进程的区别
36.哪个共享,哪个私有,共享的哪些资源?
37.threadlocal的原理
我很惊讶,他就问到这里了,我还准备了一大堆锁准备说呢

2. 锁,死锁的形成条件,锁的底层实现,AQS的实现,如何实现公平锁和非公平锁,CAS的实现;
3. 线程池的实现,工具类封装的四种线程池;

synchronized和reentrantLock的区别

13、synchronized和reentrantLock性能比较

14、synchronized锁膨胀过程

15、AQS框架

进程和线程的区别

8、介绍下java并发体系

9、countdownlatch的使用

10、countdownlatch的底层

11、讲一下AQS

线程进程区别

线程池了解吗

在一个线程fork会怎么样

进程间通信,线程间通信,怎么同步

了解哪些锁,讲了synchronized锁,自旋锁,自适应自旋锁,它是悲观锁还是乐观锁

进程和线程的信号量什么区别

生产者消费者模式怎么回事

死锁造成的原因,银行家算法

 

 

介绍Java锁(我一开始往乐观锁那边说了,面试官应该更想听我将Synchronized那些的)

15、乐观锁底层实现,我说了cas,然后把aba问题,自旋锁消耗问题和解决方法说一遍

HashMap的负载因子,以及如何调节

线程 sleep和wait的区别,守护线程,线程池的参数

18、ConcurrentHashMap1.7、1.8区别,put实现有什么不同?1.7当中的segement怎么实现的?



9. 讲讲Executor提供了哪些线程池,区别


线程实现方式,线程池,最大线程数,核心线程数,有那些拒绝策略,默认和分别是哪些。
5、有哪些锁,自旋锁、轻量级锁、重量级锁等,说说乐观锁悲观锁是什么,怎么实现,volatile关键字,CAS,AQS原理及实现。

ava并发中会遇到那些问题,fork/join,线程实现,有那些多线程,核心线程数,最大线程数,拒绝策略等,线程执行过程

进程和线程的区别?

 ThreadPoolExcutor的源码看过吗?
    没有特别仔细的看,但是他的原理是巴拉巴拉


10、死锁是什么?怎么实现死锁?

    • ashmap是否线程安全,有什么安全的hashmap?:不安全,因为在多线程同时put时或者在扩容时Put都会有线程安全问题。安全可以使用hashtable、Collections.synchronizedMap、ConcurrentHashMap这三类。但前两类都是直接在方法标签上加了synchronized,所以效率很低。而ConcurrentHashMap效率很好,在1.7中,ConcurrentHashMap是用segment数组为每个格子加锁来保证安全性。在1.8中ConcurrentHashMap和hashmap的结构完全一样,但更改了put方法。在计算了哈希值和索引后,先判断索引位置是否正在扩容,如果正在扩容就调用一个协助扩容的函数,如果没扩容再判断是否为空,为空则用CAS的方式放入,不为空则用synchronized锁住格子,判断为链表还是红黑树,分别调用对应方式放入。最后再判断一次冲突长度,大于8则转化为红黑树。
    • volatile作用:保证可见性和顺序性。Java把处理器的多级缓存抽象为JMM,即线程私有的工作内存和线程公有的主内存,每个线程从主内存拷贝所需数据到自己的工作内存。volatile的作用就是当线程修改被volatile修饰的变量时,要立即写入到主内存,当线程读取被volatile修饰的变量时,要立即到主内存中去读取,保证了可见性。禁止指令重排来保证顺序性。



    • synchronize和lock的区别,lock接口比synchronize多的3个特性:公平锁、多条件、限时等待的作用和场合,都是可重入锁,可重入锁的原理,为什么默认是非公平锁。
    • AQS和CAS的原理最好能会

 

5、volatile的底层原理

6、线程池各个参数 拒绝策略有哪些 (我只知道一个抛出异常操作了),然后回答了SingleThreadPool FiexedThreadExteaor CacgeThreadpool

 

synchronized和lock的区别

进程&线程概念与区别

说说java线程池的工作流程?

 

、你了解的线程安全是什么,为什么出现,怎么避免,怎么性能更好的避免



死锁是怎么产生的,怎么避免?请求和保持怎么去打破(说了超时和一次性分配),那一次性分配就能全部获得吗,一个线程一次性要AB,另一个线程也要一次性AB,那分给谁?(等一个用完释放呀),一个线程占有A请求B,一个线程占有B请求A,是因为加锁顺序不对导致的,那按什么顺序加锁?(被问懵了,面试官也很绝望,说“都已经说到这个地步了还是想不出来吗,很简单的,就是对锁加个序号呗”)

 

 

守护线程
线程 sleep和wait的区别,sleep的时候CPU在干啥
Volatile的作用,底层实现

 

 

 

多线程

什么是线程不安全

ThreadLocal 原理

线程池原理(参数、执行过程、拒绝策略)

写了一个BlockingQueue的生产者和消费者模型 (put和take我写出push和pull了)

 1.进程与线程的区别
2.进程之间的通讯方式
3.sleep为什么是静态的
4.什么情况下会产生死锁(面试官不知道哪的人,发音不标准,我一直听子锁子锁,这是个what??,最后才听明白,0-8梦幻开局…)
5.怎么分析你的程序产生了死锁?
6.怎么确定是什么原因导致的死锁?
6.现在已经确定程序产生了死锁,有什么工具可以直接去分析的?
7.Java的Timer类是用来干嘛的,是如何使用的(我说没用过,但是线程池创建里有一个参数)
8.好,你说到线程池,Java里是怎么创建一个线程池的

讲一下同步队列(貌似要我讲ArrayBlockingQueue,我凑合答了AQS原理)

synchronized和lock的原理

如果我想做线程安全的话,可以有哪些实现方式?

Synchronized加在不同的位置会有不同的效果能说一下吗?什么时候加在方法,什么时候加在语句块上?

有十个线程,现在有五个线程要进来,怎么做到这个约束?

  1. 异步并发多线程相关
  2. CountdownLatch有没有用过

 为什么ReentrantLock是可重入的

 

说一说java中的锁。jdk新特性中关于锁的部分?lock是可重录锁吗?是自旋锁吗?悲观锁/乐观锁?

 知道多线程,多进程吗?介绍一下怎样创建多线程,多进程?请问与java的区别是?

 

 

  1. 开发过程中有用到过线程吗

  2. 说下线程池和普通线程的区别

  3. 简单说下Activity的声明周期

  4. 了解过哪个声明周期内不适合做耗时操作吗

  5. 用过哪些数据存储方式

 

进程和线程的区别(我说的有点简单,面试官不太满意,追问我还有吗)

操作系统当中的死锁怎么发生的,什么是死锁?

怎么解决死锁

内存里的堆和栈有什么区别?

 

Java当中的线程安全怎么理解?

怎么保证线程安全?

Java里面的线程有哪几种状态?

 

线程池的原理,线程池的状态,线程池的使用有什么不好的地方?这部分面试官是想跟协程比较来着

说一说你知道的java的数据结构。说一说hashMap的底层。它是线程安全的吗?你还知道哪些Map呢?
4.说一说java中的锁。jdk新特性中关于锁的部分?lock是可重录锁吗?是自旋锁吗?悲观锁/乐观锁?
  1. AQS原理
  2. 公平锁和非公平锁的区别
  3. sync的实现,jdk1.6后的优化
  4. 一个拥有的锁的线程是什么状态的

进程和线程的区别,联系

多线程编程,死锁检测与预防,死锁的检测手段,怎样避免死锁

讲一讲线程池,讲讲为什么很多公司对于线程池的使用非常谨慎

 平时使用多线程有哪些需要注意的地方,参数怎么设定

多线程肯定涉及到锁,synchornized,Lock的区别讲一下

 

线程的状态以及状态变化过程

1.聊聊sychronized关键字,用法,底层实现,偏向锁,轻量级锁,自旋锁
2.聊聊偏向锁,轻量级锁的原理和过程
3.除了sychronized,还有啥,聊聊ReentrantLock,底层一个继承了AQS的实现类
4.聊聊AQS,volatile修饰的state,加锁过程,公平锁和非公平锁的实现

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值