5 வழக்கமான ஜாவாஸ்கிரிப்ட் நேர்காணல் பணிகள்: பகுப்பாய்வு மற்றும் தீர்வுகள்

5 வழக்கமான ஜாவாஸ்கிரிப்ட் நேர்காணல் பணிகள்: பகுப்பாய்வு மற்றும் தீர்வுகள்

மொழிபெயர்ப்பாளரிடமிருந்து: உங்களுக்காக ஒரு கட்டுரையை வெளியிட்டது மரியா அன்டோனிட்டா பெர்னா, பொதுவான ஜாவாஸ்கிரிப்ட் பணிகளைப் பற்றி பேசுகிறார், பெரும்பாலும் டெவலப்பர் விண்ணப்பதாரர்களுக்கு நேர்காணலின் போது வழங்கப்படும். கட்டுரை, முதலில், புதிய புரோகிராமர்களுக்கு பயனுள்ளதாக இருக்கும்.

தொழில்நுட்ப நிறுவனங்களில் நேர்காணல்கள் நீண்ட காலமாக நகரத்தில் பேசப்படுகின்றன. இது ஆச்சரியமாக இருக்க வேண்டியதில்லை - நேர்காணலில் வெற்றிகரமாக தேர்ச்சி பெறுவது ஒரு நல்ல வேலையைப் பெறுவதற்கான வாய்ப்பை வழங்குகிறது. ஆனால் இது மிகவும் எளிதானது அல்ல, ஏனெனில் சிக்கலான சிக்கல்கள் பெரும்பாலும் தீர்க்கப்பட வேண்டும்.

மேலும், பெரும்பாலும், இந்த பணிகளில் பெரும்பாலானவை விண்ணப்பதாரர் செய்யும் வேலையுடன் தொடர்புடையவை அல்ல, ஆனால் அவை இன்னும் தீர்க்கப்பட வேண்டும். சில சமயங்களில் கூகுள் அல்லது வேறு எந்த மூலத்தையும் பார்க்காமல் போர்டில் செய்ய வேண்டும். ஆம், நிலைமை படிப்படியாக மாறுகிறது, சில நிறுவனங்கள் அத்தகைய நேர்காணல்களை கைவிட்டு வருகின்றன, ஆனால் பல முதலாளிகள் இன்னும் இந்த பாரம்பரியத்தை கடைபிடிக்கின்றனர். இந்தக் கட்டுரையானது, வேலை தேடுபவர்களுக்கான பணிகளாகப் பயன்படுத்தப்படும் வழக்கமான ஜாவாஸ்கிரிப்ட் பணிகளின் பகுப்பாய்வுக்கு அர்ப்பணிக்கப்பட்டுள்ளது.

நாங்கள் நினைவூட்டுகிறோம்: "Habr" இன் அனைத்து வாசகர்களுக்கும் - "Habr" விளம்பரக் குறியீட்டைப் பயன்படுத்தி எந்த Skillbox படிப்பிலும் சேரும்போது 10 ரூபிள் தள்ளுபடி.

Skillbox பரிந்துரைக்கிறது: நடைமுறை படிப்பு "மொபைல் டெவலப்பர் புரோ".

முக்கிய விஷயம் என்னவென்றால், உங்கள் நேர்காணலுக்கு முழுமையாக தயாராக வேண்டும்.

ஆம், பணிகளைப் பார்க்கத் தொடங்கும் முன், சில பொதுவான நேர்காணல் தயாரிப்பு குறிப்புகளைப் பார்ப்போம்.

முக்கிய விஷயம் முன்கூட்டியே தயார் செய்ய வேண்டும். அல்காரிதம்கள் மற்றும் தரவு கட்டமைப்புகளை நீங்கள் எவ்வளவு நன்றாக நினைவில் வைத்திருக்கிறீர்கள் என்பதை சோதித்து, உங்களுக்கு அதிகம் அறிமுகமில்லாத பகுதிகளில் உங்கள் அறிவை மேம்படுத்தவும். நேர்காணலுக்குத் தயாராவதற்கு உதவும் பல ஆன்லைன் தளங்கள் உள்ளன. நாங்கள் அறிவுறுத்துகிறோம் அழகற்றவர்கள், பிராம்ப், Interviewing.io и கோட் சிக்னல்.

