【IT人生】写给今天的初学者,明天的领航人

写给今天的初学者,明天的领航人

唐洁

2012 是个极特殊的年份, 玛雅历新纪元的开始, 祖国的改革开放进入全新历史时期, 科学发展观正式写入党章。 党的十八大报告就明确指出, 坚持走中国特色新型工业化、 信息化、城镇化、 农业现代化道路, 推动信息化和工业化深度融合。 加快推进国防和军队现代化, 加紧完成机械化和信息化建设双重历史任务, 力争到 2020 年基本实现机械化, 信息化建设取得重大进展。 坚定不移把信息化作为军队现代化建设发展方向, 推动信息化建设加速发展。 这一切的一切都是那么令人振奋, 我虽然从事软件研发 12 年了, 从一线编程一直走到架构师及今天的管理人员, 虽说积累了一些经验, 也取得了研发专家头衔,但自我感觉还是很惭愧, 远没有达到心中的预期水平。 我不能算是什么编程专家, 只能说积累了一些从业经验而已, 从几个方面谈谈我这十几年编程生涯的一些感悟。

1 树立正确的观念, 合理选择专业

从高考结束迈进大学校门开始,我们今后职业生涯的方向将逐步开始规划,无论当初你怎样想,你所填报的专业就是选择的起点。我们国家的高等教育越来越普及,每年的就业形势也不容乐观,理工类相关专业从事软件研发的较多,我身边的大多数学生选择这个专业方向主要是考虑以后好就业,不管喜欢不喜欢,反正跟着潮流走不会错。在这里我要特别提醒大家,专业选择是人生转折点,中国有句古语: “男怕入错行,女怕嫁错郎”。 学生的确应该冷静地分析自己的各科水平和能力, 从兴趣爱好和价值观出发, 要想清楚两个问题: 一是所填报的专业和自己喜欢从事的职业是否一致? 二是个人的理想与自身的学习能力是否一致? 一个人只有干他愿意干的、 认为有价值的、 能力比较擅长的, 以及个性禀赋适合的工作, 才能更好地发挥潜能。 我身边有一个现实的例子, 就是我的一位同学, 原来高中时他成绩非常好, 基本是年级前三, 但高考填志愿时只是按照老师的要求填报了一所重点大学的生物专业,多年后, 据他自己说的确当年没有综合考虑自己的意愿和兴趣爱好, 他根本就不喜欢生物, 虽然他阶梯式地读到了博士, 但最终他还是完全放弃了他的专业考到一个政府事业单位当了个完全与专业不相干的科干。最近遇到他, 问起他的专业, 他竟然做抓狂状说不要和他提生物, 这位同学且不论他个人发展如何, 这对于国家的教育资源就是一种浪费, 培养一个学科博士国家需要投入多少人力物力, 结果呢? 在这里写这些话就是要强调选择专业是人生重要的转折点, 要根据自己的具体情况具体分析, 大胆而又慎重地填写好每一个专业的选择, 用谨慎的态度和科学的方法真正做到从自身的情况出发, 既然你选择了软件研发行业, 就要喜爱它, 尊重它, 用心去对待它, 才能信心百倍地迎接明天, 在这个领域有长足的进步。

2 打下扎实基础, 做好知识储备

