腐都两年小记

来源:互联网 发布:微信领取淘宝优惠券 编辑:程序博客网 时间:2024/06/06 17:10

虚度

2015年3月,我开始从学校踏入社会。

第一份工作是干游戏服务器的,但从开始工作到离职,这期间的八个月时间,竟是没写多少代码。在这里,不允许有尝试,不允许犯错,不管怎么做都是错的。我没有代码的任何权限,老板把认为关键的代码都清空后才给我的,最羞耻的是两个多月我都没彻底把代码逻辑看懂!对于一个对编程感兴趣的人来说,这样的日子,每天都是精神的折磨。回家后,躺在床上,动也不动,多想就这样一直躺下去。

每次想辞职,却又因为大学没毕业而忍了下来。坑爹的学校,这已经不是第一次坑我了,体育考试挂了,只能等到十月才能拿到毕业证。

但人总是要有些事情做的,于是我开始发展其他爱好,读诗诵词吹笛子,总之每天都是在虚度光阴,反正没有正经事要干。这时我想起14年去已经开始工作了的同学那时,看他点开浏览器,又关掉,再打开暴风,随便点点,再关了,再打开QQ看看……大抵每一个无所事事,虚度人生的人,都是如此吧。

九月,我开始意识到,我不可能永远就这样沉沦下去,也不会在这里呆太久了,于是开始浏览IT网站,如: CSDN等技术网站,为以后作准备。后来我发现,这些才是我一直想要的!作为程序员,不求留芳千古,也要不断提升自我,以求与上面这些理想中的大牛同台竞技。

等到十月底,学校终于给了通知,可以回学校拿毕业证了。十一月初,想是老板也早看出我在这没什么激情了。终于离开了这里,突然感觉身心轻快地像春归的燕子。第一件事,我便是回学校拿了毕业证。然后回家投简历,开始了面试的历程。

想必是在第一家公司表现不佳的阴影弥留心间,犹如一只蝼蚁面对世间万象时的彷徨不安感,在接下来的面试中我都表现的很谦逊。接下来的一星期里,没发现什么有意思的公司。第二星期时,在一家比较出名的游戏公司面试了一天多的时间,一直进入到第六面,基本没问题,在老板仔细看我的简历后,脸色一变,开始各种无厘头,最后莫名其妙的就没然后了。也是后来才知道,我的师兄得罪了他,怪到了我的头上,上家公司的老板也在那干过,后来出来创业了。

直到第二周周五,才得到了一家小型游戏公司的Offer,周一去上班。去了一段时间之后,发现这家公司时间很“充裕”,大家都很散漫。先是接手Python的后台,这次我对代码拥有绝对权限,我花了两星期的时间,把这套代码搞懂了,然后又花了一星期把代码部署逻辑简化了一下。组长看我很能解决问题,开始把他不想解决或解决不了的问题丢给我,我都一个个地解决了……

编程就是这样,不动手是永远学不会的。

接下来的日子过得很慢,像是北方的雪花,在空中随意飘荡着,慢慢落到地上,映着这个银色的世界,迎来了2016年的春天。

 

腐都

2016年正月初六,站在一辆长达25小时的火车,再次来到了腐都。我就像一盏将坏不坏的钨丝灯,强撑着最后一微米未断的钨丝,照亮这漆黑的夜,直到蹲在地上睡着……

看着仍旧沉浸在一片灯红酒绿中的腐都,我慢慢地穿行在熙熙攘攘的人流之中,像是刻入复古的时光机中。

今年将是如何?是否会重蹈去年的覆辙,还是最终离开?能否会有机会提升技术,还是终究要转行?谁都不知道未来我会面临什么,路途会是怎样,但我知道,我有一颗执著的心。(唉,为什么会被他人定义为固执呢,我只知道,我所坚持的,肯定是经思考后的结果)

为工作方便,我搬到了离公司更近的城南,在我搬过来的第二星期,大牛也来到了腐都,开始了工作历程。

 

继续

老板还要继续已经三岁高龄的游戏,同事陆续辞职,公司人员锐减(本来人也不多)。继主要员工走后,公司已举步维艰。尔后老板请了个任谁都不看好的外援老板,要重振旗鼓,把游戏进行到底。

客户端大神在走之前,花了一天的时间给隔壁外援交接了一下客户端逻辑。外援老板给了一个月时间熟悉代码,策划和服务器端可以先行。

