特此将本身经历过、构思过的一些面试题记录下来,若是答案有问题,欢迎拍砖讨论,但愿能对找工做或者感兴趣的同窗有所帮助,陆续整理中...java
1. synchronized和reentrantlock异同web
相同点
不一样点
- 实现机制不一样 synchronized经过java对象头锁标记和Monitor对象实现 reentrantlock经过CAS、AQS(AbstractQueuedSynchronizer)和locksupport(用于阻塞和解除阻塞)实现 synchronized依赖jvm内存模型保证包含共享变量的多线程内存可见性 reentrantlock经过ASQ的volatile state保证包含共享变量的多线程内存可见性
- 使用方式不一样 synchronized能够修饰实例方法(锁住实例对象)、静态方法(锁住类对象)、代码块(显示指定锁对象) reentrantlock显示调用trylock()/lock()方法,须要在finally块中释放锁
- 功能丰富程度不一样 reentrantlock提供有限时间等候锁(设置过时时间)、可中断锁(lockInterruptibly)、condition(提供await、signal等方法)等丰富语义 reentrantlock提供公平锁和非公平锁实现 synchronized不可设置等待时间、不可被中断(interrupted)
2. concurrenthashmap为什么读不用加锁面试
- jdk1.7
1)HashEntry中的key、hash、next 均为final 型,只能表头插入、删除结点
2)HashEntry类的value域被声明为volatile型
3)不容许用null做为键和值,当读线程读到某个HashEntry的 value域的值为null时,便知道产生了冲突——发生了重排序现象(put设置新value对象的字节码指令重排序),须要加锁后从新读入这个value值
4)volatile变量count协调读写线程之间的内存可见性,写操做后修改count,读操做先读count,根据happen-before传递性原则写操做的修改读操做可以看到
- jdk1.8
1)Node的val和next均为volatile型
2)tabAt和casTabAt对应的unsafe操做实现了volatile语义
3. ContextClassLoader(线程上下文类加载器)的做用redis
- 越过类加载器的双亲委派机制去加载类,如serviceloader实现
- 使用线程上下文类加载器加载类,要注意保证多个须要通讯的线程间的类加载器应该是同一个,防止由于不一样的类加载器致使类型转换异常(ClassCastException)
4. tomcat 类加载机制 算法
- 不一样应用使用不一样的 webapp类加载器,实现应用隔离的效果,webapp类加载器下面是jsp类加载器
- 不一样应用共享的jar包能够放到Shared类加载器/shared目录下
5. osgi类加载机制 spring
- osgi类加载模型是网状的,能够在模块(Bundle)间互相委托
- osgi实现模块化热部署的关键是自定义类加载器机制的实现,每一个Bundle都有一个本身的类加载器,当须要更换一个Bundle时,就把Bundle连同类加载器一块儿换掉以实现代码的热替换
- 当收到类加载请求时,osgi将按照下面的顺序进行类搜索:
1)将以java.*开头的类委派给父类加载器加载
2)不然,将委派列表名单(配置文件org.osgi.framework.bootdelegation中定义)内的类委派给父类加载器加载
3)不然,检查是否在Import-Package中声明,若是是,则委派给Export这个类的Bundle的类加载器加载
4)不然,检查是否在Require-Bundle中声明,若是是,则将类加载请求委托给required bundle的类加载器
5)不然,查找当前Bundle的ClassPath,使用本身的类加载器加载
6)不然,查找类是否在本身的Fragment Bundle中,若是在,则委派给Fragment Bundle的类加载器加载
7)不然,查找Dynamic Import-Package(Dynamic Import只有在真正用到此Package的时候才进行加载)的Bundle,委派给对应Bundle的类加载器加载
8)不然,类查找失败
6. sleep和wait异同sql
- wait须要组合synchronized使用,wait时会释放掉拿到的synchronized锁
- sleep只会交出cpu,不会交出锁
- 两者都有可能被interrupt
7. 如何结束一个一直运行的线程数据库
- 使用退出标志,这个flag变量要多线程可见
- 使用interrupt,结合isInterrupted()使用
8. threadlocal使用场景及问题编程
- threadlocal并不能解决多线程共享变量的问题,同一个 threadlocal所包含的对象,在不一样的thread中有不一样的副本,互不干扰
- 用于存放线程上下文变量,方便同一线程对变量的先后屡次读取,如事务、数据库connection链接,在web编程中使用的更多
- 问题: 注意线程池场景使用threadlocal,由于实际变量值存放在了thread的threadlocalmap类型变量中,若是该值没有remove,也没有先set的话,可能会获得之前的旧值
- 问题: 注意线程池场景下的内存泄露,虽然threadlocal的get/set会清除key(key为threadlocal的弱引用,value是强引用,致使value不释放)为null的entry,可是最好remove
9. 线程池从启动到工做的流程bootstrap
- 刚建立时,里面没有线程
- 调用 execute() 添加任务时:
1)若是正在运行的线程数量小于核心参数corePoolSize,继续建立线程运行这个任务
2)不然,若是正在运行的线程数量大于或等于corePoolSize,将任务加入到阻塞队列中
3)不然,若是队列已满,同时正在运行的线程数量小于核心参数maximumPoolSize,继续建立线程运行这个任务
4)不然,若是队列已满,同时正在运行的线程数量大于或等于 maximumPoolSize,根据设置的拒绝策略处理
5)完成一个任务,继续取下一个任务处理
6)没有任务继续处理,线程被中断或者线程池被关闭时,线程退出执行,若是线程池被关闭,线程结束
7)不然,判断线程池正在运行的线程数量是否大于核心线程数,若是是,线程结束,不然线程阻塞。所以线程池任务所有执行完成后,继续留存的线程池大小为corePoolSize
10. 阻塞队列BlockingQueue take和poll区别
- poll(time):取走BlockingQueue里排在首位的对象,若不能当即取出,则能够等time参数规定的时间,取不到时返回null
- take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻塞直到BlockingQueue有新的对象被加入
11. 如何从FutureTask不阻塞获取结果
- get(long timeout,TimeUnit unit),超时则返回
- 轮询,先经过isDone()判断是否结束,而后调用get()
12. blockingqueue若是存放了比较关键的数据,系统宕机该如何处理
- 开放性问题,欢迎讨论
- 将队列持久化,比较麻烦,须要将生产数据持久化到磁盘,持久化成功才返回,消费者线程从磁盘加载数据到内存阻塞队列中,维护消费offset,启动时,根据消费offset从磁盘加载数据
- 加入消息队列,保证消息不丢失,生成序列号,消费幂等,根据消费进程决定系统重启后的生产状态
13. NIO与传统I/O的区别
- 节约线程,NIO由原来的每一个线程都须要阻塞读写变成了由单线程(即Selector)负责处理多个channel注册(register)的兴趣事件(SelectionKey)集合(底层借助操做系统提供的epoll()),netty bossgroup处理accept链接(没看明白为何bossgroup设置多个thread的必要性,补充:听说是为了多个bootstrap共用bossgroup的场景),workergroup处理具体业务流程和数据读写
- NIO提供非阻塞操做
- 传统I/O 以流的方式处理数据,而 NIO 以块的方式处理数据,NIO提供bytebuffer,分为堆内和堆外缓冲区,读写时均先放到该缓冲区中,而后由内核经过channel传输到对端,堆外缓冲区不走内核,提高了性能
14. list中存放可重复字符串,如何删除某个字符串
- 调用iterator相关方法删除
- 倒删,防止正序删除致使的数组重排,index跳过数组元素问题
15. 有哪些GC ROOTS(跟平常开发比较相关的是和此相关的内存泄露)
- 全部Java线程当前活跃的栈帧里指向GC堆里的对象的引用,所以用不到的对象及时置null,提高内存回收效率
- 静态变量引用的对象,所以减小静态变量特别是静态集合变量的大小,集合存放的对象覆写euqls()和hashcode(),防止持续增加
- 本地方法JNI引用的对象
- 方法区中的常量引用的对象,例如JDK7之前版本尽可能减小在长字符串上调用String.intern()
- classloader加载的class对象,所以自定义classloader无效时及时置null而且注意类加载器加载对象之间的隔离
- jvm里的一些静态数据结构里指向GC堆里的对象的引用
- ...
16.volatile的做用
17.Spring事务传播特性
常规问题,请网上搜索
18.任一mq(如kafka)的qos有哪些,分别如何保障?
通常有:
- at most once:至多一次
- at least once:至少一次
- exactly once:有且仅有一次 实现原理请搜索,不管是否exactly once,都须要作好幂等
19.如何设计相似微博的点赞功能(高流量并发)
开放问题,请搜索
20.服务响应慢,怎么去排查问题
同上
21.谈谈sql优化的手段
同上
22.分享下微服务解耦的经验
同上
未完待续(java、算法、spring、redis、dubbo、kafka、zookeeper等)
欢迎关注个人微信公众号