目前2016主流java开发框架的 Java 虚拟机有哪些

【深入理解Java虚拟机】垃圾回收机制
1、垃圾回收要解决的问题
垃圾收集(Garbage Collection,GC),要设计一个GC,需要考虑解决下面三件事情:
(1)哪些内存需要回收?
(2)什么时候回收?
(3)如何回收?
哪些内存需要回收?
根据《Java内存区域模型、对象创建过程、常见OOM》中介绍的java内存模型,其中,程序计数器、栈、本地方法栈3个区域随线程而生,随线程而灭;栈中的栈帧随着方法的进入和退出有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这几个区域的内存分配和回收都具备确定性,故这几个区域就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟着回收了。
对于java堆和方法区则不一样,java堆是存放实例对象的地方,我们只有在程序运行期间才能知道会创建哪些对象,这部分内存的分配和回收是动态的,因此,垃圾收集器所关注的就是这一部分。
对于方法区(或者说HotSpot虚拟机中的永久代),垃圾回收主要是回收这两部分内容:废弃常量和无用的类。对于废弃常量,主要是判断当前系统中有没有对象引用这个常量;对于无用类则比较严格,需要满足下面三个条件:
(1)该类的所有实例都已经被回收,即堆中不存在该类任何势力;
(2)加载该类的ClassLoader已经被回收;
(3)对类对应的java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法;
满足了上面三个条件也仅仅是&可以&进行回收了,还要根据HotSpot的一些配置参数综合考虑。
什么时候回收?
垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象之中哪些还&存活&着,哪些已经&死去&,对于这些已经&死去&的对象我们需要进行回收。判断对象是否存活的算法:
(1)引用计数算法
算法过程如下:【给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的】。
引用计数算法实现简单,判定效率也很高,大部分情况下是一个不错的算法。但有一个比较重要的缺点:很难解决对象之间相互循环引用的问题。比如:j假设变量objA、objB为某个类的对象实例,objA中持有一个指向objB的成员,此时objB的引用计数为1;在objB中持有一个指向objA的成员,此时objA的引用计数值也为1;此时,即使把objA、objB都置为null,此时两个对象都不能被回收,因为这两个对象虽然为null了,但是它们的引用计数值都还为1。
(2)可达性分析算法
目前主流的虚拟机,如java默认虚拟机HotSpot就是用的这种方式。算法基本思路为:【通过一系列的称为&GC Roots&的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时(或者说从GC Roots到这个对象不可达),则证明此对象是不可用的】。
可作为GC Roots的对象包括:
1)虚拟机栈(栈帧中的本地变量表)中引用的对象;
2)方法区中类静态static属性引用的对象;
3)方法区中常量final引用的对象;
4)本地方法栈中JNI(即一般说的Native方法)引用的对象;
需要注意的是,即使在可达性分析算法中不可达的对象,也并非是&非死不可&的,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过(也就是说对象的finalize()方法只能被调用一次),虚拟机将这两种情况都视为&没有必要执行&。
如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它(即去执行对象的finalize()方法,这里所谓的&执行&是值虚拟机会触发这个方法,但并不承若会等待它运行结束,主要是为了防止对象的finalize方法执行缓慢或发生死循环,导致其他对象不能被执行的,从而引起内存回收系统崩溃)。
finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize()中成功拯救自己&&只需要重新与引用链上的任何一个对象建立关联即可,譬如把自己(this)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移除出&即将回收&的集合;如果对象这时候还没有逃脱,那基本上它就真的被回收了。
因此对于不可达对象判定真正死亡的过程小结如下:(1)GC进行第一次标记并进行一次筛选(筛选那些覆盖了finalize方法并且finalize方法是第一次调用的对象);--& (2)另一个低优先级的线程去调用那些被筛选出来的对象的finalize方法;--& (3)GC进行第二次标记,如果在前一步中那些筛选出来的对象没有在finalize拯救自己,此时,那些未被筛选到的和这些这些筛选到的但是没有拯救自己的对象都将会回收。
2、垃圾回收算法
2.1 标记-清除
是最基础的一种收集算法。分为&标记&和&清除&两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。标记过程就是上面可达性分析算法中所讲的二次标记过程。标记-清除算法的执行过程如下图所示:
回收前状态:
回收后状态:
(1)效率问题:标记和清除的两个过程效率都不高;
(2)空间问题:标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后需要分配较大对象时,无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作;
2.2 复制算法
为了解决上面算法的效率问题,复制算法出现。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存使用完了,就将还存活的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
复制算法的优点:
(1)每次都是对整个半区进行内存回收,实现简单、运行也高效;
(2)在那块使用内存上进行内存分配时,不用考虑内存碎片的问题,只要移动堆顶指针,按顺序分配内存即可;
将内存缩小为原来的一半,代价较高。
复制算法的执行过程如下:
回收前的状态:
回收后的状态:
按照新生代的特点,新生代中的对象98%是&朝生夕死&的,因此,可以改进上面的复制算法,目前商业虚拟机正是用这种改进的收集算法来回收新生代。
改进的收集算法:
根据新生代的特点,我们并不需要按照1:1的比例来划分内存空间,而是将内存划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor中还存活的对象一次性地复制到另外一块Survivor空间,最后清理掉Eden和刚才用过的Survivor空间,清理完成后,刚刚被清理的Eden和另一块在回收时放入存活对象的Survivor空间作为使用内存,刚被清理的Survivor作为保留空间,以便后面用来回收之用。
这种改进的收集算法也有一个问题,就是在回收时,那块空的Survivor空间能否放得下Eden和使用的Survivor空间中还存活的对象,如果Survivor空间不够存放上一次新生代收集下来的存活对象,此时就需要向老年代&借&内存,那些剩余未放下的对象就通过分配担保机制进入老年代。
2.3 标记-整理算法
复制算法如果在对象存活率较高时,就需要进行较多次的复制操作,效率也会变低。而对于老年代中的对象,一般存活率都较高,因此需要选用其他收集算法:标记 - 整理算法。标记过程仍然与&标记-清除&算法中一样,但是在标记完成后并不直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。算法示意图如下:
回收前状态;
回收后状态:
2.4 分代收集算法
当前商业虚拟机都采用这个&分代收集&算法(Generation Collection),它根据对象存活周期的不同将内存划分为几块,一般是把java堆分为新生代和老年代,根据各个年代的特点选用不同的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,因此可以选用&复制算法&,此时只需要付出少量存活对象的复制成本即可;对于老年代,因为对象存活率较高、也没有额外空间为期分配担保,就必须使用&标记-清除&或&标记-整理&算法来进行回收。
3 垃圾收集器
如果说上面介绍的收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现,按照上面的介绍,目前垃圾收集器基本都采用分代收集,因此一个垃圾收集器中一般都存在多种垃圾回收算法。不同的虚拟机提供的垃圾收集器也有很大差异,如下是HotSpot虚拟机基于JDK1.7版本所包含的所有垃圾收集器:
HotSpot中共有7中不同的垃圾收集器,如果两个收集器之间存在连线,说明它们之间可以搭配使用,其中,Serial、ParNew、Parallel Scavenge属于新生代收集器,CMS、Serial Old、Parallel Old属于老年代收集器,G1是最新的一种收集器,在新生代和老年代中都可使用。
3.1 Serial(串行)收集器
最基本、发展历史最悠久的一种收集器。看名字就知道,这个收集器是一个单线程的收集器,只使用一个CPU或一条收集线程去完成垃圾收集工作,最重要的是,在它进行垃圾收集的时候,必须暂停其他所有的工作线程,知道它收集结束。虽然有这个缺点,但是依然是虚拟机运行在Client模式下的默认新生代收集器。优点是:简单而高效,没有线程交互的开销。运行过程如图:
新生代采用的是&复制算法&,老年代采用的是&标记-整理&算法。
3.2ParNew收集器
ParNew收集器其实就是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其他行为和Serial收集器一样。ParNew是许多运行在Server模式下的虚拟机中首选的新生代收集器,其中有一个与性能无关的重要原因,除了Serial收集器外,目前只有ParNew能与老年代的CMS收集器配合使用。ParNew是一种并行的收集器。在垃圾回收中,并行是指:多条垃圾收集线程并行工作,用户线程处于等待状态;并发是指:用户线程和垃圾收集线程同时执行(不一定并行,可能交替执行)。
3.3Parallel Scavenge收集器
Parallel Scavenge收集器使用的是复制算法,也是一个并行的多线程收集器。和ParNew相似,但是Parallel Scavenge的关注点不同,CMS收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量,吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)。
上面三种都是新生代收集器,下面介绍老年代收集器。
3.4Serial Old收集器
Serial Old收集器是新生代Serial收集器的老年代版本,同样是一个单线程收集器,使用&标记-整理&算法,Serial Old的主要意义也是在于给Client模式下的虚拟机使用。
3.5Parallel Old收集器
Parallel Old是新生代收集器Prarllel Scavenge的老年代版本,使用多线程和&标记-整理&算法。运行流程如下:
3.6CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。对于互联网站或者B/S系统的这种注重响应速度的服务端来说,CMS是很好的选择。从名字Mark Sweep可以看出,CMS是基于&标记-清除&算法实现的,分为四个步骤:
(1)初始标记(CMS initial mark):仅仅标记一GC Roots能直接关联到的对象,这个步骤需要&stop the world&;
(2)并发标记(CMS concurrent mark):就是GC Roots进行可达性分析阶段,可并发执行;
(3)重新标记(CMS remark):修正并发标记期间发生变动的那一部分对象,这个步骤需要&stop the world&;
(4)并发清除(CMS concurrent sweep):执行清除阶段。
执行过程如下:
可以看到,初始标记和重新标记阶段都是并行的,需要暂停用户线程(过程比较短);在并发标记和并发清除阶段是并发的,可以和用户线程一起工作。
CMS的优点:并发收集、低停顿。
CMS的缺点:
(1)对CPU资源非常敏感,面向并发设计程序的通病,虽然不至于导致用户线程停顿,但是会降低吞吐率;
(2)无法清理&浮动垃圾&,由于CMS并发清理阶段用户线程还在运行着,伴随程序运行自然就还会有新的垃圾不断出现,这一部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉它们,只好留待下一次的GC;
(3)会产生大量空间碎片,因为CMS是基于&标记-清除&算法,这种算法的最大缺点就是会产生大量空间碎片,给分配大对象带来麻烦,不得不提前触发Full GC。为了解决这个问题,CMS提供了一个&-XX:+UseCMSCompaceAtFullCollection&的开关参数(默认开启),用于在CMS收集器顶不住要进行Full GC时开启内存碎片的合并整理过程。
3.7G1收集器
G1收集器是最新的一款收集器,JDK1.7才发布,是一种面向服务端应用的垃圾收集器,有如下特点:
(1)并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The-World停顿的时间;
(2)分代收集:分代概念在G1中依然得以保留。虽然G1可以不需其他收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果;
(3)空间整合:与CMS的&标记-清理&算法不同,G1从整体看来是基于&标记-整理&算法实现的收集器,从局部(两个Region之间)上看是基于&复制&算法实现,无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存;
(4)可预测的停顿时间;
使用G1收集器时,堆的内存布局与就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。
G1的收集过程分为以下几个步骤:
(1)初始标记(Initial Marking)
(2)并发标记(Concurrent Marking)
(3)最终标记(Final Marking)
(4)筛选回收(Live Data Counting and Evacuation)
前几个步骤和CMS有很多相似之处。运行示意图如下:
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'个人推荐&i&李兴华&/i& 《Java实战开发经典》和 《JavaWeb 开发实战经典》 等等。&br&李兴华最大的好处在于说话速度快、打字速度也够快。本来看视频学编程的时间消耗成本大,看他的视频可以把&u&时间成本降低许多&/u&(相比浪曦,尚学堂之类的),想看视频学Java的话推荐他。&br&&br&另外还有一点提醒一下的是,&b&任何培训机构的教育都只是在一个“码农”级别的,只能授之于鱼,不能授之于渔&/b&。时代变迁后,如何依靠自己的&u&学习能力&/u&适应潮流这才是最重要的,这也是大学本科与培训机构或者专科的最大区别:能力、素质上的区别(而非技能本身)。&br&&br&所以,当你发现编程不再是一个难事的时候,要开始锻炼自己的学习能力,多看技术文档,特别是英文的,适当地去了解语言底层的原理,性能上的一些优化等。&b&&u&靠自己的学习能力去适应万变的计算机编程世界,才是唯一不变的法则&/u&&/b&。
个人推荐李兴华 《Java实战开发经典》和 《JavaWeb 开发实战经典》 等等。李兴华最大的好处在于说话速度快、打字速度也够快。本来看视频学编程的时间消耗成本大,看他的视频可以把时间成本降低许多(相比浪曦,尚学堂之类的),想看视频学Java的话推荐他。…
&ol&&li&用记事本写hello world,用控制台的方式运行起来。&/li&&li&随便搞一本Java入门书籍,但作者一定不要是中国人。譬如Small Java How to program。把书中的例子敲一遍,看明白&/li&&li&学会查Java api的方法&/li&&li&买本Thinking in Java,挑你感兴趣的章节读一遍,顺便写个扫雷或者坦克大战之类的程序&/li&&li&用SSH写个图书馆管理系统,不会的地方自己查文档,尽量用官网,不要买什么李刚的SSh教程。&/li&&li&买本Effective Java,挑你感兴趣的章节读一遍。&/li&&li&买本重构,挑你感兴趣的章节读一遍&/li&&li&重构图书馆管理系统&/li&&li&重读上面那三本书&/li&&li&用Java写个聊天室系统,在你的电脑上运行起来,随便找一门课程,把大作业的答案发上去,邀请在同一网段又懒得做作业的同学下载、讨论&/li&&li&用Java写个爬虫系统,去百度知道、知乎一类的网站爬跟贵专业有关的信息,存到数据库里,再用SSH做个网站发布,邀请在同一网段又懒得做作业的同学下载、讨论&/li&&li&重读上面那三本书&/li&&li&学习一下并发、事务一类的知识&/li&&li&可能的话,组个小团队,去外面接点私活,赚钱不赚钱无所谓。重点关注一下代码规范、团队合作常识&/li&&/ol&嗯,可以出去应聘了,我觉得平均水平两倍的工资应该没问题吧。在我们这个城市大概八千是妥妥的
用记事本写hello world,用控制台的方式运行起来。随便搞一本Java入门书籍,但作者一定不要是中国人。譬如Small Java How to program。把书中的例子敲一遍,看明白学会查Java api的方法买本Thinking in Java,挑你感兴趣的章节读一遍,顺便写个扫雷或者坦克…
不知道提问者现在的计算机基础肿么样&br&&br& 如果一点基础都木有:&br&可以考虑看Absolute Java(中文版好像叫&Java核心编程&,我看的是原版,中文貌似翻译的一般,所以有条件的话可以考虑直接看原版),我学Java的时候就是看的这本,从基本概念开始讲的,讲Class神马的讲的很详细,好像有两章专门讲Class,循序渐进,很适合Java入门者&br&&br& 如果有基础,比如学过C或者C++,对OOP有大概了解:&br&可以直接看oracle的教程&a href=&///?target=http%3A///javase/tutorial/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/javase/&/span&&span class=&invisible&&tutorial/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&和Java的开发文档:&a href=&///?target=http%3A///javase/6/docs/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/javase/&/span&&span class=&invisible&&6/docs/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&然后找一个小的Project开始做,我始终认为做Project是提高最快的方法&br&&br& 还有那些说Thinking in Java的,统统无视掉把&br&这是一本好书,现在也一直在我桌边放着,但是这不是一本给入门者看的书&br&推荐这本书的人你们可以翻开第一章第一节看看标题,让一个很可能连int和long都分不清的初学者直接开始看&The progress of abstraction&?你们肿么不直接让他写编译器啊?
不知道提问者现在的计算机基础肿么样 如果一点基础都木有:可以考虑看Absolute Java(中文版好像叫"Java核心编程",我看的是原版,中文貌似翻译的一般,所以有条件的话可以考虑直接看原版),我学Java的时候就是看的这本,从基本概念开始讲的,讲Class神马的讲的很详…
大牛一般都很低调的,但还是有些可供参考的资源(不全是博客):&br&&br&&ul&&li&&a href=&///?target=https%3A///akullpp/awesome-java& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&akullpp/awesome-java · GitHub&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A//hllvm./& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&高级语言虚拟机&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Script Ahead, Code Behind&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=https%3A///codefollower/My-Blog& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&codefollower/My-Blog · GitHub&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ImportNew - 专注Java & Android 技术分享&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&并发编程网&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Java Performance Tuning Guide&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HelloJava微信公众账号网站&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///developerworks/cn/java/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&IBM developerWorks 中国 : Java 开发概述&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///forums/tag_good/Java%25E7%25BB%25BC%25E5%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Java综合讨论&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A//jm-/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&阿里中间件团队博客&i class=&icon-external&&&/i&&/a&&/li&&/ul&
大牛一般都很低调的,但还是有些可供参考的资源(不全是博客):
抛开应用场景谈设计模式是没用的,看了也是忘了。&br&有一天,你需要程序中只用一个共享的对象,或许就该考虑单例模式了&br&有一天,由于某种原因,A调不到C,而A可以通过B来调C,就是代理模式了&br&有一天,有好几个接口,你需要同时使用他们的部分特性,或许你就会用到适配器或者桥接模式了&br&有一天,当你想让你的发送者和接收者不用同步阻塞的时候,或许你就该考虑观察者、Reactor模式了&br&有一天,当你有一个抽象对象,想动态产生你想要的具体对象,或许你就需要工厂模式了&br&&br&OO就是烦,各种设计模式。其实你只要考虑怎么写出高内聚,低耦合的程序,怎么控制好权限,怎么绕开限制去设计程序的时候,就用到了各种设计模式了。&br&&br&======&br&至于技巧,大学应该打好基础,操作系统、网络、算法,如果你对java实在感兴趣,懂点jvm,把jdk看了就可以虐大部分java程序员了。&br&&br&======&br&有人说我文不对题,操蛋是作者乱改题目好不好。原题是【大神有什么java web 方面的好的开发习惯?比如一些常用的设计模式,和技巧?小弟应届生一枚,还请不吝赐教?】,还有,适配器和桥接说错了,答案在评论中,感谢 &a data-hash=&4b1aae043& href=&///people/4b1aae043& class=&member_mention& data-editable=&true& data-title=&@尘絮缘& data-tip=&p$b$4b1aae043&&@尘絮缘&/a& 指正。&br&关于设计模式,强烈推荐GOF那本。
抛开应用场景谈设计模式是没用的,看了也是忘了。有一天,你需要程序中只用一个共享的对象,或许就该考虑单例模式了有一天,由于某种原因,A调不到C,而A可以通过B来调C,就是代理模式了有一天,有好几个接口,你需要同时使用他们的部分特性,或许你就会用…
多年以前(2002吧),我自学Java,考了一个SCJP(Sun Certificed Java
Programmer),现在叫OCJP(Oracle Certified Java
Programmer),取得98%的成绩(错了一题,忘记具体题目,大概是多线程的题目)。时间过去很长了,按照记忆回忆一下:&br&&br&个人认
为,OCJP(原SCJP)的教材是极佳的学习来源,Java的基础知识讲得比较透彻。当初这种培训认证的教材是不允许外传的,但是目前相信网络上到处都
是了。想要学好Java,这个基础训练个人认为是相当重要的。多做各种训练题目,积极思考,透彻理解。当时我随便报了一个认证培训班,主要是考虑遇到问题
可以有老师帮忙解决。考取认证培训我花了好像有两个月时间吧,包括上课(周末)和自己做题。要做大量的习题,不明白的概念和知识点除了问老师之外,要自己
写代码验证,加深记忆。当时感觉比较困难的是多线程方面的知识,由于多线程程序的特点,自己写程序很难验证一些概念,只能多读书,在网上多找相关的文章
看。&br&&br&最重要的一点是,切记,&b&不要看中文教材!&/b&不知道现在中文方面的书籍翻译水平是否有提高,但是我一直没有看中文教材的习惯。包括网上的技术文章,尽量不要看中文的文章,或者只看权威网站的技术文章,比如infoq,IBM developer network上的文章还算靠谱。说句个人看法,现在网络上中文的技术网站,功利性太强,故弄玄虚的文章极多,把简单的问题复杂化,把复杂的问题简单化。(好吧,我承认我说的是CSDN)。&br&&br&基础训练是很重要的,个人认为现在的一些培训机构功利性很强,在短短的时间内塞给你大量的东西,你不但学不过来,而且为了完成任务而完成任务,很容易养成一些编程的坏习惯。&br&&br&大的道理其实大家都知道--学习是没有捷径的,需要你多思考,多练习,不放过任何一个学习的机会。在学Java的时候,我的编程基础也很弱,但是很多计算机方面的专业知识我一直在学习,玩电脑的时间也很长了,实际工作也涉及到很多软件开发的事情,所以和题主的情况不太一样。要补上这些差距需要更多的时间和更加刻苦的训练。&br&&br&我的另外一个可以分享的经验就是,我的编程水平有一个质的飞跃阶段,是2003年中,我在一个互联网公司,一个人负责一个大型的论坛的开发项目,使用JSP/Struct和Oracle数据库。毫不掩饰的说,当时我的编程水平还是比较初级,软件开发经验大概是2年左右吧,我一个人根本无法设计这么一个大型的系统而不出问题。在当时经理的同意下,直接“借用”了一个当时的商用论坛的开源版本。但是,这个商用论坛的所有代码我是全部理解透彻了以后,才开始真正做产品开发的。大概经过了半年的时间吧,我已经感觉我在软件开发方面有了一个质的飞跃,看待问题有了一定的高度。&u&所以,我给题主的另外一个建议,就是“抠代码”,优秀的开源项目有很多,找一个中等规模、非框架类的项目,花大量的时间吃透它。&/u&为什么要非框架类的项目?原因是框架类的项目针对性不强,解决实际问题的参考价值有限,特别是对于初学编程的人来说,常常会看不懂代码为什么要那么写。&br&&br&虽然我个人是因为个人的兴趣而走上软件开发这条路的,但是我并不排斥为了提高待遇而去学习编程,但是请不要功利性太强,码农并不好当,踏踏实实的做技术才是出路。&br&&br&总结一下:&br&1. 打好Java的语法基础,OCJP是王道。&br&2. 吃透一个开源项目是提高自身软件开发水平的必经之路&br&3. 有限的英文水平是所有码农上升到高手阶段的障碍,请尽量提高自己的英文水平。&br&&br&几年过后,如果题主发现自己在软件开发道路上走不长,可以转行做产品经理嘛 ;-)。(知乎上做产品的多,请轻点拍砖。)&br&&br&&br&------------更新-----------&br&这个回答的时间有点久了,再次更新的动机是有位同学连续私信我两次,问我“中等规模非框架类的项目有哪些”。说实话,我也不清楚。当年我不仅仅“扒”过一个商业论坛的源代码,还看过Resin/Jetty的源代码,究竟看什么样的项目能够对自己有帮助其实是一个很主观的选择,同时要结合自身的技术水平,这个推荐项目要做到人人满意,对于我来说是几乎不可能的事情。但是,我不想说一些“政治正确”的话来敷衍,于是在网上搜索到一个项目,花了一点时间看了看它的代码,感觉代码风格还算工整,如果有人感兴趣的话,可以下载下来看看。老话说“师傅领进门,修行在个人”,不知道我够不够资格当别人的师傅,但是,“修行”一定要靠个人的努力。所以,不管如何,我得发一个免责声明,如果因为阅读我推荐项目的代码产生头晕、呕吐、想骂人的冲动的话,本人概不负责,谢谢!&br&&br&&h2&Tiny Java Web Server and Servlet Container&/h2&&p&aka Miniature JWS&/p&&br&&br&&a href=&///?target=http%3A//tjws.sourceforge.net/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&http://tjws.sourceforge.net&i class=&icon-external&&&/i&&/a&
多年以前(2002吧),我自学Java,考了一个SCJP(Sun Certificed Java
Programmer),现在叫OCJP(Oracle Certified Java
Programmer),取得98%的成绩(错了一题,忘记具体题目,大概是多线程的题目)。时间过去很长了,按照记忆回忆一下:个人认
为,OCJP(原…
咦,看来我有资格来谈一谈,,,&br&&b&1.编码规范&/b&&br&JAVA大小写敏感,PHP对 函数名、方法名、类名是不区分大小写的。&br&这在生产中容易导致问题,比如window系迁移至类Unix系。&br&在编码规范上SUN给出了一个好的风格样式,再加上使用的各类Jar包的规范。&br&一个菜鸟只要用心,是不会写烂代码的风格的。&br&&br&PHP确有些小头痛呢,因为之前流行的是面向过程式编程。&br&独立开发者各有各的风格,个人觉得那些DISCUZ、DECMS等等是带坏一票人啊。&br&二次开发那个命名随意,真是任性。&br&当然,现在PHP也支持OOP了,各类框架的命名风格也一定程度的约束了编码人员的风格。&br&当然,要写烂一样很简单。&br&再加上是弱类型语言,代码质量的好坏比JAVA,对程序员的要求是更高的,虽然PHP简单。&br&正如 &a data-hash=&3357049aafdaf5ac8b9131& href=&///people/3357049aafdaf5ac8b9131& class=&member_mention& data-editable=&true& data-title=&@Cweili& data-tip=&p$b$3357049aafdaf5ac8b9131&&@Cweili&/a& 所说:“安全和稳定就需要开发者的水平来保证了”。&br&&br&结论就是JAVA容易养成更好的统一编码规范,利于维护、阅读。&br&菜鸟都能写出一手规范的代码。&br&&br&&b&2.变量、强类型&/b&&br&强类型语言,导致变量之间转换繁琐,定义、初始化、转换麻烦。&br&JAVA中,代码块的很大一部分是变量的定义、初始化与转换,又臭又长。&br&如果忘记初始化,程序容易报空指针错误。&br&&br&PHP在这一块就很好,变量随处用。再加上PHP的可变变量特性。&br&同样的一个route功能实现,JAVA要繁琐太多,这也是我对强类型语言一直诟病的。&br&PHP可以省去大量繁琐的定义、初始化和类型转换,代码结构轻便,更加专注于业务逻辑上。&br&&br&JAVA强类型也决定了代码在编码时期的严谨性和可靠性,这个比PHP优。&br&PHP一个可变变量可能就会让你无法重构,所以对IDE不是很友好,调试起来你要发疯。&br&JAVA重构方便,但结构笨重,开发节奏慢,调试倒是很方便。&br&&br&拿PHP来做数据安全要求高的业务还是不建议的。&br&&br&&b&3.异常、业务完整性&/b&&br&PHP的生命周期(&a href=&///?target=http%3A///2009/10/php-life-cycle/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PHP的生命周期&i class=&icon-external&&&/i&&/a&)设计决定了它的异常处理功能的使用没有JAVA广泛。&br&接触过的如DISCUZ、DECMS、ECSHOP这些系统对于异常处理很弱。&br&很少使用try{}catch{}处理异常,因为一旦执行期发生异常就可能导致程序崩溃,&br&对于业务性要求高的系统来说不是一件好事。&br&谁都不希望执行到一半,程序异常就崩溃了吧,那业务回滚怎么办?&br&&br&就如 &a data-hash=&90db68dbebf& href=&///people/90db68dbebf& class=&member_mention& data-editable=&true& data-title=&@石峰& data-tip=&p$b$90db68dbebf&&@石峰&/a& 说的:“入门简单的语言,给我的感觉是想要用的好其实更难,比如js或者php”。&br&&br&个人看法有限,知友请轻喷!&br&&br&PS:&br&&a href=&/question/& class=&internal&&为什么大型网站前端使用 PHP 后台逻辑用 Java? - Java&/a&&br&&a href=&/question/& class=&internal&&PHP 和 Java 的主要区别有哪些? - 编程语言&/a&
咦,看来我有资格来谈一谈,,,1.编码规范JAVA大小写敏感,PHP对 函数名、方法名、类名是不区分大小写的。这在生产中容易导致问题,比如window系迁移至类Unix系。在编码规范上SUN给出了一个好的风格样式,再加上使用的各类Jar包的规范。一个菜鸟只要用心,…
接口的作用对于很多新手来说很不容易理解,我给大家举个例子。&br&接口只是一个规范,所以里面的方法都是空的。&br&假如我开了一个宠物粮店,声明所有宠物都可以来我这里买粮食,这就相当于一个接口,&br&&br&public interface PetRestaurant {&br& public void buy();&br&}&br&&br&当一只狗看到了,知道自己是宠物,所以它去实现这个接口&br&public class DogPet implements PetRestaurant {&br& @Override&br& public void buy() {&br&
System.out.println(&我是狗,我要买狗粮&);&br& }&br&}&br&当一只猫看到了,知道自己也是宠物,所以也去实现这个接口&br&public class CatPet implements PetRestaurant {&br& @Override&br& public void buy() {&br&
System.out.println(&我是猫,我要买猫粮&);&br& }&br&&br&}&br&当狗和猫来我的店之前,我是不知道他们到底是什么,但是当他们来到我的店,我就知道一个要猫粮食,一个要狗粮食。因为他们都实现了 我这个接口,都可以买。下面这个类相当于一个接待顾客的类,即店小二,他接待所有实现了我这个宠物店接口的动物,传进来一个PetRestaurant 类型的宠物,注意,这个PetRestaurant 是接口&br&public class test {&br& public void buy(PetRestaurant pet)&br& {&br&
pet.buy();&br& }&br&}&br&&br&好了,这个时候我这个老板出现了,我可以给他们卖粮食了,相当于测试类&br&public class Tests {&br& public static void main(String[] args) {&br&
PetRestaurant dog = new DogPet();
//实例化一个狗,相当于把狗顾客实例化&br&
PetRestaurant cat = new CatPet();//实例化一个猫,相当于把猫顾客实例化&br&&br&
test t = new test();
//实例化一个店小二&br&
t.buy(cat);
//把猫交给店小二&br&
t.buy(dog); //把狗交给店小二&br& }&br&&br&}&br&这样运行的结果就是&br&我是猫,我要买猫粮&br&我是狗,我要买狗娘&br&&br&你知道吗,整个过程我这个店主其实根本不知道来的到底是猫是狗还是其他什么,我只要有一个店小二,把这些来的不知什么动物都全部交给店小二,店小二就知道怎么去卖了,因为这些狗啊猫啊都实现了我这个宠物店的接口,而店小二就负责接待所有实现了我这个接口的动物。这就有一个好处,假如明天来了一头小猪,只要它实现了我这个接口,我只管交给店小二处理就OK了,我这个店小二根本不需要变化,我这个店主也只需要实例化一下这个动物就OK&br&你想,假如没有接口,会怎么办,来一个猫,我要去创造一个猫,还要实例化,来一只狗,我要创建一只狗,同样要实例化,还要配备专门的店小二去接待,就会相当麻烦
接口的作用对于很多新手来说很不容易理解,我给大家举个例子。接口只是一个规范,所以里面的方法都是空的。假如我开了一个宠物粮店,声明所有宠物都可以来我这里买粮食,这就相当于一个接口,public interface PetRestaurant { public void buy();}当一只狗…
谢不妖,答主也不是二本,答主是Java EE转Android,非计算机专业培训班生,写程序3年+。&br&企业用Java主要是用Java EE开发java web或者服务项目,需要学习和使用springframework
hibernate struts2 等常用框架,属于高层的面向对象编程。如果你有足够的面向对象编程经验,可以快速学习这些框架的入门知识,网上多是用例和API介绍。如果尚未学习过面向对向编程,则建议花更多一点时间学习面向对象的编程,并且【多】写一些Java web 的项目练习,补充一些常见项目的知识,比如CRM、进销存之类的。&br&&ol&&li&网上教学视频很多,比如某马的视频,搜索一下公开课一大把,自己足够刻苦的话不建议去培训班学习,学习费用太高。&br&&/li&&li&同时,虽然有强大的hibernate 框架帮助,你还是需要一些SQL知识,面试过程中会问,企业一般也不会耐心去教,在学习过程中不可漏掉。&br&&/li&&li&Java Web 的项目离不开HTML/CSS、JavaScript这些View层的技术(&a href=&///?target=http%3A//zh.wikipedia.org/wiki/MVC& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MVC&i class=&icon-external&&&/i&&/a&三层),和SQL一起可以在&a href=&///?target=http%3A//.cn/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&w3school 在线教程&i class=&icon-external&&&/i&&/a&网站上学习,当然还是需要多做练习。&/li&&/ol&
谢不妖,答主也不是二本,答主是Java EE转Android,非计算机专业培训班生,写程序3年+。企业用Java主要是用Java EE开发java web或者服务项目,需要学习和使用springframework hibernate struts2 等常用框架,属于高层的面向对象编程。如果你有足够的面向对…
从大学来说起,大学的计算机专业都有 Java 这门课,但没有 PHP 的,除非是一些以培训技能为主的学校。而一般理科专业都有开 C 语言这门课。&br&&br&计算机专业的同学毕业后找工作,现在工作难找啊,当然要找自己优势最大的。他们学过 Java,学过 C++,而且市场对这几块人才的需求量也高,因此,Java 程序员来自计算机专业的比较多,他们有着较为扎实的编程基础:汇编、操作系统原理、多门编程语言、数据结构、数据库、软件工程、网络,等等。而且 Java 这门语言,是比较纯粹的面向对象编程语言,学这门语言也可以学会很多编程的概念:抽象、接口、多态、继承、设计模式、框架,等等,这些概念其实是跨语言的。&br&&br&而 PHP 程序员,很多来自四面八方的专业,我见过不止一个从文科毕业转 PHP 编程的。因为 PHP 上手容易,有 C 基础的更不用说了,在学校里,感兴趣,接触到,花时间,就上手了。这些同学也毕业了,找工作,有些是本专业工作难找,有些是对本专业工作不感兴趣,而市场上对 PHP 程序员的需求量也蛮大的,于是他们也根据自己的优势和兴趣选择出发,从事了 PHP 开发工作。如果是非计算机专业,编程上的基础还是比较薄弱的,除非自己花时间补上。如果对 PHP 这门语言能做的东西感兴趣而不是对编程本身,刚开始还不一定会意识到去补上那些编程的基础知识。&br&&br&所以,刚毕业,总体来说,Java 程序员在编程能力上确实是有优势。&br&&br&但,毕业之后的一两年,就很难比较了。当你进入一个团队,你能从团队中获得非常多的知识和锻炼。如果这个团队擅长网络,那你的网络技能可以迅速提高,换个公司你都能当网管;如果这个团队擅长 OO 编程和系统架构,这方面的实践你会获得非常大的锻炼,如果自己努力补上理论知识,出去就能担任一些架构的职责;再比如,团队在实施敏捷开发方法学,你理解并实践了方法学中的一些最佳实践,出去也能去影响旧的开发方法学;等等。不管是哪门语言,都有很多优秀的团队在使用。所以,毕业之后,就没啥好比的了,要比也是比你的上进心、你付出的努力。&br&&br&之所以会出现谁瞧不起谁,也许是谁在用“瞧不起谁”来蒙蔽自己的担忧:不肯花时间去了解其他语言,又担心其他语言流行了,而自己这门弱了;不肯承认别人介绍的其他语言的优点,又担心这个优点真的很优秀,但自己又懒得去研究;等等。&br&&br&真正要比较的,是语言有哪些优势,适合哪些场景,而最主要的,是人。语言是工具,人掌握了工具的优缺点,就能熟练使用工具,而且用的恰到好处,事半功倍。那些瞧不起谁的人,能把这两门语言的优缺点、适用的场景,解释个清楚么?是程序写你,还是你写程序?&br&&br&没有谁瞧不起谁。努力。
从大学来说起,大学的计算机专业都有 Java 这门课,但没有 PHP 的,除非是一些以培训技能为主的学校。而一般理科专业都有开 C 语言这门课。计算机专业的同学毕业后找工作,现在工作难找啊,当然要找自己优势最大的。他们学过 Java,学过 C++,而且市场对这…
已有帐号?
无法登录?
社交帐号登录
733 个回答
247 人关注
153 人关注
3804 人关注
133 个回答
6914 人关注
214 个回答}

我要回帖

更多关于 java主流框架有哪些 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信