第一行代码 Hello world 背后的逻辑
第一行代码 Hello world 背后的逻辑
计算机俗称电脑,只不过它是一种通过通电来模拟人脑的工具,是一种可以进行数学、逻辑运算,还具有存储记忆功能的智能设备,目前是人类的小助手。计算机是以为人类服务为宗旨的。我们人类希望计算机以后能真的像人一样去工作,从而解放人力,这是对计算机的终极目标。 记得上大学时第一门接触的语言是C语言,后来又陆续接触到Java,Php,Python,Go等,入门的第一行代码都是hello world,但是,你真的了解hello world是如何产生的吗?下面我们来一起探讨下Java语言第一行代码是如何执行的,当然,在这之前,我们需要提前了解以下小知识
1.计算机硬件知识
2.计算机操作系统知识
3.计算机语言发展史
4.JVM(Java Virtual Machine) java虚拟机
下面我们一起聊下这几个知识点:
1. 计算机硬件知识
1.1 计算机硬件组成
1.1.1 控制器
是计算机的指挥系统,负责控制计算机其他硬件的运行,相当于人的大脑
1.1.2 运算器
包括数学运算和逻辑运算,相当于人的大脑
控制器+运算器=CPU(central processing unit 中央处理器)
1.1.3 存储器
1.1.3.1 内存(主存)
如内存条(又称随机存储器),存取速度快,但是基于电工作,一旦断电数据就丢失,只能临时存储。类似于人的记忆功能,容易断片。
1.1.3.2 外存
如硬盘,存取速度相对内存很慢,数据可以近似“永久”保存。类似于使用的笔记本
1.1.4 输入设备(Input)
计算机接收外界输入数据的工具,如键盘、鼠标等
1.1.5 输出设备(Output)
计算机向外输出数据的工具,如显示屏、打印机等
1.2 CPU、存储器 之间的关系
CPU:负责运行人类的程序,人们通过程序控制CPU,再通过CPU控制计算机其他硬件,其存取的数据指令都来自于内存,由于内存只能保存临时数据,而CPU必须通过内存读取数据,故电脑在开机的时候会将部分数据从硬盘加载到内存 。
1.3 计算机分代
1.3.1 第一代计算机
真空管和穿孔卡片(真空管易烧断、浪费计算机资源、串行)
1.3.2 第二代计算机(大型机)
晶体管和批处理系统(晶体管提高了计算机的可靠性)
1.3.3 第三代计算机
集成电路芯片和多道程序设计技术 ( 不再需要人的参与,解决了人参与的耗时问题,基于通道技术实现了CPU和IO设备的并行)
1.3.4 第四代计算机
大规模集成电路芯片,微处理器的发明导致了个人计算机(微型计算机)的普及
由于计算机越来越普及,让操作系统的存在存在了重要意义,它隐藏了丑陋复杂的硬件接口,并提供管理、调度进程,将多线程对硬件的竞争变得更加有序。
2、操作系统
2.1 操作系统
能够控制,协调、管理计算机硬件资源和应用软件资源的一类控制程序。现流行的操作系统有:Windows、Linux、Mac等
2.2 操作系统的意义
控制计算机硬件的基本运行,将计算机硬件复杂的操作细节封装成简单一致的接口(功能)供上层应用软件或用户使用
2.3 程序、进程、线程的区别
2.3.1 程序
是一组计算机语言编写的指令的有序集合(一堆代码)
2.3.2 进程
可定义为正在执行的程序,在计算机中执行的任何程序实例都可称为进程,一个程序可以有多个进程。比如:QQ,支付宝
2.3.3 线程
是指某一进程中单独运行的子程序,可看作轻量型进程,可以看做是进程中运行代码的过程,所以线程存在于进程中,一个进程由一个或多个线程组成。
由于各种各样操作系统的存在,让计算机高级语言的开发变得复杂
3. 计算机语言发展史
3.1 第一代语言:机器语言
机器语言是机器能直接识别的程序语言或指令代码,无需经过翻译。
我们都知道计算机的基本计算方式都是基于二进制的方式。如下就是一段典型的机器语言代码:
这种代码计算机可以直接执行,它舒服了,可是人不爽啊,这些语言机器能识别,我们不好操作啊,So , 第二代计算机语言产生了
3.2 第二代**语言:**汇编语言。
汇编语言用一些简单的助记符代替了操作码,用地址符号或标号代替地址码。这用符号代替了机器语言的二进制码。所以,汇编语言也称为符号语言。
比起机器语言,汇编语言已经算大大进步了,至少有部分符号是我们人类定义的,至少部分符号可以很直观的看懂了,但这还不够,于是第三代语言产生了。
3.3 第三代语言:高级语言。
高级语言就进入了“面向人类”的语言,这个时候大部分代码人类都是能看懂的,但是机器不care啊
所以,这个时候就需要一个应用程序去将人类的语言翻译成机器语言,就相当于人类的翻译官。
package org.example;public class HelloWorld {public static void main(String[] args) {System.out.println("Hello world");}
}
后续我们根据jvms相关规则来解读下这个class文件
JVM的出现屏蔽了平台,无需关心操作系统,使高级语言开发成本大大降低
4 JVM(Java Virtual Machine) java虚拟机
4.1 JVM的定义
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
4.2 JVM的作用
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。JVM屏蔽了与具体平台相关的信息,使得编译程序只需生成符合在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
5 终章:Java中Hello world是如何打印出来的
经过以上及部分的了解,下面我们基于以上知识串一下 Hello world到底是如何打印出来的
5.1 预准备事项
语言:JAVA
首先: 要有硬件 (CPU + 内存 + 外存 )
其次: 也要有软件 ( 各种操作系统 )
最后: 还要有JDK( Java Development Kit ) Java 语言的软件开发工具包,JDK安装,环境变量及PATH配置请提前准备好,JDK包含JVM及其他的一些工具包
5.2 class文件详解
以上都准备好之后,安装 JDK, 安装完成之后,就该我们的HelloWorld.java出场了
package org.example;public class HelloWorld {public static void main(String[] args) {System.out.println("Hello world");}
}
之前说过,HelloWorld文件是人类识别的语言,可这玩意计算机不认啊,那咋办?
话不多说,请我们的翻译官javac上场,
5.2.1 编译
javac HelloWorld.java
对应的class文件如下
javac将 java 文件按计算机的要求翻译成计算机能识别的二进制文件,
在编译的过程中Java会有一些常规的校验,比没有漏掉括号,分号之类的,
如果都通过,这个时候就会将.java文件编译成对应的.class文件
5.2.2 class文件结构
下面我们可以通过jdk自带的工具javap 看下这个文件的结构如下
我们可以看到这个类大小是557 bytes
通过jdk1.8编译的
有33个常量
两个方法,一个默认参数为空的构造方法,一个main方法
还有一些堆栈相关的信息
如果有同事感兴趣,后续可以根据 JVMS详细解读下上面的class文件
D:\ws\target\classes\org\example>javap -verbose HelloWorld.class
Classfile /D:/ws/target/classes/org/example/HelloWorld.class
Last modified 2021-8-10; size 557 bytesMD5 checksum 3a131c437ac2a08603d1d167500d29feCompiled from "HelloWorld.java"
public class org.example.HelloWorldminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPERConstant pool:#1 = Methodref #6.#20 // java/lang/Object."<init>":()V#2 = Fieldref #21.#22 // java/lang/System.out:Ljava/io/PrintStream;#3 = String #23 // Hello world#4 = Methodref #24.#25 // java/io/PrintStream.println:(Ljava/lang/String;)V#5 = Class #26 // org/example/HelloWorld#6 = Class #27 // java/lang/Object#7 = Utf8 <init>#8 = Utf8 ()V#9 = Utf8 Code#10 = Utf8 LineNumberTable#11 = Utf8 LocalVariableTable#12 = Utf8 this#13 = Utf8 Lorg/example/HelloWorld;#14 = Utf8 main#15 = Utf8 ([Ljava/lang/String;)V#16 = Utf8 args#17 = Utf8 [Ljava/lang/String;#18 = Utf8 SourceFile#19 = Utf8 HelloWorld.java#20 = NameAndType #7:#8 // "<init>":()V#21 = Class #28 // java/lang/System#22 = NameAndType #29:#30 // out:Ljava/io/PrintStream;#23 = Utf8 Hello world#24 = Class #31 // java/io/PrintStream#25 = NameAndType #32:#33 // println:(Ljava/lang/String;)V#26 = Utf8 org/example/HelloWorld#27 = Utf8 java/lang/Object#28 = Utf8 java/lang/System#29 = Utf8 out#30 = Utf8 Ljava/io/PrintStream;#31 = Utf8 java/io/PrintStream#32 = Utf8 println#33 = Utf8 (Ljava/lang/String;)V{
public org.example.HelloWorld();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 3: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lorg/example/HelloWorld;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc #3 // String Hello world5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 5: 0line 6: 8LocalVariableTable:Start Length Slot Name Signature0 9 0 args [Ljava/lang/String;}SourceFile: "HelloWorld.java"
编译好之后,就静静的躺在硬盘上等着JVM的加载
5.3 启动
通过
java HelloWorld
启动HelloWorld程序,
在启动程序的过程中,
程序首先启动JVM,
通过ClassLoader ( 类加载器 ) ,并以双亲委派机制,找到对应path下的class文件,将HelloWorld.class文件从硬盘经过一系列(loading -> linking -> initializing)的过程加载到JVM。
然后找到入口方法main方法,
看下我们之前通过javap查看的这个栈帧相关的信息,
如函数名称,参数,最大栈深度,本地变量容量,传入参数个数,以及栈帧相关操作,局部变量表等等
public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc #3 // String Hello world5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnLineNumberTable:line 5: 0line 6: 8LocalVariableTable:Start Length Slot Name Signature0 9 0 args [Ljava/lang/String;
通过一系列的入栈,出栈以等操作,从而打印出Hello world这几个字符串。
这就是JAVA的第一行代码Hello world执行的整个过程,以上内容仅为个人理解,如有不对的地方欢迎大家探讨指正。
参考文献:
《深入理解Java虚拟机》 第二版 周志明著
《The Java Virtual Machine Specification, Java SE 8 Edition》
第一行代码 Hello world 背后的逻辑相关推荐
- Kotlin 基础语法(《第一行代码(第三版)》第二章读书笔记)
资源来自<第一行代码>(第三版)第二章 网络试读: https://www.ituring.com.cn/book/tupubarticle/30209 以下为笔记 转存失败重新上传取消正 ...
- thymealf如何实现传单个变量给html_梦回2013,看尤大vue的第一行代码,如何用30行代码实现vue(超简洁,适合初学者)...
非非非标题党,干货预警!!! 介绍 大家好,我是清池交友 app 开发日记,记录清池交友 app 开发中学习过程和踩坑日记,伪全栈[1] 技术栈:前端 js,vue,uniapp,后端 java 尤大 ...
- 有奖互动 | 秋天的第一行代码
活动信息 活动时间 2021年9月17日-9月23日 活动规则 登录NGINX社区网站在活动主贴留言,评选出10位获奖者 活动奖品 NGINX社区独家定制的精美纪念T恤衫1件 参与方式 主贴活动传送门 ...
- python第一行代码_“少年py”001:下载Python软件,写第一行代码
Python,网络上称之为人工智能时代的第一编程语言. 功能超级强大,能做科学计算.大数据处理.网络爬虫.游戏开发等等. 但是说实话,彬哥玩Python还没到这么厉害的程度,究竟怎么实现,我们不着急, ...
- 《第一行代码》总结之简介、Activity(一)
第一行代码安卓-第二版 ...
- 第一行代码第三版笔记
第3章 Activity 主acitivity:程序运行起来首先启动的activity manifest <?xml version="1.0" encoding=" ...
- 第一行代码——第十三章:继续进阶——你还应该掌握的高级技巧
目录: 13.1 全局获取 Context的技巧 13.2 使用 Intent传递对象 13.2.1 Serializable 方式 13.2.2 Parcelable 方式 13.3 定制自己的日志 ...
- Android第一行代码学习思考笔记(碎片、广播、持久化技术和Android数据库)
Android第一行代码学习思考笔记(碎片.广播.持久化技术和Android数据库 第四章 手机平板要兼顾--探究碎片 4.1碎片是什么(Fragment) 4.2碎片的使用方式 4.2.1碎片的简单 ...
- 《第一行代码》总结之实战酷欧天气、发布应用(九)
第十四章:进入实战,开发酷欧天气 实现一个功能较为完整的天气预报程序.中文:酷欧天气:英文:Cool weather 14.1功能需求和技术可行性分析. (1)应具备以下功能 ...
最新文章
- 一个接口是如何在Keycloak和Spring Security之间执行的
- python excel绘图-Python excel 画图
- 关于CSS属性display:none和visible:hidden的区别
- andrew ng machine learning week4 神经网络
- Android开发常用命令
- java tostringutils_Java之StringUtils的常用方法
- 怎样升级android10版本,手机怎么升级win10系统 win10手机版升级教程
- contentsize and frame
- 几个IE与Firefox的兼容性问题 (一、网络转载)
- html中单双引号镶嵌
- javascript中eval解析JSON字符串
- JUC与JVM并发编程学习笔记04
- java 绩效考核系统源码_基于jsp的企业绩效考核系统-JavaEE实现企业绩效考核系统 - java项目源码...
- dac生成信号频率取决于_关于高速AD/DAC测量及设计中82个疑难问题的解答
- Qt开发,应用程序错误,应用程序无法正常启动0xc000007b
- jsf服务_JSF ManagedBean ManagedProperty
- Verilog设计4位CLA加法器电路,并仿真测试
- 调试程序基本步骤方法
- Ubuntu中使用RoboMongo实现MongoDB的可视化
- 机器学习入门要学习什么内容呢?