JAVA后端面试100 QA之第一篇

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

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 类加载机制

 

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

 

5. osgi类加载机制

 

 

  • 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异同

  • 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引用的对象
  • 方法区中的常量引用的对象,因此减少在长字符串上调用String.intern()
  • classloader加载的class对象,因此自定义classloader无效时及时置null并且注意类加载器加载对象之间的隔离
  • jvm里的一些静态数据结构里指向GC堆里的对象的引用
  • ...

未完待续(java、算法、spring、redis、dubbo、kafka、zookeeper等,广告点一波)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P2158,jzoj1709-仪仗队【欧拉函数,数论】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP2158 大意 有n∗nn∗n个点,求从(1,1)(1,1)可以看到多少个点。 解题思路 我们将(1,1)(1,1)当做(0,0)(0,0),然后所有点往下和后移一步 我们可以发现点距离点(0,0…

asp.net core MVC 过滤器之ExceptionFilter过滤器(一)

简介 异常过滤器,顾名思义,就是当程序发生异常时所使用的过滤器。用于在系统出现未捕获异常时的处理。 实现一个自定义异常过滤器 自定义一个异常过滤器需要实现IExceptionFilter接口 public class HttpGlobalExceptionFilter : IExceptionFilter { …

今天是个特殊的一天,有意义的一天,值得纪念的一天~

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。今天是个特殊的一天,筹划准备两周时间的IT技能大赛终于在报告厅顺利举行,全校6个班级共有7个小组参加本次技能大赛,大家的项目丰富多彩,不但…

分布式之redis复习精讲

转载自 分布式之redis复习精讲 引言 为什么写这篇文章? 博主的《分布式之消息队列复习精讲》得到了大家的好评,内心诚惶诚恐,想着再出一篇关于复习精讲的文章。但是还是要说明一下,复习精讲的文章偏面试准备,真正在开发过程中…

Nodejs第一讲记录

大家好, 我是雄雄,欢迎关注公众号 :雄雄的小课堂Node.jsNode的简介node是运行在服务端的JS基于谷歌 JavaScript运行时建立的一个平台是一个事件驱动IO服务端JavaScript环境,基于谷歌V8引擎,V8引擎执行JavaScript的速度…

ASP.NET Core 使用Cookie验证身份

ASP.NET Core 1.x提供了通过Cookie 中间件将用户主体序列化为一个加密的Cookie,然后在后续请求中验证Cookie并重新创建主体,并将其分配给HttpContext.User属性。如果您要提供自己的登录界面和用户数据库,可以使用作为独立功能的Cookie中间件。…

Node.JS第二讲笔记

大家好,欢迎关注微信公众号:雄雄的小课堂package包包结构包其实就是一个压缩文件,解压之后还原为目录,符合规范的目录,应该包含如下文件:package.json:描述文件bin:可执行的二进制文件lib&#…

asp.net core MVC 过滤器之ActionFilter过滤器(二)

简介 Action过滤器将在controller的Action执行之前和之后执行相应的方法。 实现一个自定义Action过滤器 自定义一个全局异常过滤器需要实现IActionFilter接口 public class ActionFilter : IActionFilter { public void OnActionExecuted(ActionExecutedContext context) …

【最全最详细】publiccms使用教程

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂拉取项目(项目部署阶段)1.首先需要从gitee中拉取项目,地址为:public cms项目地址 ,在idea中点击文件--》新建--》来自版本控制的项…

越努力越幸运,三年了!!!

“大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂”今天非常的开心,因为考了三年的驾照终于考完了。在大厅候考的时候,从10.40等到了1.40,坐在下面能看到LED上有自己的名字,但是前面等待的有200多人………

为什么我们要使用Async、Await关键字

前不久,在工作中由于默认(xihuan)使用Async、Await关键字受到了很多质问,所以由此引发这篇博文“为什么我们要用Async/Await关键字”,请听下面分解: Async/Await关键字 Visual Studio(.net fra…

一次惊险的跳槽面试经历(阿里/美团/头条/网易/有赞...)

转载自 一次惊险的跳槽面试经历(阿里/美团/头条/网易/有赞...) 每次说因为生活成本的时候面试官都会很惊奇,难道有我们这里贵?好想直接给出下面这张图,厦门的房价真的好贵好贵好贵。。。 面试过程 有兴趣加入阿里的欢迎发简历…

利用bladex+avue实现一对多的关系

“大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂”今天,记录一篇技术文章吧,也是解决了好久才解决掉的(说来也惭愧)。涉及技术前端:vue,element ui后端框架&#xff…

.NET中的高性能应用

本文要点 .NET自4.0以来得到了大幅的性能提升,很值得重新考虑一下基于旧版本.NET框架所做的假定。在讨论性能时垃圾回收是个重复出现的主题,它带来了许多CLR和语言的提升,比如引用返回和ValueTask在内存分配上更细粒度度量的性能分析API会成…

利用bladex+avue实现下拉数据源展示

“ 大家好,我是雄雄,欢迎关注微信公众号:????雄雄的小课堂???? ”昨天给大家整理了下如何使用bladex实现多表查询的方法,今天我们趁热打铁,顺便看看下拉列表的实现。 需求 我们经常会有这样的需求,…

汇编语言(一)之反转字符串输出

BASED ADDRESSING反转输出 程序运行: 代码: datas segmentstring db BASED ADDRESSING$ count dw $-string-1 ;计算string的长度,$为当前地址,-1为去掉字符串结束符$srcsTip db SRC string:$ dstsTip db 0…

前后端分离项目部署上线详细教程

“ 大家好,我是雄雄,欢迎关注微信公众号:????雄雄的小课堂???? ”今天,给大家分享的是,SpringbootVue项目如何部署上线的详细步骤。 代码编辑器 前端:Webstorm 2021.1.2 后端:IntelliJ …

.Net Core2.0下使用Dapper遇到的问题

今天成功把.Net Framework下使用Dapper进行封装的ORM成功迁移到.Net Core 2.0上,在迁移的过程中也遇到一些很有意思的问题,值得和大家分享一下。下面我会还原迁移的每一个过程,以及在此过程中遇到的问题和处理这些问题的方法。 一、迁移前的…

汇编语言(二)之数值求和

输入一串数字,求和 运行结果: 程序代码: datas segmentx db ? y db ? z db ?xInputPrompt db Enter a number x$ yInputPrompt db 0dh,0ah,Enter a number y$ zOutputPrompt db 0dh,0…

avue中怎样隐藏新增和编辑的按钮

“大家好,我是雄雄,欢迎关注微信公众号:????雄雄的小课堂????”????‍♂️今天给大家分享的技术是:avue中如何设置新增和编辑的按钮隐藏掉。????‍????涉及技术????前端:avue????后端&…