致新人程序员——年轻的你和未走之路

我知道由我来写这样的文章实在是有些僭越, 但我又想对新人程序员们说些什么, 虽然我知道他们中的大多数大抵是听不进去的了, 但倘若有人能听进去, 相信对他的程序员之路, 起码也是不会有坏处, 如果能额外有所收获, 则再好不过.

在我眼里, 程序员从成长经历里大致分成两种, 一种是由编程爱好者成长而来, 另一种是学院和培训班培训而来, 我个人属于前一种, 深知编程爱好者们的深浅, 同时也接触了一些学院出身的程序员, 自认看待事实还是比较客观的. 不过无论是哪一种程序员, 都对年龄问题比较忌讳, 所以先把这块事情拎出来讲.

所谓年龄问题, 或者说是入行的先后问题, 是经常被争论的, 有的人小学就开始写程序, 有的人大学才开始写程序, 尤其是学院出身的, 一般年龄都不会太低, 所以更容易遭遇年龄问题. 从常识上讲, 起步晚的选手确实比起步早的选手要少了很多学习和研究的时间, 所以看到年纪比自己小, 却又有能力的, 大多数人都会感到自卑. 事实上, 这种自卑是毫无道理的, 所谓的闻道有先后, 术业有专攻, 没有人能够证明起步的早晚与能力水平构成直接关系, 所以绝对不要因为你入行晚或是起步晚而懊悔, 甚至失去自信心. 在这个行业, 你会经常性的看到那些18岁以下的未成年人在秀自己幼稚或高深的代码, 或是炫耀自己的幼稚或高深的技术, 其中确实不乏高手, 但更多的是嘴脸恶心的编程初学者和只会装逼的菜鸟, 有很多编程爱好者最终不会选择成为程序员, 资质和个性都是很大的影响因素, 不过他们的选择倒是对的. 而对于高手, 无论他年纪是大还是小, 都应该受到尊敬, 而不是带着年龄的有色眼镜去看待他们. 对于嘴脸恶心的, 没有必要跟他们争执, 实践证明这没有丝毫的意义, 非技术上的争执对于程序员而言永远是在浪费时间. 要记住, 真正牛逼的人用实力证明自己牛逼, 傻逼的人用时间不对等来证明自己牛逼.

由于反摩尔定律和安迪比尔定律从中作祟, 这个行业的发展速度是非常快的, 如果你够努力, 很快就能和那些起步早的人站在同一个台阶上, 除了基础性的理论知识以外, 大部分旧的技术都将很快被淘汰, 未来永远是属于先行者的. 在这个行业里去学新的东西而抛弃旧的, 是一条不成文的规矩. 通常情况下, 基础理论不会有大的改变, 但实现的方式总是会变的, 而新的方式既然能流行, 就说明它确实比旧的方式有过人之处, 那么就应该去学新的, 这种情况下, 起步早的选手并不会有多少优势, 而起步晚的选手, 很可能不用花太多功夫就能实现一些以前实现起来稍显困难的功能. 当然, 我并不是说基础理论不重要, 我没有任何这个意思, 但事实确实是新的技术先进太多, 在一些很基本的功能实现上, 完全吊打旧技术, 不过再往上高一级, 涉及到更专业的领域, 那么差距还是会拉开, 所以无论新技术多么好用, 学好基础的理论知识还是很有必要的.

谈完年龄问题, 再来谈环境问题, 我想告诉广大新人程序员的是, 你所处的技术讨论环境并不能决定你的水平, 但会很大程度的影响你的认知范围, 比如混百度贴吧和V2EX的人水平可能接近, 但认知范围在大多数情况下是后者胜过前者的, 我是没有数据可以支撑这个观点的, 但通过观察, 相信不少人也会有和我同样的看法. 在一个很low的地方如果你有一定水平很快就能身居高位, 有一些人沉迷于这种感觉, 不能自拔, 最后成了井底之蛙. 当然也有一些高低端社区都混的, 他们连队都站不好, 未来是很麻烦的, 如果不能在技术讨论方面撇清低端环境, 是很难向高处进步的.

