毕业了,开始新的生活!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dc_726/article/details/76040037

转眼间就毕业了,短短的18个月过得真快!因为一直忙于上课找工作,所以好久没发文章了。现在已经重新开始上班一个月了,渐渐安稳了下来。开始适应新生活,也重新开始走自己的学习节奏。希望渐渐能多写一些技术文章,继续学习进步!这篇“回归”的文章就先简要总结一下这一年半的经历吧,也算是给过去的生活画上个句号。


1.研究生学习总结

读研期间最骄傲的三件事儿就是:读了一所不算很有名但是性价比很高的学校,选了很多很好的课学到了很多受益终身的东西,最后GPA还不错而且没耽误找工作。最遗憾的事儿就是没选上Compiler Design,因为本科就没学好编译原理,想好好学学。顺便推荐一下读研时都快翻烂了的两本书:《Introduction to Algorithms》第三版和《Discrete Mathematics and its Application》第七版。

  • 第一学期
    • Analysis of Algorithm
    • Operating System
    • Theory of Database
    • Visualization
  • 第二学期
    • Computer System Security
    • Distributed System
    • Theory of Computation
    • Logic Programming
  • 第三学期
    • Principle of Programming Language
    • Fundamentals of Computer Network

就像之前总结过的那样,研究生的课程还是很让人长见识的,关于这部分感受以及第一学期的总结之前写了比较多,感兴趣可以翻看。下面重点学一下第二和第三学期的课程,比如Theory of Computation和Principle of PL,可以说是Computer Science领域的倚天屠龙了,分别从这一学科的两大开山鼻祖Turing和Church的图灵机和Lambda表达式诠释什么叫做计算,学起来感觉还是相当震撼的。Distributed System则深入了目前最火热的分布式计算,从理论出发,让看似无法证明正确性、高深莫测的分布式系统变成了与OS、DB等传统科目别无二致。Logic Programming课则使用Prolog语言,看似古老而无趣,实际上玩转了CS的另两个核心——逻辑、树和递归。最平淡无奇的Computer Network课则用几节课就带过了TCP/IP等基础知识,剩下一半的时间都在讲述更加现代和高级的内容,比如数据中心的TCP/IP变种、SDN、最新的HTTP2和Quic协议等等。这些知识是宝贵的,更宝贵的是这段时间养成的学习方法,怎样学、去哪里找资料、如何验证总结等。


2.北美找工:Leetcode教我的事

本来写了单独的一篇《Leetcode教我的事》,但是因为刷题中的小细节太多了,迟迟没有写完,于是就在此分三部分摘录一些重点,等什么时候写好了再发出来完整版。从16年的五月开始准备,看书、刷题、改简历、海投、找内推,到17年3月拿到offer。除了辛苦、情绪起伏、偶尔无助,现在回想起来还挺有意思。本来就是一算法老白,最后在Leetcode论坛上竟然还有人关注,还有几百的声望,那感觉真是妙不可言!重点看2.3部分吧,因为Leetcode原题在工作中用处很小,真的很少有机会自己写个数据结构、搞个DP或者递归,所以更重要的收获就是思维的训练,不管写什么代码都保持严谨的态度和良好的习惯

2.1 为什么要刷题

“因为本科时的无知愚昧,之前从未接触过刷题、数学建模、ACM之类的东西。现在为了找工作,就得遵守“游戏规则”,于是就刷起题来(关于国内和北美找工作的差异感触颇多,以后可以写一篇分享吐槽一下)。从16年夏天开始刷题,中间隔了第二学期的学习而扔下了两个多月,现在又重新捡了起来。经过一遍、两遍、三遍的练习,虽然还没找到工作:|,但也有了些感悟,于是记录下来分享给大家。主要使用的平台就是现在最火的Leetcode,辅以Hackerrank、LintCode、《Crack the Code Interview》等资源。

