Backend Ready | IT
8.32K subscribers
1.25K photos
93 videos
6 files
1K links
По всем вопросам: @AdilNow
Download Telegram
📦 Модуль v8 — заглядываем «под капот» движка Node.js**

Node.js работает на движке V8 от Google. Встроенный модуль v8 дает прямой доступ к управлению памятью и настройкам самого движка. Это инструмент для тех, кто хочет выжать из сервера максимум и найти утечки памяти.

v8 — мониторинг и управление памятью

v8.getHeapStatistics()
v8.setFlagsFromString()
v8.serialize()
v8.deserialize()

getHeapStatistics() — возвращает детальный отчет о состоянии «кучи» (Heap). Можно узнать общий размер выделенной памяти и лимит, после которого приложение упадет с ошибкой JavaScript heap out of memory.

const v8 = require('v8');
console.log(v8.getHeapStatistics());




serialize() / deserialize() — позволяют превращать объекты JS в бинарный формат V8 и обратно. Это работает быстрее, чем JSON.stringify, и поддерживает типы данных, которые JSON не умеет (например, Map, Set или BigInt).

const buffer = v8.serialize({ map: new Map([['id', 1]]) });
const data = v8.deserialize(buffer);


setFlagsFromString() — позволяет менять настройки движка прямо во время работы кода. Например, можно принудительно включить или выключить оптимизацию определенных функций (использовать только в целях отладки!).

Heap Snapshots — через API этого модуля можно программно создавать снимки памяти, чтобы потом проанализировать их в Chrome DevTools и понять, какие объекты «едят» оперативку и не удаляются сборщиком мусора.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🧩 Модуль path — правильная работа с путями к файлам**

Склеивать пути вручную через / или \ — плохая практика, потому что в Windows и Linux разделители разные. Модуль path делает это автоматически, учитывая особенности операционной системы, на которой запущен твой код.

path — навигация по файловой системе

path.join()
path.resolve()
path.basename()
path.extname()
path.parse()

path.join() — объединяет все переданные сегменты пути в одну строку, используя разделитель текущей ОС. Он также чистит путь от лишних точек и двойных слешей.

const path = require('path');
const fullPath = path.join('users', 'admin', 'config.json');
// Windows: users\admin\config.json
// Linux: users/admin/config.json




path.resolve() — превращает последовательность путей в абсолютный путь. Он всегда стартует от корня проекта, что гарантирует точность при поиске файлов.

console.log(path.resolve('images', 'logo.png'));
// Результат: /Users/dev/project/images/logo.png


path.basename() — возвращает только имя файла из длинного пути. Если вторым аргументом передать расширение, оно будет отрезано.
path.extname() — достает только расширение файла. Удобно для фильтрации загрузок (например, разрешать только .jpg).

const file = 'static/uploads/photo.jpg';
console.log(path.basename(file)); // photo.jpg
console.log(path.extname(file)); // .jpg


path.parse() — разбирает путь на части и возвращает объект с корнем, папкой, полным именем, расширением и именем без расширения.

console.log(path.parse('/home/user/dir/file.txt'));
/* { root: '/', dir: '/home/user/dir', base: 'file.txt',
ext: '.txt', name: 'file' } */

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🔐 Модуль crypto — безопасность и шифрование данных

Безопасность — это не только HTTPS. Модуль crypto предоставляет набор инструментов для создания хэшей, генерации случайных паролей и шифрования сообщений. Это база для аутентификации и защиты конфиденциальной информации.

crypto — шифрование и хэширование

crypto.createHash()
crypto.randomBytes()
crypto.createCipheriv()
crypto.scrypt()

crypto.createHash() — создает необратимый отпечаток данных (хэш). Обычно используется для проверки целостности файлов или сравнения паролей (через алгоритм SHA-256).

const crypto = require('crypto');

const hash = crypto.createHash('sha256')
.update('секретный_пароль')
.digest('hex');
console.log(hash);
// Результат: 5e884898da28047151d0e56...




crypto.randomBytes() — генерирует криптографически сильные случайные данные. Это гораздо безопаснее, чем Math.random(). Идеально для создания токенов восстановления пароля или «соли».

crypto.randomBytes(16, (err, buf) => {
console.log(buf.toString('hex'));
});


crypto.scrypt() — современный алгоритм для безопасного хэширования паролей. Он специально сделан медленным и ресурсозатратным, чтобы защитить от подбора паролей методом перебора (Brute-force).

