含答案!2020年Nginx最牛面试题31问(一)拿大厂offer抱佛脚必备

Nginx的并发能力在同类型网页服务器中的表现,相对而言是比较好的,因此受到了很多企业的青睐,我国使用Nginx网站的知名用户包括腾讯、淘宝、百度、京东、新浪、网易等等。Nginx是网页服务器运维人员必备技能之一,下面为大家整理了一些比较常见的Nginx相关面试题,仅供参考:han

Nginx是一个web服务器和方向代理服务器,用于HTTP、HTTPS、SMTP、POP3和IMAP协议。

Nginx服务器的特性包括:

反向代理/L7负载均衡器

嵌入式Perl解释器

动态二进制升级

可用于重新编写URL,具有非常好的PCRE支持

3、请列举Nginx和Apache 之间的不同点。

Nginx使用反应器模式。主事件循环等待操作系统发出准备事件的信号,这样数据就可以从套接字读取,在该实例中读取到缓冲区并进行处理。单个线程可以提供数万个并发连接。

只需将请求删除的服务器就可以定义为:

这里,服务器名被保留为一个空字符串,它将在没有“主机”头字段的情况下匹配请求,而一个特殊的Nginx的非标准代码444被返回,从而终止连接。

反向代理服务器可以隐藏源服务器的存在和特征。它充当互联网云和web服务器之间的中间层。这对于安全方面来说是很好的,特别是当您使用web托管服务时。

Nginx服务器的最佳用法是在网络上部署动态HTTP内容,使用SCGI、WSGI应用程序服务器、用于脚本的FastCGI处理程序。它还可以作为负载均衡器。

Master进程:读取及评估配置和维持

Worker进程:处理请求

为了通过一个不同的端口开启Nginx,你必须进入/etc/Nginx/sites-enabled/,如果这是默认文件,那么你必须打开名为“default”的文件。编辑文件,并放置在你想要的端口:

502 =错误网关

503 =服务器超载

有可能,但是您可以确保fastcgi_intercept_errors被设置为ON,并使用错误页面指令。

要在URL中保留双斜线,就必须使用merge_slashes_off;

语法:merge_slashes [on/off]

默认值: merge_slashes on

环境: http,server

ngx_http_upstream_module用于定义可通过fastcgi传递、proxy传递、uwsgi传递、memcached传递和scgi传递指令来引用的服务器组。

C10K问题是指无法同时处理大量客户端(10,000)的网络套接字。

Stub_status指令:该指令用于了解Nginx当前状态的当前状态,如当前的活动连接,接受和处理当前读/写/等待连接的总数

Sub_filter指令:它用于搜索和替换响应中的内容,并快速修复陈旧的数据

您可以使用Nginx模块gunzip将请求压缩到上游。gunzip模块是一个过滤器,它可以对不支持“gzip”编码方法的客户机或服务器使用“内容编码:gzip”来解压缩响应。

要获得Nginx的当前时间,必须使用SSI模块、$date_gmt和$date_local的变量。

Proxy_set_header THE-TIME $date_gmt;

用于运行Nginx -s参数的可执行文件。

在编译过程中,必须选择Nginx模块,因为Nginx不支持模块的运行时间选择。

整理的更多LINUX免费文档 面试资料 教程视频资料关注+私信1自行领取

【干货】又是一年跳槽季!Nginx 10道核心面试题及解析

Nginx是一款轻量级的高性能Web服务器和反向代理服务器,由俄罗斯的Igor Sysoev开发。它具有占用资源少、高并发、稳定性高等优点,被广泛应用于互联网领域。在Nginx的面试过程中,面试官通常会提出一些核心问题,本文将介绍一些常见的Nginx核心面试题及其解答。

Nginx的主要特点包括:

  • 高性能:Nginx采用异步非阻塞的处理方式,具有高并发和高效率的特点。
  • 轻量级:Nginx的代码体积小、占用系统资源少,适合在内存有限的环境中使用。
  • 可扩展性:Nginx的模块化设计,使得用户可以根据需求灵活扩展功能。
  • 可靠性:Nginx稳定性高,可以在高负载、高并发的环境中保持稳定。
  • 反向代理功能:Nginx支持反向代理,能够提高Web应用的可用性和可靠性。
  • 负载均衡功能:Nginx支持多种负载均衡算法,能够实现高效的请求分发。

