Java程序的运行机制是怎么样的

Java程序的运行机制是怎么样的,第1张

Java程序的运行机制可以分为以下几个步骤:

编写Java源代码:首先,程序员需要使用Java编程语言编写源代码。Java源代码是以java为扩展名的文本文件,包含了Java程序的逻辑和功能。

编译Java源代码:Java源代码需要通过Java编译器进行编译,生成字节码文件。字节码文件是以class为扩展名的二进制文件,包含了Java程序的指令、变量和方法。

解释执行字节码文件:Java虚拟机(JVM)负责解释执行字节码文件。JVM是一个虚拟的计算机,它模拟了实际计算机的硬件和 *** 作系统,能够运行字节码文件。

类加载:当Java程序被执行时,JVM会根据需要动态加载所需的类。Java类库和自定义类都会被加载到内存中。

执行Java程序:JVM会按照程序的逻辑和功能执行Java程序。程序员可以在程序中使用Java类库和自定义类提供的方法和变量。

垃圾回收:JVM还负责垃圾回收,它会自动回收不再使用的内存空间,防止程序出现内存泄漏等问题。

总的来说,Java程序的运行机制可以概括为:编写源代码 -> 编译生成字节码文件 -> 解释执行字节码文件 -> 加载所需类 -> 执行Java程序 -> 垃圾回收。

这心情大概就像几百个人堆积木。堆得歪歪扭扭,摇摇晃晃,乱七八糟,你千万不能抽里面的积木,指不定抽了一块就塌了。只能看见哪里觉得不牢靠不停的往那边填积木。只要不倒就好了。

每一位接手者在看代码之后,心里都想着重构。但其实重构了几个方法后,放弃的概率可能会越来越大

还有些情况其实并不是代码垃圾,而是维护这个代码的人一波又一波的换。新上的人在没有完全熟悉这款业务的时候又不敢随便改,等熟悉了以后,又想着跳槽,或者偷懒。除非遇到一个极其负责的人维护,但是这种人很少。

综上,code review很重要,利用好code review 去统一和实践以及监督,相信可以有效提升代码质量。

网页链接

Java从诞生以来,其基因就是开放精神,也正因此,其可以得到广泛爱好者的支持和奉献,最终很快发展壮大,以至于有今天之风光!但随着java的应用领域越来越广,特别是一些功能要发布到终端用户手中(如Android开发的app),有时候,公司为了商业技术的保密考虑,不希望这里面的一些核心代码能够被人破解(破解之后,甚至可以被简单改改就发布出去,说严重点,就可能会扰乱公司的正常软件的市场行为),这时候就要求这些java代码不能够被反编译

这里要先说一下反编译的现象。因为java一直秉持着开放共享的理念,所以大家也都知道,我们一般共享一个自己写的jar包时,同时会共享一个对应的source包。但这些依然与反编译没有什么关系,但java的共享理念,不只是建议我们这样做,而且它自己也在底层上“强迫”我们这么做!在java写的java文件后,使用javac编译成class文件,在编译的过程,不像C/C++或C#那样编译时进行加密或混淆,它是直接对其进行符号化、标记化的编译处理,于是,也产生了一个逆向工程的问题:可以根据class文件反向解析成原来的java文件!这就是反编译的由来。

但很多时候,有些公司出于如上述的原因考虑时,真的不希望自己写的代码被别人反编译,尤其是那些收费的app或桌面软件(甚至还有一些j2ee的wen项目)!这时候,防止反编译就成了必然!但前面也说过了,因为开放理念的原因,class是可以被反编译的,那现在有这样的需求之后,有哪些方式可以做到防止反编译呢?经过研究java源代码并进行了一些技术实现(结果发现,以前都有人想到过,所以在对应章节的时候,我会贴出一些写得比较细的文章,而我就简单阐述一下,也算偷个懒吧),我总共整理出以下这几种方式:

代码混淆

这种方式的做法正如其名,是把代码打乱,并掺入一些随机或特殊的字符,让代码的可读性大大降低,“曲线救国”似的达到所谓的加密。其实,其本质就是打乱代码的顺序、将各类符号(如类名、方法名、属性名)进行随机或乱命名,使其无意义,让人读代码时很累,进而让人乍一看,以为这些代码是加过密的!

由其实现方式上可知,其实现原理只是扰乱正常的代码可读性,并不是真正的加密,如果一个人的耐心很好,依然可以理出整个程序在做什么,更何况,一个应用中,其核心代码才是人们想去了解的,所以大大缩小了代码阅读的范围!

