Software Engineering

什么是Software Engineering

软件工程师(Software Engineer)一般指从事软件开发职业的人。软件工程师们也常称自己为软件开发师(Software Developers)或程序员(Programmers),也就是俗称的“码农”和“程序猿”。从事软件工程师的人靠写代码为生,通常的标签是高智商,低情商,爱钻研,单身狗等等。

在美国不管是东岸、西岸还是中部,对软件工程师的需求都很旺盛。工作机会最多的几个区域有:

硅谷(South Bay): Google, Facebook, Netflix, Apple, LinkedIn总部所在处

旧金山: Uber, Airbnb, Lyft等独角兽公司总部所在处

西雅图地区: Amazon, Google, Facebook, Uber, Airbnb, Snapchat, Oracle等公司设有分部, 同时也是Microsoft总部所在处

纽约: 金融服务业公司如Two Sigma, Hudson River Trading, Bloomberg, American Express, Goldman Sachs等都对科技人才有大量需求, Google, Facebook, Uber等科技公司在纽约也都有相当大的规模

此外,芝加哥, 德州的奥斯汀(Austin, TX),还有洛杉矶也都有相当多的工作机会。

Software Engineering里的五花八门

软件开发从功能上可分为三类:

应用软件(Application Software), 如Google Chrome, Microsoft Excel, Adobe Photoshop, Minecraft等

系统软件(System Software), 如Microsoft Windows, MacOS, Linux, Android等

软件开发工具(Programming Tools),如GCC, Valgrind, Python, JVM, Vim等

软件开发从阶段上分为设计(Design)开发(Development)测试(Testing)和维护(Maintenance)四个阶段。软件工程师的职责其实是因公司而论的。有的公司分工非常细,四个阶段有不同的岗位:

设计—程序架构师(Software Architect)

开发—软件开发师(Software Developer)

测试—软件测试员(Software Test Engineer or QA Engineer)

维护—运维工程师(Site Reliability Engineer or DevOps Engineer)

也有的公司把负责以上四种的统称为软件工程师。

做Software Engineering的优点

工资高

软件工程师的起薪是公认的所有行业中最高之一(甚至没有之一)。通常一个刚入职的软件工程师在总收入(底薪+年终奖+股票)上就能和其它行业工作数年的人平起平坐。具体薪资情况下文有详细介绍哦。

工作时间固定

那有人会问了:工资这么高,工作时间是不是特别长?还真不是!程序员的工作时间,尤其是在美国工作的程序员(国内情况可能会稍微惨一点),通常都是非常稳定且“健康”的。许多大公司的程序员都是朝十晚六,而且还可以经常在家工作。

接触新鲜事物

走在科技最前沿的软件工程师比其它职业都更有机会接触到最新鲜,最酷炫的事物,比如像VR(Virtual Reality)、AR(Augmented Reality)、区块链(Blockchain)这样的技术。而且科技公司的工作环境都比正常公司有趣很多。

成就感

从事软件工程师的人通常都对于电脑和科技非常感兴趣,不论是工作上还是业余时间,能够看到自己编的代码完成一项任务是非常有成就感的。而且万一一不小心让你做出了下一个Facebook或者Amazon,那就再也没人敢叫你“码农”了。

必备技能、适合人群

软实力(Soft Skills)

解决新问题

软件工程师遇到的每个Project都是新的挑战,用尽各种办法解决问题是一个成功的软件工程师最重要的技能。

不断学习

不管是编程语言或框架,还是其他工具,都在不断更替,一个没有好奇心去学习掌握最新最热的技术的程序员会很快被淘汰。

团队合作

一个有影响力的项目是无法一人完成的,能否有效和各种级别各种风格的程序员合作是影响成绩和晋升的重要因素。

硬实力 (Technical Skills)

精通Java或Python或C++

编程语言是软件工程师最重要的工具。一个优秀的程序员不需要会很多编程语言但必须要精通某一门。

数据结构和算法

数据结构和算法是软件工程师面试必考的技能。一个优秀的程序员懂得根据具体情况对时间或空间进行优化。

系统设计

