Merion Academy
9K subscribers
477 photos
84 videos
6 files
669 links
Самое важное про IT на доступном языке.
Сотрудничество: @olegpohl
Служба поддержки: https://t.me/merion_academy_bot
Download Telegram
Мы тут с последним напоминанием

До конца закрытой акции Merion Academy осталось всего 5 часов.

Если присматривал курс себе или хотел отправить ссылку другу, сейчас последний момент. Сегодня скидки доходят до 70%, а после полуночи акция закончится.

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

Успеть выбрать курс со скидкой
👀5
Задачка с собеса: почему список в React «путает» состояние строк? 🐸

Есть список задач. У каждой строки – поле ввода. Ты сортируешь список, и текст из первой строки внезапно оказывается у другой задачи. Данные в API правильные. Где ошибка?

Частая причина – key={index}. После сортировки индекс остался на позиции, а задача на этой позиции уже другая. React переиспользовал компонент и его локальное состояние.

Исправление: key={task.id} – стабильный идентификатор самой задачи. Он должен быть уникален среди соседних элементов и не меняться при сортировке.

На собеседовании за этим обычно спрашивают дальше: где хранить состояние, когда нужен useEffect, как обрабатывать формы и запросы к API. Эти темы разбираются на курсе «Frontend-разработка на React»: компоненты, JSX, состояние, события и работа с API.

➡️ Программа курса и бесплатная часть по ссылке
🔥5
Пятничная загадка: кто размножил запросы?

После небольшой правки React-страница стала открываться 8 секунд. Backend отвечает за 50 мс, база — за 20 мс, ошибок нет. В DevTools - около 150 одинаковых запросов к /api/items.

Факты расследования:
• проблема воспроизводится и в production-сборке;
• запрос запускается внутри useEffect;
• массив зависимостей эффекта заполнен;
• после каждого ответа компонент обновляет состояние;
• если убрать обновление состояния, шквал запросов прекращается.

Почему запрос запускается снова и снова?

👀 - виноват StrictMode: он дублирует запросы и в production
🔥 - в зависимостях эффекта есть объект или функция, которые создаются заново при каждом рендере
🤔 - браузер автоматически повторяет запрос, пока не получит ответ из кэша

Разгадка - в понедельник.
🔥35😱1🤓1👀1
React отправляет запрос дважды? Сначала проверь причину 🐸

В разработке StrictMode может дополнительно запускать setup и cleanup эффекта. Это помогает заметить эффекты, которые нельзя безопасно повторить. В production такое дополнительное выполнение из-за StrictMode не происходит.

Но если запрос повторяется при каждом рендере, посмотри на зависимости:

const filters = { status: 'open' };
useEffect(() => { load(filters); }, [filters]);

Объект filters создаётся заново при каждом рендере. Для React это новая зависимость. Вынеси постоянное значение за пределы компонента или используй примитивные зависимости:

useEffect(() => { load(status); }, [status]);

И ещё: эффекту с запросом полезна отмена через AbortController, чтобы старый ответ не перезаписал свежий.

Сохрани пост на случай, когда в Network вдруг появятся одинаковые запросы.
👀4😱1
Разгадка пятничного кейса 🐸

Одна из вероятных причин – в зависимости useEffect попал объект или функция, которые создаются заново на каждом рендере. Эффект делает запрос → ответ меняет state → новый рендер создаёт новую зависимость → эффект снова делает запрос.

Проверка: сравнить значения зависимостей между рендерами и временно заменить составную зависимость на стабильный примитив, например status или page. Если цикл исчез, источник найден. В реальном проекте возможны и другие причины; одних 150 запросов для точного диагноза мало.

А теперь короткая ловушка Python:
def add(x, items=[]):
items.append(x)
return items

Что вернут подряд add(1) и add(2)? Список по умолчанию создаётся один раз при определении функции: ответы будут [1] и [1, 2].

Безопасный шаблон:
def add(x, items=None):
if items is None: items = []
items.append(x)
return items

И в React, и в Python - всё решает момент создания значения.
1❤‍🔥7🤝1
Если запрос из Node.js зависает слишком долго, то ставим дедлайн