组长一直不想让我接游戏服务器的代码,他说那对我没任何好处。从去年开始就只有他一个人在管着PHP的游戏服务器,我管着Python的后台服务器,和Pomelo的聊天服务器。估计看到这些名字,就能让人想到这是个多么不和谐的组合,不同语言间的库不能共用,相同的逻辑与组件都必须重复造轮子。而且Pomelo连他亲爹(网易)都不管他了,我们更是没有任何这方面的文档与资料可查,即使找到相关的,版本也早已经新的不适应了。

看来还是我们自己的客户端更给力些,不到一个月的时间已经看懂逻辑,可以开发了,隔壁的还在那绕弯呢,不过隔壁老板一直很袒护自己的员工。

 

变味

当服务器的哥产假回来,快刀斩乱麻的提了离职,然后开始给我交接,两三天交接完成后,给我写了个简单的文档,然后就去新公司任职了。

如果说之前我不明白为什么组长一直不让我接管游戏服务器代码,那么现在,我真明白了,看着那像坨屎山一样的代码,任谁也提不起兴趣来。

来吧,尽情地吐槽吧,不要顾虑。之前清华大学的高才生,把他之前做web的经历带到了游戏服上,用短连接搞实时的游戏服,想靠长polling吗?显然,作者就是让你猜不到,轮询!一个简单的玩家信息,不跳五六层别想知道里面具体干了点啥!如果只有这一个地方这样是样,忍了,但很明显,几乎所有的地方都这样,要死人了!所有的命名,一个地方一个样,就不能统一一下吗?命名不一致我也忍了,你能不能把名字写的人类能看懂?好吧,命名我也忍了,逻辑能不能一致点,没有任何通用的逻辑,完全像撞翻的上万辆车,没有任何姿态的翻滚着!而你想从火海中找到一具被挫骨扬灰的尸骨,做梦呢?

三年的历史堆积,沉淀,终于让这份代码几乎无法维护了,不,是一定无法维护了。在接下来的一个月里,我一边读代码,一边维护,一边开发,几乎我每天都在剧烈的头疼中度过,每夜因心悸而惊醒,看着窗外的黑幕,我该拿你怎么办啊,我的代码?

期间招来了一个十几年工作经验的老手,呆了十几天后实在看不下去,走了。隔壁老板又靠关系找了个程序员出身的老板来帮我一起分析代码,但来了两次,看了几次代码后,再也没出现过。

最后隔壁的老板说给我找个高手做帮手。后来还真来了个ThoughtWorks的高手,听说是隔壁老板之前的同事,还出过一本PHP的书。然后他下班后如果有时间,就会过来教我如何分析代码结构,整理已知信息,梳理已知代码,一起分析一些代码,对他真心的感谢,他对我的帮助真的非常大。但再高手也无法掩盖代码已经变味的事实,他有好几次都说最好的办法就是抛弃代码,但老板说要开发,他就只好尽可能帮我出些工作中常用的方法、技能及工具,来尽快完成工作。比如说画整体流程图,用编辑器PHPStorm,类关系分析工具(忘了名字了),面向对象思想等。

 

语言

由于现在只有我一个服务器(程序员)了,所有的服务器工作都要由我一个人完成。要通过跳板机部署PHP服务器代码,时不时写个bash脚本,Python后台也要跟进维护及新功能开发,Pomelo聊天服务器也要部署,还偶尔写个Go的小工具给PE用。

慢慢地,我发现语言的一些共通特性,比如说,PHP和Pomelo(nodejs)都是动态弱类型语言,但PHP与其他动态语言又不同,PHP是没有自己的虚拟机的,如Java有JVM,Python也有Python解释器可作为虚拟机用,只有PHP是没有“根”的动态语言;Python则是动态强类型语言,类型之间需要转换;动态语言一个变量的作用域大多以一个函数或方法为Scope的,而静态编译型语言则通常以定义处为作用域;动态语言一般对元编程支持的很好,编译型语言支持的很弱甚至大多是不支持的;弱类型语言也可以类型转换,只是看有没有需要,如C语言就是弱类型语言,任何类型之间都可以互相转换,只是看需要而定。

每门语言都是根据不同的需要被发明出来的,比如PHP就是发明用来开发Web的,那在PHP语言内就会广泛支持常见Web操作,比如说Json序列化与反序列化,而对于其他方面,要么以最小化支持,要么干脆不支持,如系统编程方面。

由此而引申出的面向对象,面向过程,函数式等不同的编程方式也是看需求而定。比如做服务器方向,以面向过程式编程为佳(很不幸,我们的这个PHP服务器是面向对象的);而做图形化界面时,很多基础信息是要相互继承的,这时以面向对象为佳。至于函数式编程,我只在学校里作为兴趣自学的Scheme上试过,很有趣,但没有实用过。

关于这方面,我买了一本《代码之髓》,对不同语言间的相似点,不同点,以及为什么会为某些特征,历史出现该语言的背影及要解决的问题,都进行了分析,使我对编程语言的了解更进一步。

 

转机

这期间,我每周末去图书馆,看完了一本《Modern PHP》。这本书虽是以PHP为例,但所讲的内容更多的是通用的,即便换了其他语言,基础思想理论是相通的,做法上是一致的。比如,没有最安全的加密方式,却有让你一百年算不出来的加密方式,像bcrypt类慢Hash,只要调整对应参数,可以保证超级计算机在一万年内无法暴力破解出来。缺点也一样明显,服务器撑不起太多并行的这种计算。

随着经验的积累,我最终发现,对于他人的代码,最好的理解方式就是沿着原作者的思路去理解。每个程序员对事物的理解都不会完全一致,尝试着以对方的眼光去看对方的代码,理解起来就会简单的多。

就这样,我竟然很快理解了一块已经腐朽的不成样子的代码。不要觉得腐朽的代码没思路,烂代码只是思路乱,写的随意,并不是没思路。扩而大之,整个游戏服这一大坨屎山的谜也开始慢慢被我解开了,接下来就是慢慢地细解每一小块逻辑了。

烂代码中又开始看到希望了!

为了不使接下来的代码再乱下去,我必须找到一种可控的方式阻止现状的扩散。于是,我找到了《编程格调》,但这本书,只用看目录就好了。该书提出了很多实用的防止代码变坏的建议和技巧,如“让编译器执行平凡优化”这条对于我们这类人(在学校时经常在代码层级优化以降低时间复杂度)就很贴切。

 

离去

四月中,HR走了,后来老板也走了,我们公司已经名存实亡了,而代码模块之多,之乱,也决计不是一时半会就可以解决完的,我也已经很久没有好好睡过觉了,每夜睡的都很轻,一点很轻的声音就可以把我惊醒。

既然如此,我觉得我没必要再继续呆在这了,走吧,怎么来的就怎么走吧,走吧,在这里已经看不到未来了,走吧,工资也发不起了,走吧,走吧……

我在接下来的两星期里,把服务器交接给隔壁的一哥们后,便义无反顾地走了。

 

破万

走了之后,只休息了一个周末,马上去了下家公司工作,也是家小型创业公司,但已经不是游戏公司,是家做Web的,用的是我第一份工作的Go语言。

来了之后一开始连电脑都没有,只有先凑合着用一台老机器,新机器要第二开才能到。于是把代码下下来先看着吧。

第二天下午电脑来了,原来也是个老机器,只不过是个性能要好些的电脑,不过没关系,凑合着用嘛。第三天老板开始给我分任务了,说在接下来的两星期里完成就好了。可是他没想到,我在前两天就已经把代码结构看懂了,包括前端后台的所有流程,只差一些细节的实现上。

第三天我先把任务完成了一半,一看时间,才下午四点左右,我没急着完成剩下的一半,而是仔细打量着这个创业公司:45楼,一个非常高的楼层,在我背后能把半个腐都尽收眼底,反衬着我所在空间的狭隘。中午吃饭像过山洞,只能一人能行,通道顶离头顶是那么近,有时真怕是要塌下来似的,到食堂折折绕绕。回来没有午休,不知他们哪来的精神可以这样长年累月的撑下来。

第四天我把剩下的任务完成,也只是下午三点半,我仔细地想了想,觉得还是不要再在这呆下去了,因为这里没有我想要的环境,和人。在这里,做技术的闭门造车,不做技术的任务就是玩,短时间里可以创造一些财富吧,但从长远来说,对个人发展一点好处都没有。打定主意了,准备给老板说了,但看老板一直忙来忙去,看来今天是没时间了。

第五天早上去了,看老板不是很忙,把任务交付上去,然后说出我要辞职,老板很通情达理,说只要我想好了,他不会留我,但如果以后工作不顺心了,可以随时回来。

短短的四天后,我又失业了,回家继续投简历吧。

赶在五一前,我面试了一家做游戏的公司,一轮面试下来,面试官非常满意。对我的评价是,工作年限为一年,工作经验为三年,让我回家等消息。但这里的情况并不是很好,长时间没有任务,老板是天使投资人,不差钱,所以这里的人有产品也好,没产品也罢,反正是饿不死的,说白了就是来养老是再好不过。

