5 detyra tipike në intervistat për JavaScript: analiza dhe zgjidhje

5 detyra tipike në intervistat për JavaScript: analiza dhe zgjidhje

Nga përkthyesi: kemi publikuar për ju një artikull i Marisë Perna, i cili flet për detyrat standarde të JavaScript, që zakonisht ofrohen për aplikantët-programues në intervista. Artikulli do të jetë i dobishëm, kryesisht për programuesit e rinj.

Intervistat nĂ« kompanitĂ« teknologjike prej kohĂ«sh kanĂ« qenĂ« njĂ« temĂ« diskutimi. Nuk ka çfarĂ« tĂ« habitemi — kalimi i suksesshĂ«m i intervistĂ«s ofron mundĂ«sinĂ« pĂ«r tĂ« siguruar njĂ« punĂ« tĂ« mirĂ«. Por nuk Ă«shtĂ« aq e lehtĂ«, pasi shpeshherĂ« nevojitet tĂ« zgjidhni probleme tĂ« komplikuara.

Më së shumti, shumica e këtyre problemeve nuk kanë lidhje me punën që do të kryejë aplikanti, por duhet prapë t'i zgjidhni ato. N sometimes, duhet t'i zgjidhni ato në një tablo, pa kontrolluar me Google ose ndonjë burim tjetër. Po, situata gradualisht po ndryshon, dhe në disa kompani po hiqet dorë nga këto intervista, por shumë punëdhënës vazhdojnë të qëndrojnë pas kësaj tradite. Ky artikull i kushtohet shqyrtimit të detyrave standarde të JavaScript, të cilat përdoren shpesh si detyra për aplikantët.

KujtojmĂ«: pĂ«r tĂ« gjithĂ« lexuesit e «Habra» — zbritje prej 10,000 rublesh pĂ«r regjistrimin nĂ« çdo kurs Skillbox me kodin promovues «Habr».

Skillbox rekomandon: Kurs praktik «Mobil developer PRO».

E rëndësishme është përgatitja e kujdesshme për intervistën tuaj

Po, para se të filloni të shqyrtoni detyrat, le të shqyrtojmë këshillat e përgjithshme për përgatitjen për intervistën.

E rëndësishme është të përgatiteni paraprakisht. Kontrolloni se sa mirë i mbani mend algoritmet dhe strukturat e të dhënave, dhe forconi njohuritë tuaja në ato fusha që nuk janë shumë të njohura për ju. Ka shumë platforma online që mund t'ju ndihmojnë të përgatiteni për intervistat. Këshillojmë GeeksforGeeks, Pramp, Interviewing.io dhe CodeSignal.

Duhet të mësoni të shprehni zgjidhjen me zë. Preferohet të flisni me aplikantët për atë që po bëni, dhe jo thjesht të shkruani në tablo (ose të shkruani kod në kompjuter, gjithashtu në heshtje). Kështu, nëse bëni një gabim në kod, por mënyra e zgjidhjes është përgjithësisht e saktë, mund të rrisni shanset tuaja për sukses.

Duhet ta kuptoni detyrën para se të filloni zgjidhjen. Në disa raste, mund të kuptoni sipërfaqësisht detyrën dhe pastaj të shkoni në një drejtim të gabuar. Mund të vlejë të bëni disa pyetje sqaruese intervistuesit.

Duhet të ushtroni të shkruani kod me dorë, dhe jo në PC. Në intervistat, ndonjëherë kandidatëve u jepet një marker dhe një tabelë pa asnjë udhëzues ose formatim automatik. Kur kërkoni zgjidhje, është mirë të shkruani kodin tuaj në një copë letër ose në tabelë. Nëse mbani gjithçka në mendje, mund të harroni diçka të rëndësishme.

Detyrat model në JavaScript

Mundësisht disa nga këto detyra ju janë të njohura. Ju ose keni kaluar intervista ku duhet të zgjidhni diçka të ngjashme, ose keni praktikuar ato gjatë studimit të JavaScript. Tani është koha të zgjidhni ato përsëri, përfshirë një shpjegim të hollësishëm të procesit.

Palindrom

