线程间的同步_线程同步方法

线程间的同步_线程同步方法Java高级面试题及答案(Java高级面试题大汇总)Java高级面试题及答案【最新版】Java高级高级面试题大全(2021版),发现网上很多Java高级面试题都没有答案,所以花了很长时间搜集,本套Java高级面试题大全,Java高级面试题大汇总,有大量经典的J

Java高级面试题及答案(Java高级面试题大汇总)   Java高级面试题及答案【最新版】Java高级高级面试题大全(2021版),发现网上很多Java高级面试题都没有答案,所以花了很长时间搜集,本套Java高级面试题大全,Java高级面试题大汇总,有大量经典的Java高级面试题以及答案,包含Java高级语言常见面试题、Java高级工程师高级面试题及一些大厂Java高级开发面试宝典,面试经验技巧等,应届生,实习生,企业工作过的,都可参考学习!   这套Java高级面试题汇总大全,希望对大家有帮助哈~   博主已将以下这些面试题整理成了一个Java高级面试手册,是PDF版的   已经整理成7000多页,面试手册PDF版   相关,其他面试题   架构师专栏:300道SpringCloud面试题(持续更新)架构师专栏:Jvm面试题总结及答案 300道(针对Jvm的面试题 )架构师专栏:300道 Kafka最全面试题整理(持续更新)架构师专栏:最新Dubbo面试题,附带详细答案(持续更新)架构师专栏:110道 ES面试题及答案整理(持续更新)架构师专栏:110道 Redis面试题及答案 (持续更新)   【新更新】在java中守护线程和本地线程区别?   java中的线程分为两种:守护线程(Daemon)和用户线程(User)。   任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(bool on);true则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon()必须在Thread.start()之前调用,否则运行时会抛出异常。   两者的区别:   唯一的区别是判断虚拟机(JVM)何时离开,Daemon是为其他线程提供服务,如果全部的User Thread已经撤离,Daemon 没有可服务的线程,JVM撤离。也可以理解为守护线程是JVM自动创建的线程(但不一定),用户线程是程序创建的线程;比如JVM的垃圾回收线程是一个守护线程,当所有线程已经撤离,不再产生垃圾,守护线程自然就没事可干了,当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。   扩展:   Thread Dump打印出来的线程信息,含有daemon字样的线程即为守护进程,可能会有:服务守护进程、编译守护进程、windows下的监听Ctrl+break的守护进程、Finalizer守护进程、引用处理守护进程、GC守护进程。   【新更新】CMS分为哪几个阶段?   CMS已经弃用。生活美好,时间有限,不建议再深入研究了。如果碰到问题,直接祭出回收过程即可。   1、 初始标记   2、 并发标记   3、 并发预清理   4、 并发可取消的预清理   5、 重新标记   6、 并发清理   由于《深入理解java虚拟机》一书的流行,面试时省略3、4步一般也是没问题的。   【新更新】抽象的关键字是什么?   Abstract   【新更新】如何判断对象可以被回收   判断对象是否存活一般有两种方式:   引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。   可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象。   【新更新】如何通过反射调用对象的方法?   请看下面的代码:   import java.lang.reflect.Method; class MethodInvokeTest { public static void main(String[] args) throws Exception { String str = “hello”; Method m = str.getClass().getMethod(“toUpperCase”); System.out.println(m.invoke(str)); // HELLO } }   【新更新】如何进行单测试   使用junit   【新更新】什么情况下会发生栈内存溢出?   栈是线程私有的,他的生命周期与线程相同,每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息。局部变量表又包含基本数据类型,对象引用类型。如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常,方法递归调用产生这种结果。如果Java虚拟机栈可以动态扩展,并且扩展的动作已经尝试过,但是无法申请到足够的内存去完成扩展,或者在新建立线程的时候没有足够的内存去创建对应的虚拟机栈,那么Java虚拟机将抛出一个OutOfMemory 异常。(线程启动过多)。   【新更新】什么是Hash算法   哈希算法是指把任意长度的二进制映射为固定长度的较小的二进制值,这个较小的二进制值叫做哈希值。   【新更新】什么是上下文切换?   1、 多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。   2、 概括来说就是:当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。任务从保存到再加载的过程就是一次上下文切换。   3、 上下文切换通常是计算密集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间。所以,上下文切换对系统来说意味着消耗大量的 CPU 时间,事实上,可能是操作系统中时间消耗最大的操作。   4、 Linux 相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。   【新更新】列举一些你知道的打破双亲委派机制的例子。为什么要打破?   1、 JNDI 通过引入线程上下文类加载器,可以在 Thread.setContextClassLoader 方法设置,默认是应用程序类加载器,来加载 SPI 的代码。有了线程上下文类加载器,就可以完成父类加载器请求子类加载器完成类加载的行为。打破的原因,是为了 JNDI 服务的类加载器是启动器类加载,为了完成高级类加载器请求子类加载器(即上文中的线程上下文加载器)加载类。   2、 Tomcat,应用的类加载器优先自行加载应用目录下的 class,并不是先委派给父加载器,加载不了才委派给父加载器。打破的目的是为了完成应用间的类隔离。   3、 OSGi,实现模块化热部署,为每个模块都自定义了类加载器,需要更换模块时,模块与类加载器一起更换。其类加载的过程中,有平级的类加载器加载行为。打破的原因是为了实现模块热替换。   4、 JDK 9,Extension ClassLoader 被 Platform ClassLoader 取代,当平台及应用程序类加载器收到类加载请求,在委派给父加载器加载前,要先判断该类是否能够归属到某一个系统模块中,如果可以找到这样的归属关系,就要优先委派给负责那个模块的加载器完成加载。打破的原因,是为了添加模块化的特性。   1、并行和并发有什么区别?   1、 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。   2、 并行:单位时间内,多个处理器或多核处理器同时处理多个任务,是真正意义上的“同时进行”。   3、 串行:有n个任务,由一个线程按顺序执行。由于任务、方法都在一个线程执行所以不存在线程不安全情况,也就不存在临界区的问题。   做一个形象的比喻:   1、 并发 = 俩个人用一台电脑。   2、 并行 = 俩个人分配了俩台电脑。   3、 串行 = 俩个人排队使用一台电脑。   2、Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)?   SessionFactory对应Hibernate的一个数据存储的概念,它是线程安全的,可以被多个线程并发访问。SessionFactory一般只会在启动的时候构建。对于应用程序,最好将SessionFactory通过单例模式进行封装以便于访问。Session是一个轻量级非线程安全的对象(线程间不能共享session),它表示与数据库进行交互的一个工作单。Session是由SessionFactory创建的,在任务完成之后它会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟数据库连接(也就是在需要的时候才会)。为了避免创建太多的session,可以使用ThreadLocal将session和当前线程绑定在一起,这样可以让同一个线程获得的总是同一个session。Hibernate 3中SessionFactory的getCurrentSession()方法就可以做到。   3、Java会存在内存泄漏吗?请简单描述。   内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。理论上来说,Java是有GC垃圾回收机制的,也就是说,不再被使用的对象,会被GC自动回收掉,自动从内存中清除   但是,即使这样,Java也还是存在着内存泄漏的情况,java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。   4、生产环境服务器变慢,如何诊断处理?   1、 使用 top 指令,服务器中 CPU 和 内存的使用情况,-H 可以按 CPU 使用率降序,-M 内存使用率降序。排除其他进程占用过高的硬件资源,对 Java 服务造成影响。   2、 如果发现 CPU 使用过高,可以使用 top 指令查出 JVM 中占用 CPU 过高的线程,通过 jstack 找到对应的线程代码调用,排查出问题代码。   3、 如果发现内存使用率比较高,可以 dump 出 JVM 堆内存,然后借助 MAT 进行分析,查出大对象或者占用最多的对象来自哪里,为什么会长时间占用这么多;如果 dump 出的堆内存文件正常,此时可以考虑堆外内存被大量使用导致出现问题,需要借助操作系统指令 pmap 查出进程的内存分配情况、gdb dump 出具体内存信息、perf 查看本地函数调用等。   4、 如果 CPU 和 内存使用率都很正常,那就需要进一步开启 GC 日志,分析用户线程暂停的时间、各部分内存区域 GC 次数和时间等指标,可以借助 jstat 或可视化工具 GCeasy 等,如果问题出在 GC 上面的话,考虑是否是内存不够、根据垃圾对象的特点进行参数调优、使用更适合的垃圾收集器;分析 jstack 出来的各个线程状态。如果问题实在比较隐蔽,考虑是否可以开启 jmx,使用 visualmv 等可视化工具远程监控与分析。   5、你是如何理解fiber的?   React Fiber 是一种基于浏览器的单线程调度算法.   React 16之前 , 算法实际上是递归,想要中断递归是很困难的,React 16 开始使用了循环来代替之前的递归.   :一种将 (递归 diff),拆分成无数个小任务的算法;它随时能够停止,恢复。停止恢复的时机取决于当前的一帧(16ms)内,还有没有足够的时间允许计算。Fiber 详解   6、HashMap的扩容操作是怎么实现的?   1、 在jdk1.8中,resize方法是在hashmap中的键值对大于阀值时或者初始化时,就调用resize方法进行扩容;   2、 每次扩展的时候,都是扩展2倍;   3、 扩展后Node对象的位置要么在原位置,要么移动到原偏移量两倍的位置。   在putVal()中,我们看到在这个函数里面使用到了2次resize()方法,resize()方法表示的在进行第一次初始化时会对其进行扩容,或者当该数组的实际大小大于其临界值值(第一次为12),这个时候在扩容的同时也会伴随的桶上面的素进行重新分发,这也是JDK1.8版本的一个优化的地方,在1.7中,扩容之后需要重新去计算其Hash值,根据Hash值对其进行分发,但在1.8版本中,则是根据在同一个桶的位置中进行判断(e.hash & oldCap)是否为0,重新进行hash分配后,该素的位置要么停留在原始位置,要么移动到原始位置+增加的数组大小这个位置上   7、解释如何使用WAR文件部署web应用程序?   在Tomcat的web应用程序目录下,jsp、servlet和它们的支持文件被放置在适当的子目录中。你可以将web应用程序目录下的所有文件压缩到一个压缩文件中,以.war文件扩展名结束。你可以通过在webapps目录中放置WAR文件来执行web应用程序。当一个web服务器开始执行时,它会将WAR文件的内容提取到适当的webapps子目录中。   8、常用的并发工具类有哪些?   1、 CountDownLatch   2、 CyclicBarrier   3、 Semaphore   4、 Exchanger   9、你能保证 GC 执行吗?   不能,虽然你可以调用 System.gc() 或者 Runtime.gc(),但是没有办法保证 GC 的执行。   10、哪些集合类是线程安全的?   1、 Vector:就比Arraylist多了个 synchronized (线程安全),因为效率较低,现在已经不太建议使用。   2、 hashTable:就比hashMap多了个synchronized (线程安全),不建议使用。   3、 ConcurrentHashMap:是Java5中支持高并发、高吞吐量的线程安全HashMap实现。它由Segment数组结构和HashEntry数组结构组成。Segment数组在ConcurrentHashMap里扮演锁的角色,HashEntry则用于存储键-值对数据。一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构;一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的素;每个Segment守护着一个HashEntry数组里的素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。(推荐使用)   11、事务的ACID是指什么?   12、对象分配规则   13、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?   14、创建对象的过程是什么?   15、&和&&的区别   16、为什么wait(), notify()和notifyAll ()必须在同步方法或者同步块中被调用?   17、Java中的继承是单继承还是多继承   18、Java 中,如何将字符串 YYYYMMDD 转换为日期?   19、请你谈谈对OOM的认识   20、CopyOnWriteArrayList可以用于什么应用场景?   21、什么时候使用享模式?   22、什么是Executors?   23、死锁与活锁的区别,死锁与饥饿的区别?   24、堆的作用是什么?   25、垃圾回收的优点和原理。说说2种回收机制   26、React如何进行组件/逻辑复用?   27、请解释一下MAC代表什么?   28、ThreadLocal是什么?有什么用?   29、线程的生命周期?   30、说几个常见的编译时异常类?   31、Java 如何实现多线程之间的通讯和协作?   32、什么是Java Timer 类?如何创建一个有特定时间间隔的任务?   33、使用js一个表单素   34、多线程同步和互斥有几种实现方法,都是什么?   35、什么是重排序   36、Java 中 java.util.Date 与 java.sql.Date 有什么区别?   37、说说类加载的过程   38、React最新的生命周期是怎样的?   39、复制算法(copying)   40、用Java的套接字编程实现一个多线程的回显(echo)服务器。   全部答案,整理好了,直接下载吧   https://mp.weixin.sigusoft.com/s/TMBjoux5tpcqmbEFR-pDrA   下载链接:全部答案,整理好了

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/48590.html

(0)
上一篇 2024年 9月 4日
下一篇 2024年 9月 4日

相关推荐

关注微信