Beer::PHP 🍺
2K subscribers
12 photos
2 videos
96 links
Тут публікуються короткі замітки про PHP, Linux, Unit Testing, DB, OOP тощо, витяги зі статей, книг, відео, курсів та інших матеріалів.

Тепер тобі більше не потрібно перегортати тонни інформації ;)

@genkovich — написати автору каналу.
Download Telegram
Read, Write, Partial Update

Наступна відома проблема, коли ми намагаємось використовувати один і той самий обʼєкт як для читання (наприклад представлення на frontend) так і для запису (створення, оновлення).

👉
Візьмемо іншу сутність в рамках нашого створення замолення — Customer. Побудуємо його з низки Value Objects щоб гарантувати, що дані завжди валідні.

$customer = new Customer(
new CustomerId(uniqid()),
new Email($request->email),
new Name($request->name)),
new Password($request->password))
);

$repository->save($customer);

Які ж можуть виникнути проблеми?

1️⃣ Щось, що ми не хочемо відображати

Якщо для відображення ми будемо використовувати той самий обʼєкт Customer, існує ризик, що у відповідь потраплять зайві дані.

interface CustomerRepository
{
public function save(Customer $customer): void;
public function get(string $email): Customer;
}


Наприклад захешований пароль


{
"customerId": "5f2b...",
"email": "jane@doe.com",
"name": "Jane Doe",
"password": "$2y$10$..."
}


Так, можемо по місцю зробити щось на кшталт:

final readonly class Customer
{
// ...

public function serialize(): array
{
return [
'email' => $this->email,
'name' => $this->name,
];
}
}


2️⃣ Зміна правил валідації

Їдемо далі. Наші перевірки в Value Objects можуть змінюватись з часом. В якийсь момент, ми можемо зробити їх більш жорсткими. В базі даних можуть зберігатись записи, котрі можуть не пройти правила нової валідації, якщо ми будемо використовувати один і той самий обʼєкт для читання і для запису. Тут починаються трюки з Reflection. Вже не так райдужно.

3️⃣ Додаткові дані для відображення

Наступна проблема, коли для відображення нам потрібна інформація, котра не міститься в поточному обʼєкті. Наприклад, кількість замовлень.

[
...$customerRepository->getById($customerId),
...['orders_count' => $orderRepository->count($customerId)]
]


Варіант робочий, проте ми тут робимо 2 запити до бази даних, хоча потенційно можна зробити один.

4️⃣ Чи дійсно створення та оновлення це одне і те саме?

При створенні нового Customer ми очікуємо email, name та password. Але, наприклад, при зміні імені, що ми маємо передавати в полі пароля. Чи навпаки, при зміні пароля нам потрібна специфічна логіка (запит на зміну, надсилання токена тощо).

interface CustomerRepository
{
public function save(Customer $user): void;
public function update(Customer $user): void;
}

// Updating name
$customer = new Customer(
$request->email,
$request->name,
'а що тут робити з паролем?',
);

$repository->update($customer);


🤓 Щоб вирішити ці проблеми, доцільно використовувати окремі моделі для різних операцій. Наприклад:

final readonly class CustomerRead
{
public function __construct(
public CustomerId $customerId,
public Email $email,
public Name $name,
public int $orderCount,
) {}
}

interface CustomerReadRepository
{
public function get(CustomerId $customerId): CustomerRead;
}

Або для оновлення даних:

final readonly class CustomerNameUpdate
{
public function __construct(
public CustomerId $customerId,
public Name $name,
)
}

interface CustomerRepository
{
public function save(Customer $customer): void;
public function updateData(CustomerNameUpdate $customerNameUpdate): void;
public function updatePassword(CustomerPasswordUpdate $customerPasswordUpdate): void;
}


✏️ Write model забезпечує дотримання інваріантів і консистентність даних. Оскільки тут ми не паримось як саме будемо виводити ці дані - це дозволяє нам робити обʼєкт маленьким і конкретним.

📖 Read model дає можливість отримати всю необхідну інформацію, потрібну для конкретного відображення чи перегляду.