Nginx的安装和配置步骤一般包括以下几个步骤:

  • 下载Nginx源码:从Nginx官网下载对应版本的Nginx源码。
  • 编译安装Nginx:使用编译器编译Nginx源码,并进行安装。
  • 配置Nginx:修改Nginx的配置文件nginx.conf,配置监听端口、虚拟主机、反向代理等相关参数。
  • 启动Nginx:执行命令启动Nginx服务。

反向代理和正向代理都是代理服务器,但两者的作用和方式不同:

  • 反向代理:反向代理服务器的作用是隐藏服务器的真实IP地址,客户端向反向代理服务器发送请求,反向代理服务器再向目标服务器发送请求并将响应结果返回给客户端。反向代理通常用于负载均衡、提高Web应用的可用性和可靠性。
  • 正向代理:正向代理服务器的作用是代理客户端向目标服务器发送请求,客户端将请求发送给正向代理服务器,正向代理服务器再将请求发送给目标服务器,并将响应结果返回给客户端。正向代理通常用于绕过访问限制、隐藏客户端IP等

Nginx的负载均衡算法包括:

  • 轮询(Round Robin)算法:将请求依次分配给不同的服务器,依次轮流使用每个服务器。轮询算法简单、均衡,但当服务器负载不均衡时,可能会导致某些服务器的负载过高。
  • IP Hash算法:将请求根据客户端IP的hash值分配给不同的服务器,同一IP的请求总是分配到同一个服务器上,可以保证某个客户端的请求都由同一台服务器处理,保证session不会丢失。但当服务器数量变动时,会导致大量请求重新分配。
  • 最小连接数(Least Connections)算法:将请求分配给当前连接数最少的服务器,保证负载均衡的同时,也保证服务器的负载均衡。但此算法需要不断地监控服务器连接数,对性能有一定的影响。
  • 加权轮询(Weighted Round Robin)算法:将服务器按照权重值进行分配,权重越高的服务器会得到更多的请求。该算法可以根据服务器的处理能力分配请求,但需要人工设定权重值。
  • 加权最小连接数(Weighted Least Connections)算法:将服务器按照权重值和连接数进行分配,权重值越高的服务器会得到更多的请求,同时也保证当前连接数最少的服务器得到请求。该算法可以更好地实现动态负载均衡。

Nginx采用异步非阻塞的I/O多路复用事件驱动模型,可以同时处理大量的并发请求,其进程模型包括:

  • Master进程:负责启动和关闭Worker进程,以及管理Nginx的主配置文件和全局变量。
  • Worker进程:实际处理请求的进程,每个Worker进程独立处理连接,可以同时处理多个请求。

Nginx的进程模型有以下优点:

  • 资源占用少:Nginx的Master进程仅负责管理,不处理连接,占用资源少。
  • 可扩展性强:可以通过增加Worker进程来扩展处理能力。
  • 并发能力强:采用I/O多路复用技术,能够处理大量的并发连接。
  • 稳定性高:Worker进程之间互相独立,一个进程的崩溃不会影响其他进程。

优化Nginx的性能可以从以下方面入手:

  • 调整Worker进程数:根据服务器的CPU核心数和预计的并发连接数,适当调整Worker进程数,以充分利用服务器资源。
    • 调整TCP连接参数:修改TCP的缓冲区大小、TCP连接的超时时间等参数,以提高网络传输效率。
    • 启用文件缓存:将经常访问的静态文件缓存到内存中,可以减少对磁盘的访问,提高读取速度。
    • 启用gzip压缩:开启gzip压缩功能,可以减小响应数据的传输大小,提高网站的响应速度。
    • 使用缓存技术:使用反向代理缓存技术、FastCGI缓存技术等,可以减少对后端应用服务器的访问,提高网站的响应速度。
    • 使用HTTP2协议:HTTP2协议采用二进制分帧传输,能够提高网站的传输速度和并发量。
    • 启用SSL加密:使用SSL加密能够提高网站的安全性,但也会增加CPU的负担,需要合理调整加密算法和参数。
    • 启用HTTP缓存:使用HTTP缓存技术可以减少对后端应用服务器的访问,提高网站的响应速度。