当然,这种方式的存在,而且还比较流行,其原因在于,基本能防范一些技术人员进行反编译(比如说我,让我破解一个混淆的代码,我宁愿自己重写一个了)!而且其实现较为简单,对项目的代码又无开发上的侵入性。目前业界也有较多这类工具,有商用的,也有免费的,目前比较流行的免费的是:proguard(我现象临时用的就是这个)。

上面说了,这种方式其实并不是真正加密代码,其实代码还是能够被人反编译(有人可能说,使用proguard中的optimize选项,可以从字节流层面更改代码,甚至可以让JD这些反编译软件可以无法得到内容。说得有点道理,但有两个问题:1、使用optimize对JDK及环境要求较高,容易造成混淆后的代码无法正常运行;2、这种方式其实还是混淆,JD反编译有点问题,可以有更强悍的工具,矛盾哲学在哪儿都是存在的^_^)。那如何能做到我的class代码无法被人反编译呢?那就需要我们下面的“加密class”!

加密class

在说加密class之前,我们要先了解一些java的基本概念,如:ClassLoader。做java的人已经或者以后会知道,java程序的运行,是类中的逻辑在JVM中运行,而类又是怎么加载到JVM中的呢(JVM内幕之类的,不在本文中阐述,所以点到为止)?答案是:ClassLoader。JVM在启动时是如何初始化整个环境的,有哪些ClassLoader及作用是什么,大家可以自己问度娘,也不在本文中讨论。

让我们从最常见的代码开始,揭开一下ClassLoader的一点点面纱!看下面的代码:

Java代码

public class Demo{

public static void main(String[] args){

Systemoutprintln(“hello world!”);

}

}