Не бійтеся створювати окремі представлення для різних операцій. Ваш код стане більш стабільним, логічни та простим для підтримки.

#backend #architecture #middle #source
👍32🔥5🙊31
Знову про індекси

- Що робити, якщо ваш запит в БД відпрацьовує повільно?
- Ну я б спробував(ла) додати індекс.
- Чудово, а чому індекс пришвидшує пошук?
- Нуууу, просто це якась відсортована штука збоку. Ось вона відсортована, пошук швидше.


На моїй практиці 7 з 10 інженерів відповідають приблизно в такому форматі. Можливо тільки в мене така статистика, але пропоную зануритись трошки глибше.

❗️В 90% випадках, незалежно від бази даних (MySQL, Postgres, Mongo) для забезпечення своїх потреб ми будемо використовувати B-Tree або B+Tree індекси.

«Це ж бінарні дерева!» вигукують інженери. І так і ні.

👉 Ця структура - дійсно дерево, і замість того, щоб виконувати пошук по списку і перебирати всі дані O(n), змінивши структуру і розклавши дані у дерево ми будемо виконувати операцію зі складністю ~ O(log n). Якщо дерево бінарне, то і пошук буде бінарним.

Чому важливо, що це не просто бінарне дерево?

При додаванні нового елемента в бінарне дерево - важливий порядок додавання. Перший елемент стає коренем дерева і від нього починають будуватись всі гілки.

Додаємо числа: 10, 5, 15, 3, 7, 12, 20

Крок 1: Додаємо 10 (корінь)
10

Крок 2: Додаємо 5 (менше 10, йде ліворуч)
10
/
5

Крок 3: Додаємо 15 (більше 10, йде праворуч)
10
/ \
5 15

Крок 4: Додаємо 3 (менше 5, йде ліворуч від 5)
10
/ \
5 15
/
3

Крок 5: Додаємо 7 (більше 5, йде праворуч від 5)
10
/ \
5 15
/ \
3 7

Крок 6: Додаємо 12 (менше 15, йде ліворуч від 15)
10
/ \
5 15
/ \ /
3 7 12

Крок 7: Додаємо 20 (більше 15, йде праворуч від 15)
10
/ \
5 15
/ \ / \
3 7 12 20


❗️ Це неминуче призводить до того, що деякі гілки будуть значно довші (вищі) ніж інші. Така структура не може гарантувати швидкість пошуку по всі таблиці з однаковою ефективністю. Ось приклад незбалансованого дерева (в гіршому випадку):

Додаємо числа в порядку зростання: 1, 2, 3, 4, 5, 6, 7

1
\
2
\
3
\
4
\
5
\
6
\
7


Таке дерево фактично стає зв'язним списком з складністю пошуку O(n).

👍 Для вирішення цієї проблеми придумали збалансовані дерева. Тут при кожній операції вставки алгоритм обертає значення таким чином, щоб як умога довше забезпечити однакову висоту по всьому дереву. Обертання - досить дорога операція, і це сильно сповільнює вставку.

Припустимо, у нас є незбалансоване дерево, яке "виросло" вліво:

30
/
20
/ \
10 25

Необхідно виконати праве обертання навколо кореня (30):

Крок 1: Беремо вузол 20 як новий корінь
Крок 2: Старий корінь (30) стає правим нащадком нового кореня
Крок 3: Правий нащадок нового кореня (якщо є) стає лівим нащадком
старого кореня (25 стає зліва)

Результат:
20
/ \
25 30
/
10

Тепер дерево збалансоване

Розглянемо складніший випадок з подвійним обертанням. Дано:

30
/
10
\
20

Тут праве обертання не виправить ситуацію. Потрібне подвійне обертання:

Спочатку ліве обертання навколо 10:
30
/
20
/
10

Потім праве обертання навколо 30:
20
/ \
10 30


✅️️️️️️️ Інженери пішли далі і сьогодні ми маємо такі різновиди збалансованих дерев як B-Tree та B+Tree. В них при операції вставки ми не одразу породжуємо нову ноду, а намагаємось вставити дані за певним алгоритмом, щоб зберегти висоту. Це породжує декілька значень на рівні однієї ноди:

[15, 50]
/ | \
[5] [20] [70]


🤓 Але про них ми більш подробно поговоримо в наступному пості. Отже, головний посил, що індекси - не магія і не просто "якась штука збоку". Це конкретні структури даних, що пришвидшують пошук.

#database #middle
👍50🔥8🗿1
B-Tree та B+Tree індекси

👉 Саме вони є найбільш розповсюдженими в нашому повсякденному житті. Майже всі популярні БД (PostgreSQL, MySQL/InnoDB, SQLite, MongoDB і т.д.) використовують B+Tree для зберігання індексів. Як зазначено в попередньому пості, це різновиди збаланосованих дерев. Головна особливість в тому, що кожен вузол може мати більше двох нащадків (на відміну від бінарного дерева), а також може мати кілька ключів (значень) в одному вузлі.

Порядок B-Tree (зазвичай позначається як m) визначає максимальну кількість нащадків, які може мати вузол.
- Кожна нода (крім кореня) має від ceil(m/2)-1 до m-1 ключів
- Корінь має від 1 до m-1 ключів
- Нода з k ключами має k+1 дочірніх нод

❗️У нашому прикладі ми використовуємо B-Tree порядку 3, це значить, що може бути до 2 ключів у кожному вузлі, і до 3 нащадків для кожного вузла відповідно.

📍 B+Tree відрізняється від B-Tree тим, що всі дані зберігаються тільки в листкових вузлах, які додатково пов'язані між собою як зв'язний список, що значно пришвидшує послідовне читання а значить і кращу продуктивність при пошуку близьких значень.

Алгоритм вставки:

Коли нода заповнюється і не може вмістити новий ключ, при черговій вставці відбувається операція ділення і ми створюємо новий рівень з існуючих даних.

[5, 15]
/ | \
[3] [10,20,30] [40]

1. У нас є переповнена нода: [10, 20, 30]
2. Медіана: 20
3. Розділяємо на: [10] і [30]
4. 20 піднімається до батьківської ноди

[5, 15, 20]
/ / \ \
[3] [10] [30] [40]


Продовжуємо процес, бо [5, 15, 20] теж переповнена:

1. Медіана: 15
2. Розділяємо на: [5] і [20]
3. 15 піднімається вище

Припустимо, що раніше наше дерево мало корінь з одним елементом [50], до якого ми додаємо 15:

Проміжний результат:

[15, 50]
/ | \
[5] [20] [...]

Остаточно структура виглядає так:
[15, 50]
/ | \
[5] [20] [...]
/ \ / | \
[3] [10] [...] [30] [40]
При цьому складність пошуку гарантовано буде O(log_m n), де m — порядок дерева, як я зазначав вище.


"Перебудова індексу", або чому вставки такі дорогі?

🔥 Основна причина популярності цих індексів - оптимізація роботи з диском. Диск читається блоками (вони ж сторінки індексу фіксованого розміру, зазвичай 4KB, 8KB або 16KB залежно від БД), і B-дерева чудово це використовують, зберігаючи багато ключів в одному вузлі.

Fill Factor (фактор заповнення) - параметр, який визначає, наскільки заповненими будуть сторінки індексу при їх створенні. Наприклад, fill factor 70% означає, що сторінки заповнюються на 70%, залишаючи 30% вільного місця для майбутніх вставок.
Коли сторінка індексу заповнюється повністю (через вставки даних), відбувається операція розщеплення сторінки (page split):

1️⃣ Створюється нова сторінка
2️⃣ Приблизно половина даних переміщується в нову сторінку
3️⃣ Середній ключ "піднімається" до батьківської сторінки
4️⃣ Батьківська сторінка оновлює свої посилання

❗️Це і є супер дорога операція, бо вимагає виділення нової сторінки на диску, переміщення даних, оновлення посилань, можливе розщеплення батьківських сторінок (каскадний ефект).

Також налаштування fill factor може підвищити продуктивність бази даних:

Для таблиць з частими вставками — низький fill factor (70-80%)
Для таблиць тільки для читання — високий fill factor (90-100%)


# Postgres

