Когда ты делаешь запрос на список сущностей, а для каждой из них внутри цикла идёт ещё один запрос — поздравляю, ты поймал N+1 проблему
Например:
const users = await db.query('SELECT * FROM users');
for (const user of users) {
user.posts = await db.query('SELECT * FROM posts WHERE user_id = $1', [user.id]);
}
Результат — один запрос на юзеров и N запросов на посты. На 100 юзеров это уже 101 запрос.
Больно для БД
⚙️ Решения:
1) JOIN — часто помогает, если нужно просто склеить данные
2) IN-запрос — SELECT * FROM posts WHERE user_id IN (...)
3) DataLoader — если у тебя GraphQL или сложные вложенные запросы
🧠 Как работает DataLoader
DataLoader — это умный батчер и кэшер от Facebook
Он не делает магии, а просто:
1) Копит ключи (например, userId), по которым нужно загрузить данные
2) Выполняет один общий запрос, вроде:
SELECT * FROM posts WHERE user_id IN (1,2,3,...)
3) Раскладывает результат обратно по пользователям
Почитать подробнее можно тут
Please open Telegram to view this post
VIEW IN TELEGRAM
conf-talks
DataLoader — правильно решаем проблему N+1 запросов
GraphQL на русском — здесь много статей и видео об этой замечательной технологии.
❤1
#Собес #сравнение #типы_данных #операторы
🤔 Как происходит сравнение типов?
💬 Кратко:
В JavaScript сравнение типов зависит от оператора. Оператор
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Как происходит сравнение типов?
💬 Кратко:
В JavaScript сравнение типов зависит от оператора. Оператор
=== (строгое равенство) требует, чтобы типы сравниваемых значений были одинаковыми. Оператор == (нестрогое равенство) автоматически приводит типы к общему значению перед сравнением. Поэтому при нестрогом сравнении, например, число и строка могут быть равны.📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤1
#Собес #sql #optimization #index
🤔 Как оптимизировать SQL-запрос, выбирающий все посты пользователей с >500 подписчиков (с джойнами и проверкой NULL)?
💬 Кратко:
- Добавить индексы на
- Использовать
- Заменить подзапросы на
- Применить покрывающий индекс.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Как оптимизировать SQL-запрос, выбирающий все посты пользователей с >500 подписчиков (с джойнами и проверкой NULL)?
💬 Кратко:
- Добавить индексы на
subscribers_count и user_id.- Использовать
INNER JOIN вместо LEFT JOIN, если NULL не нужны.- Заменить подзапросы на
JOIN.- Применить покрывающий индекс.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤1
#tool #графы
📚 Терялся в собственном коде?
Встречай Gitvizz, инструмент, который мгновенно превращает кодовую базу в интерактивные графы, чтобы наглядно увидеть, как всё связано
Перейти к материалу
👉 База вопросов 👉 Новости
📚 Терялся в собственном коде?
Встречай Gitvizz, инструмент, который мгновенно превращает кодовую базу в интерактивные графы, чтобы наглядно увидеть, как всё связано
Перейти к материалу
👉 База вопросов 👉 Новости
#article #event_loop #promise
📚 Полное понимание асинхронности в браузере
Гайд по асинхронности в JavaScript. Статья на Хабр от Яндекса
Перейти к материалу
👉 База вопросов 👉 Новости
📚 Полное понимание асинхронности в браузере
Гайд по асинхронности в JavaScript. Статья на Хабр от Яндекса
Перейти к материалу
👉 База вопросов 👉 Новости
❤1
#Собес #event_loop #asynchronous #nodejs
🤔 Что такое process.nextTick()
💬 Кратко:
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Что такое process.nextTick()
💬 Кратко:
process.nextTick() — это метод, который ставит колбэк в специальную очередь. Эта очередь обрабатывается сразу после завершения текущей операции, но до перехода к следующей фазе Event Loop. Это позволяет отложить выполнение кода, но гарантировать, что он выполнится как можно скорее, даже раньше установленных таймеров.📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤2
Когда несколько транзакций работают одновременно, они могут мешать друг другу и создавать странные эффекты — аномалии.
Чтобы держать порядок, базы данных вводят уровни изоляции — насколько сильно транзакции изолированы друг от друга.
⸻
⚠️ Типичные аномалии
— Dirty Read (грязное чтение) — читаешь данные, которые ещё не закоммичены.
Если транзакция откатится — ты прочитал “призрак”.
— Non-repeatable Read (неповторяемое чтение) — читаешь одну и ту же строку дважды, а результат разный, потому что другая транзакция изменила её между запросами.
— Phantom Read (фантомное чтение) — при повторном запросе появляются новые строки, подходящие под условие, которых раньше не было.
⸻
🔒 Уровни изоляции
1) READ UNCOMMITTED — можно читать даже незакоммиченные данные. Самый быстрый и самый опасный.
2) READ COMMITTED — читаешь только закоммиченные данные.
Нет грязных чтений, но возможны неповторяемые и фантомные.
(По умолчанию в PostgreSQL)
3) REPEATABLE READ — при повторном чтении данные не меняются.
Нет грязных и неповторяемых чтений, но фантомы возможны.
4) SERIALIZABLE — максимальная изоляция, всё выглядит как последовательное выполнение. Полностью без аномалий, но возможны откаты при конфликтах
💡 Чем выше уровень изоляции — тем меньше аномалий, но ниже производительность
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🔥2🐳1
#Собес #замыкание #функции
🤔 Что такое замыкания в JavaScript и почему они важны?
💬 Кратко:
Замыкание — это функция, которая "запоминает" свою область видимости даже после того, как внешняя функция, в которой она была объявлена, завершила выполнение. Замыкания позволяют создавать функции с доступом к переменным из внешней функции, что полезно для работы с приватными данными и сохранения состояния между вызовами функции.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Что такое замыкания в JavaScript и почему они важны?
💬 Кратко:
Замыкание — это функция, которая "запоминает" свою область видимости даже после того, как внешняя функция, в которой она была объявлена, завершила выполнение. Замыкания позволяют создавать функции с доступом к переменным из внешней функции, что полезно для работы с приватными данными и сохранения состояния между вызовами функции.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤1
#tool #визуализатор
📚 Визуализатор выполнения JS-кода
Пишешь код в редакторе, двигаешь слайдер и смотришь, как движок выполняет каждую инструкцию
Перейти к материалу
👉 База вопросов 👉 Новости
📚 Визуализатор выполнения JS-кода
Пишешь код в редакторе, двигаешь слайдер и смотришь, как движок выполняет каждую инструкцию
Перейти к материалу
👉 База вопросов 👉 Новости
🔥3
#Собес #наследование #__proto__ #прототипы
🤔 Как создать наследование в JavaScript с использованием прототипов?
💬 Кратко:
Наследование в JavaScript можно реализовать через прототипы, связывая объекты друг с другом. Это можно сделать вручную с помощью свойства
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Как создать наследование в JavaScript с использованием прототипов?
💬 Кратко:
Наследование в JavaScript можно реализовать через прототипы, связывая объекты друг с другом. Это можно сделать вручную с помощью свойства
__proto__ или с использованием метода Object.create(). Это позволяет новому объекту получать доступ к свойствам и методам другого объекта через цепочку прототипов.📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤1
#Собес #замыкание #функции
🤔 Что такое замыкания в JavaScript и почему они важны?
💬 Кратко:
Замыкание — это функция, которая "запоминает" свою область видимости даже после того, как внешняя функция, в которой она была объявлена, завершила выполнение. Замыкания позволяют создавать функции с доступом к переменным из внешней функции, что полезно для работы с приватными данными и сохранения состояния между вызовами функции.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Что такое замыкания в JavaScript и почему они важны?
💬 Кратко:
Замыкание — это функция, которая "запоминает" свою область видимости даже после того, как внешняя функция, в которой она была объявлена, завершила выполнение. Замыкания позволяют создавать функции с доступом к переменным из внешней функции, что полезно для работы с приватными данными и сохранения состояния между вызовами функции.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
ORM — звучит красиво: пишешь классы, аннотации, а база сама как-то живёт. Но на практике — это как ездить закрытыми глазами на машине на автопилоте
Query Builder — это тонкая обёртка над SQL.
Ты чётко контролируешь какой запрос пойдёт в базу, какие JOIN’ы выполняются и какие поля читаются.
Он не “угадывает”, что ты хотел сделать — он просто выполняет твой запрос
С Query Builder:
await db('users')
.select('id', 'email')
.where('is_active', true);
SQL под капотом — предсказуемый:
SELECT id, email FROM users WHERE is_active = true;
А ORM может внезапно решить “загрузить” связи, добавить лишние поля или сделать 3 подзапроса вместо одного.
Ты думаешь, что сделал findOne, а реально — отправил 5 SQL-запросов
База данных — сердце системы.
Если ты не понимаешь, какой SQL реально выполняется, ты не контролируешь производительность и целостность данных
ORM часто скрывает логику за “удобным” API, но любая сложная операция превращается в дебри.
Query Builder же заставляет мыслить на уровне SQL, а не на уровне магии “entities” и “relations”
TypeORM, Sequelize, Prisma — все они в какой-то момент начинают диктовать свои правила.
Тебе нужно не просто “сделать запрос”, а ещё угадать, как ORM это интерпретирует
• Миграции — можно и нужно писать руками. Так надёжнее
• Сущности (Entity) в TypeORM — часто мешают, особенно когда структура БД не совпадает 1:1 с моделями кода
• При изменениях в схеме ORM может внезапно удалить или пересоздать таблицу, если ты где-то забыл флаг
ORM удобно, пока проект маленький и нужно собрать быструю гипотезу на коленке
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥2
#Собес #message_broker #js #nodejs
🤔 Middle/Middle+ Node.js Backend разработчик в компанию rolftech
Техсобес. ЗП: от 250к. Июнь 2025. Опыт: 4 года. Непростой собес, спрашивали по опыт и глубоко копали в техничку. Был лайвкодинг.
💬 Вопросы:
- JWT что такое? Из каких частей состоит токен?
- Что такое CORS
- Как принято работать с файлами с Node.js
- Pick, Omit, Partial в TS
- Что такое опциональная цепочка в JS?
👉 Все вопросы из этого собеседования (26)
📣 Хочешь больше собесов?
Подпишись на наш главный канал
🤔 Middle/Middle+ Node.js Backend разработчик в компанию rolftech
Техсобес. ЗП: от 250к. Июнь 2025. Опыт: 4 года. Непростой собес, спрашивали по опыт и глубоко копали в техничку. Был лайвкодинг.
💬 Вопросы:
- JWT что такое? Из каких частей состоит токен?
- Что такое CORS
- Как принято работать с файлами с Node.js
- Pick, Omit, Partial в TS
- Что такое опциональная цепочка в JS?
👉 Все вопросы из этого собеседования (26)
📣 Хочешь больше собесов?
Подпишись на наш главный канал
❤1
#Собес #cd #delivery #deployment
🤔 Что такое Continuous Delivery?
💬 Кратко:
Continuous Delivery (CD) — это процесс, при котором код после успешной проверки автоматически подготавливается для выпуска в продакшн. Он остаётся в стабильном состоянии и может быть развернут в любой момент.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Что такое Continuous Delivery?
💬 Кратко:
Continuous Delivery (CD) — это процесс, при котором код после успешной проверки автоматически подготавливается для выпуска в продакшн. Он остаётся в стабильном состоянии и может быть развернут в любой момент.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤1
#repository #кибербезопасность
📚 Структурированный 90-дневный план обучения кибербезопасности предназначенный для начинающих специалистов
План обучения, разделённый на ежедневные задания, охватывающие ключевые темы
Перейти к материалу
👉 База вопросов 👉 Новости
📚 Структурированный 90-дневный план обучения кибербезопасности предназначенный для начинающих специалистов
План обучения, разделённый на ежедневные задания, охватывающие ключевые темы
Перейти к материалу
👉 База вопросов 👉 Новости
#Собес #node.js #async
🤔 Можете ли вы объяснить асинхронный подход в Node.js?
💬 Кратко:
Асинхронный подход в Node.js позволяет выполнять задачи без блокировки основного потока. Вместо ожидания выполнения задачи, Node.js продолжает работать и обрабатывает другие задачи.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Можете ли вы объяснить асинхронный подход в Node.js?
💬 Кратко:
Асинхронный подход в Node.js позволяет выполнять задачи без блокировки основного потока. Вместо ожидания выполнения задачи, Node.js продолжает работать и обрабатывает другие задачи.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤1
Что это вообще такое
1) useValue — подставляет готовый объект/примитив по токену. Удобно для конфигов и моков
2) useFactory — создаёт значение через фабрику (функцию). Может быть async, можно внедрять зависимости, менять логику по окружению
Оба — это способы объявить провайдеры без привязки к конкретному классу
useValue — конфиг и моки
export const CONFIG = Symbol('CONFIG');
@Module({
providers: [
{ provide: CONFIG, useValue: { apiBase: 'https://api.dev', timeout: 3000 } },
],
exports: [CONFIG],
})
export class ConfigModule {}
Тест с моками:
useFactory — фабрика с зависимостями и режимами
export const PAYMENT_GATEWAY = Symbol('PAYMENT_GATEWAY');
@Module({
providers: [
{
provide: PAYMENT_GATEWAY,
useFactory: (cfg: ConfigService) => {
const isProd = cfg.get('NODE_ENV') === 'production';
return isProd
? new StripeGateway(cfg.get('STRIPE_KEY'))
: new FakeGateway(); // быстрая локальная разработка
},
inject: [ConfigService],
},
],
exports: [PAYMENT_GATEWAY],
})
export class PaymentModule {}
Принцип инверсии зависимостей: высокоуровневые модули не зависят от низкоуровневых; оба зависят от абстракций
— В Nest абстракция = инъекционный токен (строка/символ), а не интерфейс TypeScript (он стирается в runtime)
— useValue/useFactory позволяют под этот токен подложить любую реализацию без изменения кода потребителей
useValue/useFactory — это практические инструменты для реализации D из SOLID в Nest.js: вы зависите от абстракций (токенов) и свободно подменяете реализации. Так код становится тестируемее, модули — слабосвязанными, а конфигурация — гибкой. Используйте useValue для констант и моков, useFactory — для динамики и асинхронной инициализации
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#Собес #typenoscript #compilation
🤔 В чем плюсы и минусы TS.
💬 Кратко:
TypeScript добавляет статическую типизацию, что улучшает качество кода и уменьшает ошибки. Однако он требует компиляции и имеет более сложную настройку. Подходит для больших проектов и командной разработки.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 В чем плюсы и минусы TS.
💬 Кратко:
TypeScript добавляет статическую типизацию, что улучшает качество кода и уменьшает ошибки. Однако он требует компиляции и имеет более сложную настройку. Подходит для больших проектов и командной разработки.
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
❤1
#Собес #explain_analyze #indexing #query_rewrite
🤔 Что делать, если SQL-запрос выполняется слишком долго?
💬 Кратко:
Для начала проанализировать план через
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Что делать, если SQL-запрос выполняется слишком долго?
💬 Кратко:
Для начала проанализировать план через
EXPLAIN ANALYZE: найти узкие места (Seq Scan, Nested Loop). Затем добавить или изменить индексы, переписать запрос (убрать подзапросы, использовать JOIN, WITH), уменьшить выборку (LIMIT, фильтры), обновить статистику (VACUUM ANALYZE) и, по необходимости, денормализовать данные или шардировать таблицу.📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
#tool #визуализатор
📚 Визуализатор выполнения JS-кода
Пишешь код в редакторе, двигаешь слайдер и смотришь, как движок выполняет каждую инструкцию
Перейти к материалу
👉 База вопросов 👉 Новости
📚 Визуализатор выполнения JS-кода
Пишешь код в редакторе, двигаешь слайдер и смотришь, как движок выполняет каждую инструкцию
Перейти к материалу
👉 База вопросов 👉 Новости
#Собес #sigint #http #сервер
🤔 Как изящно остановить Node.js сервер?
💬 Кратко:
Изящно остановить сервер в Node.js можно с помощью
Также следует обработать события
📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал
🤔 Как изящно остановить Node.js сервер?
💬 Кратко:
Изящно остановить сервер в Node.js можно с помощью
server.close(), который завершает все активные соединения. Также следует обработать события
SIGINT и SIGTERM для завершения процессов📌 Полный разбор + примеры использования — на платформе:
👉 Перейти к разбору
📣 Хочешь получать больше таких разборов?
Подпишись на наш главный канал