周日晚上开始,大概是 11 点多以后了,我开始写这学期的《数据结构与算法分析》课程的第一次作业的倒数第二道题。题目要求是用 C 语言或者 Java 语言实现 Binary Heap、Ternary Heap、Quaternary Heap、LB-Tree、Skew Tree、 Binomial Queue 这几个数据结构,在程序开始的时候随机生成一个包含 10000 个正整数元素的数组,把这些数据存到这些数据结构中,然后把这写数从小到大取出来,统计进行内存操作的次数,来得到这几个数据结构的性能对比。
我之前和同学讨论过这个题目,对方说他花了不少时间,不过他是用 C 来实现的。我由于这次作业第二天早上就要交了,所以也就没有跟自己较劲,非要用 C 写。基于之前用 Java 的经历,我如果要从 C 和 Java 当中选一个语言来写这个程序,我毫不由于的选择了 Java。
我曾经一度非常讨厌用 Java,因为觉得语法太繁琐,要读取文件都很麻烦。在 C 之类的语言中几行就 OK 了。另外的原因大概是有些审美疲劳,虽然本事不怎么样,但那时却好高骛远,想接触一下 C++ 之类的语言以及 Ruby 之类的新型语言。Java 写多了,那时后的课程又没有什么难度,就有些小看了 Java。后来我的一下比较大的“项目”都是用 Java 完成的,我学了面向对象课程之后,对 Java 也算是有了新的尊敬。
我最近的几次大项目有点不大在状态。每次在截止日期之前都提不起兴致来,非要等到第二天就要交了,前一天晚上才用咖啡顶着,熬夜把项目不紧不慢的写完。每次大概花上夜里 8 个小时,也算是一鼓作气了。上学期《专家系统》课的学期项目是如此,这学期的《面向对象》的第一次作业飞机座位模拟也是这样,这次的《数据结构》也是一样的情况。每个程序的规模基本上在 2000 行代码左右。后来我总结了一下,发现 Java 实在是功不可没。要是让我用 C 语言或者 C++ 来在 8 个小时内写这么多代码,我中间的空指针就够我受的了。
我另外用 Java 写的项目是去年暑假上《软件工程》课的时候和另外四个人组成的小组做的学期作业,是一个自动生成歌曲列表的软件。我所在的小组完成的是底层的逻辑部分,似乎和对象的交互没什么关系。我在上学期也和另外一个人用 C 语言写过《计算机网络》课的学期项目,我之前也写过文章讲过相关的故事。那和 Java 比就完全不是一个级别的了,开始时我写 concurrency 的时候简直是一筹莫展。后来我是用的 C 写的游戏的逻辑部分,对方写了服务器和客户端的界面与交互,总算是完成了。不过在演示的时候还是出现了字符串的乱码,估计是一个某个地方有了一个“野指针”。不过打分的助教说这不是重点,于是我们也没有找具体是哪里有问题。
之所以把 C++ 排除在外,是因为我目前的 C++ 水平很弱。我曾经在 STL 流行之前觉得我对 C++ 掌握的差不多了,那时候我还在中学时期,现在想起来也是狂妄的可以。过去只知道有个 class
关键字,底层是怎么回事我是一点都不了解。现在学了面向对象课程,学到了 C++ 中的类不仅可以放在堆里面,也可以放在栈里面。这让我困惑了许久,两着之间的区别是怎么样我也考虑过很久。还有,过去光记得用 class
关键字来定义类,使用的时候也没记得要用指针。现在基本上在定义的时候前面加星号成了标准写法,也让我着实愣了一阵。我还没有用 C++ 写上几个 2000 行左右的程序,因此对于语言本身的掌控没有什么感觉。我用 Java 写这种东西,只要把题目搞清除了,从纸上设计好,就可以开始写了。类之间的组合什么的基本上不会有什么问题,顶多在检查空指针的时候查一些粗心错误。C++ 我就还没有这个底气。
我考虑了一下我为什么感觉喜欢 Java,我喜欢的到底是 Java 的什么东西?最后得到的结论大概还是自动垃圾回收以及隐藏指针吧。C++ 和 C 里面的指针分配,不管是 new/delete 还是 malloc/free 都要小心翼翼的,这些东西又不能自动递归执行,稍微有点嵌套的数据结构在释放内存的时候就要自己做许多事。Java 的自动垃圾回收虽然从效率上不如 C/C++,但以目前的机能来说,差距也不大,而节省下来的人力时间则不是机器执行时间可以比的。而指针隐藏和垃圾回收也有一定的关系,不用手动维护指针总是好的。虽然指针给了更灵活的操作,但也容易让人写出有隐患的代码。
总结出了这两点,我又检查了一遍,似乎还真没有别的我喜欢的地方了。相反倒是有我不喜欢的地方,就是 Java 没有一个好的调试器,或者说我还没有掌握一个 Java 调试器。我在上学期用 C 写项目的时候,终于对 GDB 有些开窍了,突然觉得它真是一个好工具。尽管我只会用它的很小一部分功能,但已经基本上可以满足我的需要了。我用 GDB 主要是程序有了 Seg Fault 的时候,进 GDB 运行一下看看空指针在哪里。或者就是程序有了奇怪的行为,去设个断点,分步执行一下,跟踪一下变量的变化。虽然不像我过去用的那种 FreePascal IDE 之类的调试器一样可以即时的显式监控变量的列表,但我也习惯了用 p
来查看变量的值。Java 的 SDK 里面有 JDB 这个 GDB 的模拟,我用过几次总是一头雾水。说是 GDB 的模拟,但指令基本上全都变了模样。也没有缩写了,指令本身也变了好多。我反正是一次也没有成功的用起来 JDB 过,所以到目前位置我还是在代码里面插入“人肉”断言来输出变量的值的。
基于上面说的那两点,我觉得应该有不少语言都满足这些要求,但我基本上都没有熟练到像 Java 那样子。而且 Java 也算是最流行的一个,我们老师课不让我们随便用 Ruby 写作业。或者我听说 Objective C 也不错,在 C 的语法基础上加上了自动垃圾回收什么的。不过对于他我还是一点没有入门,语法上也觉得颇为奇怪。就算是之前最熟悉的 Python,拿来让我写这种大项目我也是要愣一阵子的。
想到了这一点,我觉得应该可以找到一种适合自己的编程模式,来发挥我需要语言的特性。通晓了这一点之后,应该写千百个项目都不成问题了吧。
《越来越喜欢 Java 了》有1条评论