Backend Ready | IT
8.32K subscribers
1.25K photos
93 videos
6 files
1K links
По всем вопросам: @AdilNow
Download Telegram
🧩 Модуль url — безопасный парсинг и сборка ссылок**

Работа со строками через split или регулярные выражения — прямой путь к ошибкам и уязвимостям. В Node.js есть встроенный класс URL, который соответствует международным стандартам и автоматически обрабатывает спецсимволы.

url — разбор и валидация адресов

new URL()
url.searchParams
url.pathname
url.origin
url.format()

new URL() — создает объект, который разбивает строку на части: протокол, хост, порт, путь и параметры.

const myUrl = new URL('https://api.test.ru:8080/v1/user?id=10#hash');

console.log(myUrl.host); // api.test.ru:8080
console.log(myUrl.protocol); // https:
console.log(myUrl.hash); // #hash




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

const link = new URL('https://shop.ru/search');
link.searchParams.append('sort', 'desc');
link.searchParams.set('page', '1');

console.log(link.href);
// https://shop.ru/search?sort=desc&page=1


pathname — возвращает только путь к ресурсу. Полезно для роутинга, чтобы отсечь домен и параметры поиска.
origin — возвращает комбинацию протокола и хоста. Идеально для настройки CORS или проверки источника запроса.

const site = new URL('https://blog.js.org/posts/123');
console.log(site.origin); // https://blog.js.org


Безопасность — если передать в конструктор URL некорректную строку, он выдаст ошибку. Это отличный способ проверить, является ли строка валидной ссылкой, прежде чем сохранять её в базу.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
2
🔐 Права доступа в Linux — разбираемся с chmod и chown!

В Linux всё есть файл, и безопасность системы строится на том, кто может эти файлы читать, изменять или запускать. Если вы хоть раз видели ошибку Permission denied, значит, пришло время разобраться, как работают права доступа и как ими управлять.

В этом посте:
— Разбираем магические цифры 777, 644 и 755.
— Учимся менять владельца файлов через chown.
— Настраиваем права на чтение, запись и запуск.
— Узнаем, как рекурсивно исправить доступ во всей папке.

---

Каждый файл в Linux имеет три группы прав: для Владельца (User), для Группы (Group) и для Всех остальных (Others). Для каждой группы можно разрешить или запретить три действия: r (read — чтение), w (write — запись) и x (execute — запуск).

Как читать цифровой код:
4 — чтение (read)
2 — запись (write)
1 — запуск (execute)
0 — нет прав

Складывая эти цифры, мы получаем нужный уровень доступа. Например, 4+2+1 = 7 (полные права), а 4+2 = 6 (чтение и запись).

Популярные комбинации:
chmod 777 — «гуляй, кто хочешь». Все могут делать всё. Худший вариант для безопасности.
chmod 644 — стандарт для файлов. Владелец пишет и читает, остальные только читают.
chmod 755 — стандарт для папок и скриптов. Все могут зайти в папку или запустить файл, но менять его может только владелец.

Иногда проблема не в правах, а в том, что файл принадлежит не тому пользователю (например, root вместо вашего юзера). Чтобы сменить «хозяина», используется команда chown. Если нужно сменить и владельца, и группу сразу, пишем через двоеточие: sudo chown user:group filename.



Часто права нужно поправить не в одном файле, а во всей папке с вложенными проектами. Для этого используйте флаг -R (recursive). Но будьте осторожны: sudo chmod -R 777 / превратит вашу систему в решето за одну секунду.

Использование правильных прав — это не просто «чтобы работало», а защита вашего сервера от взлома. Скрипты должны иметь флаг +x только если вы собираетесь их запускать, а конфиги с паролями (вроде .env) должны быть закрыты от всех, кроме владельца.

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🛰️ Модуль querystring — работаем с параметрами запросов**

Хотя класс URL умеет парсить параметры, модуль querystring остается незаменимым, когда нужно быстро превратить объект в строку для тела запроса или разобрать сырые данные, которые приходят в POST-запросе от старых HTML-форм.

querystring — парсинг и сборка запросов

parse()
stringify()
escape()
unescape()

parse() — превращает строку параметров (то, что идет после знака ?) в обычный объект JavaScript.

const qs = require('querystring');

const query = 'user=admin&role=editor&active=true';
const parsed = qs.parse(query);

console.log(parsed.user); // admin




stringify() — делает обратную операцию: берет объект и собирает из него корректную строку параметров, которую можно подставить в URL.

const params = { search: 'node js', page: 5 };
const string = qs.stringify(params);

console.log(string); // search=node%20js&page=5


escape() / unescape() — низкоуровневые методы для работы со спецсимволами. Они заменяют пробелы, кавычки и кириллицу на безопасные коды (например, %20), чтобы сервер мог их прочитать.

Отличие от URLSearchParamsquerystring работает быстрее и поддерживает кастомные разделители. Если вместо & и = тебе нужно использовать ; и :, этот модуль справится в одну строку.

const custom = qs.parse('name:tom;age:20', ';', ':');
console.log(custom.name); // tom

Backend Ready | #урок
Please open Telegram to view this post
VIEW IN TELEGRAM
1
📦 Модуль 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