Forwarded from Библиотека собеса по PHP | вопросы с собеседований
Пользователь нажал «Повторить заказ». Цены в его старом заказе изменились.
📦 Задание
Фича: кнопка «Повторить заказ» в личном кабинете. Копирует предыдущий заказ, применяет промокод, создаёт новый черновик. Оригинал помечается флагом repeated для аналитики.
Через неделю — тикет от бухгалтерии: суммы в старых заказах не сходятся с тем, что было при оплате. Проблема только у заказов, которые хотя бы раз «повторяли». Суммы занижены ровно на размер скидки по промокоду.
// src/Order/Order.php
class Order
{
public function __construct(
private ?int $id,
private int $userId,
private array $items,
private string $status,
private bool $repeated = false,
) {}
public function getId(): ?int { return $this->id; }
public function getItems(): array { return $this->items; }
public function getStatus(): string { return $this->status; }
public function resetForRepeat(): void
{
$this->id = null;
$this->status = 'draft';
$this->repeated = false;
}
public function markAsRepeated(): void
{
$this->repeated = true;
}
public function calculateTotal(): int
{
return array_sum(array_map(
fn(OrderItem $i) => $i->getSubtotal(),
$this->items
));
}
}
// src/Order/OrderItem.php
class OrderItem
{
public function __construct(
private int $productId,
private int $qty,
private int $price,
) {}
public function getProductId(): int { return $this->productId; }
public function getQty(): int { return $this->qty; }
public function getPrice(): int { return $this->price; }
public function getSubtotal(): int
{
return $this->qty * $this->price;
}
public function applyDiscount(int $percent): void
{
$this->price = (int) round(
$this->price * (1 - $percent / 100)
);
}
}
// src/Order/RepeatOrderHandler.php
class RepeatOrderHandler
{
public function __construct(
private OrderRepository $orders,
private PromoService $promo,
) {}
public function handle(int $originalId, ?string $promoCode): Order
{
$original = $this->orders->findById($originalId);
$copy = clone $original;
$copy->resetForRepeat();
if ($promoCode !== null) {
$discount = $this->promo->resolve($promoCode);
foreach ($copy->getItems() as $item) {
$item->applyDiscount($discount->percent);
}
}
$this->orders->save($copy);
$original->markAsRepeated();
$this->orders->save($original);
return $copy;
}
}
// src/Repository/OrderRepository.php
class OrderRepository
{
public function __construct(private PDO $pdo) {}
public function save(Order $order): void
{
if ($order->getId() === null) {
$this->insert($order);
} else {
$this->update($order);
}
}
private function update(Order $order): void
{
$this->pdo->prepare(
'UPDATE orders SET status = ?, repeated = ? WHERE id = ?'
)->execute([$order->getStatus(), (int) $order->isRepeated(), $order->getId()]);
$this->pdo->prepare('DELETE FROM order_items WHERE order_id = ?')
->execute([$order->getId()]);
foreach ($order->getItems() as $item) {
$this->pdo->prepare(
'INSERT INTO order_items (order_id, product_id, qty, price) VALUES (?, ?, ?, ?)'
)->execute([$order->getId(), $item->getProductId(), $item->getQty(), $item->getPrice()]);
}
}
}
🔹 Задачи
— Объяснить, каким образом цены в оригинальном заказе оказались изменены в базе
— Исправить код так, чтобы оригинал гарантированно не мутировал
Ставьте → 🔥 если нравится формат. Если нет → 🌚
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19👍2👏1
🔧 Работаем с kubectl
Под завис в Pending, а вы не знаете почему. Нет ресурсов, не тот nodeSelector или PVC не биндится? kubectl describe pod покажет секцию Events — там Kubernetes прямым текстом пишет причину.
🔹 Зачем это нужно
— Events содержат сообщения от scheduler, kubelet и controller manager.
— Показывает FailedScheduling с причиной: Insufficient cpu, node affinity mismatch, и т.д.
— Видны ошибки pull-а образов, mount томов, readiness/liveness probe failures.
🔹 Как использовать
— Полное описание пода:
— Смотреть только Events (хак):
— События всего неймспейса:
— Только warning-и:
— Следить за новыми:
💡 Events живут только 1 час по умолчанию. Если под висит в Pending давно и Events пустые, посмотрите
Под завис в Pending, а вы не знаете почему. Нет ресурсов, не тот nodeSelector или PVC не биндится? kubectl describe pod покажет секцию Events — там Kubernetes прямым текстом пишет причину.
🔹 Зачем это нужно
— Events содержат сообщения от scheduler, kubelet и controller manager.
— Показывает FailedScheduling с причиной: Insufficient cpu, node affinity mismatch, и т.д.
— Видны ошибки pull-а образов, mount томов, readiness/liveness probe failures.
🔹 Как использовать
— Полное описание пода:
kubectl describe pod my-pod— Смотреть только Events (хак):
kubectl describe pod my-pod | grep -A 20 "Events:"— События всего неймспейса:
kubectl get events --sort-by='.lastTimestamp'— Только warning-и:
kubectl get events --field-selector type=Warning— Следить за новыми:
kubectl get events -w💡 Events живут только 1 час по умолчанию. Если под висит в Pending давно и Events пустые, посмотрите
kubectl get events -A --sort-by='.lastTimestamp', возможно, событие уже из другого неймспейса.👍2🔥1😁1
😎 Знакомьтесь с экспертом Proglib.academy: AI-архитектор Андрей Носов
Андрей — один из ключевых спикеров нашего курса AgentOps. Он выстраивает архитектуру, которая выживает в суровом проде и активно делится своим опытом.
За что его ценит IT-комьюнити:
🟣 Топ-спикер AI Conf 2026
🟣 Эксперт по GraphRAG и Knowledge Graphs
🟣 Автор «14 кругов ада для RAG»
🟣 Спикер Saint HighLoad
Андрей упаковал свои наработки в Google Colab, где можно пощупать 14 сценариев ошибок RAG и их решения:
🔗 Забрать Colab-ноутбук
На курсе Андрей отвечает за самые «мясные» блоки: RAG, оркестрацию агентов и их промышленную эксплуатацию.
Узнать больше о программе и обучении у Андрея:
👉 Курс о том, как внедрять AI-логику в бэкенд и сохранять стабильность сервиса
Так, продолжаем знакомить вас с командой?
👍 — Да, ждем новых лиц
🔥 — Пойду тестить Colab Носова
Андрей — один из ключевых спикеров нашего курса AgentOps. Он выстраивает архитектуру, которая выживает в суровом проде и активно делится своим опытом.
За что его ценит IT-комьюнити:
Его доклад про мифы семантического поиска и провалы Naive RAG стал одним из самых рейтинговых на конференции.
Андрей внедряет инженерный подход в сложные системы, заменяя «слепую веру» в эмбеддинги строгой логикой графов.
Разработал уникальный набор из 14 unit-тестов, на которых ломается стандартный векторный поиск (от слепоты к отрицаниям до конфликта версий).
Регулярно выступает на крупнейших хайлоад-площадках, разбирая архитектуру отказоустойчивых ИИ-сервисов.
Андрей упаковал свои наработки в Google Colab, где можно пощупать 14 сценариев ошибок RAG и их решения:
🔗 Забрать Colab-ноутбук
На курсе Андрей отвечает за самые «мясные» блоки: RAG, оркестрацию агентов и их промышленную эксплуатацию.
Узнать больше о программе и обучении у Андрея:
👉 Курс о том, как внедрять AI-логику в бэкенд и сохранять стабильность сервиса
Так, продолжаем знакомить вас с командой?
👍 — Да, ждем новых лиц
🔥 — Пойду тестить Colab Носова
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🔥 Еще с Laravel 8 появился Prunable
С его помощью вы можете удалять старые модели по расписанию. Вам больше не нужно писать пользовательские команды.
Библиотека пхпшника
#vardump
С его помощью вы можете удалять старые модели по расписанию. Вам больше не нужно писать пользовательские команды.
Библиотека пхпшника
#vardump
👍6🔥5🥱3
🚀 Laravel 13.6.0: дебаунс для очередей из коробки
Частое сохранение документа плодит в очереди дублирующиеся задачи переиндексации. Раньше спасал интерфейс ShouldBeUnique, который блокирует диспатчи на входе. Теперь добавлен полноценный debounce — выполняется только последняя задача.
Достаточно повесить атрибут на класс, и все дубли в заданном временном окне схлопываются на этапе выполнения:
Запустить дебаунс можно и без правки класса: dispatch(new SyncData($id))->debounceFor(30).
Другие обновления релиза:
— роут /up отдает JSON по заголовку Accept (полезно для балансировщиков);
— добавлен JsonFormatter для структурных логов;
— появился транспорт Cloudflare Email.
🔗 Читать подробнее
Библиотека пхпшника
#release_radar
Частое сохранение документа плодит в очереди дублирующиеся задачи переиндексации. Раньше спасал интерфейс ShouldBeUnique, который блокирует диспатчи на входе. Теперь добавлен полноценный debounce — выполняется только последняя задача.
Достаточно повесить атрибут на класс, и все дубли в заданном временном окне схлопываются на этапе выполнения:
#[DebounceFor(30, maxWait: 120)]
class RebuildSearchIndex implements ShouldQueue
{
public function __construct(public int $documentId) {}
public function debounceId(): string
{
return (string) $this->documentId;
}
public function handle(): void
{
SearchIndex::rebuild($this->documentId);
}
}
Запустить дебаунс можно и без правки класса: dispatch(new SyncData($id))->debounceFor(30).
Другие обновления релиза:
— роут /up отдает JSON по заголовку Accept (полезно для балансировщиков);
— добавлен JsonFormatter для структурных логов;
— появился транспорт Cloudflare Email.
Библиотека пхпшника
#release_radar
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤2🔥1👏1
🔥 База по экономике токенов и кэшированию от AI Platform Lead из Bitrix24
Знакомьтесь, Сергей Нотевский. AI Platform Lead в Bitrix24.
Он один из ключевых экспертов нашего курса AgentOps. На своих лекциях он детально разбирает экономику AI-агентов, кэширование токенов, LLM-инфраструктуру и вывод генеративных систем в стабильный прод.
Мы попросили Сергея поделиться материалами для тех, кто хочет оптимизировать косты на LLM в проде. Сохраняйте методичку по prefix cache метрике, которая напрямую влияет на ваши деньги.
Как говорят создатели Manus:
🛠 Что внутри методички (комбо из 3 статей + код):
🍒 Вишенка на торте: готовый SKILL для агента, который делает ревью вашего проекта, находит анти-паттерны и предотвращает низкое попадание в кэш.
— Забрать комбо-материалы на GitHub
P.S. Если хотите послушать Сергея вживую — ловите его на конференциях Kode Waves (май), Conversations AI и Highload Spb (июнь).
🎁 Акция в честь старта продаж!
Прямо сейчас при покупке Инженерного трека вы получаете полный доступ к материалам курса «Разработка ИИ-агентов» в подарок.
👉 Забрать 2 курса по цене 1 и начать обучение
Знакомьтесь, Сергей Нотевский. AI Platform Lead в Bitrix24.
Он один из ключевых экспертов нашего курса AgentOps. На своих лекциях он детально разбирает экономику AI-агентов, кэширование токенов, LLM-инфраструктуру и вывод генеративных систем в стабильный прод.
Мы попросили Сергея поделиться материалами для тех, кто хочет оптимизировать косты на LLM в проде. Сохраняйте методичку по prefix cache метрике, которая напрямую влияет на ваши деньги.
Как говорят создатели Manus:
“KV-cache hit rate is the single most important metric for a production-stage AI agent.”
🛠 Что внутри методички (комбо из 3 статей + код):
Экономика кэширования — особенности провайдеров и как правильно считать затраты.
Частые анти-паттерны — почему ваш кэш постоянно сбрасывается и вы платите больше.
Кэш в AI-агентах — специфика работы с памятью в автономных системах.
🍒 Вишенка на торте: готовый SKILL для агента, который делает ревью вашего проекта, находит анти-паттерны и предотвращает низкое попадание в кэш.
— Забрать комбо-материалы на GitHub
P.S. Если хотите послушать Сергея вживую — ловите его на конференциях Kode Waves (май), Conversations AI и Highload Spb (июнь).
🎁 Акция в честь старта продаж!
👉 Забрать 2 курса по цене 1 и начать обучение
🥱3
⚔️ nwidart vs internachi
Считается, что internachi/modular быстрее nwidart/laravel-modules, потому что тащит модули через нативный Composer, а не сканирует module.json. При прогоне 50 запросов на батч от 25 до 200 модулей на Laravel 13 / PHP 8.4 — и цифры рушат это утверждение.
⚡️ Что показал замер с OPcache ON:
— на 25–175 модулях nWidart стабильно быстрее по бутстрапу (+12 мс на каждые 25 модулей, линейно);
— у internachi на 75–100 модулях нелинейный спайк от резолва classmap;
— перелом наступает только на 200 модулях, где modules:cache даёт 621 мс против 1521 мс у nWidart — в 2.4 раза быстрее;
— по памяти internachi выигрывает всегда: на 10–12 МБ меньше на запрос (registry nWidart живёт в куче, classmap — в shared memory OPcache).
OPcache режет время бута у internachi на ~49%, у nWidart — только на ~33%. Логично: байткод кэшируется, а чтение module.json на каждом запросе — нет.
📊 Инженерный вывод: до 50 модулей разница в пределах шума, можно руководствоваться удобством DX. На 50–175 nWidart предсказуемее, а свыше 175 спасает только internachi с modules:cache, иначе линейный скан сильно замедлит работу.
🔗 Репа с данными
Считается, что internachi/modular быстрее nwidart/laravel-modules, потому что тащит модули через нативный Composer, а не сканирует module.json. При прогоне 50 запросов на батч от 25 до 200 модулей на Laravel 13 / PHP 8.4 — и цифры рушат это утверждение.
⚡️ Что показал замер с OPcache ON:
— на 25–175 модулях nWidart стабильно быстрее по бутстрапу (+12 мс на каждые 25 модулей, линейно);
— у internachi на 75–100 модулях нелинейный спайк от резолва classmap;
— перелом наступает только на 200 модулях, где modules:cache даёт 621 мс против 1521 мс у nWidart — в 2.4 раза быстрее;
— по памяти internachi выигрывает всегда: на 10–12 МБ меньше на запрос (registry nWidart живёт в куче, classmap — в shared memory OPcache).
OPcache режет время бута у internachi на ~49%, у nWidart — только на ~33%. Логично: байткод кэшируется, а чтение module.json на каждом запросе — нет.
📊 Инженерный вывод: до 50 модулей разница в пределах шума, можно руководствоваться удобством DX. На 50–175 nWidart предсказуемее, а свыше 175 спасает только internachi с modules:cache, иначе линейный скан сильно замедлит работу.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔2🔥1
Основная компетенция специалиста по Data Science – способность анализировать и интерпретировать данные, а математика является фундаментом для начала работы.
В карточках мы разбираем основные разделы математики, с которых стоит начать изучение специалисту по анализу данных.
Хотите подготовиться к офферу или подтянуть знания? Оставляйте заявку на наш курс по математике для Data Science 💙
P.S. Только до 31 мая на курс (и вообще на все программы Академии) действует
А как у вас дела с высшей математикой?
❤️ — Помню всё
🔥 — Знаю основы
🌚 — Ничего не знаю
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Forwarded from Библиотека задач по PHP | тесты, код, задания
Какой из перечисленных алгоритмов хэширования поддерживается функцией password_hash()?
Anonymous Quiz
31%
bcrypt
10%
md5
18%
sha256
41%
Все перечисленные
👍2🔥1👏1
🔍 Ловим каждый SQL-запрос в Laravel
Дебажить «а что вообще улетело в базу?» зачастую непросто. Но через DB::listen() можно перехватить каждый запрос вместе с биндингами и временем выполнения.
По сути, это не только про дебаг. Можно слать алерт в Slack, если запрос тормозит дольше порога. А для полного лога сессии есть связка DB::enableQueryLog() + DB::getRawQueryLog().
Кто-нибудь использует это в проде (или только whenQueryingForLongerThan)?
Библиотека пхпшника
Дебажить «а что вообще улетело в базу?» зачастую непросто. Но через DB::listen() можно перехватить каждый запрос вместе с биндингами и временем выполнения.
DB::listen(function (QueryExecuted $query) {
dump($query->sql); // select * from `users` where `id` = ? limit 1
dump($query->bindings); // [0 => 1]
dump($query->time); // 6.05 (ms)
});По сути, это не только про дебаг. Можно слать алерт в Slack, если запрос тормозит дольше порога. А для полного лога сессии есть связка DB::enableQueryLog() + DB::getRawQueryLog().
Кто-нибудь использует это в проде (или только whenQueryingForLongerThan)?
Библиотека пхпшника
👍4❤1🔥1
Я не говорю, что книга плохая. Я говорю, что она принесла массовому разработчику больше вреда, чем пользы.
Uncle Bob написал набор рекомендаций, а индустрия превратила их в религию. «Метод не длиннее 5 строк». «Каждый класс — одна ответственность». «Имя должно быть самодокументирующим». Звучит красиво, а на практике:
— 47 приватных методов, каждый вызывается ровно один раз
— AbstractNotificationStrategyProviderFactory
— 6 слоёв абстракции ради эндпоинта, который возвращает список товаров
— Интерфейс с единственной реализацией «на будущее»
Такие проекты всегда «чистые». И на каждом из них новый разработчик тратит две недели, чтобы найти бизнес-логику.
Откройте исходники любого успешного фреймворка в вашей экосистеме. God-классы, методы на 80 строк, комменты «don't ask why». Работает, развивается, приносит деньги.
Моё мнение:
→ Код должен быть понятен через 6 месяцев. Не «чист» — а понятен.
→ Абстракция оправдана, когда у неё больше одной реализации прямо сейчас, а не «потенциально».
→ YAGNI важнее SOLID.
Книгу стоит прочитать, принять к сведению, понять фундаментальные основы. Но не применять подходы в каждом методе.
Please open Telegram to view this post
VIEW IN TELEGRAM
💯26👍3😁3❤1😢1
🔧 Работаем с kubectl
Нужно быстро форварднуть порт сервиса из Kubernetes на localhost для отладки? kubectl port-forward — ваш туннель в кластер без Ingress, LoadBalancer и VPN.
🔹 Зачем это нужно
— Доступ к сервисам внутри кластера без внешнего endpoint-а.
— Подключение к БД, Redis, RabbitMQ для отладки прямо с рабочей машины.
— Не нужно менять конфиги, создавать NodePort или разворачивать Ingress.
🔹 Как использовать
— К поду:
— К сервису:
— К деплойменту:
— Другой локальный порт:
— Слушать на всех интерфейсах:
Нужно быстро форварднуть порт сервиса из Kubernetes на localhost для отладки? kubectl port-forward — ваш туннель в кластер без Ingress, LoadBalancer и VPN.
🔹 Зачем это нужно
— Доступ к сервисам внутри кластера без внешнего endpoint-а.
— Подключение к БД, Redis, RabbitMQ для отладки прямо с рабочей машины.
— Не нужно менять конфиги, создавать NodePort или разворачивать Ingress.
🔹 Как использовать
— К поду:
kubectl port-forward pod/my-pod 8080:80— К сервису:
kubectl port-forward svc/my-service 5432:5432— К деплойменту:
kubectl port-forward deploy/my-app 3000:3000— Другой локальный порт:
kubectl port-forward svc/postgres 15432:5432 (localhost:15432 → postgres:5432)— Слушать на всех интерфейсах:
kubectl port-forward --address 0.0.0.0 svc/my-service 8080:80👍4❤1🔥1