5 مشاكل مقابلة JavaScript شائعة: التحليل والحلول

5 مشاكل مقابلة JavaScript شائعة: التحليل والحلول

من المترجم: نشرت مقالا لك Maria Antonietta Perna ، التي تتحدث عن مهام JavaScript النموذجية، غالبًا ما يتم تقديمها للمتقدمين والمطورين في المقابلات. ستكون المقالة مفيدة ، أولاً وقبل كل شيء ، للمبرمجين المبتدئين.

لطالما كانت المقابلات في شركات التكنولوجيا هي حديث المدينة. هذا ليس مفاجئًا - فالإكمال الناجح للمقابلة يجعل من الممكن الحصول على وظيفة جيدة. لكن هذا ليس بالأمر السهل ، لأنه غالبًا ما يكون من الضروري حل المشكلات المعقدة.

علاوة على ذلك ، غالبًا لا تتعلق معظم هذه المهام بالعمل الذي سيؤديه مقدم الطلب ، لكنها لا تزال بحاجة إلى حل. في بعض الأحيان يتعين عليك القيام بذلك على السبورة ، دون التحقق من Google أو أي مصدر آخر. نعم ، الوضع يتغير تدريجياً ، وفي بعض الشركات يرفضون مثل هذه المقابلات ، لكن العديد من أصحاب العمل لا يزالون ملتزمين بهذا التقليد. هذه المقالة مخصصة لتحليل مهام JavaScript النموذجية التي غالبًا ما تستخدم كمهام للمتقدمين.

نذكر: لجميع قراء "Habr" - خصم 10 روبل عند التسجيل في أي دورة Skillbox باستخدام رمز "Habr" الترويجي.

يوصي Skillbox بما يلي: دورة عملية "Mobile Developer PRO".

الشيء الرئيسي هو الاستعداد بعناية لمقابلتك.

نعم ، قبل أن نبدأ في تقسيم المهام ، دعنا نلقي نظرة على بعض النصائح العامة للتحضير للمقابلة.

الشيء الرئيسي هو الاستعداد مقدما. تحقق من مدى تذكرك للخوارزميات وهياكل البيانات ، وحسّن معرفتك في المجالات التي لا تعرفها جيدًا. هناك العديد من المنصات عبر الإنترنت لمساعدتك على الاستعداد للمقابلات الشخصية. ننصح geeksforgeeks, جزمة, المقابلة и الرمز.

يجدر تعلم نطق القرار بصوت عالٍ. يُنصح بإخبار المتقدمين بما تفعله ، وليس فقط الكتابة على السبورة (أو كتابة رمز على الكمبيوتر ، بصمت أيضًا). وبالتالي ، إذا ارتكبت خطأ في الكود ، ولكن الحل صحيح بشكل عام ، يمكنك زيادة فرصك في النجاح.

يجب فهم المشكلة قبل البدء في الحل. في بعض الحالات ، يمكنك فهم المهمة ظاهريًا ثم السير في المسار الخطأ. قد يكون من المفيد طرح بعض الأسئلة التوضيحية على القائم بإجراء المقابلة.

تحتاج إلى التدرب على كتابة التعليمات البرمجية يدويًا ، وليس على جهاز الكمبيوتر. يحدث أنه في المقابلات يتم إعطاء مقدم الطلب علامة ولوحة لا توجد بها نصائح أو تنسيق تلقائي. عندما تبحث عن حل ، اكتب الكود الخاص بك على قطعة من الورق أو على السبورة مباشرة. إذا احتفظت بكل شيء في رأسك ، فيمكنك أن تنسى شيئًا مهمًا.

مهام القالب في JavaScript

ربما تكون بالفعل على دراية ببعض هذه المهام. لقد أجريت مقابلات حيث كان عليك حل شيء مشابه ، أو تدربت عليها أثناء تعلم JavaScript. حسنًا ، حان الوقت الآن لحلها مرة أخرى ، مع شرح مفصل للعملية.

باليندروم

المتناظرة هي كلمة أو جملة أو سلسلة من الأحرف تقرأ تمامًا بنفس الطريقة في الاتجاه المعتاد وفي الاتجاه المعاكس. على سبيل المثال ، "آنا" متناظرة ، لكن "الجدول" و "جون" ليست كذلك.

انطلاق

إعطاء سلسلة ؛ تحتاج إلى كتابة دالة تسمح لك بإرجاع صحيح إذا كانت السلسلة متناظرة ، وخطأ إذا لم تكن كذلك. في هذه الحالة ، يجب مراعاة المسافات وعلامات الترقيم.

متناظرة ('سيارة السباق') === صحيح
متناظرة ('الجدول') === خطأ