Palindromi Ă«shtĂ« njĂ« fjalĂ«, njĂ« fjali ose njĂ« renditje simbolet qĂ« lexohen nĂ« tĂ« njĂ«jtĂ«n mĂ«nyrĂ« si nĂ« drejtim tĂ« zakonshĂ«m ashtu edhe nĂ« tĂ« kundĂ«rt. PĂ«r shembull, “Anna” Ă«shtĂ« njĂ« palindrom, ndĂ«rsa “table” dhe “John” nuk janĂ«.

Shtrimi

E dhënë një varg; duhet të shkruani një funksion që kthen vlerën true nëse vargu është palindrom dhe false nëse nuk është. Duhet të merrni parasysh hapësirat dhe shenjat e pikësimit.

palindrome(‘racecar’) === true
palindrome(‘table’) === false

Analizojmë detyrën

Ideja kryesore kĂ«tu Ă«shtĂ« tĂ« ktheni vargun nĂ« drejtimin e kundĂ«rt. NĂ«se vargu “i kthyer” Ă«shtĂ« plotĂ«sisht identik me origjinalin, atĂ«herĂ« kemi njĂ« palindrom dhe funksioni duhet tĂ« kthejĂ« vlerĂ«n true. Ndryshe, false.

Zgjidhja

Ja kodi që lejon zgjidhjen e palindromit.

const palindrome = str => {
  // kthe vargun në shkronja të vogla
  str = str.toLowerCase()
  // kthe vargun hyrës dhe kthe rezultatin e
  // krahasimit
  return str === str.split('').reverse().join('')
}

Hapi i parë është të konvertoni karakteret e vargut hyrës në shkronja të vogla. Kjo është një garanci që programi do të krahasojë pikërisht vetë karakteret, jo regjistrin ose diçka tjetër.

Hapi i dytë është të kthehet vargu. Kjo nuk është e vështirë: duhet ta ktheni atë në një array përmes metodës .split() (biblioteka String). Më pas e kthejmë array-n duke përdorur .reverse() (biblioteka Array). Hapi final është të kthejmë array-n e kthyer në varg me .join() (biblioteka Array).

Tani, gjithçka qĂ« duhet tĂ« bĂ«ni Ă«shtĂ« tĂ« krahasoni vargun “e kthyer” me origjinalin, duke kthyer rezultatin true ose false.

FizzBuzz

Një nga detyrat më të njohura në intervista.

Shtrimi

Duhet të shkruani një funksion që nxjerr në konsolë numrat nga 1 deri në n, ku n është një numër i plotë që funksioni e merr si parametër, me këto kushte:

  • tĂ« nxjerrĂ« fizz nĂ« vend tĂ« numrave qĂ« janĂ« tĂ« shumĂ«fishueshĂ«m me 3;
  • shfaqja e buzz nĂ« vend tĂ« numrave qĂ« janĂ« tĂ« shumĂ«fish tĂ« 5;
  • shfaqja e fizzbuzz nĂ« vend tĂ« numrave qĂ« janĂ« tĂ« shumĂ«fish tĂ« 3 dhe 5.

Shembulli

Fizzbuzz(5)

Rezultati

// 1
// 2
// fizz
// 4
// buzz

Analizojmë detyrën

E rĂ«ndĂ«sishme kĂ«tu Ă«shtĂ« mĂ«nyra e gjetjes sĂ« numrave tĂ« shumĂ«fishme duke pĂ«rdorur JavaScript. Kjo mund tĂ« realizohet duke pĂ«rdorur operatorin e mod dhe ose mbetje — %, i cili tregon mbetjen gjatĂ« ndarjes sĂ« dy numrave. NĂ«se mbetja Ă«shtĂ« 0, kjo do tĂ« thotĂ« se numri i parĂ« Ă«shtĂ« i shumĂ«fishmĂ« me numrin e dytĂ«.

12 % 5 // 2 -> 12 nuk është i shumëfishmë me 5
12 % 3 // 0 -> 12 është i shumëfishmë me 3

KĂ«shtu, nĂ«se ndajmĂ« 12 me 5, marrim 2 me mbetje 2. NĂ«se ndajmĂ« 12 me 3, marrim 4 me mbetje 0. NĂ« rastin e parĂ«, 12 nuk Ă«shtĂ« i shumĂ«fishmĂ« me 5, nĂ« rastin e dytĂ« — 12 Ă«shtĂ« i shumĂ«fishmĂ« me 3.

