Java常见面试题总结

文章目录

  • 1. 什么是线程和进程?
  • 2. 请简要描述线程与进程的关系,区别及优缺点?
  • 3. 什么是堆和方法区?
  • 4. 并发与并行的区别
  • 5. 同步和异步的区别
  • 6.为什么要使用多线程? 优点?(重要)
  • 7. 使用多线程可能带来什么问题?
  • 8. 如何理解线程安全和不安全?
  • 9. 单核 CPU 上运行多个线程效率一定会高吗?
  • 10. 如何创建线程?(重要)
  • 11. 说说线程的生命周期和状态?(重点)
  • 12. 什么是线程上下文切换?
  • 13. 什么是线程死锁?如何避免死锁?
  • 14. 可以直接调用 Thread 类的 run 方法吗?
  • 15. 乐观锁和悲观锁
  • 16. synchronized 关键字
  • 17. 共享锁和独占锁有什么区别?
  • 18. StringBuilder和StringBuffer区别(重要)
  • 19. MAP(重要)
    • 19.1 HashMap 和 Hashtable 的区别
    • 19.2 HashMap 的底层实现
  • 20. ArrayList 和 LinkedList 的区别 (重要)

1. 什么是线程和进程?

  • 何为进程?
    进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
  • 何为线程?
    线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间做切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

2. 请简要描述线程与进程的关系,区别及优缺点?

线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。

3. 什么是堆和方法区?

堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象 (几乎所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

4. 并发与并行的区别

  • 并发:两个及两个以上的作业在同一 时间段 内执行。
  • 并行:两个及两个以上的作业在同一 时刻 执行。

最关键的点是:是否是 同时 执行。

5. 同步和异步的区别

  • 同步:发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。
  • 异步:调用在发出之后,不用等待返回结果,该调用直接返回。

6.为什么要使用多线程? 优点?(重要)

先从总体上来说:

  • 从计算机底层来说: 线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
  • 从当代互联网发展趋势来说: 现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。

再深入到计算机底层来探讨:

  • 单核时代:在单核时代多线程主要是为了提高单进程利用 CPU 和 IO 系统的效率。 假设只运行了一个 Java 进程的情况,当我们请求 IO 的时候,如果 Java 进程中只有一个线程,此线程被 IO 阻塞则整个进程被阻塞。CPU 和 IO 设备只有一个在运行,那么可以简单地说系统整体效率只有 50%。当使用多线程的时候,一个线程被 IO 阻塞,其他线程还可以继续使用 CPU。从而提高了 Java 进程利用系统资源的整体效率。
  • 多核时代: 多核时代多线程主要是为了提高进程利用多核 CPU 的能力。举个例子:假如我们要计算一个复杂的任务,我们只用一个线程的话,不论系统有几个 CPU 核心,都只会有一个 CPU 核心被利用到。而创建多个线程,这些线程可以被映射到底层多个 CPU 上执行,在任务中的多个线程没有资源竞争的情况下,任务执行的效率会有显著性的提高,约等于(单核时执行时间/CPU 核心数)。

7. 使用多线程可能带来什么问题?

并发编程的目的就是为了能提高程序的执行效率进而提高程序的运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题,比如:内存泄漏、死锁、线程不安全等等。

8. 如何理解线程安全和不安全?

线程安全和不安全是在多线程环境下对于同一份数据的访问是否能够保证其正确性和一致性的描述。

  • 线程安全指的是在多线程环境下,对于同一份数据,不管有多少个线程同时访问,都能保证这份数据的正确性和一致性。
  • 线程不安全则表示在多线程环境下,对于同一份数据,多个线程同时访问时可能会导致数据混乱、错误或者丢失。

9. 单核 CPU 上运行多个线程效率一定会高吗?

单核 CPU 同时运行多个线程的效率是否会高,取决于线程的类型和任务的性质。一般来说,有两种类型的线程:CPU 密集型和 IO 密集型。CPU 密集型的线程主要进行计算和逻辑处理,需要占用大量的 CPU 资源。IO 密集型的线程主要进行输入输出操作,如读写文件、网络通信等,需要等待 IO 设备的响应,而不占用太多的 CPU 资源。

在单核 CPU 上,同一时刻只能有一个线程在运行,其他线程需要等待 CPU 的时间片分配。如果线程是 CPU 密集型的,那么多个线程同时运行会导致频繁的线程切换,增加了系统的开销,降低了效率。如果线程是 IO 密集型的,那么多个线程同时运行可以利用 CPU 在等待 IO 时的空闲时间,提高了效率。

因此,对于单核 CPU 来说,如果任务是 CPU 密集型的,那么开很多线程会影响效率;如果任务是 IO 密集型的,那么开很多线程会提高效率。当然,这里的“很多”也要适度,不能超过系统能够承受的上限。

10. 如何创建线程?(重要)

一般来说,创建线程有很多种方式,例如继承Thread类、实现Runnable接口、实现Callable接口、使用线程池、使用CompletableFuture类等等。

不过,这些方式其实并没有真正创建出线程。准确点来说,这些都属于是在 Java 代码中使用多线程的方法。

严格来说,Java 就只有一种方式可以创建线程,那就是通过new Thread().start()创建。不管是哪种方式,最终还是依赖于new Thread().start()。

11. 说说线程的生命周期和状态?(重点)

Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态:

  • NEW: 初始状态,线程被创建出来但没有被调用 start() 。
  • RUNNABLE: 运行状态,线程被调用了 start()等待运行的状态。
  • BLOCKED:阻塞状态,需要等待锁释放。
  • WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)。
  • TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像 WAITING 那样一直等待。
  • TERMINATED:终止状态,表示该线程已经运行完毕。
    在这里插入图片描述
    在这里插入图片描述

