码农翻身之大话编程篇:2我是一个Java Class

2023-10-30 11:30

本文主要是介绍码农翻身之大话编程篇:2我是一个Java Class,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第一回    陌生警察
我出生在C盘下面一个很深层次的目录下,也不知道是谁把我放在这里的。我一直在睡觉,外边的日出日落,风雨雷电和我一点关系都没有。
直到有一天,有个家伙咣咣咣砸我房门把我叫醒。这个家伙穿着像警察的制服,左手拿着一个对讲机,右手递过来他的工作证:“你好,我是Classloader,请问你是Account类吗?”
“是啊,怎么了?”
这个人并没有回答我,而是拿起了对讲机:“头儿,你看你能不能装载这个类?”
对讲机那头好像也在问他的上司,过了半天,终于有了回音:
“我装载不聊,我的上级也说了,他们也装载不聊,你来干吧。”
“那就报数吧”这次我注意到旁边站着一个笑眯眯的小个子。
“报什么数?”我一脸懵逼。
“唉,果然没有被装载过,你是个class文件,当然要报文件开头的那几个数了,就是jdk1.0中确定的那个数啦”
“哦,我看看啊,0xCAFEBABABE”
“不错,是个Java类,你把后面两个数也报一下。”
“50,0”
“看来版本不够高啊,是jdk1.6比那一处来的”小个子接着说,“最新的虚拟机都1.8了,都函数式了,知道不?”
我哪里知道,这才模模糊糊想起来,好像是有个什么javac把我创建了出来,扔到了这个屋子里。
“现在奉命带你去Java虚拟机,有人需要你的帮助”Classloader冷冰冰的,我不太喜欢他。
“大哥,你咋找到我的?”我决定跟小个子套近乎。
“那还不简单,我们老板有个列表,上面列举这所有应该检查的目录,我们顺藤摸瓜,一个一个找,肯定能找到。”
“那万一找不到咋办?”
“基本不可能,你看老板给我们的目录列表中有C:\\workspace\myTaobao\bin,我们在下面再找三级com\mytaobao\domain,这不就找到你了么,Account.class,话说回来,万一真的找不到,将来在执行时会抛出ClassNotFound的异常,那不归我们管。”
后来我才知道,原来我全名叫做c om.mytaobao.domain.Account 
        “来来来,让我验证一下你这个class编译方式对不对”,小个子拿出一个放大镜。“嗯,常量池,访问标识,字段,方法。。。看起来没有问题”,小个子对Classloader说。被人拿着放大镜看,这种感觉极为不爽。
        “走,去虚拟机”,Classloader还是冷冰冰的。
        这哥俩不允许我带任何东西,便把我拖上车,飞奔向我从未听说过的“虚拟机”。
                                第二回    刺探信息
        我感到前途未卜,但也不能坐以待毙,一定的多了解信息。
        “大哥,你叫什么名字?”我看小个子还算和气。
        “我就是大名鼎鼎的文件验证器了,我能管很多事。”
        “那刚才为啥还要请示上级呢?”我用眼神治了一下正在开车的Classloader。文件验证器的声音一下子压低了:“你不知道,说来话长,我们之前出过事故,有个黑客写了个类java.lang.String,和老板收下一个干活最卖力的员工名字一模一样,知识这个黑客类里面竟然有格式化硬盘的代码,我们的小冰Classloader不明就里就把这个黑客类给撞在了,也执行了,最后的结果,唉,很惨的。”
        “那后来怎么办?
        “后来老板就定下规矩:他的骨干成员如String,ArrayList等只能由他自己的心腹去装在,我听说老板的心腹都是分层级的,像传销一样,每个都有上限,最顶层的叫 Bootstrap Classloader,下一次级叫做Extension Classloader,现在开车的这位叫做 App Classloader,位于最底层,赞这位在装载一个类之前,一定要问一问几位权利极高的大爷,请他们现状在,这几位装在不聊,才由我们这些小冰来出马。”
        “这样子能避免黑客攻击?”
        “能啊,你想,那个黑客写的攻击类,我们在装载之前,肯定要请示大爷来装在,由于其时核心员工,肯定他们会先装载啊,这样这些大爷就直接将String传给我们了,我们就不会装载黑客类了。”
        “你能不能少说两句”Classloader似乎生气了。
        我和文件验证器只好禁声。
        其实文件验证器也不是只会给我吹牛,他也很敬业,这家伙在车上把我的全部的字节码都要了过去,对这些天输一半的东西一遍一遍地进行检查分析,确保每个指令都是正确的,检查是不是有超类,是不是覆盖了final方法,跳转指令是不是正确
                                        第三回    初试虚拟机
        很快我们就来到了目的地,我一看虚拟机不就是几个大楼吗,不过这几个大楼可真是高啊。
        他们俩把我带进一座叫做“方法区”的大楼,进了电梯,输入2048,很快来到2048层,无数的格子间平铺开来,他们七拐八拐,轻松地把我带进到了我的位置,上面写着我的名字“ com.mytaobao.domain.Account ”。
        我问文件验证器:“这楼这么高,这么多格子间,人会坐满吗?”
        “只有极少情况会坐满,一旦满了,就会抛出异常,我们就完蛋了。你好自为之吧,再见。”他们把我安顿好就离开了。
        我往周边一看,咦,这不是著名的java.lang.String吗。我本想和他打个招呼,可他的电话似乎一直没断过,嘴里一直说着什么store,load之类我听不懂但是有点熟悉的话。正无聊着呢,我电话响了,电脑屏幕也凉了,我看到一个人对我笑着说:“你好,我刚刚new出来的Account对象,我的编号是 Account@659e0bfd
        晕倒!这家伙和我什么关系?看我一脸诧异,他说:“很快就会有个线程到达CPU车间了,他会联系你,我就是确认下你在不在,奥对了,我在一个叫做堆的地方,有空找我玩啊,byebye”,说完就消失了。
        果然没多久,视频电话又响了。这次我看到一个人站在一个明亮的车间,抱着一个包裹,她按了一个按钮,面前like升起一个工作台,台子上立了一个有很多抽屉的柜子,每个抽屉上都有一个编号,旁边还有一个深桶。(后来我就知道,那个柜子的学名叫做局部变区,那个桶叫做操作数栈)
        我正想问问怎么回事呢,就听到了他的声音:“我是线程0x3704,我要调用你的第二个方法了”我一看,我的第二个方法是add:
        Public void add(int x ,int y )
{
    x = x + y ;
 }