முடிவை சத்தமாக சொல்ல கற்றுக்கொள்வது மதிப்பு. நீங்கள் என்ன செய்கிறீர்கள் என்பதைப் பற்றி விண்ணப்பதாரர்களிடம் கூறுவது நல்லது, மேலும் போர்டில் எழுதுவது (அல்லது கணினியில் குறியீட்டை தட்டச்சு செய்யவும், அமைதியாகவும்). இந்த வழியில், நீங்கள் குறியீட்டில் தவறு செய்தால், ஆனால் தீர்வு பொதுவாக சரியாக இருந்தால், உங்கள் வெற்றிக்கான வாய்ப்புகளை அதிகரிக்கலாம்.

நீங்கள் அதைத் தீர்க்கத் தொடங்குவதற்கு முன், சிக்கலைப் புரிந்து கொள்ள வேண்டும். சில சந்தர்ப்பங்களில், நீங்கள் ஒரு பணியை மேலோட்டமாகப் புரிந்துகொண்டு தவறான பாதையில் செல்லலாம். நேர்காணல் செய்பவரிடம் சில தெளிவுபடுத்தும் கேள்விகளைக் கேட்பது மதிப்புக்குரியதாக இருக்கலாம்.

கணினியில் இல்லாமல் கையால் குறியீட்டை எழுத பயிற்சி செய்ய வேண்டும். நேர்காணலின் போது விண்ணப்பதாரருக்கு ஒரு மார்க்கர் மற்றும் ஒயிட் போர்டு வழங்கப்படுகிறது, அங்கு குறிப்புகள் அல்லது தானியங்கி வடிவமைப்புகள் எதுவும் இல்லை. ஒரு தீர்வைத் தேடும் போது, ​​உங்கள் குறியீட்டை ஒரு காகிதத்தில் அல்லது நேரடியாக போர்டில் எழுதுவது மதிப்பு. நீங்கள் எல்லாவற்றையும் உங்கள் தலையில் வைத்திருந்தால், நீங்கள் முக்கியமான ஒன்றை மறந்துவிடலாம்.

ஜாவாஸ்கிரிப்டில் டெம்ப்ளேட் பணிகள்

இந்தப் பணிகளில் சில உங்களுக்கு ஏற்கனவே தெரிந்திருக்கும். நீங்கள் நேர்காணல்களைப் பெற்றிருக்கிறீர்கள், அங்கு நீங்கள் இதேபோன்ற ஒன்றைத் தீர்க்க வேண்டும் அல்லது ஜாவாஸ்கிரிப்ட் கற்கும்போது அவற்றைப் பயிற்சி செய்திருக்கிறீர்கள். சரி, இப்போது அவற்றை மீண்டும் தீர்க்க வேண்டிய நேரம் வந்துவிட்டது, மேலும் செயல்முறையின் விரிவான விளக்கத்துடன்.

பாலிண்ட்ரோம்

பாலிண்ட்ரோம் என்பது ஒரு சொல், வாக்கியம் அல்லது எழுத்துகளின் வரிசை, இது வழக்கமான திசையிலும் எதிர் திசையிலும் சரியாகப் படிக்கப்படுகிறது. எடுத்துக்காட்டாக, "அண்ணா" என்பது பாலிண்ட்ரோம், ஆனால் "டேபிள்" மற்றும் "ஜான்" இல்லை.

அரங்கேற்றம்

ஒரு சரம் கொடுக்கப்பட்டது; சரம் ஒரு பாலிண்ட்ரோமாக இருந்தால் true ஐயும், இல்லை எனில் பொய்யையும் வழங்கும் செயல்பாட்டை நீங்கள் எழுத வேண்டும். இந்த வழக்கில், நீங்கள் இடைவெளிகள் மற்றும் நிறுத்தற்குறிகளை கணக்கில் எடுத்துக்கொள்ள வேண்டும்.

பாலிண்ட்ரோம்('ரேஸ்கார்') === உண்மை
பாலிண்ட்ரோம்('அட்டவணை') === பொய்

பணியை பகுப்பாய்வு செய்வோம்

இங்கே முக்கிய யோசனை சரத்தை தலைகீழாக மாற்றுவதாகும். "தலைகீழ்" சரம் அசல் ஒன்றிற்கு முற்றிலும் ஒத்ததாக இருந்தால், நாம் ஒரு பாலிண்ட்ரோம் பெற்றுள்ளோம், மேலும் செயல்பாடு உண்மையாக இருக்க வேண்டும். இல்லை என்றால் பொய்.

முடிவு

பாலிண்ட்ரோமை தீர்க்கும் குறியீடு இங்கே உள்ளது.

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('')
}

முதல் படி, உள்ளீட்டு சரத்தில் உள்ள எழுத்துக்களை சிறிய எழுத்தாக மாற்ற வேண்டும். நிரல் கதாபாத்திரங்களையே ஒப்பிடும் என்பதற்கு இது உத்தரவாதம், வழக்கு அல்லது வேறு எதையும் அல்ல.

