原文链接 http://yunli.blog.51cto.com/831344/1049286 在我的博客空间内,不时会有在校学生就职业发展和学习方面的内容向我寻求帮助。同学们由于初入社会没有行业经验,加上在校所学内容又广(但不深),所以在择业方面很容易产生困惑。在择业观上,他们希望找到一个将来有前途的行业,也希望在“是选择大公司还是小公司”这类问题上有人给予参考意见,也有人担心自己的学历对将来职业发展的影响。
另外,在我的工作中,也不时会有同事就自己的职业发展与我探讨。他们几乎都是对技术很有追求的“有为青年”和已经走上技术管理岗位的负责人。与在校学生的困惑有所不同的是,这些人已经选择了通讯行业,也有了好几年的工作经验,但却苦于在工作中很难发挥自己的特长和精进技术,或在技术管理岗位上担忧自己将来的竞争力。此外,也有些同事对将来是走技术线还是管理线充满着困惑。 对于所有的这些迷茫也好,困惑也好,我想借这篇文章谈一谈自己的看法。但怎么谈呢?这类话题可以说是老得不能再老了,但又新得不能再新— 因为每一个人都具有自己的独特性,在离开学校之前或参加工作之后又有着自己特有的经历和感悟,因而所面临的问题也会别具一格。时至今日的职场生涯中,每当我与同事分享自己的成长经历,总会有人为之振奋(希望你读这篇文章时也能感受到),或许以我的成长经历作为本文的写作主线是一个不错的选择!通过这篇文章,你可以看到一个1997年毕业的大专生(毕业于南昌水利水电高等专科学校,现更名为南昌工程学院)、一个在高二时英语还只考29分的人,是如何一步一步成为Motorola的软件架构师。 在继续读下去之前,读者应认识到一点:个人观点的独特性与自身的成长经历有很大的关系。因此,千万不要盲从,而应时刻保持一种批判接受的态度。或者说,你得有自己的观点,你(也只有你自己)得对自己的职业发展负责!另外,文章主线是自传形式,如果你对我的成长经历不感兴趣,可以快速地略读,只关注文中加粗的部分。 故事的开始得从大学以前开始。从小受“学好数理化,走遍天下都不怕”观念的影响,我认为只要学好数理化就行了,所以偏科很严重,高二时英语还考过29分。那时也不爱读书,高三时,别的同学在复习,我却在看《晶体管技术》这类电子技术书。这种状态,直接的结果就是第一次高考落榜了。 落榜的那个暑假,父母为我的出路没少操心。在一天早晨刷牙时,当我妈对我说希望我去复读时,我当时脑海里想“能象表哥那样考上大学那该多好啊!”,在这个念头驱使下,我答应了去复读。从那天开始,我顿悟了,真正知道自己要什么了。在复读的一年里,我学到的一种重要能力是— 自学,这为以后大学乃至职场学习打下了很好的基础。正因如此,我想给出我的职场第一感悟:自学能力是竞争力之本。 经过复读,高考总成绩提高了100多分,但也只够专科线。最终,我被南昌水利水高等专科学校录取,专业是“供用电技术”。这个专业相信很多人不知其然,其实就是电力自动化的变种专业,其专业内容主要是电站、发电厂高电压的继电保护技术。 大学读书期间,我开始有与人在成绩上一争高下的念头了,加上复读一年所获得的自学能力,以及自己的努力,学习相当轻松,尤其是只要与电子技术沾边的课程,都能轻松地拔得头魁。三年共六个学期的学习,我拿了五个一等奖学金,一个二等奖学金。毕业时,我是系里唯一的一名优秀毕业生。期间通过了大学英语四级考试和计算机二级考试,获得了江西省电子技能比赛一等奖。需要提及的是,在大学期间所学的与计算机相关的课程只有:《电子技术基础》、《计算机组成原理》、《计算机软件基础》、《单片机技术》和《Basic编程语言》。 在大学期间,我完成了人生很重要的一件事 — 找好了现在的妻子。由于她是浙江人,所以毕业时工作地点毫不犹豫地选择了杭州。那时很多同学的工作还是包分配的,而我来到了杭州的人才市场进行双向选择,那时找一份工作还是相对轻松的(注:我们大学录取那年的招生人数是90多万),投出一份简历就找好了工作。第一个工作单位是一家不到100人、地处杭州花港观鱼对面(三台山)的电力设备制造民企。 尽管选择去这家民企后立马到公司去做了实地调查,但由于没有社会经验,加上被问的人没如实反应,所以进入这家民企后所了解的情况让人大跌眼镜。另外也了解到单位会通过一些不入流的做法控制我们的户口,不让我们跳槽(那会儿的户口还是相当重要的,结婚要户口证明,有同事就因为户口被控制而登记不了)。而我们在进入这家单位时签订了六年的劳动合同。在这样的小企业干上六年意味着什么?!当时与家人打电话告知这一状况时,我都哭出来了(就在现在杨公堤与虎跑路交叉的、现早已不存在的一个电话亭里,记忆犹新呀!)。尽管前途是那样的渺茫,但带有“优秀毕业生光环”的我仍坚信自己能做得比别人更好,因为有我的职场第二感悟:自信能让你与众不同,尽管有时的自信有点莫名其妙。 在这个企业一开始的工作职责是电站设备的电气设计工程师,需要用AutoCAD(到单位后学的)设计电气图纸,并指导工人最终完成电气设备装配及调试。期间,企业经营范围扩大,需要从事电子设备的生产,因此我开始有机会接触电子技术方面的设计工作。在兄弟单位一同事的帮助下,在一个星期内我掌握了如何用Tango(后来更名为Protel,现在的名称是Altium Designer)进行原理图和PCB线路板设计。而且,这一个星期的设计结果最终成为了电气产品的一个部件。对于一个毕业不到一年的我来说,这是不小的进步。那时知道了什么是网络表、过孔、焊盘等,掌握了很多电子原件的工作原理(有的还自己用面包板做实验),明白了做电路板的大致业务流程,还能动手焊接电路板,熟练运用示波器和万用表进行调试。那段时间,我对电子技术的兴趣帮上了大忙,学习起来远比别人快。当我精通电路原理,能自如运用示波器和万用表调试电子产品时,别人却还不明白我的调试动机。我的职场第三感悟:兴趣是学习效率的催化剂,培养自己的职业兴趣。 第一次真正对编程感兴趣是从知道PLC(Programming Logic Controller)开始的。当时的电站设备采用了三菱的PLC,为了配合这一电气产品的需要,企业社招了一名懂PLC编程的工程师。由于老板担心我们相互学技术而“翅膀变硬”,所以明确提出工程师所掌握的技能不能互通有无。当时看到这位兄弟能通过“梯形图”改变PLC的行为,真是觉得他太神气了,仰慕不已。后来通过这位兄弟的私下帮助(哥们呀!),我晚上偷偷地在厂房里面学习PLC编程。为了获得良好的学习效果,我设定了对电气产品的PLC程序进行重写的目标,且最终达成了这一目标(当然,由于这个目标不能让老板知道,所以我的PLC程序不能用于商用)。我的职场第四感悟:学习应给自己设置虚拟的项目目标,以做项目的形式提升学习效果,只有这样学到的内容才会深入而实用,切忌无目标地学到哪算哪。 一年多的功夫,我成为了某电气产品的技术负责人,对整个产品的所有技术细节都了如指掌,我带领了其他几个工程师实现了该产品的“自主研发”。有趣的一件事是,老板当时并不知道我已经“翅膀硬了”,想抵赖答应过的8000元项目奖金,年轻气盛的我在与之拍完桌子之后对其他工程师下令:“没有我的允许,谁也不能将电气图纸和电路原理图用于生产”(因为年经,所以二!)。对抗的结果以老板兑现承诺而告终。这时我隐约地有了我的职场第五感悟:话语权首先来自能力,而不是职位权力(公务员、国字号、垄断企业的工程师请忽略。你懂的!)。 我那时还学会了CRC算法并将之运用于PLC的串口通讯中,但对于计算机如何通过串口与PLC通讯获得采集数据存在很大的好奇心。于是想到了学习编程语言,并计划做一个能在计算机上实时显示PLC所采集数据的软件。在向PLC编程的兄弟表达了这一想法后,他给我的建议是:学习C语言比较难,Basic语言则更容易。于是,我毫不犹豫地选择了自学C语言,因为我深信我的职场第六感悟:难学的技能一旦掌握更具竞争优势。 也正是从那时开始,我真正开始了成为软件工程师的自学旅程。那时比较幸运的是,单位专为我配备了工作电脑,所以具备了自学的硬件条件。由于那时Internet还不普及,学习书籍都来自浙江大学的科海书店(后来眼见着它的店面越来越小,这也是进入电子商务时代的一个缩影),那时隔三叉五地到科海去找书,生活最大的花费就在于购书(那时这方面的书不少是质次价高)。当然,学习的过程或多或少还得瞒着老板。那段时间,别人午休我就编程,除了看书和做书后的习题,还一直朝实现自己的计算机监控软件这个目标迈进(参见我的职场第四感悟)。终于有一天,我用Turbo C在DOS环境下实现了具有串口通讯功能的、基于图形界面的监控软件(如果你用现在的眼光看那个软件,一定会说“很土”)。当我乐此不疲地向他人演示时,你可以想象我那时有多高兴和自豪!这种小小的成功助长了我的信心,也让我感受到了我的职场第七感悟:用阶段性成果不断增强自己的自信,且最终支持自信的是能力,而不是自大。尝到了成功甜头的我随后拓展了自己就软件开发方面的学习内容。那时的我已经下定决心要向软件开发方向发展,这种选择是因为我的职场第八感悟:做自己喜欢的事,如果那是自己的兴趣最好。 1999年的某月,在企业拖欠了一个月工资的情形下,“蓄谋”逃离企业束缚的我们(共19个工程师)经过几个月的劳动仲裁后,与企业解除了劳动合同。在离开这家民企的第二天,1999年11月的某天,我在浙江大立机电技术开发公司(即现在的大立科技。后面都简称为大立公司)找到了第一份专职的软件开发工作。我逃离束缚后能很快地找到新的支点,完全得感谢我的职场第九感悟:不论身处多么困难的环境,即使觉得前途渺茫,也不要放弃学习,否则就是“自断筋脉”。 在大立公司所参与的第一个软件项目,是使用Visual C++从事Windows某变电站图像监控桌面软件的开发。尽管我之前自学过C++语言,但那时并未完全掌握面向对象编程,尤其是其中的多态。我在该桌面软件中借鉴微软的示例软件DrawCli,独立地实现了电子地图功能。正是通过掌握这个示例软件的设计与实现,我真正领悟到了面向对象设计的好处。也通过该图像监控桌面软件的开发经历,掌握了Windows VxD驱动开发、socket通讯、多线程编程、图像处理(锐化、伪彩处理、图像字符识别和图像对比等)、ODBC数据库编程(用的是SQL Server)等。 这里要插一个与我妻子相关的小故事。她是我大学的同班同学,毕业以后进了诸暨供电局从事农网预算工作。我在第一家民企工作时,时常往返于两地,有时觉得很是辛苦。另外,妻子在供电局安逸的工作环境下,时常会开玩笑说老了要是下岗了都不知能干什么。在我进入大立公司不到一年的时间里,我向公司提出了可否让她到公司来从事软件开发工作。当时在我妻子没有任何面试和编程经验(她当时只自学了谭浩强老师的《C程序设计》和一本C++的书,忘记书名了)的情况下,公司让她过来了,我想这是缘于公司对我的器重(这里要谢谢庞总和章总两位老总!)。自然,我成了妻子学习编程的老师。我的岳父岳母当时对于妻子放弃供电局的工作尽管不舍,但还是尊重了我们的想法,谢谢他们的开明。支持我们做出这一决定,除了为了解决两地分居问题,还有我们的职场第十感悟:长期安逸的工作意味着将来更大的风险。 在妻子进入大立公司不久,由我担纲了新版图像监控软件的重新开发,这是我第一次担任软件项目负责人。在这个项目上,我可以从技术层面尽情发挥,将我在老版本软件上所看到的设计不足完全克服。也正是通过这个软件项目,我的面向对象编程能力有了很大的提高,而且完整地做过了一个软件产品。用我现在的眼光来看:那时的开发工作除了引入了版本控制软件外,是不折不扣的作坊式软件开发;至于管理技能的提高,也可以说是微乎其微。 2000年底,大立公司因为业务拓展的需要,需开发嵌入式图像监控系统(系统中的前端产品是后来数字硬盘录象机的前身)。为此,公司社招了一位比我年长十岁的资深硬件开发工程师,他在进公司时已经有基于AMD的Elan SC520 x86嵌入式微控制器的硬件开发经验。他在进公司之初与章总交谈时指出:“做这类嵌入式产品,需要软件功底非常强的人”,章总的回答是:“你放心好了,我一定找一个最好的人与你搭档”(章总后来告诉我的)。是的,所找的那个人就是我!而其实那时我只有用Visual C++从事Windows桌面软件的开发经验,可见公司领导对我能力之信任!我的职场第十一感悟:机遇很重要,但你得有能力才能抓住它。 我当时所面临的技术挑战,读者可以想象。要知道,在2000年时基于x86微控制器的嵌入式系统的开发人员国内还很少。我的自学能力、电子爱好的兴趣在这种挑战面前又帮了大忙。其实,做嵌入式系统开发最主要的是参考各种资料以便掌握各类技术细节,这得通过大量地阅读芯片手册、用户手册,以及研究AMD在其官网上所提供的示例程序。在这个过程中,就技术困惑坚持探究和养成各种好的工作习惯(思考习惯、笔记习惯、总结习惯、阅读习惯)非常重要。我的职场第十二感悟:职场首先比拼的不是智商,而是坚持与好习惯。 我独自完成了该嵌入式前端产品上的软件开发工作。其中包含的大致技术内容有:从编程的角度精通x86处理器架构; PCI、IDE硬盘、网卡、串口、闪存等总线或外设的驱动;实时操作系统内核的移植工作;MINUX操作系统的文件系统的移植; XINU操作系统的TCP/IP协议栈的移植工作。移植工作往往会碰到各种技术细节问题,等移植工作完成,对被移植模块的实现和背后的原理也已了如指掌。正应如此,这一时期的工作让我对操作系统的实现原理有了很深的理解。 除了软件方面的进步,我在大立公司时的硬件知识也得到了很强扩充。不仅能轻松地阅读数字电路原理图,还自学了VHDL语言,使得拿到逻辑器件CPLD的VHDL程序就能调试软件(通过VHDL程序,可以了解编程所需的译码端口、相关信号的操作时序等)。还学会了如何使用逻辑分析仪辅助软件调试工作。前面提到的这位兄长式硬件工程师调侃我说:“你让我看到了中国软件的希望!”,而我将这话当成了对自己的鼓励。另外,这期间还考入了浙江大学专升本的通讯工程专业,给自己充电(2001年入学,2004年毕业,获多学期“优秀学生”和“优秀毕业设计”)。 由于大立公司是浙江省测试技术研究所的子公司,它或多或少带有事业单位的气息。加上公司的技术舞台有限,以及妻子也在同一家公司工作,我于2003年4月份左右离开了大立公司。在我离开之前,浙江省科委已批复了公司的申请,分配给我一套福利房。在我离开之时,房子仍在建,不少同事对于我的离职很是不解,也劝我拿到房再走。但我有我的职场第十三感悟:当短期利益与长远利益无法得兼时,选择长远利益。 在大立公司工作期间,很希望自己能入职UTStarcom这样的通讯企业(那时的UTStarcom是多么地辉煌!)。计划离开大立公司之际,我向UTStarcom提交了求职简历。这次求职开始好像很顺利,但到我真正入职UTStarcom的过程却很是曲折。 一开始当我收到UTStartcom的面试通知时,可能太希望能进入这个公司了,在没有很深入了解这个岗位的前提下,就去面试了,且马上拿到了Offer。但后来才了解到,我拿到的是生产部测试开发岗位,与实际研发部门是有区别的。 当时很纠结 — 这是我想进的公司,但却不是我想要的岗位。如果拒绝生产部的Offer,我很有可能与UTStarcom无缘。考虑再三,我还是选择了拒绝(参见我的职场第十三感悟)。并重新向研发部门投了简历。 经过度日如年的一个多月等待(那会儿刚好发生了SARS疫情),在觉得入职UTStarcom研发部门无望的情况下,我入职了另外一家小公司。令人意外的是,在入职那家公司的第二天,我收到了UTStarcom研发部门的面试通知。在HR面试的那一轮中,HR对我说,“你是我所面试的人中最有工作激情的”。那时的技术面试官中,其中一位是我日后入职后的上司 — 夏青(现在是恒生电子通讯事业部的总经理),他是我的伯乐。由于我的学历问题,在技术面试通过后,别人只要一位VP面试通过就行,我却需要两位。我的职场第十四感悟:学历是很重要的敲门砖,即便你的能力很强学历尽管很重要,但能力才是最终的通行证。 2003年6月份左右,我正式入职UTStarcom研发部,从事小灵通基站控制器(后面简称为基站控制器)的软件开发工作,也从此踏入通讯行业。在入职之初,由于自认为对于操作系统的原理很精通,又完整地做过软件项目,有点飘飘然,觉得自己是个“小牛牛”。然而,入职后一接触工作就发现,内容没有想象的那么简单! 首先,基站控制器的软件规模比我以前主导开发的项目要大很多,而且需要熟悉通讯行业的相关信令。其次,尽管我那时精通x86处理器,基站控制器用的却是PowerPC 8250,这意味着我得重新掌握它。再次,实时操作系统用的是前美国军方的、开源的RTEMS,那是我第一次接触。最后,UTStarcom的工作语言是英语,写文档和邮件都得用英语。尽管我那时能无障碍地阅读MSDN和各类芯片手册,但要着手写,却是一大挑战(口语不作要求,因为不需直接接触老外)。 一入职所分配的工作是网元网管部分告警抑制软件模块的开发。尽管PowerPC处理器和RTEMS操作系统技术细节的掌握与否并不影响日常开发工作,但我仍将掌握它们作为自己的努力目标,因为我的职场第十五感悟:技术细节掌握得越深,解决问题时就越能游刃有余。 那时工作时间应付日常开发工作,业余时间则先将精力集中放在熟读PowerPC 8250处理器相关的技术手册上(晚上还得上夜大)。加起来超过2000页的英文资料,我读了不少于3遍。随着时间的推移,当我对PowerPC 8250处理器很有感觉之后,我将工作重点转移到了熟悉RTEMS操作系统的实现细节上。先处理器后操作系统的学习安排,是基于我以往在x86处理器上的工作经验而得出的,也是因为我的职场第十六感悟:技能的发展应采取深度先于广度且交替进行的方式,只有这样,面对大量的新知识才能更淡定。 RTEMS是一个类UNIX的实时操作系统,也正因为接触这个操作系统我才意识到了自己在软件设计能力上存在很大的提升空间。尽管我对操作系统的实现原理胸有成竹,但却无力于构建一个象RTEMS那样优雅的操作系统,也真切地体会到了RTEMS的设计之美。那时基站控制器上运行的RTEMS操作系统是由美国的新泽西研发中心移植好的,杭州研发中心只需在之上做应用开发。为了就RTEMS操作系统获得更好的学习效果,我又一次运用了我的职场第四感悟,设定了自己完成RTEMS新版本移植这一目标。 RTEMS新版本的移植工作虽不在公司的日常工作范围内,但却得到了上司的支持。由于那时RTEMS还在开发新的功能,并不是很稳定,在移植过程中碰到各种奇怪的问题,有些问题还与GNU的binutils工具集有关(binutils中包括nm、ld、objdump等工具。RTEMS是用GCC编译的)。在无法确认是GNU工具集的问题之前,我甚至还向Wind River公司(其知名产品是VxWorks实时操作系统)寻求过帮助,因为那时用的是它的JTAG仿真器。移植工作虽曲折,但最终还是成功了(我所移植的版本并没有运用到产品中,后来的同事又做过了RTEMS4.6.0pre4的移植,且运用于产品中)。这一移植经历,让我对GNU的binutils、RTEMS操作系统的实现有了更为深入地掌握。 在UTStarcom工作的前期,我大多从事的是RTEMS操作系统相关的代码维护工作,工作内容除了OS内核,还包括FTP、Telnet等协议。直到中期转为做E-Box产品的互联网接入模块的开发工作。 E-Box是一个企业级电话交换产品,其中还存在一块基于ADSL的互联网接入数据板(与现在的ADSL猫功能一样),用于实现企业网对互联网的数据接入功能,这一数据板使用的是VxWorks5.5.0实时操作系统(PNE 2.0),处理器是Intel的XScale IXP425。那时VxWorks的IP协议栈还是基于BSD的,但Wind River对之做了一定增强。这段时期我的工作重点全在IP协议栈上(《TCP/IP详解》这套书帮上了大忙)。这一时期的开发经历,让我对PNE的Bridge、FastPath、MUX、PPPoE协议、Radix路由算法和VLAN协议很熟悉,也学会了用SmartBit仪器和Chariot软件做网络性能测试。总之,让我对IP(v4)协议栈方面的知识和软件实现有了长足的进步。 E-Box产品数据板上的开发工作进行了半年后,管理层决定放弃,于是我被调到了E-Box产品的软件平台组。那时平台组刚好面临一个比较麻烦的问题 — 在命令行上运行reboot命令后,有时会出现整个系统挂起,而不是期望的重启。平台组的同事花了一个多星期的时间仍没有解决这一问题。 进入平台组之际,同样是在没有任何人安排的情况下,我自己主动承担解决reboot命令功能异常的工作。在我的职业生涯中,我一直热衷于去解决别人难以解决的技术问题,因为我的职场第十七感悟:越难的技术问题,其所蕴藏的知识越丰富,也越具学习价值。 经过一天半的时间,问题被解决了。其根源在于,reboot之前没有禁用CPM协处理器。我能那么快地解决这一问题,完全是因为之前熟读过PowerPC 8250处理器的资料。 我在UTStarcom工作的后期,致力于ACE在E-Box产品中的一些应用,借助ACE的网络通信功能帮助实现在Windows平台上通过Visual Studio调试E-Box产品。我在《专业嵌入式软件开发》一书的《可开发性设计,一种高效且经济的开发模式》一章中所阐述的内容其实就是这一工作经历的总结与延伸。 另外,我还在E-Box产品上做过难度比较大的一个特性是,利用PowerPC 8250的MMU功能在VxWorks操作系统上实现了对任务栈的保护 — 当一个任务被调度而处于运行状态时,它的栈就处于可读写状态,而其他任务的栈全处于只读状态(VxWorks5.5.0内核中,还没有RealTime Process的概念,这一概念是从6.0开始有的,所以那时我所做的这一特性很具实用性)。通过这一特性,可以有效地防止任务栈被意外篡改(比如野指针操作),即便出现篡改也能尽早发现根源。这个功能的实现过程需要调试VxWorks内核,那时VxWorks的源码虽对公司提供,但Wind River公司对所提供的GNU的binutils做了特殊处理,使得无法为内核代码生成调试所需的信息,结果是无法对内核进行源码级程序调试。由于我之前的RTEMS操作系统移植经历让我对binutils非常熟悉,通过使用一定的方法(说来话长了)绕过了Wind River公司所设置的障碍,成功地实现了对VxWorks的源码级程序调试。 在职场中,我不时能成功解决复杂问题和克服技术障碍。我的职场第十八感悟:每次积累的点滴知识,一定会在将来不知不觉地发挥效能。 2006年4月份左右,我离开了UTStarcom。在UTStarcom所学到的,不只是前面所介绍的那些技术知识,更让我知道了软件开发的“正规军”是怎样的,与小公司相比,UTStarcom的软件开发流程要正规得多;也经历了英文写作的“挤牙膏”时期过渡到轻松时期(好友周海东在我的英语学习中帮了不少忙);看到了好友于善成如何通过大量阅读成为一个知识渊博的人(他的阅读量现在仍是我的学习榜样);还有上司夏青的技术敏感度到现在仍让我为之称道,是我职场至今所见过的二位具有良好技术敏感度的技术管理者之一(另一位是我在Motorola工作期间认识的,后面会谈到他);团队实力之强使得开发出的E-Box产品在我离开UTStarcom后不时能听到正面的评价。 对了,我在大立公司工作时期,就很注重软件设计文档的编写,而且在我离开之时,不仅完善了所有文档,还为后继同事做了全面的培训。我始终坚守我的职场第十九感悟:通过文档化的方式传承知识给后继者是你的基本责任,因为你作为后继者时也希望如此,这也是对自己负责的一种表现(文档的重要性请参见《该死的“代码就是文档”》一文)。 在UTStarcom工作期间,我进一步形成了将自己的技术想法写成文章与大家分享的习惯(那时同事贺旭东称我为“作家”,而我则称他为“点评家”),也因为自己在嵌入式软件开发技术上的长期点滴积累,开始有了写书的想法。