本科阶段课程的学习是一切行业的基础,在软件研发行业尤为重要。最重要的两门基础课程就是数学和英语,业界有句话 “数学水平决定你能走多远, 英语水平决定你能走多快”,现在我是深有体会。 李开复先生曾说过: “在全球范围内, 美国的研究水平无疑是先进的。 而除了美国之外, 你会发现英国的研究水平也是相当突出的。 究其原因, 其实就是语言问题。英国人可以毫无阻碍地阅读美国乃至全球各种最新的英文研究报告和资料。这对于他们把握研究方向,跟踪最新进展, 发表研究成果都有很大的帮助”。 因此, 英语学习对于我们做研发的人来说是相当重要的。 只有加强这方面素质的培养, 才能适应将来的发展。 从业多年的朋友都知道英文原版教材更新速度远快于国内教程, 且很多经翻译过的资料会失去原来精辟的讲解内涵, 如果你英文水平足以阅读原版教材的话, 会比别人进步快很多。 工科专业必修的几门数学课程: 高等数学、 高等代数、 概率论与数理统计、 解析几何、 计算方法、 离散数学、 初等数论等等必须是全部熟练掌握, 最好精通 (如果你想以后达到较高的设计层次); 英语与数学的学习可能会伴随你全部的职业生涯, 很多在校学生对于这两类课程不是很重视, 认为只是简单的基础了解, 这非常不好。 举个例子, 现在很热门的3D 类软件 (游戏, 绘图引擎等 ) 设计会用到大量的积分思想与高等代数中的线性变换概念, 而数据挖掘和预测决策分析类软件如果不懂数学分析与概率统计是根本没法做的,对于人工智能类软件的设计必须要求深入理解模糊数学理念。也许有朋友会说我是做数据库应用的,用不到什么高等数学类知识,很可惜你也错了,复杂库表结构组合的设计的合理与否完全要靠你对拓扑代数以及离散数学的理解程度,不要以为会几个 SQL函数,会用 IDE 环境做出几个操作 Oracle, DB2 的应用就是会数据库开发了,这个仅仅是皮毛功夫而已,不理解数学概念的深层次应用,永远只能停留在初级水平,而且走不远的。 举一个例子, 一家国内比较大的公司设计, 他们核心团队的研发经理对于数学知识的运用不是很好, 典型的数据库类软件J2EE+WEBLOGIC+ORACLE 的 B/S 架构, 由于系统庞大 , 后端库表逻辑设计不合理, 造成很多缺陷, 最致命的是整体库结构与前端 code 不能分离, 导致一个服务端口只能对应一个年度的库结构, 做年终结转与年度初始化时痛苦万分。 请多位专家综合分析之后, 分析结果是核心架构必须推翻, 80%的代码都要重构,我曾经寻问那个研发经理,做系统规划时考虑了代数拓扑的耦合度设计了吗?他一脸茫然, 由此可见数学知识的重要性。另外就是专业基础课的学习: 计算机组成、 操作系统原理、汇编语言、 数据结构、 编译原理、 数据库原理、 软件工程、 结构性设计语言 (Pascal、 C)、 面向对象设计语言 (C++、 C#)、 计算机网络等, 最好还深入学习一下算法分析、 分布式系统、 计算机图形学、 形式逻辑、 人工智能原理、 软件设计模式、 人机交互, 软件构架/框架等的课程。 在软件研发界, 新技术层出不穷, 但基本原理变化不大, 我从业十多年来, 越深入研究越体会到这些基础理论的重要性。 比如我正在做的数学分析与D3D 生物运动仿真引擎课题,就要用到大量的 3D 数学与专业基础理论,而且有些深层次没有理解透彻的概念还要回过头找这些资料学习参考。现在的大学普遍扩招,很多学生进入大学之后很茫然,对待课程学习也是纯应试目的,基本都是丢掉书本就忘了,很多教师在传授专业知识的时候也仅是浅尝辄止,不能形成知识的关联体系。计算机相关专业是实践性很强的学科,许多理论只看书是无法领会的,实践与理论必须相结合才行,这就需要我们自己做个有心人,现在的网络资源比十多年前要丰富多了,学习的时候可以多方面搜集相关资料,汇集理解, 另外 MIT 的公开课很好, 可以抽空看看, 有助于加深理解。 本科阶段的各项知识储备非常重要, 我见到过很多计算机专业课学的很好的, 但数学与英语基础不好, 没办法继续深入研究下去。 如果条件允许, 读研是有必要的,可以加深专业方向的学习, 提高职业素养与研究能力。 其实最理想的软件研发学习之路是本科学数学, 研究生读计算机相关专业, 读博时再考虑在某个感兴趣的领域发展。 如果有条件可以考虑一直深造下去, 等到各项理论水平都很扎实了, 再考虑投入工作。 我见过一些所谓写代码的程序员, 他们整天讨论自己掌握了多少编码技术, 什么 VB, Delphi, 数据库玩得多顺等, 其实他们忽略了软件研发最本质的东西, 以至于多年之后仍然进步不大。 现在有很多观点认为高等教育的重要性在下降, 软件研发是吃青春饭的等等,其实这是极端错误的, 在很多大公司的研究院里, 高层次的研发专家基本都在35 周岁向上, 而一些研究院的首席软件科学家基本都是数学专业毕业, 软件界的职业生涯有着典型的两类曲线。

这两幅图中 T 代表时间, P 代表专业水平,很明显第一幅图中起步发展很快,但到了某一点时开始转折,发展会变慢而后将停留在某一极限而无法超越。第二幅图起步虽然很慢,但到了某一阶段量变转化为质变开始飞跃,而后无限向高层次发展。这两幅图就是著名的人月神话第一版所述的内容,已成为很多行业职业生涯的描述。写在这里是告诉大家,基础课程学习与知识储备的重要性,千万不要浪费青春,追求所谓快速入门的短平快式的学习。说个很形象的例子:很多年轻人都喜欢看武侠小说,倚天屠龙记的张无忌为什么那么厉害,原因是他的内功基础非常扎实,学什么都很快, 临场发挥现学现卖, 超越了很多练了很多年的高手, 其实这些知识储备就是你从业的内功, 记得我从入门到运用Java 以及 J2EE 设计一款 B/S 架构的组合算法模拟机只花了 2 个月时间,而且黑白盒测试一次性通过,这些都得益于我较扎实的知识储备。

3 注重理论学习的同时, 选择合适的软件项目实践锻炼

无论你是在校学生,还是业界人士, 理论学习的同时, 配合实践锻炼是提升专业水平的必经之路。 计算机相关专业是实践性很强的学科, 所有的软件都是动手研发出来的。 没听说过只看书, 考试做题就能诞生软件专家。 有个现实的例子: 我以前有个同学很聪明, 理论学习非常好, 考试总是前几名, 但他有个毛病, 不喜欢静下心来动手搞研发, 后来硕士毕业进入了一家很大的跨国公司核心研究机构, 但由于总是不愿意动手,跟不上科研进度, 最终不得不转行做了学院派, 这是很可惜的。 软件界的学习是 40%的理论, 60%的实践, 当然盲目的实践是没有效果的。 现在各学校的教学资源都很好, 计算机专业的学生获得实践锻炼的机会比以前多很多, 找到一名理论与实践经验都很丰富的教授作为自己的第二老师是很有必要的,记得我后来就非常幸运地遇到了这样的导师,作为一名初学者可以尝试从普通的数据库类应用类软件开始动手,可以较为全面地接触一些数据库运用,网络通信及设计模式,编码规范等。特别要注意选择好自己使用的第一门开发语言工具,很多同学为了上手快喜欢用一些所谓的 RAD 类 IDE 环境,比如 Delphi,DOT NET 之类的, 这些其实不利于良好编码习惯的养成 , 最严格规范的语言就是 C/C++系列, 很多底层驱动与引擎都是基于 C/C++基础研发的, 一个真正的研发专家必定是一个 C/C++语言专家。 我当年独立设计的第一款 CMS 架构的物流仓储应用就是用C++平台开发的, 现在回想起来还是觉得很有益处。在校的学生尤其要注意理论学习与实践锻炼的同步。比如高等数学系列课程的学习可以结合 Matlab 的实验进行,有助于深入领会数学原理与算法学的基础。学习数据结构与算法分析学的时候有必要将教程的各个算法用语言逐个实现,对于汇编与计算机原理的学习可以尝试结合编写简单的显卡或声卡驱动去领会,操作系统的进程、线程池、 多并发等机制一定不要只停留在基本原理的理解, 动手做一个基础框架的内核模型会让你有很深的认识, 学习操作系统时可以结合Unix 设计原理与Windows 内核编程等书籍同步学习,会让你对一些很抽象的概念有具体形象的认识。编译原理的学习可以加深对编译机制与人工智能初步的理解,可以尝试编写基本的编译框架。在校期间如果有合适的项目研发可以抽空参加,理论与实践的同步进行可以快速提升对专业的理解。当然, 项目不是盲目去做的,各种类型的都应该尝试, 数据库应用类是比较基础与简单的算法设计类、 驱动程序、 内核引擎等等都应该有所接触, 对专业的各个领域应用都会有比较深的认识。 尤其是毕业设计非常重要, 一定要认真对待, 选题尽量选择某个领域有一定深度的课题, 我当年的本科毕业设计就是数据结构动态模拟课题, 以C++编码用计算机动画的方式将软件专业的 80 多个核心算法全部模拟出来,设计了一套一体化教学平台的软件,后来这款毕业设计软件被评为优秀设计并一直在学校作为教学案例保存。工作以后, 我一直坚持理论学习与实践相结合, 同时注意数学与英语学习的同步进行, 为了将研发领域不断深入, 后来进一步深造时利用空余时间历时 4 年系统学习了数学专业的全部课程,同时还在数学分析与概率统计及人工智能领域做了深入研究性学习,结合专业知识, 在 10 余年间大小做了 90 多个项目, 同时总结自己的实践经验写成各类论文并参加各类软件研发大赛, 一步步从一线程序员走到现在的带队架构师, 这都得益于不间断的理论学习与实践的相结合, 希望我的一点学习经历对大家能有所帮助。

4 从小工到专家, 在不断探索中积累渴望创造的激情, 完成职业生涯进阶

经历了以上几个阶段的努力,基本上算可以进入职业软件研发的门槛了,但要记住你只能算是一个 Coder 小工而已,至于能走多远还要看自己的努力,在这里有几点经验供大家参考:

(1)从编译原理的角度来理解工作中使用的高级语言。 如果做到这一点, 至少有两个好处: 第一个好处是避免一大堆低水平重复出现的编译错误。 一名优秀的 Coder 平均在一个工作日中应该完成200 行以上的源码,其编译错误应该控制在 5 个以下,要知道这 200 行源码不是一次完成的,所以大多数情况下你都要追求一次编译通过,而一名职业水准的程序员,应该进一步做到即使 purify 这类的工具来检查源码,也不会存在严重的内存泄露;第二个好处是可以提高源码的可读性和效率。规范地编写你的代码使你自己的逻辑清晰,因为你明白多加几个括号和空行、多换行对齐、多注释, 编译器是会自动识别的, 不影响程序执行的效率, 反过来, 控制好递归调用和循环内的 if 语句才是提高程序效率的关键, 要全力避免递归, 但要深刻理解递归, 能通过自己建立堆栈来把递归程序转换成非递归程序, 要求还是较高的。

(2)避免思维陷阱。 人都有自己的思维惯性, 这一定又会表现在你的程序逻辑中, 有时你就是从这个惯性中跳不出来(谁都有这个时候),但要心里有数才行, 所以你需要帮助 , 如果你有几个水平相若或更高的职业伙伴, 太好了, 当遇到花30 分钟还打不下的 bug 时 , 就别浪费时间了 , 找他们吧 , 最要紧的是能思路清晰明确地表述你的问题, 通常你自己在这个过程中或者伙伴中就有人把问题解决了, 又快又好。 另外, 有几个可以良性竞争的职业伙伴是人生的一件幸事, 1+1>2,大家各有所长, 你最好做到及时公开你的成果, 技不压身, IT 发展的这么快, 你再优秀, 那点东东也没有什么值得隐藏的, 所以你可以技术或水平不够高, 但千万不可以让真正具有职业水准的选手鄙视你的职业品质和行为。

(3)有自己 debug 的特点。这一点只是经验之谈,即使在VC 这种高度完善的开放环境下, 仍然应该要求自己仅凭打印语句就能 debug。这也有两点好处:第一个好处是, 遇到 bug你会认真想问题所在, 而不是用 debug 工具一步步简单地追踪卡在哪儿了, 你定位 bug 范围的方式是从大到小、 从粗到精,这是一种自顶向下的思维方式, 而用工具追踪, 容易形成自底向上的思维方式, 这不算好, 你应该先看到森林, 再看到树木。 程序就是逻辑过程, 大多数程序从 main 函数开始, 是由数据结构和功能子程序组成的一个树形结构的逻辑过程 (要认清即使是面向对象的程序语言也是一样的),它的执行过程是深度优先的,但你定位 bug 应该是广度优先的;第二个好处是强迫你思考并记住而不是用工具看到调用过程,大脑的抽象逻辑思维能力和胳膊上肌肉的力量一样,都是练出来的, 如果你的 bug 是程序结构上的逻辑错误引起的, 这一点就非常重要了,顺便说一句, 最难打的 bug 就是程序逻辑结构错误导致的bug。总之, 程序员的职业水准: 生产效率和程序质量, 主要是取决于源码中 bug的数量和 debug 的速度,而不是取决于编写源码的速度。给你一个我自己定义的考查一个职业程序员的指标:一个合格水准的职业程序员,编程的时间如果算一分的话,其累计 debug 的时间不能超过一分,真正职业高手累计 debug 的时间应该控制在 0.5 分以下,如何? 你关上门悄悄问问自己, 你花费在编程和 debug上的时间比例是多少?如果你把程序员作为自己一生的职业,那么就永远都要牢记一点:追求做一个 0bug 的优秀程序员!这是任何一个想成为职业程序员的人的理想,请相信: 坚忍不拔地追求实现这个理想将让你出类拔萃!

(4)做好程序的单元测试。这是另一项考查你是否是一名具有合格职业水准的程序员的一个必要指标。其实在你拿到需求的时候就要准备单元测试用例了,并且这些用例将直接影响你的详细设计。举个例子, 当你拿到一个需求时, 除了分析它静态的功能外, 还应明确它动态的操作/执行过程, 把这个动态过程明确地用流程图画出来, 比如分为 A~Z 的 26 步, 其中A 又可以进一步分解为 A1~A5 的 5 步, 直到不能再分解为止 。又比如说 A3 步不可分解了, 那么你应该把 A3 步的正常操作和所有五花八门的异常操作都列出来, 确保正常的操作肯定正确, 异常的操作起码程序不退出才行。 这样你就要写好多好多的测试用例, 说句老实话, 我也从来不写! 但我一般会列一个提纲, 比如 A3 步有正常的操作 a、 b、 c、 d、 e 共 5 项, 异常的操作有 f、 g、 h、 i、 j、 k、 l、 m、 n 共 9 项, 你在进行单元测试时都应该跑一遍, 这样的程序都还不敢说质量如何好, 但起码可以说较稳定吧! 如果要想在进行单元测试时干得快、 效率高, 那么在进行详细设计时, 你就应该把 A3 步中对所有正常操作和异常操作的判断都设计好, 在编程实现 A3 步时, 使得程序的结构合理高效。 所以, 如果你在工作中是割裂地看待软件工程中从需求、 分析、 设计、 编码、 测试等各个环节, 恐怕水平很有限喔! 但如果你在分析需求时就能看到测试的问题, 并改进设计和实现, 为此做好相应的准备工作, 整个软件开发过程你的效率会高很多, 通常你在一个开发团队中就会高度自信的, 你已越过当一名偏颇、 露骨的高手的境界, 成为一个平静的高手, 这可是 The bestin the best!因为别人看不出你高在哪儿,没见你有什么高招或特拼命干,但反正你就是干得又快又好、又省力。 关于进行单元测试还有很多复杂的方法, 这里只提到了最基本的一点, 目的是让你在工作上考虑周全、 安排有序, 其他的还要靠自己慢慢领悟。

(5)要学会如何思考 。 如何处理工作及学习中的各项问题, 因为思想决定行动, 行动决定习惯, 习惯决定命运。 学习团队精神和沟通能力, 培养团队合作的能力和领导才能, 也可以发挥你的专业特长。 但更重要的是, 你要做一个诚心诚意的服务者和志愿者, 或扮演沟通桥梁的角色, 并以此锻炼自己的沟通能力。 把握不用 “付学费” 的学习人际交往的机会, 犯了错误也可以从头来过。 一个有为的公司, 员工比拼的是胸怀。一流的人才招聘的是一流的人才, 二流的人才招聘的是三流的人才。 要与优秀的员工做好朋友, 做你一生的朋友, 和优秀的人接触会改变你的一生。 只有胸怀广阔的人才可以有所作为,否则就是平庸。 只有这样才可以成为一位合格的软件人员。

(6)不要只关注专业相关的理工科类知识。 人文 、 历史 、哲学有空也可以看看, 对启发创造力很有帮助, 日常工作中你采用何种设计架构模式都是具有创造性的, 创造力的培养不单单是专业知识的范畴, 有很多人文修养在其中。 要竖立正确的人生观, 价值观, 坚定自己的专业方向, 有条件一定要继续读研深造。 需要说明的是, 选择研发的人未必个个都是高手, 严格来说, 大部分都不会编程序。 也就是说, 庸庸碌碌之辈仍然占绝大多数。 研究生毕业的师兄只拿 3 千左右的比比皆是, 所以不要寄希望于拿一张研究生文凭出去赚高薪。 在继续深造前要想想自己目前具备的能力, 而不是混文凭, 以下供参考:  

1) 你已经认为 C++和汇编语言都是很简单的语言 , 并能够自如地运用;