上面这段话也不是说V2EX等社区怎么怎么好, 只是它相比百度贴吧, 是存在一定优势的, 比如V2EX那里有很多真实企业的招聘信息, 而且质量比较高, 那些低端企业上去招人基本会被喷. 类似的社区在国内你能找到不少, 但由于新人大量的涌入, 会导致整个社区环境变差, 导致高端用户流出, 这点也是不可否认的, 在我看来, V2EX就正走在这么一条衰败的路上, 好在现在它被墙了, 也算是GFW做的少数几件好事之一, 虽然我现在几乎不逛V2EX, 但我有这种感觉. 另外, 像SegmentFault之类的问答平台也是不错的选择. 能够找到一个合适你自己水平的地方是很重要的, 不过找不到也不是什么大碍, 你也可以和我一样不过多参与社区, 只是写写博客, 但由于圈子小的缘故, 这样的人会很容易被业界淘汰, 现在剩下的认真写博客的程序员, 基本上都有自己的一套获取前沿信息的方法, 这样就不用过分依赖社区的讨论环境了, 不过这并不容易, 同样的, 写好博客也并不容易.

另一方面, 在技术讨论时要压制自己的戾气, 国内有太多戾气很重的程序员, 我也是其中一员, 记得曾经在一个Node.js群里有人问一个包含单双引号区别的问题, 当时我给出了正解, 然后有个新人跳出来跟我扯字符串中的斜杠转义, 说JavaScript的单双引号是有语义区别的, 然后我跟这家伙断断续续辩了3个小时, 话也是越说越狠, 最后他还跑到CNode社区提了问题再把脸丢了一遍, 当时我就觉得, 整个中文编程圈子的整体水平是很低的, 即使你用的技术是最新的, 也改善不了个人水平的问题, 同时也算是了解了一下CNode社区一般成员的水平, 后来我就较少在这种鱼龙混杂的地方认真讨论技术了, 一方面是意义不大, 另一方面是免得被人指责我好为人师, 水平差的就让他自我提炼, 这是我现在认为技术圈里对待新人的最好方式, 水平差既不努力也不认真的, 会被自然淘汰, 而真正有能力成长的, 会自然成长.

在学习时, 记录学习过程是没有必要的, 但是对于已经被系统整理好的资料而言, 自己留一份备份或是记录是很有用的, 网络这么大, 有很多东西需要你去摘记, 不然可能哪天忘记了就找不到了. Evernote之类的笔记软件配合浏览器插件是很有用的, 你也可以写博客记录, 但我不建议写完整拷贝的博客, 因为互联网上的重复信息已经够多了, 如果你在公开的网络上做一份一模一样的备份, 搜索引擎可能会收录你的备份然后导致同一份资料在某个关键字的首页数次出现, 这会影响他人的查阅, 这也是我不建议那些很难写出原创内容的人写博客的原因之一.

在学习途中要多做实践, 纯理论的理解永远不如真正做上几个项目得到的收获多, 如果有时间, 应该多做你真正觉得需要做的项目, 并且应用上那些你还不太熟悉的技术, 这是个人认为的最快学习方法. 如果你暂时无法抽出时间做项目或者太懒, 那么至少保证自己能够在下次使用不熟悉的技术时能快速查找到帮助文件和相关的文档资料.

随着认识的提升, 你将不可避免的接触到UNIX哲学和开源精神两大教条, 它们在整个程序员界确实有着不可撼动的地位, 以致于一个个大有作为的程序员前赴后继, 刚入行的菜鸟们也跟着各路大牛往那软件自由的世界奔去, 一副发现新大陆的情景.

而世界并不会真如UNIX哲学和开源精神中的一样美好: UNIX哲学诞生了一批又一批的教条主义者, 它们固执的坚持UNIX伟大先驱们留下的一句又一句过时的话语, 并将其视为圣经, 并用精神胜利法驳倒一个又一个他们眼中的异教徒. 开源精神留下的则是大量的代码残渣, 这些残渣是为了开源而开源的产物, 每天都有无数的这样的代码被提交到Github上, 垃圾越堆越多, 甚至很多开源精神的奉行者, 至今以为开源只是”开放源代码”的简称, 怎么能不令我们汗颜. 我想说的是, 不要成为一个教条主义者, 也绝对不要成为什么传教士, 程序员应该做的, 就是实现这个世界还没有被实现的需求, 其他的, 都是精神鸦片, 是为真正脆弱的人准备的.

