你的位置:首页 > Java教程

[Java教程]一个大三学生的学习之悟


  也许你们(学生党)跟我拥有差不多的经历:经过了高中三年的奋发图强,度过了无数个挑灯夜读的夜晚,终于考进了大学(这里就不说是考进了理想的大学了,毕竟现实很残酷)。于是在进入了大学后,你就会发现自己越来越懒了,为啥呢?那是因为大学并不像高中那样,上课井然有序,老师时常在你身边督促着你,上了大学,你会发现,大部分的时间都是由你决定的,就这样,你就会渐渐的变得懒散,做什么事情都几乎抬不起劲,当然,这不包括你在期末考试时的“复高三”状态。但是,此时的你有没有想到在这大学的几年里,你可得为自己的未来的价值的实现提供那必要的技能。

  本人是软件工程专业学生,学的是Java这一块,作为一个代码编辑者(不敢自称程序员,毕竟不是每个学编程的人就是程序员了),以下主要谈谈本人对Java编程的一些看法,如果你是初学者,请以质疑并且在未来的实践中记得时时去跟本人所写的看法进行对比的态度来看看这篇文章,如果你是Java这一块的程序员(真正的程序员),欢迎各位前辈的拍砖。

  本人觉得,学习一个领域的东西,最重要的是有个方向,知道它包括了什么,能解决什么的问题,而我们又该学习什么。

  以下以Java这一块为例,先上图先。

                     

  如果你想学习Java这一块,并且现在还在不知道该学习什么,本人建议你可以先像上面所列的那样先学习,当然这是往Javaweb这一方向的,如果你想往Android开发方向,J2SE这一部分是基础,所以学好这一块也是很重要的,这里淡淡的说一句,要么不学,要学就不要半途而废。

  对于学一门语言,感觉不要仅仅只局限于语法,要是现在你问我,Java的所有保留字是什么,说真的,我也不能完完整整的说出来,但这有很大的关系吗?如果你是怕自己定义的变量跟Java保留字相同,那么大可放心,Java IDE会友好的提示你,如果你是大牛,用记事本来写Java,那么在编译的时候,Java编译器会提示你相关错误,也大可放心,这样的好处是锻炼你查bug的勇气和能力,因祸得福啊!要是真的不行,果断Google或者百度。

  如何学习Java,本人觉得你需要做到以下几点:

  1.从内存结构去分析程序: 先问一下,平时你是如何去思考这段代码的?

 1 public class Hello { 2  public void static void main(String[] args) { 3     int i = 10; 4     Test t = new Test(); 5     t.setName(new String("xiao")); //这里是为了说明另一个知识点,故new了一个对象  6      System.out.println(t.getName());     7  8   }        9 }10 11 class Test {12   String name;13 14   public void setName(String name) {15      this.name = name;16    }  17 18   public String getName() {19      return this.name; 20    } 21 22 }

 好吧,说说如何从内存结构去执行这段代码。首先,在我们的意识里要建立如下的一个内存模型,当程序被加载到内存时,内存可以被划分为四部分,分别是堆、栈、常量池、代码区。堆你暂时可以理解成你在程序中new出来的那些对象,它的特点是空间比较大,而且不会像栈那样的有序,一旦你new出来一个对象,它就会在堆中查找一块空间来存储你new的对象,那么你可能会问,那么系统是如何调用它的呢?这在后面再解释。堆是Java的GC工作时收集对象的地方,在这里,GC会把对象分为三个“代”,分别是新生代、年老代和永久代,GC主要分为两种:minor GC 和 Full GC,一般情况下,minor GC 比较的活跃,它作用于新生代,采用“复制”的方式工作在新生代的eden和两个survivor里,缺点是采用“复制”的算法需要double area(双倍空间),但优点是清理速度快且没有内存碎片;Full GC作用于整个堆中,包括新生代、年老代和永久代,它的触发条件可能是永久代空间不够了,又或者是survivor中经过多次的清理后仍存活的对象进阶到年老代时,此时的年老代又空间不足,或者因为 System.gc()被显示调用等别的其他原因,就会触发Full GC,Full GC 发生后,如果是单处理器的系统,那么你的运行程序就会暂停,因为此时GC在工作,或者你的系统处理器是可以并发或并行的,但如果堆的垃圾对象太多,并且Full GC 是采用“标记-清除”算法,清理速度慢且会产生内存碎片,也会使程序一定时间的暂停,而这不可控的停顿是Java语言的一个不足之处,这也是Java运用到大型且对程序运行时无法容忍停顿时间过长的项目的一个瓶颈,当然,G1的提出就是为大型运用而提出的,它吸取了“增量”收集的优点,有利于为Java GC的改进提供一些参考,关于GC的内容,稍后本人会写一篇文章来介绍一下(突然发现拓展的有点多!!!正在汗颜中...)。栈,Jvm 和 操作系统共同管理的地方,你可以理解成程序所定义的的成员变量和局部变量,这里稍稍说一下new一个对象时,它的内存模型是系统在栈中开辟一个空间,然后在堆中开辟一个空间来存储new出来的对象,然后这个对象所对应的堆空间的起始地址就会被系统放在你刚刚在栈中创建出来的空间中。对于常量池,你可以理解为存放一些常量,如字符串常量等等,而代码区无疑是存放你的代码的地方,有利于动态加载。

    好吧!看图,程序从main函数开始运行,首先就会给args分配空间,注意此时的args是引用对象,所以在堆和栈中都有分配------->执行第3条语句----->执行第4条语句------>执行第5条语句(说明:当我们new一个String对象时,由于String是final的,所以系统会先去常量池看有没有“xiao”这个字符串,如果没有,它就会在常量池里创建一个,以便下次被其他字符串变量引用,而且它自己也会自己创建一个“xiao”对象,并指向它,这里就可以解释"补充例子里的原因了,例子见下面" )------>执行对6条语句(此时栈中是一个匿名变量)------>程序结束后栈中变量会被清空

 

                                    

        

补充样例:

 1 public class TestString { 2  3  public static void main(String[] args) { 4  5    String s1 = new String("xiao"); //在常量池创建了一个对象,并自己创    建一个自己现在指向的对象 6    String s2 = new String("xiao"); //在常量池有了这个对象,不用再创建,只需自己创建一个自己现在指向的对象 7    String s3 = "xiao"; //在常量池有了这个对象,直接指向它   8    String s4 = "xiao"; //在常量池有了这个对象,直接指向它  9 10    System.out.println(s1==s2); //false 11    System.out.println(s3==s4); //true 12 13 }14 15 }

View Code

 2.不管什么语言,练是必须得,不能总是只看不练,不要去死记硬背所有的方法,要学会去查API,你知道的不知道的类和类的方法和属性那里都有。

 3.遇到异常或bug,要学会自己先去读异常和调试bug,各种IDE工具一般都有debug功能,真的解决不了再去问别人,如google、baidu及各种论坛(如博客园、csdn等),在平常的项目练习中,除了要有注释的好习惯之外,要学会单元测试,jUnit就挺不错的,当然还有其他的很多工具。

 4.最后引用马老师对对象的思考方法:面向对象的方法是当你考虑一个问题时,你首先思考的是在这一个项目中,有哪些对象、这些对象各自有什么属性和方法、这些对象之间有什么关系(继承、组合、聚集、实现等等)