Zgjidhja

Zgjidhja më e mirë do të jetë kodi si vijon:

const fizzBuzz = num => {
  for(let i = 1; i <= num; i++) {
    // kontroloni nëse numri është i shumëfishmë me 3 dhe 5
    if(i % 3 === 0 && i % 5 === 0) {
      console.log('fizzbuzz')
    } // kontrolloni nëse numri është i shumëfishmë me 3
      else if(i % 3 === 0) {
      console.log('fizz')
    } // kontrolloni nëse numri është i shumëfishmë me 5
      else if(i % 5 === 0) {
      console.log('buzz')
    } else {
      console.log(i)
    }
  }
}

Funksioni kryen kontrollin e nevojshëm duke përdorur operatorët kushtorë dhe jep rezultatin e kërkuar për përdoruesin. Në këtë detyrë duhen kushtuar vëmendje rendit të operatorëve if
else: filloni me kushtin e dyfishtë (&&) dhe përfundojini me rastin kur nuk mund të gjejmë numra të shumëfishmë. Si rezultat, ne mbulim të gjitha rastet.

Anagram

Kështu quhet një fjalë që përmban të gjitha shkronjat e një fjale tjetër në të njëjtën sasi, por në një rend tjetër.

Shtrimi

Duhet të shkruani një funksion që kontrollon nëse dy fjalitë janë anagramë, duke mos marrë në konsideratë regjistrin e shkronjave. Merren parasysh vetëm simbolet; hapësirat ose shenjat e pikës nuk merren në konsideratë.

anagram('finder', 'Friend') -> true
anagram('hello', 'bye') -> false

Analizojmë detyrën

Këtu është e rëndësishme të merren parasysh të gjitha shkronjat në të dy fjalitë hyrëse dhe numri i tyre në secilën fjalë.

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

PĂ«r ruajtjen e tĂ« dhĂ«nave tĂ« anagramĂ«s, duhet tĂ« zgjidhet njĂ« strukturĂ« si literal objekt JavaScript. ÇelĂ«si nĂ« kĂ«tĂ« rast Ă«shtĂ« simboli i shkronjĂ«s, vlera Ă«shtĂ« numri i pĂ«rsĂ«ritjeve tĂ« saj nĂ« fjalinĂ« aktuale.

Ka edhe kushte të tjera:

  • Duhet tĂ« sigurohemi qĂ« regjistri i shkronjave nĂ« krahasim tĂ« mos merret parasysh. Thjesht shndĂ«rrojmĂ« tĂ« dy fjalitĂ« nĂ« shkronja tĂ« vogla ose tĂ« mĂ«dha.
  • PĂ«rjashtojmĂ« nga krahasimi tĂ« gjitha jo-simbolet. MĂ« mirĂ« Ă«shtĂ« tĂ« punojmĂ« me shprehje normale.

Zgjidhja

// 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
}

Kujdesi në përdorimin e Object.keys() në snippet-in lart. Ky metod kthen një array që përmban emrat ose çelësat në të njëjtin rend siç shfaqen në objekt. Në këtë rast, array do të jetë kështu:

[‘f’, ‘i’, ‘n’, ‘d’, ‘e’, ‘r’]

KĂ«shtu, ne marrim vetitĂ« e objektit pa pasur nevojĂ« tĂ« ekzekutojmĂ« njĂ« cikĂ«l tĂ« gjatĂ«. NĂ« kĂ«tĂ« detyrĂ« mund tĂ« pĂ«rdoret ky metod me vetinĂ« .length — pĂ«r tĂ« kontrolluar nĂ«se tĂ« dy stringat kanĂ« tĂ« njĂ«jtin numĂ«r karakteresh — kjo Ă«shtĂ« njĂ« veçori e rĂ«ndĂ«sishme pĂ«r anagramet.

Gjetja e tingujve të theksuar

Një detyrë mjaft e thjeshtë, e cila shpesh shfaqet në intervista.

Shtrimi

Duhet të shkruani një funksion që merr një string si argument dhe kthen numrin e tingujve që ndodhen në string.
Tingujt e theksuar janë "a", "e", "i", "o", "u".

Shembulli:

findVowels(‘hello’) // —> 2
findVowels(‘why’) // —> 0

Zgjidhja

Ja varianti më i thjeshtë:

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
}

