Published on

转职前端工程师的海外求职 (德荷英日新) 心得 I — coding bootcamp 之后的能力养成篇

目錄

嗨,相信你会点入这篇文章,可能是因为你看到 coding bootcamp 的标题,也可能是有海外求职的打算。在往下读之前请先让我介绍自己,以及说说这系列心得会谈先什么。假如你有觉得符合你的需求再往下读,可能比较不会浪费时间 (因为文章会有点长 XD)。

先说说我的背景,我是个平凡的台湾人,人生前 24 年没碰过程式,两年前开始透过线上课程 (YouTube & Udemy) 自学程式。去年报名了线上 Alpha Camp 的实战课程 (Alpha Camp 是一个线上 coding bootcamp,详见此),后来转职软体业,目前是有约一年多开发经验的前端工程师。

前阵子因为家庭规划要搬去欧洲,所以我也顺着找了在欧洲的软体工程师工作,最后有顺利拿到一些工作机会。由于过去在网路社群中 (Medium 与 PTT 等地方),获得很多前人分享的宝贵经验,因此希望透过接下来两篇文章回馈社群。第一篇心得 (也就是这篇) 会是谈 coding bootcamp 后的能力养成。主要是网路上比较多分享从非本科转成工程师,但比较少分享转职成功后的持续养成 (我的个人经验来说,转职后反而才是挑战的开始),所以希望这段经验能协助那些刚顺利转职的人。

假如你比较想直接了解找海外工作的过程,可以直接跳过这篇。在第二篇《转职前端工程师的海外求职 (德荷英日新) 心得 II — 找工作与面试篇》我会分享我获得各国面试机会的过程,以及线上面试各国前端软体工程师的实际经验 (包含被问到的问题)。

直球对决冒牌者症候群

如上面提到,转职后才是挑战的开始。假如你有读过我先前写的 《A Philosophy of Software Design》心得 I — 写出复杂度低的软体,你大概已经知道,我在刚转行时刚发的几次 PR (pull request) 被狠狠地在 code review 时给了数不清的评论 (有如一张充满红字的考卷 orz…)。

当时最直接的想法是很挫折,但也很清楚意识到自己的不足。为了有效对抗这种负面感觉,我决定直球对决,开始用下班跟周末补上不足的部分,包含开始读设计模式、开始补一些电脑科学的知识。会选择直球,是因为我知道以自己的个性,这些不补起来,我会一直陷在这种负面状态中。唯有让自己足够扎实,才能摆脱这种状态。

免费的开放式线上课程

我个人看了三所不同大学的基础电脑科学课程,分别是哈佛的 CS50、史丹佛的 CS106A、柏克莱的 CS61B。这三门 YouTube 上搜寻都可以轻易找到。网上还有很多人也推例如 MIT 的 6.0001 以及柏克莱的 CS61A ,但那两门相对更基础,会更适合转职前看。此外,我选择上面说的那三门,主要是授课教授的风格,这三门课教授的风格各异,但都是我很喜欢的。

虽然这三门课重叠的内容可能有七八成,但因为不同教授讲解,有时切入的角度不同,或者解释的方式不同。即使是听过的概念,都能够更强化理解,或是有更深层与延深的理解。因为教授讲得都很生动,我基本上当追剧在看,利用通勤搭捷运的时间 (去年台湾还没有疫情在家工作时)、中午吃饭的时间来追。很推荐同样是刚转职的人,透过这些基础课程来补足,帮助很大!

觉得受用无穷的书与文章

  • 《Head First Design Patterns》这本真的深入浅出讲设计模式,非常新人友善
  • 《A Philosophy of Software Design》这本读完程式设计功力瞬间大增
  • 《JavaScript: The Good Parts》JSON 格式发明者写的,让人对 JS 理解加深很多
  • 《追求神乎其技的程式设计之道》很热血的连载,读完对如何精进程式功力有很大启发

对前端工程 (React 开发者) 很有帮助的内容

虽然不一定适用每个人,但我个人很认同 CS50 与 CS106A 课程中都有提到的概念,就是电脑科学的思维与程式设计的思维,有非常多部分是跨语言的。我自己在打底的过程中,有些内容是用不同语言学,核心概念本身有学到外,也多打开一些窗。举例来说,因为 CS106A 与 CS61B 两门课都是用 Java 教,所以公司的新产品决定用 TypeScript 写时,对于开始写型别这点,几乎没有太多要适应的地方 (虽然还是很常被一些 React 搭配 TS 时让人困惑的地方绊倒很多次就是了…)。

刷题补上不足

在上班被狂电,下班疯狂恶补后,才总算有点觉得稳下脚步的感觉。在稳下来后,我决定面对一个过去一直逃避的点 — 资料结构与演算法 (data structure & algorithms)。由于过去工作上其实没有真的用到太多演算法的东西,只有在转职前曾经练习过 LeetCode 题目,但也只做了三十题左右;简言之就是在这方面我的底子非常薄弱。

