5 Problemes habituals d'entrevista de JavaScript: anàlisi i solucions

5 Problemes habituals d'entrevista de JavaScript: anàlisi i solucions

Del traductor: va publicar un article per a tu Maria Antonietta Perna, que parla de les tasques típiques de JavaScript, que sovint s'ofereix als sol·licitants-desenvolupadors a les entrevistes. L'article serà útil, en primer lloc, per als programadors novells.

Les entrevistes a empreses tecnològiques fa temps que es parla a la ciutat. Això no és d'estranyar: la finalització satisfactòria de l'entrevista fa possible aconseguir una bona feina. Però això no és tan fàcil, perquè sovint cal resoldre problemes complexos.

A més, sovint la majoria d'aquestes tasques no estan relacionades amb la feina que realitzarà el sol·licitant, però encara s'han de resoldre. De vegades has de fer-ho a la pissarra, sense consultar-ho amb Google o cap altra font. Sí, la situació està canviant a poc a poc i en algunes empreses es neguen a aquestes entrevistes, però molts empresaris segueixen adherint-se a aquesta tradició. Aquest article està dedicat a l'anàlisi de les tasques típiques de JavaScript que s'utilitzen sovint com a tasques per als sol·licitants.

Recordem: per a tots els lectors de "Habr": un descompte de 10 rubles en inscriure's a qualsevol curs de Skillbox amb el codi promocional "Habr".

Skillbox recomana: Curs pràctic "Desenvolupador mòbil PRO".

El més important és preparar-se acuradament per a l'entrevista.

Sí, abans de començar a desglossar les tasques, anem a veure alguns consells generals per preparar-se per a una entrevista.

El més important és preparar-se amb antelació. Comproveu com recordeu els algorismes i les estructures de dades i milloreu els vostres coneixements en àrees amb les quals no esteu molt familiaritzats. Hi ha moltes plataformes en línia per ajudar-vos a preparar-vos per a les entrevistes. Aconsellem GeeksforGeeks, Pramp, Entrevista.io и CodeSignal.