总之,优化Nginx的性能需要根据具体的场景和需求来进行调整和优化,需要在充分了解系统性能瓶颈的基础上,进行针对性的优化。

Nginx与Apache相比,有以下优势:

  • 高性能:Nginx采用异步非阻塞的I/O多路复用事件驱动模型,可以同时处理大量的并发请求,性能比Apache更高。
  • 资源占用少:Nginx的Master进程仅负责管理,不处理连接,占用资源少;Worker进程之间互相独立,一个进程的崩溃不会影响其他进程,资源占用更少。
  • 可扩展性强:可以通过增加Worker进程来扩展处理能力,更加灵活。
  • 配置简单:Nginx的配置文件简单易懂,可以快速修改和配置。
  • 功能模块化:Nginx的模块化设计,使得功能模块可以按需启用,减少了系统资源的浪费。
  • 安全性高:Nginx支持防火墙、DDoS攻击防御等安全功能,可以提高网站的安全性。

综上所述,Nginx在性能、资源占用、可扩展性、配置简单、功能模块化和安全性等方面都有优势,适合高并发、高性能的场景,相比Apache更加适用于Web服务器。

Nginx高可用可以通过以下几种方式来实现:

  • 负载均衡:将客户端请求分发到多个Nginx服务器上,提高系统的可用性和性能。可以使用第三方的负载均衡软件,如HAProxy、Keepalived等。
  • 双机热备:使用主备模式,将两台Nginx服务器设置为主备关系,当主服务器出现故障时,备用服务器立即接管服务,保证系统的连续性和可用性。
  • 集群部署:将多个Nginx服务器组成一个集群,通过共享存储、同步数据等技术,实现高可用和负载均衡。
  • Docker容器化部署:通过Docker容器化技术,可以快速部署和扩展Nginx服务器,实现高可用和负载均衡。

Nginx可以通过反向代理技术来实现将请求转发给后端应用服务器,具体步骤如下:

  1. 配置upstream模块

在Nginx的配置文件中,使用upstream模块定义后端应用服务器的地址和端口号,如:

2. 配置location模块

在Nginx的配置文件中,使用location模块定义反向代理的路径和代理规则,如:

其中,proxy_pass指定后端应用服务器的地址和端口号,proxy_set_header指定请求头信息,可选配置。

3. 重载Nginx配置

在修改Nginx的配置文件后,需要执行命令重载Nginx的配置,如:

4. 验证反向代理

在浏览器中访问Nginx的IP地址或域名,即可验证反向代理是否生效。

Nginx可以通过动静分离技术来提高网站的性能和稳定性,具体步骤如下:

  1. 将静态文件独立出来

将静态文件(如HTML、CSS、JS、图片、视频等)独立出来,放到专门的文件服务器或CDN上。

2. 配置location模块

在Nginx的配置文件中,使用location模块定义静态文件的路径和代理规则,如:

其中,alias指定静态文件的目录路径,expires指定浏览器缓存时间,proxy_pass指定后端应用服务器的地址和端口号,可选配置。

3. 重载Nginx配置

在修改Nginx的配置文件后,需要执行命令重载Nginx的配置,如:

4. 验证动静分离

在浏览器中访问网站,查看静态文件是否来自专门的文件服务器或CDN,动态内容是否来自应用服务器。同时,可以使用浏览器的开发者工具查看请求和响应的情况。

本文介绍了Nginx的核心面试题,包括Nginx的基本原理、配置文件的结构和语法、常用的Nginx模块和指令、Nginx的高可用和负载均衡、反向代理和动静分离等。掌握这些知识点可以帮助你更好地理解Nginx的工作原理和应用场景,提高Nginx的使用和管理能力。同时,建议结合实际项目经验和实践,深入学习和研究Nginx的高级功能和性能优化,不断提高自己的技术水平和竞争力。

Java面试题及答案整理( 2024年12月最新版,持续更新)

春招金三银四快到了,发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全~

