Сир, сирок і race condition
Ви шукаєте "сирок", а бачите "сир". Ні, це не випадок в "Сільпо", а цілком собі питання на технічному інтервʼю.
Я практично повністю відмовився від запитань в дусі "Що таке Х?" на співбесідах, як комерційних, так і публічних. Натомість перейшов до так званих "ситуаційних" завдань, коли я просто описую якусь ситуацію, в рамках якої можна проговорити кілька різних аспектів — і технічних, і не тільки.
В рамках однієї з таких ситуацій я прийшов до питання, яке мені надзвичайно подобається, бо не ставить питання напряму, а дозволяє зрозуміти, як людина в принципі розбирається в проблемах.
Отже, питання:
У вас є табличка з пошуком, і якщо в пошуку спочатку набрати "сир", а потім швиденько дописати "-ок", то таблиця усе одно відображатиме список і сирів і сирків. Чому так може бути?
Відповіді, звичайно, я отримую доволі різноманітні, проте серед найчастіших є одна умовно невірна, і одна — вірна.
Умовно невірна — це щось там з кешуванням даних, те, як ми обробляємо запити, додаємо дані в стейт менеджменті і так далі. Чому вона для мене умовно невірна? Бо заскладна. Вона містить забагато припущень, про які зазвичай попередньо мова не йде, і може призвести до каскаду нових запитань, до яких ви можете бути не готові.
А умовно правильна — дуже проста і очевидна, бо в питанні йде мова про race condition при запитах. Це доволі поширена ситуація, особливо якщо запити відбуваються в умовах нестабільного або повільного зʼєднання.
Схема проста: запит на “сир” пішов першим, але довго обробляється. Тим часом користувач встиг дописати “-ок”, і запит на “сирок” пішов другим — але відповів швидше. У результаті інтерфейс спочатку показує правильний список, а потім перезаписується старішою, але пізнішою відповіддю. Особливо легко це проґавити, якщо показується лише один індикатор завантаження.
Рішення саме цієї задачі надзвичайно просте — необхідно скасовувати попередні запити при відправці нових. Зазвичай для цього використовується AbortController.
А для заохочення автора писати цікаві дописи зазвичай використовуються вподобайки
Іноді я чую у відповідь про Promise.race — так от, в цій ситуації він нам не підходить з багатьох причин. Наприклад, він зарезолвить перший-ліпший запит, а інші відкине. А ще він повинен знати про усі запити наперед, чого в нашій ситуації передбачити неможливо.
До речі, дехто з вас може згадати і про debounce, але конкретно в цій задачі він теж недоречний. В самій ситуації, яку я використовував на співбесідах, він, до речі, фігурує, але за дещо інших умов.
Тож моя порада: відповідаючи на подібні запитання, не ускладнюйте собі життя, не пропонуйте рішень, які передбачають додаткові неозвучені умови, а виходьте лише з того, що обговорено. Якщо відчуваєте, що вам бракує вхідних даних — ліпше запитайте, уточніть.
Запамʼятайте — прості рішення простіше обґрунтовувати, а ускладнити їх завжди можна встигнути. А от якщо ви відразу зайдете зі складного, то, швидше за все, просто закопаєтесь на місці.
Тож, якщо ваш колега знову "пакращить" відповідь на інтервʼю — покажіть йому цей кейс ;)
До речі, чи були у вас випадки на співбесідах, коли ви на просте питання давали занадто кучеряву й складну відповідь? Діліться смачненькими фейлами!
@babichdev