【牛客面经】快手Java一面 4.17

1、进程和线程区别;什么是上下文;什么中断;
进程是操作系统分配资源的最小单位,线程是CPU调度分配的最小单位。一个程序运行就是一个进程,进程拥有独立的一套变量,一个进程至少有一个线程,线程间可共享数据。
一个进程拥有多个线程时,这个任务就是多线程任务。多个线程切换执行时,需要切换上下文,即切换线程环境,将线程变量出栈入栈;
中断是停止程序运行的一种方式。可以发中断信号停止正在运行的进程,也可以发送中断信号停止正在运行的线程。当线程没有阻塞时,收到中断信号,它会停止该线程,并抛出一个中断异常;当线程阻塞时,它就不会响应中断信号。
AI回答:

进程(Process)是操作系统分配资源的基本单位,每个进程都有独立的内存空间,包含程序运行时所需的数据、代码以及资源。进程之间相互独立,彼此之间不能直接访问对方的内存空间,通信需要通过额外的机制。
线程(Thread)是进程中的一个执行单元,同一进程中的多个线程共享同一内存空间和资源,可以直接访问同一进程中的其他线程所拥有的资源。因此,线程之间的切换开销比进程之间小,能更快地实现并发操作。
简而言之,进程之间是相互独立的,而线程是属于同一个进程,共享进程的资源。进程拥有独立的内存空间,而线程共享内存空间。在实际编程中,使用多线程可以更高效地利用计算资源,但也需要注意线程安全等问题。

上下文(Context)通常指的是每个线程在执行过程中所需的状态和环境信息。这包括了线程的程序计数器、寄存器内容、堆栈信息、线程私有的变量值等。
当操作系统调度器在不同线程之间进行切换时,它需要保存当前线程的上下文信息,以便稍后能够正确地恢复该线程的执行状态。这个过程通常包括:
保存当前线程的上下文:这包括将当前线程的程序计数器、寄存器内容、堆栈指针等信息保存到内存中,以便稍后能够恢复。
加载下一个线程的上下文:从线程调度器中选择下一个要执行的线程,并将其保存的上下文信息加载到处理器中,以便开始执行该线程。
这样的上下文切换过程可以让多个线程在同一处理器上交替执行,从而实现并发执行的效果。因为上下文切换涉及到保存和加载大量的状态信息,所以它会消耗一定的系统资源,而过多的上下文切换也可能会影响系统的性能。因此,在编写多线程程序时,需要注意减少上下文切换的次数,以提高系统的效率

在Java中,线程中断是通过中断标识来管理的。当一个线程被中断时,会设置线程的中断标识为true。Java提供了一些方法和机制来处理线程的中断,例如:

  1. Thread类的interrupt()方法:通过调用线程对象的interrupt()方法可以请求中断线程。这个方法会将线程的中断标识设置为true,但并不会立即停止线程的执行。通常在程序中通过这个方法来请求线程停止执行。
  2. Thread类的isInterrupted()方法:通过调用线程对象的isInterrupted()方法可以检查线程的中断状态。可以使用这个方法在进行长时间操作时检查是否被中断,并采取相应措施做清理工作。
  3. Thread类的interrupted()静态方法:通过调用Thread.interrupted()静态方法可以检查当前线程的中断状态,并且清除中断状态(即将中断标识设置为false)。
  4. 捕获InterruptedException异常:在Java中的一些阻塞方法(如Object.wait(), Thread.sleep(), Thread.join()等)在发生中断时会抛出InterruptedException异常,通过捕获这个异常可以处理中断情况,进行相应的处理和清理工作。
    在处理线程中断时,通常建议在中断发生时优雅地停止线程,做一些善后工作。可以通过检查线程的中断状态,并根据情况做出相应的处理,让线程能够安全地停止运行。

2、数组和链表区别;为什么数组查询的复杂度为O(1);数组每个单元存放的元素大小
数组底层是一块连续存储的单元,取值时,只需要计算偏移地址,直接取值就行,所以数组查询的复杂度为O(1);链表是离散的存储单元,上一个存储单元会记录下一个存储单元的地址,易于扩展,链表读值只能顺序读,不能随机读,所以链表查询的复杂度为O(1)
AI回答:

当谈及数组和链表时,这两者是常见的数据结构,它们有一些显著的区别:

  1. 存储方式
  • 数组:数组是一种连续的内存数据结构,其元素在内存中是依次存储的,可以通过索引来直接访问任何元素。
  • 链表:链表是由节点构成的数据结构,每个节点包含数据和指向下一个节点的指针,节点在内存中不一定是连续存储的,通过指针来连接节点。
  1. 插入和删除操作
  • 数组:在数组中插入或删除元素时,需要移动后面的元素以保持顺序,这可能导致时间复杂度为O(n)的操作。
  • 链表:链表在插入和删除节点时效率较高,只需要修改指针即可,时间复杂度可以达到O(1),除非需要定位到插入或删除的位置。
  1. 查找操作
  • 数组:数组支持随机访问,可以根据索引快速访问指定位置的元素,时间复杂度为O(1)。
  • 链表:链表不支持随机访问,必须从头节点开始逐个访问,查找元素的时间复杂度为O(n)。
  1. 空间复杂度
  • 数组:数组在创建时需要预留一定大小的内存空间,因此可能存在空间浪费的情况。
  • 链表:链表在插入和删除时可动态分配内存,灵活利用内存空间。
    数组适合需要随机访问元素的情况,而链表适合频繁的插入和删除操作。

数组查询的时间复杂度为O(1)是因为数组中的元素是连续存储的,并且每个元素在内存中的位置可以通过简单的数学计算得出。具体来说,在计算机内存中,数组的数据存储是线性的,即通过一个起始地址和偏移量即可确定任何一个元素的位置。

在Java中,每个基本数据类型的大小是规定好的,并且是独立于底层系统的。这些大小在不同的编程语言或平台中可能会有所不同。当创建一个数组时,每个单元将被分配固定大小的存储空间,这是由Java虚拟机(JVM)来管理的。
对于引用类型(如类、接口、数组),数组中的每个元素存储的是引用,这个引用指向对象实例在堆内存中的位置,而不是对象本身。因此,无论引用类型的大小如何,数组的元素大小都是存储引用的大小(通常是4字节或8字节,取决于虚拟机的具体实现)。

3、JVM是什么;Java为什么是跨平台的;Java为什么既是编译型也是解释型的;
JVM是Java虚拟机,主要将编译后Java字节码运行在操作系统上,充当中间层,起到解释代码的作用。由于JVM的存在,它会针对不同的操作系统,将字节码解释成对应操作系统的汇编指令,这样就实现了“一处编译,到处运行的效果”,即Java的跨平台性。这里也体现了Java的编译、解释的两个过程。

AI回答:

JVM(Java Virtual Machine,Java虚拟机)是Java平台的关键组成部分之一,它是一个运行在实际计算机硬件上的虚拟计算机,用于执行Java字节码(bytecode)。

JVM的主要功能包括:

  1. 字节码执行:JVM负责将编译后的Java源代码转换为字节码,并执行这些字节码。字节码是一种与平台无关的中间代码,通过字节码的方式,Java程序可以在任何安装了Java虚拟机的平台上运行。
  2. 内存管理:JVM负责Java程序的内存管理,包括分配和释放内存,以及垃圾回收。Java中的自动内存管理(垃圾回收)通过JVM实现,这使得开发人员可以更专注于业务逻辑而不必过多关注内存管理细节。
  3. 垃圾回收:JVM中的垃圾回收器负责回收不再使用的内存空间,释放已分配但不再需要的对象,以避免内存泄漏和提高内存利用率。
  4. 即时编译(JIT):JVM中的即时编译器(Just-In-Time Compiler)负责将字节码实时编译成本地机器码,以提高程序的执行效率。通过即时编译,JVM可以将频繁执行的代码片段优化为本地机器码,从而减少执行时间。
  5. 异常处理:JVM提供了异常处理机制,能够捕获和处理Java程序中的异常,确保程序的健壮性和稳定性。
    总的来说,JVM作为Java平台的核心组件,为Java程序提供了一个可移植、安全、高性能的运行环境。它的存在使得Java程序可以在各种不同的操作系统和硬件平台上运行,实现了"一次编写,到处运行"的理念。

Java被称为跨平台(Platform-Independent)的主要原因是由于其使用了Java虚拟机(JVM)和字节码(Bytecode)的设计。以下是一些导致Java跨平台特性的主要原因:

  1. 字节码和JVM:Java编译器将Java源代码编译成字节码,而不是机器码。这些字节码是一种与特定平台无关的中间码。JVM负责在不同的平台上解释这些字节码并执行对应的操作,从而使Java程序能够在不同的操作系统上运行。
  2. JVM的实现:Java虚拟机是特定于每个平台的,它负责在特定平台上解释和执行字节码。因此,只需要为特定平台编写JVM的实现,而不需要修改Java程序本身就可以在不同平台上运行。
  3. 标准化:Java的平台被规范化和标准化。这保证了Java程序在不同平台上有一致的行为。无论是在Windows、macOS还是Linux等平台上,Java程序应该具有相同的功能和性能。
  4. 库的一致性:Java提供了丰富的标准类库(Standard Library),这些类库是独立于平台的。Java程序可以调用这些类库,而无需担心底层的操作系统差异。
  5. 虚拟机中间层:JVM作为Java程序和底层操作系统之间的中间层,隐藏了不同操作系统之间的差异,提供了一个统一的运行环境。
  6. 安全性:由于Java程序运行在JVM上,Java提供了安全性机制来控制Java程序的行为,确保程序不会对底层操作系统造成损害。
    总的来说,Java的跨平台特性是通过字节码和虚拟机的设计来实现的,使得Java程序具有了很强的可移植性和跨平台能力。