இரண்டாவது படி வரியைத் திருப்புவது. இதைச் செய்வது கடினம் அல்ல: .split() முறையைப் பயன்படுத்தி (ஸ்ட்ரிங் லைப்ரரி) அதை ஒரு வரிசையாக மாற்ற வேண்டும். பிறகு .reverse() (Array library) ஐப் பயன்படுத்தி வரிசையை தலைகீழாக மாற்றுகிறோம். .join() (Array library) ஐப் பயன்படுத்தி தலைகீழ் வரிசையை சரமாக மாற்றுவது கடைசி படியாகும்.

இப்போது நீங்கள் செய்ய வேண்டியதெல்லாம், "தலைகீழ்" சரத்தை அசல் சரத்துடன் ஒப்பிட்டு, முடிவை சரி அல்லது தவறு என்று திருப்பித் தருகிறது.

FizzBuzz

நேர்காணல்களில் மிகவும் பிரபலமான பணிகளில் ஒன்று.

அரங்கேற்றம்

1 முதல் n வரையிலான எண்களை கன்சோலுக்கு அச்சிடும் ஒரு செயல்பாட்டை நீங்கள் எழுத வேண்டும், அங்கு n என்பது ஒரு முழு எண், செயல்பாடு பின்வரும் நிபந்தனைகளுடன் ஒரு அளவுருவாக எடுக்கும்:

  • 3 இன் மடங்குகளுக்குப் பதிலாக வெளியீடு fizz;
  • 5 இன் பெருக்கல் எண்களுக்குப் பதிலாக வெளியீடு buzz;
  • 3 மற்றும் 5 இரண்டின் மடங்குகளாக இருக்கும் எண்களுக்குப் பதிலாக fizzbuzz வெளியீடு.

உதாரணமாக

Fizzbuzz(5)

விளைவாக

//1
//2
// fizz
//4
//சலசலப்பு

பணியை பகுப்பாய்வு செய்வோம்

ஜாவாஸ்கிரிப்டைப் பயன்படுத்தி மடங்குகளைக் கண்டுபிடிப்பதற்கான ஒரு வழி இங்கே முக்கிய விஷயம். இது மாடுலஸ் ஆபரேட்டர் அல்லது மீதமுள்ள - % ஐப் பயன்படுத்தி செயல்படுத்தப்படலாம், இது இரண்டு எண்களைப் பிரிக்கும்போது மீதமுள்ளதைக் காட்ட உங்களை அனுமதிக்கிறது. மீதி 0 என்றால், முதல் எண் இரண்டாவது எண்ணின் பெருக்கல் என்று அர்த்தம்.

12% 5 // 2 -> 12 என்பது 5 இன் பெருக்கல் அல்ல
12% 3 // 0 -> 12 என்பது 3 இன் பெருக்கல் ஆகும்

எனவே, நீங்கள் 12 ஐ 5 ஆல் வகுத்தால், நீங்கள் 2 ஐப் பெறுவீர்கள், மீதமுள்ள 2 ஐ நீங்கள் வகுத்தால், நீங்கள் 12 ஐ 3 ஆல் வகுத்தால், உங்களுக்கு 4 கிடைக்கும். முதல் வழக்கில், 0 என்பது 12 இன் பெருக்கல் அல்ல, இரண்டாவது , 5 என்பது 12 இன் பெருக்கல் ஆகும்.

முடிவு

உகந்த தீர்வு பின்வரும் குறியீடாக இருக்கும்:

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

செயல்பாடு நிபந்தனை அறிக்கைகளைப் பயன்படுத்தி தேவையான சோதனைகளைச் செய்கிறது மற்றும் பயனருக்குத் தேவையான முடிவை உருவாக்குகிறது. சிக்கலில், if...else அறிக்கைகளின் வரிசைக்கு கவனம் செலுத்துவது மதிப்பு: இரட்டை நிபந்தனையுடன் (&&) தொடங்கி, பல எண்களைக் கண்டுபிடிக்க முடியாத நிலையில் முடிக்கவும். இதன் விளைவாக, நாங்கள் அனைத்து விருப்பங்களையும் உள்ளடக்குகிறோம்.

அனகிராம்

மற்றொரு வார்த்தையின் அனைத்து எழுத்துக்களையும் ஒரே எண்ணில், ஆனால் வேறு வரிசையில் உள்ள ஒரு வார்த்தைக்கு இது பெயர்.

அரங்கேற்றம்

