سوالاتی که از من در مصاحبه‌های توسعه‌دهنده Frontend پرسیده شد

سلام، امیدوارم که خوب باشید.
مدتی پیش بود که از شرکتی که توش مشغول بودم، اومدم بیرون و دنبال کار میگشتم. تو این مدت به شرکت های مختلفی برای مصاحبه رفتم. از اونجایی که خیلی از سوالات مصاحبه پرتکرار هستند، سوالاتی که ازم پرسیده میشد رو برای خودم یادداشت میکردم. حالا تصمیم گرفتم این سوالات رو باهاتون به اشتراک بذارم(سوالات مربوط به مصاحبه شرکت های خوب و مطرح ایرانی هست، ولی بهتره اسم خود شرکت ها رو نام نبرم).
چون تعداد سوالات زیاد هست، به چند بخش تقسیمشون کردم. خود سوالات جاوااسکریپت به دو بخش تقسیم میشن: بخش اول مربوط به پاسخ های شفاهی هست. خود سوالات رو هم از مباحث پایه ای تر شروع کردم.
بخش دوم جاوااسکریپت، سوالات عملی یا همون live code هست که در پست بعدی منتشر میکنم.
از اونجایی که هدف، بیشتر منتقل کردن خود سوالات بوده، برای پاسخشون به سایت های دیگه ارجاع دادم.
امیدوارم برای کسایی که جویای کار هستند مفید باشه.
این اولین پست من در ویرگول یا هر جای دیگه هست :)) ممنون میشم اگر نظری، پیشنهادی، انتقادی داشتید یا اشکالی دیدید، بیان کنید، تا بتونم بهترش کنم این نوشته رو.
بریم سراغ سوالها :)

بخش اول: جاوااسکریپت

۱- مفهوم hoisting رو در جاوااسکریپت توضیح بدید.

از لینک زیر میتونید پاسخ این سوال رو بخونید: hoisting


۲- تفاوت let, var, const را توضیح دهید.

از لینک زیر میتونید جواب این سوال رو بخونید: var vs let vs cons


۳- توضیح دهید scopeها توی جاوااسکریپت چی هستند؟

پاسخ این سوال: scope


۴- توضیح دهید destructuring در جاوااسکریپت چیست؟

پاسخ این سوال: destructuring


۵- تفاوت arrow functions و normal functions رو توضیح دهید.

پاسخ این سوال: arrow func vs normal func
اما یکی از تفاوت های مهم این دو نوع تابع، مقدار this هست. از این لینک میتونید بیشتر درباره this بخونید: this keyword


۶- توضیح بدید IIFE چیه؟ به همراه یک مثال از کاربردش.

پاسخ این سوال: IIFE


۷- تعریف عملگر + (unary plus) و تفاوتش با متد های parseInt و Number? به طور مثال خروجی if(+'1M') چیست؟

از این لینک و پست های بعدی که بهش لینک شده، میتونید به طور کامل درباره عملگرها بخونید: عملگرها
این هم توضیح در مورد عملگر unary plus و متدهای Number و parseInt

اما اگر مشخصا بخوایم جواب این سوال رو بدیم باید بگیم که عملگر unary plus و متد Number تقریبا مشابه هم عمل میکنند، با این تفاوت که عملگر unary plus سریعتر هست، اون هم به این دلیل که محاسبات اضافی برای تبدیل انجام نمیده. اما متد Number برای تبدیل های پیچیده تر و دقیق تر مناسب هست. هر دو این روش ها، اگر رشته ورودی شامل کاراکترهای غیر عددی باشه، NaN برمیگردونن. در مقابل parseInt قادر هست چنین رشته هایی رو پارس کنه و بخش عددی رو ازش استخراج کنه.
بنابراین، parseInt('1M') برابر 1 میشه، در حالی که خروجی '1M'+ برابر NaN و خروجی Number('1M') هم برابر NaN هست. و از اونجایی که NaN یک falsy value هست، پس خروجی if(+'1M') برابر false هست و وارد بلاک if نمیشیم.


۸- تفاوت دو متد map و forEach رو در جاوااسکریپت توضیح دهید.

از لینک زیر میتونید جواب این سوال رو بخونید: map vs forEach

اما به طور خلاصه اگه بخوام جواب این سوال رو بدم:
۱- map یک آرایه جدید برمیگردونه و مستقیما آرایه اصلی رو تغییر نمیده در حالی که forEach آرایه جدیدی برنمیگردونه و در واقع undefined برمیگردونه و مستقیما آرایه اصلی رو تغییر میده.

۲- به دلیل اینکه map یک آرایه جدید برمیگردونه، میشه متدهای دیگه رو به اون زنجیره کرد. در حالی که با forEach این کار امکانپذیر نیست.

۳- از نظر سرعت و زمان اجرا، این دو مشابه هم هستن و خیلی تفاوت قابل ملاحظه ای ندارن.


۹- فرض کن لیستی از سفارش های کاربر(سبد خرید) رو داریم و میخوایم مجموع قیمت این سفارش ها رو حساب کنیم. از چه متدی در جاوااسکریپت استفاده میکنی؟

پاسخ این سوال، متد reduce در آرایه ها هست(از روش های دیگه مثل map و ... برای loop زدن میشه استفاده کرد، ولی چیزی که مصاحبه کننده دوست داره بشنوه، reduce هست :) ).
از این لینک میتونید در مورد این متد بخونید: Array.reduce


۱۰- لیستی از آیتم ها رو داریم که هر آیتم یک قیمت داره. ابتدا میخواهیم همه قیمت ها رو به اضافه 10 کنیم و سپس اون هایی رو که قیمتشون بیشتر از 20 شد رو, به ترتیب چاپ کنیم و در آخر مجموع قیمت ها رو چاپ کنیم. به ترتیب از کدوم متدهای Array در جاوااسکریپت استفاده میکنی؟

پاسخ: به ترتیب از متدهای map, filter, sort, reduce استفاده میکنیم.
مرحله ۱: استفاده از متد map برای اضافه کردن 10 به هر قیمت

const prices = [5, 12, 8, 20, 15];
const updatedPrices = prices.map(price => price + 10);

مرحله ۲: استفاده از متد filter برای انتخاب قیمت هایی که بیشتر از 20 هستند

const filteredPrices = updatedPrices.filter(price => price > 20);

مرحله ۳: استفاده از متد sort برای مرتب سازی قیمت ها به ترتیب صعودی

const sortedPrices = filteredPrices.sort((a, b) => a - b);

مرحله ۴: استفاده از متد reduce برای محاسبه مجموع قیمت ها

const total = sortedPrices.reduce((sum, price) => sum + price, 0);

۱۱- توضیح دهید primitive type ها و reference type ها چی هستن و فرقشون چیه؟ نحوه ذخیره شدن این تایپ ها رو هم توضیح دهید. و اینکه چه طوری از حافظه پاک میشن?

توی این لینک به صورت کامل درباره همه این موارد توضیح داده شده: primitive and reference data types


۱۲- تفاوت deep copy و shallow copy را توضیح دهید.

از این لینک میتونید در مورد این دو مفهوم بخونید: deep copy vs shallow copy


۱۳- مموری لیک(نشتی حافظه) رو تعریف کنید و یک مثال ازش بزنید.

توی لینک زیر مباحثی مثل تخصیص حافظه، garbage collector و مموری لیک و اشتباهاتی که میتونه منجر به مموری لیک بشه رو میتونید بخونید: memory leak


۱۴- پراکسی ها رو تعریف کنید و بگید کاربردشون چیه؟

پاسخ این سوال رو از این لینک میتونید بخونید: پراکسی ها


۱۵- به طور کلی عملیات async چه طور توسط جاوااسکریپت و مرورگر هندل میشه؟

پاسخ این سوال رو از این لینک میتونید بخونید: ایونتلوپ


۱۶- خروجی کد زیر چیست؟

const testFunc = async () => {
  await setTimeout(() => console.log('setTimeout'), 1000)
  console.log('console.log')
}
testFunc()

برای پاسخ دادن به این سوال، شما باید اول به خوبی با پرامیس ها و async/await آشنا باشید. از این لینک میتونید در مورد پرامیس ها و async/await بخونید: async/await and promise

اما خروجی این کد به این صورت هست که اول، console.log چاپ میشه و بعد از یک ثانیه، setTimeout چاپ میشه:

console.log
setTimeout

علت اون هم این هست که چون setTimeout پرامیسی رو برنمیگردونه و خروجی اون تنها یک timer ID هست، پس await روی اون تاثیری نداره. درواقع نکته این سوال این هست که شما باید بدونید که await انتظار یک promise رو داره که براش wait بکنه، در غیر اینصورت عبارت جلوش رو یک پرامیس resolve شده در نظر میگیره. اما توی مثال زیر await کاملا تاثیرگذار هست:

const myPromise = new Promise((resolve) => {
  setTimeout(() => resolve(1), 1000)
})
const testFunc = async () => {
  await myPromise.then(() => console.log('promise'))
  console.log('console.log')
}
testFunc()

output:
promise
console.log

۱۶- پروتوتایپ ها(prototype) در کلاس ها، چی هستند؟

پاسخ این سوال رو از این لینک میتونید بخونید: پروتوتایپ


۱۷- کلوژرها رو به همراه کاربردش، تعریف کنید.

پاسخ این سوال رو از این لینک میتونید بخونید: کلوژر


۱۸- کد زیر چه مفهومی رو در جاوااسکریپت بیان میکنه؟ و خروجیش چیه؟

function calculator() {
  let number = 0
  return {
      increment() {
        number++
      },
      get() {
        return number
      }
    }
}
  const c = calculator()
  c.increment()
  c.increment()
  c.increment()
  console.log('c.get()', c.get())

پاسخ: بیانگر مفهوم closure در جاوااسکریپت هست و خروجی اون ۳ هست.


۱۹- به این متغیرهای داخل closure چی میگن؟

