本文作者:伯乐在线-朱小厮。未经作者答应,克制转载!
欢迎参加伯乐在线专栏作者。
本篇所要先容的是一家互联网企业,简称MD好了。一面是电面,二三面是face2face的技能面,4面是HR面。
一面
一面的具体内容忘了记录了,大概面了45mins,问了30mins的NIO。
这里就来讲一讲NIO的一些知识点。NIO有三个部分:Selector,Channel和Buffer.传统的IO基于字节流和字符流举行操纵。而NIO基于Channel和Buffer(缓冲区)举行操纵,数据总是从通道读取到缓冲区,大概从缓冲区写入通道中。Selector用于监听多个通道的时间(比如打开,数据到达),因此,单个线程可以监听多个数据通道。
Selector内部原理实际是在做一个对所注册的Channel的轮询访问,不绝的轮询,一旦轮询到一个channel有所注册的事变发生,比如数据来了,他就会站起来陈诉,交出一把钥匙(SelectionKey),让我妈通过这把钥匙来读取channel的内容。
NIO有一个紧张的点是:Reactor模式。
从网上抠来一张Reactor模式的模子图如下:
Reactor模式有两大脚色:Reactor和Handler.Reactor负责相应I/O变乱;Handler负责非壅闭举动。至于Reactor模式的编码风格我就不赘述了。
前面说到了Selector的原理就是轮询,但是JavaNIO中有个epoll()(linux体系下),这个对并发idleConnection会有大幅度的性能提拔。epoll是linux下多路复用I/O接口Select/poll的加强版本。一样平常的轮询方式一个进程打开的FD(FileDeor)是有肯定限定的,FD_SETSIZE默认是2048,这个宏界说可以修改,但修改后的结果并不抱负,对于那些必要支持上万毗连数的IM服务器来说显然太少。epoll没有这个限定,可以通过”cat/proc/sys/fs/file-max”来查察支持的FD上限。博主本地呆板是205822。epoll()有两种利用模式:LT(Leveltriggered)缺省,ET(Edge-triggered)高速。
epoll有一个闻名的epoll-bug,也大概会导致无效的状态的选择和100%的CPU利用率,要办理epoll-bug的唯一方法是采取旧的选择,将先前注册的通道实例转移到新创建的选择器上。固然假如利用一些框架比如:Netty,Mina.
面的全问到了,问的还挺深的。末了问了为什么没用Netty之类的框架实现,尚有有相识过其他的分布式框架么?
还问了一些Java底子题。
比如多线程的ThreadPollExecutor中的饱和战略有哪些?
Ans:当线程池和队列都满了,则表明该线程池已达饱和状态。
ThreadPoolExecutor.AbortPolicy:处理惩罚程序遭到拒绝,则直接抛出运行时非常RejectedExecutionException。(默认战略)ThreadPoolExecutor.CallerRunsPolicy:调用者地点线程来运行该任务,此战略提供简单的反馈控制机制,可以或许减缓新任务的提交速率。ThreadPoolExecutor.DiscardPolicy:无法实行的任务将被删除。ThreadPoolExecutor.DiscardOldestPolicy:假如实行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重新实行实行任务(假如再次失败,则重复此过程)。
线程池怎么公道设置?
Ans:必要针对具体环境而具体处理惩罚,差别的任务种别应采取差别规模的线程池,任务种别可分别为CPU麋集型任务、IO麋集型任务和肴杂型任务。
对于CPU麋集型任务:线程池中线程个数应只管少,不应大于CPU核心数;对于IO麋集型任务:由于IO操纵速率远低于CPU速率,那么在运行这类任务时,CPU绝大多数时间处于空闲状态,那么线程池可以设置只管多些的线程,以进步CPU利用率;对于肴杂型任务:可以拆分为CPU麋集型任务和IO麋集型任务,当这两类任务实行时间相差无几时,通过拆分再实行的吞吐率高于串行实行的吞吐率,但若这两类任务实行时间有数据级的差距,那么没有拆分的意义。
线程数的个数?(这个题目二面也问到了)
Nthreads=Ncpu*Ucpu*(1+W/C)。Ncpu是cpu的个数,可以通过Runtime.getRuntime.availableProcessors()获取。Ucpu是cpu的利用率。W/C=Wait-Time/Compute-Time.ps:Runtime.getRuntime是单例模式。
二面
二面先对简历上的内容扣问了一番,问了一些题目,再此就不表了,接下去问了些Java类的题目。
1.线程池ThreadPoolExecutor以及Executors的一些题目。
2.ReentrantLock和synchronized的区别。
ReentrantLock可以停止地获取锁(voidlockInterruptibly()throwsInterruptedException)ReentrantLock可以实行非壅闭地获取锁(booleantryLock())ReentrantLock可以超时获取锁。通过tryLock(timeout,unit),可以实行得到锁,而且指定等待的时间。ReentrantLock可以实现公平锁。通过newReentrantLock(true)实现。ReentrantLock对象可以同时绑定多个Condition对象,而在synchronized中,锁对象的的wait(),notify(),notifyAll()方法可以实现一个隐含条件,假如要和多于一个的条件关联的对象,就不得不额外地添加一个锁,而ReentrantLock则无需如许做,只必要多次调用newCondition()方法即可。
从上面的比力中可以看出ReentrantLock比synchronized有很多的长处,但是JDK的开辟团队还是推许利用synchronized的方式,在JDK5中ReentrantLock比synchronized的性能良好很多,在JDK6中举行了很多的优化,ReentrantLock比synchronized只是轻微好点,而且ReentrantLock用的不好,比如Lock.lock之后再finally块中忘了Lock.unlock操纵锁就永久得不到开释,而synchronized可以主动开释锁。而且颠末JDK的开辟团队的不懈积极,synchronized的性能会越来越好,比如:方向锁,轻量级锁,自旋锁,锁粗化以及锁细化等优化操纵。
3.ReentrantLock又称之为什么?怎么实现的?尚有那些雷同的?
ReentrantLock又称之为可重入锁,内部实现是基于AQS的(对于AQS不明白的小搭档可以度娘了)。尚有一些也是基于AQS的比如Semaphore,尚有ReentrantReadWriteLock(独占锁+共享锁)。在ReentrantReadWriteLock中又涉及了一个锁降级的概念:先Hold写锁,再获取读锁,再开释写锁。没有锁升级的概念。(有关多线程的知识,可以翻看博主相干的文章,详情见参考资料1-4。)
4.sleep和wait的区别?为什么sleep在Thread中,wait在Object中?
sleep不让出锁,它不会导致锁举动的改变,而wait会让出锁。Thread.sleep的调用不会影响锁的改变,以是放在sleep中,wait与锁有关以是放在Object中。
5.为什么Java中的锁是对象锁而不是线程锁?
这个题目比力抽象,重要是在对象锁的编程模子比力简单,线程锁着实也可以,但是编程模子太复杂,以是Java采取的对象锁。
6.写一个单例模式。
博主写了一个内部类的单例模式,然后说了其他的写法比如:enum大概synchronized的写法,详情可以关注《计划模式:单例模式(Singleton)》。
背面又问了一个题目:一个类中全部的方法和属性都标注为static的,那么这是一个单例么?口试官的语气暗示这不是一个单例,但简直想不出不是单例的地方,想了一会儿才明白过来这简直是一个单例的写法。单例是包管一个类的实例构造器只实现一次,而全部标注为static的类,它就只有类构造器,类构造器可以由JVM确保只实行一次,而且是线程安全的。
尚有一道计划题:微信公众号拉取粉丝数量。
三面
三面的口试官照着简历问了一些题目,然后问了一些其他的和技能无关的,末了还问了一个技能类题目:怎么可以发生FullGC?
FullGC是指老年代发生了Stoptheworld的操纵。具体可以参考《Java堆内存》。
比如在CMS实行时有初始标记、并发标记、重新标记、并发打扫、并发重置5个步调中,初始标记和重新标记都是stoptheworld的,当发生ConcurrentModeFailure时,会触发一次Serial-Old的操纵。
可以在程序中通过设置-Xmx,-Xms等参数去触发,也可以通过System.gc()触发。固然有两个工具JConsole和JVsualVm中有“GC”的按钮。
(剩下的可以在留言区增补。)
总结:无。(对这家公司太认识,不方便评价~~)
更多链接请关注:
这里有一份面经,请查收(一)
这里有一份面经,请查收(二)
这里有一份面经,请查收(三)
这里有一份面经,请查收(四)
这里有一份面经,请查收(五)
这里有一份面经,请查收(六)
打赏支持我写出更多好文章,谢谢!
打赏作者打赏支持我写出更多好文章,谢谢!
任选一种付出方式
1赞收藏批评
关于作者:朱小厮
Java相干技能爱好者个人主页·我的文章·8·
我要评论