写点什么

iOS 面试策略之代码考查到 offer 的比较和选择

用户头像
iOSer
关注
发布于: 2021 年 04 月 05 日
iOS 面试策略之代码考查到offer的比较和选择

4.代码考查和系统设计的准备

1.如何准备代码考查

很多面试的能力都不是突击可以获得的。项目经历不是,代码能力也不是。如果说项目经历的获取还需要环境支持的话,代码能力的提高基本只需要自己投入就可以了。


在网上有很多练习编程的网站,特别是像面向求职者的 LeetCode 一类的网站,提供了各大公司的代码考察题目,并且大部分题目还有标准解答和示意代码。你可以在上面一遍一遍地练习,以提高自己的代码转换能力和逻辑思维能力。我建议大家至少做 100 道 LeetCode 里面 Facebook、Apple 这些大公司的代码题目,很多题目都设计得非常好,既是很好的练习题,又可能在实际工作中用到。Google 的面试题通常还要更难一些,对自己要求更高的同学也可以挑战一下。


我曾经面试过一个清华的应届生,考查他各种面试题目都解决得非常快,我就好奇他是怎么做到的。他回答说:他花了一年时间,把 LeetCode 上面的所有题目做了三遍。当时 LeetCode 上面大概有 700 道题目。你看,即使是清华这样厉害学校的学生,同样在代码练习量上非常努力。我自己觉得,这个应届生在努力程度上,就可以超过 95% 的别的候选人了。


如果是非科班的学生,在写代码前你还需要学习数据结构和基本的算法知识。相关的学习资料可以选择国外的公开课,或者国内 985 大学计算机专业的教材。麦克道尔著的《程序员面试金典》也是非常不错的学习资料。


除此之外,在纸或白板上写代码的能力也需要好好练习。纸上写代码麻烦的地方在于不方便及时涂改,所以需要思考得比较清楚再动手写。准备一些 A4 纸,然后拿 LeetCode 题目多练习几次,慢慢就会有感觉。


我自己在纸上写代码的经验来着早年在大学时参加的 ACM 国际大学生程序设计竞赛,这是一个 3 人组队参加的比赛。比赛时 3 个人可以合作答题,但是只有一台电脑可以使用。所以为了最大限度地提高电脑的利用率,我们同时做 3 道题,然后会现在纸上写代码,等自己在纸上完成代码的编写后,再使用电脑来录入和调试。为了备战 ACM 比赛,我差不多有几百道在纸上手写代码的经验。


我最后总结出来在纸上写代码的要诀是:一定要先把整体逻辑框架梳理清楚,然后再填充细节。所以你可以用文字、流程图或任何你喜欢的方式先把代码整体逻辑描述在纸上,然后检查没有边界问题后,再在纸上细化成具体的代码。

2.写代码之外的沟通

即使是做代码题目,必要的沟通交流也是必须的。我见过很多候选人听完题目就埋头写代码,完全不和面试官交流,这其实是非常错误得做法。如果写代码完全不需要交流,那么为什么不当做笔试题,而要耽误面试官的时间坐在你旁边?难道就只是为了监督吗?


其实,解决一道代码题目的思考过程是非常有价值的,面试官问你一道代码题目,其实是希望和你一起沟通交流,了解你的思路,帮助你找到最好的解法,最后才是把代码完成的事情。


所以,当面试官给你一道题目,你首先要做的是和面试官足够地交流。你可以首先确保你完整地理解了题意,这可以通过询问题目的一些细节来达到,比如问输入的数据范围,输出的具体要求,一些异常的情况是否要考虑等等。


等你完全理解题意之后,下一步就是将你的想法说出来。你完全不必担心没有一下子说出最好、最完美的解法,大部分好的代码题目都可以一题多解,你可以先说一个最简单直接的方法,然后说出这种方法的时间复杂度、空间复杂度。一般面试官都会问你有没有更好的做法,或者你也可以直接说想思考有没有更好的做法。接着你可以试试看能不能想出一些办法,即使一些办法没有完全想清楚所有细节,也可以说出来。好的面试官如果发现你的方法完全方向不对,还可以及时干预。