Cipher и Decipher — инструменты для симметричного шифрования. Ты можешь зашифровать текст ключом, передать его по сети, а на другом конце расшифровать тем же ключом.

const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('Важные данные', 'utf8', 'hex');
encrypted += cipher.final('hex');


Hmac — (Hash-based Message Authentication Code). Позволяет убедиться, что данные не были изменены в процессе передачи, используя секретный ключ.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
⏱️ Модуль timers — управление временем и очередью событий

В Node.js работа с задержками — это не просто пауза в коде. Модуль timers управляет тем, как и когда функции попадают в Event Loop. Помимо привычных браузерных методов, здесь есть специфические инструменты для оптимизации нагрузки.

timers — планирование выполнения кода

setTimeout() / clearTimeout()
setInterval() / clearInterval()
setImmediate()
process.nextTick()

setTimeout() — запускает код через указанное количество миллисекунд. В Node.js этот метод возвращает объект, который можно использовать для отмены или управления поведением процесса.

const timer = setTimeout(() => {
console.log('Прошло 2 секунды');
}, 2000);

// Если нужно отменить:
clearTimeout(timer);




setImmediate() — «микрозадача» Node.js. Она выполняет код сразу после того, как завершится текущая фаза опроса событий (Poll фаза). Это эффективнее, чем setTimeout(fn, 0).

setImmediate(() => {
console.log('Выполнится в фазе Check');
});


process.nextTick() — самый «быстрый» таймер. Он заставляет функцию выполниться сразу после текущей операции, еще до того, как Event Loop перейдет к следующей фазе. Чрезмерное использование может «заблокировать» ввод-вывод.

unref() и ref() — уникальные методы Node.js. Если вызвать timer.unref(), активный таймер не будет удерживать процесс от завершения, если в коде больше ничего не происходит.

const interval = setInterval(() => {}, 1000);
interval.unref(); // Сервер выключится, если нет других задач


Promisified Timers — в новых версиях Node.js можно использовать таймеры с await без лишних оберток.

const { setTimeout } = require('timers/promises');
await setTimeout(1000);
console.log('Ждали одну секунду');

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Исходный Код
Смоделировали задачу с двумя ++ для разработчиков!

🔥 Ситуация:
Запускаем модуль выплат для e-commerce. Использовали стандартную схему с Webhooks от платежного шлюза. Локально все летает, автотесты подтверждают идемпотентность.


📊 После релиза видим аномалию:
У 0.1% юзеров транзакции дублируются. Причем в логах шлюза - два успешных вызова с разницей в 50 мс, а в нашей базе - две записи с разными ID, но одинаковым внешним Correlation ID.


🎮 Задача:
Вам нужно определить ту самую причину в логике бэкенда или БД, которая позволила создать дубль, несмотря на проверку.

🔍
Варианты ответов в карточках!


💬 Если дается сложно: две подсказки оставили в комментариях!

📱 Исходный код — подписаться!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Исходный Код
Я считаю, что правильный ответ:
Anonymous Quiz
19%
A
13%
B
46%
C
16%
D
6%
E
🛡️ Модуль events — архитектура на основе событий

Node.js построен вокруг событий. Почти всё — от HTTP-серверов до потоков чтения файлов — работает на базе класса EventEmitter. Этот модуль позволяет создавать свои события и строить слабо связанную архитектуру приложения.

events — создание и обработка событий

emit()
on() / once()
removeListener()
eventNames()

emit() — генерирует событие, передавая данные всем подписанным слушателям. Это похоже на крик в рупор: кто слушает, тот среагирует.

const EventEmitter = require('events');
const myEmitter = new EventEmitter();

myEmitter.emit('order_created', { id: 105 });




on() — регистрирует постоянного слушателя. Каждый раз, когда событие случается, вызывается колбэк.
once() — срабатывает только один раз. После первого выполнения слушатель автоматически удаляется. Удобно для одноразовых действий, например, инициализации БД.

myEmitter.on('update', (data) => console.log('Обновлено:', data));
myEmitter.once('start', () => console.log('Запуск системы...'));


removeListener() — отписывает конкретную функцию от события. Это критически важно для предотвращения утечек памяти, если ты динамически создаешь слушателей.
error — это специальное событие. Если ты сделаешь emit('error') и на него никто не подписан, Node.js завершит процесс с ошибкой. Всегда вешай обработчик ошибок!

myEmitter.on('error', (err) => {
console.error('Что-то пошло не так:', err.message);
});


