失效链接处理 |
Javaq发~程面试题整?50?PDF 下蝲
本站整理下蝲Q?/strong>
链接Q?a target="_blank">https://pan.baidu.com/s/153KGSo-G79j4t6Fga7Hegg
提取码:(x)h9gp
相关截图Q?/strong>
![]()
主要内容Q?/strong>
Javaq发~程面试150?/div>
Q1Q线E越多程序是否就q行得越快?
{:(x)q发~程的目的是Z(jin)让程序运行得更快Q但是ƈ不是启动得线E越多就能让E序最大限度地q发执行。在q发~程Ӟ如果希望通过多线E执行Q务让E序q行得更快会(x)面(f)很多挑战Q比如上下文切换的问题、死锁的问题Q以?qing)受限于g和Y件的资源限制问题?/div>
Q2Q多U程q发是怎么实现的,必须要用多核处理器实现吗Q?/div>
{:(x)即是单核处理器也支持多U程执行代码QCPU通过l每个线E分配CPU旉片来实现q个机制。时间片是CPU分配l各个线E的旉Q因为时间片非常短(一般是几十毫秒Q,所以CPU通过不停地切换线E执行,让我们感觉多个线E是同时执行的?/div>
Q3Q什么是上下文切换?
{?CPU是通过旉片分配算法来循环执行dQ当前Q务执行一个时间片后会(x)切换C一个Q务。但是在切换前会(x)保存?sh)一个Q务的状态,以便下次再切换回q个d时可以再加蝲q个d的状态。所以Q务从保存到再加蝲的过E就是一ơ上下文切换?/div>
Q4Q如何减上下文切换Q?/div>
{:(x)①无锁ƈ发编E:(x)多线E竞争锁时会(x)引v上下文切换,所以多U程处理数据Ӟ可以通过一些方法来避免使用锁,例如数据的id按照hash法取模分段Q不同的U程处理不同数据D늚数据。②CAS法QJava的atomic包用CAS法来更新数据而不需要加锁。③使用最线E:(x)避免创徏不需要的U程Q比如Q务很,但是创徏?jin)很多线E来处理Q这样会(x)造成大量U程都处于等待状态。④协程Q在单线E里实现多Q务的调度Qƈ在单U程里维持多个Q务间的切换?/div>
Q5Q多U程避免死锁的方法?
{:(x)①避免一个线E同时获得多个锁。②避免一个线E在锁内同时占用多个资源Q尽量保证每个锁只占用一个资源。③试使用定时锁,使用lock.tryLock(timeout)来替代用内部锁机制。④对于数据库锁Q加锁和解锁必须在一个数据库q接里,否则?x)出现解锁失败的问题?/div>
Q6Qvolatile关键字的作用Q?/div>
{:(x)①volatile是轻量的synchronizedQ它在多处理器开发中保证?jin)共享变量的可见性。可见性的意思是当一个线E修改一个共享变量时Q另外一个线E能dq个修改的倹{②如果volatile变量修饰W用恰当的话,它比synchronized的用和执行成本更低Q因为它不会(x)引vU程上下文的切换和调度。③如果一个字D被声明成volatileQJavaU程内存模型保所有线E看到这个变量的值是一L(fng)?/div>
Q7Qvolatile的底层是如何实现的?
{:(x)有volatile修饰的共享变量在q行写操作时的汇~代码是hlock前缀的指令,lock
前缀的指令在多核处理器下?x)引发两件事Q①当前处理器~存行的数据写回到系l内存。②处理器将~存回写到内存的操作?x)在其他CPU里缓存(sh)(jin)该内存地址的数据无效?/div>
Z(jin)提高处理速度Q处理器不直接和内存q行通信Q而是先将pȝ内存的数据读到内部缓存后再进行操作,但操作完不知道何时会(x)写回内存。如果对声明?jin)volatile的变量进行写操作QJVM׃(x)向处理器发送一条lock前缀的指令,这个变量在~存行的数据写回到系l内存。但是就写回内存,如果其他处理器缓存的D是旧的,再执行计操作就?x)有问题QABA问题Q。所以在多处理器下,Z(jin)保证各个处理器的~存是一致的׃(x)实现~存?sh)致性协议,每个处理器通过嗅探在ȝ上传播的数据来检查自q存的值是不是q期?jin),当处理器发现自己~存行对应的内存地址被修改,׃(x)当前处理器的缓存行讄为无效状态,当处理器对这个数据进行修Ҏ(gu)作的时候,?x)重Cpȝ内存?sh)把数据d处理器缓存里?/div>
Q8Qvolatile如何优化性能Q?/div>
{:(x)可以通过q加字节的方式优化性能Q例如JDK7中的队列集合cLinkedTransferQueue是使用?jin)追加字节的方式来优化队列出队和入队的性能。由于一些处理器的高速缓存行?4个字节宽Q不支持部分填充~存行,如果队列的头节点和尾节点都不?4字节Q当一个处理器试图修改头节Ҏ(gu)׃(x)整个缓存行锁定Q那么在~存?sh)致性的作用下会(x)D其他处理器不能访问自己高速缓存(sh)的尾节点Q而队列的入队和出队又?x)频J修改头节点和尾节点Q因此多处理器情况下?x)严重?jing)响队列的入队和出队效率。追加到64字节后就可以填满高速缓冲区的缓存行Q避免头节点和尾节点加蝲到同一个缓存行Q它们的操作不?x)互盔R定?span style="white-space:pre">
但以下两U场景不应该使用q种方式Q①~存行非64字节宽的处理器。②׃n变量不会(x)被频J地写,因ؓ(f)使用q加字节的方式需要处理器d更多的字节到高速缓冲区Q这本n׃(x)带来一定性能消耗。如果共享变量不被频J写Q锁的几率很没有必要避免互盔R定。不q这U追加字节的方式在Java7可能不生效,因ؓ(f)Java7可以淘汰或重新排列无用字D,需要用其他追加字节的方式?/div>
Q9Qsynchronized锁的形式有哪些?
{:(x)①对于同步普通方法,锁是当前实例对象。②对于?rn)态同步方法,锁是当前cȝClass对象。③对于同步Ҏ(gu)块,锁是synchronized括号里配|的对象?/div>
Q10Qsynchronized的底层是怎么实现的?
{:(x)JVMZq入和退出Monitor对象来实现方法同步和代码块同步,但两者的实现l节不一栗代码块同步是用monitorenter和monitorexit指o(h)实现的,而方法同步是使用另一U方式实现的Q细节ƈ未在JVM规范中详l说明,但是Ҏ(gu)的同步也可以使用q两个指令来实现?/div>
monitorenter指o(h)是编译后插入到同步代码块的开始位|,而monitorexit是插入到Ҏ(gu)l束处和异常处,JVM要保证每个monitorenter必须有monitorexit与之配对。Q何对象都有一个monitor与之兌Q当一个monitor被持有后它将处于锁定状态。线E执行到monitorenter指o(h)Ӟ会(x)试获取对象所对应的monitor的所有权Q即试获得对象的锁?/div>
Q11Q什么是锁升U(锁优化)(j)Q?/div>
{:(x)JDK1.6Z(jin)减少获得锁和释放锁带来的性能消耗,引入?jin)偏向锁和轻量锁,在JDK1.6中,锁一共有4个状态,U别从低到高?sh)次是?x)无锁状态、偏向锁状态、轻量锁状态和重量U锁状态,q几个状态会(x)随着竞争情况逐渐升。锁可以升但不能降U,如果偏向锁升U成轻量U锁后就不能降成偏向锁Q这U只能升U不能降U的锁策略是Z(jin)提高获得锁和释放锁的效率?br />
|