你如果在思路上有卡住,你甚至可以请求面试官给你一些 “提示”。虽然这可能使得你面试表现稍微减分,但是比起完全没有写出代码来说也要好很多。


除了写代码之前和面试官交流、确认解法,写完代码之后,你也需要和面试官讨论你的代码细节问题。通常代码中多多少少会出现一些问题,面试官会给你一些引导,帮助你发现并且修改有问题的代码。

3.如何准备系统设计

如果你是一个应届生,通常考查的系统设计题都不太难,你只需要有一些系统设计的基础,都不至于完全答不上来。在准备资料上,可以看看《设计模式》相关的书。如果有机会实习,可以多尝试一些不同的职位,如果你同时尝试过客户端和服务器端开发,在系统设计上就可以更加综合考虑设计方案在多端的实现难度,以便做出权衡。


另外,你可以通过学习分析一些开源项目的代码,来学习架构设计。在网上,你通常也可以搜索到一些常见的系统设计题目,在本书的上一节中,我也提供了好多系统设计题。把这些系统设计题目仔细研究,尝试自己实现一下,通过实践并且和同学讨论,相信你也会有不错的成长。


系统设计题目通常都不会有特别标准的解答,其实考查过程更看重一个人分析解决问题的思路。这样的思路可以保证即使未来遇到没有见过的问题,也可以从容地系统性思考和判断。所以,你需要给面试官展现你思考的过程。在面试中,了解需求细节,解释设计思路,讨论和判断一个设计的优缺点,都能够让面试官体会到你这方面的素质。


虽然没有标准的答案,但是系统设计还是有一些解题套路,下面我就给大家介绍一下。


首先系统设计题都非常考查一个人知识的全面性。所以大家应该平时多了解一些 iOS 之外的技术,比如适度了解一下 Android 端、Web 端以及服务器端的各种技术方案背后的原理。你可以不写别的平台的代码,但是一定要理解它们在技术上能做到什么,不能做到什么。你也不必过于担心,面试官在考查的时候,还是会重点考查 iOS 相关的部分。


在知识足够宽泛的情况下,你需要首先和面试官明确问题的各种细节,比如假如题目是“设计一个类似微博的信息流应用”,你需要了解清楚这个信息流应用更多的技术要求,比如:


  • 信息流的内容是否包括图片,文字,语音。

  • 平均每个用户每天有多少的信息流更新量。

  • 是否需要做图文混排。

  • 是否需要做图片的缓存,历史信息的缓存。

  • 断网情况下是否需要显示离线内容。

  • 发送失败情况下是否需要暂存内容。

  • 系统对核心功能的性能(例如发送,刷新)的要求是多少。


有一些技术细节可能是面试官想考查的,你问的时候他就会要求多一些;有一些技术方案明显很复杂的,你提出来,他即使不考查你,也会觉得你的考虑是足够周全的。


在确定技术细节要求后,你就可以开始讲你的系统架构设计了,这个时候讲的要诀是先框架,再细节。你需要先把各个模块的层次画出来,比如刚刚那道题目,你先介绍一下整体 App 是怎么和服务器通讯的,服务器端的信息流大概是如何存储的,然后你就需要详细介绍 App 的部分。


在介绍 App 的框架时,先画出 Model 层,Controller 层,View 层。然后再进一步细化,比如把 Model 层细化到本地存储,图片缓存,网络请求等模块。View 层如何处理图文混排,Controller 层如何与其它层通讯。


当框架介绍得差不多的时候,你需要把后续的选择交给面试官。面试官可能会选其中某一个模块,让你做更细一步的设计。比如让你设计网络通讯的 RESTful 接口,细化缓存相关的 API 名字。面试官甚至可能选一两个具体的函数,让你写写。面试官也可能进一步挑战你的一些设计细节,这个过程中,你可能需要修正自己的设计,也可能需要解释你的设计。


下图就是回答系统设计题的框架。



