JAVA后端面试100 Q&A之第一篇

面试.jpg

跳槽不算频繁,但参加过不少面试(电话面试、face to face面试),面过大/小公司、互联网/传统软件公司,将自己经历过、构思过的一些面试题记录下来,如果答案有问题,欢迎拍砖讨论,希望能对找工作或者感兴趣的同学有所帮助,陆续整理中...

1. synchronized和reentrantlock异同

相同点
  • 都实现了多线程同步和内存可见性语义
  • 都是可重入锁
不同点
  • 实现机制不同
    synchronized通过java对象头锁标记和Monitor对象实现
    reentrantlock通过CAS、ASQ(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(线程上下文类加载器)的作用

  • 越过类加载器的双亲委派机制去加载类,如serviceloader实现
  • 使用线程上下文类加载器加载类,要注意保证多个需要通信的线程间的类加载器应该是同一个,防止因为不同的类加载器导致类型转换异常(ClassCastException)

4. tomcat 类加载机制

tomcat类加载器.png

  • 不同应用使用不同的 webapp类加载器,实现应用隔离的效果,webapp类加载器下面是jsp类加载器
  • 不同应用共享的jar包可以放到Shared类加载器/shared目录下

5. osgi类加载机制

osgi类加载机制.png

  • 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,使用自己的类加载器加载
    5)否则,查找类是否在自己的Fragment Bundle中,如果在,则委派给Fragment Bundle的类加载器加载
    6)否则,查找Dynamic Import-Package(Dynamic Import只有在真正用到此Package的时候才进行加载)的Bundle,委派给对应Bundle的类加载器加载
    7)否则,类查找失败

6. sleep和wait异同

  • 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. 线程池从启动到工作的流程

  • 刚创建时,里面没有线程
  • 调用 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的必要性),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等)

欢迎关注我的微信公众号
68号小喇叭
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容