自2018年8月起,因为换工作和换住地,我就开始了环绕十号线半周的通勤生活,从进站闸机到出站闸机要50分钟,来往就是接近2个小时。无聊且网络信号不好的地铁旅途中,读书就成了唯一的选择。先后购买了一些纸质书、Kindle Oasis 2nd、iPad mini 5th 4G作为工具,目前稳定在iPad mini上
刚开始的时候只是随性得读一些博客和历史书籍,比如漫长的《讲谈社 · 中国的历史》,和一些Function Programming/LISP/DDD的内容,今年3月下定决心要离开新东方,于是转而开始刷题和针对跳槽进行阅读,直到最近拿到想要的offer,这段为了离开而进行的读书生涯才终于宣告结束
话要提前说好,虽然对新东方有诸多不满,但最终还是挺感谢新东方
- 其一,入职时涨了工资,上家公司工资太低只能勉强度日,如今终于能活得滋润;
- 其二,跟着公司旅游去了一趟日本,了却了长久的愿望、开阔了视野;
- 其三,正是因为这些不满让我有了充足的动力去提升自己、迎来改变,痛苦固然痛苦,但也促使我成长和反思;
- 其四,在这个俞敏洪、李笑来、罗永浩都战斗过的地方体验了一番,感受到了新东方的气质,还得到了跟俞敏洪的握手和合影,很值得
怨气固然有,但跟满满的感谢并不冲突,一码归一码,看客请自行判定
一、为什么要走
跳槽是有互相激励作用的,当你的朋友们都在为了追求更大的发展、更好的团队、更高的工资而跳槽并且成功的时候,你会自然而然得想要加入他们,俞敏洪说:A bigger world, A better you. A better you, A bigger world. 当前的环境不足够好且看不到改善的时候,跑路是一件很自然而然的选择,那么当时我遇到了什么呢?
能看到的未来就是我在新东方没有未来
入职的时候offer letter上我的title是“高级开发工程师”,HR一波神奇操作之后(HR解释说跟我领导沟通过),我变成了“开发工程师”,我就想问了,那些连话都说不清楚、独立实现一个功能都做不到、开发能力连外包都比他强的人也是开发工程师,这种工程师我他妈1个能打10个,bug还少90%,给同样的title?
说我水平不行、入职时间短、经验积累少就算了,有些服务好几年、每天各个团队都来哭着求帮忙、每天都加班到晚上9、10点钟才回家、每年都接受俞敏洪亲自表彰的优秀员工,也是“开发工程师”,也就那点工资。论付出我比不过人家,论熟悉程度我比不过人家,论加班时间我还是比不过人家,结果他还跟我同一个title,不知道在新东方要怎么做才能算是个高级开发或者开发专家,擅长写PPT吗?我PPT也写得挺好的啊,转正的时候隔壁团队的leader在review我的答辩的时候还夸奖了呢
不过话又说回来了,从3月到12月,每次有什么应用程序池崩溃、应用的线程池满了把Redis拖垮、异构数据库做对比、打包脚本和流程出问题之类的奇奇怪怪没人处理的问题就直接丢给我去弄,说明我水平也还可以,起码交付给我我能查遍所有文档然后给个答案,至少比英文文档都看不懂、还要我逐句翻译的强,对吧?
在新东方干好、干坏、甚至抄人家的代码改改就交差都同岗同薪同酬,那未来在哪里呢?难道是在某个好未来过来的领导的弥天大饼之中?
推荐领导们拨冗阅读老板以为最不可能离职的员工为什么往往会提出离职? 码农这一行,能干好活的都不是傻子,希望能把那些踏踏实实干活、干好活了的同事当人看,人家付出那么多,给他们应有的升职加薪,不丢人;倒是养一些话都说不清楚、事也做不好、还特别喜欢甩锅的冗员,显得管理水平挺低的,丢人
不过话说回来,要是某些优秀员工真的一怒之下重新找工作了,人家要技术有技术、要能力有能力,去个一二线大厂没问题,倒是新东方这摊子要怎么收拾呢?
996
在入职之前我跟所有面试官和HR都确认过,除了紧急事务和上线以外,正常开发迭代是不会加班和强制加班的,入职之后一个多月,某个从好未来过来的产品领导大手一挥,“兄弟们抓紧一点、辛苦一点,我们开始996吧”,我可去你妈的996吧!
在宣布996开始施行的誓师大会上,这位领导还把CTO和人力的某个领导请了过来,承诺这就开始制定奖励方案,等这项目上线之后一定大大有赏,话虽然说得信誓旦旦只差声泪俱下,但是结果呢?
项目是5月底上线的,在6月财年结束的时候,我的绩效B+(据说A以上的就可以申请升职,我估算了一下比例我们组也就那两个服务时间很长的老员工可能拿到了A以上的绩效),年终奖是最低的1.5个月,涨薪低到什么程度呢?我10月份才发现我的公积金不是整数了才知道涨薪,但是由于太低了,还没有20元/小时的加班工资带来的浮动大,根本就没有注意到
画大饼、做压榨、不兑现,信任如同用烂的抹布被扔掉。最后不仅画大饼的领导跑路了,CTO也跑路了,我觉得下一本书可以这样写:《画饼与跑路 —— 我的教育创业之路》
那996产出真的很高吗?不见得,每天真正有效的写代码时间最多5个小时,上一天班其实已经很累了,继续加班毫无产出,每天如此循环往复,身体累了导致第二天也没有效率,总产出甚至会变少,考虑到加班带来的bug增多,996得不偿失。但是领导们不这样想,其他团队没有加班,而我们在996,这就是一个巨大的噱头,他能在他的领导面前吹嘘的内容可多了
“人不够就加外包”
这不是我黑谁,也不是讲笑话,而是“画大饼”领导又一力作。在跟人聊到开发资源不够的时候,他来了这么一句:时间不够就多加班,人不够我们就多招外包
我其实很不明白这些自称在行业里奋战了几年、十几年还出了一本像模像样的书的“老兵”,为什么能对软件开发和管理说出这么无知可笑的话,似乎从来就没有读过软件工程和软件管理方面的书、也没有任何对管理、对开发的思考,全凭一股“大干快上堆人头”的傻气,就妄图解决一切问题,naive!
软件开发不是建筑工地抹水泥,是靠产品经理和程序员心智进行规划和设计得到结果,真希望领导们能拨冗阅读《人月神话》,了解一下软件开发的基本原理再出来瞎忽悠
方向迷茫
一个后端15个人,前端7个人的团队,做一个已经用了13年的系统的改造、重写,某领导打鸡血说改造完要再用20年,建设方向从头到尾就一直在变,每个月开会都会有新目标。我猜是每次领导们去给更高层的领导们回报时,更高层的财务、客服和校长们总能提点新目标,于是下面的人也就跟着变来变去。说白了,主管项目的人也没有想好到底要做一个什么项目,也不知道哪些要做哪些不要做,哪些该做哪些不该做,就这么走一步看一步了
方向的模糊让我很迷茫,不知道自己该做啥,也不觉得自己做的东西有什么价值,怀疑和自我怀疑是不信任的起源
团建完回去加班
又一个神奇的操作,白天团队建设,拉去一个什么游戏厅做一些很傻的游戏做到下午六点钟,然后大家一起坐地铁回公司加班到晚上9点,这天还是周五,槽点太多我甚至不知道该从哪里吐起来
二、继续C#/dotnet?
不了,没有前途,也没有钱途。虽然我是被微软Empower us all的广告骗上船的,但是在国内C#真的不太可能出现咸鱼大翻身了
社区凋敝
一个没有新鲜血液涌入、也没有大牛开路的社区是没有未来的。新鲜血液涌入保证了社区的持续活跃和生产力的可持续。大牛开路意味着有人为社区发声、带来持续的影响力、号召力以及技术的不断向前更迭。这两点在国内的dotnet社区都看不到
高薪工作缺失
去拉勾、BOSS看看,C#/dotnet想要找一个20k月薪的工作有多难,起码都是技术带头人级别的了,如果20k往上动不动就是CTO级别了
但是如果换成Go/Java,那你只需要是个中级/高级开发,起薪就是20k。为什么呢?因为C#的中级大概连独立实现个功能都很困难,一说他不行他就跟你扯什么框架性能吊打Java,连业务都做不好还谈什么框架,再说了,某些所谓的框架里http请求除了200以外的全部抛异常,这框架能用?Java的中级起码能自己去对照一下阿里的要求,看看自己是什么水平了。换句话说,dotnet技术栈对人才连个大家公认的、像样的衡量标准都没有,想撒泡尿照照自己都没机会
其实社区凋敝和高薪工作缺失是一个鸡蛋相生的关系,社区凋敝大家都不学、不用、不会,那么现有该技术的公司就难以招到合格的人才,后续也就难以继续使用该技术;使用该技术的公司少了,那开发者就更少会有人学习、使用该技术,于是进入死亡螺旋
三、往何处去
Go/k8s
软件开发的形态正在发生变化。
每次软件开发的形态发生变化的时候,都是对“如何管理复杂性”这个亘古不变的终极问题提出新的解答,k8s可以认为是这个新解答的核心,而Go/Rust则是适合k8s的语言。
或许有人会认为我的理解中关系反了,是先有了Go才有了docker和容器,容器之上有了k8s。这样说没错,但是倒回去想想究竟要解决什么问题,就知道问题的核心在哪儿了。我们不断前进,不断追问自己,寻求更好的解决方案,当前得到的答案是k8s,这是我理解的k8s的意义
至于Java,是的,它现在依然很火,它基础设施超级完善,但是它跟C#一样不太适合k8s,所以未来不是特别看好,或许会继续存活下去,而且活得很好,因为它已经too big to fail了。但是我不愿意再投身于一个熙熙攘攘的红海,「世之奇伟、瑰怪,非常之观,常在于险远,而人之所罕至焉」
四、怎么去
学习Golang
Golang是一门非常好入门的语言,如果有其他语言基础,特别是C系语言的基础的话,很多东西都一通百通,再稍微读一读The Go Programming Language和Effective Go,基本上就可以做出自己想要做的大部分工具了,我就是这样入的门
刷题
我不是一个科班出身的程序员,算法和数据结构我没有学过,入门之后就一直在实习和工作,现阶段对我来说算法几乎成了通往更好工作岗位最大的拦路虎,只要解决这个,我几乎就铺平了自己前往一个对技术有追求的团队的路
从4月份开始,我在LeetCode上刷题,从一无所知开始刷题是极其痛苦的,这绝对是我入行以来最艰辛的一段路,最开始我连easy难度的题都要翻评论区的答案才能完成,也不知道刷到什么时候是个头,于是抱着日拱一卒的心态慢慢来,度过了最难的前100道题。虽然到现在也只刷了185道,但是我除了LeetCode以外还读了CRACKING the CODING INTERVIEW,按照各种分类把里面的题和解答也都七七八八得读过和写过,所以在后来面试算法题的时候其实也基本够用了
算法的确很少在工作里直接用到,但是它有两点重要价值值得一刷,我以后也会继续刷下去
- 这是一块前往高薪工作的敲门砖
- 算法和数据结构能改变思维、改变对程序的认识
刷过之后,再去看日常的业务代码会发现他们其中蕴含的算法和数据结构,很容易找到值得优化的点和优化的方法,甚至能改变面对复杂业务需求时的反应:第一反应不再是写代码,而是
- 抽象、分析、找到问题的核心
- 复杂问题分治、拆解成子问题
- 解决问题
跟刷题的思路是一样的,或者说,正确得解决问题的思路都是类似的
写简历
完全没想到的是,8年前学习InDesign的用法,居然在这时候能排上用场,在dribbble上找了一些模板,挑选了其中比较满意的板式和元素,拼凑成了自己的简历
第一版简历只有一些个人信息、工作经历和自我描述,内推的时候感觉还行,至少简历筛选能过。但是有一次在投一家公司(忘记哪家了,大概是京东或者瓜子)时简历投过去没有得到任何回复,我感觉简历可能有点问题,于是在个人描述里分割出来了一块,用圆圈数量代表熟练度的方法写了我掌握的技术,类似于C#、Redis、MySQL、Elastic Search、Kafka之类的,再后来就再也没有出现过简历扔过去杳无音讯的情况,不过后来的投递也基本都是内推或者直接联系到开发负责人,也基本就没有简历筛选这关了
五、面试
头条 —— 毫无准备,惊慌失措
头条是8月面试开始的第一站,连自我简介都没有准备就把简历扔去内推了,想的是以赛代练。aPaaS面了两轮,抖音火山面了一轮,基本上都是算法题,其他的也都不问,做完完事。没什么收获,也没有暴露什么问题,体验也很一般。大概就是他们也不怎么急着招人,我也根本没打算去,大家都是例行公事走个过场
旷视 —— 邀约而去,发现问题
旷视是因为我在Twitter上发了我在找工作的消息,说本大爷准备了几个月,要开始找工作啦。于是他们的一个员工DM我,问我要不要去试试,我想试试就试试呗,就当去玩玩
于是过去面了两轮,第一轮都是些简单的业务问题,回答得七七八八,谈不上多好也谈不上多烂
第二轮是DM我的L,还是钳子的前同事,他考的问题既贴近他们的实际工作,也还挺有趣,似乎是从GeeksForGeeks上找。从Redis的复制机制开始,一路问到Redis的集群等等知识,这里暴露我对Redis、操作系统一知半解的缺点,回家后我买了基本操作系统的书恶补,还写了一篇日志记录现在没有回答好的那个Redis复制的问题: Redis 复制时的 fork 的子进程
这一轮是非常有收获的,暴露我在Redis细节、操作系统细节、MySQL的细节上都有很多不够透彻的问题,让我后来又认认真真重新复习了一遍
多抓鱼 —— 满心期待,埋下伏笔
在面试的间隙在v2ex上看到了多抓鱼的抓人启事,我是他们的忠实用户,对他们的产品理念和开发理念都很认同,当然想去尝试一下,于是发了条推找他们的员工求内推,他们的一个SRE和前端都DM了我,我根据提示给他们的HR邮箱发了邮件,约好了第一轮面试,没想到是唯一一轮
由于他们用Python,我还临时在去之前买了基本Python的教材恶补了一番,然后用Python刷了几道LeetCode,自信满满就去了,心想怎么也能混到终面吧。一面不算很难,面试题都比较常规,唯一不太常规的是面试官看我在简历里写了自己刷过LeetCode于是全部都不用LeetCode里的算法题考我。算法基本上都是递归和链表,第二个递归我没有发现可以用递归(主要是在刷LeetCode的时候为了追求速度一般都没有用递归去处理二叉树,其实那个题用递归可以非常简洁快速得到答案),虽然磕磕绊绊但是面试官还是表示由于你的理念跟我们很契合,这一面算过了,后面加油
过了两天HR发来了一个笔试题,约定十一之后交,于是我花了十一中的整整6天,对的,整整6天都在肝这玩意,从Python的项目基本结构开始学,然后是Tornado、单元测试、集成测试、Travis,肝了一个我觉得还可以的结果:keaising/dejavu
虽然自己知道做得不够好但是还有一点侥幸,期待万一他们能看到我的努力给我继续往后面试的机会,结果提交了笔试之后整整一周都没有消息,感觉有点凉,后来给HR打电话了HR表示技术负责人对笔试结果很不满意,但是鉴于我的态度会给我写一封邮件说明下哪些地方需要改进,然后我再去准备3个月,如果之后还有兴趣,再接着聊。我本来还挺期待的
结果快两个月过去了,我依然没有收到他们的改进建议邮件,我至今不知道自己的项目哪里做得不够好,我还在等,如果他们依然有兴趣告诉我的话,我依然愿意把这个笔试题做得更好一点,尽我所能。只要能提高自己,为什么不呢?
不过说实话多抓鱼的面试体验并是不太好,不知道他们是不是太忙了,总是感觉没啥反应,也可能是我不够好吧,人家也没啥兴趣招,那就这样了
Curiosity China —— 重新审视,自信满满
其实面完多抓鱼的时候我已经不太想继续在今年面下去了,感觉确实离我想去的工作岗位还有一些距离,也有点太累了,保持高度紧张的战斗状态已经大半年了,整个人都有点累,想休息一段时间,虽然经验和教训都积累了一些,但还是想摸个鱼明年再战,有一个巨大的拖延借口:快过年了嘛,明年再说
这时候他们来了一句,要不你再来我司面一下?本来准备在最后一两家再去他们那儿的,因为一直都知道他们那边的情况,那边的offer一旦拿到了我肯定会去,但这不是一家offer都没拿到嘛,索性去试试咯,反正今年要是没拿到,明年再战就是了
于是改了改简历,很快得约了个电话初面,电话聊了一个多小时,问的知识都很基础也很贴近业务,貌似还挺满意,很快约了当面聊。
去Curio面试之前我还反反复复审视了自己写在简历上的每一句话,想了想可能会问到的所有问题的答案,可以说这是我在面试这几家公司里准备得最充分的一个,去的时候也是最自信的一个,我知道他们会问的问题大概会落在什么范围内,最后也确实就在这个范围内,自己发挥得也不错
当面聊了接近3个小时,一开始展示他们的产品的时候给我一种新员工入职培训的感觉,真的,新东方的入职培训都没有讲那么细。而且面试题都是很实际的业务问题,丝毫没有刁难人的感觉
HR基本没啥问题,因为她似乎发现了我们都还挺熟的,当然咯,某师傅在Twitter上视奸我还不让我fo他!
CTO就问了下两年来有啥进步,为什么现在想通了要加入。我的回答是两年前我刚毕业,也刚踏入这个行业,对行业、对自己、对Curio都没有认知,对,没有能力认知当然就没有认知了;而两年后我有了自己的认知,也有了自己的能力,感觉他们是符合我对好团队的期待和要求的,自然也就希望加入
面试到这里就结束了,后来他们讨论了一下,本来还有笔试题环节,但是看了我给多抓鱼写的笔试题之后觉得够了就没给笔试,很快拿到了HR的口头offer
理念契合,人情熟络,这次我希望加入他们
End
确定离开之后我也想过,真的嫌弃新东方么?谈不上,最多是觉得信管这边的管理略显稚嫩、跟互联网大厂比起来技术水平非常一般,在这里待了一年多,靠工作里的积累和同事的知识,基本没有提升和进步。但是如果换个角度,把新东方看作是一家正在挣扎着朝精细化运营、技术转型升级、上云等方向奋勇前进的传统企业,这些问题就是艰难的转型过程中不得不面临的阵痛,面对这些问题的新东方,已经是教育行业里很有远见卓识的了,只不过我没那么多时间精力跟随它走完整个过程,不得不提前离开
甚至感谢新东方和那个已经跑路的好未来领导的想法还要多一些。我啊,是不被逼一把就不会动的懒鬼,要不是被逼996了大半年,可能我现在还是没有足够的动力去刷LeetCode、去广读博客、去学新技术,正是新东方给了这么一个扔下谷底的机会,我才有动力自己往上爬,才有了现在轻轻松松说“对不起我要离职了”的资本和勇气,这就是历史的进程
那个人的奋斗呢?个人的奋斗当然也是很重要的,在十号线上刷题太认真坐过站,在四号线上困到睡得手机和iPad掉地上,为了不瞌睡在地铁上一直站着都是家常便饭,我不是一个脑子很聪明可以靠天赋吃饭的人,我得到的都是我努力付出换回来的
读书是不会停止的,只不过会换个地方
PS: 今年、未来几年的行情都很不好,朝更好的地方前进可以,但不要轻易裸辞