“请把第一条指令给我说一下”0x3704继续问我要东西。我还不太熟练,找了半天才说:“iload_0”于是他就从柜子里的机械手吧一号抽屉的一个数30 扔到了工作台上的一个桶里,这个桶很窄,没法并排放两个数,但是很深。

然后他又说:“下一条指令”
“iload_1”
于是一号抽屉的一个数40也被扔到了桶里,从桶上面就看不到30了。

“下一条指令”
“iadd”
于是他就把两个数从桶里取出来,做了个飞快的动作,这两个数变成了一个数70,然后他又把70放到了桶里。

“下一条指令”
“istore_0”
于是他又把70从桶里捞出来,放到了柜子上编号为0的地方,之前的30就被扔掉了。我看的目瞪口呆,这货在干嘛?
我问他:“不是吧两个数加起来吗?为啥搞的这么麻烦?”他不理我,知识继续说“下一条指令”。我只有配合他进行下去。
java.lang.String难的悠闲,端着一杯咖啡一边看我手忙脚乱地取指令,一边说:“新人都这样,别着急,等你熟练了,闭着眼睛就搞定了,就像我一样,你可能不知道,我们这个虚拟机叫做基于堆栈的虚拟机,看到那个桶没有,其实就是个先进后出的栈啊,我们虚拟机的所有指令其实都是对栈进行操作。”
可是我还是好气:“这栈有什么好啊?”旁边的格子间java.util.Stack立刻说:“这事儿你得问我啊,怎么说呢,主要是为了简单,你看我们只用一个简单的栈,就能完成所有的工作,你做的就是往栈里扔东西(入栈),然后从最上面拿东西(出栈)就行了。不像Intel的CPU,搞了巨多的桶,每个桶只能容纳一个数,他们还美名其曰七寸器,做加法的时候,先把一个数放到第一个桶,再把另一个数放到第二个桶,加起来以后的结果害的你找个桶,有些桶还不通用,这么多桶找起来麻烦死了。”
“可是我们的栈操作起来就麻烦了啊,你看一个简单的假发都得操作半天”,我不依不饶地说。“可是我们的指令可以优化啊,不过我不太懂”
这个游戏我整整玩了一天,没有现成找我的时候,我就闲着,String说的对,熟练以后简直太简单了。
String就不一样了,几乎每时每刻都有线程给他打电话要指令,没办法,String确实是虚拟机的骨干和经营,使用频繁,业务纯属,忙而不乱。有时候我会看到线程布置一个工作台,而是一摞子工作台,也是一个压一个,线程们都很老实,永远在最上面那个工作,从来都不会先干下面的活。