ËshtĂ« e rĂ«ndĂ«sishme tĂ« vĂ«mĂ« re pĂ«rdorimin e metodĂ«s .includes(). Ajo Ă«shtĂ« e aksesueshme edhe pĂ«r stringa, edhe pĂ«r array. Duhet ta aplikoni pĂ«r tĂ« zbuluar nĂ«se njĂ« array pĂ«rmban njĂ« vlerĂ« tĂ« caktuar. Kjo metodĂ« kthen true, nĂ«se array pĂ«rmban vlerĂ«n e specifikuar, dhe false, nĂ«se jo.

Ka edhe një zgjidhje më të shkurtër për problemin:

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

Këtu përdoret metoda .match(), e cila lejon realizimin e një kërkimi efektiv. Nëse një shprehje e rregullt si argument i metodës zbulohet brenda stringut të specifikuar, atëherë vlera që kthehet është një array i simboleve të përputhura. Ndërsa nëse nuk ka përputhje, .match() kthen null.

Fibonacci

Një detyrë klasike që mund të takoni në intervista të niveleve të ndryshme. Duhet kujtuar se sekuenca e Fibonacci-t është një radhë numrash ku çdo numër i mëpasshëm është shuma e dy numrave të mëparshëm. Kështu, dhjetë numrat e parë paraqiten kështu: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.

Shtrimi

Duhet të shkruani një funksion që kthen regjistrimin n në një sekuencë të caktuar, ku n është numri që kalon si argument në funksion.

fibonacci(3) // —> 2

Kjo detyrë përfshin kalimin nëpër cikël një numër të caktuar herësh, siç është specifikuar në argument, duke kthyer vlerën në pozitat përkatëse. Ky lloj formimi i detyrës kërkon përdorimin e cikleve. Nëse në vend të kësaj përdorni rekursivitetin, kjo mund t'i pëlqejë intervistuesit dhe t'ju japë disa pikë shtesë.

Zgjidhja

const fibonacci = num => {
  // ruaj sekuencën Fibonacci që po
  // do ta gjenerosh brenda një array dhe
  // inicializo array-n me dy numrat e parë
  // të sekuencës
  const result = [0, 1]
 
  for(let i = 2; i <= num; i++) {
    // shto shumen e dy numrave
    // që paraprijnë pozitat e i në array-n rezultat
    // në fund të array-it rezultat
    const prevNum1 = result[i - 1]
    const prevNum2 = result[i - 2]
    result.push(prevNum1 + prevNum2)
  }
  // kthe vlerën e fundit në array-in rezultat
  return result[num]
}

Në array-in rezultat, dy numrat e parë ndodhen në rresht, pasi çdo regjistrim në sekuencë përbëhet nga shuma e dy numrave të mëparshëm. Në fillim të dy numrave, që mund të merren për të prodhuar numrin e ardhshëm, nuk ka, kështu që cikli nuk arrin t'i gjenerojë ato automatikisht. Por, siç e dimë, dy numrat e parë janë gjithmonë 0 dhe 1. Prandaj, mund ta inicializojmë array-in rezultat manualisht.

Sa i përket rekursivitetit, këtu është më e thjeshtë dhe më e komplikuar njëkohësisht:

const fibonacci = num => {
  // nëse numri është ose 0 ose 1 kthe numrin
  if(num < 2) {
    return num
  }
  // rekursivitet këtu
  return fibonacci(num - 1) + fibonacci(num - 2)
}

Ne vazhdojmë të thërrasim fibonacci(), duke kaluar numra gjithnjë e më të vegjël si argumente. Ndaluar kur argumenti i kaluar është 0 ose 1.

Përfundimi

Probabilisht, ju keni hasur nĂ« ndonjĂ« nga kĂ«to detyra, nĂ«se keni kaluar intervista pĂ«r pozita si zhvillues frontend ose JavaScript (veçanĂ«risht nĂ«se Ă«shtĂ« niveli junior). Por nĂ«se ato nuk ju kanĂ« rĂ«nĂ«, mund tĂ« jenĂ« tĂ« dobishme nĂ« tĂ« ardhmen — gjithsesi pĂ«r zhvillimin tuaj tĂ« pĂ«rgjithshĂ«m.

Skillbox rekomandon:

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster