掐指一数毕业已12年(本科),当年稚嫩的小鲜肉如今已为人父,成了微胖的中年大叔,回想起来如果毕业时拟定的职业计划一切顺利,今天创业的公司应该要快上市了,或者至少也应该是年薪百万,早已实现财务自由成为成功人士……
然而现实却是写了12年的代码,仅仅是从当年的小菜鸟成长为今天的老菜鸟。
IT这个行当里,天天都能看到各种新星闪耀,新技术、新语言、新框架、新的传奇轮番上演,今天你的成功可以复制,明天他的成功又不能复制,看起来似乎屌丝逆袭机会遍地都是,而现实中呢,绝大多数程序员终其职业生涯一身也只不过是混口饭吃,如果够努力够幸运的话,也许能在屌丝逆袭的剧情中扮演一个路人丙,当然了,路人甲和路人乙都不是那么好当的。
回想自己的12年,应该走了不少弯路,虽说弯路上也有不一样的风景,不过总结总结总不会错滴。
要不要读个研
本科毕业之后到底要不要先读个研?我想这可能是在大学无忧无虑的生活4年之后面临的第一个选择题,我自己就多次考虑过这个问题。在我看来,如果本科还算是牛逼,而且对自己的学习能力有足够的自信,但又不想读到博士或者留校之类的话,建议不用念硕士了。中国的大学属于难进易出,只要有一定的学习能力,修满学分再编个论文啥的非常简单,副作用是在校期间的学习能力会断崖式下降。既然高考的时候你已经证明过自己了,我觉得就没有必要再多浪费三年光阴了,不管你的导师有多么牛逼的项目,你自己在学校有多么的勤奋好学,最终你获得的经验都比不上在外面公司里干几个实际项目,更何况我们都知道硕士导师所谓的项目都是怎么回事。
如果本科念的学校一般的话,建议还是考个研究生,因为特别对于应届毕业的学生来说,文凭几乎是能力的唯一证明,特别是本身学习能力还是很强,只是高考没有发挥好的同学来说,考个牛逼学校的研究生可以重新证明一下自己。
如何挑选团队
特别对于新手程序员来说,在不同的团队里成长速度是有很大差别的,如果可以选择的话不妨先了解下要参与的团队是否适合培养新人或者是否适合自己。个人建议可以从下面几个维度来考虑:
平均年龄
如果团队的平均年龄比较大,意味着团队成员多多少少已经经历过好几个团队,甚至好几个公司,稍微再大一点的可能已经结婚生子,在这种团队的优点是身边的同事经验比较丰富,如果学习能力够强的话能够快速学习到很多东西;缺点是一般这种团队的凝聚力和协同会存在问题,各自为战的情况比较多,另外,有相当多的老员工存在知识老化、主动性低、激情减退的问题,综合考虑的话相对年轻的团队更适合培养新人。
开发阶段
项目在不同的开发阶段的开发强度不一样,日常工作中关注的重点也不一样,用一个表格来比较一下。
开发阶段 | 开发强度 | 关注点 | 优点(对新人) | 缺点(对新人) |
---|---|---|---|---|
初期 | 高 | 架构搭建和新功能开发 | 经历从无到有的过程,代码质量较高,学习速度快 | 进度压力大 |
中期 | 一般 | 功能完善和质量稳定 | 开发节奏稳定,压力不大,偶尔参与一些大规模的重构 | 框架基本定型,学习内容较分散,学习速度一般 |
后期 | 低 | 零散小功能和bug修复 | 进度压力较小 | 零散的修补,代码开始腐化,学习速度慢 |
如果你精力充沛,愿意付出更多的时间和承担更大的压力,就比较适合第一类团队,如果你对自己没有太多信心,希望稳扎稳打慢慢来,就比较适合第二类和第三类团队。
高手有多高
学习的过程中身边有没有高手的指导是非常重要的,就算是世界冠军也同样需要教练的反馈和意见。对于一个新手来说,身边同事的最高水平基本决定了未来半年到一年的时间能达到的最高水平,所以,如果可能的话,选择最NB的高手做自己的队友。
开发模式
这里要给敏捷团队做个广告,敏捷团队采用的各种技术实践对于新手程序员的提升是非常明显的,比如:
- 结对编程
- TDD
- 自动化测试
- 持续集成
有的技术实践能帮助你快速学习别人的经验,有的技术实践能帮助你大幅提升工作效率,具体就不展开说了,只有做了才知道。
如何定位bug
新手程序员刚进入职场时经常会分配到一些 bug 定位的任务来练手,通常我们依赖程序运行的 log 可以定位大多数的 bug ,但还是会碰到一些 bug 缺少足够的 log 很难定位,甚至是很难复现,这种时候该怎么做呢?很多新手程序员在这个问题上摸不着头脑。
有的程序员看起来更善于解决这类问题,一个卡住你一两天的问题对于他来说可能就是半个小时的事,如果在事后分析他定位问题的思路,你会发现非常清晰,感觉“就应该这样做”或者“哦,原来这么简单”之类的,但下次换你来定位的时候,可能一上来就找不到着手的方向。
以前我认为这些人可能是有特别的“灵性”或者“天赋”,后来有一个同事(很早之前的)讲了一个观点让我豁然开朗,他把定位 bug 的过程分成 3 步,有点现在流行的机器学习的意思:
- 收集信息
- 根据 bug 现象,做出假设
- 验证假设,如果假设被推翻,回到第 1 步
实例化一下大概是这样:首先对相关的代码足够熟悉,然后看看复现 bug 的条件,log 中的可疑之处等等,然后结合 bug 的现象,假设是因为代码的某个地方出现了问题,比如可能是多线程访问的互斥出了问题,那么根据这个假设反证,比如在代码中增加不同线程访问时的打印看是否的确存在线程冲突,如果验证结果符合假设那基本就定位了,如果假设被推翻,那说明之前收集的信息不够全面,再回过头来看看还有哪里是自己没有考虑到的。