算法一个既熟悉又陌生的词。我曾经很躁动的时候,想去各家应聘或者面试,然后人家问算法你会么?当时听到了,我就蒙蔽了,只能摇头。
天啊,作为接受过本科计算机专业学习的大学生来讲,竟然不知道什么是算法。我好脸红。
那什么是算法呢?
在接触过了一些人,一些事,一些教育之后,加上经常想想到底什么是之后。终于决定发这么一篇随笔,分享一下我关于算法这个事儿的看法。
现在并不方便查算法的定义。网断了。。。按照我的印象,算法就是处理一个问题的流程。它可以不像程序那样,有必要的输入输出,什么有限次,正确性。他就是单单对一个问题的观点和看法。比如拿文件流的操作来说,打开文件,写入内容,关上文件。这就是算法。
交换两个数据的在数组中的位置。这个东西,就有可能涉及到数据结构,比如至少要知道什么是数组。要知道内存中怎么定义数据。这样才可能会想到要再引入一个单元。作为中转站。所以算法又常常跟数据结构相联系。
说到联系,那么算法除了跟数据结构有关系,还跟哪些因素有关呢?既然说了(我所谓的)它的定义,是解决问题的逻辑、思路。那么它一定会跟这个问题本身有关系,前面举那个例子,说的是数据位置的交换,那么如果是数字的话,就可以少引入一个单元,来减小对内存的开支(这种方式大家都见过的,就不写了)。对于跟处理这个问题的人有关系。那人又跟什么有关系呢?跟人对问题的看法,以及人的经历,经验。人对问题怎么看,前两天跟同学一起讨论删元素节点的问题:甲指向乙,乙指向丙,丙指向丁,现在要求在O(1)时间删除单向链表的乙节点。怎么做?当然甲的前面还有很多元素,丁的后面也有很多元素。只是为了待会儿好描述这个问题。为了不让链表断掉,怎么着都得遍历一遍,拿到甲,然后再把丙链到甲后面,最后再把乙删了。当时想了好久,也不得解,最后被分享了答案:因为乙要被删除,所以其实其实不用太在意乙的存在,不妨把丙的值赋给乙,乙指向丁,然后把丙删了。看问题的方式不同,解决的方式就会不一样。经历得多了,自然有解决的办法,处理的次数多了经验也就有了。就像刚刚这个链表,我不说,你没听过,很难想到要怎么做;我说了,你记下了,你就基本忘不了了。
所以我其实挺反感面试的时候出算法题的。甚至更可怕的是算法调优题。因为有的时候这种东西就像是脑筋急转弯。合理的好的处理问题的逻辑,或者说是算法,如果用一个等式描述的话,应该是对于问题的充分理解,加上恰到好处的灵感,加上适当的休息与放松。不能对问题理解的游刃有余,怎么也不会想到这样一种诡诈的偷梁换柱(删除丙,而不是乙的等效情况)的手法。恰到好处的灵感,有时候,可以自己完成,有时候,可能需要你出去走走,玩玩,悲伤一阵,失落一段,就像疯狂动物园里的兔子,总是跟肉食动物干草食动物那个问题磕,可能未必会有进展,但是如果回家休息一阵儿。没准就能得到跟问题有关的线索。看到那些让动物发狂的花朵。当然灵感的来源光靠自己也不行,你需要多与他人沟通交流,依然需要乐观向上的态度。所以碰到算法题,我的心情就是日了狗了。这种时候,就先别想优化,先把问题解决出来,然后拿语言写出来,先让他正确运行,后面的事儿,后面再说。不要因为怕,或者是恶心算法题就不做了。虽然我的确依然认为算法题在一定程度上等价于脑筋急转弯儿。有些什么“咵嚓”一下砸地板上了问你电视怎么没坏,“灯”掉了一个问你轮胎还有几个,你得见过知道这个急转弯儿,你才能不上套,你没见过,就是做不出来,所以算法题实际上考察的是你见识问题的多寡,以及你面对问题的态度。这么想,可能会好一些。
实现算法跟语言有关系,跟对语言的熟悉程度有关系。在刚刚说了先想好,然后拿合适的语言实现。有些问题,就是鞭长莫及,有些就是效率极高。不同的语言就是会产生不同的效果。对于10岁的一个健康孩子和一个睿智青年以及一位阅历丰富的长者,如果他们都说汉语,那么对于同样问题的描述必然是不相同的。写程序好比说话,孩子说话可能将将能把问题说清楚,青年,可能能更加一语中的,长者除了见多识广,对于语言的把握亦是精深,言简意赅,寥寥数字便将问题讲清。这的确跟语言本身,以及对于语言的把握有着十分重要的关系。
算法调优,跟这个人的经历经验,以及对问题的理解程度有关系。
看到一些招聘要求,要求能对算法调优,真是随便拉个郎,便想结婚生子,子孙满堂。未免想太多。我认为怎么才能对一个算法进行调优。这需要对问题了若指掌。那怎么才算是理解透彻,能够在董事和总经理面前把这个逻辑讲清楚(别说什么程序员不会与人交流,说不明白问题,只会敲代码。我觉得只要是事情就一定能说明白,尤其是关于程序上、逻辑上的这一块儿,如果说不明白只能是他自己就不明白。),能够在当初缔造这个算法的人面前,边说边敲。如果非得为这些东西加一个标量我觉得,要至少在底下默写个5遍。
依然在象牙塔里面,胡乱说了很多,我觉得会不会算法调优,就跟你问你会不会做饭,会不会打乒乓球,会不会开车一样,会不会游泳一样。他并不真的实际对应你会还是不会两个端点。他是连续的一个不可以用函数描述的东西。但我知道它里面有几个参数比如,如果是做饭的话,跟你的心情有关,状态有关,心情不好敲出来的代码的注释都不太会是人话。如果是开车的话,你虽然拿了驾照,只有你知道你倒库跟侧方停到底停得怎么样,你虽然取得了认证,可是只有你知道自己的深浅。如果是游泳的话,只有你知道自己的极限能有多远,能在多大范围内进行调优。换做是打乒乓球,行内人看站姿看动作,便知你是否会打,如果你能至少拿到一个小的比赛的冠军,至少说明你可以栽培。最起码不用被从零开始带。(下面的东西毫不相干——如果计算机能够自己把所有这些东西都做抽取并且用一个函数描述,或者给计算机一个混沌时代,为他打上断点,如果实时监测到他能演化到奴隶社会,或者封建社会,就可以了基本让这套系统停下来了,但是我觉得那个时候基本就已经晚了,因为计算机系统已经学会学习了,学会创造规则了,我觉得计算机能够学会规则,并且自己缔造规则的时刻,就是计算机进行统治的时刻。欢迎看看我的另一个看法对于alphago的胜利以及人工智能有多智能才会统治世界的看法。)
都在路上,与大家共勉。