bookmark_border意识流工作感想

一直在想要把工作的感想给整理一下。看到这篇文章里写的效率低的开发团队的几个特点/分类,我们公司的膝盖已经戳烂了。(看到“保姆式开发”几乎从不说脏话的我嘴里迸出了卧槽二字。)

工作感想还没整理。现在意识流一篇帮助自己整理。。。

我并不是很想做开发。在逻辑思维方面我比较迟钝。做开发的话我的优点是愿意尝试和不assuming(简直paranoid)。只要有文档和尝试的环境,搞各种script我是没有问题的。我另外的长处是对BI数据库比较有经验。我对Application比较没经验。我们公司的BI产品,还有一部分是application的成分(客户使用界面),想想我在现在公司的5年,最大的收获大概是瞥见一眼application开发,我们公司的开发水准很烂,但看到开头提的那篇文章之后我想我也是得到了一些关于烂的思考。

我喜欢捣鼓script,我更喜欢借用我会技术又会沟通的能力,做一些桥梁工作。工作这么多年来,我见过的人里面,除了极少数人,沟通和技术结合没有我比我强的。当然比我会说话的人多了去了,然而我认为实质的沟通的基础是你要懂你沟通的东西。我也和销售打过交道,有的销售是非常有魅力的人,然而他只负责散发魅力,说实质的东西的时候必须站在他的角度才能沟通。懂数据,懂技术的人,能像我一样沟通的人很少。That said,我加入现在公司的初衷是做这样的桥梁。我加入的是operation部门。我们的operation部门不仅给产品上线、monitor它们的运作,还要保证数据的质量并处理各种客户的咨询。由于我擅长看数据和写脚本,我加入不久就写了一系列脚本帮助monitor我们当时几百个instance(如今已经超过一千个了)。这里对我的技术是有提高的,在之前我只写过ETL的SQL和简单的shell script,连个DB store procedure都没见过。但这家公司的ETL是基于SQL Server的DB SP的,我一边理解产品,一边写出了那些脚本。开发中有些愿意讨论问题的,我也有时候找他们请教。Operation部门工作了两年,我意识到我们产品的问题这么多,其实需要的是开发质量提高。中国办公室的开发老大愿意让我去开发部门继续做更深的技术支持,我就答应了。因为在operation做得再好,也是我已经做了两年的事情了,做得好不再值得骄傲。当时在我看来开发部门有很多事情我可以帮助做好的。比如,开发部门的沟通太烂;大部分开发查数据的技能比我差;大部分开发互相之间都在鸡同鸭讲更不要说和别的部门讲了;大部分开发都不知道operation是怎么deploy和monitor我们的产品的,也不知道客户一般都喜欢干什么。

到了开发部门,我的第一件事是理解release流程。我很惊讶地发现,给定一个特定的时间,在产品环境的某个版本发现了问题,给开发开CR去修复的时候,修复哪些版本这个问题是没有定论的。每一次开CR都需要问release manager,而得到的答复也没有确定的准则。在开头引用的那篇文章里,对此有精确的描述:

配置管理上的问题。对于源代码的配置管理,其实并不是一件简单的事情。配置管理和软件和团队的组构的结构非常有关系。我看到过两种非常没有效率的配置管理,一种是以开项目分支的方式来做项目,同时开很多分支,分支开的时间还很长,导致merge回主干要花大量的时间去解决各种冲突,另一种是N多的团队都在一个代码库中做修改,导致出现很多复杂的问题,比如某团队的改动出现了一个bug,要么所有的团队的功能都得等这个bug被修复才能被发布,要么就是把所有的改动回滚到上一个版本,包括其它团队开发的功能。很明显,软件模块的结构,软件的架构,以及团队的组织形式都会严重影响开发效率。

我们的情况是上面说的很多module在一个库,一个bug会导致所有的无法上线。我们情况的区别是,我们的产品环境压根从来没有回滚上一个版本的功能。很长一段时间我不理解release management对QA提供ETA的要求。ETA方便给客户期待,然而我找QA问ETA的时候经常得到的答复是这样的:如果开发下周二之前把修改提交,那么我们的ETA就是周五。然后周五的ETA就被宣布了。根本不给“开发如果没有来得及修改提交”或者“提交后又测出bug”留余地。

