
Dalla traduzione: abbiamo pubblicato per voi un articolo , spesso proposte ai candidati programmatori durante i colloqui. L'articolo sarà utile, prima di tutto, per i programmatori principianti.
I colloqui nelle aziende tecnologiche sono diventati una leggenda. Non c'è da sorprendersi: superare un colloquio con successo offre la possibilità di ottenere un buon lavoro. Ma non è così semplice, poiché spesso è necessario risolvere problemi complessi.
Inoltre, la maggior parte di questi problemi non ha alcuna attinenza con il lavoro che il candidato svolgerà, ma è comunque necessario risolverli. A volte bisogna farlo sulla lavagna, senza consultare Google o qualsiasi altra fonte. Sì, la situazione sta cambiando lentamente e alcune aziende stanno rinunciando a tali colloqui, ma molti datori di lavoro seguono ancora questa tradizione. Questo articolo è dedicato all'analisi dei problemi tipici di JavaScript, che vengono spesso utilizzati come esercizi per i candidati.
Ricordiamo: per tutti i lettori di «Habr» — sconto di 10.000 rubli per l'iscrizione a qualsiasi corso Skillbox con il codice promozionale «Habr».
Skillbox consiglia: Corso pratico .
La cosa principale è prepararsi con cura per il colloquio
Sì, prima di iniziare a esaminare i problemi, esaminiamo alcuni consigli generali per la preparazione al colloquio.
La cosa principale è prepararsi in anticipo. Controlla quanto bene ricordi algoritmi e strutture dati e rafforza le tue conoscenze nelle aree che non conosci troppo bene. Ci sono molte piattaforme online che possono aiutarti a prepararti per i colloqui. Ti consigliamo di , , e .
È utile imparare a spiegare le soluzioni ad alta voce. È consigliabile raccontare ai candidati cosa stai facendo, piuttosto che limitarti a scrivere sulla lavagna (o a digitare codice sul computer, rimanendo in silenzio). In questo modo, se nel codice commetti un errore, ma la logica della soluzione è corretta, puoi aumentare le tue possibilità di successo.
Devi riflettere sul problema prima di procedere con la soluzione. In alcuni casi, è possibile comprendere superficialmente il compito e poi andare nella direzione sbagliata. Potrebbe essere utile fare alcune domande chiarificatrici all'intervistatore.
È necessario esercitarsi a scrivere codice a mano, non al computer. Capita che durante i colloqui ai candidati venga dato un marcatore e una lavagna, dove non ci sono suggerimenti né formattazione automatica. Nella ricerca di una soluzione, è utile annotare il proprio codice su un foglio di carta o direttamente sulla lavagna. Se si tiene tutto in mente, si potrebbe dimenticare qualcosa di importante.
Compiti standardizzati in JavaScript
Probabilmente alcune di queste attività ti sono già familiari. O hai partecipato a colloqui in cui era necessario risolvere qualcosa di simile, oppure ti sei esercitato su di esse mentre studiavi JavaScript. Adesso è il momento di affrontarle nuovamente, con una spiegazione dettagliata del processo.
Palindromo
Un palindromo è una parola, una frase o una sequenza di caratteri che si legge esattamente allo stesso modo in entrambe le direzioni. Ad esempio, "Anna" è un palindromo, mentre "table" e "John" non lo sono.
Enunciato
Data una stringa, bisogna scrivere una funzione che restituisce true se la stringa è un palindromo e false altrimenti. Si devono considerare spazi e punteggiatura.
palindrome(‘racecar’) === true
palindrome(‘table’) === false
Analizziamo il compito
L'idea principale qui è invertire la stringa. Se la stringa "invertita" è completamente identica all'originale, allora abbiamo un palindromo e la funzione deve restituire true. Altrimenti, false.
Soluzione
Ecco il codice che permette di risolvere il problema del palindromo.
const palindrome = str => {
// trasforma la stringa in minuscolo
str = str.toLowerCase()
// inverte la stringa di input e restituisce il risultato del
// confronto
return str === str.split('').reverse().join('')
}Il primo passo è trasformare i caratteri della stringa di input in minuscolo. Questo garantisce che il programma confronti i caratteri stessi, e non il maiuscolo o altro.
Il secondo passo è invertire la stringa. Questo non è difficile: dobbiamo trasformarla in un array tramite il metodo .split() (libreria String). Poi invertemo l'array utilizzando .reverse() (libreria Array). L'ultimo passaggio è trasformare l'array invertito in una stringa usando .join() (libreria Array).
Ora, tutto ciò che bisogna fare è confrontare la stringa "invertita" con quella originale, restituendo il risultato true o false.
FizzBuzz
Uno dei compiti più popolari durante i colloqui.
Enunciato
È richiesto di scrivere una funzione che stampi in console i numeri da 1 a n, dove n è un intero passato come parametro, con queste condizioni:
- stampare fizz al posto dei numeri divisibili per 3;
- output buzz al posto dei numeri multipli di 5;
- output fizzbuzz al posto dei numeri multipli sia di 3 che di 5.
Esempio
Fizzbuzz(5)
Risultato
// 1
// 2
// fizz
// 4
// buzz
Analizziamo il compito
La cosa principale qui è il metodo di ricerca dei numeri multipli utilizzando JavaScript. Può essere realizzato utilizzando l'operatore modulo o il resto — %, che consente di mostrare il resto della divisione di due numeri. Se il resto è 0, significa che il primo numero è un multiplo del secondo.
12 % 5 // 2 -> 12 non è un multiplo di 5
12 % 3 // 0 -> 12 è un multiplo di 3
Quindi, se dividiamo 12 per 5, otteniamo 2 con un resto di 2. Se invece dividiamo 12 per 3, otteniamo 4 con un resto di 0. Nel primo caso 12 non è un multiplo di 5, nel secondo — 12 è un multiplo di 3.
Soluzione
La soluzione ottimale sarà il seguente codice:
const fizzBuzz = num => {
for(let i = 1; i <= num; i++) {
// controlla se il numero è un multiplo di 3 e 5
if(i % 3 === 0 && i % 5 === 0) {
console.log('fizzbuzz')
} // controlla se il numero è un multiplo di 3
else if(i % 3 === 0) {
console.log('fizz')
} // controlla se il numero è un multiplo di 5
else if(i % 5 === 0) {
console.log('buzz')
} else {
console.log(i)
}
}
}La funzione esegue i controlli necessari utilizzando gli operatori condizionali e restituisce il risultato richiesto all'utente. È importante prestare attenzione all'ordine degli operatori if…else: si inizia con la condizione doppia (&&) e si termina con il caso in cui non si riescono a trovare numeri multipli. Di conseguenza copriamo tutte le opzioni.
Anagramma
Così si chiama una parola che contiene tutte le lettere di un'altra parola nello stesso numero, ma in un ordine diverso.
Enunciato
È necessario scrivere una funzione che verifichi se due stringhe sono anagrammi, senza tenere conto della maiuscole. Si considerano solo i caratteri; spazi o punteggiature non vengono presi in considerazione.
anagram(‘finder’, ‘Friend’) -> true
anagram(‘hello’, ‘bye’) -> false
Analizziamo il compito
È importante tenere conto che è necessario verificare ogni lettera nelle due stringhe di input e la loro quantità in ciascuna stringa.
finder -> f: 1 friend -> f: 1
i: 1 r: 1
n: 1 i: 1
d: 1 e: 1
e: 1 n: 1
r: 1 d: 1
Per memorizzare i dati dell'anagramma, è consigliabile utilizzare una struttura come il literal object di JavaScript. La chiave in questo caso è il simbolo della lettera, il valore è il numero delle sue ripetizioni nella stringa corrente.
Ci sono anche altre condizioni:
- È necessario assicurarsi che la maiuscole non venga considerata nel confronto. Basta trasformare entrambe le stringhe in minuscolo o maiuscolo.
- Escludiamo dal confronto tutti i non-simboli. È meglio lavorare con .
Soluzione
// 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
}Si prega di notare l'uso di nello snippet sopra. Questo metodo restituisce un array contenente nomi o chiavi nella stessa ordine in cui compaiono nell'oggetto. In questo caso, l'array sarà il seguente:
[‘f’, ‘i’, ‘n’, ‘d’, ‘e’, ‘r’]
In questo modo, otteniamo le proprietà dell'oggetto senza la necessità di eseguire un ciclo pesante. In questo compito, possiamo utilizzare questo metodo con la proprietà .length — per verificare se entrambe le stringhe hanno lo stesso numero di caratteri — una caratteristica importante delle anagrammi.
Ricerca delle vocali
Un compito piuttosto semplice, che appare spesso nei colloqui.
Enunciato
Devi scrivere una funzione che prenda una stringa come argomento e restituisca il numero di vocali contenute nella stringa.
Le vocali sono 'a', 'e', 'i', 'o', 'u'.
Esempio:
findVowels(‘hello’) // -> 2
findVowels(‘why’) // -> 0
Soluzione
Ecco la soluzione più semplice:
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
}È importante notare l'uso del metodo .includes(). È disponibile sia per le stringhe che per gli array. Dovrebbe essere usato per identificare se un array contiene un determinato valore. Questo metodo restituisce true se l'array contiene il valore specificato e false in caso contrario.
Esiste anche una soluzione più breve al problema:
const findVowels = str => {
const matched = str.match(/[aeiou]/gi)
return matched ? matched.length : 0
}Qui viene utilizzato il metodo .match(), che consente di implementare una ricerca efficiente. Se l'espressione regolare fornita come argomento al metodo viene trovata all'interno della stringa specificata, il valore restituito diventa un array di caratteri corrispondenti. Se non ci sono corrispondenze, .match() restituisce null.
Fibonacci
Un compito classico, che può essere trovato in colloqui di vari livelli. Vale la pena ricordare che la sequenza di Fibonacci è una serie di numeri in cui ogni numero successivo è la somma dei due precedenti. Così, i primi dieci numeri appaiono nel seguente modo: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.
Enunciato
Devi scrivere una funzione che restituisca l'n-esimo termine di una determinata sequenza, dove n è il numero passato come argomento della funzione.
fibonacci(3) // -> 2
Questo compito implica l'esecuzione di un ciclo per il numero di volte specificato nell'argomento, restituendo il valore alla posizione corrispondente. Questo tipo di formulazione del problema richiede l'uso di cicli. Se invece utilizzi la ricorsione, potrebbe piacere all'intervistatore e darti qualche punto extra.
Soluzione
const fibonacci = num => {
// memorizza la sequenza di Fibonacci che stai per generare all'interno di un array e
// inizializza l'array con i primi due
// numeri della sequenza
const result = [0, 1]
for(let i = 2; i <= num; i++) {
// aggiungi la somma dei due numeri
// precedenti alla posizione di i nell'array result
// alla fine dell'array result
const prevNum1 = result[i - 1]
const prevNum2 = result[i - 2]
result.push(prevNum1 + prevNum2)
}
// restituisci l'ultimo valore nell'array result
return result[num]
}Nell'array dei risultati, i primi due numeri si trovano nella riga, poiché ogni voce nella sequenza è la somma dei due numeri precedenti. All'inizio non ci sono due numeri da cui partire per ottenere il numero successivo, quindi il ciclo non può generarli automaticamente. Ma, come sappiamo, i primi due numeri sono sempre 0 e 1. Pertanto, l'array dei risultati può essere inizializzato manualmente.
Per quanto riguarda la ricorsione, qui è tutto più semplice e più difficile allo stesso tempo:
const fibonacci = num => {
// se num è 0 o 1 restituisci num
if(num < 2) {
return num
}
// ricorsione qui
return fibonacci(num - 1) + fibonacci(num - 2)
}Continuiamo a chiamare fibonacci(), passando numeri sempre più piccoli come argomenti. Ci fermiamo quando l'argomento passato è 0 o 1.
Conclusione
Probabilmente ti sei già imbattuto in uno dei compiti indicati se hai sostenuto colloqui per posizioni di sviluppatore frontend o JavaScript (specialmente a livello junior). Ma se non li hai già incontrati, potrebbero tornarti utili in futuro, almeno per una crescita personale.
Skillbox consiglia:
- Corso online pratico .
- Corso online .
- Corso pratico annuale .
Fonte: habr.com
