网站性能检测评分
注:本网站页面html检测工具扫描网站中存在的基本问题,仅供参考。
济南python
「面霸实战」五天拿下Google、Facebook等硅谷五家公司Offer Facebook视频课程
【新智元导读】一位华裔技术工程师曾笑寒连续面试了 LinkedIn、Salesforce、Google、Airbnb 和 Facebook 五家硅谷科技巨头,最终全部都拿到了 Offer。作者分享了在面对五家不同的科技公司及不同的岗位,所做的准备工作、面试技巧以及自己的一些实践经验,希望可以为正在准备跳槽的工程师提供一些帮助。
在 2017 年 7 月 24 日至 28 日的五天里,一位华裔技术工程师曾笑寒(https://linkedin/in/xiaohanzeng)连续面试了 LinkedIn、Salesforce、Google、Airbnb 和 Facebook 五家硅谷科技巨头,最终也全部都拿到了 Offer。
在此之前,并非计算机专业出身、工作时间短暂、知识及经验均有限的作者,在经历一次失败的面试之后,并未丢失信心,而是从头来过。作为一名全职工作者,其在闲暇之余准备面试,能同时拿到 5 家科技巨头的 Offer 这样的结果确实非常地幸运,但是其背后付出的努力也不容忽视。本文接下来将与大家分享作者在面对五家不同的科技公司及不同的岗位,所做的准备工作、面试技巧以及自己的一些实践经验,希望可以为正在准备跳槽的工程师提供一些帮助。
以下为译文:
最初的缘由
起因是 2017 年即今年,我作为一名普通的软件开发工程师,已经在 Groupon 芝加哥总部工作了近三年。这是我的第一份工作,我的团队和项目都非常赞,我们一起构建很酷的东西、在公司内部发挥各自的影响力、发表论文等等。但是,工作轻松,生活自在,随着时间的推移,我发现我的学习速度正逐渐放缓,内心开始希望迎接新的挑战。同时作为一名在芝加哥住了八年的码工,也非常向往湾区的优秀公司。
生命短暂,职业生涯则更短。在与妻子沟通并得到她的全力支持之后,我决定采取行动,做出第一次职业转变。
准备
首先我对机器学习的职位很感兴趣,但其实我申请这五家公司的职位名称和面试过程都稍有不同。LinkedIn、Google、Facebook 的职位是机器学习工程师,Salesforce 是数据工程师,Airbnb 是软件工程师。因此我需要准备三个不同领域:算法和编程、机器学习和系统设计。
由于白天还有一份全职工作,所以只能晚上喝周末抽出一些时间准备面试,总体而言,一共花了 2-3 个月的时间。以下就是我如何在这三个方面做准备。
算法和编程
的确,算法和编程面试并不是评估开发人员所有技能的最好方法,但短时间内没有更好的办法来判断是否是一名优秀的工程师。
这一块其实是最好也最难准备的。一方面有许多的网站提供了大量的题目可以练习,另一方面也需要投入大量时间精力。我主要使用 Leetcode 和 Geeksforgeeks 进行练习,还推荐 Hackerrank 和 Lintcode。我花了几个星期的时间过一遍常见的数据结构和算法,然后针对性地重点关注我不太熟悉的领域,最后解决了一些常见问题。由于我时间有限,我通常每天做两题。
我的想法是:
多练习,没有捷径。与其做完 Leetcode 上所有 600 道题,不如覆盖全部类型并彻底理解每一道题。我总共做了大约 70 道题,我认为已经足够了。我的想法是,如果 70 道题还没有帮助,那么你可能方法有问题,做 700 道也没有任何帮助。做最难的题,其余的都会变得更加容易。如果一道题超过两小时都做不完,可以看答案了。再花时间思考并不值得。做完一道题后一定要看答案。我很佩服那些一行 Python 代码解决问题的人,虽然有时依赖语言的某个特性,但实在是很精妙。使用你最熟悉的常用语言,在面试时可以用到。系统设计
系统设计领域与实际工作经验更密切相关。 如果你有不少系统设计的经验,那么花的时间可以相对少一些。虽然是很看经验,但也还是可以准备的,网上也有很多的经验贴和练习题。我主要阅读关于系统设计面试、大型系统架构、案例研究相关文章。
个人感觉这个领域面试时会涉及很多问题,包括但不限于系统架构、面向对象的设计、数据库模式设计、分布式系统设计、可扩展性等。因为我主要面试的职位是机器学习相关的,所以这次面试遇到的 session 少一些(主要是 Airbnb)。
这些是我认为比较有帮助的一些资料:
http://blog.gainlo.cohttp://horicky.blogspothttps://hiredintech/classrooms/system-design/lesson/52http://lecloud/tagged/scalabilityhttp://tutorials.jenkov/software-architecture/index.htmlhttp://highscalability/虽然系统设计面试会涵盖很多主题,如何回答这些问题还是有一些通用思路的:
先明白需求,然后考虑大框架,最后是具体设计。不要马上跳到细节上,而不弄明白需求是什么。没有完美的系统设计。根据需要做出取舍(trade-off)。尽管如此,准备系统设计面试的最好方法就是坐下来设计一个系统,深入探索你平时使用的工具、框架和库。举个例子,要是工作中用到 HBase,有的人可能就只是简单的用一下 Client 跑一些 DDL,做一些 Get,但有的人可能就会摄入一些了解整个系统的设计,包括整个读 / 写流程、如何保证很强的一致性、次要 / 主要压缩起到作用、LRU 缓存和 Bloom Filter 的作用等等。你甚至可以将 HBase 和 Cassandra 进行比较,看看它们设计上的相似点和不同之处。面试时如果要求你设计一个分布式的键值存储,你就不会觉得太突然。
许多博客也能提供很多知识,比如 Hacker Noon、一些公司的工程博客以及开源项目的官方文档。
最重要的是要保持好奇心和谦虚。像海绵一样吸收知识的养分。
机器学习
机器学习面试可以分为理论和产品设计两个方面。
除非你有机器学习研究经验或者机器学习课程学得很好,那么阅读一些教科书是很有帮助的。经典教材如《The Elements of Statistical Learning》和《Pattern Recognition and Machine Learning》都很有帮助,如果你对特定领域感兴趣,你可以阅读更多相关内容。
确保你理解如偏差 / 方差权衡、过度拟合、梯度下降,L1/L2 正则化、贝叶斯定理、协同过滤、降维等基本概念。熟悉常用公式与模型推导,如贝叶斯定理,如逻辑回归和支持向量机。尝试实现简单的模型,如决策树和 K 均值聚类。如果你在简历上提到一些模型,确保你对其完全理解并能评价其优缺点。
对于机器学习产品设计,要了解构建机器学习产品的一般过程。我是这样做的:
找出目标是什么:预测、推荐、聚类、搜索等。选择正确的算法:监督与无监督、分类与回归、广义线性模型 / 决策树 / 神经网络等。为做出的选择给出原因。根据可用数据选择 / 设计相关功能。选择模型性能指标。可以考虑如何为生产优化模型。我想再次强调保持好奇心和持续学习的重要性。不要仅仅用 Spark MLlib 或者 XGBoost 简单地调用 API 训练出一个模型,我更推荐去研究为什么 Stochastic gradient descent 适合分布式训练,又或者了解 XGBoost 和通常的 GBDT 有什么区别,包括对 Loss Function 的定义有何特别之处,为什么用到二阶导等等。
面试过程
最开始我在 LinkedIn 上回复 HR 的留言,并请其给我推荐职位。在某家明星创业公司求职失败后(我稍后会谈到),我努力准备了好几个月,在 HR 的帮助下,我在湾区安排了整整一周的现场面试。我周日抵达湾区,在世界上最好的几家科技公司五天面试了大约三十位面试官,很幸运地,得到了这五家的工作机会。
电话面试
所有电话面试都是标准的。唯一的区别是面试时间:LinkedIn 面试 1 小时,而 Facebook 和 Airbnb 则是 45 分钟。
熟练程度是电话面试的关键,因为时间有限,通常你只有一次机会。你必须很快判断出问题类型,并给出一个宏观解决方案。一定要和面试官沟通你的思路,说明你的意图。这可能一开始会让你速度慢一点,但沟通比任何事情都重要,会对面试有很大帮助。不要死背答案,因为面试官肯定会一眼看穿。
对于机器学习的职位,一些公司会问机器学习相关问题,因此面试前温习巩固一下机器学习方面的知识与技能。
为了更好地利用我的时间,我在同一个下午约了三个电话面试,每个之间间隔 1 小时休息。这样的做法不一定适合所有人,好处是可以趁热打铁状态好,坏处是如果一个没面好,后面的面试可能会受到影响。
同时面多家公司的一个好处是有时候能够省去某些环节。有些硅谷公司规定对于湾区以外的面试人要进行两轮电话面试。我之所以能够省去 Airbnb 和 Salesforce 第二轮电话面试,是因为对方得知我一轮电话面试就拿到了 LinkedIn 和 Facebook 现场面试的机会。
更令人吃惊的是,Google 甚至没电话面试就请我参加现场面试,这也是因为对方得知我下周要来湾区参加四个现场面试。我知道这会让我很累,但是,没有人会拒绝 Google 的现场面试邀请!
现场面试
五家公司虽然都是 IT 公司,但处于不同的领域,文化上也各有千秋。我简单说一说自己对它们的感觉。另外虽然不算是吃货,但作为民以食为天的中国人,自然也要对午饭进行一下评价。
这是我第一个现场面试,我在 LinkedIn 的 Sunnyvale 办公室。作为专注于职场社交的公司,LinkedIn 的特点是端庄、大气、职业化,内部文化也相应地非常专业。员工的穿着都是商务休闲装,整体给人一种职场精英的感觉,与他们的宗旨非常契合。
面试方面,编程和机器学习各 1 小时。编程面试都是标准问题,但机器学习面试可能会有些困难。尽管如此,我之前收到 HR 的电子邮件,里面包含了非常有用的准备材料,因此面试中没有太出乎意料的事情。我听说 LinkedIn 有硅谷最好的食堂,从我的实际体验来看,这差不多是真的。
LinkedIn 被微软收购以后少了经济压力,使其可以放开手做非常酷的事情。LinkedIn 新添加的视频和专业广告等功能令人兴奋。作为一家专注于职业发展的公司,LinkedIn 优先考虑其员工的职业成长。目前包括 ads relevance、feed ranking 在内很多组都在招人,所以如果你想加入,那就赶快行动。
Salesforce Einstein
Einstein 是 Salesforce 近几年主推的明星产品,拥有一个明星团队。这个团队非常新,感觉非常像初创公司。团队主要是使用 Scala,Tech stack 都是 Akka/Play/Spark 那一套,这也是最吸引我的一点。我最初接触到 Einstein 是在 2017 年 4 月的 ScalaDays 上听了 Matthew 以《Type safety in machine learning》为题的演讲,之后又在 Spark Summit West 上听了 Leah 的演讲。喜欢 Scala 的人一定不要错过。
面试地点是 Salesforce 位于 Palo Alto 的办公室。这个团队很有凝聚力,能保证工作生活平衡。每个人都热爱并真正享受自己做的东西。与其他现现场面试相比,四场 session 总共时间略短,总体侧重于 Data engineering 和 System design。另外需要注意的是,coding 也是要上机跑的。面试后,Matthew 甚至带我参观了惠普的车库。
当今业界领头人,没有什么可说的。最重要的印象就是大,非常非常大。去见我 Google 的朋友的时候骑自行车骑了 20 分钟。中午吃饭排队人很多。
我在 Mountain View 的许多楼里的一幢进行面试。我不知道具体是哪一幢,因为 Google 真的非常大。
面试官看起来都很年轻,他们一说话就显得很聪明。和他们一起工作一定是非常愉快的。
值得注意的是 Google 特别强调算法的复杂度,确保你真的明白时间和空间复杂度,能够针对瓶颈进行优化!这一点与别的公司不同。
Airbnb
快速扩张的 Unicorn 公司,拥有非常独特的公司文化以及可能是硅谷最美丽的办公室。推出了新产品包括 “体验” 以及餐馆预订服务、在高端小众市场进行尝试、以及进入中国市场,这些都为 Airbnb 的前景增添了积极因素。如果可以承受高风险,并希望获得快速增长的 pre-IPO 经验,那么 Airbnb 是完美的选择。
Airbnb 的 coding 面试有点独特,要求上机,并且每个 Session 只有 45 分钟时间,某些题目的难度也相当大,所以压力还是不小的。
Airbnb 独树一帜的跨职能面试,这也是我最享受的,我和面试官轻松交流。Airbnb 认真对待公司文化,技术上优秀并不能保证拿到 Offer。
总的来说,我认为 Airbnb 的现场面试流程最长,环节最多,题目很难,总体感觉最累。如果你有兴趣,一定要了解他们的文化和核心价值观。
另一个仍在高速发展的巨人,与 Google 相比规模更小,速度更快。在社交网络市场铺开了全面产品线,处于垄断地位,以及在 AI 和 VR 方面的大量投资,未来 Facebook 只有更多的增长潜力。有像 Yann LeCun 和 Yangqing Jia 这样的明星,如果你对机器学习感兴趣的话,这是一个完美的地方。
我的面试是在楼顶有花园的海景房 Building 20,也是扎克伯格办公的地方。
Facebook 的整个面试过程我自己感觉是最不好的,一方面是因为已经是第五场面试,整个人已经很疲劳了,另外可能是 Facebook 的规定,面试官都没有对我的答案给出特别明显的好与不好的信号,虽然我觉得自己的答案没有错,但也稍微有些拿不准自己的表现。
两场 Coding 还算是正常,两道题都在面试官的提醒下总共给出了两种解法,有一场还问了两道题。下午我已经感觉自己生病了,头疼得厉害,最后硬撑着完成了面试,出来以后感觉不太好,没想到最后竟然也拿到 Offer 了。
总体来说,我觉得 Facebook 的工作人员坚信其公司愿景,并为他们正在建设...
基于nose-html-report定制测试报告 推广视频课程
环境准备
pip3.5 install nose-html-report
安装目录文件:
├── __init__.py├── __pycache__│ └── __init__.cpython-35.pyc└── templates├── report2.jinja2└── report.html
主要修改 __init__.py文件及测试报告模板文件report2.jinja2
jinja2模板有自己的语法,具体可以谷歌,如:
if elif else endif 条件语法 :
{% if not test.failed %}{% set test_status="Pass" %}{% elif test.failed and test.type == 'skipped' %}{% set test_status="Skip" %}{% elif test.failed and test.type != 'skipped' %}{% set test_status="Fail" %}{%- else -%}{% set test_status="Error" %}{%- endif %}
for语法:
L{% for test in group.tests %}
{%- endfor -%}
测试报告定制的实现主要包括如下类
class OutputRedirector(object): # 输出重定向类
包含一个文件对象fp,主要包括如下方法
def write(self, s): def writelines(self, lines):def flush(self):def readall(self):
class Group(object): # 测试用例组
主要包括如下两个对象
self.stats = {'errors': 0, 'failures': 0, 'passes': 0, 'skipped': 0} # 用例组的结果状态统计self.tests = [] # 用例组中具体测试用例统计
class HtmlReport(Plugin): # 测试报告插件
构造函数def startTest(self, test): # 重定向输出初始化def complete_test_output(self, err_msg='', traceback=''): # 测试完成后的断开重定向链接同时返回缓存数据def begin(self):def complete_global_output(self):def options(self, parser, env): 通过nosetests运行测试用例时携带的命令选项 def configure(self, options, config): 通过命令配置进行实际相关配置两边的加载 根据配置加载指定模板def report(self, stream): 基于模板,对模板中的变量进行赋值,写测试报告 通过self.report_data,以group为单位,对测试结果结果进行传递,group中包含stats及tests对象,分别记录该测试组中测试运行状态及具体用例信息""Writes an Xunit-formatted XML fileThe file includes a report of test errors and failures."""self.stats['total'] = sum(self.stats.values())for group in self.report_data.values(): group.stats['total'] = sum(group.stats.values())self.report_file.write(self.jinja.get_template(os.path.basename(self.report_template_filename)).render( report=self.report_data, stats=self.stats, start_time = str(self.test_start_time)[:19], rawoutput=self._format_output(selfplete_global_output()), duration_time = self.test_duration_time - datetime.resolution))self.report_file.close()if self.config.verbosity > 1: stream.writeln("-" * 70) stream.writeln("HTML: %s" % self.report_file.name)def addSuccess(self, test): # 测试成功 返回的状态信息及用例详情name = id_split(test.id())group = self.report_data[name[0]]self.stats['passes'] += 1group.stats['passes'] += 1group.tests.append({ 'name': name[-1], 'failed': False, 'output': self._format_output(selfplete_test_output()), 'shortDescription': test.shortDescription(), 'time': str(datetime.now() - self.test_start_time),})def addError(self, test, err, capt=None): # 测试失败 返回的状态信息及用例详情、错误信息等"""Add error output to Xunit report."""exc_type, exc_val, tb = errtb = ''.join(traceback.format_exception( exc_type, exc_val if isinstance(exc_val, exc_type) else exc_type(exc_val), tb))name = id_split(test.id())group = self.report_data[name[0]]if issubclass(err[0], SkipTest): type = 'skipped' self.stats['skipped'] += 1 group.stats['skipped'] += 1else: type = 'error' self.stats['errors'] += 1 group.stats['errors'] += 1group.tests.append({ 'name': name[-1], 'failed': True, 'type': type, 'errtype': nice_classname(err[0]), 'message': exc_message(err), 'tb': self._format_output(tb), 'output': self._format_output(selfplete_test_output(exc_message(err), tb)), 'shortDescription': test.shortDescription(), 'time': str(datetime.now() - self.test_start_time),})def addFailure(self, test, err, capt=None): # 测试失败 返回的状态信息及用例详情、失败详情"""Add failure output to Xunit report."""exc_type, exc_val, tb = errtb = ''.join(traceback.format_exception( exc_type, exc_val if isinstance(exc_val, exc_type) else exc_type(exc_val), tb))name = id_split(test.id())group = self.report_data[name[0]]self.stats['failures'] += 1group.stats['failures'] += 1group.tests.append({ 'name': name[-1], 'failed': True, 'errtype': nice_classname(err[0]), 'message': exc_message(err), 'tb': self._format_output(tb), 'output': self._format_output(selfplete_test_output(exc_message(err), tb)), 'shortDescription': test.shortDescription(), 'time': str(datetime.now() - self.test_start_time),})def _format_output(self, o): 字符相关编码
if isinstance(o, str): # return o.decode('latin-1') return o.decode('UTF-8') else: return o