美国上市公司,专注Java培训21年

C老头和Java小子的硬盘夜话


这是一个程序员的电脑硬盘, 在一个叫做“学习”的目录下有两个小程序, 一个叫做Hello.java , 另外一个叫做hello.c 。

Hello.java 自视甚高,有点看不起老派的hello.c , 经常叫他“C老头”。

这hello.c 也瞧不起“嚣张”的 java 程序, 也给他起来一个外号: “Java 小子”。

但是这个目录下没有其他人, 每天深夜,主人睡去以后就是无边的黑暗和无尽的孤独, 尽管互相看不顺眼, C老头和Java小子还是得聊聊天解闷。

“C老头儿, 我听说你们C语言在诞生的时候也是以可移植性著称?” Java 小子率先发难,充分发挥了中国人话里有话,笑里藏刀的特点。可移植性是Java最引以为傲的亮点, 编写一次,处处运行可不是说着玩的, 他决定以己之长攻彼之短,先给C老头挖个坑, 等他入坑后再羞辱他一番。

“哪里哪里, 我们可比不上你们Java ” 没想到C老头竟然不跳坑, Java 小子的招数被化于无形。

“那你们怎么号称移植性好啊,难道在Windows平台上开发的程序能运行在Linux上?” Java小子心有不甘,继续穷追不舍。

“我们那是代码的可移植性,不是程序的可移植性,比方说吧, 像我这个hello.c 可以在windows上编译运行, 也可以在Linux上编译运行, 完全不用修改代码。 ”

C老头和Java小子的硬盘夜话

Java 小子感到很吃惊, 这是一次编写到处编译啊, 好像不比自己差啊。 他觉得有点沮丧,看来这一板斧砍不下去了。

可是转念一想, hello.c只是个非常简单的程序,像Windows、Linux上都有他的编译器和标准程序库, 那肯定可以移植了, 要是使用了系统平台的接口了呢?

“你要是调用了Windows平台的API,例如创建一个线程,拿到Linux上怎么办?”

“那我们C语言就用条件编译” C老头早就料到Java小子会这么问。

C老头和Java小子的硬盘夜话

“哈哈,有没有搞错, 这么麻烦啊,源代码中这么多古怪的#ifdef, 程序员们还不累死。 ” Java小子终于抓住了把柄。

“这已经很不错了,在我们C语言刚刚诞生的时候, 可是上个世纪70年代, 根本没有什么Java虚拟机之说, 没有什么抽象层能屏蔽底层的平台API, 可不得辛苦程序员?” C老头说得很客观,Java 小子的嚣张的气焰消失了大半。

“那C语言怎么不与时俱进,也搞个虚拟机啊” Java 小子异想天开。

“这你就不懂了, C语言生来就是做系统级编程的,就是要贴近硬件,追求性能和效率,弄个虚拟机,我怎么去直接操作内存? 和硬件交互? 对了,我们可以用指针可以直接操作内存,效率极高, 你的Java就不行了吧”

“Java 当然没有指针了, 那玩意儿太容易出错,也容易出现漏洞, 我们的James Gosling老爹就禁止我们直接操作内存。”

“我们C语言一旦编译链接以后,就成为一个可以独立执行的程序了, 而你呢,只是变成一个Hello.class 而已,没有虚拟机, 你都运行不了, 说得难听一点, 就是一个寄生虫啊。” Java 老头不动声色,开始组织反击。

Java 表示无言以对。

“还有啊, 我的hello.exe一旦运行, 那就是一个独立的进程,拥有一个独立的地址空间,被CPU独立调度; 而你的Hello.class 什么都不是, Java虚拟机(java.exe)才是一个进程,Hello.class 被装载以后只能在这个进程里作为一个线程来运行, 生活的空间也就是什么方法区、堆..... 这境界也差得太远了吧”

姜还是老的辣, C老头招招致命。

"等等, 你刚才说了一个什么词来着,链接?这是什么鬼东西?" Java 小子抓住了一根稻草。

“链接你都不懂? 真够老土的, 赶紧去看看《深入理解计算机系统》第7章吧。 简单来说是把一个符号和这个符号的地址给绑定起来。”

“我只看过《深入理解Java虚拟机》 , 没看到什么链接啊, 你那个定义太抽象了,没人能听懂!”

C老头心里鄙视了一下Java小子,所学果然浅薄, 盘算着举个例子来说明下什么是链接。

“你知道编译是怎么回事吗? ” C 老头打算另辟蹊径给Java讲讲。

