/ 故事

一个程序猴子在创业的公司的一年,是如何从0到1

传说中有一只程序猴子,我们暂且叫他小C,小C在经历了一次创业失败之后,毕竟临近毕业,所以就需要寻找一份工作,作为一个实际项目经历丰富却不背理论的人,所以决定选择一家普通的小公司来工作。

原来只有小C一个后台研发,并且代码为0

入职前几天,小C还在想着,又回归平常的生活了。由于带团队久了,虽然独立解决问题的能力凶残了很多,但是毕竟没有人带,没法吸取前人的经验,并且正所谓当局者迷旁观者清,自己的不足也很难以发现。

但是入职之后,小C蒙了。后台就小C一个人,那就是说没人带小C啦。并且是没有代码的,然后API文档却已经写好的,然后APP端界面是已经完成的,并且他们是2个人。

更可怕的是,他们要出第二版新功能。那么意味着小C是要从版本0写到版本2,而APP是版本1写到版本2,加班加点无可避免了。

技术选型

既然小C接手的时候是0行代码,并且并没有CTO指导,那么意味着对于技术的选择小C有很大的自由度。

开发语言选择,这个就没得选啦,既然面试的时候是招聘python,没理由进来直接用php来开发吧。

web框架选择,虽然python的web框架是django雄踞榜首,但是也是百花齐放百家争鸣。除了django以外,flask, tornado,web.py,bottle等也是使用率非常高的。怎么选择呢?由于小C同学使用flask的经验比较丰富,所以决定使用flask框架。(框架选择原则:文档是否比较完善,解决问题的资源是否充足,项目组学习门槛合不合适)

存储选择,数据库选择常用的mysql即可,而缓存则选择数据结构比较丰富的redis。

代码管理

作为一个优秀的码农,怎么会在项目不使用代码管理工具呢,哪怕只有自己一个开发?

这个时候瞧瞧IOS的代码管理工具,原来是可怕的SVN。小C决定还是不随波逐流,还是稳稳的使用git作为版本工具。就是这个决定才免受像IOS经常发生合并代码出现代码丢失问题。

代码管理工具的作用:方便找回以前的代码,方便多人协作,防止误删代码。

测试小工具的重要性

虽然可以使用火狐浏览器或者谷歌浏览器的插件来请求接口,但是毕竟是一个通用的工具,测试起来还是不够便利。

因此,一个简单测试小工具就显得十分重要了。这个工具需要什么功能呢?

  • 能够自动测试所有的接口
  • 由于接口在本地,测试服务器,正式服务器的url等一些信息都是一样的,但是域名,token等是不一样的。所以这个小工具应该支持测试用例只需编写一次,而服务器信息独立配置,然后达到可以方便测试各个服务器的接口。
  • 最好有一个界面而不是命令行操作,降低学习成本。

对接是如何让小C崩溃的

业务逻辑简单,代码编写也简单,但是沟通却不简单。因为人与人之间的想法是不同,所以对接往往是一个耗时的过程。下面列出经常对接错误的地方:

  • 参数缺失,有些必选参数没有写。
  • 参数名写错了,这个相对第一个概率比较大。
  • GET和POST混乱了,这个也是真实发生的事情。

为了解决这个问题,专门在测试服务器用日志记录下请求类型,请求的URL和请求的参数。每次对接只需要查询日志即可。

最无奈的事情,线上调试

小C在连续加班三个月之后,项目终于上线了。上线之后,一些测试没有显示的BUG陆续出现,这个时候产生一个很严重的问题,我们很多情况下都没法还原当时的情景。

左想右想,想出了一个还算可以的方案。就是记录下每一次的请求信息,返回的信息,如果出错的时候还记录下出错的信息。然后由于数据量巨大,所以选择每一天记录一个db,并且使用mongodb来存储。以后出现问题之后,只需要查找日志即可。

消息中间件初接触

由于业务上有一些非常耗时的操作,例如发送推送信息。这个时候就需要异步处理了,异步处理一个办法是把任务写入数据库,然后独立进程来处理。也可以写入rabbitmq或者redis,然后慢慢处理。

消息中间件也可以处理并发写的问题,就像上面请求信息记录,如果实时写入mongodb,对整个系统的性能还是有所影响的。最好的做法是写入类似于rabbitmq的消息中间件,然后再慢慢写入数据库。

一天10次部署是如何实现的

既然是小公司,业务变化之大实在是预期之内。需求每天都在变,美其名曰业务试错,其实就是一拍脑袋想出的需求,好多根本就是口头说明,设计图都没有。