现在的公司要求都好高,动不动就三年工作经验,硕士学位,对于我们这些小二本出来才一年,或还不够一年的人来说,简直就不可能找的到工作了。不过管那么多,先投了再说。

五一后两天,终于等到了一家公司的面试,进入公司后给我感觉很棒,环境很健康阳光,看上去很年轻、积极、向上。面试官看我只有一年的工作年限,就说出点智力题吧,就不面技术了。当场就懵了,结果很差劲,我智商真的很差吗?一道题都没答出来。看我这么菜,没办法,还是面技术吧。不知不觉面到了中午饭时间,面试官说我通过了他这关,评价和上面类似,工作年限只有一年,可工作经验已经有三年了。

在第二天的老板面试中,也没问什么关键性的问题,让回来等消息。呵呵,又是回来等消息。我问,什么时候可以给结果,一星期以内。结果二面完后的第二天,HR给我打来电话,问我自己意向,没问题就发Offer了,如果没问题,尽早来上班。最后给我开的工资是1XXXX(公司要求保密),这是在工作了一年后,终于工作上五位数了,总算是不用太节约着花钱了。

 

微服

上班的第一件事总是一样的,熟悉代码,熟悉业务。

可这次我遇到的代码与之前的已经大想径亭了,之前代码都是一个巨无霸,可这次的代码却是相似又不同的小个头。业界把这种服务架构叫做“微服务架构”,由一组小服务组成所有后台服务。不同的小服务以分布式相关联,最后统一由一个出口供客户端调用。

微服务的好处很明显,随意拓展分布,服务轻量,职责单一,容易重构甚至重写。不足之处也很明显,服务多了,管理成本增加,附加子程序也在增加,网络调用链、时间消耗明显在加长。

不同的还有服务器,之前用的服务器都是Ubuntu系统,而这次用的是CentOS系统,不过好在linux系统的环境对个人用户来说都不会差太多。

同上面一样,来了之后两天的时间熟悉了业务代码逻辑,结构等,并开始从游戏服到Web服的思路转换,从巨无霸到微服务的思维转换。

 

搜索

第一个要做的任务并不是改代码以适用新业务,而是新写一个微服务提供搜索的功能,并且做一个从RPC到HTTP的尝试。组长也很体贴,先把之前另外一个组的代码先给我作为参考。

整体逻辑上也不是很复杂,把信息存入ElasticSearch外部组件,再通过HTTP查询出来,不需要自己来做搜索过程。之前做游戏服时,几乎所有的事情都是由自己的代码完成的,外部组件除了数据库作为落地之外,是不用任何外部组件的,包括框架。

用成熟的外部组件可以避免自己写的代码中难免有Bug,以及对于效率的考虑。另外,这也是微服务的思想之一,让适合的服务做适合的事,不必让一个程序事无巨细,事必躬亲。让适合的程序做它擅长的事,利用现有组件解决已知问题,充分解放人力成本,人的时间才是成本最高的,没必要重复造轮子,而且造出来也不一定比原来的好,这是网络快速发展过程中形成的必然选择结果。

 

苹果

接下来的日子就开始做各种需求了,好消息就是公司终于有苹果电脑可以换了。

MacOS可谓是同时兼具Windows的界面和类Unix的环境了。以前用Windows工作时总要在虚拟机里开Linux,在Windows上运行图形化界面,用Vim操作Linux上的文件。现在我可以在MacOS上用图形化界面的IDE了。花了一天左右的时间熟悉了MacOS后,深深的喜欢上用它了。

对于平时自己练习时,用不装太多插件的Vim确实是不错的,近乎白板编程,可是对于工作,快速开发迭代过程中,用IDE加快编程速度是个非常明智的选择。为什么这样说,工作开发过程绝对不是让你来练习打字的,不管用什么编辑器,以快为主,以效率优先!即分清主次,踩住重心,不要去为那无聊的编辑器、环境之争分心,一切以方便开发为主,为重。

 

重构

后台终于决定要把之前Python版本的消息系统重构了,于是组长叫我快点搞完手头的需求,和他一起重构。

当我拿到代码时,那是全Python版本的消息网关,而我们要把它重构成Go语言版本。第二天早上组长问我看的怎么样了(Python版),我苦笑着说,“你也要给我点时间让我看呀!”我是第一天下午接近下班才拿到的代码,等到第二天下午的时候,花了不到一天的时间,把消息网关的整体结构和逻辑看懂了,基本可以动工了。

动态类型一时爽,代码重构火葬场。在Python代码中是没有变量的类型的,若不把逻辑看懂,很多时候都不知道变量里存的是什么东西。

