从一道面试题谈谈一线大厂码农应该具有的基本能力

从一道面试题谈谈一线大厂码农应该具有的基本能力

码农唐磊 程序猿石头
从一道面试题谈谈一线大厂码农应该具有的基本能力
从一道面试题谈谈一线大厂码农应该具有的基本能力程序员

做者:Yura Shevchenko 来源:skypixel.com 面试

关于一线码农的面试,我想说

求职面试在绝大部分人来讲都是必不可少的,本身做为求职者也参与了很多面试(不管成功或者失败),做为技术面试官参与面试也有四五年的经验,在面试过程当中也见识到了各类各样的人(有厉害的,也有奇葩的)。在这里也只想谈谈本身的一些见解,我说的不必定对,有不一样的意见能够留言参与讨论。算法

面试原本就是一个双向选择的过程,面试官和候选人的地位本应该是一个平等的位置,面试官但愿经过简单的交流沟通能够对候选人的技术,沟通等有必定了解进而肯定候选人是否匹配相应的职位。我的认为一场成功的面试最好是可以让求职者和面试官都有必定的收获(曾经也遇到过在某次面试后,HR 告诉我有候选人特地跟她反馈要表达对面试官的感谢,由于让他颇有收获,这固然仍是让我感到很是高兴的),每次参与面试,也但愿本身能达到这个目标。对于候选人来讲能从面试过程了解本身的不足或者交流探讨面试问题;对于面试官来讲能了解候选人的技术和项目,在交流探讨中也是一次学习和巩固。 另外面试可否经过最终强调的是职位匹配,一个萝卜一个坑,萝卜太大或过小都不必定合适。因此有时候面试没经过并非候选人不够优秀,也有多是候选人过于优秀(例如原本只想招聘 P6,结果来了一个 P8的候选人确定不合适)。编程

由于面试时间有限,1个小时(通常状况)的时间很难去全面了解候选人的技术实力,所以在面试过程当中很难作到绝对的公平。举个简单的例子,面试官出一道题目,候选人 A 可能曾经作过或见过,因此可以比较轻松地回答出这个问题,而候选人 B 没有作过,虽然不能答出让面试官满意的答案,但 B 提供了一些解题的思路,虽然最终并无答出这道题目,这就必定说明候选人 B 比 A 差么? 并非吧。vim

下面就从这道题目提及,这道题目是我在过往的面试中常常考察的一道题目。网络

动笔试试吧

实现一个函数,完成 开根号 的操做,方法签名以下:数据结构

double sqrt(int v, double t)

要求:框架

  1. 不能调用系统库函数,诸如 Math.sqrt(v) 之类的;
  2. 假设计算出的结果为 r,要求知足这个条件: 图片 ,其中图片 是真实的值, t 为给定的一个偏差范围,例如0.1等,即你计算出的值要在给定的偏差范围内。
  3. 实现语言不限,你条件能够比上述更加苛刻,但不能宽松。例如调用你的接口 sqrt(9, 0.21) 返回值属于 [2.79, 3.21] 这个区间的任意一个都知足条件。
    看到这里,其实你能够 拿出笔和纸,尝试解答一下,须要注意的是答案要知足给定的偏差条件,欢迎沟通交流。其实这个题目是就是 leetcode 上原题稍加变化获得,作过的确定以为 leetcode 其余题目来讲相对比较简单。但没作过也不要紧,若是在面试官的提示下可以最终把这道题目解出来,在我看来也 OK 的,甚至有可能比刷过题记住解题答案的更好(固然刷过题目自己的确定会围绕这个题目穿插其余小问题的)。

从一道面试题谈谈一线大厂码农应该具有的基本能力

分割线


开始解答

其实刚开始,我认为这道题目比较简单,至少在给予提示后,理想状况下大部分一线coding的程序员均可以给出实实在在 code 的。然而“理想很丰满,现实很骨感”,事实并不是如此,然而在面试很不少人以后, 发现此道题目并不简单,若是你能写出来,说明你已经比不少人优秀了(至少在我过往的社招面试经历中)。 异步

