一晃做程序员也有十年了,总觉得时间过的很快,仿佛第一次写程序还是去年的事情。虽然到现在也已经换了三四家公司了,但总有种自己没有做过什么的感觉。于是便想把个人的经历写下来,留给以后的自己作为个人回忆。
一、大学时代
学生时代写程序并不能作为“程序员”的经历,我真正的成为一名程序员要从大四开始说起。
大四的时候保研结束,有些空闲的时间想着找一些事情做做,机缘巧合认识了一个大很多届的师兄,自己开了一个公司做智能手机应用。
那是2009年,现在二分天下的苹果和安卓的代表手机还是iPhone 2G和HTC G1;系统的版本还是iPhone OS 2和Android 1.5。
我进公司实习的第一个应用是把一个在iPhone上的工具类程序移植到Android上。当年的Google还可以访问,但是Android的代码示例也几乎只有官方的Demo,公司里也并没有没有别的会写Android程序的程序员。
正是在这样一抹黑的情况下,我迈出了移动开发的第一步。当时每天去公司就是把一台G1连上笔记本电脑,改两行代码后花上半分钟运行一下,看看效果,不行再改两行再试,效率非常的低下。
功夫不负有心人,做了三个月之后程序终于上线了。虽然反响也并不好,没有达到iPhone上的营收效果,没多久就从Market上撤下来了。但不管怎么说,这也是我第一次写的产品代码,我在程序员的道路上迈出了第一步。
研究生期间”不务正业“又辗转做了几个公司的Intern,当时为了能兼顾实验室和Intern,特意都选择了可以remote的实习。其中包括两家在美国的公司。
在这两家公司最大的收获便是锻炼了英语读写说的能力,从一开始面试的时候连名词都听不明白,到后来可以和老外侃侃而谈,在这里迈出的第一步很关键。
另一个收获就是除了Android之外,又接触了iOS的编程(当时还叫iPhone OS),学习了一门叫Objective C的语言,以至于很长一段时间在Java和Objective C之前切换的时候会不自觉地打出括号和点的组合。
2012年7月研究生毕业,在年初的时候我开始了找工作,由于实验室的背景关系好多师兄毕业后都选择去了国外大公司工作,于是我也在期待着可以跟随师兄们的脚步。
无奈自己的硬实力不够,没有能够通过国外大厂的面试。在国内的找工作也并没有非常好的进行,大公司并没有很多移动开发者的职位,待遇比较不错的职位投递了简历却并没有得到回应。
在机缘巧合之下,有几家日本的IT公司来到中国招聘毕业生,我参加了其中一家公司的招聘会并顺利的通过了面试,于是来到了日本东京开始了自己的程序员生涯。
D社对于新加入公司的毕业生程序员的培训不得不说还是做的比较到位,首先对于海外招聘的毕业生,提供了日语的全日制培训以及之后正式入岗后的日语追加培训。
其次,在正式分配部门之前,有为期两个月的技能培训。技能培训的内容是将公司内的Perl框架简化后让大家进行一个类似于填补作业的项目,并全程有老师指导,每阶段需要提交代码并且答辩。答辩不通过的话需要再等两天后才可以预约下一次答辩。
现在看来过于严苛和形式主义,但是在以后的工作中,越来越体会到新人培训的重要性,因为在之后的公司从没有过这样细致到“手把手”式的培训。
1)对于每一句写下的代码,老师会问为什么这么写,有没有别的写法,各种写法有什么不同?会细扣到代码的顺序,变量名的命名,注释的语法等等。
实际上这是非常细致的代码审查(Code Review)流程,大部分新人程序员着眼于如何快速的实现功能,有时会不假思索的借鉴来代码,而我之后供职的公司并没有这样的培训,大多数的代码审查也只是停留在错误检查和性能上。
个人觉得在一开始写程序时养成良好的习惯非常重要,尤其是对于刚脱离校园环境的程序员。
在D社的培训结束后加入了一个临时的岗位,做了三个月的Perl的网站开发,之后又调去了别的部门操刀旧业,维护公司的门户App,说实话门户App的技术含量真心不高,就是WebView封装出来的。
期间做了唯一一件有些技术含量的事情是把App内的聊天功能加上了推送功能。在客户端启动时,在服务器端注册客户端的推送口令,在客户端的网页里通过api来通知服务器把消息放进队列,服务器端有定时任务去消化队列中的消息。
这其实是一个非常普通的小系统,也比较成熟,对于个人来说主要的作用就是独立设计并且完成了一个完整的系统,并且在生产环境中实际的运行起来。
反思一下自己在D社的一年半,在职场的第一份工作并没有能够很好的积累。而只是停留在完成布置的任务阶段,并没有去主动的学习。
三、 后端程序员
在I社的前三年我一直在SEM组工作,SEM(Search Engine Marketing)组的主要任务是自动的将公司投放在搜索引擎上的广告优化。这是一个纯后端的组,以前的工作经验在这里并没可以发挥的地方。
我的工作内容,从一开始去开发维护一个基于Python的内部工具网站(后来知道老板看我的简历是做App的,误以为我是前端能手),三个月之后Python工具网站的开发告一段落,开始接触竞价算法(Java后台程序)。
当时正适逢移动流量开始渐渐追赶并超过个人电脑的流量,针对移动端广告进行竞价调整(Bidding Adjustment)是一个重要的功能。
正是在进行这一工作的时候,我有机会去主导从MySQL切换到RabbitMQ的解决方案,解耦合算法端和API端的紧密联系。并且通过和系统工程师的配合,解决了首次部署RabbitMQ中遇到的问题,并设置了警报规则去监视系统的运行健康状况。
在切换的过程中,为了保证无故障的切换,先后采用了试运行(Dry Run)的方式模拟从MySQL切换到RabbitMQ的场景,接着运用了A/B test的工具分出少量流量测试RabbitMQ流程的稳定性,最后达到100%切换后进行代码的清理。
在这个项目中我学到了很多宝贵的经验,对于以后进行的一些重构式工程有很重要的方法论上的参照意义。
与此同时,自己也不满足于只是去做分配下来的任务,开始观察并思索作为工程师的痛点。比如,每次上游的一些库会莫名其妙的改变一些公有接口,导致下游的项目构建收到影响,结果给下游项目的开发人员带来了额外的负担。
另一方面,上游库的开发者要想改变删除过期的接口让下游项目迁移到新的接口,又苦于在公司内部喊嗓子得不到有效的回应,下游项目的工程师没有动力去及时的跟进改变,导致过期接口的删除迟迟不能进行。在这种情况下,如何可以减少不必要的公有接口修改,同时又能提高必要公共接口修改的曝光性?
在研究了公司的构建系统之后,我决定在构建系统上,利用一些开源工具和Java编译插件的技术,实现了两个小功能:
在发布库的新版本是总是和最后一个旧版本比较API的修改,如果有任何公有接口的修改或缺失则给出警报;
提供编译期的注解(Annotation),让程序员可以对公有接口(类)设置过期时间,在过期时间到来之时下游的项目如果有引用则会出发构建失败。
I社是我从一名初级程序员向着高级程序员成长,随着在公司的时间增长,手头的工作也很快不能够满足自己的兴趣。在SEM组待了将近三年之后我的经理建议我换组,在经历了一番挣扎后我选择了去一个有前端以及顺带一些移动应用的组,在这里我又重操了一段做移动端应用的经历,并且又学习了一些前端方面的知识。
恰逢也同样是美国总部的H社在东京开始招全栈程序员,虽然同样是美国公司,但是H社还尚未上市,团队也较小,所以抱着施展一番拳脚的想法去面试了H社全栈工程师的职位,并于去年7月加入了H社公司。
四、全栈程序员
加入H社后的首个项目是将一个年头已久的PHP前端+后端网页改成PHP + Apache Thrift + GraphQL + NodeJS +React的新框架。作为全栈(Full Stack)工程师,我需要从PHP到React从头到尾都做一遍。
首先便是读原来的PHP代码,并抽象成Thrift服务。其次便是在NodeJS服务器端将Thrift服务映射成GraphQL的Schema,并实现GraphQL的Resolver逻辑,然后便是用一个Node应用代替PHP的前段,用React的框架来渲染出一模一样的网页。
在短短的几个月内,从一窍不通的React小白,到完成了整个页面的迁移,自己对于React框架的应用和一些实践有了自己的理解。
GraphQL也是一个对我新鲜的概念,在GraphQL的实践中,我感到这个框架其实也很适用于我在I社工作的第二个组,甚至可以在脑海中把原来的API用GraphQL一一对应起来。
这种相互印证的感觉让我再次意识到做出换工作的决定并没有错误,否则我的思路会很长时间局限在I社的框架中。
春节期间利用闲暇时间,把公司的A/B测试系统进行了优化,这个优化也是我刚进入H社时最想改变的一点,然而遭到很多质疑的点,于是我在进公司提出的propse基础上做了退让,专注于解决最基本的痛点,加入了基于不同域名实行不同的分配(Bucketing)。在于现行系统并存的情况下一步一步的将功能发布了出来,在公司内获得了好评。
五、 下一个十年
纵观我的程序员经历,从移动应用开发,到后端、前端,以及零星的DevOps和Release Engineering的经验,我觉得自己是朝着“全才”的方向发展。然而全才意味着什么都懂一些,但是又说不上是哪个领域的专家。
下一个十年,我想我仍会热爱程序员这个工作,我会在现在的岗位上,朝着填补我技能树上的空白努力,争取在下一份工作,可以将自己全部的所学都用上。
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721