Java通常被描述为一种既是编译型又是解释型的语言,这是因为Java的执行过程涉及到两种不同类型的编译和执行:
编译型:Java源代码首先经过编译器(javac)编译成字节码文件(.class文件)。这个过程将源代码翻译成字节码,但字节码并非直接在操作系统上执行的机器码。这个过程属于编译型语言的特性。
解释型:Java虚拟机(JVM)负责在运行时解释并执行字节码。JVM会逐行解释字节码并将其转换为特定平台上的机器码,或者使用即时编译器(Just-In-Time Compiler,JIT)将字节码编译成本地机器码来提高性能。这种动态解释和编译的过程使得Java在某种程度上也具有解释型的特性。
综上所述,Java在编译阶段将源代码编译成中间字节码,这是编译型语言的一部分,然后在运行时通过JVM进行解释和执行字节码,这是解释型语言的一部分。这种组合使得Java具有编译型和解释型语言的优点,包括跨平台特性、即时编译优化等。
需要注意的是,随着技术的发展,现代的JIT编译器越来越强大,可以将热点代码直接编译为本地机器码,从而提高Java程序的性能。这也是Java在实际运行中通常表现出更接近编译型语言的特性。

4、除了Java还熟悉什么语言(我说的Python);Python和Java区别;
Python是强类型,解释型脚本语言,具有非常强的灵活性;
Java是弱类型语言,兼具编译、解析一体的语言,具有一次编译,多处运行的跨平台优势。
5、了解HashMap吗;HashMap插入元素过程
HashMap底层是由红黑树实现的,在插入过程中,会先计算key的哈希值,再放入对应桶中,如果桶里已经有元素了,将拉出一条外链,在链表中插入value
6、重写HashMap的equal和hashcode方法需要注意什么;重写HashMap的equal方法不当会出现什么问题;
重写equal方法必须重写hashcode方法,保证equal相等时,它们的hash值必须相等,同时,equal、hashcode方法必须具有对称性,即a=b,b=a也必须成立。equal方法重写不当时,如果是本是相等,hashcode不等,则会导致逻辑异常;如果是本是不等,hashcode一直相等,则会导致哈希冲突,不相等的值,一直进入equal逻辑判断,造成额外开销。
7、列举HashMap在多线程下可能会出现的问题;
HashMap是线程不安全的,不安全性主要体现在,多个线程读写同一个map时,当一个线程判断这个key不存在,则更新key对应的值;另一个线程也做同样的操作,结果两个线程都同时判断出这个key不存在,都同时更新了这个key对应的值,导致最后key的值不符合预期。
8、synchronized关键字的底层原理;
synchronized作用在变量上,可使变量线程可见。底层主要是读写屏障实现的,当被synchronized作用的变量值发生变化时,对其它线程的读屏障全部屏蔽,这样,其它线程都可读取该变量的最新值。
9、线程池了解吗;有哪些常见参数;线程池工作队列满了有哪些拒接策略;
线程池是优化线程资源的手段,通过池化技术,复用先前的线程,减少创建线程的开销,增加代码运行的效率。
对线程池常见的参数,有设置线程池工作线程大小,表示的是线程池工作的线程数量;
最大可用线程大小,表示的是,当任务队列满时,会开启最大线程处理的数量;
线程最大存活时间,表示的是,空闲时,一个线程自然消亡的时间;
队列大小,表示的是,最大存积任务数,队列满时,会启动最大线程数进行处理;
拒绝策略,表示的是,启动最小线程数满时,任务队列还是满了,应该采取的策略。
常见的拒绝策略有,直接丢弃、抛出异常、当前主线程进行处理。
10、有线程池参数设置的经验吗,都设置过哪些参数
以上线程池参数均有设置过,一般线程池工作线程大小设为 2 * CPU + 1;最大可用线程大小设为工作线程的1.5倍,线程最大存活时间为60s,队列大小根据业务并发提交的任务数进行判断,常设为50,拒绝策略一般设为当前主线程进行处理。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值