当被问起这道题目以后,可能遇到的答案以下。数据结构和算法

直接放弃

题目给出后,我通常首先明确候选人弄清楚了题目的含义而后会给一两分钟让候选人先思考一下。

面试官:你有什么思路吗?
求职者: 没有啊。

可能候选人心里OS是: “你出这样的题目是否是有病啊,明明有 lib 函数能够直接用的”。(以前同组有其余小伙伴确实有遇到这样的候选人,语言虽没这样夸张,大意是:实际工做中会出现这样的问题吗? 我直接给你百度一个就好了)

在此强调,面试这道题目并非想强调这个题目自己,指望以这道题目为契机,考察候选人在分析问题和解决问题的能力,在交流过程当中所体现的逻辑推理和思惟方式等,固然最后也会看看实实在在的 Code,从编码过程当中看候选人的编程习惯,风格等等。

也有候选人刚开始抱着那个约束偏差范围的不等式研究 N 久,而后没有而后了的。刚开始看这个条件固然好,但若是这个不等式没有思路能够先放一放,不必在那苦熬。

面试官:这样吧,若是我问题 根号10 等于多少?你怎么回答?
求职者:3点几吧。
面试官:你怎么知道是3 点几,由于你知道9开根号是3,想象一下,你也能够彻底用程序帮忙模拟你大脑思考的过程。
求职者: 我再想一想……

其实这里是但愿提醒候选人,咱们首先是要解题,而后才考虑效率。即无论用什么方法可以给出一个答案的,这个时候候选人可能进入下一个阶段了。

在实际工做场景中其实也是同样,遇到一个问题,首先咱们要想到的是如何解决这个实际问题,有了最基础的解决方案以后再谈优化。

暴力搜索

实际面试过程当中也有人是直接到这个阶段的。

先用一个循环找到 r,使得 r^2 是离给定 v 最近的平方数,即你但愿算根号10 ,先找到3,由于3^2=9 。

而后再用一个循环, 每次 r+=t ,直到 r^2 > v 为止。

面试官:这个方法从理论上讲, 是一个可行的方案,设想一下,若是个人精度要求很高,但愿计算的 v 也很大,如 sqrt(v = 10000000, t = 0.000001) 之类的,调用你这个方法效率是否是很低,这个时候应该怎么优化?
求职者:这样的话,我这个方法效率确实比较低,不过能够这样优化,好比设置一个步长,一次迭代后,若是没有达到预期,能够不断修改这个步长来增大逼近真实值的速度,好比10倍偏差,100倍偏差等。

其实,在与候选人的不断交流中能够看出候选人的 Problem Solving 的能力,这也是面试考察中的一点。例如关于上面问题的优化,也可能用于在实际工做中遇到的问题。

例如,咱们在实际工做中可能常常会写一些异步的回调通知接口等,这个接口多是其余团队维护的,有可能因为网络问题等回调接口可能会失败进而须要重试,对于重试的机制其实就能够借鉴上面的“步长”机制,第一次回调失败, 我等待 1s 后重试,失败再重试,也许间隔 1s 不太恰当,是否能够修改等待的步长,等待好比 5s,10s?等等再重试直到成功。为何要这样作? 也许对方 server 原本如今就处于峰值,你不停的重试不但没有增长你接口调用成功的机会,反而增长对方 server 的负担。

额,跑题了,回到这个问题自己,继续

面试官:恩,这样作确实能够优化。但从本质上讲,假设咱们不考虑偏差的话,这个题目其实就是在一个有序的列表里面去搜索知足条件的特定的值。刚刚你的方法是一个线性的搜索方案。常见的搜索还有其余什么吗?
求职者:二分搜索?
面试官:对呀,你能够尝试想一想可否借用一下这个思路来解决这个问题。