MaxListeners — по умолчанию на одно событие можно повесить не более 10 слушателей. Если нужно больше, используй setMaxListeners(). Это сделано для того, чтобы ты случайно не создал бесконечный цикл подписок.
🌊 Модуль stream — работа с огромными данными без перегрузки RAM

Если тебе нужно прочитать файл размером 10 ГБ на сервере с 2 ГБ оперативки, обычный fs.readFile уронит приложение. Стримы решают эту проблему, передавая данные небольшими кусочками (чанками), как конвейер.

stream — потоковая обработка данных

Readable
Writable
Duplex / Transform
pipeline()

Readable — поток, из которого можно читать. Данные поступают по мере готовности, не забивая память целиком.

const fs = require('fs');
const readable = fs.createReadStream('big_video.mp4');

readable.on('data', (chunk) => {
console.log(`Получено ${chunk.length} байт`);
});




Writable — поток, в который можно записывать. Например, отправка ответа пользователю или запись логов в файл.

const writable = fs.createWriteStream('copy.mp4');
readable.pipe(writable); // Автоматическая перекачка данных


Transform — особый вид потока, который изменяет данные «на лету». Например, можно сжимать текст в Gzip прямо в процессе чтения.

const zlib = require('zlib');
readable.pipe(zlib.createGzip()).pipe(writable);


pipeline() — современный способ объединения потоков. В отличие от .pipe(), он корректно обрабатывает ошибки во всех звеньях цепи и очищает ресурсы, если что-то пошло не так.

const { pipeline } = require('stream/promises');

await pipeline(
fs.createReadStream('file.txt'),
zlib.createGzip(),
fs.createWriteStream('file.txt.gz')
);


Backpressure — механизм, который не дает источнику «затопить» приемник данными, если тот не успевает их обрабатывать. Стримы в Node.js управляют этим автоматически.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
2👎1
200 тыс.₽ сейчас РЕАЛЬНО базовый минимум ⏺️

Который нужен для комфортной жизни в любом месте⤵️

Не знаешь, где словить такой куш?

Удаленка в долларах 💸 — канал для профи из СНГ с вакансиями в стабильной валюте.

IT, маркетинг, дизайн, крипта: ты точно в этом разбираешься

Осталось только начать нормально зарабатывать!

15+ актуальных вакансий за сегодня уже в канале:
https://t.me/+qoCsrhInumQyN2Ni 🔗
Please open Telegram to view this post
VIEW IN TELEGRAM
📦 Модуль cluster — масштабируем приложение на все ядра CPU

Node.js по умолчанию работает в одном потоке. Это значит, что даже на мощном сервере с 16 ядрами ваше приложение будет использовать только одно. Модуль cluster позволяет легко запустить клон вашего приложения на каждом ядре, увеличивая производительность в разы.

cluster — многопоточность для бэкенда

cluster.isPrimary
cluster.fork()
cluster.on('exit')
process.pid

cluster.isPrimary — свойство, которое помогает понять, является ли текущий процесс "главным" (менеджером) или "рабочим" (воркером).

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isPrimary) {
// Мастер-процесс создает воркеры
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
// Рабочие процессы запускают сервер
http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello World');
}).listen(8000);
}




cluster.fork() — создает новый рабочий процесс. Каждый воркер имеет свою память и свой Event Loop, но все они делят один и тот же порт сервера.

Балансировка нагрузки — Master-процесс сам распределяет входящие запросы между воркерами. Если один воркер занят тяжелыми вычислениями, запрос уйдет свободному.

Устойчивость — если один из воркеров упадет из-за ошибки, Master-процесс может это отследить и мгновенно запустить новый экземпляр.

cluster.on('exit', (worker, code, signal) => {
console.log(`Воркер ${worker.process.pid} умер. Запускаю новый...`);
cluster.fork();
});

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Какие http методы могут быть?

HTTP (HyperText Transfer Protocol) методы представляют собой набор стандартных операций, которые используются для взаимодействия между клиентом и сервером в сети. Каждый метод определяет конкретное действие, которое должен выполнить сервер. Вот основные HTTP методы и их предназначение:

🟠GET
Метод GET используется для получения данных с сервера. Он запрашивает представление ресурса, не изменяя его состояния. GET запросы часто используются для запросов веб-страниц и получения данных из API.

🟠POST
Метод POST используется для отправки данных на сервер с целью создания или обновления ресурса. Это может включать отправку формы на веб-сайте или загрузку файла. POST запросы обычно содержат данные в теле запроса.