在Python中,字符串和数字之间的转换是很容易的,但同样的事情在Go里面就有些麻烦了,同样的还有很多结构都存在着相同或相似的问题,甚至有些是结构还是数组都不明确。为解决这个问题,我仔细翻看着api文档,也就在这里,我彻底会用Go中的接口了,用接口,完美地解决了数据间的兼容问题。

服务器最要紧的是啥?稳定!稳定压倒一切!为什么Java会长期占据编程语言的榜首?就是因为Java的稳定。Java是动态语言不假,但它是强类型语言,每一个变量的类型,作用域非常明确,除去废话多这一我窃以为的缺点,本质上来说,Java是非常优秀的。

另外我认为Go语言是非常有发展前途的,Go是一门实战类语言,并非学院派语言(利于教学)。同Java一样,Go也是强类型语言,同样的方便跨平台。与Java不同的是,Java编译成字节码中间文件,Go是直接编译成二进制文件;Java完全面向对象,Go面向过程,鸭子模型。不过我个人更喜欢Go那极其精简的语法和方便的交叉编译。

 

消息

Go里面最出名的两个接口莫过于io.Reader和io.Writer了,由此联想C++里面的cout<<和cin>>操作,Java里的各种数据流,可以得出一种在编程里常用的思想——流操作。

当时,我要在Windows和MacOS之间传输大文件,用U盘拷有点麻烦,用QQ会有网速限制(虽是在同一局域网,但MacOS下的QQ却是去远程拉的数据,速度大概只能到几百K),搭一个FTP什么的服务器又太重没必要。最后我打算用一下流思想:首先确定用C/S架构,客户端负责文件流到网络流,服务端相反,网络流到文件流,很简单的一个局域网文件传输程序出炉了!

不久,我们组也需要一个消息网关了,我们决定不用其他组的网络组件,用最基本的,也就是不容易出错的简单协议实现。我在协议设计时将传输层网络流引入到表示层数据流,再由数据流引入到应用层协议解析流,最后得到的协议经处理后再以相反的流输出到客户端。整个过程没有任何拖泥带水,全部用标准库就可以实现,保证了协议的可靠性。

流是编程中很重要,很有价值的一种思想,它是一种可以无限扩展,无限小到无限大的一种非结构数据。常见的流数据有:文件,网络,通道等,常见的应用场景有:(解)压缩,(反)序列化,加密解密,扫描,图像,视频,协议等。流更像是编程语言中的泛型,平时不用管它是什么,用它时可以解析为任何结构,极大地降低了程序员的心智负担与编程难度。

 

女票

忘了之前谁说过,当你不需要女票时,你就可以拥有女票了。

我买了几本书,《人月神话》、《编程人生》等,正打算好好研习一下前人的智慧,增长自己的见识时。与她的一句玩笑话,使我脱单了……

其实不管是之前,还是后来想想,那段时间确实是最不需要女票的时候,我有很多书要看,我有很多程序要写。可是这让我信了上面那句话。

 

止步

程序员一般都非常专注,自从学了编程以来,我也经常很专注地做一件事。

可是最近我发现,我不是不专注,而是没有足够的时间去专注了,晚上回来的时间本来就不多,除去洗漱的时间,剩下的时间还要劈情操,很少有时间专注地看书和写程序了。不过我也不在意,因为在我的观念里,人才是第一位的。

业精于勤荒于嬉,这段时间虽不至于倒退,专业技能却也止步不前了,想想也对,如果吃饭喝水也能提高自己,那每个人都是圣人了。

终究还是我个人太逗逼了,失去了她……

 

帝都

大牛最近很抑郁,因为他是今年才出来找工作的,第一份工作不适合,第二份工作因种种原因辞职了,在这个看工作经验的社会,后来竟是没找到工作。他决定去帝都培训,然后明年在帝都工作。毕竟帝都市场更大,对人才的需求也更大,相信他在那里会闯出一片蓝天的。

十月底,在他离去的那天,我上午请假,去火车站送他。我们交流了很多,腐都的整体技术氛围,对技术的追求与发展,放眼未来的计划与实践,个人的不足与改进,人生的趣味与无奈等等。

并不是每个做技术的人都可以和另一个做技术的聊的来技术,对技术没有看法,心不在技术上的人,怎么能奢望与他探讨技术。

相信在帝都这样一个充满着无限可能与挑战的环境中,大牛一定会飞起来,成为大神。而我自己也一直在期待着到帝都那种各路牛人风云际会的大环境中试练一番,不是为了在技术上一定有什么突破,只为了见识见识这个天堂与地狱共存的大熔炉。