12. 什么是线程上下文切换?

线程在执行过程中会有自己的运行条件和状态(也称上下文),比如上文所说到过的程序计数器,栈信息等。当出现如下情况的时候,线程会从占用 CPU 状态中退出。

  • 主动让出 CPU,比如调用了 sleep(), wait() 等。
  • 时间片用完,因为操作系统要防止一个线程或者进程长时间占用 CPU 导致其他线程或者进程饿死。
  • 调用了阻塞类型的系统中断,比如请求 IO,线程被阻塞。
  • 被终止或结束运行

这其中前三种都会发生线程切换,线程切换意味着需要保存当前线程的上下文,留待线程下次占用 CPU 的时候恢复现场。并加载下一个将要占用 CPU 的线程上下文。这就是所谓的 上下文切换。

上下文切换是现代操作系统的基本功能,因其每次需要保存信息恢复信息,这将会占用 CPU,内存等系统资源进行处理,也就意味着效率会有一定损耗,如果频繁切换就会造成整体效率低下。

13. 什么是线程死锁?如何避免死锁?

线程死锁是多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

  1. 如何预防死锁?
    破坏死锁的产生的必要条件即可:
  • 破坏请求与保持条件:一次性申请所有的资源。
  • 破坏不剥夺条件:占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
  • 破坏循环等待条件:靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。
  1. 如何避免死锁?

    避免死锁就是在资源分配时,借助于算法(比如银行家算法)对资源分配进行计算评估,使其进入安全状态。

14. 可以直接调用 Thread 类的 run 方法吗?

new 一个 Thread,线程进入了新建状态。调用 start()方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容,这是真正的多线程工作。 但是,直接执行 run() 方法,会把 run() 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。

需要重写run()方法实现多线程

15. 乐观锁和悲观锁

  1. 什么是悲观锁?

    悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。

  2. 什么是乐观锁?

    乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停地执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或 CAS 算法)。

理论上来说:

  • 悲观锁通常多用于写比较多的情况(多写场景,竞争激烈),这样可以避免频繁失败和重试影响性能,悲观锁的开销是固定的。不过,如果乐观锁解决了频繁失败和重试这个问题的话(比如LongAdder),也是可以考虑使用乐观锁的,要视实际情况而定。
  • 乐观锁通常多用于写比较少的情况(多读场景,竞争较少),这样可以避免频繁加锁影响性能。不过,乐观锁主要针对的对象是单个共享变量。

16. synchronized 关键字

  1. synchronized 是什么?有什么用?
    synchronized 是 Java 中的一个关键字,翻译成中文是同步的意思,主要解决的是多个线程之间访问资源的同步性,可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。

17. 共享锁和独占锁有什么区别?

共享锁:一把锁可以被多个线程同时获得。
独占锁:一把锁只能被一个线程获得。

18. StringBuilder和StringBuffer区别(重要)

a. 相同点:

用法一样,作用一样

b. 不同点:

StringBuilder:拼接效率比StringBuffer高,线程不安全

StringBuffer:效率比较底,线程安全

拼接效率:StringBuilder>StringBuffer>String

19. MAP(重要)