当年我们还有一个非常低级的问题:我们的产品有一个版本号,在部署的server上,代码存在这个版本号为名字的路径下。后来bug越来越多我们变成两周更新一次release,但是版本号不变,这就造成如果不具体看代码你无法知道你面前的版本X是不是最新的版本X。对于DEV和QA来说,只要改好了代码,测试通过,他们就任务完成了——我们deliver了一个修改好的版本X。当时出了一系列问题都是宣布release了但实际上并没有更新到deploy server上。因为DEV和运维之间当时几乎一直在鸡同鸭讲。后来终于认识到需要更新到server上之后,还有很多问题。有些bug需要更新代码后重新deploy,有些bug只要更新代码就好,还有些bug重新deploy后还需要跑一些一次性的脚本。谁来跑脚本这件事一直没定下来。理论上让开发去产品环境deploy是很糟的。但OPS的技术能力有限,让他们跑命令行也经常很危险。还有的时候跑了一次性脚本之后代码没更新,下一次deploy问题又回来了。作为战斗在第一线处理产品问题的我,这样的事情见得太多了,我经常跟老板反应,但是总是‘解决问题更重要’,解决了以后大家就舒一口气又去忙各自的了。

那篇文章里的“保姆式”开发和我们的现状最像。

所谓“保姆式”软件开发就是——我只管吃饭,不管做菜洗碗,就像——衣来伸手,饭来张口的“小皇帝”一样,身边有一堆太监或宫女,不然生活不能自理。这种情况经常见于开发和测试,开发和运维间的关系。很多公司,测试和运维都成了开发的保姆。

我就能看到,很多开发快速写完代码后基本上都不怎么测试就交给QA去测试了,QA一测,我草,各种问题,而只会做黑盒的QA并不能马上就能确定是代码的问题还是环境的问题,所以还要花大量时间排除不是环境问题,才给开发报BUG。很多问题,可能只需要做个Code Review,做个单测就可以发现了,硬要交给QA。运维也是一样的,开发出来的软件根本就没有考虑什么运维的东西,因为有运维人员,所以我才不考虑呢。

我们公司的产品deploy一个的代价非常大,有几百个参数,好多机器需要权限。deploy过程中如果遇到错,需要各种技术能力来分析解决:DB的,java的等等。所以我经常看见开发问QA要环境进行开发。产品环境经常遇到的问题是,你改了一个代码解决了你的问题,但是这个代码在deploy别的类型的instance之后会有问题。当年我做开发的时候非常paranoid(当然因为我技术基础差),我一定要把我想到的所有情况都跑一遍才放心。我们的开发经常会说:“这个改好了让QA去跑一下吧。”,或者在你问他“XXX在YYY的情况会不会有问题”的时候经常得到的答复是,让QA去试试吧。

文章中说的watchdog式开发,我们也是很多。

什么是WatchDog?就是说——为了解决某个系统的问题,我要用一个新的系统去看着它

  • 我的系统架构太复杂,出了问题不好查找。咋办?那就搞个专门的特殊的监控系统吧……
  • 我的系统配置太复杂,容易配错了。咋办?那就加一个配置校验系统吧……
  • 我的系统配置和真实的情况有时候可能会不一性。咋办?那就加一个巡检系统吧……
  • 我的系统测试环境和线上环境有时候会搞混了。咋办?那就为线上环境加一个权限控制系统吧……
  • 我的系统有单点,那就加个负载均衡器吧,负载均衡器的单点呢?那就再加个等价路由器吧……

因为我们的系统很难从整体来把握。整个公司大概只有三个开发能从架构角度了解全局。而其中最重要的一个人,是个asshole。整个公司的人,素质好一些的都在尽力和他合作,素质差一些的整天在骂他。所有人都对他多多少少有点无奈。我曾经被他说哭过好几次。其中有时候的确是我的理解有误,如果我被直接告知我哪里错了,一般我会看我的错误并且觉得很羞愧。但是这个人指出错误的时候从来不说清楚,而且带着很挑衅的不客气语气,说着读不通的英语(印度人的英语其实是很好的,但是他一直散发着一种“我不care发表清楚的沟通”的气场)。