CREATE TABLE my_table (
id serial PRIMARY KEY,
data text
) WITH (fillfactor = 70);

# Для InnoDB доступний параметр fillfactor на рівні сервера
# в my.cnf або my.ini

[mysqld]
innodb_fill_factor = 80


👍 Сподіваюсь, у світі стало трошки менше магії, і трошки більше розуміння того, як працюють системи, якими ми користуємось щодня.

#database #middle
👍38🔥92🗿1
Ювілейний, 10-й випуск FWDays PHP Talks — вже на каналі

Ми нарешті сіли і поговорили про те, як не втопитися в логах, як збирати трейси в event-driven, як жити, коли в тебе триста мікросервісів.

Згадали такі речі, як EFK, Grafana Loki, Jaeger, Prometheus, OpenTelemetry, PageDuty, Graylog, "і отой забутий пайплайн на івентах, де ніхто не знає, що з чим з’єднане".

📍 Чим обсервабіліті відрізняється від моніторингу?
📍 Чому "все логуватити" — це погано, а не логувати — ще гірше?
📍 Скільки вартує моніторинг і чи треба він бізнесу?
📍 Чому Event-Driven це чудово, поки не треба дебажити?

👉 Подяка Йожефу, як завжди, за настрій і формат.

👍 Олексію — за архітектурну мудрість і чесність про "комфортну зону" архітектора.

🎧 Слухайте. Лайкайте. Пишіть нам, якщо з чимось не згодні 😉

https://youtu.be/frJGs9WovWY

#php #observability #monitoring #logging #tracing
🔥14👍6
PHP 8.5: Clone with - майже те, що треба

Готувався до подкасту, де будемо розглядати нові можливості PHP 8.5 і неочікувано натрапив те, що цю фічу вже імплементували. Я був шокований, адже я чекав цього ще з моменту, як ввели readonly property (php8.1), навіть був RFC, котрий заглох, а тут бах, і вже змержили. Що правда не все супер райдужно, адже фактично створили новий RFC і імплементацію розділили на кілька етапів. То давайте розбиратись

Чим круті readonly properties та іммутабельні обʼєкти

► Не треба гратись з інкапсуляцією, створювати додаткові getters/setters
► Ніхто випадково не поміняє дані десь в глибині коду
► Можна безпечно передавати об'єкт кудись - він точно повернеться таким самим
► Легше дебажити - об'єкт не може магічно змінитись між рядками коду
► Thread safety з коробки (якщо раптом дійде до async в PHP 9)

Але все це круто до моменту поки ми не захочемо щось з цим обʼєктом таки зробити [pic | code]

І через це пилили костилі, приходилось або писати купу окремих with методів [pic | code] (просто копіпасту), або гратись з рефлексією, що також є ресурсозатратно і не зовсім надійно [pic | code]

І тепер в PHP 8.5 ми зможемо досягти результату дуже просто

$mariaViolin = clone($maria, ['instrument' => 'скрипка']);


Ну майже просто 😅

🗿 Які є підводні камені?


Справа в тому, що ми не можемо просто взяти і зробити це без додаткових дій, адже коли в PHP 8.4 формалізували asymmetric visibility (можна окремо задавати видимість для читання і запису), стало зрозуміло, що всі public readonly властивості по дефолту були public(get) protected(set).

Чому protected(set) а не public(set) за замовчуванням, бо readonly властивості з самого початку (PHP 8.1) були задумані як "встановлюються тільки в конструкторі". Ну і не private(set), щоб можна було цим керувати в дочірніх класах

👉 Саме тому, при спробі викликати клонування в 8.5 поза обʼєктом призведе до відповідної помилки [pic | code], тому треба про це памʼятати і якщо необхідно - явно вказувати public(set) для властивостей вашого обʼєкту [pic | code]

💡 Або, робити відповідні зміни прямо всередині вашого обʼєкта, додаючи відповідні методи [pic | code], що мені подобається більше, але підійде не для всіх випадків.

🤔 Чи по тій самій схемі, замінити страшний приклад з рефлексією на реалізацію простого with [pic | code]

Ще один важливий момент

