Entrevista live-coding – Encuentra el segundo número más grande en array

Información meta-rápida:

Estaba buscando el lugar realmente correcto para esta pregunta, no hay ninguno en stackoverflow. Seguir respondiendo esta pregunta requiere experiencia en progtwigción.


Soy ingeniero senior de software y desarrollador principal de node.js en compañía de 250 empleados, por lo tanto, realizo entrevistas técnicas. Estoy aquí solo por 2 meses, así que no tengo mucha experiencia (la compañía anterior era mucho más pequeña, por lo que contratar a un nuevo backend era muy raro).

La parte de la entrevista es en vivo, generalmente a través de Skype. Creo que esto es bastante importante, porque algunas personas realmente no pueden hacer casi nada.

Pero hay una cosa que me molesta: muchas personas que fallan en la tarea "encuentran el segundo mayor número en set", lo que creo que es muy fácil.

Normalmente les escribo este fragment de código con solo una limitación: no orderen una matriz y no utilicen funciones especiales para las matrices:

const _arr = [1, 7, 8, 5, 4, 2]; function findSecondBiggest(arr){ } console.log(findSecondBiggest(_arr)); 

Y la tarea es escribir código en la function que encuentra el segundo número más grande. Pensé que esta sería solo una pregunta de "verificación" y sería "solo hazlo" para la mayoría de los progtwigdores.

Incluso los desarrolladores que parecen bastante prometedores a menudo fallan en eso. Sé que están bajo presión, pero incluso estoy tratando de guiarlos, calmarlos y tienen al less 20 minutos (a menudo incluso 30, ya que me quedo 10 minutos más para darles la oportunidad de terminarlo). Muchos desarrolladores se ven muy prometedores: tienen buena experiencia, conocimiento, pueden evaluar por qué están usando este marco / tecnología … Pero no pueden hacerlo.

Lo consulté con Technical Lead y él dice que si no pueden hacer esto, debemos suspenderlo, ya que estamos buscando a los progtwigdores y esperamos escribir el código. Además, la empresa está interesada en desarrolladores de nivel medio a superior.

¿Es esta tarea realmente tan difícil? ¿O es uno bueno que realmente muestra si puedes encontrar al less un algorithm simple e implementarlo?

También estoy aceptando la solución donde se usan dos for-cycles cuando el primero encuentra el número más grande, el segundo para el ciclo encuentra el segundo número más grande porque todavía es O (n).

Completamente de acuerdo con el sentimiento de smac89 . Como miembro de un equipo de contratación de ingenieros y mentor de código, no soy partidario de las preguntas de entrevistas con restricciones poco realists.

En lugar de hacer una pregunta, un candidato nunca se encontrará fuera de una entrevista técnica, planteará una pregunta desafiante relevante para lo que el candidato estará trabajando y le permitirá demostrar su conocimiento del idioma y las habilidades que utilizará.

Como un gran ejemplo, un amigo compartió recientemente una pregunta de entrevista frontend: crea una aplicación sencilla sin bibliotecas, dentro de un límite de time.

Utilizando un punto final API proporcionado (que arrojó resultados paginados utilizando un parámetro de búsqueda de ?page=N ), la aplicación tuvo que realizar una búsqueda de usuario, recuperar todos los resultados (que pueden implicar varias páginas de resultados), orderar todos los resultados alfabéticamente y mostrar todos los resultados a la vez. Esto requirió conocimiento (y más importante aún, conocimiento) de fetch , Promise (y Promise.all ), methods de matriz, escuchas de events y manipulación JavaScript de vanilla JavaScript.

El candidato puede consultar cualquier documento y utilizar cualquier método incorporado según sea necesario. La restricción de time permitió que se completara el time suficiente, siempre y cuando el candidato estuviera familiarizado con los methods JS incorporados, Fetch API, Promises, etc.

IMO, una pregunta de entrevista casi perfecta (para los desarrolladores frontend al less).

Mi 2 ¢.

Y aquí está mi solución a la pregunta que:

  • Utiliza ES5
  • No utiliza methods de matriz (que no sean Array.length)
  • Maneja cajas de borde como una matriz homogénea, una matriz de longitud 1, etc.
 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])); 

En realidad, los desarrolladores tomarán el path de menor resistencia. Es decir, orderarán la matriz y tomarán el segundo elemento pasado. Menos código para escribir y less pensamiento involucrado. Una victoria en mi libro.

Así que la pregunta que debes tener en count es si quieres desarrolladores que puedan recordar cómo implementar este algorithm correctamente desde cero (posiblemente con errores), o aquellos que pueden reutilizar methods ya existentes para encontrar la solución en el menor time posible, con casi pena de time insignificante, Y sobre todo libre de errores.

Quiero decir, ¿cuándo fue la última vez que quisiste encontrar el segundo elemento más grande en una matriz de millones de elementos? La mayoría de los desarrolladores probablemente solo opten por el método que describí inicialmente (orderando y tomando el segundo más grande), y dejar la optimization en O (n) para otro momento si se descubre que el código es el cuello de botella a cualquier problema de performance.

No es difícil, y te hace pensar. Definitivamente usaría este tipo de pregunta en una entrevista. Sin embargo, prepararía algunas preguntas orientadoras:

  1. ¿Cómo encontrarías el más grande?
  2. ¿Cómo sabes que un número es el segundo? etc …

Y aquí está mi solución encantadora (casos de testing robados de la respuesta de @BrettDeWoody ). Puede usar la forma estándar de encontrar el número más grande y luego agregar el más bajo también.

 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 
 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)); 

No, no diría que esta es una pregunta exactamente difícil. A pesar de que hay algunas capturas que pueden arrojar fácilmente a alguien bajo estrés:

  • Manejo de input incorrecta (no hay suficientes elementos de input)
  • Manejo especial para el jefe de la input
  • Intercambio de variables si no conoce la syntax de ES6
  • Mezcla de índice y valor

Entonces, aunque no es difícil, hay un par de cachings que pueden hacer que los candidatos se peguen fácilmente o que se confundan.

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]; } } 

y con methods pnetworkingefinidos

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