驽马十驾

好久没写,拖延症又发作了。
另一方面,最近刚换了工作,各种事情还是挺头疼的,此间曲折难与人言。

换工作这种事呢,也不是第一次经历,没有那么多感慨了。但总归是一个比较大的变动,也有了一些新的体会与想法。整个过程虽称不上一帆风顺,但秉承着一贯的革命乐观主义精神,还是有些东西值得说道说道的。经历和见识有限,博君一笑罢了。

面试感想?

为啥会想到换工作呢?我出去面试的最大感受,就是很难说清我过去两年做了什么。。。这就是问题所在了。

虽然我一直吐槽自己是“打杂工程师”,啥都干,对很多领域都有些了解。但从个人成长来说,这未必是好事。有我的原因,有团队的原因,也有公司的原因。在“打杂”的过程中,想要去沉淀一些什么,真的很难。如果说是技术上的沉淀,业务都没起来何谈技术架构?只会慢慢变成一个crud boy;如果是业务上的沉淀,隔个几个月就换个业务方向,又能有啥深入的思考?

这种情况下,面试时就会很被动。我的技术基础还可以,所以一般一面都能聊得很开心,跟面试官天南海北的瞎扯。我也挺喜欢这种感觉的,就像技术交流一样,平时工作中真的很难有这种机会。
但后续的面试中,往往会涉及一些很“大”很“虚”的问题。包括你对业务的理解,对架构的思考和规划,甚至是方法论。有次面试官直接让我谈谈对DDD(领域建模)的理解。。。如果是我年轻的时候,估计会觉得这特么都是扯淡,就像魏晋玄学一样,清谈而不解决实务。确实谈论这些很容易变成嘴皮功夫、变成ppt(某司的核心竞争力),但这些东西是真实存在并且有用的,前提是自己真的有经历过、思考过,而不是看了一些文章、一些书籍便到处吹嘘。当一个人在谈论这些的时候,分辨他是否有真材实料,也是个技术活。

某次二面,从头到尾都没有问一点技术细节,就是讲系统是如何设计的,我说一些细节甚至会被阻止。我举了自己之前在做的一个社区系统的例子,被问的十分狼狈。说来惭愧,社交领域真的没咋思考过,这个系统也只是为了应付功能。如果是大数据、分布式相关领域的,我还能扯上两句。说到底还是做的事情太杂太浅,不够深入。结果不出意外的挂了。
事后反思,这块其实有很多事情可以讲的。风控、服务化、结构化、数据挖掘、个性化推荐。。。但之前从来没有想过,所以这波挂掉也不冤。

出去面试之前我曾联系过一个猎头,大致介绍了下我的情况。他说我之前搞大数据,现在做业务开发,如果还做业务想拿到好的offer可能比较难。当时我不以为然,觉得他很外行,都是相通的嘛。没想到他一语成谶。。。略显讽刺的是,最终还是凭大数据相关的经验拿到了不错的offer,又滚回去搞数据平台了。。。换言之,我这两年到底有没有成长。。。不过也没啥好抱怨的,路都是自己走的嘛。

面试中的另一个问题在于我只敢说自己确定了解的一些事情,一些了解不多的领域都会很谨慎,这其实也是有些吃亏的。对于那些很“虚”的问题,适当的吹水还是有必要的。要给人一个侃侃而谈的印象,不要有不确定的观点,不要犹豫。有些时候太实在不是好事,说到底还是程序员思维作祟。
话说技术分享也是一样的,看看别人的题目:系统稳定性保障核武器、高可用架构演进之路、海量数据场景下解决方案。。。看着就不明觉历有木有,气场就不一样。

此外,面试中经常碰到的一个情况:对面是一个不懂你领域的高P,尤其是职位不是特别“对口”时。这种时候一般着重考察技术之外的能力,比如逻辑、沟通、深入思考、领导力。有些面试官会引导你,问你细节,然后不断深入;而另一些人则会直接把你做的事贬的一文不值,抹杀所有努力,典型句式:“不就是xxx么”,言下之意你这个太简单太low。。。这种时候我就有点被动了,不知道该怎么接话茬。我会尝试说服对方,但很多时候连说服的机会都没有,“这个太简单,换个话题”。我曾尝试跟某个面试官解释hadoop,对方直接一句为啥不用oracle就把我噎回来了。。。我也懒得再浪费口水了。我不知道这是一种面试策略还是怎样,还是单纯取决于面试官个人性格?当然我承认确实有些人是站得高看得远,可能在他们看来确实是low,就像我们带新人一样。。。但这其中的真真假假又如何区分?也许只是我运气太差?

话又说回来,表达能力真是很重要,如何把自己在做的事情说的高大上,尤其是对于外行,每个人都应该仔细思考。“做牛逼的事,讲给傻逼的人听”,确实如此。

总的来说我还是挺喜欢面试的感觉的,能让我看到自己的不足,这已是万幸了。如果一直沉浸在已有的小圈子中,很容易变成温水煮青蛙。有句话说的好,人受憋屈武艺高,跳出舒适区去外面看看,还是很有必要的。

P.S. 面试过程中感觉没怎么碰到算法题啊,唯一碰到的一道题是kSum,我特么还没答出来。。。其实这个题也是很经典了,在leetcode上做3Sum/4Sum之类的我也写过通用的解法,但面试中状态不佳也没啥好说的。。。

P.P.S. 面试中遇到了一些“话术”,像是销售一样。。。一般就是各种挑你的错误,不断的打击你,但这种套路一旦识破了就很容易出戏,就像一个销售对另一个销售使用话术一样。。。

十字路口

我之前说自己中年危机,还是戏谑的意味多一些。但这次换工作的经历,让我觉得自己正站在一个十字路口上,必须做出一些很重要的改变。

对于年轻人,只要技术基础好、态度积极、踏实肯干、听话就可以了。一直以来无论我在哪家公司,招聘应届生、工作一两年的人,标准差不多都是这样。但对于我这种老年选手,就没那么简单了。这也就是我一直在强调的“沉淀”的重要性。

你要明白如果公司招你进去,对你的“期待”是什么。如果只是简单的crud,干嘛要招你这么贵的一个人,找个应届生培养个两个月,不是一样的效果?又不是皇亲国戚。。。是要你带起某块业务?是从头搭建技术架构?是看中你的经验还是资历?总不会是看中颜值吧,又不是孙红雷。。。要思考对公司的“价值”是什么。想清楚这些东西,以后的路才好走,不至于浑浑噩噩的混日子。