设计大型的可扩展系统(Scalable System)的题目时常出现在Experienced Hire的面试中。即使是New Grad也应该对一些经典的设计类题目有所了解,比如如何设计Twitter或如何设计Web Crawler。


未来发展路径

刚入职的New Grad为Software Engineer 1 (PhD除外, PhD入职即为2级),一般两年后升级到Software Engineer 2, 再过三到四年后升级为高级工程师(Senior Software Engineer)。 到了这个级别可以选择继续走技术路线做Individual Contributor,也可以走管理路线做Engineering Manager。

如果走技术路线继续做Engineer,那么下一级是资深工程师(Staff Engineer), 然后是高级资深工程师(Senior Staff Engineer)。资历较浅的工程师(Junior Developer)一般负责大项目中的细节,而资历较深级别较高的工程师会负责整个项目的设计和任务分配。有些资历较深的工程师还有Tech Lead的职位,对于整个项目进行技术上的指导和把关。

如果走管理路线做Manager,那么下一级是Engineering Manager, 然后是Senior Engineering Manager, 如果对于公司的贡献够大还可以升至Director, VP, 乃至SVP。

在职业初期跳槽的工程师很多,在工作机会很多的湾区,在同一家公司待的时间平均为一年至一年半。随着资历的上升在一家公司工作的时间也会变长,不乏有在同一家公司的做5年以上的高级工程师。

薪酬、工作时长

薪酬水平

Google, Microsoft这样的科技公司的软件工程师的薪水由基本工资(Base Salary),年终奖(Bonus)和股票(RSU)三部分构成。当工程师们在谈论年收入或比较各家公司Offer时,一般都用三项总和。

这个账怎么算?下面由专业的程序员揭秘一下!

Offer Letter里,基本工资和股票是保证的,不受个人或公司业绩影响。年终奖一般为k% * 基本工资。k取决于工程师的级别,、当年个人以及公司业绩。比如一个GoogleNew Grad Base Salary$110K,年终奖为15% * Base Salary也就是$16.5K

上市科技公司的Offer一般会给一定数量的自家股票,但会分成几年分发。比如Google给了240Alphabet Inc. Class C Capital Goog),但是分成四年给。所以每年会得到60Goog。如果第一年Goog平均价格为$1.1K,那当年股票的收入即为$66K。如果第二年Goog均价涨到了$1.3K,那第二年的股票收入将为$78K

软件工程师薪资待遇普遍丰厚。一线公司的New grad年收入普遍在$140K,有些公司甚至能达到$200K。随着级别提高,收入范围也会拉大。一线公司的高级工程师收入在$300K$400K。资深工程师的年收入一般为$400K$600K。

工作时长

软件工程师的工作时间通常比较稳定,尤其是比较大的科技类公司。一般每天朝10晚6,一周工作40小时是比较标准的。虽说大多数程序员会利用自己的时间补充知识,提升自己,但这个行业总体来说还算是有比较好的Life Style。但是在有些创业公司,尤其是中国,软件工程师需要经常加班,每周工作时间甚至可以达到80小时或者更多。

常见公司

上市公司

上市公司中Google, Facebook, Netflix的薪水和面试难度都是行业里的标杆。此外Amazon, Microsoft, LinkedIn, Bloomberg, Apple也都是值得一去的一流公司。业界流传的“FAANG”就是指的Facebook,Apple,Amazon,Netflix,Google。

独角兽公司

类似Uber, Lyft, Airbnb, Robinhood这样的独角兽公司门槛不低于以上的上市公司,而且工作节奏更快所以很适合更有野心也愿意接受风险的软件工程师。

金融服务公司

金融服务业中有一些以科技为核心的公司,如Two Sigma, DE Shaw, Citadel, Hudson River Trading, Jump Trading。这些公司软件工程师的面试难度和薪水有时会更高但工作压力也会更大,适合对数学或金融感兴趣的软件工程师。


申请流程、时间线

New Grad职位需要在入职前一年的10月中旬之前投完简历。比如要2022年暑假入职那就得在2021年的10月中旬之前完成申请。

申请途径分三种:公司官网,校招(Career Fair),和内推(Referral)。对于申请New Grad职位的应届毕业生来说校招是最容易拿到面试的,所以在Career Fair上务必好好表现。对于已经有Industry经验的Experienced Candidate来说内推无疑是最有效的。