这套面试文档包含了:Java基础、JVM、多线程&并发、spring、mybatis、springboot、MySQL、springcloud、Dubbo、Nginx、MQ、数据结构与算法、Linux、Zookeeper、Redis篇、分布式、网络篇、设计模式、maven篇、ElasticSearch篇、tomcat篇、Git篇、软实力篇,应有尽有、一网打尽!

一、基础篇

1、 Java语言有哪些特点?

  • 简单易学、有丰富的类库
  • 面向对象(Java最重要的特性,让程序耦合度更低,内聚性更高)
  • 与平台无关性(JVM是Java跨平台使用的根本)
  • 可靠安全
  • 支持多线程

2、面向对象和面向过程的区别

面向过程:是分析解决问题的步骤,然后用函数把这些步骤一步一步地实现,然后在使用的时候一 一调用则可。性能较高,所以单片机、嵌入式开发等一般采用面向过程开发

面向对象:是把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个个步骤, 而是为了描述某个事物在解决整个问题的过程中所发生的行为。面向对象有封装、继承、多态的特性,所以易维护、易复用、易扩展。可以设计出低耦合的系统。 但是性能上来说,比面向过程要 低。

3 、八种基本数据类型的大小,以及他们的封装类

注:

1.int是基本数据类型,Integer是int的封装类,是引用类型。int默认值是0,而Integer默认值是null,所以Integer能区分出0和null的情况。一旦java看到null,就知道这个引用还没有指向某个对象,再任何引用使用前,必须为其指定一个对象,否则会报错。

2.基本数据类型在声明时系统会自动给它分配空间,而引用类型声明时只是分配了引用空间,必须通过实例化开辟数据空间之后才可以赋值。数组对象也是一个引用对象,将一个数组赋值给另一个数组时只是复制了一个引用,所以通过某一个数组所做的修改在另一个数组中也看的见。

虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,每个元素 boolean元素占8位。这样我们可以得出boolean类型占了单独使用是4个字节,在数组中又是1个字 节。使用int的原因是,对于当下32位的处理器(CPU)来说,一次处理数据是32位(这里不是指的是32/64位系统,而是指CPU硬件层面),具有高效存取的特点。

4、标识符的命名规则。

标识符的含义: 是指在程序中,我们自己定义的内容,譬如,类的名字,方法名称以及变量名称等等,都是标识符。

命名规则:(硬性要求) 标识符可以包含英文字母,0-9的数字,$以及_ 标识符不能以数字开头 标识符不是关键字

命名规范:(非硬性要求) 类名规范:首字符大写,后面每个单词首字母大写(大驼峰式)。 变量名规范:首字母小写,后面每个单词首字母大写(小驼峰式)。 方法名规范:同变量名。

5、instanceof 关键字的作用

instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法 为:

其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。

注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。

6、Java自动装箱与拆箱

装箱就是自动将基本数据类型转换为包装器类型(int–>Integer);调用方法:Integer的valueOf(int) 方法

拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int)。调用方法:Integer的 intValue方法

在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行:

而在从 Java SE5 开始就提供了自动装箱的特性,如果要生成一个数值为 10 的 Integer 对象,只需要

这样就可以了:

面试题 1 : 以下代码会输出什么?

运行结果:

为什么会出现这样的结果?输出结果表明 i1 和 i2 指向的是同一个对象,而 i3 和 i4 指向的是不同的对

象。此时只需一看源码便知究竟,下面这段代码是 Integer 的 valueOf 方法的具体实现:

其中 IntegerCache 类的实现为:

从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间, 便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

面试题2:以下代码输出什么

运行结果:

原因: 在某个范围内的整型数值的个数是有限的,而浮点数却不是。

7、 重载和重写的区别

重写(Override)

从字面上看,重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。

重写 总结: 1.发生在父类与子类之间 2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同 3.访问修饰符的限制一定要大于被重写方法的访问修饰符 (public>protected>default>private) 4.重写方法一定不能抛出新的检查异常或者比被重写方法申 明更加宽泛的检查型异常

重载(Overload)

在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不 同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是 否相同来判断重载

重载 总结: 1.重载Overload是一个类中多态性的一种表现 2.重载要求同名方法的参数列表不同(参 数类型,参数个数甚至是参数顺序) 3.重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准

篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java基础、JVM、多线程&并发、spring、mybatis、springboot、MySQL、springcloud、Dubbo、Nginx、MQ、数据结构与算法、Linux、Zookeeper、Redis篇、分布式、网络篇、设计模式、maven篇、ElasticSearch篇、tomcat篇、Git篇、软实力篇 面试专题

需要全套面试笔记的转发+关注后私信小编【学习】即可免费获取

二、JVM篇

1、知识点汇总

JVM是Java运行基础,面试时一定会遇到JVM的有关问题,内容相对集中,但对只是深度要求较高.

其中内存模型,类加载机制,GC是重点方面.性能调优部分更偏向应用,重点突出实践能力.编译器优化 和执行模式部分偏向于理论基础,重点掌握知识点.

需了解 内存模型各部分作用,保存哪些数据.

类加载双亲委派加载机制,常用加载器分别加载哪种类型的类.

GC分代回收的思想和依据以及不同垃圾回收算法的回收思路和适合场景.

性能调优常有JVM优化参数作用,参数调优的依据,常用的JVM分析工具能分析哪些问题以及使用方法.

执行模式解释/编译/混合模式的优缺点,Java7提供的分层编译技术,JIT即时编译技术,OSR栈上替换,C1/C2编译器针对的场景,C2针对的是server模式,优化更激进.新技术方面Java10的graal编译器

编译器优化javac的编译过程,ast抽象语法树,编译器优化和运行器优化.

2、知识点详解:

1)、JVM内存模型:

线程独占:栈,本地方法栈,程序计数器 线程共享:堆,方法区

2)、栈:

又称方法栈,线程私有的,线程执行方法是都会创建一个栈阵,用来存储局部变量表,操作栈,动态链接,方法出口等信息.调用方法时执行入栈,方法返回式执行出栈.

3)、本地方法栈

与栈类似,也是用来保存执行方法的信息.执行Java方法是使用栈,执行Native方法时使用本地方法栈.

4)、程序计数器

保存着当前线程执行的字节码位置,每个线程工作时都有独立的计数器,只为执行Java方法服务,执行 Native方法时,程序计数器为空.

5)、堆

JVM内存管理最大的一块,对被线程共享,目的是存放对象的实例,几乎所欲的对象实例都会放在这里, 当堆没有可用空间时,会抛出OOM异常.根据对象的存活周期不同,JVM把对象进行分代管理,由垃圾回收器进行垃圾的回收管理

6)、方法区

又称非堆区,用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器优化后的代码等数据.1.7 的永久代和1.8的元空间都是方法区的一种实现

7)、JVM 内存可见性

JMM 是定义程序中变量的访问规则 , 线程对于变量的操作只能在自己的工作内存中进行 , 而不能直接对主内存操作. 由于指令重排序 , 读写的顺序会被打乱 , 因此 JMM 需要提供原子性 , 可见性 , 有序性保证 .

3、说说类加载与卸载

加载过程

其中验证,准备,解析合称链接

加载通过类的完全限定名,查找此类字节码文件,利用字节码文件创建Class对象.

验证确保Class文件符合当前虚拟机的要求,不会危害到虚拟机自身安全.

准备进行内存分配,为static修饰的类变量分配内存,并设置初始值(0或null).不包含final修饰的静态变 量,因为final变量在编译时分配.

解析将常量池中的符号引用替换为直接引用的过程.直接引用为直接指向目标的指针或者相对偏移量等.

初始化主要完成静态块执行以及静态变量的赋值.先初始化父类,再初始化当前类.只有对类主动使用 时才会初始化.

触发条件包括,创建类的实例时,访问类的静态方法或静态变量的时候,使用Class.forName反射类的时候,或者某个子类初始化的时候.

Java自带的加载器加载的类,在虚拟机的生命周期中是不会被卸载的,只有用户自定义的加载器加载的类才可以被卸.

1)、加载机制-双亲委派模式

双亲委派模式,即加载器加载类时先把请求委托给自己的父类加载器执行,直到顶层的启动类加载器. 父类加载器能够完成加载则成功返回,不能则子类加载器才自己尝试加载.*

优点:

1. 避免类的重复加载

2. 避免Java的核心API被篡改

2)、分代回收

