Devs Hive

Менторство, підготовка до співбесід та карʼєрний розвиток

Доступ до бази запитань на інтервʼю, з детальним технічним поясненням. Окрім технічного пояснення, детальний розбір того, як краще відповідати на запитання.

Детальний розбір запитань на інтервʼю

Основна відмінніть від інших подібних сервісів - тут не суха інформація(яку ви можете і в ChatGPT запитати). Я розписав інформацію про те, як правильно відповідати на запитання, щоб пройти інтервʼю. Окрім цього, в більшості запитань розписано теми які ви можете зачепити, щоб перенаправити інтервʼю в потрібне вам русло.

TypeScript

Яка різниця між type i interface в TypeScript?

Це часте запитання на інтервʼю, особливо на Junior i Middle позиції. В цілому, те, що зазвичай хочуть почути на інтервʼю - це merge інтерфейсів.

Розберемо на прикладі:

interface IUser {
name: string;
email: string;
}

interface IUser {
age: number;
}

// TypeScript зробить merge цих двох інтерфейсів
// Це тепер один інтефейс тому IUser буде очікувати і поле age
const user: IUser = {
name: 'Test',
email: 'test@test.com',
age: 30,
}

Якщо ви спробуєте такий підхід з type, то отримаєте помилку. При відповіді на це питання буде бонусом додати випадки, коли краще використовувати type, коли interface:

  1. interface краще використовувати для опису структури обʼєктів і класів, як це і задумано в ООП.
  2. для всього іншого доцільніше використовувати type, особливо в контексті побудови складних типів: union, utility types, function signatures…
Бази даних

Як працює LEFT JOIN?

LEFT JOIN - це тип JOIN, який повертає всі рядки з лівої таблиці, навіть якщо у правій таблиці немає відповідних збігів. Якщо збіг у правій таблиці є - дані з неї додаються а якщо збігу немає - замість значень з правої таблиці буде NULL.

Розберемо приклад

Ми маємо дві таблиці users i orders. Наша задача полягає в тому щоб отримати всіх користувачів разом з замовленнями. Якщо в користувача немає замовлення, ми все одно маємо включити його в список тому ми будемо використовувати LEFT JOIN.

-- users
id | name
------------
1 | Alice
2 | Bob
3 | Charlie

-- orders
id | user_id | product
------------------------
1 | 1 | Laptop
2 | 1 | Mouse
3 | 2 | Keyboard

Запит буде мати наступний вигляд. Давайте розберемо його детальніше:

-- Вибираємо стовпці, які хочемо бачити в результаті:
-- name - з таблиці users
-- product - з таблиці orders
SELECT
users.name,
orders.product
FROM
users
-- Робимо LEFT JOIN — тобто беремо ВСІ рядки з таблиці users (ліва таблиця)
-- і додаємо дані з таблиці orders (права таблиця), якщо знайдеться збіг.
LEFT JOIN
orders
-- Визначаємо умову, за якою пов’язуються рядки з обох таблиць:
-- якщо значення users.id збігається з orders.user_id, то ці рядки об’єднуються.
ON
users.id = orders.user_id;

В результаті виконання запиту, ми отримаємо такий результат:

name | product
-------------------
Alice | Laptop
Alice | Mouse
Bob | Keyboard
Charlie | NULL -- Хоч і Charlie не має співпадінь в правій таблиці, LEFT JOIN все одно додає його до вибірки, але в значенні правої таблиці буде NULL
Алгоритми і стрктури даних

Як можна визначити складність алгоритму?

Найперше, розберемось з тим що таке складність алгоритму. Це спосіб оцінити, скільки ресурсів алгоритм споживає в залежності від розміру вхідних даних. Існує два способи, щоб виміряти складність алгоритму.

Time Complexity

Часова складність алгоритму - це спосіб зрозуміти, наскільки він повільнішає, коли даних стає більше. Для вимірювання використовується Big O нотація, яка показує верхню межу вимірювання.

| Нотація | Назва | Пояснення |
|--------------|----------------------|---------------------------------------------------|
| O(1) | Константна | Завжди займає однаковий час. |
| O(log n) | Логарифмічна | Зростає дуже повільно при збільшенні n. |
| O(n) | Лінійна | Час зростає прямо пропорційно кількості даних(n). |
| O(n log n) | Лінійно-логарифмічна | Трохи повільніше за лінійну, але ще ефективна. |
| O(n²) | Квадратична | Повільна, бо має два вкладені цикли. |
| O(2ⁿ) | Експоненційна | Дуже повільна при великому n. |

Розберемо детальніше

O(1) - Яскравим прикладом константної складності є операція присвоювання, або доступ до поля обʼєкта по ключу.

O(log n) - При цій складності, час виконання росте дуже повільно, навіть при значному збільшенні вхідних даних. Прикладів його застосування дуже багато і найпростіший це бінарний пошук.

O(n) - При цій складності, час виконання росте прямо пропорційно збільшенню кількості елементів. Наприклад, ми перебираємо масив з 100 елементів. При використанні алгоритму з логарифмічною складність, при збільшенню кількості елементів до 100 000, ми майже не відчуємо змін в часі виконання алгоритму, тоді як при використанні O(n) алгоритм значно сповільниться.

O(n log n) - Простими словами це поєднання лінійної і логарифмічної складності. Наприклад наш алгоритм використовує стратегію divide and conquer O(log n), щоб розділяти масив і використовує перебір O(n), щоб обробити усі елементи.

O(n²) - Це відбувається тоді, коли для кожного елемента алгоритм перевіряє всі інші елементи. Найчастіше, коли є два вкладені цикли.

O(2ⁿ) - Експоненційна складність є найповільнішою серед всіх. Якщо описати її простими словами, то вона подвоює кількість операції. Наприклад, на 10 елементів, потрібно буде зробити орієнтовно 1024 операції.

Простий приклад визначення складності алгоритму

В нас є функція, яка повертає мінімальне значення масиву. Фактично ми маємо 2 операції, це присвоєння в let min = arr[0] i перебір масиву arr . Операція присвоєння завжди займає константний час O(1), так як не залежить від кількості елементів, тоді як при переборі масиву ми залежимо від кількості елементів в цьому масиві тому складність буде O(n). Визначення складності алгоритму, відбувається по найскладнішій операції. В нас це перебір масиву тому складність функції findMin буде O(n).

function findMin(arr) {
let min = arr[0]; // O(1)
for (let i = 1; i < arr.length; i++) // O(n)
if (arr[i] < min) min = arr[i];
}
return min;
}

Space Complexity

Це кількість додаткової пам’яті, яку алгоритм потребує, окрім вхідних даних. Наприклад, створення додаткових змінних, масивів, обʼєктів і тд. Для визначення space complexity ми використовуємо ту саму Big O нотацію, але оперуємо не кількістю операцій, а кількістю задіяних структур.

Після того як ви відповіли на питання, буде дуже великим плюсом наголосити на важливість розуміння складності, так як це має пряме відношення до розуміння структур даних, а стркутури є фундаментом для розуміння сучасних розподілених систем, баз даних, кешування і багатьох інших важливих тем.

Системний дизайн

Що таке ідемпотентність?

Отже, почнемо з визначення того, що таке ідемпотентність. Це концепція, яка гарантує, що багаторазове повторення дає той самий ефект, як і одноразове.

Найчастіше це запитання звучить в контексті розмови про дизайн REST API, тому доцільно буде розібрати цю концепцію в контексті HTTP-методів.

Наприклад, розберемо метод PUT. Згідно з REST, він займається повним оновленням ресурсу. І якщо ми відправимо його 10 разів з однаковим body, то всі ці виклики дадуть такий самий результат, як і один виклик цього методу.

Те саме стосується GET, DELETE і PATCH. Щодо PATCH, то, згідно зі специфікацією, він може бути як ідемпотентним, так і ні.

Але якщо розібрати метод POST, то згідно концепції REST, кожен виклик буде створювати новий запис в базі даних і таким чином, повторний виклик НЕ дасть однаковий ефект - отже, метод не ідемпотентний.

Додатково, я би рекомендував почитати про ідемпотентність в розподілених системах і розповісти про це на інтервʼю. Також, хорошою практикою буде згадати про Idempotency Key i навести приклад його використання.

Перейти до бази запитань

Безкоштовний ревью-дзвінок

Перед початком менторства проводжу 30-хвилинний дзвінок для розуміння вашого кейсу та складання індивідуального плану розвитку

30-хвилинний дзвінок

Безкоштовна консультація для обговорення ваших цілей та потреб

Аналіз кейсу

Розуміння вашого поточного рівня та визначення пріоритетів розвитку

Індивідуальний план

Створення персоналізованого плану дій для досягнення ваших цілей

Послуги

Обирайте окремі напрямки або поєднуйте їх у цілісний план.

1:1 Менторинг

Персоналізований менторинг, для побудови сильного інженерного профайлу.

  • Постановка та досягнення цілей
  • Код ревʼю і фідбек
  • Наставництво в веденні пет проектів
  • Стратегія навчання, адаптована під твої потреби

Підотовка до інтервʼю

Підготовка до технічного і System Design інтервʼю, а також розбір вашого профайлу.

  • Мок інтервʼю з детальним фідбеком і плануванням наступних кроків
  • Практика системного дизайну
  • Аналіз CV з розгорнутим зворотнім звʼязком і подальшими кроками

Персональний план розвитку

Включає в себе розробку плану, регулярні зустрічі і постійний аналіз навчання.

  • Створення roadmap під ваші потреби
  • Карʼєрний коучинг i шлях до оферу
  • Підготовка до сертифікацій: AWS SAA/Cloud/AI, Terraform, KCNA

YouTube

Короткі, практичні відео про співбесіди, бекенд, фронтенд, хмари та карʼєрне зростання.

Звʼязатись зі мною

Заповніть форму або виберіть зручний для вас спосіб зв'язку.