在一本西方玄幻类小说《盘龙》中有这么一段,有人问主角,“假如你修炼亿万年,再也无法进步了,会不会放弃分身,见识一番巅峰强者聚集的战场?”“会!”

 

三层

最近我为公司写了一些底层代码,基础架构,和一些被定义为难以实现或无法实现的东西。

走在河边,我又开始思考起了高中时一直没想明白的一件事。每当我觉得有所进步时,都会去想,试图想明白,可是一直没想明白过。

在高中,一开始解题时,都会正推题目得到解;后来,发现有些题目会很难正推过去,于是有一种思路叫逆推;我从化学身上学到了它俩的结合:正推一部分,逆推一部分,再跳跃一下,从中间逆推一步分和前面正推的接上头,正推一部分和前面的逆推接头;再发展为不断正推,逆推,正推,逆推的一种犹如抽丝剥茧的方式;到高二时,发展为一种直截了当地解决问题;在一次体育课上由一种军棋游戏启发得到的类似韩信点兵,“多多益善”的方式。

靠这些不断发展想法,一直可以在班里名列前茅,可是最后这些想法统统消失不见,不可再见,找不到,想不透。

今天有幸可以想清楚了。可以分三个层次去想这个问题,底层为细节实现,中间为经验导向,上层为全局把控。当要开展一个项目时,需要全局把控力来决定系统的整体形态,经验导向决定下面每个模块要解决的问题,细节实现最后把大大小小的问题变成现实。

我们在学校里有这样一个群体,整天研究数据结构和算法,算法在这里可以为细节实现打下坚实的基础。如果知道某些东西是可实现的,那么经验导向就会更大胆,经验导向能确定的面越大,全局把控就可以把控更广阔的局面。整个体系是可以不断扩大的,以最底层为基,建立更高的大厦。

这里需要纠正一个观点:不要单纯地为了学习算法而学习算法,算法是一种开阔思路,增强解决实际问题能力的东西。任何不能实用,不能解决实际问题的算法都是流氓算法,这里的实际问题不是各种智力题,而是自己生活中要面对的问题。为什么有些算法楼教主可以学可以用,而我们却没必要学,这就需要对自己所处的现实层次有比较精准的把握,可以有想法,有梦想,也要有自知之明。

正推是最基础的方式,逆推是在对细节有了一定程度的深入后的方式,中间插入是已经稍微有些经验导向了,能直截了当地解决问题说明已经有相当程度的经验了,多多益善是可初窥全局的方式。可悲的是,我当初太过于在意这之上是什么,从而荒废了对细节实现的重视,导致整座大厦的坍塌。

前人早就意识到了这一点,提出刻意练习及跳出安逸圈的办法,以保持底层的安稳,上层的稳定。后来,在有机会的时候,我都会尽量刻意地练习已经会的,同时反思。挑战一些不熟练,但可以实现的领域,不断扩大安逸圈。

 

精力

想清楚这些后,我们就会发现和靠努力拼上去社会精英还是有一拼之力的,因为我们之间没有太多的智力差距(天才另算,他们有些高智商甚至可以碾压这些,世界也因这些不公平才有趣,不是吗)。我们可以用减少底层建设的时间来拉近与他们的距离。

想必大家也知道名校名导师的作用了,一个好的导师对基础的教学可以涉及到方方面面,不用学生自己去收集与发现细节实现;还会在基础的层次上引入经验导向,让学生从起点高于我们。我们对于资源、细节及经验的缺失,在他们的眼里只是常识。

那办法是什么呢?标准,以标准要求自己。放弃乱搞一通,漫无目的的学习和实践,那只是在浪费时间,浪费精力。没有好的导师,那标准就是我们最好的导师,不管有没有全部了解了细节,先保证可以应对现实,下来闲暇的时光可以继续研究,理解,相信总有一次是可以豁然开朗的。

关于这个最好的一个例子就是用标准库,看标准库是怎么实现的,哪些点是自己没想到的,哪些点是业界标准,哪些点是可以学习的等。多看标准及实现,对个人技术发展及各种标准的理解都大有裨益。比如,path/filepath包,对于文件路径及扩展名等进行了实现,看源码可以了解关于文件路径的一些标准叫法,及标准实现,我们自己的实现过程中有哪些误解,还有更深入地学习了对于文件路径的操作等。

 

标准

