字节码

PythonI/O进阶学习笔记_9.python的生成器

两盒软妹~` 提交于 2020-01-07 03:26:03
content: 1. 什么是生成器 2. 生成器的实现 3. 生成器的应用 一.生成器简介 1.什么是生成器 在 Python 中,使用了 yield 的函数被称为生成器(generator)。 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。 调用一个生成器函数,返回的是一个迭代器对象。 可以看到,普通函数就是返回的return,而生成器函数是生成了一个生成器对象。 为什么能和普通函数不一样返回生成器对象? 因为在python在运行之前进行编译成字节码。发现了yield关键字,所以在编译的时候就定义了。 生成器对象,实际上也是实现了我们的迭代协议的。 为啥会用到生成器? 简单举个例子: 列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。如果仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 如果列表元素能按照某种算法推算出来,那我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。 生成器在python中的设计使用 实现了延迟求值和惰性求值,也是后面协程实现的基础。 2.生成器怎么用 例子

Java中的反射

≯℡__Kan透↙ 提交于 2020-01-06 22:03:56
反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释。 一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。 Apple apple = new Apple ( ) ; //直接初始化,「正射」 apple . setPrice ( 4 ) ; 类加载器 类的加载:当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。 获取Class对象的三种方式: 1.通过类名获取 类名.class 2.通过对象获取 对象名.getClass() 3.通过全类名获取 Class.forName(全类名) 一个类在加载过程中的三部曲: 1.加载 就是指将class文件读入内存,并为之创建一个Class对象. 任何类被使用时系统都会建立一个Class对象。 2.连接 验证 是否有正确的内部结构,并和其他类协调一致 准备 负责为类的静态成员分配内存,并设置默认初始化值 解析 将类的二进制数据中的符号引用替换为直接引用 3.初始化 系统给出的默认值 类的加载时机(重点) 创建类的实例 访问类的静态变量,或者为静态变量赋值 调用类的静态方法 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象 初始化某个类的子类 直接使用java

JAVA字节码文件之第一篇(结构)

眉间皱痕 提交于 2020-01-06 21:57:27
开发工具:IEDA、JDK1.8、WinHex 一、字节码文件结构 .Class 字节码中有两种数据类型: 字节数据直接量:这是基本的数据类型。共细分为 u1 、 uZ 、 u4 、 u8 四种,分别代表连续的 1 个字节、 2 个字节、 4 个字节、 8 个字节组成的整体数据。 表(数组):表是山多个基本数据或其他表,按照既定顺序组成的大的数据集合。表是有结构的,它的结构体现在:组成表的成分所在的位置和顺序都是已经严格定义好的。 Class字节码文件的整体结构 二、Demo分析 源代码:该代码贯穿整个字节码学习的章节 package com.jalja.java.bytecode; /** * @Auther: XL * @Date: 2020/1/4 12:58 * @Description: */ public class BytecodeTest { private int num=1; public int getNum() { return num; } public void setNum(int num) { this.num = num; } } javap -verbose 分析一个字节码文件,会输出字节码文件的魔数、版本号、常量池、类信息、类的构造方法、类中方法的信息、类变量与成员变量等信息 F:\workspace\IDEA\study\jalja-base

python中的函数、生成器的工作原理

浪尽此生 提交于 2020-01-06 14:15:25
1.python中函数的工作原理 def foo(): bar() def bar(): pass python的解释器,也就是python.exe(c编写)会用PyEval_EvalFramEx(c函数)运行foo()函数 首先会创建一个栈帧(stack Frame),在栈帧对象的上下文里面去运行这个字节码。 import dis print(dis.dis(foo)) #打印字节码 可以尝试着去打印foo的字节码: 关于字节码的解释: LOAD_GLOBAL:首先导入bar这个函数 CALL_FUNCTION:执行bar函数 POP_TOP:从栈的顶端去把元素打印出来 LOAD_CONST:返回结果,这里没有return,就是None RETURN_VALUE:返回结果 打印bar的字节码: print(dis.dis(bar)) 这个字节码全局是唯一的,函数是全局唯一的,然后在函数里面会调用另外一个函数。 当foo调用函数bar,又会创建一个栈帧,然后将这个函数的控制权交给这个栈帧。 所有的栈帧都分配在内存中,它不是放在栈的内存上,而是放在堆的内存上,你不去释放它就会一直存在我们的内存当中。 这就决定了栈帧可以独立于调用者存在,比如就算函数不存在了,只要有指针指向bar这个栈帧,就可以对其进行控制。 (python中一切皆对象,栈帧也是对象,是一个字节码对象) import

AOP与IOC区别

穿精又带淫゛_ 提交于 2020-01-05 06:05:48
Spring核心知识 Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。 为什么说Spring是一个一站式的轻量级开源框架呢?EE开发可分成三层架构,针对JavaEE的三层结构,每一层Spring都提供了不同的解决技术。 • WEB层:SpringMVC • 业务层:Spring的IoC • 持久层:Spring的JDBCTemplate(Spring的JDBC模板,ORM模板用于整合其他的持久层框架) 从上面的简要介绍中,我们要知道Spring的核心有两部分: • IoC:控制反转

Node.js和Chrome V8 引擎了解

左心房为你撑大大i 提交于 2020-01-05 02:58:20
说起Node就不得不先介绍一个Chrome V8 引擎。 随着Web相关技术的发展,JavaScript所要承担的工作也越来越多,早就超越了“表单验证”的范畴,这就更需要快速的解析和执行JavaScript脚本。 而JavaScript本质上是一种解释型语言,与编译型语言不同的是它需要边执行边解析,而编译型语言在执行时已经完成编译,可直接执行,有更快的执行速度。V8引擎就是为解决这一问题而生,在node中也是采用该引擎来解析JavaScript。 V8引擎是一个JavaScript引擎实现,最初由一些语言方面专家设计,后被谷歌收购,随后谷歌对其进行了开源。V8使用C++开发,,在运行JavaScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。V8支持众多操作系统,如windows、linux、android等,也支持其他硬件架构,如IA32,X64,ARM等,具有很好的可移植和跨平台特性。 另外,JavaScript引擎的执行过程大致是: 源代码-→抽象语法树-→字节码-→JIT-→本地代码(V8引擎没有中间字节码)

java 虚拟机原理

青春壹個敷衍的年華 提交于 2020-01-04 17:59:12
什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,是一个虚构出来的计算机,它屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码,ByteCode), 就可以在多种平台上不加修改地运行。这背后其实就是JVM把字节码翻译成具体平台上的机器指令,从而实现“一次编写,到处运行(Write Once, Run Anywhere)”。 Java为什么能够跨平台? Java引入了字节码的概念,jvm 只能认识字节码,并将它们解释到系统的API调用。针对不同的系统有不同的jvm实现,有 Linux 版本的 jvm 实现,也有 Windows 版本的 jvm 实现,但是同一段代码在编译后的字节码是一样的。在不同的系统平台上运行是通过JAVA解释器将字节码解释为不同平台的机器码,在不同的 jvm 实现上会映射到不同系统的 API 调用,从而实现代码的不加修改即可跨平台运行。 JVM、JRE、JDK的关系 JRE(Java Runtime Environment,Java运行环境),面向Java程序的使用者,而不是开发者。JRE是运行Java程序所必须环境的集合,包含JVM标准实现及 Java核心类库。它包括Java虚拟机、Java平台核心类和支持文件 JDK(Java Development Kit

01Java代码是怎么运行的

末鹿安然 提交于 2020-01-04 01:14:22
从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执行方法区内的代码。 在运行过程中,每当调用进入一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。这个栈帧的大小是提前计算好的,而且 Java 虚拟机不要求栈帧在内存空间里连续分布。 硬件 从硬件视角来看,Java 字节码无法直接执行。因此,Java 虚 大专栏 01Java代码是怎么运行的 拟机需要将字节码翻译成机器码。 HotSpot 在 HotSpot 里面,上述翻译过程有两种形式:第一种是解释执行,即逐条将字节码翻译成机器码并执行;第二种是即时编译(Just-In-Time compilation,JIT),即将一个方法中包含的所有字节码编译成机器码后再执行。 前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。 来源: https://www.cnblogs.com/lijianming180/p/12147688.html

JAVA运行时数据区

与世无争的帅哥 提交于 2020-01-03 23:04:22
引 JAVA虚拟机在执行JAVA程序的时候,会把它所管理的内存区域划分成若干个不同的数据区域。每个区域都有各自的功能,也有各自的创建和销毁时间,有的区域可能随着虚拟机的进程的启动而存在,有的区域可能根据用户线程的启动和结束来创建及销毁。 根据《Java虚拟机规范(JavaSE 7版)》的规定,Java虚拟机所管理的内存会被划分成以下几个运行时数据区域 下面将详细讲述各个数据区的作用 程序计数器(Program Counter Register): 程序计数器是一块比较小的内存区域,可以把它看成当前线程正在执行的字节码的行号指示器,虚拟机在解释字节码的时候,就是根据这个玩意来知道下一条需要执行的字节码在哪里(并非一定一行一行执行,如果遇到类似汇编中的jmp指令,可能会跳转到非下一行的指令),分支、跳转、循环、异常处理、线程恢复(比如被notify唤醒的线程)等基础功能都需要依赖于这个计数器。 Java虚拟机的多线程,它通过多个线程切换并分配CPU执行时间(CPU时间片)来实现多线程。也就是说,在一个瞬间(某一个确定的时刻),一个处理器(对于多核处理器来说,是指一个核心处理器)都只会执行一条线程中的指令。因此,在线程恢复后,为了能让该线程可以知道已经执行到哪一条指令,所以每一个线程都会有一个独立的程序计数器,独立工作,独立存储,互不影响,我们把这样每一个线程都会有的独立区域叫做

Java程序运行原理分析

梦想与她 提交于 2020-01-03 21:25:13
一、Java内存区域 线程隔离(独占)的数据区:虚拟机栈、本地方法栈、程序计数器 每个线程都会有它独立的空间,随线程的生命周而创建和销毁 所有线程共享的数据区:堆、方法区 所有线程都能访问这块内存数据,随虚拟机或GC而创建和销毁 1、程序计数器 程序计数器可以看作是当前线程所执行的字节码的行号指示器。字节码解释器就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何Out0fMemoryError情况的区域。 2、Java虚拟机栈 虚拟机栈是描述Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至执行完成的过程