一道系统设计题的考查方式可以千变万化,需要的是你和面试官之间密切地交流,性格内向的程序员很可能在这方面吃亏。所以,除了有方泛的知识面以及扎实的架构设计基本功外,多和面试官讨论交流也是面试过程中的关键因素。

5.复盘

复盘是一个人持续提高和进步的源泉。也许你觉得你的面试表现很好,但是为什么面试没有通过呢?当你被拒的时候,与其抱怨面试官或者面试流程不公正,倒不如静下心来想一想,看看是不是自己忽视了某些细节或者关键点。如下图所示:



例如,当你的算法或系统设计题解决方案不太好时,面试官通常不会直接纠正你,他只会稍微引导一下。面试结束后,他更不可能给你做教学,教你应该怎么做答这些题目。所以,你的解决方案好不好,你其实只是凭感觉来的。你可能觉得你已经解决了这个问题,但是面试官可能心里想,这个解决方案虽然可以工作,但是是他见到过的最最愚蠢低效的办法。


所有的这一切,你都无法直接知晓。你只能在面试之后,特别是被拒之后,仔细复盘分析一下,看看自己可能哪些问题回答得不好。这个时候,找人请教和讨论也显得特别重要,你可以把你怀疑的一些面试糟糕表现描述出来,然后找人一起分析一下,通常情况下都会有一些收获的。


除了复盘算法和系统设计题,也需要复盘一下自己整体的面试流程是否表现正常。例如:


  • 我的自我介绍是否流利?

  • 我的项目沟通是否介绍清楚了?

  • 面试官有没有完全理解我介绍的项目挑战?

  • 我的时间控制是否到位?

  • 我有没有迟到,中途接电话,或者任何被认为不礼貌的行为?

  • 我做得不好的地方,有没有短期可以改善的?

  • 我做得不好的地方,短期不能改善的,我能不能用别的方式适当弥补?比如面试中强调自己的强项。


每次面试后,做一个小结,可以使得自己每次都会有一点点进步,几十场面试下来,相信大家都会有不小的成长。

5. 如何提问

有些时候前面的环节占用了太多的时间,面试官可能就不会给你提问的机会。但如果面试官说:“我的问题问完了,你有什么问题吗?” 那么恭喜你,你基本上已经完成了整个面试,而且还有一点时间可以交流一下。通常这个提问环节留给双方的时间不会特别多,所以可以就你关心的问题来提一到两个问题即可。


很多候选人会说:“我没有什么问题”。这是可以的,但是这个环节最好还是提个问题稍好一点,它能够显示出你对目标公司的关注和兴趣。提问的内容可以围绕着技术氛围、技术分享、公司的业务、未来的方向等等。比如:


公司在 iOS 端主要使用了哪些技术框架?公司内部有技术分享或者别的学习交流机会吗?公司当前团队有多大,希望我进去参与哪方面的业务?公司当前有没有什么大的竞争对手?未来公司希望在哪些产品上重点发力?但是切忌不要问以下这些问题,否则会显得自己很不专业。


1.询问面试表现很多人在面试结束后,都忍不住问:“我刚刚的面试表现怎么样?”面试官通常都不会当面评价候选人,因为这可能引起冲突。大部分候选人都不能冷静地面对面试批评。而即使你面试表现很好,是否录用也取决于你的竞争者的表现是否在你之上,所以面试官真的很难回答这个问题。


通常如果你问了这个问题,面试官要么糊弄地回答:“还不错”,要么就诚恳地回答:“我们通常不当面反馈面试表现”。


2.询问面试题答案有人会在面试结束前问:“刚刚那道题目应该怎么做?”面试官听到这种问题通常只能苦笑一下。你要知道,这是面试,不是面试培训。面试官没有义务给你解答题目,而且通常为了保证面试题目资源的保密,面试官也不愿意把一道题目的最优解告诉你。如果你回去告诉了你的朋友,这道题目就没有考察的功能了。


如果你特别想知道面试题答案,还是应该自己在面试结束后仔细钻研。大部分公司也会要求候选人对面试题保密,所以如果你把题目放到网上共享,通常也是不被允许的,严重的情况下,可能造成通过的面试 offer 因此被取消。