Если проект использует встроенный fetch, укажи таймаут через AbortSignal.timeout:

const res = await fetch(url, {
signal: AbortSignal.timeout(5000)
});

Через 5 секунд сигнал отменит запрос. Ошибку всё равно нужно обработать: таймаут — ожидаемый сценарий при работе с сетью, а не повод ронять весь обработчик.

try {
const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
if (!res.ok) throw new Error('HTTP ' + res.status);
} catch (err) {
console.error('Запрос не выполнен:', err);
}

Важно: таймаут ограничивает ожидание на стороне клиента; он не обещает, что сервер прекратит уже начатую работу.

Есть ли таймауты у внешних API, от которых зависит ваш сервис?
👀9
Найти пользователей с шестью и более заказами — куда поставить условие? 🐸

SELECT user_id, COUNT(*) AS orders_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) >= 6;

WHERE фильтрует строки до группировки. HAVING фильтрует группы после неё. Поэтому условие на COUNT(*) находится в HAVING.

Если нужны только оплаченные заказы, добавь условие раньше:

SELECT user_id, COUNT(*) AS paid_orders
FROM orders
WHERE status = 'paid'
GROUP BY user_id
HAVING COUNT(*) >= 6;

Строчка WHERE status = 'paid' убирает неоплаченные заказы до подсчёта. А HAVING оставляет пользователей, у которых оплаченных заказов шесть или больше.

Лайфхак для проверки: сначала запусти тот же запрос без HAVING и посмотри на суммы по нескольким знакомым user_id.
🤝10🙏1
👀26🤣4😱3
Пятничная загадка: SQL-отчёт умножил выручку

В таблице orders у заказа №42 сумма 1000 ₽. У него две строки в order_items и два события в payments. Аналитик собирает отчёт:

SELECT o.id, SUM(o.total) AS revenue
FROM orders o
JOIN order_items i ON i.order_id = o.id
JOIN payments p ON p.order_id = o.id
GROUP BY o.id;

Для заказа №42 отчёт показывает 4000 ₽. В таблице orders одна строка, сумма там правильная. Ни одна таблица не содержит дублей по своему первичному ключу.

Почему получилось именно 4000 ₽?

👀 - SUM складывает значение total дважды: один раз до JOIN и ещё раз после
🔥- два JOIN создали четыре строки: 2 товара × 2 платежа
🤔- база округлила сумму из-за разных типов данных в таблицах

Ставь реакцию. Разбор и правильный запрос — в следующий понедельник.
🔥50👀4
Разгадка: почему SQL-отчёт показал 4000 ₽ вместо 1000 ₽

Правильный ответ: 🔥 два JOIN создали четыре строки для одного заказа.

У заказа №42 было:
- 2 строки в order_items
- 2 строки в payments

После соединения таблиц база получила 2 × 2 = 4 строки. В каждой из них осталось o.total = 1000, поэтому SUM(o.total) сложил одну и ту же сумму четыре раза.

orders не содержит дублей. Дубли появились в результате соединения таблиц.

SUM(DISTINCT o.total) здесь не является надёжным исправлением. Если два разных заказа стоят одинаково, один из них потеряется в подсчёте.

Если нужна выручка по заказам, не присоединяй таблицы «один ко многим» до подсчёта суммы:

SELECT o.id, o.total AS revenue
FROM orders o;

А если нужны товары и платежи, сначала собери их отдельно по order_id, а потом присоедини к заказу.
🔥6😱1
Три команды, когда сервер внезапно начал тормозить 🐸

Не открывай сразу десять вкладок. Начни с трёх быстрых проверок.

uptime - Показывает нагрузку и помогает понять, сервер тормозит давно или проблема появилась только что.

free -h - Проверяет оперативную память и swap. Если свободной памяти почти нет, процессы могут начать ждать диск.

df -h - Показывает заполненность файловых систем. Когда заканчивается место, начинают странно вести себя логи, базы и сервисы.

После этого уже смотри конкретный процесс и логи, иначе легко чинить не причину, а первый симптом.

Какую команду запускаешь первой?
👀8🔥4😱1🤝1