本科期间,差不多一直是自己在做开发,每个项目(自己做的那些东西,真不能和正经项目比,不过想不到别的词汇了,就暂且这么说吧)差不多都是因为兴趣而起,因为项目的腐烂(程序员修炼之道, Software Entropy)而终。由于自己不成熟的编程技术以及开发手段,总是闹出各种各样的项目现在真的是有内伤了,做项目真的有点害怕了,害怕自己做的这么点儿的项目都难以维护,哪还敢去接其他的东西呢。
我也一直想办法去改善这种情况,更准确的说,一直在找开发的方法以及开发的工具。从最开始用<%%>的JSP到用JSTL,从用STRUTS+JDBC到STRUTS2+Hibernate。后来觉得做这种web开发太累了,实在没心情去写那些讨厌的数据库CRUD讨厌在多个浏览器之间测试兼容性了。之后听说了敏捷以及TDD这些东西,有眼前一亮的感觉。在之后的一个小东西里面尝试了Junit,开始真的很不错,可是我感觉自己没有掌握好方法,总感觉自己做的很多东西是没办法做测试的。比如,我做爬取,不知道怎么样设计这个测试,导致最终的单元测试代码中开始出现System out这样的东西...更可悲的是在一次对项目迁移的时候放弃了自己觉得越来越混乱的单元测试代码,紧紧保留了"真正"的代码。之后就没有好好去尝试TDD了。还有就是版本控制了,最开始用SVN,现在想想挺2的。首先,自己根本没有仔细研究这个东西,为了用这么个版本控制,自己在自己的电脑上装了服务器又装了客户端,总觉得开着个apache挺别扭的...现在好了,在一次交流活动中听说了git这个有趣的东西。发现github这个伟大的网站,我把最近的开发项目纷纷转移到了那里,舒服多了~
我一直觉得做开发应该是一件很有意思的事情,它应该让我觉得开心,让我觉得有成就感,但事实却让我很失望,每次做开发都让我觉得很担心,很有压力,我担心问题不能解决,我担心系统不够完善,我担心bug频出,我担心越来越难维护的代码。我反复思考是不是哪里出了问题,应该怎么去改善。我一直觉得现在这么多问题是自己采用的技术不够好,自己的眼界不够广,自己的编程能力不够强和经验不够丰富。我觉得我也确确实实在努力的看书学习,去关注更新更好的技术,参加一些技术社区的活动,去一些平台多多coding。但是,我更缺少的是一种信念,一种支持,一种转变成强大信心的东西去弥补之前的内伤。
以前也看过一些敏捷的东西,但是不够上心。以前总觉得结对编程什么的对我来说没什么用,因为我是一个人在编程,那种团队的东西对我来说完全没有必要,主观的排斥这些内容。后来关注的就是TDD了,但是就像我前面所说的,我发现很多东西不好实现测试,而且很多东西在我开发之初都不知道它应该是个什么样子,都是走一步看一步,所以根本没有一个测试的框架。之后再一次百度开发者大会上,我听了一个敏捷开发的演讲让我有了眼前一亮的感觉。感觉他所说的一些问题正是我所遇到的问题,让我认识到不仅仅是我这样的小菜鸟也遇到了类似的问题,而且也让我感受到敏捷确实是在针对这些问题在做事情。于是我又一次翻出一个讲敏捷的,评价很高的书 Practices of an Agile Developer。我只能用我直白的语言讲,真的很不错。我想把自己比较喜欢的话以及对这本书的感慨都写下来。
No matter how far down the wrong road you' ve gone, turn back.
希望我可以迷途知返... 下面就是伟大的敏捷宣言,每次看都让我感慨万千:那就是我所期望的开发的感觉。 书中的开篇提到了很多精神上,态度上的问题:团队合作应该建立在一个平等的,乐观的,充满活力的氛围之中的。但是这种氛围的基础一定是团队里面的人都要靠谱!这个非常重要,一定不能有打酱油的人存在。如果你发现你的队友有人在打酱油,就应该剔除他,如果你的队友都在打酱油,那你就应该离开这个团队。
If a team member is repeatedly harming the team by their actions, then they are not acting in a professional manner. They aren't helping move the team toward a solution. In that case, they need to be removed from this team.
If the majority of the team (and especially the lead developers) don't act in a professional manner and aren't interested in moving in that direction, then you should remove yourself from the team and seek success elsewhere (which is a far better idea than being dragged into a "Death March" project
这个是一切的基础,平等的水平才有平等的待遇才有平等的互利。怎么能让一个大牛面对一堆菜鸟呢,那大牛显然是输出多输入少了,而且也会觉得很别扭,自然而然的想撤了。
Don’t code in isolation
这也是要有平等的水平才行的吧,如果我的代码总是很烂而你的代码很好,我总是能从你那里收获很多而你从我这里却收获甚微,让我来看是不是有点亏,当然这种说法确实有点小家子气了,不过事实就是这样的,各有亮点才能相互学习,共同进步~
You can't be an expert at everything. Don't try, But once you're an expert at a few things, it becomes easier to gain expertise in selected new areas.
第三章,谈到要不断地学习,我是有心学习的,可总觉得自己不求甚解的态度太不靠谱。是的,不可能样样精通的,但是这个精通到底是要达到什么样的地步呢? 之后,又谈到了对团队的建设方面,要多多共享自己的信息(6 invest your team),但是作者更强调:
Is Everyone Better Than You? Good!
Legendary jazz guitarist Pat Methany offers this advice: "Always be the worst guy in every band you' re in. If you' re the best guy there, you need to be in a different band. And I think that works for almost verything that’s out there as well." Why is that? If you're the best on the team, you have little incentive to continue to invest in yourself. But if everyone around you is better than you are, you'll be keenly motivated to catch up. You'll be on top of your game.
这也是我自己一直坚持的观点,我想去一个所有人都比我厉害的地方(而且我觉得不会很难:))。这也更表明了作者的态度,平等源于"平等"。
最近在做毕业设计了,刚刚终于让那个PyAIML可以学习中文的语句了,这个速度真的大大慢于我的预期。我想在这里写出来我对这个东西做一个任务分解,详细的说说每一块应该做什么。 首先,当然是要概述一些这个东西咯。我想要用目前的PyAIML去构建一个支持中文的ALICE。这种基于模板匹配的聊天机器人我觉得还是应该有一个自动学习的机制才能有所发展。最后,为了让这个聊天机器人可以更好的发展,需要提供更多的接口,让它可以通过不能的接口和别人去聊天,比如QQ,MSN等等。
我把问题分成如下几个:
中文的问题倒不是很难,可就是很讨厌。最近跑程序见到最多的错误就是UnicodeEncodeError和UnicodeDecodeError,恶心的不得了,每次看到这两个错误我都觉得自己以后应该去一个7位ascii就可以包含所有字符的国家活着去。编程这么久,遇到的最多的问题就是这讨厌的编码问题,mysql乱码,数据爬取乱码等等。写完这篇日志,我就要再写一篇专门将Python的编码相关的日志。我们回归正题,AIML是以词为单位进行分词的,以空格为词的分隔。天然中文之间是没有空格的,我要做的包括:
构建自动学习是最近工作的主题,随着中英的测试成功后,这个也告一段落了。AIML的Specification中有说标签可以执行代码的。可PyAIML做的太槽了,
我想尽各种办法让python可以运行下的python代码,在这里遇到了诸多的难题。首先,如何让python代码可以在运行时嵌入到python当前环境中呢?这里,伟大的stackoverflow拯救了我,我找到了how to input python code in run time and execute it ?, oh shit, i suddenly can not type Chinese in ubuntu now, what a shit os, it is better to be a server!!!! 好吧,我来到了我可爱的windows,一切继续吧。execfile可以把一个临时文件的代码相当于嵌入到当前的环境中。但是python是以indent为格式进行代码解析的。但是我们可爱的AIML默认把string 之间的 's+' 给删除掉了,我首先做的就是为system设置xml:space = "preserve"。然后,我写了一个算法可以格式化这些内容。之后就是无尽的debug了,比如全局变量和局部变量的问题呀,比如execfile无法嵌入import声明呀,比如中文字符问题呀。一坨一坨的,纠结了很久。这里就提一提我最后遇到的一个bug吧。
file = codecs.open(filename, 'r+', encoding='utf8')
xmldom = minidom.parse(file)
可耻的 minidom.parse 报错了,我纠结了很久很久!关键是之前已经因为各种bug烦的受不了了,遇到这个bug根本就没仔细看错误说明,开始根本就没注意是 parse 方法报错了!!!再次自责自己的不仔细,不淡定!最后,我删掉了那个codecs,让filename直接传递给 minidom.parse 就没问题了,一切就解决了!!!
把大量的时间耗费在某些很白痴的 bug 上真的很打击我,我觉得这些时间真的是白白浪费了,明明可以做很多事情的时间,就是因为不仔细,不细心就丢失了。开始怀疑自己平时编程是不是养成了太多的坏毛病。最近在看新浪名校公开课的stanford的编程基础课,那里老师就说,如果你有了编程基础但是养成了一些坏习惯还不如那些一张白纸,什么都不知道的门外汉好教呢。我觉得我就有点坏毛病了,很多东西浅尝辄止实在是不能成大器。
最后一个就是添加接口的问题了,我现在最想添加的就是 QQ 的接口了,不过看情况吧,不知道能不能做到那一地步,因为为了让机器人足够聪明,我还有很多工作要做,如果来不及的话,我就添加个 web 界面就OK了吧:)
这个标题似乎让人很晕,我也在试图去修改它让它变得更清楚一些。大概已经两个年半过去了,我还是觉得这个想法是合理的。
所谓生活就是在你忙着制定其他计划的时候发生的事情。
复用的概念在软件开发领域已经倡导了很多年了,GoF 的设计模式也已经深入人心。他们提倡模式的复用,代码的复用,软件的复用。当然,这是三个不同的层次。所谓的模式的复用是让一个软件有可生长的空间,让它拥抱变化使你最初的代码不因为新的变化需要大量的重写。代码的复用是将通用功能的模块做成了所谓的类库,避免了程序员重复发明轮子的过程。这种思想也让这个世界涌现出了众多的伟大的类库和框架,它们精心的结构,巧妙的接口让人惊叹不已。真不敢想象没有这些伟大的类库这个世界将是一个什么样子。伟大的东西就像这个领域发展的必然趋势,没有 APACHE 的世界最终也要有一个可能不叫做 APACHE 的角色出现。至于所谓的软件复用就有点说不清楚了,我们很难想像你 windows 里面的某两个软件可以被用于做别的事情。不过根据我目前的知识水平,我多能想到的就是 UNIX 下的一系列软件。那些命令行下的,神奇的 shell 程序。管道把它们连接起来形成了一套可以随意组合的灵活工具。
不过,我没有想在真正的 reusable 上花太多的段落,我们回到第一段的引言。从小到大,我们给自己或有心或无心的定下了无数的计划。我们这里所说的计划是一个方向,是一个按部就班、坚持不懈的达到某个预期目标的过程。它似乎是一个整体,似乎是一连串的动作只是为了最终的那个结果。所谓的功亏一篑就是说你沿着这个道路一路向前却恰恰少了最后一根稻草,是的,少了最后这么一篑你就输了。
那么,真的如此么?真的要这样坚持么?无心插柳:Gmail 作者、FriendFeed 创始人 Paul Buchheit 谈人生偶然性则给我们阐述了生活的另一番场景:无心插柳柳成荫,机会就在我们周围,但被我们的习惯和信念断送。生活的乐趣就在于这丰富的偶然性之中。过分的心无旁骛很有可能断送了巨大的机遇。你真的确定自己的计划或者说是信念就是你达到目的的最好途径么。事实上,个人的信念或者计划总是源自于自己对外界世界信息的分析和理解。当你获取了一个所谓的计划之后就摒弃了最初计划的来源是很不明智的。你最初的计划很有可能是因为你获取了片面的信息而得出的结论,此后的一意孤行不一定能够得到你需要的结果,或者不能很快的得到你想要的结果。
那么,我们应该怎么做呢。我认为很好的把握计划的粒度才是关键。
计划是要执行的,不过绝不能一意孤行下去。这个所谓的计划很可能要根据你的心智的越发成熟而产生变化。我们要做的应该是在这个过程中把计划分解成一个个小的模块并认真的执行这些小模块,让每一段经历都"值得一提"。这和我们的软工原则是一致的:我们让每个模块有自己独立的功能,避免各个模块的过分依赖。当我们发现我们的需求发生了变化,那么原有的模块依然有用武之地。最怕的就是在经历计划的变革之后,我们发现自己原来的工作一无是处了。
下面,我们就要说一说上一段所提到的"值得一提"了。其实,原则就是让你以前的经历有价值,不能因为它是错误的计划的产物就变得一无是处。举个例子,一个人在一个自己不感兴趣的公司做过一份自己不喜欢的工作,没几年就离开了。那么,在这个公司的一段时间是应当有价值的。是的,它在一个完整的计划中是失败的,但是你在这个经历中应该有所收获,而且最好是“值得一提”的。值得一提这个词真的很功利,它就好像是在说如果你去一个新的公司去面试,当 HR 问你以前的工作时,你可以很自豪的说出自己的业绩,而不是无言以对。当然,“值得一提”应该是你真的有所收获并有所成绩的外在表露,而不是夸夸其谈。
所以,请珍惜生活的每一个阶段,不要找任何借口去荒废它。未来是那样的不可捉摸,你永远都不知道自己现在所做的一切对将来会有什么样的影响。请用心的去度过你生活的每一个部分。不论你的计划是什么,它并不重要,重要的是你经历的过程。希望你回首往事,发现自己的一段段经历都好像是给自己留下的无数可重用的优秀代码,自己随手捏来加以组合就可以构建一个伟大的系统。你生活的过程,其实在很大程度上并不是在“做软件”,而是在为了将来的“信手捏来”积累优秀的资源。
我自己在最近的一两年内接过一些外包项目或者和人做一些合伙项目。这些新项目有的已经在被人使用了一些时候了,这我当然很开心。有些项目在我接的时候就知道它注定会失败(真的哦)。但是我还是做了,一个是出于钱的考虑(对于一个穷学生来说,这再自然不过了);另一方面则是觉得其实这些项目怎么来说都算是"真是的需求"。对的,比学校里的课程大作业强多了。我应该去捕捉这种机会去实际做一些东西。这其实对于很多人来事也算是难能可贵了。我除了关注项目的业务层级的发展之外还可以去关注它的技术方面的发展:这完全是另一个视角。这个项目不论成功与否,我通过实际项目去联系自己的技术的目的达到了。然后,通过踩过的这些坑,我可以在未来的项目中做的更快。
很多人不重视这些的,但实际上这些纷繁错杂的、在实际项目中才能历练出来的各种解决问题的能力以及遇到各种诡异问题的经验的积累还是非常重要的。因为事实上开发工作很多内容就是这些:救火。并且,我也在反复强调,这确实是在比较真实的项目中才能遇到的。比如,我们在平时做自己的项目的时候,我们很少接触百万级或者千万级的数据。而在给别人做项目的时候就会有这些问题。那么性能的问题,内存,带宽这些都会显现出来。我本身就很崇尚实用主义,在实际项目中去学习一些东西对我来说确实非常的适合。