二分搜索

固然,部分候选人提示二分后,就直接可以 get 到点,而且可以写出二分大致框架,但可能结束条件写的有点问题。

若是候选人尚未思路,就会继续

面试官:这样理解吧,你刚刚的搜索整数部分的过程实际上是线性的,一个一个数去暴力穷举。借助二分的意思就是,好比算 根号10,你搜索范围是 [0, 10] (其实除了几个数以外范围能够更小[0, v/2],你能证实么?)。

  • 由于5^2 = 25 > 10 , 因此 r 属于[0, 5)
  • 由于(5/2) ^2 = 6.25 < 10 , 因此 r 属于 (2.5, 5)
  • 由于(3.75^2 = 14.0625 > 10) ,因此 r 属于 (2.5, 3.75)
  • 继续,若是你结束条件不太肯定,能够暂时无论…

提示到这里,感受已经相对比较明显了。

面试官: 你如今明白了吗?
求职者:明白了。
面试官:那你写一下代码吧。

一个二分查找,算法思路都结合例子讲一遍了,在候选人回答明白的状况下,理想当中,做为一线开发者写出来应该不成问题吧。然而…理想和现实仍是有差距的。
不少人都喜欢用递归写,但是不少人递归里面的最重要的结束条件都木有, 一些边界条件等等都木有。因此通常状况下,代码写完后,我会让候选人本身写测试用例。

面试官:写好了是吧,你写几个测试用例吧,假设这个接口是别人写的,你应该从哪几个角度去测试。
求职者:sqrt(-4, 0.21),哎呀,我这里忘了判断了。改一下代码。
求职者:sqrt(0, 0.21),sqrt(4, 0.21)… 还有问题,再改改。
面试官:……

为何要别人提示要测试用例,才去 check 本身写的代码的正确性呢。有的候选人写的代码,就不拿一些异常状况去 check,就用上面讲的 sqrt(10, 0.21) 的例子都得不到预期结果。

可以到达这一个步骤的人已经较少了,若是你有较全测试用例和边界条件的判断,再加上后面的结束条件可以正确,基本上这道题目就算满意了。

关于结束条件

本质上讲,这个算法就是一个迭代逼近的过程,用二分的思路后,关键就在于何时结束。 题目中已经给了偏差条件 图片 ,难点在于其中的图片不知道,不太方便直接进行计算判断。很多人用一个另外的结束条件来进行了判断即: 图片 ,其实这两个条件是不同的。

对于这个结束条件,你有什么见解吗? 能证实你的想法吗?

其余解法

固然本题还有一些其余的数学解法,例如用牛顿迭代法,梯度降低法(最速降低法),泰勒公式展开等等。若是候选人能想到这些,说明他仍是有必定数学基础的,若是愿意可让他讲讲。(考察这道题目本意并非指望候选人用这些数学方法解的。)

对于这道题目,你有什么比较好的思路吗? 欢迎留言参与讨论。

