ITPub博客

首页 > > > 我的编程生涯(9):困境和顿悟··············

我的编程生涯(9):困境和顿悟··············

作者:u_453e1a12781dea 时间:2016-01-21 15:36:23 0 删除 编辑
我的编程生涯(9)
迷失与初恋



按:应Ager的要求,我逐渐地贴出了我曾经走过的路,从一开始的朦胧,到启蒙,到学习和自我学习的过程和那些心中的感情。

这会是一个系列,Ager说会催促我将其完成。那么就从最开始的朦胧开始吧。大家可以就当做小说来看,不过里面我也会将自己的学习过程,以及之后的一些想法加进去。

篇幅比较长一点,不好意思~另外这些文字本身也会 因为大家的反馈做出一些修改。说白了,这就是一个大坑儿,所以谢谢观赏啦~~

大
一的下半学期,对我来说是一个重要的转折。

延续了整个上半年的疯狂的吸收,似乎到了瓶颈地带。我看完了我所能找到的任何一本书。现在是开始编程的时间了。 

可是,我意外地发现,我居然不知道该如何开始。 

因为以前编程的时候用的是Lava,那货是不存在malloc和free的,所有的内存都给你 (从8192到24K的所有内存),然后你自己爱怎么用怎么用,反正就是这么多。突然一下子转移到有了内存保护Windows,我感到很不适应。虽然看过了许多书,但是在这种情况下应该怎么办,我还是没有任何概念。
 
于是一开始的时候,我开始全局变量干活,可是看到VC++2005生成的模块代码我又彻底傻眼了——全局变量的声明放哪儿……这儿好像有很多个cpp文件…… 

所以,基本上大一下学期开始,我是一直在摸着石头过河的。恩,全局变量很好。那别的文件怎么用这些东西呢?突然有一天发现的extern可以派上用场(诶?谭浩强讲了这个么?还真是没印象了!)。突然一下子,从一个单文件、没有预处理、没有指针、没有堆内存的语言转移到完全版本的C语言,完全没有任何经验。 

还有就是算法问题。当时的我居然无法设计一些很简单的算法。比如说小学写的贪吃蛇吧。当时就用的是整个棋盘模拟。可是遇到需要稍微分析(或者叫挖掘)的应用,我就傻了。比如说写五子棋的游戏:你怎么判断有五颗子排一排呢?写个循环判断一下?恩,横,竖,左斜,右斜,四个循环。感觉不太漂亮啊……算了也没别的办法了。可是写连连看的时候彻底傻了……两个图案在同一排?同一列?不同排?不同列?中间经历了哪些块? 

最后的结果是,写连连看的时候,居然每个情况统统写了一个函数,最后写了16个函数覆盖了所有的情况才搞定。 

我开始觉得有点不对劲了。 

苦闷的是,我完全不知道如何解决这些不对劲的地方。我没有人交流,学校里面的老师除了写1加到100的程序以外什么都不会。我开始觉得自己似乎缺了一块,但是我又不知道缺的到底是哪一块。
 
那段时间,我好像是遇到了对手的食神一样,做完一道菜,尝一下,发现味道不对,然后扔掉继续做下一道菜。这样一直一直下去,一股叫做烦闷的情绪开始蔓延。我开始减少编程的时间,开始在网上漫游,寻找我能找到的任何信息。 

慢慢地我开始学会使用搜索引擎。那个时候的搜索引擎没有现在的聪明,于是我自己学着将问题总结成几个关键字再去搜索,而不是去搜索一整段话。这种总结的能力极大地帮助了我了解我面对的困境。我学会了使用论坛,学会了在论坛提问。反正不知道是什么时候,我发了“BCCN”论坛,遇见了飞燕。 

飞燕真的可以算是我编程入门的启蒙老师。在我学会了编程语言以后,她教会了我如何用这种语言写一篇声情并茂的文章。或者更浅显点,她至少教会了我基本的代码审美观,不是缩进、空格这些,而是一份代码,如何才能算是在逻辑上“好看”。 

反正不知道什么时候,我当了飞燕算法群的管理员。经常参加飞燕组织的各种活动。其中就包括ACM/ICPC的线上模拟评测。
 
我开始发现,原来编程可以并不只是产生“某种人眼可见的效果”,而可以仅仅产生纯逻辑问题的输出。我开始关注什么叫“算法”,我发现之前如同填鸭被填进去知识突然开始显现了它们自己的意义:为什么要学数据结构?因为你要学会如何保存、处理你自己的数据!为什么要学习算法?因为这是被归结为处理问题高效的方法,而站在更高的高度,算法实质上就相当于你写文章的“笔法”,它内部贯彻了一种思想。而且因为计算机的思想很单纯(就是高效),并没有人类那么多复杂的想法,所以算法的思想就会更加纯粹。它形成了一种统一的审美观,形成了人们对程序本身一种统一性的看法和评价标准。 

突然开始觉得不再孤单,觉得和整个世界联系起来了。就如同一个默默地学习写字的人,突然看到了这个世界上绚烂的文章,开始明白怎么写的文章别人爱看,开始明白怎么有效地在有限的篇幅表现自己的感情和思想,而不仅仅是辞句的堆叠。直到从此刻开始,我才真的觉得自己入了门。距自己接触计算机,已经度过了十年了。 

以数据结构为骨,以算法为魂,以代码为肉,才是完整的程序。数据结构决定了程序的移植性和大体的接口,算法决定了程序整体的风格和特征,而代码,则是程序的“肉皮囊”,是对程序的第一印象。这就是我对编程的理解。

而后C++的学习就开始豁然开朗:和C以算法——命令的执行——为中心不同,C++实质上是以数据结构为中心的。它倾向于构建外界无关的一个完整的状态体,被称为“对象”,任何有需要改变这个状态体的企图,都必须通过和这个对象声明的“消息”,即方法。对象本身接收到了消息之后的处理过程,就是算法。对C++而言,算法依然是魂,而数据结构依然是骨,代码则依然是肉。
 
这里写起来,好像顿悟就在一瞬间。但我还记得那段时光是怎么度过的。在春光明媚的四月天,我一个人在宿舍不停地写不停地调试。每天早晨8点打开VC,一直写写调调到天黑。偶尔抬起头,看着窗外明媚的阳光,又埋头继续编程。这样的领悟过程是慢慢的,是沉淀在记忆中的,我已不记得当初付出了多少精力。 

我开始慢慢地将知识都连贯了起来。计算机组成原理告诉了我我写的程序是如何执行的,如同人如何理解字词这样的知识。数据结构构成了程序的骨骼,决定了程序的运动方式。算法本身改变了程序员自身的思维方式,又通过程序员的思维方式来规划程序本身的运行方式,就好像是一个人跳着美好的舞蹈,对外星人来说可能只是肢体的某种带着规律的运动,而对于同样的人类来说,这给予了我们美好的观感和感情,我们能体验出其中的美,这就是算法。
 
在这个基础上,计算机的整个构架在我眼中清晰了。 

算法的第一种思想,就是枚举——计算机的运行速度很快,所以要习惯让程序去做大量重复性的劳动,比如说拿起一个答案,检查它对不对,然后检查下一个。计算机能以很快的速度完成这样的工作。这种思想旨在改变程序员的固有思维:要记住,计算机是很快的。 

算法的第二种思想,则是分治。将一个复杂的问题,划分为几个不那么复杂的部分,然后分别处理。分治本身是算法的灵魂,也就是编程的灵魂的灵魂。如果说枚举是走路,那么分治就是跑步了。分治思想告诉我们,计算机一次不能处理太多太复杂的情形,因为计算机需要我们告诉他每一步的具体工作。那么让程序短小,让计算机高效的一个办法是,顺着问题的特点,将相同的工作划分在一起,将不同的工作划分开,然后让计算机去“枚举”,这就是分治。另一种分治则是将相同的工作划分开,然后在处理后续的工作时,用上之前处理的信息。这是加快计算机程序执行的一个最重要的思想:不做重复功。如果说枚举告诉程序员,计算机是很快的,那么分治就是在告诉程序员,计算机其实没有你想象中的快。 

其他的什么递归,什么搜索,本质上就是在枚举和分治之间玩着灵活的游戏。就比如说一个人身体的某个关节本身只会有一个运动方向,但是整个人动起来,就可能形成很没美观的动作。问题是你得先理解计算机最基础的特性,你才能够利用这些特性,做一些复杂和花哨的动作。 

我终于有了一种清晰的感觉:我已经跨过了最高的那道门槛。 

注:本故事版权属ChinaUnix社区用户starwing83所有,转载请注明出处。

(未完待续)



原文作者:;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2019-07-17

  • 博文量
    1982
  • 访问量
    17892