我是半个程序员

  大一那会儿,经常有学长们来宿舍推销计算机考证培训课程。宿舍小王影凭借强大的pascal基础以及由此带来的浓厚兴趣,上当交了钱,领了一些内部资料来。我听着这证还挺有用,关键是这东西挺好玩,就把资料借来看看。我也萌生了考证的念头。那时真没钱,肯定不会去报班,于是就借那些报了班领了资料但是不看的同学的资料过来看,对C语言有了初步的了解。偶尔学院里的一次新生交流会,有位学长推荐了一本谭浩强的C语言程序设计,我记在了心里。后来,和牙医冯小杰去超市,路过楼下的旧书店,竟然发现了这本书。略微怂恿下,牙医花了5块钱将书收下。带回宿舍我就开始看,这书写得确实不错,看得一点也不吃力。经常听人说学计算机语言一定要多上机,我就去学校的机房,那一堆老机器,运行Tubor C是绰绰有余了。当然,考试还有一项内容是公共基础,什么数据结构、堆、栈,当时觉得特枯燥,现在觉得也是。于是就死记硬背。考前几个晚上和小王影互相考问。最后,就这么过了二级,总共好像是过了3个人。后来,同学们都去报二级了,因为当时有个说法是毕业一定要过二级,不知道是不是真的。这样的话,我的优越感就没了,于是,我又去报了三级。三级分方向,我选了网络技术,看书才发现超级无聊,全靠死记硬背。最后考前还有两章没有看完,也就去考了,也就考过了,记得机试只考一道题,要么满分,要么零分。之后学校课程才开始上VB和C,我没有沉下心来好好巩固下基础,只是凭着先有的知识应付了下,这个有点可惜。后来又学了VF,现在已完全无印象。比较有意思的事情是后来和小王影他们组队去参加程序设计大赛,限时做题目。

  大三那会儿说到最后的发展方向,老姐一直建议我向交叉学科靠齐,本专业是环境工程,再看看自己对什么感兴趣,一交叉,应该会很有前途。我开始寻找计算机和环境工程的交叉点。受自己思维和见识以及搜索能力的局限,没有找见具体的东西。有一门薛喜成薛老师的计算机在环境工程中的应用,我本以为找到路了,最后却发现不是我要找的东西。我不知道我要找的具体东西是什么,但是我感觉这门课不是。这课都是讲线性回归什么的,不是很感兴趣。当时还偷偷发短信给薛老师问有关计算机和环境工程的联系点,结果他没回,之后也没勇气打个电话,不了了之。后来不知道怎么萌生出想学经济的念头,一交叉,发现这个词是“环境经济学”,居然还是一个专业,特别兴奋,立马决定考研考“环境经济学”。有那么一个学期还专程跑去听经济学的课,发现老师讲的真不咋滴,基本都是照本宣科。后来听取了过来人的意见,工科不能丢,环境经济学太理论了,不利于就业。再三犹豫下,还是决定考本专业,但是要选一个好学校,最后锁定了同济。

  大三大四两年基本放下了程序,也没过多往这方面想。怪自己太中庸,没有积极探索自己的兴趣。最后考研失利,成绩烂到都不好意思说自己是考同济的。本来打算二战,最后在林小新和韩小悦的怂恿下,调剂到上理。韩小悦给了我四个备选导师,我没有任何原因地选择了我当时的导师,现在的老板。复试那天,我是第二个,正对面坐着的是一个气场很强的家伙,复试完才知道我选的人就是他。上理那会儿还没像现在这么火,调剂名额很充足,我也就顺利被录了。这个时候,我自认为和编程这东西没啥关系了,要在环境工程的领域里好好深造。

  复试完后回西安做毕业论文的时候,有一天接到一个陌生号码,是老板打来得的。他说他将成为我的导师,而且很缺人,希望我能尽快过去。他说面试的时候我说过对编程感兴趣,他那边正缺会VB和C语言的人。我当时还没明白过来具体是什么,心里却是异常兴奋。就这样,我又把之前的VB和C课本拿出来看。而且听韩小悦说过这老师是自己开公司的,我就不停幻想着即将到来的研究生生涯。毕业回家待了一周就兴致勃勃的奔向了上海。

  过了两天老板带我引见了工程师戴工,简单介绍了具体的工作。原来老板一直在开发一款水质分析产品,对当时的我而言完全没有概念。简单的说就是用来测油的,戴工是纯硬件工程师,我要做的是学会编程,协助他将仪器弄出来。戴工让我先开始接触单片机,从最简单的51开始。第一次听说“单片机”这个词,各种百度搜索,稍微有了概念。后来在同济的一家旧书店看到一本51单片机C语言程序设计,四折收下。回去后开始看书,这种感觉和当时第一次看谭浩强的C语言无异。下载了编译环境KEIL4来玩,后来有师兄送了我一套51单片机开发板,一下子入门了,然后就感觉很难提高了,因为不知道接下来要做什么。开学了,注意力又分散到其他事物中,单片机始终停留在入门级。后来老板说单片机一时半会儿弄不出来,还是先弄VB吧,软件比较着急。于是我又开始去整VB。

  这段时间基本没有了自己的主心骨,没有了自己的方向。不停在老板的指示下,从单片机切换到VB,又从VB切换到单片机。这个时候,我始终觉得基础太差,决定好好打基础,同时向着伟大的程序员靠拢。在编程的世界里,计算机语言多到数不清,VB、C只是冰山一小角。有时候考虑到自己的发展之路,不免有些迷茫。真正的程序员在我这个时候已经很牛逼了。以我这种学习速度,恐怕是很难了。而且以我的定势思维,什么事情都应该搞清楚来龙去脉,不然很难掌握,又太过于追求完美。于是,我产生了深深的自卑感,觉得基础太差,而另一边老板又希望我能立马上手做实际性的东西出来。由此,心里难免有些浮躁,很难静下心来好好打基础,又无法一下子用上手。

  终于有一天,我决定先抛弃薄弱的基础,而把先人留下的源代码细细研读。这是两份源代码,一份是MSP430单片机C语言,一份是VB。我的终极目标是把这两份都看懂,然后可以在上面随心所欲的修改。C代码主文件有8000多行,我开始慢慢梳理。由于结构过于庞大,在电脑屏幕上下滑动看代码很费事,我开始抄代码。边抄边整理。基本上看的都是云里雾里的,我安慰自己,只要梳理出框架来就好,具体细节可以回头再体会。写这份代码的人很不专业,变量命名很乱,程序整体结构也很乱,最关键的是基本没有注释。读这样的代码非常费力,很多时候都要靠猜。书上都会有一节讲写代码的规范,我是深刻理解了注释和变量命名的重要性。断断续续看了三个月,对框架有了基本的把握,知道了哪块内容对应了什么功能。但是,对于单片机怎么控制泵,怎么控制阀,怎么显示等等涉及硬件的东西,我全然不知。

  这个时候,老板开始开发另外一款水质分析仪。我被要求写软件编制说明书,因为我还没有能力独立编制软件,所以只能找外面的软件工程师帮忙。但是必须要有一份软件编制说明书来告知软件工程师这个软件要怎么编。老板只是老板,并不懂产品开发流程。于是,在我费了老大心思写完整整17页各种图文结合的软件编制说明书交给软件工程师后,他说需要硬件协议,我写的基本没什么用。而硬件协议需要硬件工程师给出,于是我成了软件工程师和硬件工程师之间的枢纽。最后,我明白了产品开发流程:从提出需求开始,硬件工程师根据需求设计硬件结构画电路图确定硬件协议,然后交至软件工程师编制软件,两边结合后调试。最后由于精力有限,这个仪器没有继续开发,但是在这个过程中学会了什么叫仪器开发。

  我还是把精力转回到源代码上。在老板的敦促下,我同时跟着戴工熟悉仪器,戴工一直没能让我上手动仪器,比较遗憾,我也没学到什么实质性的东西。其实比较正常,这款仪器是戴工毕生的心血,以做技术的眼光,怎么可能轻易教给别人呢。而且我不是那种特别能拉关系的人,一度很无望。结果,转机出现了。戴工要回老家了。他一走,我直接成为这款仪器的后续开发接班人。

  当时是怎么样一种心情?很难讲。老板经常会问,这个你会吗。我会一点,但是不敢讲出来。因为,一旦说会,满满的都是负担。但是我很兴奋,仪器在我手里,想怎么拆想怎么学习都行,完全摆脱了戴工的束缚。另一方面,稍微有点不明白的地方就很困扰,因为没有可以帮忙释疑的人。不管怎样,我开启了硬件学习之路。

  从程序中,我看出某些控制信息,只看代码完全不知道是控制什么东西。我拆下电路板,开始研究MSP430芯片上的每个引脚接的什么部件,通过比较数据手册上的引脚示意图,来分析。然而,我对电路一窍不通,电路板上接的元器件除了电阻其他一个都不认识,再加上电路板本身线路的复杂布局,往往从芯片的某个引脚出发,就找不见它接到哪里去了。后来学会了使用万用表,可以测量通路,这才得以顺利找见了接口。大致明白了芯片各引脚的最终接口,也就找见了控制信息所对应的部件。最终,我看懂了这些代码,知道了如何修改代码以使硬件改变运行状态。光看代码是一件很枯燥的事情,但却很有用,看代码时会有各种疑惑,这些疑惑正是去了解硬件的突破口。而一旦了解了硬件的接法,那么这些疑惑也都自然解决了,代码看起来就非常顺畅。两者相辅相成,如果我没有去看代码,不产生疑惑,而直接去看硬件电路的接法,也许什么都看不出来。很多时候,想学一样新事物,对它的某个点产生疑惑的时候才是开始学习的最好时机。

  代码看得差不多了,我尝试着修改了,编译也通过了,下一步就是把它烧录到单片机中。51单片机那套开发板带有两种烧录方式,都很方便。MSP430我不知道怎么进行,但是我见过戴工烧录程序。于是,我也去淘宝上买了430仿真器。买来发现,仿真器有14个引脚输出,而电路板上才6个脚,怎么接?看了430的数据手册,怎么都对不上号。最后在一个QQ群里遇到一个大神,给我大致讲了原理,并指导我怎么接。尝试了大概一周时间,把程序顺利下载到了芯片中。这个时候,我已经能够轻松修改进样时间和排放时间了。与此同时,由于程序太过混乱,我开始整理代码,在保证运行正确且功能不变的情况下,将代码模块化方便调用,减少重复。

  这款仪器开发有些年头,老板特此成立了拥有生产资质的公司,然后开始申请CMC,也就是生产制造许可证。根据要求,需要有三台仪器送检。我带着师弟装好了三台,开始调试。然而测量结果总是很差,无法达到送检的要求。问题出在一个步进电机上,而它正是整个仪器的核心。实在躲不过去,老板一句话:换!他请来另外一个工程师,帮忙修改电路,剩下程序上的事情交给我。这个工程师非常nice,我有什么不懂的,他会很耐心很详细的向我讲解。他修改完电路,告诉我每个引脚需要输出什么信号,怎么给信号。我按照他的意图在程序上一步一步实现。这是我第一次编程去实现实际中的一个功能。第一步是写代码让电机转动起来,然后控制转动速度。第二步是写代码控制转动的方向。第三步,计算每步的转角,为符合仪器的运作计算出特定步数,为了计算这个步数,还特意编写了一段小程序。快两个月的时间,我找见了最佳参数,仪器测量结果也很让人满意。编程并不是我唯一的工作。电机的安装接线都由我来做。于是,我学会了使用电钻电焊,认识了各类开关电源各种电压输出。这些不是兴趣所致,而是非做不可,不然,怎么去验证我的程序是否正确可行。

  产品的开发本身就是一个完善的过程。我们的仪器也不例外,通过各种试验验证,里面需要有很多要修改的地方。老板觉得最需要修改的是仪器的操作界面。他亲自操刀,以他多年的工作经验和水质分析仪器的一般操作思路画好了整个操作菜单体系,交给我说,以后仪器就按这个操作菜单来,你能实现吗?我看了下,这无异于把整个程序的结构颠覆了。我答应试试。如果之前的修改是小试牛刀的话,那么现在就是大动干戈了。首先要解决的是显示问题。显示屏上显示字符原本是一个很基础的东西。我一直没有去接触,现在必须得学了。通过对一些数据手册的理解,加上原程序的实例,很容易就上手了,当然还有一些问题,但是时间紧迫,只要能达到我的使用要求就足够了。其实这一路走来,基本都是这么一个状态。很多东西虽然都用上了,却只是略知一点皮毛。而我的个性是既然学了就要学好点,有那么一段时间为这个事情纠结。我很想把每个遇到的新事物连它的祖宗都搞明白,总是时间不够。慢慢的,也就习惯了这种状态,需要用了就去学,用上了就够了。在我毕业的时候,整个程序也都改完了。这个时候,它不再是别人的代码,而是我自己的。我再没有看过优秀的代码,只是凭借着for,if,switch等基本语句运转了近万行代码。有可能效率不高,还是那句话,能用上就好。所以即使到现在,编程的基础还是很薄弱。

  下位机告一段落,上位机软件紧随着开始了。现在实验室都习惯用一台电脑去控制仪器进行操作,这个功能我们的仪器自然也不会少。先前传下来的VB程序,我已经断断续续看了一些。看VB比较容易些,因为可视化,比较直观。这个年代,VB6.0显得老古董了些,但是,能用就好,能用就好。编VB这套程序的前辈肯定没有学过美学或者设计,因为界面实在是又难看又凌乱。和下位机一样,在有所保留的情况下,我对界面重新进行了规划设计。我也没有什么设计功底,只能以整齐简洁的原则进行。VB使用起来非常方便,代码也不分大小写,编辑速度很快。唯一的缺点是凌乱,控件太多,每个控件有自己的属性、方法和事件,凭空去掌握每个控件基本是不大现实。我决定边改边学,需要什么控件就学什么控件。这段时间,度娘是我最好的老师,MSDN也帮了我很大的忙。我想实现某种功能,先在百度里搜什么控件能够实现这项功能,然后查看这个控件的使用案例或者直接在MSDN里查找用法。刚开始特别费劲,后来慢慢习惯了,有的控件直接把使用案例的代码复制过来稍加修改即可被我所用。有的时候度娘会很不给力,很难找见我想要的答案,但是我还是很感谢她,毕竟,她能帮我的也只能到这里了。

  整个软件界面修改完后,接下来开始实现上位机和下位机的通信。这就需要非常重要的通信协议,最开始对这个概念非常模糊,脑子里一直形不成概念。现在倒可以很形象的打个比方出来。A想在QQ上和B聊天,发过去“在吗”,如果B不在线,那么聊天就不会继续,就是通信失败。当然还有一种情况是B看到这条消息但是没有回复A,通信是成功的,但是A不会知道。如果B回复了,那么聊天就开始了,也就是通信成功。最后一种是比较合理的通信方式。我自己定义了所有协议,并分别在上位机和下位机编写了反馈程序。还是那样,不知道这样的协议规不规范,反正最后是能用了。程序编好了,在电脑和仪器上实际测试的时候会有很多问题,经常有的就是B收到消息却不回复导致的误解。我们的开发进程如一列疾驰的高铁,一旦能用就进行下一个问题的研究,没时间去细究规范。

  为了和其他厂家竞争,仪器还需要进样器,老板负责找人设计加工进样器,我负责控制程序的编写,两周之后,进样器出来了。随之我们也卖出了第一台自己产的仪器。老板终于盼到到了这一天的到来,他等这一天等的太久。之前都是在投入,零产出。然而,事情并没有这么简单。用户提了很多要求,必须满足他们的要求,不然就不签收。仪器打回重改,而且经过验证,把老板打算申请的专利给推翻了,一切重来......

  重新讨论确定了方案,却又暴露出另外一个问题,芯片上引脚不够了,无法再增加其他部件。这一度让我们觉得无望。后来得到别人的指点,说有一种译码器,可以扩展引脚。我才想起了初学单片机那会儿有一节讲的是I/O口的扩展,我不知道有什么用,完全没有放在心上。再一次证明,平白无故去学一样东西,效果远远比不上当你知道要干什么用的时候。译码器这类玩意儿其实属于数字电路一块,我没有任何电子电路基础,自然也不会知道有这样的神器存在。可笑的是,在我研二那会儿,有过补习电子电路的打算,也去图书馆借了书,但是怎么都看不进去,没有学下去。知道了译码器的用处,我紧接着特别想知道它的原理,这个正是学习数电的突破口。可惜现在对于新确定的设计方案所需的程序尚未完工,没有时间腾出来学习这些。新程序大体已经完成,剩下检测工作。大家都觉得这是最后的大决战,完成这一步,仪器基本就成熟了,不会再有大的改动。可是谁又能知道接下来会有什么问题呢......

  写这篇日志原本是突然兴起,很想写点东西,结果越写越多,一发不可收拾。为什么有这么多东西要写,因为心里有那么一丝自豪,一路上太多的成就感,感觉自我价值得到了充分体现。难怪经常有程序员写点类似于传记的东西,那是对自己价值的肯定以及获得诸多成就的自我满足感。而这,也许就是程序员的局限性,活在这样一个自我陶醉的状态中,不停遇到问题,想出解决方案,品尝一个个小突破带来的成就感,从而,再也无法自拔了。另外,在同事眼中,技术做得好的也是受人尊敬的,用户对技术也是拥护有加,而对销售经常是冷眼旁观。所有一切,使得小小的程序员滋生出大大的自我主义,忽视了生活中其他美好的事物,甚至一辈子过着精神大于物质的生活。解决问题那一刻的成就感,确实能够充实整个内心,然而,也就仅此而已了。这些在成功人士眼中,都如同过家家一般幼稚。唯一让我感到欣慰的是,我学会了一种学习的方法。对于一件新事物,我不会说“会”或者“不会”,我会说“试试看呗”。容易的时候很快就搞定了,难的时候要花很长很长时间,但最终都是能搞定的。这几年遇到了太多太多纠结难熬难搞定的事。但是,只要熬过去了,结果一般都不会很差。凡事都是一个过程,不管过程如何曲折如何难熬,只要你坚持并一直怀有信心,都会得到一个美好的结果。只是,有的过程很长,长到你无望乃至绝望,长到做完之后有太多的感触和收获;有的过程很短,短到让你觉得理所应当,短到做完这件事没什么感觉和想法。所以,过程还是长一点好,难熬无所谓,关键是有收获。

  接下去的路还长着呢,仅以此文做一个节点,不是结束,而是开始。

                                                         (写于2013.9.18)

posted @ 2017-07-09 10:36  seanbei  阅读(1708)  评论(7编辑  收藏  举报