19.1 HashMap 和 Hashtable 的区别

  • 线程是否安全: HashMap 是非线程安全的,Hashtable 是线程安全的,因为 Hashtable 内部的方法基本都经过synchronized 修饰。
  • 效率: 因为线程安全的问题,HashMap 要比 Hashtable 效率高一点。另外,Hashtable 基本被淘汰,不要在代码中使用它
  • 对 Null key 和 Null value 的支持: HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个;Hashtable 不允许有 null 键和 null 值,否则会抛出 NullPointerException。
  • 初始容量大小和每次扩充容量大小的不同: ① 创建时如果不指定容量初始值,Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为 2 的幂次方大小。也就是说 HashMap 总是使用 2 的幂作为哈希表的大小。
  • 底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树),以减少搜索时间(后文中我会结合源码对这一过程进行分析)。Hashtable 没有这样的机制。

19.2 HashMap 的底层实现

实现原理:
HashMap 实际上是一个数组和链表的结合体, HashMap 基于 Hash 算法实现的;

(1) 当我们向 HashMap 中 Put 元素时, 利用 key 的 hashCode 重新计算出当前对象的 元素在数组中的下标

(2) 写入时, 如果出现 Hash 值相同的 key, 此时分类, 如果 key 相同, 则覆盖原始值; 如果 key 不同, value 则放入链表中

(3) 读取时, 直接找到 hash 值对应的下标, 在进一步判断 key 是否相同, 进而找到对 应值

  1. JDK1.8 之前

    JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列。HashMap 通过 key 的 hashcode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash 判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。

    所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法 换句话说使用扰动函数之后可以减少碰撞。

    所谓 “拉链法” 就是:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。
    在这里插入图片描述

  2. JDK1.8 之后
    相比于之前的版本, JDK1.8 之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。
    在这里插入图片描述

20. ArrayList 和 LinkedList 的区别 (重要)

(1) ArrayList 基于动态数据实现, LinkedList 基于链表实现, 两者都是线程不安全的
(2) ArrayList 基于数组, 查询快; linkedList 基于链表, 新增和删除更快
(3) LinkedList 不支持高效的随机访问

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python爬虫 - 爬取html中的script数据(zum.com新闻信息 )

文章目录 1. 分析页面内容数据格式2. 使用re.findall方法,编写爬虫代码3. 使用re.search 方法,编写爬虫代码 1. 分析页面内容数据格式 (1)打开 https://zum.com/ (2)按F12(或 在网页上右键 --…

SpringCloud Alibaba--nacos简介和配置管理和登录

目录 一.理论基础 二.nacos 2.1 简介 2.2 安装 三.父项目 三.生产者 3.1 配置依赖 3.2 配置文件 3.3 启动类 3.4 控制类 四.消费者 4.1 配置依赖 4.2 配置文件 4.3 启动类 4.4 feign的接口 五.效果 六.负载均衡--权重算法 6.1重启nacos 6.2 设置权重 6.3 设…

SSH Key生成

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

「React Native」为什么要选择 React Native 作为的跨端方案

文章目录 前言一、常见因素二、举个栗子2.1 项目背景2.2 为什么选择 React Native2.3 项目实施2.4 成果总结 前言 没有完美的跨端技术,只有适合的场景。脱离适用场景去谈跨端技术没有什么意义。 一、常见因素 共享代码库: React Native 允许开发者编写…

一个docker配置mysql主从服务器

这也就是因为穷,不然谁用一个docker配置主从,哈哈 既然成功了就记录下。过程挺折磨人的。 首先要保证你的电脑安装好了docker 为了保证docker当中主从能正常连网,现在docker里面创建一个网络环境 docker network create --driver bridge mysq…

MATLAB的几种边缘检测算子(Sobel、Prewitt、Laplacian)

MATLAB的几种边缘检测算子(Sobel、Prewitt、Laplacian) clc;close all;clear all;warning off;%清除变量 rand(seed, 100); randn(seed, 100); format long g;% 读取图像 image imread(lena.png); % 转换为灰度图像 gray_image rgb2gray(image); % 转换为double类型以进行计算…

Vue3中使用无缝滚动插件vue3-seamless-scroll

官网:https://www.npmjs.com/package/vue-seamless-scroll 1、实现效果文字描述: 表格中的列数据进行横向无缝滚动,某一列进行筛选的时候,重新请求后端的数据,进行刷新 2、安装:npm i vue3-seamless-scrol…

CentOS7/RHEL7 root密码破解

我们知道root是CentOS7/RHEL7系统的管理员用户,一般情况下,我们是不会把其密码忘记的,如果万一忘记了,如果破解root密码呢,今天就为大家详细讲讲。 1.CentOS7/RHEL7 root密码破解 以VMware虚拟机上CentOS7系统为例 …

【js】解决自动生成颜色时相邻颜色视觉相似问题的技术方案

解决自动生成颜色时相邻颜色视觉相似问题的技术方案 在进行大规模颜色生成时,特别是在数据可视化、用户界面设计等应用领域,一个常见的挑战是确保相邻颜色在视觉上具有足够的区分度。本文介绍的方法通过结合黄金分割比与饱和度、亮度的周期性变化&#…