先简单说一下这些平台和资料的特点,以及本人的一些用法和经验:

  • Leetcode: 现在最火爆的刷题平台了,可以说是事实标准了。而且新题出的非常快,现在已经奔着五百道去了。找个工作都快赶上准备ACM了……
  • Hackerrank: 虽然不如Leetcode上的题那么经典,但是很多公司发的OA(Online Accessment)都是在这个平台上做的。所以还是得上去练练,熟悉一下。题目特点就是长!不像Leetcode题目那样直接,Hackerrank的题一般都会套着一层“壳”,让你感觉这题很接近现实生活,好像从来没见过。其实扒掉外壳一看,就是Leetcode上某道题或者某个经典算法的变形。
  • LintCode: 有一些Leetcode没有的题,以及少量的Leetcode加锁题甚至Crack the Code Interview里的OO设计题等。但缺点是部分题的Java版本不一致,有的8有的7,Test Case不全等问题,可以作为对Leetcode的辅助。
  • 《Crack the Code Interview》:应该找工最常用的一本书了,里面的大部分题都是面试高频题。其实很多已经被Leetcode覆盖到了,所以还是做Leetcode为准,累了可以看看里面的讲解,加深一下印象。”

2.2 刷题能学到什么

“接下来就说一下都学到了什么。其实半年学下来真正感到最重要的肯定不是那些牛人写好的最优Solution。这样我想起了以前看到的一句话:牛顿的万有引力太牛了,但你学会了也不代表你就成了下一个牛顿,因为在背后牛人是如何思考解决问题的过程是不会告诉你的,或者也没法传授给你。这个道理放在刷题上一样适用,关键是思考,而不是被牛人写好的答案。想想你已经找到工作,甚至工作稳定后,这些日子还有什么东西是你能回想起来记忆犹新,感到收益良多的呢?下面就谈谈个人的一些感受,重要程度由低到高排列:

  • Core Java:熟悉基础语法,而且很多平台都支持Java 8甚至9,你大可以借此机会用各种新语言特性,让你的代码更简洁更Cool~
    • API:Character/String/StringBuilder、Integer/Long/Math、Array/List/Queue/Stack/HashMap/TreeMap
    • I/O:Leetcode这样的平台是不需要我们处理I/O的,但Hackerrank以及一些公司的OA题目都是要自己处理I/O的,而且Java的I/O又是如此繁杂,所以要想不浪费临场时间就需要提前熟悉做好准备。
    • Java 8:Streams用的不对,最爽是用Lambda方便代替内部类,比如Comparator等,非常简洁!
  • Data Structure & Algorithm 工具箱:其实很多问题都能够在经典的算法书籍里找到对应,所以通过完整的刷一遍题能够让你对常用的算法有个了解,形成自己的工具箱。Combinatorics问题在《The Algorithm Design Manual》中有详细介绍,而String的相关算法在《Algorithm, 4th Edition》中有专门章节,其他所有算法均可参考“百科全书”《Introduction to Algorithms, 3rd Edition》。
    • Data Structure:Linked list、Stack、Hashtable、BST
    • Sorting:Insertion Sort、Merge Sort、Quick Sort、Heap Sort、Counting Sort、Radix Sort、Bucket Sort、Heap & Heap Sort
    • Searching:Hashing、Binary Search、Binary Search Tree、Order-statistic Tree、Segment Tree
    • String:Trie、KMP、Regular Expression
    • Graph:Shortest Reachability、Topological Sort、Bipartite Test、Strongly Connected Component (Union-Find)、Minimum Spanning Tree、Shortest Path (Single Source & All-Pairs)
    • Advanced:Divide-and-Conquer、Combinatorial、Greedy、Dynamic Programming、Geometry (Sweeping)
  • 教科书中没有的实用问题:有一些不好归类,甚至在书里没见过的算法。
    • Sliding window:可能出自TCP/IP的滑动窗口算法。
    • Two pointer scan:最经典的2 Sum、3 Sum都是双指针扫描的范例。
    • Bit manipulation
    • Random generator:一些随机数产生算法。
    • Squeeze space:压缩算法的运行空间。”

2.3 忘记后还剩下什么