所以呢,开头说了,我来公司的第一件事就是写了个monitor系统,也算是watchdog的一部分,不过这是在产品之外的。我觉得很多真的产品开发,也是对他的整体设计不得要领无法写出integrate到整个产品的好东西,而是尽力保护自己开发的部分,即使冗余也不敢信赖已有的东西。我曾经听一个已经离职的开发经理说过,那个架构师的代码,即使他们看到有可以优化的地方,他们一般也不敢提建议。

虽然我并不下决心想做开发,但是看看coolshell博客,简直觉得振奋。也许我对技术的热情也是有点“希望保持业余兴趣”那样。按照引用的这篇文章,我并不是个合格的开发。我会的技术太少。专攻技术的问题在我们公司的开发中也很突出,甚至明明都是ETL的东西,A开发的东西B就觉得自己没必要去了解。更不要说大部分BI开发不懂java的部分,而绝大部分java开发的SQL水平在我看来简直小儿科。在这个工作中,我也试练了我的学习能力。写SP对我很容易(来自SQL和shell背景);查询MDX对我来说有点难:我按照MSDN上的教程自建了一个cube(当时我要就建cube的权限问题问了一个当时我们的cube专家,他都并不知道根本逻辑,只是建议我都用admin账号)、读了MDX Solutions的前几章;另外学会的是powershell。Powershell我不能完全说学会了,没有官方教程和完整的说明书(MSDN的结构太恶心了,PS的manual是和.NET的混合的),我看了powershell.net上的一个非官方教程,对变量、control flow、function、object等等理解了。但是后来看代码的时候还是看到了我本来不知道的东西。微软的环境很封闭,文档很难懂,依赖微软产品的我们公司应该也是直接间接受了影响。不过PS似乎代表了微软的进步(终于有比较成熟的script语言了)。最近又写了一点点python的脚本。

我愿意学习,也希望在厉害的开发环境工作。然而我更大的能力是沟通和英语水平。我这个没有计算机知识基础的人进入这个行业有一定的巧合,也一部分是因为这个行业发展快,还需要人手。看看我能找到什么机会吧。

bookmark_border这两天工作上发生了一件事,让我很难平静

这两天工作上发生了一件事,让我很难平静。

过年前最后一天(我买了五点半的电影票打算早走的,我知道过年前是最后能刷R1的时候)。下午三点的时候发现来了一个High priority的ticket,是一个中国cube的ETL挂在cube process上了,是比较基本的问题。我就先开了profiler看process的错误。很快发现是process measure group P的时候报了个numeric overflow bigint的错。然后我就想办法在那个partition找哪个数据的值超长了。看了一下P的view的定义,只看到一个column是bigint,再仔细一看这个column的定义,我记起来别的cube的这个column曾经也出过一样的错。这个column的设计本来就有点奇怪,把store_key, item_key和一个measure X的值concat起来(当中有2个0间隔)再转bigint。按照我们系统目前的store_key, item_key的位数来看,measure X只要超过两位数就会overflow。然而当时PM说,这个measure只能是0到5六个值。估计是开发看了这个需求,也没想过可能需要处理超长的效果。(去年11月的时候我第一次遇到这个问题时,我的第一反应是把这个问题给DEV,因为这样危险的设计在我看来很可怕。在和QA确认的时候才得知还有限制0到5这回事。)

当时我急着赶电影,我就回复了一下:“这和ticket XXX是一样的问题。X数据只能是0到5。可是现在我们有42002这么大的数据。请检查一下是不是又重复load了文件。我已经关闭了这个silo的ETL。”这一句重复的文件的猜测,是因为去年我检查这个问题的时候,时间比较充裕,就顺便检查了一下数据源的历史记录,发现了重复的文件。实际上,这一次不一定是同样的原因造成数据过大。然而我想,是个operation(他们天天看数据,天天set up文件load)都会明白,接下来就该是他们去修复数据了。

春节值班的时候,我特意留意了一下这个ticket,我惊讶地发现他们没有更新。我猜是因为没人看见我说我关了ETL,所以它没有继续报错,所以没人注意到这件事。于是我把ETL又开了。(我们的产品环境就是这么混乱。)

