海龟龟

我的上岸之路——从Quant到Software Engineer

前言

大家好! 最近成功上岸成为了一名Software Engineer。抢滩登陆期间,一共面了6家公司(大厂小厂都有),都拿到了IC5等级的offer,自己对于面试的成功率还是颇为满意。

回想起当时在职业岔路口犹犹豫豫的时候得到了很多前辈和好心人的帮助, 所以故作此篇做一总结,希望也能帮助到后来人。

背景和缘起

我的背景非常不CS:本科在国内某985/211学的经济,硕士来的美国学的金融工程(MFE),毕业后的前三年在投行做Quant,然后跳槽去了一家小公司做Quant Developer至今(大概也快三年多了)。

在职业早期从没有想过要转码:和很多MFE的学生一样,学生时代的我对于自己的职业规划都是紧密围绕在 买方、卖方、交易、量化研究 等字眼的周围。工作以后发现梦想和现实的差距是巨大的:美国的量化金融已经是夕阳产业,在某投行的三年专业技术上长进非常小,每天做的事情都是拧螺丝:修一修regression tests,重写以前的infrastructure和framework,对于定价模型的理解也只能停留在读懂代码和model doc的level,当年第0代和第1代的老Quant已经找不到踪影,也没有人可以给你多讲讲模型背后的故事和逻辑。

由于对于卖方工作的倦怠,三年之后跳槽去了一家小的Fintech公司。当时的动机更多的是年少无知,吃了CEO画的情怀的大饼以为自己挖到了宝,幻想可以若干年后上市。

这次跳槽冥冥之中为我的转码之路做好了铺垫。

因为公司比较小,虽然我的position是Quant Developer,但是在公司早期,基本上后端的所有项目,我都有或多或少的参与,我的计算机的理论和实践经验基本就是在现公司里learning by doing获得的。在熬过了学习曲线最陡峭的那一段以后,我开始享受成为一名码农的快乐了。

真的准备踏上转码之路,是因为一篇公众号文章。

2020年7月,当时在做的一个项目被sales强行逼迫上马,所以的逻辑都要配合sales的story来设计,即使很多逻辑从一个工程师的角度来说都非常不make sense。不愉快的工作经历加上在现在公司能够学的也比较有限,让我又萌生了跳槽的心思。这时候,一篇公众号文章让我彻底下定了决心:三个月,从华尔街量化分析师到硅谷程序员

我的背景要比文中的霸霸弱一点(本科加工作经历),但是总的来讲,背景还是有一定相似度的。而且最让我欢欣鼓舞的是,霸霸在全职工作的时候能够三个月刷800多道题,当时已经疫情在家工作快6个月让我觉得大好的WFH的“划水”和学习的契机,不好好利用岂不是浪费,从此便懵懵懂懂的开始了我的转码之旅。

准备阶段之算法篇

准备算法没有什么捷径可言,有很多帖子刷了100题或者200题就上岸的经验贴只是幸存者误差,扎扎实实的练硬本领才是硬道理。

image

我从开始准备到定下offer大概刷了6~7个月的题目。11月和12月因为身份问题上的不确定性,不知道什么时候能跳槽所以刷的慢了些。等到今年的1月份所有可能阻碍跳槽的问题都扫清了,我又开始加量刷题了,到最后刷了1000道左右的题目。

回顾我的刷题史,大体会分为三个阶段。

第一阶段:啥也不会,信心受挫。刚开始刷题的时候可能也就勉强能写出来个简单难度的,还不能做到第一遍就bug free,中等和困难的问题基本上都写不出来。这个阶段主要是因为知识点的缺乏和对数据结构熟练程度(常用数据结构如栈、队列、堆; 常用的built-in函数如二分搜索、排序等等)不够造成的。我个人的解决方案是先按知识点的类别进行刷题,我总结的常用的知识点大概有下面几类:

基础知识:

  • 二分搜索:熟练掌握二分搜索的模板,以及可以熟练解决二分搜索下的各类问题。
  • 宽度优先搜索(BFS):可以和queue的数据结构一起学习。
  • 深度优先搜索(DFS):着重掌握回溯法和记忆化搜索。
  • 二叉树:掌握二叉树类问题基本的技巧。很多二叉树问题都是可以递归解决的。
  • 链表:掌握链表的基本的技巧。
  • 快速排序算法:这里顺便可以掌握一下Quick Select算法,用来解决第K大的问题。
  • 字符串:熟练掌握你使用的编程语言中对字符串的各类操作以及熟练掌握回文串类问题的解题技巧。
  • 常用数据结构:stack/queue/priority_queue/set/dict等等

进阶知识:

  • 动态规划
  • 滑动窗口(Sliding Window) 、双指针(Two Pointers)
  • 扫描线(Sweep Line)
  • 单调栈和单调队列
  • 并查集(Union Find)
  • 字典树(Trie)
  • 最短路算法(Dijkstra以及Bellman-Ford)
  • 线段树(Segment Tree)
  • 树状数组(Binary Indexed Tree)
  • 最大流、最小割、二分图匹配

以上的知识点如果能熟练掌握了,基本上算法面试就没有什么大问题了。在刷新题的时候要制定好计划进行复习。

