在念书期间,学习数据结构课程的时候,我发现了一个质量很好的 Java 数据结构 项目,当时也是受益匪浅。后来的几年作者没有再维护,但我认为这会是一个非常好的模式。

记得在 OJ 上做 ACM 时,我总会去思考这个代码会如何去通过测试用例,达到 Accepted 状态,记得当时的同学、学长说是后台有一个跑测试用例的服务。通过这个服务可以检查你代码的语法正确性、结果正确性以及时间空间复杂度。

后来在工作中我接触到了 TDD 开发模式,或者说代码开始有单元测试,所以就会想起了这个项目,打算重做一个。一来自我学习,当程序、数据结构、算法与我有更深的理解;二是验证这种模式对于他人的益处是否有我想象的那样多。

内容

基础的数据结构和算法必不可少,那么基础的程度我想先以红皮书《算法》为主。确保在这个点上,我能做到最好。随后,我会加入《算法导论》的内容和案例。几个好处:第一,《算法导论》提到的案例以及实现都是工业级的,比如切割钢条,DNA 最长公共序列,股票涨幅等。第二,《算法导论》里面给出了大量的数学推导和论证。所以在后期做性能测试的时候,如果我的测试结果和预想的有偏差,我可以找到理论依据或者的确是自己出 bug 的地方。再者,并发编程,IO,网络编程,设计模式以及一些系统设计的内容同样是这个项目会涉及的。除了基础的算法或者数据结构我应该去实现,同时我也会从 Leetcode,Lintcode,剑指 Offer 上去寻找一些相关的题目的解答和测试用例。举个例子就是我们实现 Kth Bigest 这种问题的时候,有一种就是快排的做法,可以发现只要对快排做少许的修改就可以实现;当然,用堆也是个很好的选择。

这个项目除了数据结构和算法,还有包括但不限于设计模式,网络 IO,并发编程等计算机领域较为基础的案例实现与测试。

测试

在实际的项目开发中,编写测试代码是很多公司为了保证软件质量的推荐方法。但是在这个项目里面,除了证明算法的正确性。更多的是在于能够让使用者在研究某个代码的时候,能够方便、清晰发现程序是怎么跑的。这一点很重要,相比于只给出代码和代码的图文讲解,我认为:每个人的理解能力和理解方式都是不同的,但做编码工作的人,大量的认知和理论都会实现到代码上。所以,只有很清楚自己要写什么样的代码的时候,才能真正按照意图写出来。这一点,我认为通过测试用例的方式是最好。当我想理解一段代码的时候,我可以 debug,可以试做修改通过跑测试的方式来证明自己的思路是没有问题的。

在编写测试代码的时候,我常常遇到了一些问题,比如给定一个数组生成最低二叉搜索树,我该如何证明生成的二叉搜索树是最低的。在我写单例模式的测试代码的时候,我发现我需要模拟并发的情景来证明一些线程安全问题。这个过程充满了挑战和乐趣。

对于学习者

我认为不管是实现一个经典的算法,还是 finish a problem,最重要的是要学会如何解决问题。所谓的问题是什么呢?在这个项目里,问题就是测试代码里面的内容。程序要实现的,就是以某种方式通过测试用例。这些我和一些 contributors 的实现对于每一个学习者来说只是一个参考和值得质疑的(质疑程序的性能和正确性;包括测试代码是否合乎逻辑)。我认为,当拿到一个新的算法时,最好先去自己实现一遍,然后去对应的 unit test 跑一遍,当其中有疑难的时候,记得 debug。只有在源码 + debug 的投射下,所有的疑惑都会被散去,那些看起来含糊不清的逻辑也会变得清晰。

地址

Talk is cheap. Show me the test!