JAVA面试部分——后端-线程后篇

这篇具有很好参考价值的文章主要介绍了JAVA面试部分——后端-线程后篇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

3.12 如果在运行当中,遇到线程不够了,会以什么样的方式创建线程

线程池在运行过程中,如果遇到线程不够的情况,会根据线程池的类型和配置进行不同的处理:

  • 对于固定大小的线程池:如果线程因异常结束,会有一个新的线程来替代它。线程池的大小一旦达到最大值就会保持不变。

  • 对于可缓存的线程池:线程池的大小超过了任务所需要的线程,就会回收部分空闲的线程。当任务数增加时,此线程池又可以智能地添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

无论哪种类型的线程池,当需要执行新的任务但所有线程都在忙时,任务会被放入等待队列中,等待其他线程空闲后执行。如果等待队列也已满,且系统允许创建新线程,那么线程池会创建新的线程来处理该任务。如果系统不允许创建新线程,则根据拒绝策略来处理该任务。

3.13 Java多线程引发的问题?

Java多线程可能引发以下问题:

  • 内存资源耗尽:Java中每个线程都会占用一部分内存空间,当线程数过多时,会导致系统内存资源的消耗增加。如果系统内存无法满足所有线程所需的内存,则会引发OutOfMemoryError异常,在这种情况下,系统很可能会崩溃或死锁。

  • CPU资源利用率降低:过多的线程数会使CPU在调度线程时的负担增加。因为在任何时刻,CPU只有一个核心可以执行线程代码,当线程数过多时,CPU在不停地切换线程上下文,导致CPU利用率低下,从而降低系统性能。

  • 线程安全问题:访问共享的变量或资源,会有并发风险,这里的共享变量或资源指的是:对象的属性,静态变量,共享缓存,数据库等等。所有依赖时序的操作,即使每一步操作都是线程安全的,但是如果存在操作时序不对,比如操作的数据变量未初始化完成,依旧会产生并发问题。

  • 性能问题:从某种程度上来讲,多线程可以提高复杂的运算效率,但是一定程度上多线程可能会带来性能提交上下文切换。线程运行个数超过CPU核心数的时候,CPU就需要对线程进行调度,线程调度中就涉及线程切换,线程的切换的开销是很大的,CPU需要保存当前线程的运行场景,将当前线程的当前运行状态保存好,为载入新的运行线程做准备。这样来来回回其实是很耗费性能的。

为了避免这些问题,需要合理地配置和管理线程资源,确保线程的数量和优先级符合系统的需求和限制。同时,在编写涉及多线程的代码时,需要特别注意线程安全和同步问题,以避免出现竞态条件和数据不一致的问题。

3.14 并行与并发

并行是指多个任务在同一时间段内同时发生,这些任务可能由不同的处理器或者多核CPU来处理。并行通常可以显著提高程序的执行效率,因为它可以同时处理多个任务,而不是在一段时间内依次处理。在并行的情况下,不同的任务可以独立执行,不需要等待其他任务的处理。只有在多处理器或多核的机器上才能真正实现并行。

并发则是指多个任务在同一时间段内交替执行,从外部看来这些任务是同时进行的。并发通常通过在一个时间段内划分成若干个时间片段,然后在这些时间片段中依次执行每个任务来实现。这种方式可以减少等待时间,提高程序的响应速度。例如,在单处理器上运行的程序,通过合理的调度可以使得多个任务交替执行,实现并发的效果。但是,并发仍然需要等待某些任务的时间片段,因此其执行速度仍然受到一定的限制。

简而言之,并行是多个任务同时发生,并发是多个任务交替发生。并行更多地涉及到硬件的并行处理能力,而并发更多地涉及到软件的调度和执行策略。

3.15 多线程访问多个接口的时候怎么保证效率,比如访问A接口2s,B接口3s,如何优化?

在多线程访问A接口和B接口的情况下,可以采取以下优化措施:

  • 使用异步访问:对于需要等待较长时间的接口访问,例如B接口需要等待3秒,可以使用异步访问方式。这样主线程不会被长时间阻塞,可以继续执行其他任务,从而提高整体效率。

  • 合并接口访问:如果A接口和B接口之间存在依赖关系,可以将它们合并在一起进行访问。例如,可以先访问A接口,然后紧接着访问B接口,从而减少总的等待时间。

  • 使用线程池:通过线程池提供的一组线程来处理多个接口的访问请求。线程池可以重复利用已创建的线程,减少创建和销毁线程的开销,提高效率。

  • 优化网络连接:对于网络连接的优化,可以采取一些措施,如使用长连接、减少网络跳转等。这样可以减少网络通信的开销和时间,提高效率。

  • 缓存技术:对于频繁访问的接口,可以使用缓存技术。将已经获取的数据存储在缓存中,避免重复请求相同的接口,从而减少访问时间和网络开销。