Поточна реалізація ніяк не впливає на використання магічного метода __clone, тобто параметри в нього досі передавати не можна, а при його імплементації ми отримаємо копію обʼєкту БЕЗ урахування того, що ми передали в якості аргументу [pic | code]. Це було свідоме рішення під час розбиття rfc на різні етапи, бо ця фіча ломає BC і сильно ускладнює імплементацію

💪 І тим не менш, я думаю, що Clone with - це крок в правильному напрямку

Поки памʼятаємо про protected(set) для readonly, скоріш за все це зміниться, та __clone() без параметрів, котрі обіцяють додати в майбутньому.

Але навіть з усіма нюансами - це краще ніж те, чим ми користувались. А ви що думаєте? Будете використовувати clone with?

#php85 #readonly #clonewith #middle #source
🔥25👍18
Media is too big
VIEW IN TELEGRAM
Один із трендових напрямків зараз — інтеграція AI у CI/CD 🤖🚀

І це реально круто, що на етапі CI воно може в рази пришвидшити написання та перевірку коду.
Але коли мова про CD, тут ще є нюанси 🙃

Моделі статистичні → значить, вони недетерміновані. Це може давати:
фолс-позитивні результати (бачать проблему там, де її нема)
🤷‍♂️ пропускати важливі речі (не ловлять баг, коли він є)
🌀 «галюцинації»
🙅‍♂️ «огріхи» від неповного датасету чи неідеального навчання

Попри все, тренд рухається вперед. І цікаво спостерігати, як AI буде поступово «вростати» у CI/CD процеси 💡
👍16🙊3🔥1
Все, що потрібно знати про PHP 8.5: від clone with до Fatal Errors stack trace

Друзі, цього разу ми з Йожефом пройшлися по прийнятих RFC у PHP 8.5 — від клонування імутабельних об’єктів до покращення OPcache і свіжого pipe-оператора.

📍Що розібрали по суті (з живими прикладами):

• Immutability + clone with — нормальний шлях для value objects/DTO. Порівняли з попередніми «костилями» (рефлексія, копіпасти with*), розібрали нюанси: публічний set для readonly, порядок викликів та відсутність параметрів у __clone, shallow vs deep copy.

• URI-класи в ядрі (RFC 3986 / WHATWG) — стандартизований парсинг без власноручних регексів.

• array_first() / array_last() — прозорий доступ до крайніх елементів без reset()/end() та внутрішніх поінтерів; чому це справді краще за array_key_first()/array_key_last().

• Pipe operator |> — ланцюжки викликів у зрозумілому функціональному стилі.

• #[NoDiscard] — ловимо тих, зто «забув використати» дані з return.

• Стек-трейс у Fatal Errors — нарешті нормальний дебаг замість «білого екрану».

👉Велика подяка Йожефу за настрій та практичні поради, як завжди було круто

Випуск вже на каналі. Слухайте, дивіться, ставте питання та вподобайку, якщо було корисно.

https://youtu.be/abHntd9evic?si=BGg-K9KagHf1dXkF
👍34🔥61
Ну що, нарешті PHP fwdays’25

Особисто для мене це завжди крута подія, котру кожен рік чекаю, щоб засинхронізуватись з колегами, подивитись що відбувається у інших, заглибитись в актуальні підходи, поговорити про архітектуру та використання фреймворків, дізнатись кейси по інтеграції AI у PHP і т.д.

Коли: 4 жовтня (субота)
Де: Київ (офлайн, лише 80 місць) + онлайн

Серед спікерів:
— Андрій Яценко, Oro Inc. — «Застрибуємо у гайп-потяг AI розробки, поки він не згорів»
— Владислав Поздняков, mono — «Long running processes на PHP»
— Юрій Панайотов, Silpo (E-commerce) — «Як мати 200+ PHP сервісів у продакшні і не з’їхати з глузду?»
— В’ячеслав Вергелес, TENTENS tech — «Міцний сон інженера: як ми забезпечуємо якість, щоб спати спокійно»
— Олександр Бучек, MacPaw — «Не клонувати інфру, а ізолювати дані: ефемерні PR-оточення у shared-env»