3.询问薪资大部分公司的薪资都是非常保密的,能知道薪资的人除了 HR 外,只有很高级的主管才有可能知道。大部分的面试官可能都不知道你的职位薪资。所以如果你有这方面的需求,应该直接找 HR 咨询,而不应该问面试官。


一般你的最后一轮面试官有可能是你未来的主管,他可能会询问你的薪资和期望,遇到这种情况,你可以趁机反馈出自己的意愿,但如果面试官没有提,最好你也就不要问这方面的信息,以免面试官拒绝回答造成自己过于尴尬。


小结整体来说,面试的打分和提问环节相关性不大,所以大家只要别问敏感问题即可。

6. offer 的比较和选择

恭喜你!经过努力,你最后拿到了好几家公司的 offer!这些公司有的规模很小,是成立不久的创业公司;有的已经是纳斯达克的上市公司,员工数量过万;有的是外企,有着复杂但是规范的流程;有的是国企事业单位,工资虽然不太高但是福利好并且工作压力不大。你该如何选择?


很多人都会纠结,我也曾经纠结过。现在回过头来,我觉得要做好选择,核心还是对自己的情况有一个清晰的判断。每个人不一样,所以最后的选择也不一定一样。


1.工作 vs 生活这辈子打算怎么过,其实很多人都没有想得特别清楚明白。每个人的选择没有什么高低贵贱之分。也许你希望新工作能够尽量兼顾工作与生活,也许你希望新工作能够帮助自己快速在职业上成长。生活的目标不一样,答案也就不一样。想清楚了,答案就明显了很多。


如果你希望尽量兼顾工作与生活,那么那些工作强度大的 offer 自然应该就排在低优先级。哪些公司工作强度大?询问一下对方公司的 HR 或者面试官,平常的上下班时间,加班的频率,通常都可以得到比较客观的回答。如果你恰好有在目标公司上班的朋友,那么你应该可以获得更多这方面的信息。你也可以在网上搜索相关的关键词,获得信息。


其实在很多国家,人们并不是那么看重工作的,很多人更多的看重生活以及家庭。只是国内的环境以及我们从小的教育,使得我们很看重工作,以及工作的职业成长。


2.职业成长大部分人看重职业成长,这一点非常好理解:程序员是一个需要持续学习和积累的工作,如果不能在工作中持续学习成长,几年之后如何在职场获得立足之地呢?但追求快速的职业成长不一定表示一定要去工作强度特别大的公司,其实核心还是看:


工作的内容指导你的导师(我们行业内常常叫 Mentor)一个有职业成长的 offer,其工作内容应该可以让你建立起对相关专业领域的完整知识,并且该工作内容很可能具有成长性和发展性。比如,如果是偏研究的工作,基于深度学习的研究就比别的人工智能研究更加具有成长性。又如,做用户产品就比做内部系统更具有成长性。


如果你的 offer 是去维护一个已经开发了 10 多年的老旧系统,除非是要你花大力气重构它,否则你的工作成长性也会较差,因为难的问题都已经被别人早解决过了。


行业的成长也很重要,比如互联网行业就比传统的软件行业好,移动互联网行业又比传统互联网行业好。选了一个好的行业,你的能力和待遇会随着行业的发展而发展。选错了一个行业,即使你做到这个行业的冠军,整个行业不挣钱,你的日子也不会好过。


除了工作本身的吸引力外,指导你的导师也很重要。一个领域的知识架构是什么样的,重要的观点和讨论,都是一个好的导师能够指引的。当然,你不要抱有什么事情都是导师手把手教这种幻想,这在公司里面既不现实,也不利于你自学能力的发展。


3.职业背景有一些人,特别是学校不太好的人,会特别看重第一份工作的公司背景。因为大部分公司在挑选简历的时候,差不多主要就看两条:毕业院校和工作过的公司。所以,我建议学校不太好的同学,可以在考虑 offer 的时候选择名气比较大的公司。这样对你未来的简历,会有一定的加分效果。


