南昌达内IT培训学校
4000857126
新闻详情

2023年南昌本地口碑出名的大数据开发培训机构精选名单汇总

来源:南昌达内IT培训学校时间:2023/3/20 11:28:14 浏览量:105

  达内专注IT培训20年,覆盖70座城市,近342家校区遍布,开设Java大数据、软件测试、Python人工智能、web前端、Linux云计算、网络安全与运维、UI设计、运营、影视特效、全链路网络营销等IT培训、泛IT培训和非IT培训共12大IT课程,拨打客服电话预约了解课程详解及优惠!

  大数据全栈工程师,小白也能拿高薪!来达内&大数据培训机构学习大数据,带给你的不只是高薪,更是技术的提升.达内大数据培训班让每位学员都能找到适合自己的课程,练就更牛技术,挑战更高薪水,学大数据就到达内&大数据培训机构。

  课程直切企业需求 培养数据分析人才

  数据库编程

  数据分析基础编程;数据分析宏语言;数据分析SQL;数据分析编程

  统计分析

  多元统计:因子分析,聚类分析;统计基础与假设检验,T检验与方差分析;线性回归与模型修正,逻辑回归;统计基础与实践序列

  数据挖掘

  数据挖掘前期处理与决策树;逻辑回归与神经网络;聚类模型、关联分类;常见数据挖掘工具要点分析

  Python爬虫

  Python的基本语法;基于Python的爬虫实现;Scrapy、PySpider等爬虫框架;利用Python爬虫获取数据

  数据可视化

  利用Echars等Web前端技术;利用相关数据可视化工具;数据可视化解决方案分享;业务评估系统BI设计与实现

  数据分析+Hadoop

  Hadoop平台使用;其他分析工具与大数据应用讲解;数据分析数据库管理平台接口课程

  大数据开发:关于JVM内存模型JMM详解

  一.JMM 的定义

  Java程序内存的分配是在JVM虚拟机内存分配机制下完成。

  Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,增加了Java程序在各种平台下对内存的访问都能增加效果一致的机制及规范。

  简要言之,jmm是jvm的一种规范,定义了jvm的内存模型。它屏蔽了各种硬件和操作系统的访问差异,不像c那样直接访问硬件内存,相对安全很多,它的主要目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。可以增加并发编程场景中的原子性、可见性和有序性。

  二.JMM的重排序屏障

  从Java源代码到较终实际执行的指令序列,会经过三种重排序。但是,为了增加内存的可见性,Java编译器在生成指令序列的适当位置会插入内存屏障指令来禁止特定类型的处理器重排序。对于编译器的重排序,JMM会根据重排序规则禁止特定类型的编译器重排序;对于处理器重排序,JMM会插入特定类型的内存屏障,通过内存的屏障指令禁止特定类型的处理器重排序。这里讨论JMM对处理器的重排序,为了更深理解JMM对处理器重排序的处理,先来认识一下常见处理器的重排序规则:

  其中的N标识处理器不允许两个操作进行重排序,Y表示允许。其中Load-Load表示读-读操作、Load-Store表示读-写操作、Store-Store表示写-写操作、Store-Load表示写-读操作。可以看出:常见处理器对写-读操作都是允许重排序的,并且常见的处理器都不允许对存在数据依赖的操作进行重排序(对应上面数据转换那一列,都是N,所以处理器不允许这种重排序)。

  那么这个结论对我们有什么作用呢?比如点:处理器允许写-读操作两者之间的重排序,那么在并发编程中读线程读到可能是一个未被初始化或者是一个NULL等,出现不可预知的错误,基于这点,JMM会在适当的位置插入内存屏障指令来禁止特定类型的处理器的重排序。内存屏障指令一共有4类:

  · LoadLoad Barriers:确保Load1数据的装载先于Load2以及所有后续装载指令

  · StoreStore Barriers:确保Store1的数据对其他处理器可见(会使缓存行无效,并刷新到内存中)先于Store2及所有后续存储指令的装载

  · LoadStore Barriers:确保Load1数据装载先于Store2及所有后续存储指令刷新到内存

  · StoreLoad Barriers:确保Store1数据对其他处理器可见(刷新到内存,并且其他处理器的缓存行无效)先于Load2及所有后续装载指令的装载。该指令会使得该屏障之前的所有内存访问指令完成之后,才能执行该屏障之后的内存访问指令。

  数据依赖性

  根据上面的表格,处理器不会对存在数据依赖的操作进行重排序。这里数据依赖的准确定义是:如果两个操作同时访问一个变量,其中一个操作是写操作,此时这两个操作就构成了数据依赖。常见的具有这个特性的如i++、i—。如果改变了具有数据依赖的两个操作的执行顺序,那么较后的执行结果就会被改变。这也是不能进行重排序的原因。例如:

  · 写后读:a = 1; b = a;

  · 写后写:a = 1; a = 2;

  · 读后写:a = b; b = 1;

  重排序遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。但是这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作,不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑。

  as-if-serial语义

  as-if-serial语义的意思指:管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。编译器,runtime 和处理器都必须遵守as-if-serial语义。

  as-if-serial语义把单线程程序保护了起来,遵守as-if-serial语义的编译器,runtime 和处理器共同为编写单线程程序的程序员创建了一个幻觉:单线程程序是按程序的顺序来执行的。as-if-serial语义使单线程程序员无需担心重排序会干扰他们,也无需担心内存可见性问题。

  重排序对多线程的影响

  如果代码中存在控制依赖的时候,会影响指令序列执行的并行度(因为)。也是为此,编译器和处理器会采用猜测(Speculation)执行来克服控制的相关性。所以重排序破坏了程序顺序规则(该规则是说指令执行顺序与实际代码的执行顺序是一致的,但是处理器和编译器会进行重排序,只要较后的结果不会改变,该重排序就是合理的)。

  在单线程程序中,由于as-ifserial语义的存在,对存在控制依赖的操作重排序,不会改变执行结果;但在多线程程序中,对存在控制依赖的操作重排序,可能会改变程序的执行结果。

  三.内存区域

  1. 程序计数器

  程序计数器是一块很小的内存空间,它是线程私有的,可以认作为当前线程的行号指示器。是当前线程锁执行字节码的行号治时期,每条线程都有一个独立的程序计数器,这类内存也称为“线程私有”的内存。正在执行java方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如果是Natice方法,则为空。

  1.1. 作用

  程序计数器有两个作用

  字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理

  在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。

  1.2. 特点

  一块较小的内存空间

  线程私有。每条线程都有一个独立的程序计数器。

  是一个不会出现OOM的内存区域。

  生命周期随着线程的创建而创建,随着线程的结束而死亡。

  1.3我们为什么需要程序计数器

  我们知道对于一个处理器(如果是多核cpu那就是一核),在一个确定的时刻都只会执行一条线程中的指令,一条线程中有多个指令,为了线程切换可以恢复到正确执行位置,每个线程都需有独立的一个程序计数器,不同线程之间的程序计数器互不影响,独立存储。

  注意:如果线程执行的是个java方法,那么计数器记录虚拟机字节码指令的地址。如果为native【底层方法】,那么计数器为空。这块内存区域是虚拟机规范中没有OutOfMemoryError的区域。

  2. Java栈(虚拟机栈)

  同计数器也为线程私有,生命周期与相同,就是我们平时说的栈,栈描述的是Java方法执行的内存模型。

  每个方法被执行的时候都会创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。【栈先进后出,下图栈1先进较后出来】

  对于栈帧的解释参考 Java虚拟机运行时栈帧结构

  栈帧: 是用来存储数据和部分过程结果的数据结构。

  栈帧的位置: 内存 -> 运行时数据区 -> 某个线程对应的虚拟机栈 -> here[在这里]

  栈帧大小确定时间: 编译期确定,不受运行期数据影响。

  通常有人将java内存区分为栈和堆,实际上java内存比这复杂,这么区分可能是因为我们较关注,与对象内存分配关系较密切的是这两个。

  平时说的栈一般指局部变量表部分。

  局部变量表:一片连续的内存空间,用来存放方法参数,以及方法内定义的局部变量,存放着编译期间已知的数据类型(基本类型和对象引用(reference类型),returnAddress类型。它的较小的局部变量表空间单位为Slot,虚拟机没有指明Slot的大小,但在jvm中,long和double类型数据明确规定为64位,这两个类型占2个Slot,其它基本类型固定占用1个Slot。

  reference类型:与基本类型不同的是它不等同本身,即使是String,内部也是char数组组成,它可能是指向一个对象起始位置指针,也可能指向一个代表对象的句柄或其他与该对象有关的位置。

  returnAddress类型:指向一条字节码指令的地址【深入理解Java虚拟机】怎么理解returnAddress

  栈帧

  需要注意的是,局部变量表所需要的内存空间在编译期完成分配,当进入一个方法时,这个方法在栈中需要分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表大小。

  Java虚拟机栈可能出现两种类型的异常:

  线程请求的栈深度大于虚拟机允许的栈深度,将抛出StackOverflowError。

  虚拟机栈空间可以动态扩展,当动态扩展是无法申请到足够的空间时,抛出OutOfMemory异常。

  3. 本地方法栈(Native Method Stack)

  本地方法栈和Java虚拟机栈实现的功能与抛出异常几乎相同

  只不过虚拟机栈是为虚拟机执行Java方法(也就是字节码)服务,本地方法区则为虚拟机使用到的Native方法服务.

  在JVM内存布局中,也是线程对象私有的,但是虚拟机栈“主内”,而本地方法栈“主外”

  这个“内外”是针对JVM来说的,本地方法栈为Native方法服务

  线程开始调用本地方法时,会进入一个不再受JVM约束的世界

  本地方法可以通过JNI(Java Native Interface)来访问虚拟机运行时的数据区,甚至可以调用寄存器,具有和JVM相同的能力和权限

  当大量本地方法出现时,势必会削弱JVM对系统的控制力,因为它的出错信息都比较黑盒.

  对于内存不足的情况,本地方法栈还是会拋出native heap OutOfMemory

  较的本地方法应该是System.currentTimeMillis(),JNI 使Java深度使用OS的特性功能,复用非Java代码

  但是在项目过程中,如果大量使用其他语言来实现JNI,就会丧失跨平台特性,威胁到程序运行的稳定性

  假如需要与本地代码交互,就可以用中间标准框架进行解耦,这样即使本地方法崩溃也不至于影响到JVM的稳定

  当然,如果要求极高的执行效率、偏底层的跨进程操作等,可以考虑设计为JNI调用方式

  4. JAVA堆

  对于大多数应用来说,堆是java虚拟机管理内存较大的一块内存区域,因为堆存放的对象是线程共享的,所以多线程的时候也需要同步机制。因此需要重点了解下。

  java虚拟机规范对这块的描述是:所有对象实例及数组都要在堆上分配内存,但随着JIT编译器的发展和逃逸分析技术的成熟,这个说法也不是那么,但是大多数情况都是这样的。

  即时编译器:可以把把Java的字节码,包括需要被解释的指令的程序)转换成可以直接发送给处理器的指令的程序)

  逃逸分析:通过逃逸分析来决定某些实例或者变量是否要在堆中进行分配,如果开启了逃逸分析,即可将这些变量直接在栈上进行分配,而非堆上进行分配。这些变量的指针可以被全局所引用,或者其其它线程所引用。

  参考逃逸分析

  注意:它是所有线程共享的,它的目的是存放对象实例。同时它也是GC所管理的主要区域,因此常被称为GC堆,又由于现在收集器常使用分代算法,Java堆中还可以细分为新生代和老年代,再细致点还有Eden(伊甸园)空间之类的不做深究。

  根据虚拟机规范,Java堆可以存在物理上不连续的内存空间,就像磁盘空间只要逻辑是连续的即可。它的内存大小可以设为固定大小,也可以扩展。

  当前主流的虚拟机如HotPot都能按扩展实现(通过设置 -Xmx和-Xms),如果堆中没有内存内存完成实例分配,而且堆无法扩展将报OOM错误(OutOfMemoryError)

  4.1特点

  Java虚拟机所需要管理的内存中较大的一块.

  堆内存物理上不一定要连续,只需要逻辑上连续即可,就像磁盘空间一样.

  堆是垃圾回收的主要区域,所以也被称为GC堆.

  堆的大小既可以固定也可以扩展,但主流的虚拟机堆的大小是可扩展的(通过-Xmx和-Xms控制),因此当线程请求分配内存,但堆已满,且内存已满无法再扩展时,就抛出OutOfMemoryError.

  线程共享

  整个Java虚拟机只有一个堆,所有的线程都访问同一个堆.

  它是被所有线程共享的一块内存区域,在虚拟机启动时创建.

  而程序计数器、Java虚拟机栈、本地方法栈都是一个线程对应一个

  5 方法区

  Java虚拟机规范中定义方法区是堆的一个逻辑部分,但是别名Non-Heap(非堆),以与Java堆区分.

  方法区中存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据.

  运行时常量池

  是方法区的一部分,class文件除了有类的字段、接口、方法等描述信息之外,还有常量池用于存放编译期间生成的各种字面量和符号引用。

  5.1 特点

  线程共享

  方法区是堆的一个逻辑部分,因此和堆一样,都是线程共享的.整个虚拟机中只有一个方法区.

  代

  方法区中的信息一般需要长期存在,而且它又是堆的逻辑分区,因此用堆的划分方法,我们把方法区称为代.

  内存回收效率低

  Java虚拟机规范对方法区的要求比较宽松,可以不实现垃圾收集.

  方法区中的信息一般需要长期存在,回收一遍内存之后可能只有少量信息无效.

  对方法区的内存回收的主要目标是:对常量池的回收和对类型的卸载

  和堆一样,允许固定大小,也允许可扩展的大小,还允许不实现垃圾回收。

  当方法区内存空间无法满足内存分配需求时,将抛出OutOfMemoryError异常.

尊重原创文章,转载请注明出处与链接:http://www.soxsok.com/wnews770404.html 违者必究! 以上就是关于“2023年南昌本地口碑出名的大数据开发培训机构精选名单汇总”的全部内容了,想了解更多相关知识请持续关注本站。

温馨提示:为不影响您的学业,来 南昌大数据培训 校区前请先电话或QQ咨询,方便我校安排相关的专业老师为您解答
教学环境
  • 达内环境

    达内环境

  • 达内环境

    达内环境

  • 达内环境

    达内环境

预约申请
  • * 您的姓名
  • * 联系电话
  • * 报名课程
  •   备注说明
提交报名
版权所有:搜学搜课(www.soxsok.com) 技术支持:搜学搜课网