本文由尚学堂学员们根据自己参加过的面试回忆、总结而成,一线互联网企业常见的14个Java面试题,包括各大互联网企业、创业小公司,互联网企业、传统软件公司。对于刚毕业和想要跳槽的宝宝们,再适用不过啦,赶紧拿起小本本记下来,下次面试就可以用上啦~

01、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)

02、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语义

03、ContextClassLoader(线程上下文类加载器)的作用

 

  • 越过类加载器的双亲委派机制去加载类,如serviceloader实现

  • 使用线程上下文类加载器加载类,要注意保证多个需要通信的线程间的类加载器应该是同一个,防止因为不同的类加载器导致类型转换异常(ClassCastException)

04 、tomcat 类加载机制

 

  • 不同应用使用不同的 webapp类加载器,实现应用隔离的效果,webapp类加载器下面是jsp类加载器

  • 不同应用共享的jar包可以放到Shared类加载器/shared目录下

 

 

05、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)否则,类查找失败

 

 

06、如何结束一个一直运行的线程

 

  • 使用退出标志,这个flag变量要多线程可见

  • 使用interrupt,结合isInterrupted()使用

 

 

07、threadlocal使用场景及问题

 

  • threadlocal并不能解决多线程共享变量的问题,同一个 threadlocal所包含的对象,在不同的thread中有不同的副本,互不干扰

  • 用于存放线程上下文变量,方便同一线程对变量的前后多次读取,如事务、数据库connection连接,在web编程中使用的更多

  • 问题: 注意线程池场景使用threadlocal,因为实际变量值存放在了thread的threadlocalmap类型变量中,如果该值没有remove,也没有先set的话,可能会得到以前的旧值

  • 问题: 注意线程池场景下的内存泄露,虽然threadlocal的get/set会清除key(key为threadlocal的弱引用,value是强引用,导致value不释放)为null的entry,但是最好remove

 

 

08、线程池从启动到工作的流程

 

  • 刚创建时,里面没有线程

  • 调用 execute() 添加任务时:

  • 1)如果正在运行的线程数量小于核心参数corePoolSize,继续创建线程运行这个任务

  • 2)否则,如果正在运行的线程数量大于或等于corePoolSize,将任务加入到阻塞队列中

  • 3)否则,如果队列已满,同时正在运行的线程数量小于核心参数maximumPoolSize,继续创建线程运行这个任务

  • 4)否则,如果队列已满,同时正在运行的线程数量大于或等于 maximumPoolSize,根据设置的拒绝策略处理

  • 5)完成一个任务,继续取下一个任务处理

  • 6)没有任务继续处理,线程被中断或者线程池被关闭时,线程退出执行,如果线程池被关闭,线程结束

  • 7)否则,判断线程池正在运行的线程数量是否大于核心线程数,如果是,线程结束,否则线程阻塞。因此线程池任务全部执行完成后,继续留存的线程池大小为corePoolSize

 

 

09、阻塞队列BlockingQueue take和poll区别

 

  • poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null

  • take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻塞直到BlockingQueue有新的对象被加入

 

 

10、如何从FutureTask不阻塞获取结果

 

  • get(long timeout,TimeUnit unit),超时则返回

  • 轮询,先通过isDone()判断是否结束,然后调用get()

 

 

11、blockingqueue如果存放了比较关键的数据,系统宕机该如何处理

 

  • 开放性问题,欢迎讨论

  • 将队列持久化,比较麻烦,需要将生产数据持久化到磁盘,持久化成功才返回,消费者线程从磁盘加载数据到内存阻塞队列中,维护消费offset,启动时,根据消费offset从磁盘加载数据

  • 加入消息队列,保证消息不丢失,生成序列号,消费幂等,根据消费进程决定系统重启后的生产状态

 

 

12、NIO与传统I/O的区别

 

  • 节约线程,NIO由原来的每个线程都需要阻塞读写变成了由单线程(即Selector)负责处理多个channel注册(register)的兴趣事件(SelectionKey)集合(底层借助操作系统提供的epoll()),netty bossgroup处理accept连接(没看明白为什么bossgroup设置多个thread的必要性),workergroup处理具体业务流程和数据读写

  • NIO提供非阻塞操作

  • 传统I/O 以流的方式处理数据,而 NIO 以块的方式处理数据,NIO提供bytebuffer,分为堆内和堆外缓冲区,读写时均先放到该缓冲区中,然后由内核通过channel传输到对端,堆外缓冲区不走内核,提升了性能

 

 

13、list中存放可重复字符串,如何删除某个字符串

 

  • 调用iterator相关方法删除

  • 倒删,防止正序删除导致的数组重排,index跳过数组元素问题

 

 

14、有哪些GC ROOTS(跟日常开发比较相关的是和此相关的内存泄露)

 

  • 所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用,因此用不到的对象及时置null,提升内存回收效率

  • 静态变量引用的对象,因此减少静态变量特别是静态集合变量的大小,集合存放的对象覆写euqls()和hashcode(),防止持续增长

  • 本地方法JNI引用的对象

  • 方法区中的常量引用的对象,因此减少在长字符串上调用String.intern()

  • classloader加载的class对象,因此自定义classloader无效时及时置null并且注意类加载器加载对象之间的隔离

  • jvm里的一些静态数据结构里指向GC堆里的对象的引用

本文转自尚学堂公众号,获取更详细的Java面试题集和面试大全,请来上海尚学堂官网下载获取学习。

一线互联网企业常见的14个Java面试题,Java面试题集大全等你拿,颤抖吧程序员!的更多相关文章

  1. 对于长沙互联网发展,一个外来两年Java程序员的所见所感所愿

    惟楚有材,于斯为盛 本文有感于2019长沙互联网求职招聘大会,内容比较多,但都是我自己的一些所见.所感和所愿. 2019年3月的最后一天,参加2019长沙互联网求职招聘大会,看到了很多的招聘企业,也看 ...

  2. Java后端程序员都做些什么?

    这个问题来自于QQ网友,一句两句说不清楚,索性写个文章. 我刚开始做Web开发的时候,根本没有前端,后端之说. 原因很简单,那个时候服务器端的代码就是一切:接受浏览器的请求,实现业务逻辑,访问数据库, ...

  3. 【面试题】100IT名企java面试必考面试题

    一.Java 基础部分 1.   JAVA 的基本数据类型有哪些 ?   String 是不是基本数据类型 ? Java  有 8 种基本数据类型:           byte    int     ...

  4. Java学习1 - java 历史

    Sun的Java语言开发小组成立于1991年,其目的是开拓消费类电子产品市场,例如:交互式电视,烤面包箱等.Sun内部人员把这个项目称为 Green,那时World Wide Web还在图纸上呢.该小 ...

  5. java较全的面试题

    一.Java基础部分 1. JAVA的基本数据类型有哪些 ? String 是不是基本数据类型 ? 2. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? ...

  6. 想要成为一名优秀的Java程序员,你需要这8个锦囊

    私底下,隔三差五就有读者问我:"二哥,怎么样才能像你一样,成为一名优秀的 Java 开发者呢?"假如把"怎么才能像你一样"去掉的话,这个问题就是一个好问题,否则 ...

  7. 【分享】熟练的Java程序员应该掌握哪些技术?

    Java程序员应该掌握哪些能力才能算是脱离菜鸟达到熟练的程度? 1.语法:Java程序员必须比较熟悉语法,在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息 知道是什么样的语法错误并且知道任 ...

  8. 夯实Java基础系列5:Java文件和Java包结构

    目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...

  9. Java文件和Java包结构

    Java中的包概念 Java中的包是封装一组类,子包和接口的机制.软件包用于: 防止命名冲突.例如,可以有两个名称分别为Employee的类,college.staff.cse.Employee和co ...

随机推荐

  1. java接受安卓及ios App上传的图片,并保存到阿里OSS

    做后台的时候,写了两个方法,分别用来获取安卓和苹果IOS端上传的头像,保存到阿里云OSS图片存储服务器上.(SMM框架) 安卓及H5版本: /** * 上传用户头像 */ @RequestMappin ...

  2. href="#" 是什么意思?

    <a href="#" onclick="process1()">开始你表演</a>作用:书签的另一种用法建立书签语法:<a na ...

  3. 适合Python的5大练手项目, 你练了么?

    在练手项目的选择上,还存在疑问?不知道要从哪种项目先下手? 首先有两点建议: 最好不要写太应用的程序练手,要思考什么更像是知识,老只会写写爬虫是无用的,但是完全不写也不行. 对于练手的程序,要注意简化 ...

  4. CSS学习笔记六:写原生导航栏

    因为刚开始学习CSS时,只了解了一些基本样式,然后就跑去学习bootstrap.bootstrap是个不错的东西,挺好玩,起码让你写界面写的轻轻松松,几行引入代码,再来个复制粘贴就解决了,而且boot ...

  5. Flask构建微电影(二)

    第三章.项目分析.搭建目录及模型设计 3.1.前后台项目目录分析 微电影网站 前台模块 后台模块 前台(home) 数据模型:models.py 表单处理:home/forms.py 模板目录:tem ...

  6. CAS与OAuth2的区别

    CAS与OAuth2的区别 一. CAS的单点登录时保障客户端的用户资源的安全 . OAuth2则是保障服务端的用户资源的安全 . 二. CAS客户端要获取的最终信息是,这个用户到底有没有权限访问我( ...

  7. 基于支付系统真实场景的分布式事务解决方案效果演示: http://www.iqiyi.com/w_19rsveqlhh.html

    基于支付系统真实场景的分布式事务解决方案效果演示:http://www.iqiyi.com/w_19rsveqlhh.html

  8. java 各数据类型之间的转换

    String —> Date SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date ...

  9. Java中创建线程的三种方式及其优缺点

    1.自定义一个继承Thread的类,由于Java的单继承特性,限制了该类的扩展性. 2.实现Runnable接口,重写run()方法. 3.实现Callable接口,重写call方法.线程执行体可以有 ...

  10. 对JDK的深入理解

    今天对Java的jdk有了更加深入的理解: Java的jdk其实一共包含三部分内容: 1.工具包 2.类库 3.JRE jdk的全名:Java develop kit (java开发工具) jdk包含 ...