标准是前人留下来宝贵的东西,里面包含了应有的细节实现和经验导向。学习标准,并应用它是在实践中理解它的细节和经验,这样做既保证了工作的正确性,又加速了自己的成长速度。所有不同想法和创新的请在不影响他人,不影响工作的前提下实验,反证也是加快理解的途径之一。

在Go语言标准库中,对于业界的问题,一般都是以标准为基本的实现。一次偶然的情况,我们发现,客户端上传的图片下载下来后会转向,在分析源码和图片编码标准进行对比后发现,Go标准库只把标准图片编码过程实现了,对于非标准,但业内约定俗成的东西没有实现。这样做是有一定好处的,标准的都一样,非标准的每家不一定相同,那是用户的“责任”(下面会讲到)去实现自己的标准。我们只需要花精力对我们用的图片标准进行编码,以修正了图片转向的问题。

最近,后台组开了一个标准组,人数很少,负责制定后台代码、环境、架构等方面的标准,很荣幸我也是其中一员(应该是组长推荐)。

我负责语言方面的技巧和坑,借此机会,我把语言中不常用的和不推荐的用法也都尝试了一下,力图写出有价值的文档。比如不推荐用的unsafe包,让人困惑的nil interface和interface nil问题。

就我个人而言,我是非常赞成制定标准的,上到架构设计的标准,下到编码的标准,都需要一个执行的标准。如果对于公共架构到代码没有一个统一的标准,就会发生像之前公司的那种腐朽的无法维护的项目。反过来,如果一切都有统一的规范和标准,在看整体架构时会有一种一气呵成的顺畅感,在看代码实现时,不看作者是不能分出代码是由谁写的,在交流时不会出现太多理解上的难度,大大降低了交流的成本。

 

分享

当大家都准备的差不多后,leader觉得可以给大家公开宣讲了,便把大家召集起来,来了次大宣讲,每个标准组成员把自己负责部分的标准给大家讲了出来,以及以后如何执行的问题。

当我给大家宣讲的时候,听到几个低声的“卧槽,还能这么玩”和“TMD,原来是这样,坑好多”。我们这很多都是名企或名校出来的高才生,当我听到这句话时,我知道,我已经慢慢拉近因资源、时间不对称所产生的距离了。

我很喜欢跟大牛、帅师兄交流,他们都是很坦率,对技术有自己见解的人,更主要的是,他们不会故意隐藏什么。这是中国人的一个惯病,什么事留一手,但从技术上来说,藏着掖着并没什么好处,你所以为对的思想或技术,在其他人眼里可能就是错的、过时的,而且,每个人对技术的理解是有差别的,对别人叙述,对方很可能从其他角度审视你的见解,帮你更加完善自己技术,或者提出你之前没想到的问题,引起你的深思。还有就是,叙述本身也是整理、描述自己技术的一种方式,在描述的过程中,你本身也有可能激发新的想法,自我完善。

 

责任

这一星期,我每天晚上回来写代码,自己实现一个代码评测库。

当我在Mac上写完后,一切运行的非常完美,因为Mac本身也是Linux的一种,所以完美兼容Linux系统,就在周五晚上,我准备让它兼容Windows,于是我把系统相关的代码写了份Windows版的。当运行起来时,一切都那么的融洽,可是运行时间长了之后,发现CPU暴涨到了100%,这可不是一件好事。我反复查看Windows系统编程相关的部分,API调用没问题,实在查不出来,已经很晚了,先睡觉吧。星期六有些事情要做,没顾的上理它。

星期日早上,迷迷糊糊地想到了一种可能性:当进程不存在时,Windows API并没有返回应有的错误!马上翻身起床,改进了调用的地方,测试,Perfect!解决!

这时,想到了Go源码中经常见到的一句注释:“It is the caller's responsibility to dosomething.”再联想最近一直在看的《程序设计实践》,很快理解了一个很重要的词:“责任”。单一职责原则不只是宏观上的原则,包括其他的五项原则,它们的适用范围应该是上到架构,下到函数间调用的存在,在编程时如果不注意这些,迟早是要出问题的。对于这些隐患一定要在写程序之前就有所预防,以防为后来埋坑。

 

异地

第二周,我们小组要做异地多活,组长问我有什么想法。