综上所述,通过异步访问、合并接口访问、使用线程池、优化网络连接和采用缓存技术等措施,可以优化多线程访问A接口和B接口时的效率。具体优化方案需要根据实际情况进行选择和调整。

3.16 多线程去做io操作,Copy文件如何实现?

在多线程环境下进行文件复制操作可以提高效率,因为可以同时处理多个文件。下面是一种可能的实现方式:

  • 创建一个线程池,线程池的大小根据系统的硬件资源和文件数量来决定。

  • 将需要复制的文件分成多个批次,每个批次包含一定数量的文件。

  • 对于每个批次,向线程池提交一个任务,该任务负责复制该批次的文件。

  • 在每个任务中,使用操作系统提供的文件复制函数(如Java中的File.copy或Java的nio包中的FileChannel.transferTo方法)来复制文件。

  • 在复制过程中,可以设置线程的优先级为低,以避免复制操作占用过多资源导致系统响应缓慢。

  • 等待所有任务完成,完成后的文件可以通过某种方式进行合并,例如使用文件锁或者合并工具。

需要注意的是,在多线程复制文件时,需要确保文件的完整性和一致性。例如,如果一个文件正在被其他程序修改,可能会导致复制操作失败或者复制的文件不完整。因此,在复制前应该检查文件的完整性和一致性,或者等待文件被修改完成后再次尝试复制。

另外,还需要注意文件名冲突的问题。如果多个线程同时复制同一个目录下的文件,可能会出现文件名冲突的情况。可以通过重命名文件或者使用不同的目录来避免这种情况。

总之,多线程复制文件可以提高效率,但需要注意文件的完整性和一致性,以及避免文件名冲突的问题。

3.17 如何杀掉线程或进程?

在程序中终止线程或进程是一个需要谨慎处理的问题,因为如果处理不当,可能会导致程序崩溃或出现其他问题。以下是几种终止线程或进程的最佳方式:

  • 线程同步:使用各种线程同步机制,如信号量、事件等,来控制线程的执行。通过等待或通知线程继续执行,可以安全地终止线程。

  • 异常处理:在线程或进程中抛出异常,导致线程或进程终止。但是,这种方式可能导致程序崩溃或出现其他问题,因此不推荐使用。

  • 正常结束:通过在线程或进程的代码中添加退出条件,使其在满足条件时自动结束执行。这种方式是最安全和最推荐的方式。

  • 操作系统命令:在操作系统级别使用命令来终止线程或进程。例如,在Linux系统中,可以使用kill命令来终止进程。但是,这种方式可能会导致程序崩溃或出现其他问题,因此不推荐使用。

总之,最佳的终止线程或进程的方式是使用线程同步机制和正常结束执行。如果必须使用异常处理或操作系统命令来终止线程或进程,应该谨慎处理,以避免出现程序崩溃或其他问题。

3.18 AQS有了解吗?

Java中的AQS(AbstractQueuedSynchronizer)是一个用于实现并发同步的工具类,它提供了一种实现同步器的框架和实现方式。AQS的核心思想是利用一个先进先出(FIFO)的双向队列来管理线程的竞争和等待。它可以用于实现诸如ReentrantLock、Semaphore、CountDownLatch等同步工具类。

以下是一些AQS的应用:

  • ReentrantLock:ReentrantLock是一个可重入的互斥锁,它使用AQS来实现锁的功能。在ReentrantLock的实现中,通过继承AQS类并实现其抽象方法,利用state和exclusiveOwnerThread两个状态变量来实现加锁和解锁操作。

  • CountDownLatch:CountDownLatch是一个等待其他线程完成的操作,它使用AQS来实现等待操作。CountDownLatch内部维护了一个计数器,当计数器为0时,await()方法返回。而countDown()方法则用来减少计数器的值。

  • Semaphore:Semaphore是一个计数信号量,它使用AQS来实现信号量的功能。如果计数器为0,acquire()方法会阻塞,直到其他线程释放许可证。

除了上述应用之外,AQS还可以用于实现其他类型的同步工具类,如StampedLock等。总之,AQS是Java并发编程中的一个重要组成部分,它提供了一种灵活、高效的方式来实现并发同步。

3.19 说一下 synchroinzed 锁膨胀?

"synchronized"是Java中的一个关键字,用于实现同步。它提供了一种互斥的机制,确保同一时刻只有一个线程可以执行某个方法或代码块。然而,在实际应用中,由于一些情况可能会导致synchronized锁膨胀,进而影响程序的性能。