“归根结底,最重要是严谨的思考过程。加强逻辑思维能力,解决问题能力,才是最终目的,可能也是多年以后你最受用的东西。以下是个人总结的过程,实际做题和面试时没有这么机械,但加粗的部分是重点,必不可少的。每个人都有自己最习惯的方式,以下仅供参考。

  • 理解问题
    1. Example:举例子对理解问题至关重要,还可以帮助我们找规律,而且最后分析阶段还要用几个例子验证代码正确性。
    2. Input type/format:确定输入的类型和格式 =》 确定入参的Domain值域 =》 设计Edge Case的检测条件(参加后面Cheatsheet)。
    3. Output:输出也是很重要的一点,比如DP问题是要最优解还是要构造的整个路径,那可是差很多的(参加后面Cheatsheet)。
  • 设计
    1. Pick from toolbox
    2. Prepare test case:用前面的例子,再完善一些作为编码后的测试用例,提前列好也有助于正确编码,比如链表问题。
    3. Time/space complexity estimate:提前预估复杂度
  • 编码
    1. Method signature:这也是第一阶段与面试官沟通后的产物,早点写出来便于沟通与确认。
    2. Guard condition:边界检查,避免空指针等非法输入。
    3. Pesudocode/comments:对于可以分出几步的问题一定先列出伪码,以免扎入编码细节后漏掉大步骤。
    4. Invariant/Variable meaning:想好变量、循环、子方法的不变量,这样有助于编码正确性和之后自证阶段。
    5. Short variable name:在不失可读性的前提性,让代码尽量短,所以入参、出参、局部变量的起名很重要。常见的有:循环i/j/k,数组A或nums、长度n、矩阵A、长宽m/n、二分查找的l/r/m、字符串str、栈s、队列q、当前/前驱/后继结点cur/pre/suc、Sentinel头dmy、dfs子方法等。这在Whiteboard面试中,不管对速度、正确性、可读性都是绝对有好处的。
    6. Extract:因为Whiteboard可能不大,所以像DFS、递归以及重复代码等提取成小方法有利于排版。
  • 分析
    1. Read carefully:写完后就做一件事,读,仔细读,使劲儿读。这样可以排出掉低级的语法错误、typo、变量名前后不一致等。
    2. Debug test case:前面排出掉“编译”错误,下面就来排出“运行时”错误。太烧脑的话就在Whiteboard上追踪变量值,这样能更准确一些。
    3. Time/Space complexity:前面预估过,此时就着重分析一下(参加后面Cheatsheet)。
    4. Prove correctness:有了Read carefully + Debug test case + Invariant comment,我们就可以比较自信地讲解为什么代码是正确的了。做好这几步的话,即便有问题也多半是很小的问题,也是可以接受的。

如果面试官抛出了Follow-up(参加后面Cheatsheet),需要我们实现的话,那么再从头开始这一过程。”


3.入职亚马逊一个月体验

三月拿到了Amazon的offer,于是毕业后就搬家到了西雅图。一路也是比较辛苦,还好有公司的相关部门帮助。现在已经基本稳定下来了,行李都到了,找到了公寓,东西也渐渐添全。就这样离开了纽约,开始了新的生活。西雅图的夏天还是非常友好的,天天大晴天,湖水植被多得不像话,翡翠之城的美誉的确不是瞎说的。在吓人的九个月的雨季来临之前,也算是给了一个适应和缓冲的时间。现在刚入职还不忙,在公司空闲时,突然想起自己九年间都已经在五家公司工作过了。于是就想总结一下入职一家公司后,都应该从哪些方面去学习和成长,哪些东西是最有价值的。

  1. Logistics: culture, schedule, benefits, payroll, time off - 刚入职时了解公司的文化和相关福利,看有什么是必须入职后要马上做的。
  2. Development process I (Familiarize yourself) - 搭建开发环境
    • Env: desktop, VM application
    • Version control: SVN, Git
    • IDE & plugin: Eclipse, Intellij
    • Build-and-deploy: Ant, Maven, Shell
    • Debug/Make small change
  3. Development process II (Start coding) - 了解整个开发流程
    • Dependency management: Maven, Gradle
    • Scaffold
    • Test: TDD, unit, integ, prod
    • CI: Jenkins with plugin
    • Code review: self, pair
    • Bug tracker: JIRA
  4. Development process III (Being expert) - 对整个系统有深入了解
    • Read code: how it works (entry point, scripts, architecture, data source, external systems…)
    • Tech stack: language, frameworks, web server, load balancer, message queue, worker, cache, database, VM
    • Tech decision: license, cost, goal, performance, scalability, reliability, security
    • Design: doc format, estimate, prototype
  5. Release process (Get involved in real world release) - 发布后的监控和线上问题解决
    • Stakeholder: Customer, ProjMgr, ProdMgr, Architect, Leader, QA, Operations, Support, DBA
    • Schedule: milestone, deadline
    • Methodology: Agile
    • Release: AutoDeploy
    • Monitor: Log, DB, CloudWatch
    • Troubleshoot: Patch, hot fix, escalate
  6. Continuous learning - 持续学习以及非技术的东西
    • Business model
    • Coding convention
    • Wiki, knowledge base
    • Training resource
    • How to write tech docs & ppt