我说,“异地最大的问题就是数据间的同步问题,对于我们现在程序与数据分离的服务器来说,比巨无霸服要容易实现的多。”“什么是程序与数据分离?”“就是程序不占有数据,只负责处理逻辑,数据由专门的内存或关系数据库存储。这样可以很方便的实现水平扩展和分布式。”“哦,继续。”“既然不能百分百保证数据间同步,就一定要做好数据处理者的责任划分,多段代码同时处理相同的数据肯定要出错;可重入的接口可以有重试,不可重入的错误抛回,比如拉取数据,这种简单逻辑,允许错误重试;创建过程我们需要完整的数据返回,但不能影响给客户端的接口格式,所以我们需要处理好格式的转换;对于第一期,不需要做异地的统统抛给远端。暂时想到这么多,你比较熟悉内存数据库,你给出一个统一的缓存规则吧。”“嗯,还有在数据未完成同步期间,要保证本地数据的拉取正常,注意数据的merge。那你把架子先搭起来吧!”“我咧~”

有了这些基本原则,接下来的事情就要简单的多了,我们俩花了一星期的时间完成了第一期异地多活方案的实现,开始进入测试阶段。整体来看,基本上没什么问题。

在这个过程中,大量的地方需要防御,也就是大量的需要防御式编程。所谓防御式编程就是假设一切有可能出错的地方都要防御,前人已经总结过:一切可能出错的地方最终都会出错。做法很简单,就是所有不符合程序的输入与输出都要进行检查,只有符合程序运行标准或可兼容的数据才能正常运行,否则及早抛出错误。这里要遵循一个原则:宽进严出,对输入的数据放宽条件,尽可能的兼容,对输出的数据格式进行严格的统一,方便外部调用者使用。

 

定时

这次终究还是躲不掉了,我们需要一个定时服务来跑一些定时的,预期的行为。即使这次躲过去了,明年来了也肯定是要加的。听说其他小组的童鞋已经有一套很完善的实现了,我们想还是不要重复造轮子了,拿来主义吧。

第一个问题就很严重,我们组的服务器和他们的服务器隔着伟大的GreatWall,不太可能相互调用了,所以我们需要自己部署一套了,我向那哥们要代码,看看能不能满足我们的业务需求,结果那哥们声称代码由他自己管理,不想多个人共同开发他的这一套代码。最后还是要请组长的面子去跟他要过代码来。唉,人生真是失败啊。

这次就很快了,我花了不到两小时的时间就把这套代码的逻辑走向和我们要改的地方及改的方案确定下来了。想想还是不要改了,交给那哥们自己去改吧,我还省心了呢,呵呵。

其实这也是大组内的原则之一,大家尽量用同一套问题处理方案,不要每个小组各自开小灶,这是为了实现组内组件的统一,如果有什么优化或修正,不用强动员每个小组都去修改,只需要给大家讲解一下优化或修正的必要性或好处。

 

明年

我想明年一定要开始看大牛给我推荐了很多次的《Modern Operating Systems》了,大牛说,现在计算机行业发展很快,但最基础的思想还是上世纪的,学习这些思想对你很有帮助。这里预祝大牛在帝都飞黄腾达,苟富贵,莫相忘,哈哈哈哈……

《三体》之中有句名言:“真正进入太空的人,再也不是人。”当我们进入计算机科学领域时,就再不是之前的我们了。我们必须不断完善自己,学习新的知识,前人的经验。

程序员问科比:“科比,你为何如此成功?” 科比反问:“你知道洛杉矶每天凌晨4点的样子吗?” 程序员:“知道,那个时候我一般还没下班。你问这个干嘛?” 科比:“不干嘛,草!” 谈话结束。

或许是因为薪资的原因,诚如《围城》中说的那样:“城中的人想出去,城外的人想冲进来。”很多人放弃原来的行业,纷纷转来搞IT。但从事IT多年后,又有很多人不堪重负,要么进升管理层,要么转行进入其他行业。总之这是一个快速迭代的行业,快速迭代的技术,快速迭代的人。

从事IT行业,本身就是体验这个世界的一种快速模型,这个模型里融合了人类历史的发展历程,各种思想、哲学、经验,看待事物角度等方方面面。这个模型不需要上万年的演化,随着个人工作中的不断深入研究与思考,我们会在短时间内(依人而定,与个人的领悟能力相关,短则几年,长则永生)吸收前人的智慧结晶,并反过来作用于现实,也许有一天,IT行业不止是技术上的先驱,也会成为人类思想哲学的前沿,引领着世界走向更加美好!

这里说明了一个问题,计算机是一门实践的科学,对于我们不搞理论计算机科学的人来说,动手实践是快速前进最好的办法,没有之一。

说了这么多,明年应该干嘛呢?我的回答是,不知道!在这个快速发展与变化的时代,窃以为,我们应该常立志,而不是立长志,时常保持动态变化,不断调整个人的方向,以适应这个浮夸的社会…… 

1 0
原创粉丝点击