⚡️Группа хакеров взломала сервера Skillbox, Geekbrains, Skillfactory и ещё 12 онлайн-школ, чтобы выгрузить их курсы в Telegram
Юристы пытаются удалить каналы за Авторские Права🤡 – потому вот актуальные ссылки на архивы:
По школам:
├ Skillbox (1.12 ТБ)
├ Нетология (846 ГБ)
├ SkillFactory (720 ГБ)
├ GeekBrains (934 ГБ)
└ Другие (3.21 ТБ)
По ЯП:
├ Python (1.48 ТБ)
├ SQL (982 ГБ)
├ C++ (590 ГБ)
├ С (318 ГБ)
├ GoLang (290 ГБ)
└ Другие (3.17 ТБ)
Ссылка на общий архив: @schools_hack_arc
📡 Модуль dgram — быстрая передача данных по UDP
Если модуль net работает с надежным протоколом TCP (где важна доставка каждого байта), то модуль dgram отвечает за работу с UDP (User Datagram Protocol). В UDP нет постоянного соединения и проверки дошли ли данные, зато он работает с минимальными задержками. Это идеальный выбор для онлайн-игр, стриминга видео, аудиосвязи и систем реального времени.
dgram — работа со свободными датаграммами
— createSocket()
— send()
— bind()
— on('message')
— Создание UDP-сервера — Для работы нужно создать сокет, указав тип протокола (udp4 для IPv4 или udp6 для IPv6), и привязать его к порту через метод bind().
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
console.log(`Получено: ${msg} от ${rinfo.address}:${rinfo.port}`);
});
server.bind(41234);
— Отправка пакетов (send) — Поскольку соединения нет, при каждой отправке метода send() нужно явно указывать адрес и порт получателя. Данные передаются в виде буфера (Buffer).
const client = dgram.createSocket('udp4');
const message = Buffer.from('Привет, UDP-сервер!');
client.send(message, 41234, 'localhost', (err) => {
if (err) console.error(err);
client.close();
});
— Мультикастинг (Multicast) — Уникальная фишка UDP. Модуль dgram позволяет отправлять один пакет сразу целой группе хостов в сети с помощью методов addMembership() и setMulticastTTL(). Это активно используется в локальных сетях для поиска устройств (например, протокол SSDP для умного дома).
— Когда использовать? — Когда скорость передачи критичнее, чем потеря отдельных пакетов. Если в шутере от первого лица один пакет с координатами игрока потеряется — ничего страшного, ведь через миллисекунду прилетит новый, более актуальный.
⚙ Backend Ready | #Уроки
Не крипта, не мемкоины, не казино ❌
🥇 Твой пассивный доход должен строиться на понятных активах
А не на СКАМерских проектах-однодневках.
Notal 📈 — канал о том, как зарабатывать на автоматической торговле золотом и серебром без вечной жизни на графиках.
Начните с простого: получите БЕСПЛАТНУЮ версию робота с доходностью до 25% годовых. Без подписок. Без настроек.
🤖 SilentGain
Как возможны 25% годовых? Узнай⤵️
https://t.me/+SZaP3SGi1uZjNzYy
📡 Модуль perf_hooks — точное измерение производительности
Стандартный метод Date.now() или объект new Date() не подходят для точного замера скорости работы кода. Они зависят от системных часов ОС, которые могут синхронизироваться или корректироваться прямо во время работы приложения. Встроенный модуль perf_hooks предоставляет доступ к High Resolution Time — независимому и сверхточному таймеру, который измеряет время в миллисекундах и микросекундах.
perf_hooks — метрики, маркеры и аудит скорости
— performance.now()
— performance.mark()
— performance.measure()
— PerformanceObserver
— High Resolution Time — Метод performance.now() возвращает количество миллисекунд, прошедших с момента старта процесса Node.js, с точностью до микросекунд (дробная часть).
const { performance } = require('perf_hooks');
const start = performance.now();
// Какой-то тяжелый алгоритм или цикл
for (let i = 0; i < 1000000; i++) {}
const end = performance.now();
console.log(`Алгоритм выполнялся: ${(end - start).toFixed(4)} мс`);
— Маркеры и замеры (mark & measure) — Позволяют расставлять контрольные точки в разных частях приложения и измерять расстояние между ними. Это избавляет от необходимости создавать кучу локальных переменных для хранения времени.
performance.mark('A'); // Начало операции
// Код операции...
performance.mark('B'); // Конец операции
performance.measure('Операция А-Б', 'A', 'B');
— PerformanceObserver — Удобный инструмент для сбора всех замеров в одном месте. Вместо того чтобы вручную вызывать функции сбора метрик по всему коду, вы создаете наблюдателя, который автоматически реагирует на появление новых замеров.
const { PerformanceObserver } = require('perf_hooks');
const obs = new PerformanceObserver((items) => {
items.getEntries().forEach((entry) => {
console.log(`${entry.name}: ${entry.duration} мс`);
});
});
obs.observe({ entryTypes: ['measure'], buffered: true });
— Мониторинг Event Loop — С помощью класса MonitorPerformance внутри этого модуля
⏳ Модуль async_hooks — отслеживание жизненного цикла асинхронных ресурсов
Поскольку JavaScript в Node.js построен на асинхронности, стандартный стек вызовов (stack trace) часто теряет контекст. Если внутри асинхронного колбэка происходит ошибка, бывает невозможно понять, какой именно HTTP-запрос или какая функция его породила. Встроенный модуль async_hooks предоставляет API для создания хуков, которые следят за созданием, развитием и уничтожением любых асинхронных ресурсов в приложении.
async_hooks — прозрачность асинхронных операций
— createHook()
— init() / before() / after() / destroy()
— executionAsyncId()
— triggerAsyncId()
— Асинхронные ресурсы — Для модуля async_hooks асинхронным ресурсом является всё, что имеет колбэк: промисы (Promise), таймауты (Timeout), TCP-соединения (TCPWrap), операции с файлами (FSReqCallback) и многое другое.
— Анатомия хуков (init, before, after, destroy) — Метод createHook принимает объект с колбэками, каждый из которых отвечает за определенный этап жизни ресурса.
const async_hooks = require('async_hooks');
const fs = require('fs');
const hook = async_hooks.createHook({
init(asyncId, type, triggerAsyncId, resource) {
// Вызывается в момент создания асинхронного ресурса
fs.writeSync(1, `Создан ресурс: ${type} с ID: ${asyncId}\n`);
},
before(asyncId) {
// Вызывается непосредственно перед выполнением колбэка ресурса
},
after(asyncId) {
// Вызывается сразу после того, как колбэк отработал
},
destroy(asyncId) {
// Вызывается, когда асинхронный ресурс уничтожается (очищается из памяти)
}
});
hook.enable(); // Включаем отслеживание
— Идентификаторы (Async IDs) — Каждому асинхронному действию присваивается уникальный номер (asyncId). Метод executionAsyncId() возвращает ID текущего контекста выполнения, а triggerAsyncId() — ID ресурса, который вызвал (спровоцировал) создание текущего. Это позволяет выстроить полное дерево зависимостей.
— ⚠️ Важное предупреждение по производительности — Использ
🌐 Модуль wasi — запуск WebAssembly за пределами браузера
Технология WebAssembly (Wasm) изначально создавалась для того, чтобы запускать тяжелый скомпилированный код (на C, C++, Rust, Go) прямо в браузере на околонативной скорости. Модуль wasi (WebAssembly System Interface) расширяет эти возможности, позволяя Wasm-модулям выходить за рамки песочницы браузера и безопасно взаимодействовать с операционной системой: читать файлы, работать с сетью и системным временем.
wasi — мост между бинарным кодом и ОС
— new WASI()
— wasiImport
— start()
— initialize()
— Что такое WASI? — Это стандартизованный API, который предоставляет коду WebAssembly доступ к системным вызовам (системным функциям ОС). Без WASI бинарный файл .wasm внутри Node.js изолирован и не может сделать даже элементарный console.log или прочитать файл с диска.
— Изоляция и Безопасность — Главная фишка WASI — это безопасность на основе разрешений (capability-based security). Вы не просто даете Wasm-модулю доступ к файловой системе, а жестко прописываете в конфигурации (свойство preopens), к каким конкретно папкам на вашем компьютере этот модуль имеет доступ. К остальным директориям он дотянуться не сможет при всём желании.
const fs = require('fs');
const { WASI } = require('wasi');
const wasi = new WASI({
version: 'preview1',
args: process.argv,
env: process.env,
// Разрешаем модулю читать и писать только в локальную папку /sandbox
preopens: {
'/sandbox': './my-local-sandbox-folder'
}
});
(async () => {
// Загружаем скомпилированный Wasm-файл (например, написанный на Rust)
const wasmBuffer = fs.readFileSync('./optimized_algorithm.wasm');
const wasmModule = await WebAssembly.compile(wasmBuffer);
// Передаем системные интерфейсы WASI внутрь Wasm-модуля
const instance = await WebAssembly.instantiate(wasmModule, {
wasi_snapshot_preview1: wasi.wasiImport
});
// Запускаем исполнение
wasi.start(instance);
})();
— Зачем это нужно веб-разработчику? — Чтобы переиспользовать
🛠️ Модуль util — швейцарский нож для разработчика
Когда стандартных возможностей JavaScript не хватает для решения повседневных задач (дебаг объектов, превращение колбэков в промисы или проверка типов), на помощь приходит встроенный модуль util. Это набор служебных утилит, которые делают жизнь разработчика намного проще.
util — вспомогательные инструменты и полифилы
— promisify()
— inspect()
— format()
— types
— promisify() — легендарный метод, который берет старую функцию, работающую на колбэках (callback-style), и превращает её в современную функцию, возвращающую Promise. Это позволяет использовать async/await со старыми библиотеками.
const util = require('util');
const fs = require('fs');
// Превращаем fs.readFile в функцию на промисах
const readFile = util.promisify(fs.readFile);
async function getConfig() {
try {
const data = await readFile('./config.json', 'utf8');
console.log(data);
} catch (err) {
console.error('Ошибка чтения:', err);
}
}
— inspect() — возвращает строковое представление объекта. В отличие от JSON.stringify(), этот метод умеет красиво подсвечивать синтаксис в консоли, не ломается на циклических ссылках (circular references) и позволяет настраивать глубину отображения вложенных объектов.
const complexObj = { a: 1, b: { c: { d: 'глубоко' } } };
console.log(util.inspect(complexObj, { depth: null, colors: true }));
— format() — форматирует строку в стиле языка C (используя спецификаторы вроде %s для строк, %d для чисел). На базе этого метода построена привычная нам функция console.log().
const greeting = util.format('Привет, %s! У тебя %d новых сообщений.', 'Алексей', 5);
console.log(greeting); // Привет, Алексей! У тебя 5 новых сообщений.
— util.types — встроенный валидатор типов данных, который заглядывает глубже обычного оператора typeof. С его помощью можно со 100% уверенностью проверить, является ли объект регулярным выражением, датой, Async-функцией или, например, Map/Set.
const types = require('util').
Модуль zlib — сжатие данных и архивация
Когда сервер отправляет пользователю огромные JSON-ответы, HTML-страницы или текстовые логи, это сильно нагружает сеть. Встроенный модуль zlib позволяет сжимать данные на лету с использованием популярных алгоритмов Gzip, Deflate и Brotli. Это уменьшает размер передаваемых файлов в несколько раз, ускоряя загрузку приложений и экономя трафик.
zlib — оптимизация трафика через сжатие
— createGzip() / createGunzip()
— createBrotliCompress() / createBrotliDecompress()
— gzip() / gunzip()
— Сжатие потоков (Streams) — Поскольку zlib полностью интегрирован со стримами Node.js, вы можете сжимать файлы или сетевые ответы буквально в одну строчку кода через .pipe(), не загружая весь файл в оперативную память.
const zlib = require('zlib');
const fs = require('fs');
const source = fs.createReadStream('large_log.txt');
const destination = fs.createWriteStream('large_log.txt.gz');
const gzip = zlib.createGzip();
// Читаем -> Сжимаем в Gzip -> Записываем на диск
source.pipe(gzip).pipe(destination);
— Brotli против Gzip — Модуль поддерживает алгоритм Brotli (createBrotliCompress), который был разработан Google. Он сжимает текстовые данные (HTML, JS, CSS) на 15–20% эффективнее, чем старый добрый Gzip. В современном вебе это стандарт де-факто для отдачи статики.
— Асинхронная работа с буферами — Если вам нужно сжать не поток, а конкретную строку или буфер в памяти (например, перед сохранением в базу данных), у модуля есть простые методы-колбэки (или их promisify-версии).
const { gzip, gunzip } = require('zlib');
const { promisify } = require('util');
const doGzip = promisify(gzip);
const input = 'Очень важная строка, которую нужно сильно сжать';
const compressedBuffer = await doGzip(input);
console.log('Размер до:', Buffer.byteLength(input), 'байт');
console.log('Размер после:', compressedBuffer.length, 'байт');
— HTTP-сжатие — Именно с помощью zlib на чистом Node.js реализуется обработка заголовка Accept-Encoding: gzip, br. Серв
Айтишники ловите сборник бесплатных курсов, полезных инструментов и книг
Проект «TERMINAL» стал крупнейшей библиотекой бесплатного образования. В одном канале собраны курсы, книги, полезные инструменты и практические тренажёры для всех разработчиков
🎓 Практические курсы и задания
🪽 Книги и статьи известных авторов
😮💨 Полезные инструменты и ресурсы
🌟 IT-новости и инсайды
Обучение по всем направлениям: SQL, Python, Frontend, PHP, C++, Golang, GIT, Linux, QA, Java, кибербезопасность и др.
Ценишь знания, подпишись: Terminal_tg
🖥️ Модуль os — информация об операционной системе
Когда твое приложение запускается на сервере, ему часто нужно подстраиваться под окружение. Модуль os предоставляет прямой доступ к операционной системе, позволяя узнать всё о процессоре, оперативной памяти, сетевых интерфейсах и системных папках устройства, на котором выполняется код.
os — аудит железа и системного окружения
— cpus()
— freemem() / totalmem()
— networkInterfaces()
— homedir() / tmpdir()
— os.cpus() — возвращает массив объектов со сведениями о каждом ядре процессора: модель, скорость (в МГц) и время, проведенное в различных режимах. Это важнейший метод для настройки кластеризации (cluster), чтобы запускать ровно столько копий приложения, сколько ядер есть на сервере.
const os = require('os');
const cores = os.cpus().length;
console.log(`Твой сервер имеет ${cores} логических ядер.`);
— Мониторинг памяти (freemem / totalmem) — позволяют в реальном времени оценивать загруженность сервера. totalmem показывает общий объем оперативной памяти в байтах, а freemem — сколько осталось свободно. На базе этих метрик строят системы алертов.
const freeGB = (os.freemem() / 1024 / 1024 / 1024).toFixed(2);
const totalGB = (os.totalmem() / 1024 / 1024 / 1024).toFixed(2);
console.log(`Память: свободно ${freeGB} ГБ из ${totalGB} ГБ`);
— os.networkInterfaces() — возвращает детальную информацию о сетевых адаптерах устройства (IP-адреса, MAC-адреса, маски подсети). Полезно, когда нужно программно определить локальный IP-адрес сервера в сети.
— Кроссплатформенные пути (homedir / tmpdir) — спасают от ручной проверки системных путей. os.homedir() вернет путь к домашней директории текущего пользователя (C:\Users\... на Windows или /home/... на Linux), а os.tmpdir() — путь к системной временной папке для безопасного сохранения кэша или загружаемых файлов.
⚙ Backend Ready | #Уроки
📊 Модуль string_decoder — безопасное декодирование бинарных потоков
При работе с потоками данных (Streams) или буферами (Buffer) файлы и сетевые пакеты прилетают в приложение по частям (чанками) в виде сырых байт. Если текстовый файл сохранен в кодировке UTF-8, то некоторые символы (например, кириллица или эмодзи) могут занимать от 2 до 4 байт. Если чанк оборвется посреди такого многобайтового символа, обычный метод buffer.toString() превратит сломанный стык в нечитаемый знак вопроса ``. Модуль string_decoder решает эту проблему, бережно склеивая разорванные символы.
string_decoder — правильная конвертация байт в текст
— new StringDecoder()
— write()
— end()
— Проблема разбитых символов — Если передавать кириллический текст по кусочкам, есть огромный шанс, что один из байтов буквы «При» останется в первом куске, а второй байт уйдет в следующий. Buffer.concat() решает это постфактум, но если вам нужно обрабатывать текст *в процессе* чтения потока, стандартный .toString() выдаст брак.
— Как работает StringDecoder — Он создает внутренний буфер для «остатков». Если на конце чанка обнаруживается неполный многобайтовый символ, декодер придерживает его у себя и склеивает с началом следующего чанка, гарантируя идеальный текст без артефактов.
const { StringDecoder } = require('string_decoder');
const decoder = new StringDecoder('utf8');
// Эмодзи 🔥 состоит из 4 байт: [0xf0, 0x9f, 0x94, 0xa5]
const chunk1 = Buffer.from([0xf0, 0x9f]); // Половинка эмодзи
const chunk2 = Buffer.from([0x94, 0xa5, 0x20]); // Вторая половина + пробел
// Обычный chunk1.toString() выдаст кракозябру, но декодер умнее:
console.log(decoder.write(chunk1)); // Выведет пустую строку (ждет продолжения)
console.log(decoder.write(chunk2)); // Выведет: 🔥
— Метод end() — Если поток данных завершился, а в буфере декодера все еще лежат какие-то неопознанные байты (например, файл был изначально поврежден), вызов decoder.end() принудительно вернет их в виде символов замены, очистив память.
— Заче
🤔 Чем отличается rebase от merge?
В Git команды rebase и merge используются для объединения изменений из разных веток, но делают это по-разному. Основное различие между ними заключается в том, как они сохраняют историю коммитов и как они влияют на структуру репозитория.
🚩Основные отличия
🟠Merge (Слияние)
Объединяет две ветки, создавая новый коммит слияния (merge commit), который имеет две родительских ветки. Сохраняет всю историю коммитов обеих веток без изменений. История ветвления и слияния сохраняется. Если есть конфликты, Git предложит их разрешить перед созданием коммита слияния.
git merge <branch>
git checkout main
git merge feature-branch
🟠Rebase (Перебазирование)
Переносит все коммиты текущей ветки на вершину целевой ветки. Это делает историю линейной, как если бы изменения были сделаны последовательно. Изменяет историю коммитов, создавая новые коммиты для каждого коммита из текущей ветки. История ветвления исчезает. Если есть конфликты, Git предложит их разрешить по мере переноса каждого коммита.
git rebase <branch>
git checkout feature-branch
git rebase main
🚩Плюсы и минусы
🟠Merge
➕Простота
Процесс слияния прост и понятен.
➕Сохранение истории
Вся история коммитов сохраняется, включая информацию о ветвлении и слиянии.
➖Коммиты слияния
Создаются дополнительные коммиты слияния, что может усложнить историю.
🟠Rebase
➕Чистая история
История линейная и более читабельная.
➕Упрощение навигации
Проще следить за последовательностью изменений.
➖Изменение истории
Изменение коммитов может привести к проблемам, если кто-то уже основывается на этих коммитах.
➖Конфликты
Может потребоваться больше усилий для разрешения конфликтов, особенно если коммитов много.
🚩Когда использовать
🟠Merge
Когда важно сохранить полную историю изменений, включая ветвление и слияние. В крупных командных проектах, где история изменений важна для отслеживания.
🟠Rebase
Когда важно иметь чистую и линейную историю изменений. Для интеграции изменений из основной ветки в текущую рабочую ве
🍿 ИИ становится более контекстным: пользователям все реже нужны идеальные промпты
Руководитель группы продукта «Поиск и Рекомендации» Яндекс Маркета Любовь Горбунова считает, что необходимость в предельно точных формулировках снижается: нейросеть все лучше понимает запросы и в перспективе с ней можно будет общаться как с консультантом в магазине — в свободной форме и с уточнениями по ходу диалога.
Еще один тренд — использование ИИ вместе с VR/AR-технологиями. Уже сейчас такие решения улучшают сценарии виртуальной примерки одежды. А в будущем подход может распространиться и на другие категории, например, на «примерку» мебели в интерьере.
🎧 ИИ-музыку почти никто не слушает
В новом исследовании изучили Spotify и выяснили, что 93% нейротреков не набирают даже 1000 прослушиваний.
Авторы называют это music slop. Тысячи композиций заливают пачками в разные жанры, надеясь случайно попасть в рекомендации. Дистрибьюторы почти этому не мешают, а детекторы пока легко обходятся.
А как часто вам попадается в реках нейрохрючево?
• Источник
🤔 Что такое миксины?
Это один из способов повторного использования кода в объектно-ориентированном программировании. Они представляют собой классы или функции, которые предоставляют методы для других классов, без необходимости быть основой для этих классов. Миксины позволяют «подмешивать» функциональность в другие классы, обеспечивая гибкость и модульность кода.
🚩Характеристики
🟠Повторное использование кода
Миксины позволяют избежать дублирования кода путем инкапсуляции общих методов и свойств, которые могут быть использованы в различных классах.
🟠Множественное наследование
В языках, поддерживающих множественное наследование (например, Python), миксины могут быть использованы как базовые классы для других классов, предоставляя дополнительные методы и свойства. Это позволяет создавать классы, комбинируя несколько миксинов для расширения функциональности.
🟠Композиция
В языках, где множественное наследование не поддерживается или нежелательно (например, в JavaScript), миксины могут быть применены через композицию, где функциональность миксина добавляется к целевому объекту или классу.
🟠Изоляция поведения
Миксины позволяют изолировать и инкапсулировать определенное поведение или функциональность, что упрощает тестирование и поддержку кода.
🚩Примеры использования
🟠Python
Миксины часто используются через множественное наследование.
class LoggableMixin:
def log(self, message):
print(f"Log: {message}")
class Database(LoggableMixin):
def save(self, data):
self.log("Saving data")
# Код для сохранения данных
db = Database()
db.save({"key": "value"})
🟠JavaScript
Миксины могут быть применены через композицию.
const loggableMixin = {
log(message) {
console.log(`Log: ${message}`);
}
};
class Database {
save(data) {
this.log("Saving data");
// Код для сохранения данных
}
}
Object.assign(Database.prototype, loggableMixin);
const db = new Database();
db.save({ key: 'value' });
Избегайте использования CASE в WHERE
Хотя SQL допускает использование выражений CASE внутри WHERE, они часто делают запросы менее читаемыми и усложняют понимание их логики. Логика фильтрации оказывается спрятана внутри условного выражения вместо того, чтобы быть выраженной напрямую через булевы предикаты. Кроме того, оборачивание условий в CASE может затруднить для оптимизатора запросов анализ предиката и эффективное использование индексов. Во многих случаях это делает запрос non-SARGable (Search ARGument Able), то есть база данных не может эффективно использовать индексы для поиска нужных строк.
Вот наивный вариант:
SELECT *
FROM Products
WHERE CASE
WHEN Category = 'Electronics' THEN Price < 500
ELSE Price < 100
END;
В этом запросе логика фильтрации встроена внутрь выражения CASE, из-за чего условие становится менее прозрачным и потенциально более сложным для эффективной оценки оптимизатором.
Лучший способ выразить такую логику, это использовать операторы AND и OR напрямую в условии фильтрации. Явно записанные булевы предикаты делают логику проще для чтения и понимания, потому что условия хорошо видны, а не спрятаны внутри CASE.
Такой подход также даёт оптимизатору базы данных больше возможностей для анализа предиката и потенциально более эффективного использования индексов. Во многих случаях прямолинейная булева логика даёт запросы, которые и читаются лучше, и работают быстрее. Вот улучшенный вариант запроса:
SELECT *
FROM Products
WHERE Price < 100
OR (Category = 'Electronics' AND Price < 500);
Избегайте использования IN с NULL
Оператор IN относится к тем конструкциям, которые легко вносят тихие баги в запрос, если использовать его неправильно. Когда вы включаете NULL в список IN, сравнение никогда не даст TRUE для части с NULL. В результате строки, содержащие NULL, не матчятся так, как многие ожидают. SQL использует трёхзначную логику: TRUE, FALSE и UNKNOWN. Сравнения с NULL не возвращают ни TRUE, ни FALSE; они возвращают UNKNOWN. Вот наивный вариант использования IN:
SELECT *
FROM Employees
WHERE DepartmentID IN (1, 2, NULL);
Поскольку NULL даёт UNKNOWN, запрос выше выполнится без ошибок, но гарантированно вернёт пустой результат.
Правильный способ обрабатывать NULL - использовать IS NULL. IS NULL явно учитывает то, как SQL работает с отсутствующими значениями. Это помогает запросу корректно различать реальные значения и неизвестные значения, что предотвращает тихие логические ошибки. Вот как этот запрос лучше писать:
SELECT *
FROM Employees
WHERE DepartmentID IN (1, 2)
OR DepartmentID IS NULL;
На Stepik завирусился полный курс по вайбкодингу c Claude Code
Первым делом вы изучите базу инструмента, а после научитесь:
✓ Разрабатывать MCP-серверы и Claude Skills
✓ Создавать собственных ИИ-агентов под свои задачи
✓ Эффективно работать с Claude и не упираться в лимиты
✓ Проектировать приложения через Claude Design
✓ Строить личную систему знаний на базе Obsidian + Claude Cowork
✓ Автоматизировать разработку через Agent Loops и хуки
✓ Запускать параллельные воркфлоу из нескольких агентов
✓ Проектировать приложения вместе с Claude Code
✓ Автоматизировать задачи через Connectors и внешние сервисы
✓ Перевести Claude Code из помощника в полноценного участника команды разработки
✓ Убирать из текстов типичные ИИ-шаблоны с помощью файла anti-ai-writing-style.md.
✓ Работать с таблицами при помощи Cowork
В конце дорожная карта и 7 практических способа обхода ограничений Anthropic 🎉
В течении 48 часов действует скидка 25%
🔗 Модуль path — работа с путями к файлам и папкам
Разные операционные системы используют разные разделители путей: Windows предпочитает обратный слэш (\), а Linux и macOS — прямой (/). Модуль path позволяет писать кроссплатформенный код, который будет корректно работать на любой системе, автоматически подстраиваясь под её правила.
path — манипуляция путями без ошибок
— path.join()
— path.resolve()
— path.extname()
— path.parse()
— path.join() — объединяет сегменты пути в одну строку, используя специфичный для системы разделитель. Это гораздо надежнее, чем складывать строки через +.
const path = require('path');
const fullPath = path.join('users', 'bairas', 'projects', 'app.js');
// Windows: users\bairas\projects\app.js
// Linux: users/bairas/projects/app.js
— path.resolve() — превращает последовательность путей в абсолютный путь. Он работает как команда cd в терминале: берет текущую рабочую директорию и «наслаивает» на неё переданные сегменты.
— path.extname() — моментально возвращает расширение файла. Полезно, когда нужно отфильтровать только .jpg картинки или .js скрипты в папке.
console.log(path.extname('index.html')); // '.html'
— path.parse() — разбирает строку пути на составные части: корень, директорию, базовое имя, расширение и имя файла без расширения. Возвращает удобный объект.
const info = path.parse('/home/user/dir/file.txt');
/*
{
root: '/',
dir: '/home/user/dir',
base: 'file.txt',
ext: '.txt',
name: 'file'
}
*/
— dirname и filename — хотя это глобальные переменные, их почти всегда используют вместе с модулем path, чтобы вычислить путь к файлам относительно текущего скрипта, а не от места запуска терминала.
⚙ Backend Ready | #Уроки
🐳 Почему Kubernetes стал стандартом оркестрации
Сталкиваешься с масштабированием приложений и устал от ручного управления сотнями контейнеров? Разбираем, как архитектура Kubernetes решает реальные проблемы деплоя в продакшене через понятные компоненты — без сложной теории.
Ключевые преимущества: автовосстановление подов при падениях, автоматическое масштабирование под нагрузкой, rolling updates без downtime, Service discovery и load balancing из коробки. Разбор реального кейса миграции Tinder — как перешли с 4 серверов на 1000+ подов с 99.99% доступности.
Незаменимый инструмент для DevOps-инженеров и разработчиков, которые хотят строить отказоустойчивые системы вместо рутины по мониторингу контейнеров 🚀
Перейти на сайт
Backend База | #Kubernetes #DevOps #Backend
🛠️ Свой Spring Starter для Outbox/Inbox паттерна
Как обеспечить надёжную доставку событий между микросервисами и избежать потерь данных при сбоях? Автор столкнулся с этой проблемой при разработке аналитического сервиса и решил создать собственное решение.
Ключевая проблема — потеря событий при транзакциях с базой данных. Решение: Spring Starter, который реализует Outbox и Inbox паттерны через Event Sourcing. В статье — архитектура готовой библиотеки, принцип работы через две таблицы (outbox_events и inbox_events), настройка мониторинга и интеграция с Kafka, а также практические примеры применения.
Полезный инструмент для разработчиков, которые строят микросервисные приложения и хотят гарантировать доставку сообщений без головной боли 🚀
🌐 Перейти на сайт
⚙️ Backend База | #Spring #Backend #Архитектура
«Современные микропроцессоры: руководство на 90 минут».
Автор пишет, что вчера обсуждал со стажёрами разные аспекты оптимизации производительности и был приятно удивлён их интересом к внутреннему устройству современных процессоров.
В итоге он собрал компактный материал, который примерно за полтора часа даёт обзор того, как устроены современные микропроцессоры и что важно понимать для оптимизации производительности.
https://lighterra.com/papers/modernmicroprocessors/
🐳 Docker Compose для мультиконтейнерных приложений
Работаешь с микросервисами и устал вручную настраивать связи между контейнерами?
Docker Compose позволяет описывать всю инфраструктуру в одном YAML-файле: сети, тома, сервисы и их зависимости. Запускаешь одну команду — и получаешь готовое окружение для разработки или тестирования.
Незаменимый инструмент для всех, кто работает с Docker и хочет упростить управление сложными приложениями 🚀
🐱 Перейти на GitHub
💼Alt-sendme — отправляйте файлы и папки в любую точку мира без хранения в облаке — любой размер, любой формат, без аккаунтов и ограничений.
Бесплатный инструмент для передачи файлов с открытым исходным кодом, использующий возможности передовой одноранговой сети, позволяет передавать файлы напрямую, не сохраняя их на облачных серверах.😏