تحليل المهمة

الفكرة الرئيسية هنا هي قلب الوتر للخلف. إذا كانت السلسلة "العكسية" متطابقة تمامًا مع السلسلة الأصلية ، فعندئذ يكون لدينا متناظر ويجب أن تعود الوظيفة إلى القيمة 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 () (مكتبة String). ثم نعكس المصفوفة باستخدام .reverse () (Array library). الخطوة الأخيرة هي تحويل المصفوفة العكسية إلى سلسلة باستخدام .join () (Array library).

كل ما هو مطلوب الآن هو مقارنة السلسلة "العكسية" بالسلسلة الأصلية ، وإرجاع النتيجة صواب أو خطأ.

fizzbuzz

واحدة من أكثر مقابلات العمل شعبية.

انطلاق

مطلوب كتابة دالة تعرض الأرقام من 1 إلى n إلى وحدة التحكم ، حيث يمثل n عددًا صحيحًا تأخذه الوظيفة كمعامل ، مع الشروط التالية:

  • fizz الإخراج بدلاً من مضاعفات 3 ؛
  • إخراج الطنانة بدلاً من مضاعفات 5 ؛
  • إخراج fizzbuzz بدلاً من مضاعفات كل من 3 و 5.

مثال

فيزباز (5)

نتيجة

/ / 1
/ / 2
// أز
/ / 4
//شرب حتى الثمالة

تحليل المهمة

الشيء الرئيسي هنا هو طريقة البحث عن المضاعفات باستخدام JavaScript. يمكن تنفيذه باستخدام عامل التشغيل أو الباقي -٪ ، مما يسمح لك بإظهار الباقي عند قسمة رقمين. إذا كان الباقي 0 ، فهذا يعني أن الرقم الأول هو من مضاعفات الثانية.

12٪ 5 // 2 -> 12 ليس من مضاعفات العدد 5
12٪ 3 // 0 -> 12 من مضاعفات 3

لذلك ، إذا قسمنا 12 على 5 ، فسنحصل على 2 مع الباقي 2. إذا قسمنا 12 على 3 ، فسنحصل على 4 مع باقي 0. في الحالة الأولى ، 12 ليس مضاعفًا لـ 5 ، في ثانيًا ، 12 هو مضاعف 3.

حل

سيكون الحل الأفضل هو الكود التالي:

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: بدءًا بشرط مزدوج (&&) وينتهي بالحالة التي يتعذر فيها العثور على أرقام متعددة. نتيجة لذلك ، نحن نغطي جميع الخيارات.

الجناس الناقص

هذا هو اسم الكلمة التي تحتوي على جميع أحرف كلمة أخرى بنفس الرقم ، ولكن بترتيب مختلف.

انطلاق

نحتاج إلى كتابة دالة تتحقق مما إذا كانت السلاسل عبارة عن جناس ناقص ، وأن حالة الأحرف ليست مهمة. عدد الأحرف فقط ؛ لا تؤخذ المسافات أو علامات الترقيم في الاعتبار.

الجناس الناقص ("مكتشف" ، "صديق") -> صحيح
الجناس الناقص ('hello'، 'bye') -> false

تحليل المهمة

من المهم هنا مراعاة أنه من الضروري التحقق من كل حرف في سطري إدخال ورقمهما في كل سطر.

الباحث -> 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 - للتحقق مما إذا كانت كلتا السلسلتين تحتويان على نفس عدد الأحرف - وهذه ميزة مهمة في الجناس الناقصة.

البحث بحرف العلة

مهمة بسيطة إلى حد ما تظهر غالبًا في المقابلات.

انطلاق

تحتاج إلى كتابة دالة تأخذ سلسلة كوسيطة وتعيد عدد حروف العلة التي تحتويها السلسلة.
أحرف العلة هي "أ" و "هـ" و "أنا" و "س" و "ش".

على سبيل المثال:

findVowels ('hello') // -> 2
findVowels ('why') // -> 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)
}

نستمر في استدعاء فيبوناتشي () ، ونمرر بأعداد أصغر وأصغر كوسيطات. نتوقف عندما تكون الوسيطة التي تم تمريرها 0 أو 1.

إنتاج

على الأرجح ، لقد واجهت بالفعل أيًا من هذه المهام إذا كنت تجري مقابلة مع وظيفة مطور للواجهة الأمامية أو وظيفة مطور JavaScript (خاصة إذا كانت في مستوى مبتدئ). ولكن إذا لم تصادفها ، فقد تكون مفيدة في المستقبل - على الأقل من أجل التطوير العام.

يوصي Skillbox بما يلي:

المصدر: www.habr.com

إضافة تعليق