从个人发展的角度,我大概想了下:

  • 要有自己的“领域”。也可以说是自己的护城河、核心竞争力,一个意思。通俗点说就是在某个方向上要能有深入的理解,要能别人所不能,这样才能体现自己的价值。所谓的领域,可能是技术的,可能是非技术的。一个典型的例子就是现在的算法工程师,随着AI的火热,身价也水涨船高,但算法的壁垒还是比较高的,如果之前没研究过想进入这个领域还是挺难的,就算进入这个领域想达到一定的高度也要旷日持久的投入,这就是他们的“护城河”。另外总有些人会拿“深度”、“广度”来说事,说自己“深度”不行,“广度”还可以之类的。但这只是块遮羞布而已,你在某个深度上证明自己之前,没人在乎你的广度。
  • 更多的关注人,而不是事。换言之,be social。在某个年纪之前,只要埋头做事就可以了。但如果还想持续保持竞争力,就要更多的关注人。不说八面玲珑,至少要能融洽相处吧,如果要带团队,更是如此,要清楚每个人的性格,擅长/不擅长什么,才能合理安排。对我这种脸盲症中期患者而言,还是有点难度的。。。隐居的高手什么的,那都是扯淡,现在哪有单打独斗做事的,都是靠团队冲锋。有人会拿多隆举例子,说他一心钻研技术取得什么什么成就。但多隆只有一个,而所谓的技术宅到处都是,性格乖僻无法合作的我也见过不少。还有很多人以乔布斯为偶像,但没学到乔布斯的才华,只学到了他的刻薄和偏执。反正我看到的混得好的人,都是非常擅于处理人际关系的。
  • 有自己的想法,别怕发言,能独当一面,自带体系,不要等别人指挥。因为越向上走,接收到的“指令”往往越模糊,可能只是一句话。要把这句话落地实现,跟拿着详细设计文档写代码,完全不是一个层次的事情。必须要自己去思考如何实现,全权的own这个东西,很多事情要主动的牵头和推动。关键在于做事的意愿,也可以叫做野心、aggressive、匪气。说到匪气,有时候工作真的和土匪一样,太书生气是要吃亏的。。。生活中亦是如此,善良又胆小的人没有活路
  • 职责没有边界。所谓小富即安:搞好我自己这一块就可以了,其他的天塌下来也不关我的事。这种想法挺常见的,但对于自身的长远发展其实是不利的。
  • 严禁追求完美。这是很多程序员的通病,总是想找一个完美的解决方案。领先别人一步是天才,领先十步就是神经病了。同理,思虑周全是好事,但导致瞻前顾后不敢行动就是SB了。我们当然要思考长期的解决方案,但很多时候我们要先拿出一个短期的“补丁”,才有资格去思考中长期的事情。
  • 尽量去做核心业务,去接触核心的技术、核心的圈子。毕竟扎马步之类的练得再好,也只是基础动作,也比不上九阴真经里的一招半式。。。关键在于开拓“眼界”,这是很抽象但是也很重要的一个东西。好比谈到创业,有些人只能想到学校门口开个炒饭大排档,有些人却可以写商业计划书去骗风投。。。而且不同的圈子里,能接触到的人也不一样,从其他人身上学习往往是一条捷径。

乱七八糟写了这么一通,感觉还是说的不清楚。。。就是隐隐的有一种感觉,但很难写出来,所谓的“升咖”的机会。

话说回来,其实很多时候都是因事成人,一个人的成功不是因为能力如何出众,而是做对了某件事。但如何在恰当的时机把握住机会,就是成功者区别于常人之处了。君子善假于物,此言不虚,顺大势而行方是正途。你可以说是狗屎运,但不得不服。

最后摘录一段鸡汤:

在某个年纪之前,你可以靠透支身体、小聪明和老天给你的运气一直取巧地活着。然而到了某个年纪之后,真正能让你走远的,是自律、积极和勤奋。

还是架构

架构这个东西,就像盲人摸象一样,每个人都有自己的理解。架构说到底就是“做某件事的方法”。这个东西不能没有,但是也不能过于纠结。我也说不清楚,但我经历过一些反模式,倒是可以说说。

这两年参与了各种业务,每次一有新需求,开发们就开始叫,这个做不了,那个改动太大。。。然后开始和产品撕逼,要求砍需求,或者评估一个很长的开发时间,让产品们知难而退。。。就算最后迫于压力接下需求,也是各种吐槽。
但仔细想想的话,有些需求是合理的,反而是技术架构设计的不好才导致各种问题。产品说我要做一个能发140字短文本的社区,好的技术们去实现了;后续产品们又要求能发图片,但上一个版本的设计只能支持文字,于是又是各种大改。。。但这个问题开始的时候就应该想到啊。这就像代码里的hard code一样,既然当初偷了懒,欠下技术债务,给自己埋了坑,踩坑的时候就别抱怨。

过于短视,只关注眼前的一些需求,只关注一些“点”,缺少全面的思考就可能导致各种问题,因为大家都抱着一种事不关己的态度,反正我把分给自己的需求做完没bug就行了。。。
正常来说要先有个通用的架子,然后结合需求和产品的未来规划来做设计。

  • 尽管有许多架构都能满足功能需求,但其中只有一少部分能满足品质需求,比如可变性、性能、容量、安全
  • 在设计的过程中,有许多“决定”要做,未必是架构师来做决定,有些决定是“隐含”的
  • 越早期的“决定”,影响越大
  • 越早期的阶段,修复错误就越容易
  • 不要让架构“自动出现”。切忌不断的“堆日常”,最后只会让整个系统失控。