我问java.util.Stack:“这些工作台也是栈吧”“猜得不错,学名叫做Java栈,每个线程都有一个,其中的每个工作台你都看过了,学名叫做栈帧,知道不?每个台子都代表一个方法调用,这一罗工作台就是方法调用方法导致的啊”
确实是,因为我发现一旦调用新方法,就会立刻形成一个新的工作台,压在老的上面。方法调用完成后,栈顶的工作台就销毁了,线程会在底下的工作台继续机械的干活。
第四回    快乐假期
第二天,-x3704又问我要指令,我有点生气:“你就不会记住吗?”他说:“我可不能记住,万一你被重新装在了,指令变了怎么办?”
我告诉他指令是“iload_0”,他刚把数据扔到桶里,古怪的事情发生了,神兽敏捷的0x3704突然好像凝固了一样,不动了。
只听到String欢呼:“遇到断点了,码农开始调试了,我们放假了!”
“调试?什么是调试?”
“就是码农会单步,手工执行这些指令,他们慢死了,可能一秒才能执行一步,由于我们的时间比他们快得多,他们的一秒,简直就是我们的只几天,走出去玩去”
“出去玩?能上哪玩?”
“我们去找我们new出来的对象玩去”我想到了之前联系过我的对象 Account@659e0bfd, 想着去看看也不错。
        这个叫做堆的大楼更加拥挤,全是人,String的对象当然最多,String类左右逢源,不停地打招呼,从我创建出来的Account对象几乎找不到。
        一队全副武装的士兵在不停地巡逻,时不时地吧对象拉出来,塞到车里去。
        “这是在干嘛啊”我问String类。“这些热那叫清理着,专门清理没有用的对象,你看,车里那个不是 Account@659e0bfd
        “啊?昨天我还和他联系,她怎么会没用了呢?
        “很可能他只是个方法的局部变量,方法结束之后,就没人饮用了,拜拜占用空间,你看这楼太拥挤了,如果不清理,很快就会住满,系统崩溃,out of memory了”
        “那这个楼就不能盖得更高点吗?”我有点可怜这些被回收的对象们。
        “楼有多高,是由码农们决定的,他们在启动虚拟机的时候就会制定参数。”
        “那士兵怎么知道谁有没有用?”
        “引用计数呗,如果对象被使用,计数就会增加,不用的时候就会减少,如果时0,那就可能被清理了。”
        “那我们会被清理掉吗?”
        “我应该不会,但是你时有可能的。”我当然明白,String时核心员工,而我只不过是一个外边加载过来的一个类而已,不过我也确实有点想我的家了。
        果然,又过了十天,0x3704才动弹了一下,问我要第二条指令。我告诉了他“iload_1”接下来又是十天的长假。
                    第五回    真相大白
        漫长的调试假期终于结束了,我回到了自己的工作间,发生了更加奇怪的事情,整个世界毫无征兆的消失了。
        我晕晕乎乎,发现自己还是躺在自家床上,我是做了一场梦么?可是过去的记忆如此真切,到底是怎么回事?
        管他呢,我已经知道了自己所在的房子的门牌号:C:\workspace\myTaobao\bin\com\mytaobao\domain探索一下吧,唉,大部分人都非常无趣,不理我。
        正在我准备回去接着睡觉的时候,我先发现了C:\workspace\myTaobao\src\ 下也有一个一模一样的目录com\mytaobao\domain,关键是里边竟然有个Account.java ! 出生的模糊记忆告诉我, javac 就是从这里把我生成的。 
        我正要给他打招呼,一个“hi”还没说出口,我就被新的Account.class覆盖掉了。
        临死前,我终于明白,这个码农在开发程序,调试程序,不断地重启服务器。而我这个类隐藏着一个bug,经过调试之后被发现,然后fix了。

这篇关于码农翻身之大话编程篇:2我是一个Java Class的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/307603

相关文章

Java中对象的创建和销毁过程详析

《Java中对象的创建和销毁过程详析》:本文主要介绍Java中对象的创建和销毁过程,对象的创建过程包括类加载检查、内存分配、初始化零值内存、设置对象头和执行init方法,对象的销毁过程由垃圾回收机... 目录前言对象的创建过程1. 类加载检查2China编程. 分配内存3. 初始化零值4. 设置对象头5. 执行

SpringBoot整合easy-es的详细过程

《SpringBoot整合easy-es的详细过程》本文介绍了EasyES,一个基于Elasticsearch的ORM框架,旨在简化开发流程并提高效率,EasyES支持SpringBoot框架,并提供... 目录一、easy-es简介二、实现基于Spring Boot框架的应用程序代码1.添加相关依赖2.添

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程

《SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程》本文详细介绍了如何在虚拟机和宝塔面板中安装RabbitMQ,并使用Java代码实现消息的发送和接收,通过异步通讯,可以优化... 目录一、RabbitMQ安装二、启动RabbitMQ三、javascript编写Java代码1、引入

spring-boot-starter-thymeleaf加载外部html文件方式

《spring-boot-starter-thymeleaf加载外部html文件方式》本文介绍了在SpringMVC中使用Thymeleaf模板引擎加载外部HTML文件的方法,以及在SpringBoo... 目录1.Thymeleaf介绍2.springboot使用thymeleaf2.1.引入spring

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在