分代回收基于两个事实:大部分对象很快就不使用了,还有一部分不会立即无用,但也不会持续很长时 间.

年轻代->标记-复制 老年代->标记-清除

3、回收算法

a、G1算法

1.9后默认的垃圾回收算法,特点保持高回收率的同时减少停顿.采用每次只清理一部分,而不是清理全部的增量式清理,以保证停顿时间不会过长

其取消了年轻代与老年代的物理划分,但仍属于分代收集器,算法将堆分为若干个逻辑区域(region),一部分用作年轻代,一部分用作老年代,还有用来存储巨型对象的分区.

同CMS相同,会遍历所有对象,标记引用情况,清除对象后会对区域进行复制移动,以整合碎片空间.

年轻代回收: 并行复制采用复制算法,并行收集,会StopTheWorld.

老年代回收: 会对年轻代一并回收

初始标记完成堆root对象的标记,会StopTheWorld. 并发标记 GC线程和应用线程并发执行. 最终标记完成三色标记周期,会StopTheWorld. 复制/清楚会优先对可回收空间加大的区域进行回收

b、ZGC算法

前面提供的高效垃圾回收算法,针对大堆内存设计,可以处理TB级别的堆,可以做到10ms以下的回收停顿时间.

  • 着色指针
  • 读屏障
  • 并发处理
  • 基于region
  • 内存压缩(整理)

roots标记:标记root对象,会StopTheWorld. 并发标记:利用读屏障与应用线程一起运行标记,可能 会发生StopTheWorld. 清除会清理标记为不可用的对象. roots重定位:是对存活的对象进行移动,以

腾出大块内存空间,减少碎片产生.重定位最开始会StopTheWorld,却决于重定位集与对象总活动集的比例. 并发重定位与并发标记类似.

4、简述一下JVM的内存模型

1).JVM内存模型简介

JVM定义了不同运行时数据区,他们是用来执行应用程序的。某些区域随着JVM启动及销毁,另外一些区域的数据是线程性独立的,随着线程创建和销毁。jvm内存模型总体架构图如下:(摘自oracle官方网站)

JVM在执行Java程序时,会把它管理的内存划分为若干个的区域,每个区域都有自己的用途和创建 销毁时间。如下图所示,可以分为两大部分,线程私有区和共享区。下图是根据自己理解画的一个 JVM内存模型架构图:

JVM内存分为线程私有区和线程共享区

线程私有区

1)、程序计数器

当同时进行的线程数超过CPU数或其内核数时,就要通过时间片轮询分派CPU的时间资源,不免发生线程切换。这时,每个线程就需要一个属于自己的计数器来记录下一条要运行的指令。如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为 空。

2)、虚拟机栈

线程私有的,与线程在同一时间创建。管理JAVA方法执行的内存模型。每个方法执行时都会创建一个桢栈来存储方法的的变量表、操作数栈、动态链接方法、返回值、返回地址等信息。栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出stackOverflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出 OutofMemoryError。 使用jclasslib工具可以查看class类文件的结构。下图为栈帧结构图:

3)、本地方法栈

与虚拟机栈作用相似。但它不是为Java方法服务的,而是本地方法(C语言)。由于规范对这块没有强制要求,不同虚拟机实现方法不同。

线程共享区

1)、方法区

线程共享的,用于存放被虚拟机加载的类的元数据信息,如常量、静态变量和即时编译器编译后的 代码。若要分代,算是永久代(老年代),以前类大多“static”的,很少被卸载或收集,现回收废弃 常量和无用的类。其中运行时常量池存放编译生成的各种常量。(如果hotspot虚拟机确定一个类 的定义信息不会被使用,也会将其回收。回收的基本条件至少有:所有该类的实例被回收,而且装 载该类的ClassLoader被回收)

2)、堆

存放对象实例和数组,是垃圾回收的主要区域,分为新生代和老年代。刚创建的对象在新生代的 Eden区中,经过GC后进入新生代的S0区中,再经过GC进入新生代的S1区中,15次GC后仍存在就进入老年代。这是按照一种回收机制进行划分的,不是固定的。若堆的空间不够实例分配,则 OutOfMemoryError。

Java面试题目录

多线程&并发篇(46道面试题)

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。