پاسخ: به این متغیرها میگن state :)


۲۰- تعریف symbolها در جاوااسکریپت.

توی این لینک میتونید در مورد سیمبل ها و بقیه نوع های داده ای، بخونید: نوع های داده ای


۲۱- کاربرد متد create در Object

از این لینک میتونید در مورد متد create بخونید: create


۲۲- خروجی کد زیر چیست؟

var Employee = { company: 'xyz' } 
var emp1 = Object.create(Employee); 
delete emp1.company 
console.log(emp1.company);

خروجی این کد مقدار xyz هست. دلیلش هم این هست: با استفاده از متد create ما آبجکت Employee رو به عنوان پروتوتایپ آبجکت emp1 معرفی میکنیم. مرحله دوم، delete هست و از اونجایی که delete فقط پراپرتی های خود آبجکت رو delete میکنه (نه پراپرتی هایی که از پروتوتایپ به ارث برده)، پس پراپرتی company پاک نمیشه. و خروجی نهایی xyz هست.


۲۳- کاربرد متد freeze در Object

از این لینک میتونید در مورد متد freeze بخونید: freeze


۲۴- تفاوت متدهای bind, apply و call رو توضیح دهید.

از لینک های زیر میتونید در مورد هر کدوم از این متدها و تفاوتشون بخونید:
apply
call
call vs apply
bind


۲۵- تابع add رو به گونه ای بنویسید که اون رو به هر دو صورت زیر بشه call کرد:

console.log(add(5, 6))
console.log(add(5)(6))

پاسخ: توی این سوال، به صورت غیر مستقیم از تکنینک currying پرسیده شده. کد تابع add به صورت زیر هست:

function add(x, y) {
  if(y) return x+y
  else return (z) => return x+z
}

۲۶- تفاوت sessionStorage و localStorage رو توضیح بدهید.

توی این لینک علاوه بر دو استوریج بالا، cookies هم توضیح داده شده و به مقایسه این سه پرداخته: client-side storage
این لینک هم میتونه مفید باشه و به indexedDB هم پرداخته: mdn client-side storage


۲۷- در هنگام نوشتن یک فیچر سرچ, میخواهیم هر وقت کاربر کاراکتر جدید وارد کرد, ریکوئست قبلی کنسل بشه. چه طور این رو پیاده سازی میکنید؟

پاسخ کوتاه این سوال، استفاده از AbortController هست که یک web api هست که به شما اجازه میده تا درخواست های fetch رو کنسل کنید.
از لینک زیر میتونید در مورد AbortController بخونید و یک مثال ازش ببینید، همچنین در مورد تکنیک debouncing هم که مربوط به سوال بعدیه هم توضیح داده شده. AbortController


۲۸- در هنگام نوشتن یک فیچر سرچ, میخواهیم بعد از چند میلی ثانیه که یوزر مقدار رو وارد کرد ریکوئست بزنیم به api. به این تکنیک چی میگن؟

پاسخ: به این تکنینک debouncing میگن. از این لینک در مورد debouncing میتونید بخونید: debounce


۲۹- مفاهیم اصلی در functional programming چیست؟
پاسخ این سوال رو میتونید از این لینک بخونید. هر چند مفاهیم دیگه ای مثل currying ,recursion, functors و monads هستند که تو این لینک بهشون اشاره نشده.
لینک زیر هم به طور کلی یه رفرنس خوب برای یادگیری مفاهیم سمت وب هست. برای currying, monads, recursion هم رفرنس داره توی خودش: web skills (توصیه میکنم حتما سر بزنید بهش)

یک سوال متناوب هم میتونه توضیح مفاهیم اصلی در OOP(Object-Oriented Programming) باشه (البته از من چنین سوالی پرسیده نشد)، که به صورت خلاصه: Encapsulation, Abstraction, Inheritance و Polymorphism از مفاهیم اصلی OOP هستند.


۳۰- متد get در کلاس ها رو توضیح بدهید(getter ها چی هستند؟ و چه فایده ای دارند؟)

پاسخ این سوال رو از این لینک میتونید بخونید: js getters and setters


منابع:

https://ditty.ir
https://www.geeksforgeeks.org
https://developer.mozilla.org
https://medium.com/@rabailzaheer/primitive-vs-reference-types-a-javascript-guide-6b3638ed508a
https://virgool.io/@ava.bakuei/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-shallow-copy-%D9%88-deep-copy-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-yatxr3etfuhd
https://virgool.io/@hesanam/%D8%AD%D8%A7%D9%81%D8%B8%D9%87-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%AC%D9%84%D9%88%DB%8C-memory-leak-%D8%B1%D9%88-%D8%A8%DA%AF%DB%8C%D8%B1%DB%8C%D9%85-vktctmei312j
https://virgool.io/JavaScript8/async-programming-under-the-hood-event-loop-part-1-hfr5zzmikjgy
https://www.telerik.com/blogs/three-browser-storage-mechanisms
https://dev.to/jamesrweb/principles-of-functional-programming-4b7c
https://andreasbm.github.io/web-skills