但如果你已经是非常好的学校(比如 985、211 院校)的毕业生了,那么我建议你不用太考虑公司的名气。因为对于你来说,学校背景这一条已经够你用作未来面试的敲门砖了。


4.薪资的考虑通常情况下,你的薪资是符合市场上相同工作年限的薪资范围的。在薪资范围内,你能拿到多少取决于新公司的内部薪资标准、你的面试表现,以及你以前的工作经历。


大部分人的直觉想法都是:「谁给的钱多去谁那儿」,但是我建议大家也综合考虑上面提到的职业成长以及公司的背景。如果一个工作没有职业成长性,那么给得钱再多,我也不建议大家去。


应届生的薪资通常都是不能谈的,但是非应届生因为每个候选人情况都不一样,很可能可以谈。


5.考虑创业公司如果你的学校背景特别好,又在比较好的大公司实习过,那么如果有一些上升期的创业公司,其实也是不错的选择。


首先,在这些创业公司里面,你可能获得更多的锻炼机会。然后,你的学校背景和实习经历,使得你即使换工作,也不会因为在创业公司很受影响。最后,也是最重要的是,如果这家公司最终上市,你有可能因此获得极大的期权回报。


6.讨论与决策以上我提供了一个基于工作和生活侧重点不同的考虑方式,考虑到每个人自身的具体情况,其实你还可以有别的考虑方式。比如有一些人可能父母身体不好,希望更多的离家近;又可能有一些人身体不太好,不希望太累。在你有了你的一套考虑逻辑以及结论之后,我还是建议你找你欣赏的人讨论商量一下,分享一下你的决策思路,也听听他的意见是什么。这些人可能是你的同学,朋友或者是导师,长辈。


一个好的决策应该是充分收集信息,并且独立决策的。所以你和少数人的讨论过程,有助于进一步判断你的思路是否有漏洞。一个人的 offer 还是会影响他好几年的职业生涯,所以在这个阶段多收集信息,多思考是非常必要的。但是我们也要切忌人云亦云地做决策,一定要自己独立的做判断,不要简单的盲从权威或者大众,因为没有任何人比你自己掌握的信息更多。


7.反馈在你做完决定之后,你就需要给公司反馈你的结果了。对于拒绝的 offer,你应该礼貌地表示歉意,并且希望以后可以保持联络。谁知道你未来会不会再次考虑他们的 offer 呢?


对于你接受的 offer,你应该更加积极地获取更多的信息。比如看看能否有机会和未来的团队 Leader 见面,了解一下未来工作可能用到的技术栈,提前体验一下公司的产品或者做一些相关技术上的学习。这些都可以帮助你更好更快地融入新的公司和团队。


8.心态的调整鱼和熊掌不可兼得。很多同学可能在 offer 选择的时候患得患失,最后即使做了决定,也会有后悔的时候。我想说大家还是应该调整好心态,没有哪个公司是完美的,在我们 IT 行业,也很少有人在一个公司待一辈子。所以调整好心态,决定了 offer 之后,就把该放的放下,努力把自己的思想放在未来的工作本身上。因为只有自己的能力提升了,才可能有更大的职业成长空间。


小结总结一下,你首先要对自己的未来生活有一个规划,是更偏重于家庭和生活,还是更偏重于工作。


然后,如果你希望偏重于工作,那么你需要考虑:职业成长性、职业背景、薪资。如果你特别优秀,我也建议你考虑一下创业公司的机会。


最后,你的决策过程应该和重要的人讨论,但是决策本身仍然应该由你自己做出。做出决策后,你应该礼貌地拒绝掉不接受的 offer,然后对于接受的 offer,做进一步的信息沟通和入职准备。

小编推荐阅读

推荐👇:

如果你想一起进阶,不妨添加一下交流群931 542 608


面试题资料或者相关学习资料都在群文件中 进群即可下载!


用户头像

iOSer

关注

微信搜索添加微信 mayday1739 进微信群哦 2020.09.12 加入

更多大厂面试资料进企鹅群931542608

评论

发布
暂无评论
iOS 面试策略之代码考查到offer的比较和选择