Val la pena aprendre a pronunciar la decisió en veu alta. És aconsellable dir als sol·licitants què estàs fent, i no només escriure a la pissarra (o escriure codi a l'ordinador, també en silenci). Així, si cometeu un error en el codi, però la solució generalment és correcta, podeu augmentar les vostres possibilitats d'èxit.

El problema s'ha d'entendre abans de començar la solució. En alguns casos, podeu entendre superficialment la tasca i després anar pel camí equivocat. Potser val la pena fer algunes preguntes aclaridores a l'entrevistador.

Heu de practicar l'escriptura de codi a mà, no en un ordinador. Succeeix que en les entrevistes al sol·licitant se li dóna un marcador i una pissarra on no hi ha indicacions ni format automàtic. Quan busqueu una solució, escriviu el vostre codi en un full de paper o a la pissarra. Si ho tens tot al cap, pots oblidar alguna cosa important.

Tasques de plantilla en JavaScript

Probablement ja esteu familiaritzat amb algunes d'aquestes tasques. O heu fet entrevistes en què havíeu de resoldre alguna cosa semblant, o bé les heu practicat mentre aprenia JavaScript. Bé, ara toca resoldre'ls de nou, i amb una explicació detallada del procés.

Palíndrom

Un palíndrom és una paraula, frase o seqüència de caràcters que es llegeix exactament de la mateixa manera tant en el sentit habitual com en el sentit contrari. Per exemple, "Anna" és un palíndrom, però "taula" i "John" no ho són.

Posada en escena

Donada una cadena; heu d'escriure una funció que us permeti tornar true si la cadena és un palíndrom, i false en cas contrari. En aquest cas, s'han de tenir en compte els espais i els signes de puntuació.

palíndrom('cotxe de carreres') === cert
palíndrom('taula') === fals

Anàlisi de la tasca

La idea principal aquí és girar la corda cap enrere. Si la cadena "inversa" és completament idèntica a l'original, llavors tenim un palíndrom i la funció hauria de tornar true. Si no, fals.

decisió

Aquí teniu el codi que us permet resoldre el palíndrom.

const palindrome = str => {
  // turn the string to lowercase
  str = str.toLowerCase()
  // reverse input string and return the result of the
  // comparisong
  return str === str.split('').reverse().join('')
}

El primer pas és convertir els caràcters de cadena d'entrada a minúscules. Això és una garantia que el programa compararà exactament els propis personatges, i no majúscules ni una altra cosa.

El segon pas és el revés de la línia. Això és fàcil de fer: cal convertir-lo en una matriu utilitzant el mètode .split() (biblioteca String). A continuació, invertim la matriu utilitzant .reverse() (biblioteca de matrius). L'últim pas és convertir la matriu inversa en una cadena mitjançant .join() (biblioteca de matrius).

Ara només cal comparar la cadena "inversa" amb l'original, retornant el resultat vertader o fals.

efervessada

Una de les entrevistes de feina més populars.

Posada en escena

Cal escriure una funció que mostri nombres de l'1 al n a la consola, on n és un nombre enter que la funció pren com a paràmetre, amb les condicions següents:

  • sortida fizz en lloc de múltiples de 3;
  • sortida de buzz en lloc de múltiples de 5;
  • sortida fizzbuzz en lloc de múltiples de 3 i 5.

Exemple

Fizzbuzz (5)

Resultat

// 1
// 2
// efervessada
// 4
// brunzit

Anàlisi de la tasca

El més important aquí és la manera de trobar múltiples mitjançant JavaScript. Es pot implementar mitjançant l'operador mòdul o el residu -%, que permet mostrar la resta quan es divideix dos nombres. Si la resta és 0, vol dir que el primer nombre és múltiple del segon.

12% 5 // 2 -> 12 no és múltiple de 5
12% 3 // 0 -> 12 és múltiple de 3

Així, si dividim 12 per 5, obtenim 2 amb un residu de 2. Si dividim 12 per 3, obtenim 4 amb un residu de 0. En el primer cas, 12 no és múltiple de 5, en el segon, 12 és múltiple de 3.

decisió

La millor solució seria el següent codi:

const fizzBuzz = num => {
  for(let i = 1; i <= num; i++) {
    // check if the number is a multiple of 3 and 5
    if(i % 3 === 0 && i % 5 === 0) {
      console.log('fizzbuzz')
    } // check if the number is a multiple of 3
      else if(i % 3 === 0) {
      console.log('fizz')
    } // check if the number is a multiple of 5
      else if(i % 5 === 0) {
      console.log('buzz')
    } else {
      console.log(i)
    }
  }
}

La funció realitza les comprovacions necessàries mitjançant declaracions condicionals i produeix el resultat requerit per l'usuari. A la tasca, val la pena parar atenció a l'ordre de les declaracions if...else: començant amb una doble condició (&&) i acabant amb el cas en què no s'han pogut trobar múltiples números. Com a resultat, cobrim totes les opcions.

Anagrama

Aquest és el nom d'una paraula que conté totes les lletres d'una altra paraula en el mateix número, però en un ordre diferent.

Posada en escena

Hem d'escriure una funció que comprove si dues cadenes són anagrames, i el cas de les lletres no importa. Només compten els caràcters; no es tenen en compte els espais ni els signes de puntuació.

anagrama('cercador', 'amic') --> cert
anagrama('hola', 'adéu') --> fals

Anàlisi de la tasca

Aquí és important tenir en compte que cal comprovar cada lletra en dues línies d'entrada i el seu número a cada línia.

cercador -> f: 1 amic -> f: 1
i: 1 r: 1
n: 1 i: 1
d: 1 e: 1
e: 1 n: 1
r:1 d:1

Per emmagatzemar dades d'anagrames, hauríeu de triar una estructura com ara un literal d'objecte JavaScript. La clau en aquest cas és el caràcter de la lletra, el valor és el nombre de repeticions d'aquesta a la línia actual.

També hi ha altres condicions:

  • Cal assegurar-se que no es tingui en compte el cas de les lletres a l'hora de comparar. Només has de convertir les dues cadenes en minúscules o majúscules.
  • Excloem tots els no personatges de la comparació. Millor treballar amb expressions regulars.

decisió

// helper function that builds the
// object to store the data
const buildCharObject = str => {
  const charObj = {}
  for(let char of str.replace(/[^w]/g).toLowerCase()) {
    // if the object has already a key value pair
    // equal to the value being looped over,
    // increase the value by 1, otherwise add
    // the letter being looped over as key and 1 as its value
    charObj[char] = charObj[char] + 1 || 1
  }
  return charObj
}
 
// main function
const anagram = (strA, strB) => {
  // build the object that holds strA data
  const aCharObject = buildCharObject(strA)
  // build the object that holds strB data
  const bCharObject = buildCharObject(strB)
 
  // compare number of keys in the two objects
  // (anagrams must have the same number of letters)
  if(Object.keys(aCharObject).length !== Object.keys(bCharObject).length) {
    return false
  }
  // if both objects have the same number of keys
  // we can be sure that at least both strings
  // have the same number of characters
  // now we can compare the two objects to see if both
  // have the same letters in the same amount
  for(let char in aCharObject) {
    if(aCharObject[char] !== bCharObject[char]) {
      return false
    }
  }
  // if both the above checks succeed,
  // you have an anagram: return true
  return true
}

Presteu atenció a l’ús Object.keys() al fragment de dalt. Aquest mètode retorna una matriu que conté els noms o les claus en el mateix ordre que apareixen a l'objecte. En aquest cas, la matriu serà així:

['f', 'i', 'n', 'd', 'e', ​​​​'r']

D'aquesta manera obtenim les propietats de l'objecte sense haver de fer un gran bucle. En una tasca, podeu utilitzar aquest mètode amb la propietat .length - per comprovar si ambdues cadenes tenen el mateix nombre de caràcters - aquesta és una característica important dels anagrames.

Cerca de vocals

Una tasca bastant senzilla que sovint es troba a les entrevistes.

Posada en escena

Heu d'escriure una funció que prengui una cadena com a argument i retorni el nombre de vocals que conté la cadena.
Les vocals són "a", "e", "i", "o", "u".

Exemple:

findVowels('hola') // --> 2
findVowels('per què') // --> 0

decisió

Aquí teniu l'opció més fàcil:

const findVowels = str => {
  let count = 0
  const vowels = ['a', 'e', 'i', 'o', 'u']
  for(let char of str.toLowerCase()) {
    if(vowels.includes(char)) {
      count++
    }
  }
  return count
}

És important parar atenció a l'ús del mètode .includes(). Està disponible tant per a cadenes com per a matrius. S'hauria d'utilitzar per esbrinar si una matriu conté un valor determinat. Aquest mètode retorna true si la matriu conté el valor especificat i false en cas contrari.

També hi ha una solució més breu al problema:

const findVowels = str => {
  const matched = str.match(/[aeiou]/gi)
  return matched ? matches.length : 0
}

Aquí s'utilitza el mètode .match(), que us permet implementar una cerca eficient. Si una expressió regular com a argument de mètode es troba dins de la cadena especificada, el valor de retorn és una matriu de caràcters coincidents. Bé, si no hi ha coincidències, aleshores .match() retorna nul.

Fibonacci

Una tasca clàssica que es pot complir en entrevistes de diversos nivells. Val la pena recordar que la successió de Fibonacci és una sèrie de nombres, on cada següent és la suma dels dos anteriors. Així, els deu primers nombres tenen aquest aspecte: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.

Posada en escena

Heu d'escriure una funció que retorni l'nè registre en una seqüència determinada, i n és un nombre que es passa com a argument a la funció.

Fibonacci(3) // --> 2

Aquesta tasca implica fer un bucle a través del nombre de vegades especificat a l'argument, retornant el valor a la posició adequada. Aquesta manera d'establir el problema requereix l'ús de bucles. Si utilitzeu la recursivitat, és possible que a l'entrevistador li agradi i us doni uns quants punts addicionals.

decisió

const fibonacci = num => {
  // store the Fibonacci sequence you're going
  // to generate inside an array and
  // initialize the array with the first two
  // numbers of the sequence
  const result = [0, 1]
 
  for(let i = 2; i <= num; i++) {
    // push the sum of the two numbers
    // preceding the position of i in the result array
    // at the end of the result array
    const prevNum1 = result[i - 1]
    const prevNum2 = result[i - 2]
    result.push(prevNum1 + prevNum2)
  }
  // return the last value in the result array
  return result[num]
}

A la matriu de resultats, els dos primers nombres estan continguts en una fila perquè cada entrada de la seqüència consta de la suma dels dos números anteriors. No hi ha dos números al principi que es puguin prendre per obtenir el següent número, de manera que el bucle no els pot generar automàticament. Però, com sabem, els dos primers nombres són sempre 0 i 1. Per tant, podeu inicialitzar la matriu de resultats manualment.

Pel que fa a la recursivitat, tot és més senzill i més complicat alhora:

const fibonacci = num => {
  // if num is either 0 or 1 return num
  if(num < 2) {
    return num
  }
  // recursion here
  return fibonacci(num - 1) + fibonacci(num - 2)
}

Seguim cridant a fibonacci(), passant com a arguments nombres cada cop més petits. Ens aturem quan l'argument passat és 0 o 1.

Sortida

El més probable és que ja t'hagis enfrontat a qualsevol d'aquestes tasques si estàveu entrevistant per a una feina com a desenvolupador de frontend o JavaScript (especialment si és un nivell júnior). Però si no us heu trobat, poden ser útils en el futur, almenys per al desenvolupament general.

Skillbox recomana:

Font: www.habr.com

Afegeix comentari