去贡献那些你愿意贡献的能让其他程序员受益的开源代码, 而不是往本就拥挤的代码仓库里添加更多的废料, 虽然每个人都会或多或少的提交垃圾代码, 但也需要学会适可而止.

还有一部分不务正业的去研究什么工具好, 从用操作系统到用什么IDE和Editor, 甚至机械键盘的轴哪种好, 这些都不是新人应该去关注的地方, 因为工具在大多数时候并不能拯救你的编码水平, 用Visual Studio配红轴键盘写出一堆垃圾的也大有人在. 最夸张的莫过于新人不好好学习编程转而研究Linux操作系统桌面环境, 这种人把自己使用操作系统的初衷推翻, 然后在最无关紧要的部分里花费大把大把的时间, 最后是得不出什么真正有用的东西的. Windows和Mac OS X是最适合程序员的操作系统, 而Linux是在服务器或嵌入式设备上用的, 请务必记住我说的话, 而Windows是最适合PC使用的操作系统, 对了, Mac OS X也是PC, 说不是PC那是装逼时用的话, 请不要相信.

此外, 分清计算机技术和计算机科学也是很重要的, 大多数程序员都是技术方向, 少部分程序员在技术方向以外, 还有研究计算机科学的. 你真正要分清的是那些纯粹搞计算机科学的人, 他们也在写代码, 但他们干的完全不是和你一样的事, 你只要知道这些人大多数人写程序比不过你, 而你写算法比不过他们就行了, 不要试图和他们争论, 虽然只差几个字, 但计算机技术和计算机科学确实是秀才与兵的关系, 大家的侧重点不同, 思考方向不同, 争论起来永远是鸡同鸭讲, 没有结果.

再来说说编程语言的学习, 大多数程序员的第一门语言都是命令式编程语言, 命令式编程语言之间有很多共通点, 当你掌握一门命令式编程语言后, 学习其他命令式编程语言是很容易的, 大多数时候它们只是底层实现的方式变了一下, 语法变动一下, 掌握一门新的编程语言能获得的成就感是很强烈的, 建议遵循着成就感继续掌握多门编程语言, 你掌握的命令式编程语言种类越多, 就越能发现一门语言的不足和长处, 渐渐的你就会直到这门语言适合用在什么样的生产环境, 适合用来开发什么项目, 这种感觉和经验的积累是很重要的, 最终在技术选型等场合时, 就能做到取长补短, 实现混合编程.

一般情况下, 你都会在学习各种编程语言时得到一个你真正心仪的支持REPL的语言作为日常工具使用, 对一些人来说是Python, 对我来说是JavaScript. 这类工具语言能在平时帮你计算一些简单的数学算式, 进行进制转换, 处理简单文本, 有益无害.

掌握命令式语言后, 学习函数式编程也是很有必要的, 虽然大多数时候函数式编程都用在算法和人工智能领域上, 而且基本都是在搞计算机科学的人在用, 但其中的编程思想都是很重要的, 如果你之前看过有关编程语言模式的书籍, 很快就会发现这些模式在函数式编程上都可以被更优雅的实现, 对于程序员而言, 函数式编程语言是一道坎, 学会了感觉好像什么都没学会, 没学又会觉得少学了什么, 但我还是要再重复一遍, 学习函数式编程是有必要的.

最后一个关于编程语言的警告是——不要幻想用中文编程, 至今还没有出现一个真正能用的中文编程语言, 像易语言、习语言这样只是把语法关键字本地化的语言, 是不能算作中文编程的, 而且这类语言的社区也是大量小白的聚集地, 没有良好的编程讨论氛围, 不建议加入.