隔了几天我又值班,发现operation看到了这个ticket,然而第一个回复是(一个脑子比较僵硬的中国男operation):“我没有看到有重复文件,所以根XXX应该不是一样的问题,请再看看为什么cube process挂。”在我之前值班的开发同学M回复说:“为了跑过去,我已经从DB里删了数据,并且把删的数据存在了table_name_bak里。”这里的table_name是我们基本的measure group A。接下来,是operation老大吩咐美国的operation把坏的数据用正确的方法unload掉。

年后上班这个ticket仍没有解决,并且变成了urgent回到我头上,而问题还是原来那一个。不过加上了最近有过attribute变动,变成如果要process,是把所有partition都要process才能过去。这个cube属于之前中国特殊数据load,为了缩短上线时间,他们把这个retailer的数据全都做了redundant load,实际客户看到的数据只有我们load的数据的十分之一都不到,所以full process很慢。负责monitor新数据load的operation女生不知道这些,因为是周一ETL总体很忙,她无法在数据源unload数据。于是她一个劲催我也删一下数据嘛。

我的各种本能都告诉我不该在产品环境删数据。以前我的经理是BI开发的经理,如果他在我会跟他聊几句,肯定会避免发生接下来的事情。现在我的经理是APP开发经理,他的BI经验其实不多,我就没想跟他聊(实际上他虽然看所有的urgent ticket,但也并没有明白我实际上后来犯了个错)。

事实就是,我知道这是numeric overflow;我知道>5的数据都不对(进了cube也会因为dimension没有而不显示),虽然如果是8这样的值还不会造成overflow报错;operation一直在跟我强调过年值班的开发M同学删了数据后面就process进去了。“你看他那时回复的呀!”我有一种如果我不删数据,我就没有M同学有能力的压力。(实际上,M也是有技术但没有产品sense的人,在BI的方面,经验也是比我差一截。然而他是开发我是产品技术支持,而且他是男生,男生的无知自信对技术和产品sense差一些的人来说,就等于强大,不幸的是我们公司都是这样的人。)我还有一半的思绪在想如果要对这么大的表删数据,性能会不会很可怕。

结果我就按照M说的,把measure group A的不合法数据删了。

接下来是7小时的full process。

昨天早上上班的时候,我看到晚上的process挂了。我幡然醒悟:造成overflow的数据是measure group P的。P是从A算出来的。等于我删数据并没有帮助数据process成功,反而耽误了一天的时间。

我把这一点告诉了operation的女生,她还疑问:为什么M删了以后就process成功了呢?要么是M其实删了P的数据。如果要删P数据,鉴于它的计算逻辑非常复杂,如果暴力删数据会造成什么情况我说不清。我当时是觉得M一定是删了P的数据,因为他对P的逻辑肯定没有我熟悉,所以因为无知无畏而删是有可能的。后来仔细看超级长的ticket,我才发现更合理的解释是美国的opertaion当时unload掉了错误的数据(P会在ETL中重新计算一遍),只不过新的错误数据又来了。请operation按照正常的手法unload数据才是正确的做法,是我一开始的建议,但是在催促和担心自己看起来没有男开发一样的本事,再加上没有人来管我,我做了一个错误的操作。

现在,在我的坚持下,operation终于退回去修了数据,现在cube process终于跑过去了。

这个错误并没有引起任何关注。这件事的后果只是,本来delay了7天的数据多delay了一天。我的经理没发现我做错了,operation还没有来责怪我,我估计也不会。因为在我们其他的产品支持工程师里,比我这个错厉害很多的错多了去了。我一直在配合大家工作的同时,默默尽力坚持我的标准。这个错已经不是第一个让我觉得“啊,我现在怎么标准降低这么多啊?”的事件了。

一方面没受到指责,也更说明管理的混乱。另一方面,我自己也很难原谅自己犯了一个可以避免的错误。我从一开始对问题的鉴别,和对解决问题的建议都是正确的。我们公司的管理太fucked up才造成我从这么正确的起点开始都能走到错误的操作。