采访实时编码 - 查找数组

时间:2017-11-07 09:29:25

标签: javascript arrays node.js algorithm

快速元信息:

我正在寻找这个问题的正确位置,stackoverflow上没有。仍在回答这个问题需要编程经验。

我是高级软件工程师和领导node.js开发人员,公司有250名员工,因此我正在进行技术面试。我在这里只呆了两个月,所以我没有那么多的经验(之前的公司规模要小得多,所以聘请新的后端人员非常罕见)。

访谈的部分是实时编码,通常是通过Skype。我认为这非常重要,因为有些人几乎无法做任何事情。

但是有一件事让我感到困惑 - 很多人在执行任务时“找到阵列中的第二大数字”,我觉得这很容易。

我通常只用限制编写这段代码 - 不要对数组进行排序,也不要对数组使用任何特殊函数:

const _arr = [1, 7, 8, 5, 4, 2];

function findSecondBiggest(arr){
}

console.log(findSecondBiggest(_arr));

任务是将代码写入找到第二大数字的函数。我认为这只是“检查”问题,并且对于大多数程序员来说都是“只做”。

即使是看起来很有前途的开发人员也常常失败。我知道他们处于压力之下,但我甚至试图引导他们,让他们平静,他们至少有20分钟(通常甚至30分钟,因为我在通话中停留了10分钟,让他们有机会完成它)。 很多开发人员看起来很有前途 - 他们有很好的经验,知识,能够评估他们使用这个框架/技术的原因......但是不能做到这一点。

我已经与技术主管进行过咨询,他说,如果他们无法做到这一点,我们应该停止 - 因为我们正在寻找程序员,我们期待编写代码。该公司也对中高级开发人员感兴趣。

这项任务真的很难吗?或者,如果您能够提出至少简单的算法并实现它,它是否真的很好?

我也接受这样的解决方案:当第一个找到最大数字时,你使用两个for-cycles,第二个for-cycle找到第二个最大数字,因为它仍然是O(n)。

5 个答案:

答案 0 :(得分:3)