🎟 Квитки вже у продажу. Діє знижка 10% за моїм промокодом PHP10Beer.
🔗 Деталі та квитки
🔥15👍6
Сьогодні важлива подія

Думаю ні для кого не секрет, що насправді я давненько відійшов від постійного програмування на PHP, займаю менеджерську позицію, пробую себе в golang, python та іншому стеку.

🤷 Виходить так, що контекст змінився, а канал ні. Мені хочеться ділитись думками частіше, та завжди себе зупиняю, що вони "не в тему каналу".

👉 Важлива подія в тому, що тільки но закатив перший відос на свій YouTube канал. Він зовсім не про PHP, він про те як якісно проводити 1-on-1. Про подібні речі також хочеться писати пости, отримувати фідбек, ділитись спостереженнями і дискутувати.

Тому:
1. Закликаю всіх подивитись відос, буду вдячний за коментарі, критику, особливо конструктивну
2. Дати реакцій, чи заходить така тематика і подібний контент
3. Кому заходить - підтримати підпискою, вподобайкою, зворотнім звʼязком

https://youtu.be/s2wuc-t3ZO0

#1-1 #manager #teamlead #youtube
👍31🔥13
Нарешті це сталось. Я повністю перебрав, доповнив і опублікував статтю на DOU — «Принцип підстановки Барбари Лісков (про передумови, постумови та інваріанти)».

Спробував максимально розжувати те, що ж Барбара мала на увазі, додати конкретики та пройтися по кожному важливому пункту 🙂

У статті розповів про:
• принцип самої підстановки
• передумови та післяумови
• коваріантність і контраваріантність
• як з цим жити або як обійти

📌 Якщо ви вважали цей принцип незрозумілим — рекомендую до прочитання, адже я постарався навести реальні приклади коду та чіткі пояснення.

🙃 До речі, давно не писав у такому форматі, тож радий повернутися.

👇🏻 Діліться своїм досвідом у коментарях — цікаво почути, чи стало трошки зрозуміліше, що воно таке і з чим його їдять.

https://dou.ua/forums/topic/55754/
🔥52👍7
Друзі, продовжую низку неочікуваних новин 🙂 Давно хотілось створити подкаст, де говорити на менш технічні і на більш загальні теми в айтішці. Про професії, зони відповідальності, курйозні ситуації, ринок, проблеми, чи просто понити.

То ж вийшов перший пілотний випуск, в котрому спробували прояснити «Хто такий Delivery Manager»

Було дійсно цікаво поговорити з Олею, вона Delivery Manager із понад 10-річним досвідом у міжнародних компаніях.

📍 Якщо коротко, що затронули:
– чим насправді відрізняється Project, Product і Delivery Manager;
– як менеджери справляються зі стресом і факапами;
– чи потрібна технічна експертиза, щоб ефективно керувати командою;
– як виживає команда без менеджера та що не так із Jira;
– чи може штучний інтелект замінити менеджера.

🎥 Випуск уже на каналі
Переходьте, дивіться, ставте запитання в коментарях і буду дуже вдячний за ваш зворотній звʼязок

https://youtu.be/RGyYU2fhDtY
🔥17👍76
Записали черговий подкаст для FWDays PHP Talks з Павлом і Йожефом. Цього разу копнули Event Driven архітектуру.

Почали з основ — навіщо це все придумали, а потім розібрали три стовпи Event Driven: Event, Producer та Subscriber.

📍Ну і, звісно, поговорили про вузькі місця:

• Хто створює черги — продюсер чи сабскрайбер?
• Як правильно налаштовувати конфіги?
• Що робити з навантаженням і скейлінгом воркерів?
• І найболючіше — коли падають воркери, у тебе починає деградувати вся система.

Плюс затримки. Ті самі затримки, від яких нікуди не подітись 😅

👉 Коротше, якщо працюєте з Event Driven або тільки плануєте впроваджувати — рекомендую послухати. Ми розповіли про все те, з чим самі стикалися і що, на жаль, доводилось розгрібати.

Переходьте, дивіться, пишіть вашу думку і фідбек — буду радий подискутувати 🙂