இரண்டு சரங்கள் அனகிராம்களா என்பதைச் சரிபார்க்கும் ஒரு செயல்பாட்டை நாம் எழுத வேண்டும், மேலும் வழக்கு ஒரு பொருட்டல்ல. எழுத்துக்கள் மட்டுமே கணக்கிடப்படுகின்றன; இடைவெளிகள் அல்லது நிறுத்தற்குறிகள் கணக்கில் எடுத்துக்கொள்ளப்படுவதில்லை.

anagram('finder', 'friend') —> true
அனகிராம்('ஹலோ', 'பை') —> தவறு

பணியை பகுப்பாய்வு செய்வோம்

இங்கே கருத்தில் கொள்ள வேண்டிய முக்கியமான விஷயம் என்னவென்றால், இரண்டு உள்ளீட்டு வரிகளில் உள்ள ஒவ்வொரு எழுத்தையும் ஒவ்வொரு வரியிலும் அவற்றின் எண்ணையும் நீங்கள் சரிபார்க்க வேண்டும்.

கண்டுபிடிப்பாளர் —> f: 1 நண்பர் —> f: 1
நான்: 1 ஆர்: 1
ந: 1 நான்: 1
ஈ: 1 இ: 1
இ: 1 ந: 1
ஆர்: 1 டி: 1

அனகிராம் தரவைச் சேமிக்க, நீங்கள் JavaScript ஆப்ஜெக்ட் போன்ற கட்டமைப்பைத் தேர்ந்தெடுக்க வேண்டும். இந்த வழக்கில் முக்கியமானது கடிதத்தின் தன்மை, மதிப்பு என்பது தற்போதைய வரியில் அதன் மறுபடியும் எண்ணிக்கை.

மற்ற நிபந்தனைகளும் உள்ளன:

  • ஒப்பிடும்போது கடிதங்களின் வழக்கு கணக்கில் எடுத்துக்கொள்ளப்படவில்லை என்பதை உறுதிப்படுத்த வேண்டும். நாங்கள் இரண்டு சரங்களையும் சிறிய அல்லது பெரிய எழுத்துக்கு மாற்றுகிறோம்.
  • ஒப்பீட்டிலிருந்து அனைத்து கதாபாத்திரங்கள் அல்லாதவற்றை நாங்கள் விலக்குகிறோம். உடன் வேலை செய்வது சிறந்தது வழக்கமான வெளிப்பாடுகள்.

முடிவு

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

பயன்பாட்டில் கவனம் செலுத்துங்கள் Object.keys() மேலே உள்ள துணுக்கில். இந்த முறை, பொருளில் தோன்றும் அதே வரிசையில் பெயர்கள் அல்லது விசைகளைக் கொண்ட வரிசையை வழங்குகிறது. இந்த வழக்கில், வரிசை இப்படி இருக்கும்:

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

இதன் மூலம் மொத்தமாக வளையம் செய்யாமல் பொருளின் பண்புகளைப் பெறுகிறோம். ஒரு சிக்கலில், இரண்டு சரங்களும் ஒரே எண்ணிக்கையிலான எழுத்துக்களைக் கொண்டிருக்கின்றனவா என்பதைச் சரிபார்க்க, .length பண்புடன் இந்த முறையைப் பயன்படுத்தலாம் - இது அனகிராம்களின் முக்கிய அம்சமாகும்.

உயிரெழுத்துக்களைத் தேடுங்கள்

நேர்காணல்களில் அடிக்கடி வரும் மிகவும் எளிமையான பணி.

அரங்கேற்றம்

ஒரு சரத்தை வாதமாக எடுத்து, சரத்தில் உள்ள உயிரெழுத்துக்களின் எண்ணிக்கையை வழங்கும் செயல்பாட்டை நீங்கள் எழுத வேண்டும்.
உயிரெழுத்துக்கள் "a", "e", "i", "o", "u".

உதாரணம்:

findVowels('ஹலோ') // —> 2
உயிர் எழுத்துக்கள் ('ஏன்') // —> 0

முடிவு

இங்கே எளிய விருப்பம்:

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
}

.includes() முறையைப் பயன்படுத்துவதில் கவனம் செலுத்த வேண்டியது அவசியம். இது சரங்கள் மற்றும் வரிசைகள் இரண்டிற்கும் கிடைக்கிறது. ஒரு அணிவரிசையில் ஒரு குறிப்பிட்ட மதிப்பு உள்ளதா என்பதைத் தீர்மானிக்க இது பயன்படுத்தப்பட வேண்டும். அணிவரிசையில் குறிப்பிடப்பட்ட மதிப்பு இருந்தால் இந்த முறை சரி என்றும், இல்லையெனில் தவறு என்றும் வழங்கும்.

