Стандартный ответ — «потому что in-memory». Это правда, но не объяснение. Куча баз данных хранит данные в памяти и не показывает таких цифр. Настоящий ответ в другом: каждое архитектурное решение Redis убирает конкретный источник latency.
🧵 Один поток
Redis обрабатывает команды последовательно в один поток. Никаких мьютексов, никакого context switching. Тысячи соединений при этом обслуживаются через epoll/kqueue — один поток следит за всеми сокетами через I/O multiplexing и не блокируется ни на одном из них.
📦 Адаптивные структуры
Hash с небольшим числом ключей хранится не как хэш-таблица, а как listpack — плотный байтовый массив, который влезает в один cache line. Никаких pointer chasing. Только когда данных становится много, Redis переключается на полноценную хэш-таблицу. Sorted Set — одновременно хэш-таблица и skiplist. O(1) по ключу и O(log N) для range-запросов без второго прохода.
💾 fork()
Снапшот RDB пишется дочерним процессом после fork(). Благодаря CoW основной процесс продолжает работу и не видит никакой паузы — ОС копирует только изменённые страницы памяти. AOF идёт дальше и логирует каждую команду, давая возможность восстановиться до последней записи. Точнее, но дороже — компромисс осознанный.
🧹 bounded expiry
Ключи с истёкшим TTL удаляются двумя способами: лениво при обращении и активно — каждые 100 мс Redis сэмплирует случайную выборку и чистит просроченные. Если таких больше 25%, повторяет цикл. Это не O(N) по всей базе, а предсказуемая нагрузка с жёстким потолком по CPU.
Redis — это не «база данных в памяти». Это система, где каждый выбор — однопоток, listpack, fork(), bounded expiry — существует потому, что альтернатива добавляла latency. In-memory здесь просто необходимое условие, а не причина скорости.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍5❤1
Классика: у тебя Value Object с readonly-свойствами, и нужно вернуть копию с одним изменённым полем. До 8.4 приходилось делать фабричный метод вручную:
class Money {
public function __construct(
public readonly int $amount,
public readonly string $currency,
) {}
public function withAmount(int $amount): static
{
return new static($amount, $this->currency);
}
}В PHP 8.4 появился clone with:
$price = new Money(1000, 'USD');
$discounted = clone $price with {
amount: 850,
};
Никаких withField() методов на каждый чих. clone with работает даже с readonly — это единственное место, где PHP позволяет их «изменить» без рефлексии.
#vardump
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8👍6❤2🔥2👾1
🔥 Laravel Facades красота или костыль?
Скрытые зависимости, нарушение SRP, привязка к фреймворку через __callStatic() — звучит страшно. Но 64% PHP-девов используют Laravel и не парятся.
Как пишете вы, Facades или DI? И считаете ли, что Тейлор красиво «продал» антипаттерн?
💬 Пишите ваше мнение в комментарии
#междусобойчик
// Читаемо и быстро
Cache::get('user:' . $id);
// Явно и тестируемо
public function __construct(
private CacheInterface $cache,
) {}
Скрытые зависимости, нарушение SRP, привязка к фреймворку через __callStatic() — звучит страшно. Но 64% PHP-девов используют Laravel и не парятся.
Как пишете вы, Facades или DI? И считаете ли, что Тейлор красиво «продал» антипаттерн?
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5😁3🌚1
Forwarded from Библиотека собеса по PHP | вопросы с собеседований
Код прошёл нагрузочное тестирование. На проде деньги задвоились 👇
📦 Задание
Фича: пользователь может переводить бонусные баллы другу. Логика простая — проверить баланс, списать, начислить. Тесты зелёные, нагрузочное прогнали — всё ок. Через три дня после релиза: у нескольких пользователей баланс ушёл в минус, у других — задвоился.
// src/Bonus/BonusTransferService.php
class BonusTransferService
{
public function __construct(
private PDO $pdo,
private BonusRepository $repo,
) {}
public function transfer(int $fromId, int $toId, int $amount): void
{
$this->pdo->beginTransaction();
try {
$fromBalance = $this->repo->getBalance($fromId);
if ($fromBalance < $amount) {
throw new InsufficientFundsException();
}
$this->repo->debit($fromId, $amount);
$this->repo->credit($toId, $amount);
$this->pdo->commit();
} catch (Throwable $e) {
$this->pdo->rollBack();
throw $e;
}
}
}
// src/Bonus/BonusRepository.php
class BonusRepository
{
public function __construct(private PDO $pdo) {}
public function getBalance(int $userId): int
{
$stmt = $this->pdo->prepare(
'SELECT balance FROM bonus_accounts WHERE user_id = ?'
);
$stmt->execute([$userId]);
return (int) $stmt->fetchColumn();
}
public function debit(int $userId, int $amount): void
{
$stmt = $this->pdo->prepare(
'UPDATE bonus_accounts SET balance = balance - ? WHERE user_id = ?'
);
$stmt->execute([$amount, $userId]);
}
public function credit(int $userId, int $amount): void
{
$stmt = $this->pdo->prepare(
'UPDATE bonus_accounts SET balance = balance + ? WHERE user_id = ?'
);
$stmt->execute([$amount, $userId]);
}
}
🔹 Задачи
— Объяснить, как именно происходит race condition в этом коде
— Почему транзакция здесь не защищает от проблемы
— Исправить getBalance так, чтобы устранить race condition
Ставьте → 🔥 если нравится формат. Если нет → 🌚
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤3👍1
🤔 Разрабатываете ИИ-агентов, но всё ещё не уверены в их стабильности и прогнозируемости?
Мы поговорили с десятками разработчиков ИИ-агентов и сделали отдельный курс по AgentOps.
🧠 На нём вы узнаете:
– как оптимизировать траты на токены;
– как на практике оценить качество работы агента;
– как «докручивать» RAG-системы без потери качества;
– как обеспечить устойчивость агента к сбоям внешних сервисов без падения всей системы и про многое-многое другое.
📅 Старт: 19 мая.
👥 Спикеры — практики с опытом в AI и Data Science в крупных IT-компаниях, таких как Яндекс, Huawei, МТС и др.
Длительность: 6-12 недель в зависимости от тарифа.
🔗 Программа курса и другие подробности
Мы поговорили с десятками разработчиков ИИ-агентов и сделали отдельный курс по AgentOps.
🧠 На нём вы узнаете:
– как оптимизировать траты на токены;
– как на практике оценить качество работы агента;
– как «докручивать» RAG-системы без потери качества;
– как обеспечить устойчивость агента к сбоям внешних сервисов без падения всей системы и про многое-многое другое.
📅 Старт: 19 мая.
👥 Спикеры — практики с опытом в AI и Data Science в крупных IT-компаниях, таких как Яндекс, Huawei, МТС и др.
Длительность: 6-12 недель в зависимости от тарифа.
🔗 Программа курса и другие подробности
🤯 Представьте, что ваш AI-агент работает так же предсказуемо, как обычный микросервис. Звучит утопически, но это именно то, к чему должна прийти разработка в 2026 году.
Основная боль текущих реализаций — полная непредсказуемость поведения. Сегодня агент выполнил задачу за два шага, а завтра ушёл в рекурсию и потратил все лимиты.
Наш обновлённый курс «Разработка AI-агентов» научит, как приручить этот хаос с помощью
✅ Что вы получите:
— понимание того, как управлять логикой агента на уровне кода;
— навыки работы с
— готовые паттерны для обработки ошибок и галлюцинаций;
— опыт создания систем, которые реально экономят время.
Есть пара мест со скидкой до завтра, решайтесь 👈🏻
Основная боль текущих реализаций — полная непредсказуемость поведения. Сегодня агент выполнил задачу за два шага, а завтра ушёл в рекурсию и потратил все лимиты.
Наш обновлённый курс «Разработка AI-агентов» научит, как приручить этот хаос с помощью
Python и современных фреймворков. Мы не будем учить «общаться» с нейросетью, мы будем строить из неё надёжный инструмент.✅ Что вы получите:
— понимание того, как управлять логикой агента на уровне кода;
— навыки работы с
LangChain и библиотеками оркестрации;— готовые паттерны для обработки ошибок и галлюцинаций;
— опыт создания систем, которые реально экономят время.
Есть пара мест со скидкой до завтра, решайтесь 👈🏻
🥱5❤1
🐳 Фишка Docker CLI
Запустите docker stats с правильными флагами, и вы увидите всё в реальном времени.
🔹 Зачем это нужно
— Показывает live-метрики по CPU, памяти, сети и I/O для всех запущенных контейнеров.
— Критично для Java-сервисов: помогает поймать утечки памяти, GC pressure и неожиданный CPU spike прямо в момент нагрузки.
— Работает без установки каких-либо агентов.
— В отличие от top внутри контейнера видит реальные лимиты cgroup, а не ресурсы хоста.
🔹 Как использовать
— Все контейнеры в реальном времени:
— Конкретный сервис:
— Один снимок без стриминга:
— Только нужные поля:
— В JSON для скриптов:
Флаг --format принимает Go-шаблоны — те же, что и в docker inspect. Можно вывести ровно то, что нужно, и скормить в jq или свой мониторинг-скрипт.
⚠️ Если контейнер запущен без -m / --memory, JVM видит всю память хоста и выставляет heap соответственно. docker stats мгновенно покажет, есть ли лимит — колонка MEM USAGE / LIMIT.
Запустите docker stats с правильными флагами, и вы увидите всё в реальном времени.
🔹 Зачем это нужно
— Показывает live-метрики по CPU, памяти, сети и I/O для всех запущенных контейнеров.
— Критично для Java-сервисов: помогает поймать утечки памяти, GC pressure и неожиданный CPU spike прямо в момент нагрузки.
— Работает без установки каких-либо агентов.
— В отличие от top внутри контейнера видит реальные лимиты cgroup, а не ресурсы хоста.
🔹 Как использовать
— Все контейнеры в реальном времени:
docker stats— Конкретный сервис:
docker stats my-spring-app— Один снимок без стриминга:
docker stats --no-stream— Только нужные поля:
docker stats --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"— В JSON для скриптов:
docker stats --no-stream --format jsonФлаг --format принимает Go-шаблоны — те же, что и в docker inspect. Можно вывести ровно то, что нужно, и скормить в jq или свой мониторинг-скрипт.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1🔥1
Пока одни продолжают спорить «нужен ли AI в разработке», другие уже автоматизируют рутину через цепочки специализированных агентов — и делают это прямо в PHP-проектах.
Свежая статья на Хабре от PHP-разработчика, который прошёл путь от «AI неудобен» до полноценного пайплайна с оркестрацией агентов в продакшене.
Что внутри:
— Почему один большой промпт не работает, и как принцип "один агент — одна ответственность" решает проблему размытия контекста
— Как выстроить цепочку: php-developer → phpstan-developer → php-test-developer → авто-фиксер — каждый в своём чистом контексте
— Specification-Driven Development на практике: спека первична, код вторичен
— Реальный опыт с Claude Code, RooCode, KiloCode — с честными плюсами и минусами
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍1🔥1😁1🥱1
🔥 Настройка Pest PHP
Если ты всё ещё пишешь тесты на чистом PHPUnit с setUp() и простынями $this->assert... — этот пост для тебя. Настраиваем Pest с нуля в реальном Laravel-проекте.
📦 Шаг 1 — Установка
После этого в корне появится tests/Pest.php — файл для глобальных хелперов и настроек. Не игнорируй его.
✍️ Шаг 2 — Первый тест
Забудь про классы. Pest — это функции:
🧩 Шаг 3 — Datasets (параметризованные тесты)
Вместо копипасты одного теста на каждый кейс:
⚙️ Шаг 4 — Глобальные настройки в Pest.php
Открываем tests/Pest.php и настраиваем раз и навсегда:
Теперь RefreshDatabase не нужно писать в каждом файле, а кастомные матчеры делают тесты выразительнее.
🚀 Шаг 5 — Запуск
💡 Почему Pest, а не чистый PHPUnit?
Меньше бойлерплейта, человекочитаемый вывод, встроенные архитектурные тесты (arch()) и отличная интеграция с Laravel. Команда Laravel официально рекомендует его с 11-й версии фреймворка.
Ставьте 🔥 если используете Pest.
Если ты всё ещё пишешь тесты на чистом PHPUnit с setUp() и простынями $this->assert... — этот пост для тебя. Настраиваем Pest с нуля в реальном Laravel-проекте.
📦 Шаг 1 — Установка
composer require pestphp/pest --dev
composer require pestphp/pest-plugin-laravel --dev
php artisan pest:install
После этого в корне появится tests/Pest.php — файл для глобальных хелперов и настроек. Не игнорируй его.
✍️ Шаг 2 — Первый тест
Забудь про классы. Pest — это функции:
it('создаёт пользователя через API', function () {
$response = $this->postJson('/api/users', [
'name' => 'Ivan',
'email' => 'ivan@example.com',
]);
$response->assertCreated();
expect($response->json('data.name'))->toBe('Ivan');
});🧩 Шаг 3 — Datasets (параметризованные тесты)
Вместо копипасты одного теста на каждый кейс:
it('валидирует email', function (string $email) {
$response = $this->postJson('/api/users', [
'email' => $email
]);
$response->assertUnprocessable();
})->with([
'пустой' => [''],
'без собаки' => ['notanemail'],
'только домен' => ['@example.com'],
]);⚙️ Шаг 4 — Глобальные настройки в Pest.php
Открываем tests/Pest.php и настраиваем раз и навсегда:
uses(
Tests\TestCase::class,
Illuminate\Foundation\Testing\RefreshDatabase::class,
)->in('Feature');
expect()->extend('toBeSuccess', function () {
return $this->toMatchArray([
'status' => 'success'
]);
});
Теперь RefreshDatabase не нужно писать в каждом файле, а кастомные матчеры делают тесты выразительнее.
🚀 Шаг 5 — Запуск
./vendor/bin/pest
./vendor/bin/pest --filter="создаёт пользователя"
./vendor/bin/pest --coverage # требует Xdebug или PCOV
Меньше бойлерплейта, человекочитаемый вывод, встроенные архитектурные тесты (arch()) и отличная интеграция с Laravel. Команда Laravel официально рекомендует его с 11-й версии фреймворка.
Ставьте 🔥 если используете Pest.
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱11🔥6❤1👍1😁1
🐳 Фишка Docker CLI
Контейнер запустился, но ведёт себя странно — не то сетевое окружение, не те переменные, непонятно что вообще внутри? Просто запустите docker inspect, и у вас будет полная картина без лишних инструментов.
🔹 Зачем это нужно
— Возвращает полный JSON с внутренностями: переменные окружения, тома, сетевые настройки, лимиты ресурсов, entrypoint, restart policy.
— Работает не только с контейнерами — понимает образы, тома и сети.
— Незаменимо, когда нужно быстро понять, почему контейнер ведёт себя не так, как ожидается.
🔹 Как использовать
— Полный дамп:
— Только IP-адрес:
— Все переменные окружения:
— Смонтированные тома:
Флаг -f принимает Go-шаблоны — вытащите ровно то поле, которое нужно, без парсинга тысячи строк JSON вручную.
Контейнер запустился, но ведёт себя странно — не то сетевое окружение, не те переменные, непонятно что вообще внутри? Просто запустите docker inspect, и у вас будет полная картина без лишних инструментов.
🔹 Зачем это нужно
— Возвращает полный JSON с внутренностями: переменные окружения, тома, сетевые настройки, лимиты ресурсов, entrypoint, restart policy.
— Работает не только с контейнерами — понимает образы, тома и сети.
— Незаменимо, когда нужно быстро понять, почему контейнер ведёт себя не так, как ожидается.
🔹 Как использовать
— Полный дамп:
docker inspect my-container— Только IP-адрес:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container— Все переменные окружения:
docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' my-container— Смонтированные тома:
docker inspect -f '{{json .Mounts}}' my-container | jqФлаг -f принимает Go-шаблоны — вытащите ровно то поле, которое нужно, без парсинга тысячи строк JSON вручную.
❤4🔥3👍2
Исследование облачных платформ
Apple Hills Digital собирает мнения специалистов об инфраструктуре: облака, гибридные решения, on-premise.
Можно пройти короткий отбор (~3 минуты) и попасть в основную часть исследования.
Дополнительно — участие в розыгрыше iPhone*
* Принимая участие в опросе Вы становитесь участником розыгрыша под наименованием «Если ты работаешь в IT, пройди опрос и выиграй iPhone 17 Pro». Информация об организаторе розыгрыша, сроках проведения, правилах проведения розыгрыша, количестве призов, сроках, месте, порядке получения призов размещена по ссылке.
Apple Hills Digital собирает мнения специалистов об инфраструктуре: облака, гибридные решения, on-premise.
Можно пройти короткий отбор (~3 минуты) и попасть в основную часть исследования.
Дополнительно — участие в розыгрыше iPhone*
* Принимая участие в опросе Вы становитесь участником розыгрыша под наименованием «Если ты работаешь в IT, пройди опрос и выиграй iPhone 17 Pro». Информация об организаторе розыгрыша, сроках проведения, правилах проведения розыгрыша, количестве призов, сроках, месте, порядке получения призов размещена по ссылке.
❤1
Forwarded from Библиотека задач по PHP | тесты, код, задания
Какова временная сложность сортировки слиянием (Merge Sort) в худшем случае?
Anonymous Quiz
15%
O(log n)
35%
O(n^2)
10%
O(n)
40%
O(n log n)
🔥3👍1🥱1
⚡️ array_walk и внешний контекст
Многие не используют третий аргумент array_walk — а зря.
Третий аргумент — проброс внешних данных прямо в коллбэк. Не нужен use, не нужна глобальная переменная.
Читается чище, зависимости явные и сразу видно, что коллбэк работает с $discounts.
🐸 Библиотека пхпшника
#vardump
Многие не используют третий аргумент array_walk — а зря.
$discounts = ['vip' => 0.3, 'regular' => 0.1];
$prices = ['vip' => 1000, 'regular' => 500];
array_walk($prices, function (&$price, $key, $discounts) {
$price -= $price * ($discounts[$key] ?? 0);
}, $discounts);
// ['vip' => 700, 'regular' => 450]
Третий аргумент — проброс внешних данных прямо в коллбэк. Не нужен use, не нужна глобальная переменная.
Читается чище, зависимости явные и сразу видно, что коллбэк работает с $discounts.
#vardump
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1
🤔 Repository в Laravel: паттерн или антипаттерн?
Eloquent — это Active Record. Когда ты оборачиваешь его в репозиторий и возвращаешь User::where(...)->get(), ты не абстрагируешься от ORM. Ты просто перекладываешь Eloquent в другой класс.
Настоящий репозиторий возвращает доменные объекты, а не модели с методами ->save() и ->delete().
💬 Что думаете?
🐸 Библиотека пхпшника
#междусобойчик
Eloquent — это Active Record. Когда ты оборачиваешь его в репозиторий и возвращаешь User::where(...)->get(), ты не абстрагируешься от ORM. Ты просто перекладываешь Eloquent в другой класс.
Настоящий репозиторий возвращает доменные объекты, а не модели с методами ->save() и ->delete().
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👏5👍3😁1
🦾 Надоело чинить «упавших» ИИ-агентов после каждого микросбоя внешних сервисов?
Анонсируем старт продаж большого курса по AgentOps. Мы собрали опыт десятков разработчиков и сделали программу, которая учит выводить ИИ в стабильный прод.
🗓 Ждем вас 28 апреля в 19:00 МСК на эфире: «Как эффективно управлять контекстным окном LLM в мультиагентных системах и не сливать бюджет на токены».
👉 Кто вещает и в чем польза?
Спикер Кирилл Кухарев (Senior AI Engineer в Raft, спикер AI Conf и Highload++). Он реализовал более 50 коммерческих проектов в GenAI и на вебинаре покажет, как взять под контроль работу нескольких агентов, чтобы они не перекидывали друг другу лишний контекст и не сжигали ваши деньги.
В прямом эфире разберем:
• Как формируется контекст в LLM при маршрутизации между агентами;
• Куда утекают лишние токены и возникает перерасход;
• Практические методы: как сжимать историю, грамотно делить задачи, лимитировать передачу контекста и собирать промпты прямо в процессе запроса пользователя.
🔥 Два способа получить максимум:
1. Приходите на вебинар 28 апреля. Дарим участникам промокод на 5.000 ₽ (работает 3 дня после эфира - это шанс забрать курс по самому низу рынка).
2. Выбирайте Инженерный трек. В подарок к нему идет полный доступ к записям и автопроверкам завершенного курса «Разработка ИИ-агентов».
👉 Занять место на вебинаре и стать профи в AgentOps
Анонсируем старт продаж большого курса по AgentOps. Мы собрали опыт десятков разработчиков и сделали программу, которая учит выводить ИИ в стабильный прод.
🗓 Ждем вас 28 апреля в 19:00 МСК на эфире: «Как эффективно управлять контекстным окном LLM в мультиагентных системах и не сливать бюджет на токены».
Спикер Кирилл Кухарев (Senior AI Engineer в Raft, спикер AI Conf и Highload++). Он реализовал более 50 коммерческих проектов в GenAI и на вебинаре покажет, как взять под контроль работу нескольких агентов, чтобы они не перекидывали друг другу лишний контекст и не сжигали ваши деньги.
В прямом эфире разберем:
• Как формируется контекст в LLM при маршрутизации между агентами;
• Куда утекают лишние токены и возникает перерасход;
• Практические методы: как сжимать историю, грамотно делить задачи, лимитировать передачу контекста и собирать промпты прямо в процессе запроса пользователя.
🔥 Два способа получить максимум:
1. Приходите на вебинар 28 апреля. Дарим участникам промокод на 5.000 ₽ (работает 3 дня после эфира - это шанс забрать курс по самому низу рынка).
2. Выбирайте Инженерный трек. В подарок к нему идет полный доступ к записям и автопроверкам завершенного курса «Разработка ИИ-агентов».
👉 Занять место на вебинаре и стать профи в AgentOps
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1😁1
Сколько среди нас
Понятно, что грейд — довольно относительная история, но примерно ваш грейд:
🔥 — Senior
👍🏼 — Middle
❤️ — Junior
😁 — Ещё учусь
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥92👍79😁19❤17👾6
🏃♀️ Уже завтра стартует курс по разработке AI-агентов.
Про AI-агентов часто думают, что это просто модная обертка над джпт для пет-проектов. Кажется, прикрутил API к скрипту и типа готово. А вот и нет! Когда дело доходит до прода, начинаются настоящие проблемы.
Эту инженерную часть мы и будем разбирать на курсе. Будем учиться интегрировать внешние API, работать с RAG, LangGraph, CrewAI и деплоить всё это так, чтобы работало как часы.
Стартуем завтра. Для участия и доступа к программе переходите по ссылке.
Про AI-агентов часто думают, что это просто модная обертка над джпт для пет-проектов. Кажется, прикрутил API к скрипту и типа готово. А вот и нет! Когда дело доходит до прода, начинаются настоящие проблемы.
Зачем глубоко копать мультиагентные системы, если можно обойтись старым добрым кодом? Как контролировать расходы на токены, чтобы новая фича не разорила бизнес? Как заставить агента работать стабильно и предсказуемо, а не галлюцинировать?
Эту инженерную часть мы и будем разбирать на курсе. Будем учиться интегрировать внешние API, работать с RAG, LangGraph, CrewAI и деплоить всё это так, чтобы работало как часы.
Стартуем завтра. Для участия и доступа к программе переходите по ссылке.
🥱1