Web3 游戏周报(4.14-4.20)

【4.14-20】Web3 游戏行业动态: 前迪士尼老板与漫威、星球大战人才携手推出 Web3 游戏工作室 加密集换式卡牌游戏《Fantasy》在 Blast 主网上线 加密游戏工作室 Avalon 融资 1,000 万美元,Hashed 领投 Faraway 收购 Yuga Labs 旗下两大游戏 IP“HV-MT…

结构型设计模式

享元模式 享元模式(Flyweight Pattern)是一种用于性能优化的设计模式,它通过共享尽可能多的相似对象来减少内存使用,尤其是在大量对象的情况下非常有效。这个模式是在对象数量多而对象状态大部分可共享的情况下实现的。 享元模式…

【C 数据结构】树

文章目录 【 1. 基本原理 】1.1 子树、空树1.2 有序数、无序树1.3 森林 【 2. 结点 】【 3. 度、层次、深度 】 【 1. 基本原理 】 树结构是一种 非线性存储结构,存储的是具有 一对多 关系的数据元素的集合。一对多 如下图中的左图所示,对于数据 A 来…

【webrtc】Chrome和Firefox在SDP协商过程中,针对localhost的不同处理

内网下chrome端webrtc协商失败 现象 我有一个webrtc服务器在局域网内,使用chrome浏览器访问时,发现webrtc在做媒体协商时失败。 具体表现是,在交换sdp后,ice的状态是oniceconnectionstatechange: failed 但是换成Firefox浏览器…

html接入腾讯地图

1.申请key key申请地址&#xff1a;https://lbs.qq.com/dev/console/application/mine 官方文档 https://lbs.qq.com/webApi/javascriptGL/glGuide/glBasic 2.html接入示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"U…

全国青少年劳动技能与智能设计大赛安徽省赛——庐江县师资培训活动圆满举行

为贯彻落实科教兴国的国家战略目标&#xff0c;根据《教育部办公厅关于公布 2022—2025 学年面向中小学生的全国性竞赛活动》的相关通知。为了提升教师在劳动技能与智能设计领域的教学与指导能力&#xff0c;为即将到来的省级大赛做好充分准备。4月18日&#xff0c;一场由庐江县…

维基百科、百度百科和搜狗百科词条的创建流程

随着网络的发展&#xff0c;百度百科、搜狗百科、维基百科等百科网站已经成为大众获取知识的重要途径。因为百科具有得天独厚的平台优势&#xff0c;百科上的信息可信度高&#xff0c;权威性强。所以百科平台也成为商家的必争之地。这里小马识途聊聊如何创建百度百科、搜狗百科…

GPT与GAN结合生成图像——VQGAN原理解析

1、前言 这篇文章&#xff0c;我们讲VQ_GAN&#xff0c;这是一个将特征向量离散化的模型&#xff0c;其效果相当不错&#xff0c;搭配Transformer&#xff08;GPT&#xff09;或者CLIP使用&#xff0c;达到的效果在当时可谓是令人拍案叫绝&#xff01; 原论文&#xff1a;Tam…

LTD271次升级 | 网站/小程序可设访问IP的黑白名单 • 官微中心支持PDF等办公文件预览与并分享 • 订单退款显示更详尽明细

1、新增IP访问限制功能&#xff1b; 2、订单新增交易号显示与退款明细显示&#xff1b; 3、自定义地址增加四级地区&#xff1b; 4、Android版App优化文件功能&#xff1b; 5、已知问题修复与优化&#xff1b; 01 官微中心 1) 新增IP限制访问功能 允许或者禁止某些 IP 或…

uniapp项目中禁止横屏 ,app不要自动旋转 -,保持竖屏,uniapp取消重力感应

uniapp项目中禁止横屏 &#xff0c;app不要自动旋转 -&#xff0c;保持竖屏&#xff0c;uniapp取消重力感应 1.适用于移动端&#xff0c;安卓和IOS&#xff0c;当即使手机打开了自动旋转的按钮&#xff0c;设置如下的代码后&#xff0c;页面依旧保持竖屏。 步骤一&#xff1a…

【深度学习】yolo-World,数据标注,zeroshot,目标检测

仓库&#xff1a;https://github.com/AILab-CVC/YOLO-World 下载权重&#xff1a; 仓库下载和环境设置 下载仓库&#xff1a;使用以下命令从 GitHub 上克隆仓库&#xff1a; git clone --recursive https://github.com/AILab-CVC/YOLO-World.git创建并激活环境&#xff1a…
最新文章