New Grad Candidates要让自己从同学中脱颖而出,最重要的是要有实习经历 (Internship)。所以如果要在2021年10月中旬之前完成申请的话就必须有到2021年的暑假实习。暑假实习的时间表和全职的时间表相似,也就是说在2020年的十月中旬前要申请2021年的暑假实习。

如何为入行做准备

刷题

刷题是必不可少的。Leetcode, Hackerrank都是很好的工具。《Cracking the Coding Interview》还有《The Algorithm Design Manual》也都是很好的复习书籍。

mage 0he Algorithm Design Manual Steven S Skiena 2nd ed {Version E-B00k !!!}

准备出色的简历

一份好的简历可以让你更容易通过初步的筛选来获得面试的机会。如果你对你的简历不自信,你可以参考Offer帮为你精心准备的Insider Guide for a Perfect Resume,以及Verb List来解决让你头疼的动词使用问题。有一份Draft简历之后,一定要记得去找一些有经验的人来帮你修改(例如学校的Career Center,同学或者目标公司的员工;Offer帮的简历完善计划也会有专业的招聘官来帮你逐行逐句修改简历)。

Mock Interview

找同学来模拟面试能让你在真实面试时不那么紧张。多做几次Mock Interview还能让你发现自己面试时的小毛病。Offer帮全方位加速计划中也会有FLAG的老师来帮你进行更专业的Mock Interview。

多面试

就算不是自己心仪的公司也千万不要放过面试的机会。每次面试都是一次提高自己Technical Skills和Interview Skills 的绝佳机会。

面试考点解析

面试中可能会遇到 …

你的简历 (Interesting Projects, Internships, etc.)

数据结构和算法(Data Structures And Algorithms) - Hash Tables, Binary Search Trees, Sorting Algorithms, Heaps, Dynamic Programming, etc.

CS 基础知识 -- e.g., Difference between threads and processes

编程语言相关的问题

现场编程。对于每一道题,你都需要做到:

1. Develop the algorithm

2. Implement your algorithm in Python/Java/C++

3. Come up with test cases to find and fix the bugs in your code

4. Analyze the time and space complexity of your implementation

逻辑难题(Logic Puzzles)

系统设计(System Design)

Behavioral Questions --可以戳哈佛大牛的Behavioral Interview指南详细了解

面试中的几个注意事项

遇到问题没听懂或者面试官问的不清晰的,在回答之前一定要向面试官确认清楚问题,否则就会答非所问。如果你觉得需要自己假设一些条件,注意一定要跟面试官确认你的假设是合理的。举几个你可以向面试官确认的问题:

"What should I do if the array is empty"
"Can I expect the input to be reasonable?"
"Can there be duplicates in the input array?"

在解答问题或者现场编程的时候,一定要向面试官阐述你的思维逻辑,有些面试官对于你的想法和解题过程比答案更为看重。这样的好处还在于如果你卡在一个环节,面试官还可以根据你阐述的内容给你一些提示。

在解题的过程,尽量想象成你在跟同事一起解决一个难题,这样就把面试变成了跟面试官一起的一次讨论,而非给你的一场测试。

遇到不会解答的问题,也不要放弃,尽量说出你懂的内容。

多注意听面试官说了什么,不要开始解题就进入自闭模式,有的时候面试官会给你很多有帮助的信息,同时也可以显示出你能够接受新鲜事物和想法。

优化,优化,再优化(Never stop optimizing)。如果你觉得你写出的算法在运行时间上已经做到最好了,尝试从其它角度去进一步优化 。

如果一个问题可以有不同的方法解答,而你能向面试官解释每一种方法的优缺点,将会非常加分。

写代码时要注意有条理性。尽量不要写太长的Function,而是去写相对短一些的,比较独立的代码,这样不但能体现你的逻辑,也能让代码本身方便面试官理解和测试。不要纠结编程语言中的语法错误。

面试前做足对于公司的Research,这样不但遇到面试官问公司相关的问题时不会傻眼,也可以帮助你在最后问面试官问题环节得到一些灵感。