在前一章节我们简单的谈论了编译器和解释的区别,因为说的比较简单,所以我打算用这一章的篇幅去谈一下编译器,然后再谈一下解释器。
我个人认为,作为一个程序员我们需要去了解编译器的一个工作流程,这样对我们代码的组织会有清晰的一个认知,增加我们对程序本身的理解。很多人可能并不关心编译,我尽量用比较浅显明白的语言将程序编译的流程说清楚,如果非必要,我不太会插入太多的图表去解释,因为我觉得文字的描述才是最精确的。
现在我们都用IDE去写代码。然后编译程序,最后成个一个可执行的文件(在windows系统中,我们看到的是.exe结尾的文件,在linux系统中,可执行文件没有后缀名)或者一个war包,jar包(注意这里的war包或者jar包也可以理解为编译,将java的源码编译成了字节码,在前一章我们讲过,字节码是与平台无关的,所以你的jar包可以部署在windows上,也可以部署在linux,mac上,无需再次编译)。
如果早期写过c或者c++的同学,其实编译的时候,生成后缀名为lib或者dll(linux中的动态链接库为.so后缀结尾)的文件,这两个文件都可以称之为库文件,库文件一般都是被别的代码调用的文件。lib我们称之为静态库,dll为动态链接库,这两个文件的不同之处是加载的方式。静态库lib顾名思义,就是在编译成可执行文件的时候就需要将这个库文件要嵌入到可执行文件中,所以可执行文件包含了静态库的内容;动态链接库相反,在编译的时候并不需要加载到可执行文件中去,只有在程序运行的时候根据需要再从外部加载到内存中。那么问题来了,为什么需要这样做?
先说静态库,它的特点就是1,比较稳定,因为可执行文件本身就包含了静态库内容,不存在兼容性的问题(版本不对的问题);2,加载的时间很短,因为动态库文件在程序启动的时候就加入了内存;3,无法被多个程序共享,如果多个程序都需要这个静态库,那么这个静态库对每个程序来讲,都需要一份独立的拷贝,这样会占用内存。4,如果你静态库需要更新,需要重新编译所有使用该库