“那我肯定知道啊, 我这个Hello.java经过编译以后,不就变成Hello.class了”

“我们C语言的程序,经过预处理,编译,汇编等步骤以后,能变成一个叫做'目标文件' 的东西”

C老头和Java小子的硬盘夜话

“假设我这个hello.c程序又调用了cal.c中的函数add :”

hello.c :

C老头和Java小子的硬盘夜话

cal.c :

C老头和Java小子的硬盘夜话

“那就会生成两个目标文件, hello.o 和 cal.o”

C老头和Java小子的硬盘夜话

Java 小子问道: “难道你这个hello.o 不能执行吗? ”

“那肯定不能执行,你看那个add函数的定义是在cal.o 这个目标文件中, 我hello.o中根本就没有啊!怎么执行? 所以编译器只好在hello.o 中记录类似这样的东西:hello.o 中需要调用add 函数,但是这个函数的实际地址不在本文件中,链接的时候需要找到实际地址,把它给替换掉! 替换的过程就是一个重定位的过程 , 这一步做完了,才可以执行。 ”

C老头和Java小子的硬盘夜话

Java 小子说: “不对吧, 假设我也调用了另外一个类Calculator.java 中add方法, 我们俩编译以后生成两个class 文件,这两个文件完全独立, 不用做链接, 直接就可以运行啊。 ”

C老头和Java小子的硬盘夜话

“你们肯定会做链接的,只不过这个链接不是在编译期做的,而是在运行期做的。 等到Hello.class被装入你的Java虚拟机运行的时候, 会发现有个指令要调用Calculator的add方法, 这个时候就需要装载Claculator.class ,找到add方法来调用执行。 这也是一种链接,只不过是运行时的动态链接而已。” C老头做了一个总结陈述。

Java 小子现在明白了C老头说的链接的含义: 把一个符号(add函数的名称)和这个符号的地址(add函数的真正地址,那里有add函数的指令)给绑定起来。

“这老头还挺厉害嘛” Java小子心里不由得对C老头产生了敬意, 他决定从明天开始,不再叫他C老头了,叫他老师, 向他多多请教。

眼看着天马上亮了,两人互道晚安。

第二天半夜,Java小子兴冲冲地找C老师讨教, 可是hello.c已经找不到了, 同一个目录下来了一个叫做hello.py的新家伙, 他热情地对Java小子打打招呼: “你好,我是Python,初来乍到,请多多关照。”

“你知道hello.c去哪儿了吗?”

“他呀, 程序员主人觉得C语言的指针太复杂了,实在是学不会,就放弃了, 顺便把hello.c给删除了。 ”

(完)

感谢大家阅读由java职场分享的“C老头和Java小子的硬盘夜话”希望对大家有所帮助,更多精彩内容请关注Java培训官网

免责声明:本文由小编转载自网络,旨在分享提供阅读,版权归原作者所有,如有侵权请联系我们进行删除


【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,如涉及作品内容、版权和其它问题,请在30日内与我们联系,我们会予以重改或删除相关文章,以保证您的权益!

Java开发高端课程免费试学

大咖讲师+项目实战全面提升你的职场竞争力

  • 海量实战教程
  • 1V1答疑解惑
  • 行业动态分析
  • 大神学习路径图

相关推荐

更多
  • 程序员进阶:成为更好程序员的8种途径
    程序员进阶:成为更好程序员的8种途径
    本文讲述了8种方式帮助你如何从一名普通的程序员进阶成为一名伟大的程序员,让我们就从此时此刻开始提高自己的开发技能吧。 详情>>

    2017-11-06

  • 1024程序员节
    1024程序员节
    1GB=1024M,而1GB与1级谐音,也有一级棒的意思。从2014年起,每年10月24日定义为程序员节。 详情>>

    2017-10-23

  • Java程序员面试失败的五大原因
    Java程序员面试失败的五大原因
    下面是 Java程序员面试失败最有可能的5大原因,当然也许这5点原因适用于所有的程序员,所以,如果你是程序员,请认真阅读以下内容。 详情>>

    2017-10-25

  • Java开发工程师前途何在?
    Java开发工程师前途何在?
    经常听见有人这样说:现在JAVA开发工程师前途何在,到底有没有前途呢?怎样才能做一个好的JAVA工程师,我的路应该如何去走。我是新手,不知道这个专业怎么样,看见好多人都在埋怨软件开发辛苦、挣得少,事实如此吗? 详情>>

    2018-05-23

  • Java开班时间

    收起