锁膨胀是指随着系统并发量的增加,锁的持有时间变长,锁的竞争加剧,导致需要更多的内存空间和CPU资源。在Java中,synchronized锁的膨胀通常表现为对象头中的Mark Word的膨胀。

当一个线程持有锁时,该锁会占用一个Mark Word,其中包含了一些元信息,如锁的持有状态、线程持有锁的时间等。随着并发量的增加,线程持有锁的时间变长,Mark Word中的元信息也会不断增加,从而导致Mark Word的膨胀。

锁膨胀会对程序的性能产生负面影响,因为它会增加内存占用和CPU的开销。当锁竞争激烈时,线程需要频繁地获取和释放锁,导致CPU的上下文切换和内存访问的开销增加,进而影响程序的性能。

为了避免锁膨胀对程序性能的影响,可以考虑使用其他并发控制机制,如使用CAS操作实现无锁算法、使用读写锁等。此外,也可以通过合理地设计程序的并发模型、减少锁的持有时间、避免锁的过度使用等方式来降低锁竞争和锁膨胀的风险。

3.20 锁的一些方法及使用

在Java中,常用的锁机制有synchronized和Lock接口。它们提供了一些方法和使用方式,可以用于实现互斥和并发控制。

  • synchronized:

    1. 使用方式:在方法或代码块前加上synchronized关键字即可。

    2. 实现方式:通过对象头中的Mark Word标识锁的持有状态,如果Mark Word的值为0,表示未加锁;如果Mark Word的值不为0,表示持有锁,其他线程需要等待该线程释放锁。

    3. 优点:自动获取和释放锁,使用简单;支持多个监视器(monitor)锁,允许多个线程同时持有锁。

    4. 缺点:不支持可重入性,即一个线程不能重复获取同一个锁;性能较差,因为需要使用对象头中的Mark Word来标识锁的持有状态。

  • Lock接口:

    1. 使用方式:创建一个Lock接口的实现类(如ReentrantLock),然后使用该实现类来加锁和解锁。

    2. 实现方式:通过实现Lock接口中的lock()和unlock()方法来实现加锁和解锁操作。

    3. 优点:支持可重入性,即一个线程可以多次获取同一个锁;性能较好,因为不需要使用对象头中的Mark Word来标识锁的持有状态。

    4. 缺点:需要手动获取和释放锁,使用较为繁琐;不支持多个监视器(monitor)锁,只能有一个线程持有锁。

除了synchronized和Lock接口之外,Java还提供了一些其他的锁机制,如读写锁(ReadWriteLock)、信号量(Semaphore)等。它们各有优缺点,可以根据具体的场景选择合适的锁机制。

3.21 什么是函数式接口,结构上有什么特点,能声明其他东西吗,默认方法有什么?

函数式接口是Java中的一种接口,它只包含一个抽象方法。在Java 8及以后的版本中,函数式接口被用于支持Lambda表达式和函数式编程。

函数式接口在结构上的特点如下:

  1. 只包含一个抽象方法。

  2. 可以包含默认方法和静态方法。

  3. 使用@FunctionalInterface注解进行标识,以确保它符合函数式接口的规范。

除了抽象方法之外,函数式接口还可以声明默认方法和静态方法。默认方法允许在接口中提供方法的默认实现,可以被实现接口的类选择性重写。静态方法则允许在接口中定义与接口本身相关的一些工具方法,类似于工具类的功能。

函数式接口的抽象方法可以用Lambda表达式或方法引用来实现。Lambda表达式是一种简洁的匿名函数写法,可以用来实现函数式接口的抽象方法。方法引用则是指引用现有方法,并传递给其他函数或对象。

默认方法允许在接口中提供默认实现,可以被实现接口的类选择性重写。默认方法主要用于在不影响现有代码的情况下添加新的功能,或者为旧版接口提供新的实现方式。

总之,函数式接口是Java中用于支持函数式编程的一种特殊接口,它只包含一个抽象方法,但可以包含默认方法和静态方法。函数式接口的抽象方法可以用Lambda表达式或方法引用来实现,而默认方法则允许在接口中提供默认实现。

3.22 什么情况会导致内存泄露

在Java中,以下是一些可能导致内存泄露的情况:

  1. 静态变量:如果静态变量引用了一个对象,而这个对象没有被其他变量引用,那么这个对象将无法被垃圾回收器回收,从而导致内存泄露。

  2. 监听器:如果一个对象持有监听器,但该对象本身被垃圾回收器回收,而监听器没有被正确取消,那么就会造成内存泄露。

  3. 集合类:如果集合类中存储了大量的对象,而这些对象没有被正确释放,那么就会造成内存泄露。

  4. 缓存:如果缓存中存储了大量的对象,而这些对象没有被正确释放,那么就会造成内存泄露。

  5. 未关闭的资源:如果程序中打开了一些资源(如数据库连接、文件流等),但未及时关闭,就会造成内存泄露。

