java面试题3

1. JVM中内存结构模型

JVM的内存结构大概分为:

堆(Heap):线程共享。所有的对象实例以及数组都要在堆上分配。回收器主要管理的对象。

方法区(Method Area):线程共享。存储类信息、常量、静态变量、即时编译器编译后的代码。

方法栈(JVM Stack):线程私有。存储局部变量表、操作栈、动态链接、方法出口,对象指针。

本地方法栈(Native Method Stack):线程私有。为虚拟机使用到的Native 方法服务。如Java使用c或者c++编写的接口服务时,代码在此区运行。

程序计数器(Program Counter Register):线程私有。有些文章也翻译成PC寄存器(PC Register),同一个东西。它可以看作是当前线程所执行的字节码的行号指示器。指向下一条要执行的指令。

2. Java中多线程在哪些项目中用到了

3. 活锁死锁问题分析,什么是活锁,什么是死锁.出现的原因是什么?如何避免?

活锁指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试—失败—尝试—失败的过程。处于活锁的实体是在不断的改变状态,活锁有可能自行解开。

解决协同活锁的一种方案是调整重试机制。比如引入一些随机性。例如如果检测到冲突,那么就暂停随机的一定时间进行重试。这回大大减少碰撞的可能性。 典型的例子是以太网的CSMA/CD检测机制。

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

死锁的发生必须具备以下四个必要条件

1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

产生原因:竞争资源引起进程死锁

当系统中供多个进程共享的资源,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁。

解决方法:

在系统中已经出现死锁后,应该及时检测到死锁的发生,并采取适当的措施来解除死锁。

死锁预防。

这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。

死锁避免。

系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源;如果分配后系统可能发生死锁,则不予分配,否则予以分配。这是一种保证系统不进入死锁状态的动态策略。

死锁检测和解除。

先检测:这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源。检测方法包括定时检测、效率低时检测、进程等待时检测等。

然后解除死锁:采取适当措施,从系统中将已发生的死锁清除掉。

这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。

4. 多线程下如何做到数据共享?(可扩展数据共享的使用场景)

java中线程的两种实现方式,一种是Thread类,一种实现runable接口,实现runable接口可以实现数据共享

使用thread类在操作多线程时无法达到资源共享的目的,而使用runable接口实现多线程操作可以实现资源共享

5. 多线程下如何保证线程安全?(可扩展两种锁)

美团技术团队: 不可不说的Java“锁”事 - 美团技术团队

6. HashMap的底层详细介绍?(1.7和1.8前后区别)

HashMap的实现原理:

1.HashMap的结构是数组+链表 或者 数组+红黑树 的形式

2.HashMap底层的Entry[ ]数组,初始容量为16,加载因子是0.75f,扩容按约为2倍扩容

3.当存放数据时,会根据hash(key)%n算法来计算数据的存放位置,n就是数组的长度,其实也就是集合的容量

4.当计算到的位置之前没有存过数据的时候,会直接存放数据

5.当计算的位置,有数据时,会发生hash冲突/hash碰撞

6.解决的办法就是采用链表的结构,在数组中指定位置处以后元素之后插入新的元素

7.也就是说数组中的元素都是最早加入的节点

8.如果链表的长度>8时,链表会转为红黑树,当链表的长度<6时,会重新恢复成链表

在JDK1.6,JDK1.7中,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个链表的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

7. ArrayList和LinkList的区别?(使用场景和特性分析)

相同点: ArrayList和LinkList分别实现了List接口,元素都有下标,数据有序,允许存放重复元素

不同点:

ArrayList底层通过数组,数组扩容实现,默认构造方法新建一个空数组,调用add方法添加数据时扩容为10,空间不足时以1.5倍扩容.扩容时需申请新的连续空间,把旧数组复制过去,添加新的数据,回收旧数组.

LinkList底层是链表结构,不需要连续的空间,大小不固定

因为ArrayList是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的,可以直接返回数组中index位置的元素,因此在随机访问集合元素上有较好的性能。但是要插入、删除数据却是开销很大的,因为这需要移动数组中插入位置之后的的所有元素。

相对于ArrayList,LinkedList的随机访问集合元素时性能较差,因为需要在双向列表中找到要index的位置,再返回;但在插入,删除操作是更快的。因为LinkedList不像ArrayList一样,不需要改变数组的大小,也不需要在数组装满的时候要将所有的数据重新装入一个新的数组。

8. ConCurrentHashMap和HashMap的区别,分段锁机制?(理论)

HashMap底层通过数组+链表 或者 数组+红黑树实现,可以存储null键和null值,线程不安全,并发情况下不可用

在JDK1.7中ConcurrentHashMap采用了分段的数组+链表方式实现,线程安全

通过把整个Map分为N个Segment,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问, 可以提供相同的线程安全,但是效率提升N倍,默认提升16倍

jdk7:

数据结构: ReentrantLock+Segment +HashEntry, 一个segment 中包含一个HashEntry 数组, 每个HashEntry 又是一个链表结构

元素杳询: 二次hash, 第一次Hash定位到segment, 第二次Hash 定位到元素所在的链表的头部

锁: segment 分段锁 segment 继承了ReentrantLock, 锁定操作的segment ,其他的segment 不受影响,并发度为segment 个数,可以通过构造函数指定,数组扩容不会影响其他的segment

get 方法无需加锁, volatile保证

jdk8

数据结构: synchronized+CAS+Node+红黑树, Node的vaI和next 都用volatile 修饰, 保证可见性

查找, 替换,赋值操作都使用CAS

锁: 锁链表的head 节点, 不影响其他元素的读写, 锁粒度更细, 效率更高, 扩容时, 阻塞所有的读写操作、并发

读操作无锁:

Node 的val和next 使用volatile 修饰, 读写线程对该变量互相可见

数组用volatile 修饰, 保证扩容时被读线程感知

9. NIO和AIO,BIO三者区别?(理论)

BIO (Blocking I/O):同步阻塞I/O模式。请求数据过程,始终与服务器保持连接,一个链接使用一个线程,造成线程阻塞。

NIO (New I/O):同步非阻塞I/O模式。请求数据过程,如果服务器没有数据返回,采用轮询机制,需要进行I/O处理时,才会使用一个线程去处理,避免了BIO模型下大量线程处于阻塞等待状态。

AIO ( Asynchronous I/O):异步非阻塞I/O模式。异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。AIO相对于NIO的区别在于,NIO需要使用者线程不停的轮询IO对象,来确定是否有数据准备好可以读了,而AIO则是在数据准备好之后,才会通知数据使用者,这样使用者就不需要不停地轮询了。

10. 介绍下Spring框架?(从框架简介,到框架核心,到框架特性)

Spring是一个为了解决企业应用开发的复杂性而创建的开源框架,

Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架

轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。

控制反转——

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值