சிக்கலுக்கு ஒரு குறுகிய தீர்வு உள்ளது:

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

இது .match() முறையைப் பயன்படுத்துகிறது, இது திறமையான தேடலைச் செயல்படுத்த உங்களை அனுமதிக்கிறது. ஒரு முறை வாதமாக ஒரு வழக்கமான வெளிப்பாடு குறிப்பிட்ட சரத்திற்குள் காணப்பட்டால், திரும்பும் மதிப்பு என்பது பொருந்தும் எழுத்துகளின் வரிசையாகும். சரி, பொருத்தங்கள் இல்லை என்றால், .match() பூஜ்யத்தை வழங்கும்.

ஃபைபோனச்சி

பல்வேறு நிலைகளில் நேர்காணல்களில் காணக்கூடிய ஒரு உன்னதமான பணி. ஃபைபோனச்சி வரிசை என்பது ஒரு எண்களின் வரிசையாகும், அங்கு ஒவ்வொன்றும் முந்தைய இரண்டின் கூட்டுத்தொகையாகும். எனவே, முதல் பத்து எண்கள் இப்படி இருக்கும்: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.

அரங்கேற்றம்

ஒரு குறிப்பிட்ட வரிசையில் n வது பதிவை வழங்கும் ஒரு செயல்பாட்டை நீங்கள் எழுத வேண்டும், n என்பது செயல்பாட்டிற்கு ஒரு வாதமாக அனுப்பப்படும் எண்ணாகும்.

ஃபைபோனச்சி(3) // —> 2

இந்த பணியானது, வாதத்தில் குறிப்பிடப்பட்டுள்ள எண்ணிக்கையை ஒரு லூப்பின் வழியாக நடப்பதை உள்ளடக்கியது, மதிப்பை பொருத்தமான நிலையில் திருப்பித் தருகிறது. சிக்கலை முன்வைக்கும் இந்த வழியில் சுழல்களைப் பயன்படுத்த வேண்டும். அதற்குப் பதிலாக நீங்கள் மறுநிகழ்வைப் பயன்படுத்தினால், அது நேர்காணல் செய்பவரை மகிழ்வித்து உங்களுக்கு சில கூடுதல் புள்ளிகளை வழங்கக்கூடும்.

முடிவு

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

முடிவுகள் வரிசையில், முதல் இரண்டு எண்கள் தொடரில் உள்ளன, ஏனெனில் வரிசையில் உள்ள ஒவ்வொரு உள்ளீடும் முந்தைய இரண்டு எண்களின் கூட்டுத்தொகையாகும். தொடக்கத்தில், அடுத்த எண்ணைப் பெறுவதற்கு இரண்டு எண்கள் இல்லை, எனவே லூப் தானாகவே அவற்றை உருவாக்க முடியாது. ஆனால், நமக்குத் தெரிந்தபடி, முதல் இரண்டு எண்கள் எப்போதும் 0 மற்றும் 1 ஆகும். எனவே, நீங்கள் முடிவுகளை வரிசையை கைமுறையாக துவக்கலாம்.

மறுநிகழ்வைப் பொறுத்தவரை, எல்லாம் எளிமையானது மற்றும் அதே நேரத்தில் மிகவும் சிக்கலானது:

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

நாம் fibonacci() ஐ அழைக்கிறோம், சிறிய மற்றும் சிறிய எண்களை வாதங்களாக அனுப்புகிறோம். அனுப்பப்பட்ட வாதம் 0 அல்லது 1 ஆக இருக்கும்போது நிறுத்துகிறோம்.

முடிவுக்கு

பெரும்பாலும், நீங்கள் முன்னோட்டம் அல்லது ஜாவாஸ்கிரிப்ட் டெவலப்பர் வேலைக்காக (குறிப்பாக ஜூனியர் மட்டத்தில் இருந்தால்) நேர்காணல் செய்யப்பட்டிருந்தால், இந்தப் பணிகளில் ஏதேனும் ஒன்றை நீங்கள் ஏற்கனவே சந்தித்திருக்கலாம். ஆனால் நீங்கள் அவற்றைக் காணவில்லை என்றால், அவை எதிர்காலத்தில் பயனுள்ளதாக இருக்கும் - குறைந்தபட்சம் பொது வளர்ச்சிக்கு.

Skillbox பரிந்துரைக்கிறது:

ஆதாரம்: www.habr.com

கருத்தைச் சேர்