既然部署如此频繁,那么就需要实现快速简单的部署。由于小C是使用GIT作为代码管理工具,所以最简单的办法,在服务器也使用GIT,部署的时候只需要git pull拉取最新代码。但是python 应用需要重启才会使用最新代码,应用部署使用nginx + gunicorn + flask。所以又写了一个shell脚本来先kill掉gunicorn进程,然后在启动gunicorn进程。部署过程只需要先拉取代码,再执行shell脚本即可,所以一天10次部署完全没有任何压力。

使用任务管理工具的前后

一开始,是没有使用任务管理工具的。那时候产品经理出APP的原型图,然后小C根据图片确定要给什么接口和设计数据库结构,然后所有需求都是口头描述(天呐,小C竟然还活着)。

本来,虽然存在各种不合理性。但是呢,还是可以勉强进行开发的,但是后来发生的一系列事情打破了这微妙的平衡。

  • 某一堆功能经过技术团队加班加点之后,APP要发版本了,就在发版本前的内部测试中(公司小,没测试团队,所以都是老板,产品来测试),突然老板就说这功能怎么这样子,怎么哪个功能又没有,快点改。(就是没有任务管理工具,没记录下当时的话语,所以百口难辩,只能夹着尾巴加班咯)
  • 经常过来问,这功能做好了没有,怎么系统这样子的?(问多了真的好烦的说)

研发效率往往跟心情挂钩,也许你会说这不理性,但是你问问研发有多少人可以做到理性呢?所以要改变现状,既然由于都是口头安排任务才无据可查,那么白字黑字写清楚,大家对质都方便。

既然是互联网行业,当然要无纸化啦。任务管理工具使用在线的就好(为了避免广告嫌疑,使用哪一家任务管理工具就不说名字了)。自从使用了任务管理工具之后,研发进度一清二楚,他们也没法说我们这个做得不对,哪个没有做。总的来说也是相安无事了。

竟然用上了docker

一开始,公司服务器都是ubuntu(小C表示只喜欢redhat系Linux系统)。本来一切都在平稳运行中,然而某一天,一个业务需求把这一切都摧毁了。

这个可怕的业务需求,就是基于HTTP2的apns。由于某个版本的ubuntu默认情况是无法使用http2的,正确来说不知道如何配置。

但是,工作不是说一个系统问题就砍需求。那是要直接走人的节奏,更换服务器系统,线上服务咋办?迁移不是一句话能够解决的。

既然系统换不了,装个虚拟机还是可以的吧。然而,那普通得不能再普通的服务器,只能安装伟大的docker了。docker跑的容器与容器里面的进程消耗的内存几乎一样,是轻量级虚拟化的最佳实践。

使用docker的另一个好处是,统一了线上和线下的环境,老板再也不会说我上线就崩溃了。

注:docker并不是说多么高科技,用上docker可以很好的隔离服务器环境,并且避免测试没问题,线上出问题的情况。

为了快速迭代,第三方是一个好的选择

由于初创公司的产品,一个一个都是巨人。一个APP往往是若干个系统的集合,然而给到后台的开发时间就是那么的一丁点。这个时候:

  • 图片系统自己开发,没几个月能稳定么?
  • IM系统,不做一年能扛几千万用户么(老板不是整天说千万级用户么)
  • 数据分析,自己造一个统计系统,已经无法知道需要多长时间了。

然而接入第三方,往往只需要一天,一天,就是这么的愉快。

加班与效率

互联网行业可是加班的重灾区,然而99.99%的加班是可以避免的。

  • 给崇尚加班文化的公司一句话,以为加大工作时间就会加大产出么,到头来只是效率降低,总量不变。
  • 给产品经理的一句话,程序猴子骂你们不是没有缘故的。你就不要在我们准备吃饭的时候叫我们改,然后自己跑去吃饭。也不要不临近下班不给需求。

工作虽重要,健康价更高

钱可以挣,但健康没有了就没有了。小C的一位同事就是由于经常加班,导致饮食不规律,然后弄到胃疼。然而其实到头来什么都没得到,一句慰问都没有,何必呢!

各位互联网研发,保重身体,道理就不多说了。

一点点想说的话

网上很多写应届生应该选择大公司还是小公司,其实只能说大公司会让你眼界更加开豁,学到更多设计精妙的设计思想。而加入小公司,你会被磨练成一个全栈工程师(有一定可能性),但是独当一面的能力会被锻炼出来。路还是得自己选。

公司的架构是一步一步的演化出来的,而程序猴子的技能也是一次又一次的实战的经验所得。

编程书籍推荐(请点击这里),如需留言请在公众号留言。

注:本文仅授权jinkey公众号和yubang简书,公众号shuidukou 发布