一个好的架构通常也是有些套路的:

  • 关注状态。可能是整个系统的状态,也可能是一行数据的状态、一次调用的状态。也可以说是生命周期、链路。画个状态图,把整个状态变化的过程捋顺了,很多时候就能看出有哪些扩展点,就像AOP一样。
  • 分层。所有的架构都有一个根本的目标,就是解耦,分层是最简单的手段。层与层之间的交互尽量清晰。
  • 关注元数据和配置。它们都可以用于增加系统的可变性和扩展性,可以适当使用DSL等,像规则引擎之类的,但也不宜过度。
  • 关注各种非功能性需求,像是监控、SLA、安全等等。即使很长时间内都没有这种需求,初始设计时也必须考虑到。
  • 参考已有的架构。一些已经有最佳实践的领域,可以直接借鉴。更重要的是注意各种反模式,就像代码里的“坏味道”一样,一旦出现类似的“不和谐”的感觉就要注意了。

具体到大数据这块,我感觉我现在就是个造发动机的。。。数据平台的职责在于向下屏蔽各种基础设施(hadoop/spark/kafka之类),向上提供友好的、业务相关的UI和API,提供各种使用数据的能力。在它上面会有数据仓库、各种数据驱动的应用等强业务相关的系统。所以感觉它就是个发动机,数据就是汽油。最差的架构就是一堆基础设施,直接暴露给用户,没有一点平台的概念。就像暴露一堆“裸设备”给别人用,这就是为啥要有文件系统。
一个不太恰当的比喻:就像NewSQL一样,我们应该提供sql给用户使用,而不是直接丢一堆low-level API给他,说你自己玩去吧。。。

P.S. 关于业务和技术,我现在还是觉得应该是以业务为导向的,即使现在搞平台相关,离业务稍远。这是一种“思考方式”,脱离业务需求去单独的研究技术是很危险的:不注重业务意义、不注重与人交流、搞各种奇技淫巧。一个反例就是,我曾经研究过一些guava中函数式编程的接口,然后用到了自己的系统中,这tm就是给后来的人埋坑,我保证他们看不懂。。。业务是应该驱动技术的,应该从业务的角度去思考,我要用技术去做哪些事。

P.P.S. 既然说到了奇技淫巧,我发现很多程序员都有这个坏习惯:喜欢在正式项目里“练手”,把简单的东西写的很复杂,看到一些新奇的东西就强行用在项目里,还喜欢自己造轮子,最后都没人维护。。。所以说,好的代码总是相似的(有最佳实践),烂的代码则是千奇百怪。

END?

年纪渐长,心中总是难免有些感慨。好比以前听歌听周杰伦,“为你翘课的那一天,教室的那一间”;现在开始听李宗盛了,“岁月你别催,该来的我不推,走远的我不追”。
现在我的很多文字,如果给几年前的我看,估计会被吐槽“这谁啊这么矫情”吧。。。有很多事情,还是希望自己能早点明白。很多道理不是不知道,但只有亲身经历过才会懂,这真是个矛盾。我已经过了为赋新词强说愁的年纪了(大概),但幸好吐槽的功力还保留着几分。

有时候也会想,生活&工作咋就这么复杂呢,就不能只是简单的吃着火锅唱着歌么。。。但不管你喜不喜欢,现实如此。不想被麻匪绑走的话,还是努力些吧。
似乎我从来不是一个聪明的人,旁人对我的形容多是“踏实”。驽马十驾,功在不舍,聊以自慰吧。

一些文章:
http://geek.csdn.net/news/detail/235751
https://zhuanlan.zhihu.com/p/27891140