🟠PUT
Метод PUT используется для обновления существующего ресурса или создания нового ресурса на сервере. Если ресурс уже существует, он будет обновлен, если нет — будет создан.

🟠DELETE
Метод DELETE используется для удаления ресурса с сервера. Запросы DELETE могут быть небезопасными, так как они изменяют состояние сервера, удаляя данные.

🟠PATCH
Метод PATCH используется для частичного обновления ресурса. В отличие от PUT, который заменяет весь ресурс, PATCH изменяет только указанные части ресурса.

🟠HEAD
Метод HEAD аналогичен GET, но без тела ответа. Используется для получения метаданных о ресурсе, таких как заголовки, без загрузки самого ресурса.

🟠OPTIONS
Метод OPTIONS используется для запроса информации о поддерживаемых методах на сервере или на конкретном ресурсе. Это может быть полезно для определения доступных операций перед отправкой основного запроса.

🟠CONNECT
Метод CONNECT используется для установления туннеля к серверу через прокси. Обычно используется для HTTPS через прокси.

🟠TRACE
Метод TRACE выполняет тестовый запрос по маршруту до ресурса. Он возвращает запрос, полученный сервером, что может помочь в диагностике сетевых проблем или выявлении изменений в маршруте запроса.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
4
🏗️ Модуль child_process — запуск внешних программ и скриптов

Иногда возможностей Node.js не хватает, и нужно вызвать системную команду, запустить Python-скрипт или скомпилировать C++ код. Модуль child_process позволяет Node.js порождать дочерние процессы и общаться с ними.

child_process — работа с системными командами

exec()
spawn()
fork()
execFile()

exec() — запускает команду в оболочке (shell) и буферизирует весь вывод. Идеально для коротких команд, результат которых помещается в память.

const { exec } = require('child_process');

exec('ls -lh', (err, stdout, stderr) => {
if (err) return console.error(err);
console.log(`Файлы:\n${stdout}`);
});




spawn() — запускает процесс и работает с ним через потоки (streams). Это лучший выбор для тяжелых задач или команд с огромным выводом, так как данные передаются частями.

const { spawn } = require('child_process');
const child = spawn('find', ['/']);

child.stdout.on('data', (data) => {
console.log(`Чанк данных: ${data.length}`);
});


fork() — специальный метод для запуска других Node.js модулей. Он создает выделенный канал связи (IPC) между родителем и ребенком, позволяя обмениваться объектами через send().

// В родительском коде
const n = fork('worker.js');
n.on('message', (m) => console.log('Получено:', m));
n.send({ hello: 'world' });


Безопасность — никогда не передавайте данные от пользователя напрямую в exec(), иначе злоумышленник может выполнить произвольный код на сервере (Command Injection). Используйте spawn() с массивом аргументов — это безопаснее.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
🚀 Модуль worker_threads — настоящий параллелизм в Node.js

Если cluster копирует весь процесс, то worker_threads позволяет запускать тяжелые вычисления в отдельных потоках внутри одного и того же процесса. Это идеальное решение для задач, которые нагружают процессор (CPU-intensive), таких как обработка изображений или сложные математические расчеты.

worker_threads — многопоточность без копирования процессов

Worker
parentPort
isMainThread
workerData

isMainThread — флаг, который помогает понять, выполняется ли код в основном потоке или внутри воркера.

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');

if (isMainThread) {
const worker = new Worker(__filename, { workerData: 'начать расчет' });
worker.on('message', (result) => console.log('Результат:', result));
} else {
const result = `Воркер получил: ${workerData}`;
parentPort.postMessage(result);
}




workerData — позволяет передавать данные из основного потока в воркер при его создании. Это могут быть любые клонируемые объекты.

parentPort — специальный канал связи, через который воркер может отправлять сообщения обратно в основной поток с помощью postMessage().

SharedArrayBuffer — в отличие от cluster, воркеры могут разделять одну и ту же область памяти. Это позволяет огромным массивам данных быть доступными для всех потоков одновременно без затрат на копирование.

Зачем это нужно? — Обычный код Node.js блокирует Event Loop при тяжелых циклах. Воркеры позволяют перенести эти циклы «в сторону», чтобы сервер продолжал отвечать на запросы других пользователей.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
📡 Модуль net — фундамент сетевого взаимодействия

Если http — это высокоуровневый стандарт для веба, то модуль net — это «низкий уровень». Он позволяет работать напрямую с TCP-сокетами, создавая серверы и клиенты, которые общаются голыми данными без лишних заголовков.

net — создание TCP-серверов и сокетов

net.createServer()
net.connect()
socket.write()
socket.pipe()

net.createServer() — создает TCP-сервер. В отличие от HTTP, здесь вы сами решаете, какой протокол использовать для общения — будь то чат, передача файлов или свой проприетарный формат.

const net = require('net');

const server = net.createServer((socket) => {
socket.write('Привет от TCP сервера!\n');
socket.on('data', (data) => {
console.log('Клиент прислал:', data.toString());
});
});

server.listen(8080);




net.connect() — создает клиентское соединение с сервером по IP и порту. Это база для написания своих баз данных, прокси-серверов или систем мониторинга.

const client = net.connect({ port: 8080 }, () => {
console.log('Подключено к серверу!');
client.write('Привет, сервер!');
});


socket.pipe() — сокеты в Node.js являются дуплексными стримами. Это значит, что вы можете «пробросить» данные из одного соединения в другое одной командой. Так пишутся простейшие прокси-серверы.

IPC (Inter-Process Communication) — модуль net умеет работать не только с сетью, но и с локальными именованными каналами (Unix Domain Sockets). Это самый быстрый способ заставить два процесса на одном сервере обмениваться данными

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
🛡️ Модуль tls — защищенные сетевые соединения

Если модуль net работает с «голым» TCP, то tls (Transport Layer Security) добавляет поверх него слой шифрования. Это фундамент для создания защищенных серверов, таких как HTTPS, и безопасной передачи данных, которую невозможно перехватить.

tls — шифрование сетевого трафика

tls.createServer()
tls.connect()
pfx / key / cert
ALPN

tls.createServer() — создает сервер, который требует SSL/TLS сертификаты для работы. Без них браузер или клиент не смогут установить безопасное соединение.

const tls = require('tls');
const fs = require('fs');

const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem')
};

tls.createServer(options, (socket) => {
socket.write('Вы подключены по защищенному каналу!\n');
socket.pipe(socket);
}).listen(8000);




Сертификаты (Key & Cert) — для работы tls нужны закрытый ключ (key) и сертификат (cert). В разработке часто используют самоподписанные сертификаты, но в продакшене — только от доверенных центров (CA).

tls.connect() — позволяет создать клиент, который безопасно подключается к TLS-серверу. Он автоматически проверяет валидность сертификата сервера, защищая от атак типа «человек посередине» (MITM).

ALPN (Application-Layer Protocol Negotiation) — расширение TLS, которое позволяет клиенту и серверу договориться, какой протокол использовать (например, HTTP/2 или HTTP/1.1) еще в процессе установки защищенного соединения.

Безопасность — модуль tls по умолчанию использует современные протоколы (TLS 1.2 и 1.3) и отключает старые, уязвимые версии (вроде SSLv3), обеспечивая высокий уровень защиты «из коробки».



Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🛡️ Модуль os — информация об операционной системе

Модуль os предоставляет методы для взаимодействия с операционной системой, на которой запущен Node.js. Это позволяет адаптировать работу приложения под конкретное железо: узнавать количество ядер, объем свободной оперативной памяти или домашнюю директорию пользователя.

os — системные данные и ресурсы

os.cpus()
os.freemem() / os.totalmem()
os.networkInterfaces()
os.homedir()
os.platform()

os.cpus() — возвращает массив объектов с данными о каждом ядре процессора (модель, скорость, время работы). Это ключевой метод для автоматического масштабирования через модуль cluster.

const os = require('os');
console.log(`Ядер процессора: ${os.cpus().length}`);




os.freemem() / os.totalmem() — показывают объем свободной и общей оперативной памяти в байтах. Помогает приложению понять, стоит ли сейчас запускать тяжелую задачу или памяти уже критически мало.

const freeGB = (os.freemem() / 1024 / 1024 / 1024).toFixed(2);
console.log(`Свободно памяти: ${freeGB} GB`);


os.networkInterfaces() — выдает детальную информацию о сетевых интерфейсах (IP-адреса, MAC-адреса). Нужно, если вашему серверу необходимо знать свой локальный или внешний IP.

os.platform() / os.type() — возвращают название платформы (win32, linux, darwin). Позволяет писать условия для специфических системных команд.

if (os.platform() === 'win32') {
console.log('Запущено на Windows');
}


os.homedir() — возвращает путь к домашней папке текущего пользователя. Это гораздо надежнее, чем пытаться угадать путь вручную.


Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3