跟先前经历冒牌者症候群一样,我知道要克服这种状态,最有效的方式就是多学习、多练习,直到我真的把不足的地方补起来。因此我就开始了为期四个月的每天刷题时期。除了 LeetCode 之外,我有额外用了一些付费资源。到实际面试之前,我完成了以下的练习

  • 《Cracking the Coding Interview 6th Edition》 — 189 题
  • AlgoExpert — E25 / M55 / H46,总计 126 题
  • LeetCode — E50 / M60 / H2,总计 112 题

《Cracking the Coding Interview》是很多人推的一本书,从观念到实作题目,都有很完整的讲解,因为里面的题目比较简单,假如跟我一样演算法题目的基础薄弱,从这本书开始,是个不错的选择。读完这本后就可以进到刷题实作的平台 (例如 LeetCode)。

除了买书外,我有额外买一个叫 AlgoExpert 的课程。会买主要是先前有订阅里面讲课老师的 YouTube 频道 (有兴趣的人可以在 YouTube 上搜寻 Clément Mihailescu,讲师之前在 Google 与 Facebook 当过软体工程师),加上看了它免费试看影片后,觉得教的还不错,因此决定买来看。课程约是三千多元台币。我个人觉得花这三千台币左右的费用,前期还算值得,但后期就觉得还好了。

前期觉得值得,主要是因为我底子不足的关系,所以观念讲解对我特别有帮助。但后期觉得不那么值得,主要是发现还是有蛮多好的 YouTube 频道,基本上可以取代 AlgoExpert。其中我个人最推一个叫 NeetCode 的 YouTube 频道。我在该频道不到五千订阅时就订阅,写这篇文时它已经超过三万订阅。但我觉得好频道值得更多订阅,所以特别推广一下,一人一订阅支持免费的好频道 XD

在看完 AlgoExpert E/M/H 共 126 题的讲解影片后,发现 NeetCode 完全可以取代 AlgoExpert。这不是说 AlgoExpert 不好,毕竟当初我会买也是因为有很清楚的概念讲解,同时通常会提供多个解,包含最佳解,以及有题目分类。只是这些 NeetCode 也是全都有做到。

举例来说,当初看到 AlgoExpert 这题很常在 Phone Interview 被问的费氏数列 (Fibonacci Number) 问题。相信多数人都知道,这题最直观的解法是用递回 (recursion),但是时间与空间复杂度都很差;假如用记忆化 (memoization) 的方式解可以大幅优化时间复杂度;而用动态规划 (dynamic programming) 方式则可以再进一步优化空间复杂度。对于刚踏入刷题领域的我来说,看到这样逐步优化的解法,觉得真的很有帮助,大开眼界。

不过,后来看到 NeetCode 有完全一样的优化讲解。 LeetCode 的 70. Climbing Stairs 是完全一样概念的题目,而 NeetCode 也是很清楚地讲了三种不同的解法。多看几个 NeetCode 的教学影片后,就越来越觉得当初花钱买 AlgoExpert 的自己很盘……。

另外,AlgoExpert 宣称有个好处是有帮忙做选题,所以可以省去选题的时间。不过其实网路上找一下,就可以看到像是 Blind Curated 75 这类别人已经帮忙选好的 (NeetCode 有个播放清单专讲这些题目 XD),而 AlgoExpert 选的题目跟那些其实没差太多。所以是后回头看,我觉得底子够扎实的人,纯粹练习题目来说,不太需要 AlgoExpert,有 LeetCode 就很够了。跟我一样底子不扎实的,看 NeetCode 就很够。我没有要黑 AlgoExpert 的意思,如上面提到,我觉得它的内容做得很好。这边纯粹想说,假如你不想跟我一样后来觉得自己很盘,就直接看 NeetCode 吧~

实际开始刷题后,我大概花三周读完 《Cracking the Coding Interview》的 189 题,基本上中餐读、下班读、周末全天读。接着花六周看了 126 题 AlgoExpert 题目,并且每题实作。剩下的时间都花在 LeetCode 上。因为 AlgoExpert 蛮多题目都是从 LeetCode 上汇集来的,所以遇到一样的题目,就解比较快。

在实际做 LeetCode 时,我是参考「半路出家软体工程师在矽谷」大大在他的部落格写的一篇文,标题是《听说你最近在刷题- 软体工程师的面试一定会遇到的资料结构及演算法关卡》。在参考别人解法时,我多半是点击 Most Votes 来看。即使最多人投的解法用的语言不是我用的,但思路上通常能给很大的启发。我会吸收并消化后,试着用 JavaScript 再写一次。

心态调适