提醒一下, 英语在这个行业里很重要, 而且是作为一个瓶颈存在的, 如果你的英语水平不够, 是没法在短时间内阅读英文资料和文献的, 这就会影响你学习的效率, 在学习编程的初期, 中文资料基本都可以满足你的学习需求, 但到了稍微高一点的领域, 中文资料的翻译速度是跟不上你的学习速度的, 所以必须要有自己阅读英文文章的能力. 另外有一点我看着很奇怪的现象就是一些新人不务正业去主攻翻译而不是技术, 这种做法我是不认同的, 在你没有得到技术之前, 最好不要去搞翻译, 如果你不能传播知识, 至少不要用自己没有把握的知识去误人子弟.

要有耐心, 在开发程序的过程中你会经历很多很多的失败, 从花一个下午找bug发现只是少写了个分号到写了一系列复杂的算法后发现结果不是你想要的然后要从头开始调试, 能够简单解决的都不是问题, 而不能简单解决的都会浪费你数小时甚至数天的时间, 必须要做好失败的准备, 同时绝对不要轻易的决定一个问题解决的具体时间, 这是不理智的行为, 而且大多数时候都会后悔.

在平日对计算机的使用习惯上, 我建议程序员们尽力使用正版软件, 绝对不要为了逃避使用正版软件或仅为了使用开源免费软件而转去使用Linux, 这会变成一件很滑稽的事情. 优秀的产品需要有人付费, 而这本就是一件天经地义的事. 开发人员投入心血开发出了软件, 别人凭什么”免费”享受他们的成果? 如果你的财力暂时不足以支持你购买正版, 那么在使用盗版时, 也请记得感激那些软件开发者们, 尤其是Adobe旗下的各种被盗版泛滥的生产力工具, 如果有人在使用盗版, 却又对软件本身没有任何感激之情, 那么作为一个人, 他的道德是相当失败的, 这类道德败坏的中国式程序员在圈内太多了, 我不希望有更多这样的人加入这个圈子.

在开源软件或是免费软件和服务的选择上, 也要掌握自己筛选和辨识好坏的能力, 比如程序员用360系的东西很容易被同行鄙视, 而用Google系的产品则会受到同行的认同.

学会科学上网, 入行后你会发现平时遇到的大多数问题通过Google英文搜索就可以搞定, 而百度根本就搜不到有用的东西, 如果你还没这种感觉, 说明境界太低, 还需要多加磨练. 另外, 基础很重要, 有一些东西确实不是最新的技术能够帮你简单搞定的, 一朝一夕的努力还是会起一定作用的, 不过这也是取决于你具体在干什么了, 比如SQL语言已经诞生将近30年了, 至今还在被广泛使用, 那么一个长期使用SQL语言的人, 总会比刚开始用SQL语言人有更多经验的.

在处理合作关系时, 除非你是设计师出身, 否则请不要觉得自己做的设计比专业设计师厉害, 至少我接触过的大部分程序员, 他们的审美是不可靠的. 同样的, 也不要越权去做数据库管理员、运营维护人员和测试人员的工作, 如果你是后端开发人员, 不要想着正面肛前端, 前端开发人员也不要想着正面肛后端, 所谓术业有专攻, 除非对方真的菜得抠脚, 或者你本身有全栈工程师级别的能力, 否则请不要轻易越权.

尽量减少装逼次数或戒掉装逼(很难), 装逼是新人程序员最大的恶习, 水平越高, 越能发现自己水平的不足, 就越能控制自己装逼的情绪, 当你刚开始学习编程时, 请时刻保持一颗谦卑的心. 水平再高一些, 会染上吹牛逼的恶习, 也需要自我克制, 因为这个行业里, 同行打脸是完全不留情面的, 程序员之间的辩论是少数可以直接分出胜负的辩论领域之一, 如果要吹牛逼, 则建议做好能辩赢同行的准备, 否则也别怪输了辩论自己心里难受.

最后讲一下死线和设限这两个对程序员影响严重的东西, 死线是程序员完成开发目标的唯一动力, 而设限是程序员拖延症发作的基本表现, 对这两个问题, 没有好的解决方法, 唯有早死心才能早解脱, 如此而已.

特别感谢: guoruei对社区部分内容的补充.