这并不难,它会让你思考。我肯定会在采访中使用这类问题。但是,我会准备一些指导性问题:

  1. 你会如何找到最大的?
  2. 你怎么知道数字是第二个? 等...
  3. 这是我可爱的解决方案(来自@BrettDeWoody's answer的测试案例)。您可以使用查找最大数字的标准方法,然后添加最低数字。

    const _arr = [1, 7, 8, 5, 4, 2];
    
    function findSecondBiggest(arr){
      const r = {};
    
      for(let i = 0; i < arr.length; i++) {
        if(r.first === undefined || arr[i] > r.first) {
          r.second = r.first;
          
          r.first = arr[i];
        } else if (arr[i] !== r.first && (r.second === undefined || arr[i] > r.second)) {
          r.second = arr[i];
        }
      }
        
      return r.second; // for arrays with length under 2, the answer would be undefined
    }
    
    console.log(findSecondBiggest([1, 7, 8, 5, 4, 2])); // 7
    console.log(findSecondBiggest([1, 0, 0, 0, -1, -2])); // 0
    console.log(findSecondBiggest([2, 2, 1, 0, -1, -2, 2])); // 1
    console.log(findSecondBiggest([1, 1, 1, 1, 1])); // undefined
    console.log(findSecondBiggest([0, 0, 0, 1])); // 0
    console.log(findSecondBiggest([1, 2, 3, 4])); // 3
    console.log(findSecondBiggest([Infinity, -Infinity])); // -Infinity
    console.log(findSecondBiggest([-Infinity, Infinity])); // -Infinity
    console.log(findSecondBiggest([1, 2, 3, 4, 5, Infinity])); // 5
    console.log(findSecondBiggest([1])); // undefined

答案 1 :(得分:2)

实际上,开发人员将采取阻力最小的道路。也就是说,他们将对数组进行排序并采用倒数第二个元素。写的代码少,涉及的思维也少。在我的书中获胜。

因此,您需要考虑的问题是,您是否希望开发人员能够记住如何从头开始正确实现此算法(可能是错误的),或者是那些可以重用现有方法以便在最短时间内找到解决方案的开发人员,几乎可以忽略不计的时间惩罚,而且大多数都没有错误。

我的意思是你最后一次想要找到数百万元素数组中的第二大元素是什么时候?大多数开发人员可能只选择我最初描述的方法(排序并占据第二大),如果发现代码是任何性能问题的瓶颈,则将优化留给O(n)一段时间。

答案 2 :(得分:2)

完全同意smac89的观点。作为工程招聘团队和代码导师的成员,我不喜欢采用不切实际的约束的面试问题。

不是提出问题,候选人将永远不会在技术面试之外遇到问题,而是提出与候选人将要工作的内容相关的具有挑战性的问题,并允许候选人展示他们将使用的语言和技能的知识

作为一个很好的例子,一位朋友最近分享了一个前端访谈问题 - 在时间限制内构建一个没有任何库的简单应用程序。

使用提供的API端点(使用?page=N查询参数返回分页结果),应用程序必须进行用户搜索,检索所有结果(可能涉及多页结果),对所有结果进行排序按字母顺序排列结果,并立即显示所有结果。这需要fetchPromise(和Promise.all),数组方法,事件监听器和vanilla JavaScript DOM操作的知识(更重要的是,提高认知度)。

候选人可以查阅任何文档,并根据需要使用任何内置方法。只要候选人熟悉内置的JS方法,Fetch API,Promises等,时间限制就足以让时间完成。

IMO,一个近乎完美的采访问题(至少对于前端开发者而言)。

我的2¢。

以下是我对以下问题的解决方案:

  • 使用ES5
  • 不使用数组方法(Array.length除外)
  • 处理边缘情况,如同构数组,长度为1的数组等

function findSecondBiggest(arr, startInd){
  let start = startInd || 0;
  let largest = arr[start];
  let secondLargest = null;
  const arrLength = arr.length;
  
  if (start === arrLength - start) {
    return null;
  }
    
  for (var i = start + 1; i < arrLength; i++) {
    largest = arr[i] > largest ? setSecond(largest) && arr[i] : largest;
  }
  
  function setSecond(num, check) {
    secondLargest = num;
    return true;
  }
  
  if (secondLargest === null) {
    arr[arrLength] = arr[0];
    return findSecondBiggest(arr, start + 1);
  }
  
  return secondLargest;
}

console.log(findSecondBiggest([1, 7, 8, 5, 4, 2]));
console.log(findSecondBiggest([1, 0, 0, 0, -1, -2]));
console.log(findSecondBiggest([2, 2, 1, 0, -1, -2, 2]));
console.log(findSecondBiggest([1, 1, 1, 1, 1]));
console.log(findSecondBiggest([0, 0, 0, 1]));
console.log(findSecondBiggest([1, 2, 3, 4]));
console.log(findSecondBiggest([Infinity, -Infinity]));
console.log(findSecondBiggest([-Infinity, Infinity]));
console.log(findSecondBiggest([1, 2, 3, 4, 5, Infinity]));
console.log(findSecondBiggest([1]));

答案 3 :(得分:1)

const _arr = [1, 7, 8, 5, 4, 2];

function findSecondBiggest(arr) {
    if(arr.length < 2) {
        return undefined;
    }
    var first = arr[0];
    var second = arr[1];
    if(second > first) {
        [first, second] = [second, first];
    }
    for(var i = 2; i < arr.length; i++) {
        var tmp = arr[i];
        if(tmp > first) {
            [first, second] = [tmp, first];
        } else if(tmp > second) {
            [first, second] = [first, tmp];
        }
    }
    return first != second ? second : undefined;
}

console.log(findSecondBiggest(_arr));

不,我不会说这是一个非常难的问题。即使有一些捕获物可能很容易使人处于压力之下:

  • 处理输入错误(输入元素不足)
  • 输入头部的特殊处理
  • 如果您不了解ES6语法,则交换变量
  • 混合索引和值

因此,虽然不是很难,但有一些缓存会让候选人容易陷入困境,或导致他们感到困惑。

答案 4 :(得分:0)

var a = [1,7,8,5,4,2];

   for (var i = 0; i < a.length ; i++) {
       var big = 0;
       for (var j = 0; j < a.length ; j++) {               
           if (a[j] > a[i]) big++;
       }           
       if (big == 1) {
           return a[i];
       }
   }

并使用预定义的方法

a[a.sort().length-2]