Резюме — це не автобіографія і не список технологій, які ви колись бачили. Це документ, який має пройти два різні фільтри: рекрутера, який дивиться на нього близько хвилини і шукає збіг із вакансією, і техліда, який відкриває його перед співбесідою і шукає, за що зачепитись питаннями. Ці двоє читають різні речі, і резюме має обслуговувати обох, не перетворюючись на два документи.
Нижче — те, що реально впливає на рішення «запросити чи ні», з боку людини, яка проводить технічні співбесіди на PHP.
Перший екран вирішує все інше
Верхні 10–12 рядків — це весь ваш бюджет уваги на першому проході. Вони мають відповісти на чотири питання без прокручування:
- Хто ви за роллю і рівнем. «PHP/Laravel developer, 5 років» — це відповідь. «Спеціаліст з розробки програмного забезпечення» — ні.
- Основний стек з версіями. Не перелік усього, а те, на чому ви працювали останній рік.
- Формат і локація. Місто/часовий пояс, віддалено чи гібрид, чи готові до релокації. Це найчастіша причина, чому переписка вмирає на третьому листі.
- Контакти, які працюють. Пошта, Telegram або LinkedIn, посилання на GitHub. Телефон — за бажанням, але тоді реальний.
Що на першому екрані не потрібно: фото, вік, сімейний стан, «стресостійкість», «націленість на результат» і шкали з зафарбованими зірочками навпроти кожної технології. Зірочки нічого не означають: ваші чотири зірки з п'яти за Symfony і мої чотири — це різні речі, і жоден інтервʼюер не буде їх звіряти.
Замість блоку «Про себе» на пʼять речень працює одне-два, які фіксують спеціалізацію і тип задач:
Бекенд-розробник, 5 років на PHP. Останні три роки — Laravel-моноліт із чергами й інтеграціями платіжних провайдерів: домен, API, фонова обробка, підтримка в проді. Люблю задачі, де треба розібратися, чому воно повільне.
Це не маркетинг, це фільтр. Людина, яка шукає фронтенд-важкого фулстека, одразу зрозуміє, що ви не той кандидат, — і добре.
Стек: версії, роль, чесність
Найпоширеніша помилка — перелік з тридцяти позицій, де PHP, MySQL, HTML, Docker, Kubernetes, RabbitMQ, React і Figma лежать через кому в один рядок. Такий блок не читають: він не дає інформації, бо в ньому все однаково важливе, тобто нічого.
Робочий варіант — згрупувати і показати глибину:
- Мова: PHP 8.3/8.4,
declare(strict_types=1), типізовані властивості, enum, readonly-класи. - Фреймворки: Laravel 12 (черги, події, Eloquent, Filament), Symfony 6.4 LTS — підтримка legacy-сервісу.
- Бази: PostgreSQL 16 — схема, індекси, читання
EXPLAIN (ANALYZE, BUFFERS); MySQL 8 — на попередньому проєкті. - Якість: Pest/PHPUnit, PHPStan (level 8 на домені, level 5 на решті), Pint, Rector.
- Інфраструктура: Docker Compose локально, GitHub Actions, Redis, Nginx + php-fpm; деплой — не мій, але читаю пайплайн і вмію його полагодити.
Версії — не формальність. Графік підтримки на php.net публічний: 8.1 не отримує навіть security-фіксів із кінця 2025 року, у 8.2 security-підтримка добігає кінця 2026-го, актуальні гілки — 8.3 і 8.4. Рядок «PHP 8.1» у резюме в 2026 році нічого не псує, але одразу задає інтервʼюеру питання: це ваш реальний прод чи ви просто не оновлювали текст? Якщо прод справді на старій гілці — так і напишіть, це нормальна ситуація, і розмова про те, що заважає оновитись, часто цікавіша за сам стек.
Останній рядок про деплой — важливіший, ніж здається. Позначена межа («це робив я», «це поруч зі мною, я в курсі») знімає половину незручних моментів на співбесіді. Написати Kubernetes, бо він був у кластері, куди їздив ваш код, — найшвидший спосіб отримати пʼять питань про те, чого ви не робили.
Досвід: задача → рішення → наслідок
Найгірший формат опису місця роботи — перелік обовʼязків: «розробка нового функціоналу», «виправлення багів», «код-рев'ю», «взаємодія з командою». Це справедливо для будь-якого розробника на планеті й тому не несе інформації.
Робоча одиниця — пункт із трьох частин: що було не так, що ви зробили, що з цього вийшло.
Каталог із фільтрами віддавав список за 6–8 с на піку. Розібрав час по складових (TTFB, PHP, база), знайшов N+1 у рендері карток і відсутній складений індекс під фільтр за категорією і статусом. Додав
with()для звʼязків, індекс і кешування агрегатів із інвалідацією на подію оновлення товару — сторінка стабільно вкладається в 800 мс.
Про цифри — просте правило: наводьте лише ті, які ви памʼятаєте і можете пояснити. Питання «а чим ви це міряли?» ставлять майже завжди, і відповідь «Debugbar показував» цілком нормальна, а от «прискорив систему на 300%» без відповіді, що саме прискорилось і відносно чого, гарантовано перетворює сильний пункт на слабкий. Якщо чисел немає — пишіть наслідок якісно: «прибрали ручний ретрай платежів, служба підтримки перестала робити це руками».
Два-три таких пункти на місце роботи краще за десять рядків обовʼязків. Для позицій, старших за пʼять років, достатньо назви компанії, ролі, дат і одного рядка контексту — деталі там уже нікого не цікавлять.
І окремо про масштаб: «висока навантаженість» — порожнє слово. Конкретика типу «~40 тис. активних користувачів, близько 500 фонових джобів на хвилину в піку» дає інтервʼюеру опору. Але тільки якщо ви ці числа справді бачили в моніторингу, а не оцінили на око.
Що видно з вашого репозиторію за тридцять секунд
Якщо в резюме є посилання на GitHub, його відкриють — і не читатимуть увесь код. Відкриють один-два файли з найпоказовішими назвами: контролер, сервіс, міграцію. Ось приблизно те, що бачить рецензент і що з цього читає:
// Варіант, який читається як «написав, поки працює»
public function store(Request $request)
{
$order = Order::create($request->all());
Mail::to($request->email)->send(new OrderCreated($order));
return redirect('/orders/'.$order->id);
}
Тут чотири речі одразу: $request->all() замість валідованих даних (mass assignment живе рівно тут), синхронна відправка листа всередині HTTP-запиту, відсутні типи параметрів і повернення, захардкоджений URL. Жодна з них не «помилка новачка» сама по собі — разом вони дають рівень.
// Той самий сценарій, написаний так, як його чекають від middle+
public function store(StoreOrderRequest $request, PlaceOrder $placeOrder): RedirectResponse
{
$order = $placeOrder(OrderDraft::fromRequest($request->validated()));
return redirect()->route('orders.show', $order);
}
Валідація винесена у Form Request, бізнес-сценарій — в окремий викликуваний клас (його можна запустити з консольної команди чи з джоби), лист відправляє слухач події в черзі, маршрут іменований, типи проставлені. Це не «краса заради краси» — кожен пункт тут прибирає конкретний клас проблем, і на співбесіді ви зможете назвати який.
Практичний висновок: якщо репозиторій у резюме є, він має бути тим, який ви готові захищати. Один невеликий проєкт із README, composer.json із зафіксованими версіями, тестами й налаштованим CI кращий за десять форків і незакінчених навчальних робіт. Порожній профіль GitHub — не мінус; профіль із трьома «hello world» — мінус.
Формат файлу і дрібниці, які коштують відповіді
- PDF з текстовим шаром. Не скан, не картинка, не посилання на Google Docs із закритим доступом. Багато компаній заливають резюме в систему обліку кандидатів, а вона витягує текст; двоколонкові макети, таблиці, текст у графічних блоках і піктограми замість підписів витягуються погано або перемішуються.
- Одна колонка, звичайні шрифти. Дизайнерські шаблони з бічною панеллю виглядають добре у превʼю і розсипаються при парсингу.
- Назва файлу — ваша.
Ivanenko_PHP_Developer.pdfзамістьresume_final_v3(2).pdf. Це дрібниця, але ваш файл лежатиме в теці серед сотні інших. - Дві сторінки — стеля для більшості випадків. Три сторінки означають, що ви не вирішили, що важливо, і перекладаєте це рішення на читача.
- Мова. Українська для локального ринку, англійська — якщо цілитесь в іноземні компанії або продуктові команди з англомовною комунікацією. Дві версії, не суржик з обох. Технічні терміни залишайте англійською: «черги», але
Laravel Horizon, а не «Ларавел Гарайзон». - Дати без дірок. Пропуски в кілька місяців ніхто не рахує, але рік без пояснення викликає питання, яке краще зняти одним рядком, ніж на дзвінку.
Адаптація під вакансію — це не переписування
Повністю переписувати резюме під кожну вакансію не треба й шкідливо: ви витратите вечір і почнете додавати те, чого не робили. Але два дешеві рухи дають найбільший ефект.
Перший: переставити акценти в блоці стеку так, щоб те, що є в описі вакансії і справді є у вас, стояло вище. Якщо в вакансії ключове слово — Symfony, а у вас Symfony у третьому рядку після Laravel і Vue, підніміть його.
Другий: супровідний лист на три-чотири речення, які неможливо надіслати нікому іншому. Один рядок про те, що саме в цій вакансії ви вмієте робити, один — про найближчий досвід із конкретикою, один — про формат і готовність почати. Шаблон «зацікавила ваша вакансія, я відповідальний і швидко навчаюсь» не читають до кінця.
Останнє. Резюме не отримує вам роботу — воно отримує дзвінок. Тому єдиний критерій якості кожного речення: чи дає воно інтервʼюеру привід поставити питання, на яке вам буде приємно відповідати. Усе, що не дає, — вода, і його можна прибрати. А коли дзвінок призначено, працює вже інше: пройдіться банком питань по своєму рівню й перевірте, що кожен пункт вашого ж резюме витримує два уточнювальні питання поспіль.