这里列举的有点像个模版,也可以简单地用来检测一家公司的开发章程是否完善。正好以此为例,简单说一下Amazon的编码生活,虽然Amazon因为工作压力和福利等方面,在所谓的FLAG联盟(Facebook、Linkedin、Amazon、Google,也可以额外算上Microsoft)中是口碑比较差的一个。但是作为在国内工作多年的“老兵”表示,可能还是要比国内互联网要轻松一些,加了“可能”因为才入职不久所以只能根据目前观察到的状况作猜测。首先,工作环境还是很不错的,赶上了好时候,入职就给配了i7+16G内存的MacBook Pro,外加两个有点夸张的27寸显示器。现在平时就用了一个看邮件和聊天工具,尝试开过两个感觉有些晃眼…… 可以申请换一个34寸的曲面显示器,长度非常夸张。另外还可以申请换升降桌,本想在家里也弄一个,上网一查才知道看着简单的桌子竟然价格不菲。另外,休息室和茶水间跟福利好的公司虽然没法比,但已经够用。福利方面就是基本工资、签字费(按月发的奖金)、分四年才能兑换的股票、完善的保险、401K养老金、以及少量补助。

再说上面模版里对应的内容。Amazon的开发流程和工具非常完善,甚至有人说Amazon对自动化工具有些过于狂热了。确实有一些,因为方方面面都有现成的工具,从代码生成、依赖管理、版本管理、环境分配、打包部署、线上监控等等,如果大家感兴趣可以重点看两个工具Brazil和Apollo,不知道是不是最出名的,但在内部用得最多。因为Amazon对开源的贡献较少,所以大家只能自行搜一些文章看看介绍和设计理念吧。目前在AWS下一个组做ElasticSearch,刚接触还了解不多,以后会逐渐学习并总结一些有用的文章。

关于生活,这边的活动还是挺多的。有外面的活动,有公司组织的,还有就是每个组自己的。老外们都不用什么准备,随便弄点零食和饮料,大家就能站一起搞一个小时的Happy Hour。还有动不动的各种工作餐。因为现在还没开始算进传说中的oncall rotation里(类似值班,当周的线上出问题了就由你解决),所以压力不大,周围人一般十点左右来,五六点走。周末去去超市,周围转悠转悠。目前还都在适应,估计完全进入正轨还得些时间。

现在回想起这一年半的学习生活,感觉非常值得。一年半前完全不能想象现在的生活,短短18个月生活就发生了巨大变化。但仔细想想,整个过程下来也花了三四年时间,从准备GRE和托福英语考试、DIY自己的文书、填一堆学校的网申系统、之后适应新生活、认真上课做作业、刷题改简历、办理工作相关手续,每一步都很不容易。能有一次这样完整的经历,感觉已经没有什么遗憾了~

附上一个小小的福利,刚入职去硅谷办公室出差时偶遇了Java之父James Gosling,没想到他的办公室就在我们组旁边。老爷子每天来得很早,在一个独立的办公室里安静地工作着,不知道在忙什么。

这里写图片描述

展开阅读全文

没有更多推荐了,返回首页