常见问题

  1. 问:为何题目中的 v 的类型是 int?
    答:还真没有理由,double 也行(这会增长一个坑,你知道是什么吗?),可能仅仅是由于 leetcode 上原题计算的数是 int 吧。
  2. 问:我能正确答对这道题目就必定能经过此次面试吗?
    答:强调一下,面试中考察这样一个题目,并非仅仅考察这道题目自己,不是说你将这道题作对了,就能经过面试,反之也不是说你没作对这道题目就必定不能经过咱们的面试。咱们经过这道题目为契机,但愿考察的是候选人在分析问题解决问题的能力,在交流过程当中所体现的逻辑推理和思惟方式等,固然也有最后实实在在的 code。
  3. 这不是一道数学题目吗,为何程序员面试须要考察这样的数学问题?
    答:同上,不是考察这道题目自己。另外,这也能够说不是一道数学题目,固然能用数学的方式解答。候选人能用数学的方式解答也算正确。
  4. 问:二分是这道题目的标准答案吗?我能用其余解法吗?
    答:同上,题目没有标准答案,就算你用最暴力的算法搜索出来也是正确的解法,其余数学方法也对。
  5. 问:这道题目这么简单,牛顿迭代分分钟秒掉,是否是太简单了?
    答: 给你点赞图片。
  6. 问:这题目在说什么,我搞了半天没看懂,这TM是啥?
    答:若是确实认真看完整篇文章或跟面试官交流了那么久,仍是根本不明白这到底说的是一个什么问题。那就别管了吧,随他去吧,可能不是目标用户而已。
  7. 问:我在实际工做中根本就不会遇到这样的问题,你问这个有什么用?
    答:同第2条答案。
    问:大家公司还缺人么,面试会考察哪些点?
    答:有兴趣或者有其余问题能够戳我邮箱,邮箱地址:aUB0YW5nbGVpLm1l。 面试考察可能会涉及:CS 基础/Code/数据结构和算法/解决问题/项目经验/系统设计/沟通团队协做等等。

结语

本文题目是“从一道面试题谈谈一线大厂码农应该具有的基本能力”,其实,上面大部份内容只谈到了这道题目自己(也穿插了一些对这道题目的分析和理解)。上述题目的场景是社招面试中的,对于这样的题目来讲校招的反馈会更好。由于在校生可能对于工做经验,项目经验等比较欠缺,因此只好用一些比较固定的算法来面试进行筛选(本质上跟学校考试没有太大的区别)。

但这种相似的题目在社招场景下就彻底不适用吗?社招的的同窗写不出来就有很充分的理由吗?或许你在工做场景中不会遇到实际这种题目,但我其实想表达的是,做为在最前线写代码的码农,在别人讲解了二分算法且本身也能理解的状况下,能写出这个二分算法应该不算太难?至关于一个需求,你们讨论了算法实现和解法,须要你把它变成能跑的 code 而已。

其实这篇文章最开始叫“从一道面试题谈谈一线码农应该具有的基本能力”,几年前发出来被喷了,后来想一想彷佛被喷也有点道理,由于在平常有些场景下,“复制粘贴”工程师貌似也够用了,遇到问题有更高水平的人来帮你解决就行,你们都同样的话,怎么体现高手水平呢?但从用人单位角度想,固然是更但愿招聘更加优秀的选手,怎样体现优秀呢?候选人基数太大,怎么筛选,其实也就“高考”同样嘛,经过“考试”择优录取而已。

咱们就不去讨论是否每一个写代码的人都须要有这样的能力(好像答案也是显而易见并非)。但我建议我们一线的程序员们(特指有上进心的一线程序员)应该对一些基本的数据结构和算法有所了解,对常见的算法复杂度有所了解? 或者至少应该有这样的追求吧?好比二分搜索复杂度为何是 。以前遇到过好比有的候选人,Java 开发七八年经验了,简历描述精通 Java,但不清楚 ArrayList, HashMap 内部大概是怎么作的(我理解,无论什么都须要知道大体的实现原理才有可能去优化遇到的各类性能问题吧?)。还有什么熟练掌握 Vim,结果其实就是熟练掌握如何打开和关闭 vim。还有的候选人口头表达头头是道,结果落实到写代码就根本下不了笔。

有时候感受大部分程序员都被大量的需求压迫着,被产品经理催促着,仓促地码着繁琐的业务代码,不断的改着 Bug 又引入新的 Bug。 业务代码重要么,固然重要(代码就是服务于具体业务的),但同时也仍是但愿咱们不要抛弃一些基础的东西,多培养一下咱们的编程素养。咱们在用编程语言,利用各类工具来实现咱们想要达到的目的的时候,能作到“知其然,知其因此然”岂不更好?

相关文章
相关标签/搜索