第二阶段:“这题我能做出来”。第一阶段是最困难的阶段,等到第一阶段的知识点都掌握的差不多了,就会到第二阶段。第二阶段的感觉是看到一道题,有思路,可以上手写一写,写出来的代码可能不是最优的或者看起来比较乱。这个时候需要做两件事情:一是开始乱序刷题,不再按知识点刷,而是随机刷,锻炼自己看到问题、分析问题和解决问题的能力。二是多看牛人的代码,每次刷题不要AC以后就万事大吉了,多去讨论区看看牛人们的代码,分析和改进自己的代码。这一个阶段可以参加每周六的周赛,虽然成绩可能会比较惨烈。

第三阶段:信手拈来,人剑合一。经历了几个月的第二阶段,可以明显感觉到自己写码水平的提升,这个时候你看到一道新题会觉得很兴奋,很享受写码的过程。看到题目以后也不会感觉没有头绪,可以通过自己的分析来选择最合适的数据结构和算法解决问题。每周六的周赛可以稳定的写出来三题,运气好可以写出来四题。

如果你通过坚持刷题到了第三阶段,那么恭喜你,基本上你的代码水平可以横扫各种面试中的算法问题了。

准备阶段之系统设计

对于应届毕业生其实是不需要准备系统设计的,但是对于有工作经验的同学,如果想冲Senior Software Engineer的话,那么系统设计是必须要准备的。在面试中,系统设计的问题通常会让你实现一个比较小的服务或者功能(因为时间有限,通常都是1小时)。我在面试的时候遇到了下面这些系统设计问题:

  • 设计Google Calendar (不考虑和其他用户的交互,要考虑重复的event)
  • 设计一个Message Queue (要求消息有序)
  • 设计一个酒店的预订系统
  • 设计一个Slack(要求支持群聊功能)
  • 设计一个视频上传系统(类似于YouTube,要求在前端显示上传进度和视频转码的进度,要求进行access control等等)
    等等。

如何准备系统设计

准备系统设计最重要的是要理解系统设计的方法论。有一些常用的概念是需要先深入理解的,例如:

  • Availability, Consistency, Scalability, CAP theorem
  • Consistency Patterns (weak/eventual/strong)
  • Latency, Throughput
  • Synchronous, Asynchronous

等等。还有一些常用的组件要充分理解,因为面试中经常会被问到技术如何选型等问题:

  • CDN
  • Load balancer
  • Reverse Proxy
  • DNS
  • Message Queue
  • Cache (Redis vs Memcached)
  • Database (SQL vs NoSQL)
  • RESTful API vs RPC vs GraphQL
    对于上面提到的基础知识可以参考这篇资料

在熟练掌握了基础知识了以后,可以去看Grokking the System Design Interview。里面有一些非常常见的服务的设计方法。在学习具体实例的时候要注意从四个方面体会系统设计上的取舍和技巧,这四个方面分别是

  • Scenario:要实现哪些functional requirements
  • Service:为了实现这些requirements,需要设计哪些服务
  • Storage:每一个服务对应的数据存储,应该如何设计数据库的schema?应该选用何种数据库?
  • Scalability:为了保证高可用、高并发、高一致性,该如何进行进化?

也就是所谓的4S分析法。其中确定Scenario是最为关键的,需要和面试官充分沟通交流,明确要实现的功能具体是什么,我最喜欢的架构师说过一句话叫:“脱离业务的架构设计都是耍流氓”。

把Grokking the System Design Interview的课程看完了以后,你会发现,对于系统设计常用的技巧其实不是特别多。只要你能清楚的分析出要实现的功能和要实现的服务,基本上就成功了一半,对于scalability上的扩展和技术选型,常用的技巧例如:

  • 考虑 读写分离缓存 来减轻数据库的读写压力
  • 对于多服务的场景,考虑 垂直拆分 服务的方式来解耦
  • 对于数据量比较大的场景,考虑 水平拆分(分库或者分表)来减轻单个数据库的压力
  • 对于耦合比较严重的设计,采用引入 消息队列 的方法来解耦
  • 对于查询需求比较复杂的场景,采用 数据冗余 来解决不同查询需求的问题

在学习的过程中,可以像我上述这样,把一些知识点和技巧总结起来,方便复习。

上面说的更多侧重的是面试准备方面,适用于短期冲刺、临阵磨枪的同学。如果想要切实在架构方面所有成就的同学,还是推荐打好基本功:

  • 多去看各种大厂的技术博客,里面有很多落地的系统设计方法和方法论
  • 阅读《Designing Data-Intensive Applications》等必读教材
  • 多看源码和white paper

[本文首发海龟龟论坛,未经允许,谢绝转载]

3赞

首先是恭喜!然后是感谢分享!通过自己努力去拿到自己想要的东西的经历真的特别棒!

(让我回想起作为家属见证 @reylo 狂刷题的那几个月 :joy: :joy: 太不容易啦!)

1赞

恭喜恭喜!楼主真的准备得很全面充分,学习一个!
同时也祝楼主新工作顺利,有什么工作新感受也欢迎分享呀~