2) 你能够在 30 分钟之内想到正确的五子棋AI 算法设计思路和方向;

3) 你完全理解 STL 为什么这么重要;

4) 你能够独立地解决所有的编译与链接问题 , 哪怕你从来没有遇到的问题, 你也不需要询问任何人;

5) 英文网站是你的首要信息来源;

6) 能够读懂英语写成的国际标准, 比如 NTFS 磁盘格式标准;

7) 你经常站在集合论的角度思考算法问题;

8) 能够理解一个简单的驱动程序, 能够理解一个简单 3D交互程序;

9) 你能够认识到线性代数和概率论在实际编程工作中的极端重要性;

10) 你完全理解 COM 的设计思想, 尤其能够理解 COM 为什么要设计成这样;

11) 当我说到虚函数的重要作用时, 你不会急着去找书来翻;

12) 你能够说出 C++为什么比其他语言优秀的理由。

如果你同时具备 5 条以上,可以认为你已经具备较好的开发经验了。 在这种状态下深造读研, 你将取得最大的效益值。从小工到专家, 在不断探索中积累渴望创造的激情, 完成职业生涯进阶, 特别注意进阶深造期间, 你一定要做有理论深度的算法设计, 比如大规模数据的搜索算法, 性能是首要考虑因素, 不要奢望 SQL 函数能够帮你解决问题, 所有的问题你都必须自己解决, 你必须解决内外存交换的性能瓶颈。 再比如极品飞车的 3D 场景生成、 图形变换、 碰撞检测、 物性模拟、纹理映射、 灯光模型等等, 这些都是必须精通的技术。 要是你认为深造多年之后还是要去搞一般的程序设计, 如信息管理系统之类的软件, 那么你职业生涯的价值就完全不会得到充分的体现。

5 选择合适的领域, 自主创新核心技术, 为振兴国产软件出力

以正确的学习方法经过坚持不懈的努力,你终将在软件研发的某一个领域有所成就,可能你已成为某个领域的专家,这时你可以专注地在某个领域发展,而不必担心基本的衣食住行问题。这时如果你有心,建议你考虑支持一下我们民族软件的发展,考虑一下自主创新一些核心的技术。在此借机呼吁一下,我们广大的 IT 人士,各类信息化公司,多投些精力做一下系统级的基础研发,有能力多关注一下自主创新核心技术,让我们自主研发的操作系统、编译器、 数据库、 D3D 引擎等等基础核心技术的平台能够在祖国大地生根发芽, 结出累累硕果。 有句话 “师夷长技以制夷”, 还有句话“天下兴亡匹夫有责”, 仅做为一名从业十多年的老鸟在这里写下这些话, 期盼广大的正在入行及一起奋战的 IT 同仁们,今天的初学者, 也是明天的领航人, 让我们一起为振兴国产软件努力奋斗。 祝愿祖国更加强大, 明天更美好!

猜你喜欢

转载自blog.csdn.net/u013212391/article/details/22992299
今日推荐