上面这段代码,大家都认识。但我要问的是:如果我们使用javac对其进行编译,然后使用java使其运行(为什么不在Eclipse中使用Run as功能呢?因为Eclipse帮我们封闭,从而简化了太多东西,使我们忽略了太多的底层细节,只有从原始的 *** 作上,我们才能看到本质),那么,它是怎么加载到JVM中的?答案是:通过AppClassLoader加载的(相关知识点可以参考:>

那又有一个新的问题产生了:ClassLoader又是怎样加载class的呢?其实,AppClassLoader继承自javalangClassLoader类,所以,基本 *** 作都在这个类里面,让我们直接看下面这段核心代码吧:

看看这个方法中的逻辑,非常简单,先从内存中找,如果没有,则从父级或根先找,如果没找到,则再从自己的方法里面找!那findClass里面是什么样的呢?很不幸,这个方法是个抽象(abstract)的,也就是使用什么方式加载,由程序使用ClassLoader自己决定!这就给我们留下了巨大的“”!让我们看一下非常常见的一个ClassLoader的实现,那就是URLClassLoader(几乎所有的j2ee的web项目的容器使用的ClassLoader都是继承自它),让我们看一下它的findClass的实现:

这个方法里面的逻辑也很简单,从定义的ucp(就是各个jar包或class文件的具体路径)中读取指定的class文件的信息(如字节流之类),然后交给defineClass定义到JVM中,让我们继续看一下这个方法的核心部分:

看到这里,已经没有必要再往下面看了(再往下就是native方法了,这是一个重大伏笔哦),我们要做的手脚就在这里!

手脚怎么做呢?很简单,上面的代码逻辑告诉我们,ClassLoader只是拿到class文件中的内容byte[],然后交给JVM初始化!于是我们的逻辑就简单了:只要在交给JVM时是正确的class文件就行了,在这之前是什么样子无所谓!所以,我们的加密的整个逻辑就是:

在编译代码时(如使用ant或maven),使用插件将代码进行加密(加密方式自己选),将class文件里面的内容读取成byte[],然后进行加密后再写回到class文件(这时候class文件里面的内容不是标准的class,无法被反编译了)

在启动项目代码时,指定使用我们自定义的ClassLoader就行了,而自定义的部分,主要就是在这里做解密工作!

如此,搞定!以上的做法比较完整的阐述,可以仔细阅读一下这篇文章:>

通过这个方法貌似可以解决代码反编译的问题了!错!这里有一个巨大的坑!因为我们自定义的ClassLoader是不能加密的,要不然JVM不认识,就全歇菜了!如果我来反编译,呵呵,我只要反编译一下这个自定义的ClassLoader,然后把里面解密后的内容写到指定的文件中保存下来,再把这个加了逻辑的自定义ClassLoader放回去运行,你猜结果会怎样?没错,你会想死!因为你好不容易想出来的加密算法,结果人家根本不需要破解,直接就绕过去了!

现在,让我们总结一下这个方法的优缺点:实现方式简单有效,同时对代码几乎没有侵入性,不影响正常开发与发布。缺点也很明显,就是很容易被人破解!

当然啦,关于缺点问题,你也可以这么干:先对所有代码进行混淆、再进行加密,保证:1、不容易找到我们自定义的那个ClassLoader;2、就算找到了,破解了,代码可读性还是很差,让你看得吐血!(有一篇文章,我觉得写得不错,大家可以看一看:>

嗯,我觉得这个方法很好,我自己也差点被这个想法感动了,但是,作为一个严谨的程序员,我真的不愿意留下一个隐患在这里!所以,我继续思索!

高级加密class

前面我们说过有个伏笔来着,还记得吧?没错,就是那个native!native定义的方法是什么方法?就是我们传说中的JNI调用!前面介绍过的有一篇文章中提到过,其实jvm的真实身份并不是java,而是c++写的jvmdll(windows版本下),java与dll文件的调用就是通过JNI实现的!于是,我们就可以这样想:JNI可以调用第三方语言的类库,那么,我们可不可以把解密与装载使用第三方语言写(如C++,因为它们生成的库是不好反编译的),这样它可以把解密出来的class内容直接调jvmdll的加载接口进行初始化成class,再返回给我们的ClassLoader?这样,我们自定义的ClassLoader只要使用JNI调用这个第三方语言写的组件,整个解密过程,都在黑盒中进行,别人就无从破解了!

嗯,这个方法真的很不错的!但也有两个小问题:1使用第三方语言写,得会第三方语言,我说的会,是指很溜!2对于不同的 *** 作系统,甚至同一 *** 作系统不同的版本,都可能要有差异化的代码生成对应环境下的组件(如window下是exe,linux是so等)!如果你不在乎这两个问题,我觉得,这个方式真的挺不错的。但对于我来说,我的信条是,越复杂的方式越容易出错!我个人比较崇尚简洁的美,所以,这个方法我不会轻易使用!

对了,如果大家觉得这个方法还算可行的话,可以推荐一个我无意中看到的东西给大家看看(我都没有用过的):jinstall,

更改JVM

看到这个标题,我想你可能会震惊。是的,你没看错,做为一个程序员,是应该要具有怀疑一切、敢想敢做的信念。如果你有意留心的话,你会发现JVM版本在业界其实也有好几个版本的,如:Sun公司的、IBM的、Apache的、Google的……

所以,不要阻碍自己的想象力,现在没有这个能力,并不代表不可能。所以,我想到,如果我把jvm改了,在里面对加载的类进行解密,那不就可以了吗?我在设计构思过程中,突然发现:人老了就是容易糊涂!前面使用第三方语言实现解密的两个问题,正好也是更改JVM要面对的两个问题,而且还有一个更大的问题:这个JVM就得跟着这个项目到处走啊!

程序员应该学会怎样保护自己?

1 技术不是全部

这个观念,我曾不止一次普及过,眼里只有技术的程序员,跟读书时分的书呆子没什么差异。程序员们许多都认为只需技可以牛,我就可以凭仗技术挣更多的钱,然后就可以过的更好,所以容易往往忽略了其他方面的展开,沟通交流、为人处事都是很重要的,程序员的弱势在于终年跟机器打交道,认为什么都很机器相同讲道理,轻视了人道的杂乱与丑陋,没有一点防备心思,这些都是很风险的,总归一句话,程序员们大多智商较高,但是情商较缺少,但是人这一生,情商绝比照智商要更有用的多。

2 培养第二技术

都说程序员是芳华饭,被认为中年危机最严峻的一个集体,在许多人看来不理解,说人到中年,有车有房,收入也较高,怎样会有那么大的危机呢?但是殊不知,人到中年,收入虽然高了,但是房贷、车贷压力不小,一起还背负着家庭的职责,处处都是花钱的当地,而且经济大环境欠好,很担忧公司展开遇到困难,自己受到各种影响,换岗的话虽然不愁找工作,但是这个年岁薪资岗位低了不想姑息,高的话除非处理岗位,不然企业不如找个年轻点的、薪酬低点的来代替了,种种原因导致中年危机感很重。

我之前就说过,一定要培养第二技术,永久不要把全部赌注都押宝在工作上,年轻的时候趁早培养第二技术,写作、讲演、英语、咨询等等都归于第二技术,根据你的个人兴趣爱好去选择,第二技术会是你的后路,当你到了中年,或许第二技术早就展开的如火如荼,甚至跨越你的本职工作,拥有第二技术的人从不会担忧危机的到来,规劝全部程序员们,一定要重视第二技术的培养。

3 永久不要在非正常状况下做任何决议

这次事情许多人都想不通,当事人高学历,经验丰富,被裁了大不了换份工作就是了,何须想不开呢?简直太懦弱了。其实我们不知道当时是在一个什么环境下,我们处在事外当然看得清,但是许多决议其实都是一念之差,就是那么一瞬间没想通,导致激动做出差错的选择,我们能总结出的经验教训就是:永久不要在非正常状况下做任何决议。

什么叫非正常状况?醉酒、愤怒、极度哀痛甚至振奋、反常快乐等状况都归于非正常状况,这种状况做出的决议一般都是不客观甚至差错的,别的,做决议的时分多想想身边的家人,考虑的要素全面点,会更能避免一些想不开发生。

4 职场中不要讲感情

成熟的职场人士是不会讲感情的,不要把公司作为家相同,更不能把公司伙伴作为家人看待,那些只给你打感情牌,没有任何实质性的表明的公司或许老板,你得留神了。

当然,可以对公司以及伙伴有感情,但是不可以感情用事,在公司的任何决议,假如你都可以抛开感情,其实都很好处理,但是许多同学想不开,在遇到类似事情的时分,往往会有非常不冷静的处理方式。

反诈骗是一项非常重要的工作,而高级程序员可以通过以下几种方式来帮助防止诈骗行为:

1 加强网络安全措施:高级程序员可以通过加强网络安全措施来帮助防止诈骗行为。这包括使用强密码、加密数据传输、使用防火墙和安全软件等。

2 数据挖掘和分析:高级程序员可以使用数据挖掘和分析技术来识别诈骗模式和模型。通过分析大量的数据,他们可以发现诈骗者的行为模式和趋势,并及时采取措施。

3 建立机器学习模型:高级程序员可以建立机器学习模型来预测和识别诈骗行为。这些模型可以通过监控网络流量和用户活动来自动识别和预测诈骗行为。

4 实时监控:高级程序员可以建立实时监控系统,以便及时发现和阻止诈骗行为。这些系统可以监控用户活动、网络流量、交易记录等信息,并及时触发警报,以便采取措施。

5 教育用户:高级程序员可以通过教育用户如何保护自己来帮助防止诈骗行为。他们可以开发教育课程、提供安全建议和提示,以便帮助用户识别和避免诈骗行为。

总之,高级程序员可以通过加强网络安全措施、使用数据挖掘和分析技术、建立机器学习模型、实时监控和教育用户等多种方式来帮助防止诈骗行为。这些措施可以提高企业和个人的网络安全水平,保护他们的财产和隐私。

程序员遇到bug是在正常不过的事情了,就算非常资深的程序员也无可避免bug的存在,一般来说,除非你写一辈子 Hello World。

不过世界上的确存在一些凤毛麟角天才的程序员,他们差不多能做到这一点。接到任务之后,思考,冥想,在笔记本上画出数据结构或某个算法片段,腹稿打的差不多了就开 始编程,用 Vim、Emacs 或 IDE 工具,大部分时候能够一气呵成,然后构建代码,构造测试数据,运行程序,在反复调试中修复几个编程过程中没有考虑到的问题,就可以提交到代码库了。

他们的 代码交给测试和其他开发者,少有人能挑出 bug,因为他们对代码有敏锐的感觉,能够在别人忽略的地方发现代码的坏味道,并给出巧妙而优雅的解决方案。

他们是天生的代码创造者,这样的人往往效率高 而且少有错误,以至于会被一些平庸的团队忽略,因为技术领导总是会下意识的去关注那些最容易出事的环节,但这些人才是团队真正的脊梁,不是那些四处救火者。

以上就是关于Java程序的运行机制是怎么样的全部的内容,包括:Java程序的运行机制是怎么样的、作为一个程序员,面对别人写的稀烂的代码,怎么办、如何防止程序员反编译等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9804998.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存