大家都知道想申请海外软体工程师的工作,资料结构与演算法题目是必须练扎实的。但是为什么真正能做到的人还是有限呢? 我认为最关键的原因,还是因为这个过程并不容易。以我自己来说,我原本待的公司也是很棒的公司,所以有时候卡住、累了的时候,脑中就跑出「还是就算了」这种想要求安逸的想法。

身为平凡人,能否在这漫长的修炼过程支撑下去,我觉得反倒是决胜的关键。因此最后这个段落想要分享一些我能够在四个月,每个下班与周末持续做刷题的一些小撇步。可能不一定适用每个人,但假如你也有一度想说算了的话,或许可以参考这些作法。

(I) 有清楚的动力 身为平凡人,我觉得我能在漫长自我精进持续的关键原因,是因为有很清楚的动力。之所以兴起去欧洲工作的想法,是因为今年五月台湾疫情关系开始在家工作时,我跟另一半实在没事做,每天看各种 YouTube 频道,其中包含旅欧工程师的 YouTube 频道。不看还好,一看则一发不可收拾,例如这个在荷兰的工程师 HoiAle,或这个在德国的工程师 Stanley 的太太 Weiwei ,看到它们工作与生活都享受,就觉得好想也这样。

当想到未来能够早上先去滑个小船,下午再继续写程式,动力就马上起来,然后又能多刷三题。假如觉得累的时候,再看一下能请两周假租一台露营车去德奥玩一圈,动力又起来,然后又能多刷五题 XDD 总之有清楚的动力,坚持就相对不困难。

(II) 转换思维享受过程 在刚入行半年时,不论是上 CS 的线上课程,或是读软体设计、JavaScript、React 的内容,因为读的东西在工作上可以立即用到。但是资料结构跟演算法的题目练习,说实话非常少出现在实际工作中。因此自然会觉得「到底为什么要做这件事?」或是「假如只是为了面试,花时间在这上面浪费掉的人生,真的值得吗?」等等的声音。

不过我后来发现换个角度,把演算法当成艺术来欣赏,会有截然不同的感受。举例来说,我为了模拟在时间压力下解题目,后期开始打 LeetCode Weekly Contest。印象很深刻的是 LeetCode 1980 题 Find Unique Binary String,我那时用 backtracking 的方式解出来,还觉得自己解得不错。结果后来看讨论区有人用 Cantor’s diagnolization 的方式解,当下觉得惊为天人,竟然可以有这么聪明的方式,在萤幕面前赞叹了好一番。这种欣赏的角度,让解题目不再枯燥,而是真的觉得很享受~

(III) 放宽心但保持成长思维 很多时候,最佳解就是不那么容易被想出来。举例来说 LeetCode 287 题 Find the Duplicate Number。一开始看到这题很自然想到,可以先排序然后透过回圈来判断是否重复;又或是建立一个 hash map,然后一样搭配简单的回圈,来解决这问题。但偏偏题目中有说,不能更动原始阵列 (换句话说不能排序),同时只能用空间复杂度 O(1) 的方式来解 (换句话说不能用 hash map)。

然后我的脑袋在挣扎了半小时后,就宣告放弃。这时去看讨论区别人的解法,看到某篇 Most Votes 讨论区中有人分享了这篇,某个史丹佛大大写的文章 。文章开头提到,这题要用 O(n) 的方式来解,连史丹佛的演算法大师 Don Knuth 都花了 24 小时才解出来。看到这段我就放宽心了,毕竟连演算法界的大师都要花这么多时间,我在半小时内想不出来,就别那么苛责自己了! 当然半小时内想不出来,不代表我要就此放弃。把这篇文章读懂,再把文章中提到的 Floyd’s cycle detection algorithm 搞懂,最后即使我不是原创想到这个解法,但未来遇到类似的问题,我也变得有能力解出来。

上面提到的 NeetCode 有讲解这题,讲得很清楚,推荐有兴趣的人可以看看

(IV) 适当休息与调节 因为能力培养是长期的马拉松,而不是短跑;因此,适当的休息与调节很重要。我自己的方法是看韩剧,感谢在我申请海外工作的期间,有《机智医生生活》以及《海岸村恰恰恰》这两部好剧 (虽然金宣虎黑掉,但剧真的很好看)。每周看一两集韩剧是我犒赏自己的方式,看得时候就好好放松,看完后就觉得又活过来了~。

当然你可能有不同的调节方式,但切记在每天高强度自我锻炼的同时,务必要有调节。如果去咖啡店、去爬山、去找朋友聊天等等不同方式,能让你好好充电,那就别吝啬每周拨出一点时间来做这些事呀。

下一步:申请与面试

当把底逐步打起来后,下一步就是实际申请海外工作,以及实际面试了。我将在下一篇《转职前端工程师的海外求职 (德荷英日新) 心得 II — 找工作与面试篇》分享我从开始申请到实际面试的心得,有兴趣的人可以接这看下去。