https://youtu.be/SNplV4BaKvU
🔥23👍3
Чому я почав вести YouTube? 🎬

А чи має бути причина?

Ніби без причини щось не має сенсу. Чому, коли хочеться спробувати щось нове, ти одразу шукаєш, пояснення, мотивацію, а іноді і виправдання?

Не все має починатись з логіки. Деякі речі народжуються просто тому, що хочеться, тому, що є внутрішній імпульс — і все, без уточнення «навіщо».

Мені подобається говорити, спілкуватись, ділитись думками, записувати подкасти, знайомитись з людьми з індустрії, отримувати фідбек, як позитивний, так і той, після якого хочеться рости.

І цього достатньо.

Не шукайте «чому». Коли всередині є справжнє бажання — це вже і є причина

https://youtube.com/@beercodeit?si=ZHLpe7xaN3eGQfqo
👍16🔥6
Друзі, маю для вас новий випуск на своєму каналі 🚀

Продовжуємо говорити відверто про айтішку. Цього разу ми спробували розібратися, хто ж такий DevOps інженер і чому всі кажуть, що ця роль "не для джунів".

В гостях був Томош – Cloud DevOps інженер, який погодився простою мовою пояснити, за що йому платять гроші 😁

📍 Якщо коротко, про що поговорили:

– Чому насправді "не буває Junior DevOps" і звідки тоді вони беруться?
– SysAdmin, DevOps, DevSecOps, FinOps – у чому різниця і де чия відповідальність?
– "Лінивий DevOps" – це хороший DevOps?
– Що бісить девопсів найбільше?
– Наскільки глибоко DevOps має знати код (Python, GoLang) і чи важливі soft skills?
– Вплив ШІ: як Copilot, Grok та Claude вже змінюють підходи до інфраструктури та автоматизації

Переходьте, дивіться, і, звісно, діліться своїми історіями та запитаннями в коментарях. Буду дуже вдячний за ваш зворотній звʼязок!

https://youtu.be/s-TTevLwMPA
👍11🔥3🙊1
Друзі, вийшла друга частина розмови Fwdays PHP Talks про DDD! 🎥

Разом з Йожефом Гісемом та Ігорем Проніним продовжили говорити про те, як бізнес і розробка можуть нарешті порозумітися 🙂

У цьому епізоді:

💬 про те, як знайти спільну мову між бізнесом і девелоперами — щоб усі рухались в одному напрямку, а не говорили різними мовами

🧩 коли реально варто використовувати Event Storming і контекст-мапи — і як ці штуки допомагають розкласти складну систему по поличках

⚙️ Value Object, Entity та Rich Model — не просто теорія, а як це працює у живих проєктах

Якщо тема DDD тобі близька — обов’язково глянь випуск і поділися своїми спостереженнями в коментарях 👇🏻

https://youtu.be/AnicWaTTvLg?si=4PFnfL_SLmBRL6AM
👍20🔥3
Звільнення

Мабуть, одна з найбільш табуйованих і неприємних тем у менеджменті.

Зізнавайтесь, чи бачили ви співробітника, якого "тягнуть"?

🤔 "А раптом він виправиться?", "Шкода людину", "Може, це я погано пояснив?".

Я проходив через ці сумніви. Але правда в тому, що коли ви не звільняєте неефективну людину, ви руйнуєте команду зсередини.

👉 Тому у новому відео вирішив підняти цю важку тему і розкласти все по поличках:

• Чому ми насправді боїмося звільняти (і до чого тут емпатія)
• Оцінка 360 та 9-box model: як зрозуміти, хто "тягне", а хто ні
• Токсичність, чому це бомба сповільненої дії
• Performance Improvement Plan (PIP)
• Покроковий скрипт, як повідомити про рішення, щоб це було професійно

Звільнення - це, мабуть, найскладніше рішення для менеджера. Але іноді - найправильніше

Тому дивіться відео, там багато практичних інсайтів: https://youtu.be/lZ-a_LzJXhU

Буду вдячний за зворотній звʼязок

#manager #teamlead #youtube
🔥8👍4