为了避免内存泄露,程序员需要正确使用Java的内存管理机制,如使用弱引用、及时关闭资源、正确处理监听器等。同时,也可以使用一些工具来检测和修复内存泄露,如Java的内存分析工具(Memory Analyzer Tool,MAT)等。文章来源地址https://www.toymoban.com/news/detail-816937.html

到了这里,关于JAVA面试部分——后端-线程后篇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA面试部分——后端-数据库前篇

    5.1 mysql中char和varchar的区别,varchar(100)中的一百的含义,能存放多少汉字? 在MySQL中,CHAR和VARCHAR都是用来存储字符串的数据类型,但它们之间存在一些主要区别。 存储方式:CHAR是固定长度的,而VARCHAR是可变长度的。这意味着CHAR会根据你设定的长度存储字符串,即使实际

    2024年01月16日
    浏览(41)
  • Java后端开发面试题——框架篇

    Spring框架中的bean是单例的吗?Spring框架中的单例bean是线程安全的吗? singleton : bean在每个Spring IOC容器中只有一个实例。 prototype:一个bean的定义可以有多个实例。 Spring bean并没有可变的状态(比如Service类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的 如果在bean中定

    2024年02月12日
    浏览(42)
  • Java后端开发面试题篇——Redis

    Redis的数据持久化策略有哪些 RDB的执行原理? bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。 fork采用的是copy-on-write技术: 当主进程执行读操作时,访问共享内存; 当主进程执行写操作时,则会拷贝一份数据,执

    2024年02月12日
    浏览(36)
  • Java后端开发面试题——消息中间篇

    RabbitMQ-如何保证消息不丢失 交换机持久化: 队列持久化: 消息持久化 ,SpringAMQP中的的消息默认是持久的,可以通过MessageProperties中的DeliveryMode来指定的  消费者确认 manual:手动ack,需要在业务代码结束后,调用api发送ack。 auto:自动ack,由spring监测listener代码是否出现异常

    2024年02月11日
    浏览(37)
  • 华创云鼎面试:java后端开发

    华创云鼎面试: 1、项目:项目业务介绍、项目人员组成 2、分布式锁用过哪些 基于数据库的锁:可以使用关系型数据库的事务和行级锁来实现分布式锁。通过在数据库中创建一个标志位或特定的锁表来表示资源的锁定状态,其他进程在访问该资源之前需要先获取该锁。这种方法

    2024年02月12日
    浏览(37)
  • JAVA后端开发面试基础知识(八)——Spring

    Spring是一个轻量级Java开发框架 我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发,比如说 Spring 支持 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、

    2024年03月10日
    浏览(71)
  • JAVA后端开发面试基础知识(一)——JVM

    Class loader(类装载) 根据给定的全限定名类名(如: java.lang.Object)来装载class文件到 Runtime data area中的method area。 Execution engine(执行引擎) 执行classes中的指令。 Native Interface(本地接口) 与native libraries交互,是其它编程语言交互的接口。 Runtime data area(运行时数据区域) 这就是我们常说

    2024年03月10日
    浏览(58)
  • Java后端开发面试题——JVM虚拟机篇

    目录 什么是程序计数器? 你能给我详细的介绍Java堆吗? 什么是虚拟机栈 1. 垃圾回收是否涉及栈内存? 2. 栈内存分配越大越好吗? 3. 方法内的局部变量是否线程安全? 4.什么情况下会导致栈内存溢出? 5.堆栈的区别是什么? 能不能解释一下方法区(元空间)? 常量池 运行

    2024年02月09日
    浏览(39)
  • 程序员/后端开发方向Java 跳槽注意事项(简历和面试经验分享)

    程序员/后端开发方向Java 跳槽注意事项(简历和面试经验分享) 应届生面试经验参考:https://www.cnblogs.com/rainbow-1/p/16779048.html 简历: 1、个人感觉还是要写真话,包装的内容要有一定的基础,问起来能够对答几个回合。 2、基本信息最好直接写年龄,而不是出生年月。跳槽简历

    2024年04月08日
    浏览(76)
  • 【Java】后端开发语言Java和C#,两者对比注解和属性的区别以及作用

    欢迎来到《小5讲堂》 大家好,我是全栈小5。 这是《Java》序列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。 温馨提示:博主能力有限,理解水平有限

    2024年01月16日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包