Skip to content
📌知识点小结
  • 编译型语言(C/C++、Go)先整体翻译成机器码再运行,运行快、产物是可执行文件。
  • 解释型语言(Python、JS)由解释器在运行时逐行翻译执行,灵活、跨平台、便于调试。
  • Java 介于两者之间:先编译成 .class(字节码),再由 JVM 解释/JIT 执行。
  • JIT 即时编译:运行时把热点字节码再编译成机器码,兼顾灵活与速度。
✅自测一下

0.30 编译型与解释型:程序是怎么跑起来的 ​

第〇篇【零基础预科】免费。不管用哪种语言写代码,最终都要变成 CPU 能懂的东西才能跑。这一篇讲清两条路:编译和解释。

CPU 只懂一种极其原始的机器码,而你写的 Python、C 代码人能看懂、机器看不懂,所以中间必须有个"翻译"。翻译的时机不同,就分成了两条路:编译像"整本书写完、一次性翻译好再出版",解释像"现场一句句同声传译"。搞清这个,你才知道为什么有的语言改完就能跑、有的得先编译一下。

一、编译型:先翻译完再跑 ​

1. 代表:C、C++、Go ​

  • 写好源码(.c 等);
  • 用编译器整体翻译成机器码;
  • 产物是可直接运行的程序(.exe 或无后缀可执行文件);
  • 运行快,但换操作系统要重新编译。

用生活例子讲:编译型像交一篇论文前,先找翻译整本译好、装订成册,之后读者(CPU)直接读成品,速度快。代价是——你想让这本书给另一套"读者"(另一套操作系统/CPU)看,就得重新翻译一遍。这也是为什么 Windows 上的 .exe 拿到 Linux 上不能直接跑:它已经被翻译成了"只适合 Windows 这台机器读"的东西。

你可能会问:编译是好事还是坏事?为什么不全都编译? 编译跑得快,但"编译"这个动作本身要花时间,而且编译出来的东西和平台绑死。对写检测脚本这种"小、改得勤、要到处跑"的活,编译反而是累赘——你总不能改一行就重新编译一次再运行。所以语言选型从来没有绝对好坏:要极致性能、又能接受编译成本,选编译型;要灵活、跨平台、迭代快,选解释型。安全人两边都会碰到,知道各自的脾气就行。

2. 解释型:边解释边跑 ​

  • 代表:Python、JavaScript;
  • 没有"先编译"这一步;
  • 由解释器在运行时逐行翻译执行;
  • 灵活、跨平台、便于调试;
  • 运行相对慢一些。

解释型像开一场现场同传:演讲者说一句,译员当场翻一句。好处是灵活——改了一句立刻就能讲,不用整本重译;同一份 Python 源码,只要机器上装了解释器,Windows、Linux、macOS 都能跑。坏处是慢:因为每次都要现场翻译,多了这一层开销。你写的检测脚本大多是 Python,改完直接 python xxx.py 就跑,不用先"编译",就是这个原因。

二、Java 介于两者之间 ​

Java 的做法是两步走:

  1. 先用 javac 把 .java 源码编译成 .class 字节码(不是机器码);
  2. 再交给JVM运行。JVM 先解释字节码,热点代码再用 JIT 即时编译成机器码跑。

字节码不是给某台具体 CPU 的机器码,而是给 JVM 这种"虚拟 CPU"的指令,所以同一份 .class 在装了 JVM 的 Windows、Linux 上都能跑——这就是"一次编译,到处运行"。JIT(即时编译)则是个折中:运行时发现某段代码被反复执行(热点),就顺手把它编译成机器码缓存起来,下次直接跑快的,既保留了跨平台的灵活,又不至于一直慢。

你可以把 JVM 想成一台"虚拟机":它在你真实的操作系统里再模拟出一台专门跑 Java 的小机器。真正的操作系统不认识 .class,但 JVM 认识;有了这层中间的小机器,Java 程序就被"挡"在了和真实平台无关的位置上。这也是为什么很多企业级后台系统爱用 Java——写一份、哪儿都能部署,不用为不同系统各维护一版。

你可能会问:那我学安全,到底该关心哪种? 你日常写检测脚本用的是 Python 这种解释型,改完即跑、迭代快;但你打的靶标里,很多中间件(如 Tomcat 跑的 Java 应用)是 Java 生态。知道它"源码→.class→JVM"这条链,你看到漏洞 PoC 里出现 .class、.jar 这类文件,就不会觉得陌生——它们是 Java 程序跑起来的中间产物。

三、对安全学习者的意义 ​

  • 解释型的 Python 适合写检测脚本:改完马上跑,不用编译,跨平台;
  • 像 Java 这类带字节码/虚拟机的生态,目标程序常是 .class/.jar,分析时要认 JVM 这层;
  • 知道"程序怎么跑起来",才看得懂漏洞利用里"让目标执行我们的代码"到底执行的是什么。

最后这点值得多说一句。所谓"拿到 shell""执行我们的命令",本质都是让目标机器把某段数据当成代码去翻译、去跑。你现在明白了"代码要先翻译成机器码才会被 CPU 执行",回头再看那些"注入一段让程序自己执行的输入",就明白它在钻哪个空子了——这正是编译/解释这套底层知识和漏洞之间的连接点。

再补一个和你后续实操直接相关的感受。以后你下到一个漏洞 PoC,可能是一个 .py 文件(解释型,你本机有 Python 就能直接跑),也可能是一个 .jar(Java,得先有 JVM 才能跑起来看效果)。看到文件后缀,你就能大致判断"我该装什么环境才能让它跑起来"——是装个 Python 就行,还是得先把 Java 环境配好。这份"看后缀判断运行方式"的直觉,就是这一篇给你的。

四、本篇小结 ​

  • 编译型:先整体翻译再跑,运行快、要重编译;
  • 解释型:边翻译边跑,灵活跨平台、便于调试;
  • Java 等介于两者之间:源码→字节码→虚拟机运行。
  • 安全上:Python 写脚本,Java 生态认 .class/JVM。

记住这条主线就够:翻译的时机决定了语言的脾气——先整体翻的跑得快但绑平台,边翻边跑的灵活但慢点,Java 这种则是在两者之间找平衡。

下一篇 0.31 讲"怎么读一段没见过的代码"。