PHP | Вопросы собесов
2.3K subscribers
34 photos
1.54K links
Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy

Контакт для рекламы: @sendme_ads
Download Telegram
🤔 Зачем нужны паттерны проектирования?

Это повторяемые решения типичных задач. Они помогают разработчикам создавать программы, которые легко поддерживать, расширять и модифицировать. Паттерны проектирования упрощают процесс разработки, обеспечивая проверенные способы решения распространенных проблем, что экономит время и силы разработчиков.

🚩Зачем они нужны


🟠Повторяемость и стандартность
Паттерны обеспечивают повторяемость решений для часто возникающих задач, что снижает вероятность ошибок и улучшает читабельность кода.
🟠Улучшение коммуникации
Использование общепринятых паттернов облегчает коммуникацию между разработчиками. Когда все понимают, что подразумевается под, например, «одиночкой» (singleton), это упрощает обсуждение архитектуры системы.
🟠Повышение качества кода
Паттерны проектирования способствуют созданию более структурированного, гибкого и поддерживаемого кода.
🟠Экономия времени и ресурсов
Паттерны позволяют не изобретать велосипед, а использовать проверенные решения, что ускоряет процесс разработки.

🚩Как они используются

Паттерны проектирования делятся на несколько категорий, каждая из которых решает определенный тип задач:
🟠Порождающие паттерны
Эти паттерны касаются создания объектов. Примеры: Singleton, Factory, Builder.
🟠Структурные паттерны
Эти паттерны касаются построения структуры больших объектов. Примеры: Adapter, Composite, Decorator.
🟠Поведенческие паттерны
Эти паттерны касаются взаимодействия и распределения обязанностей между объектами. Примеры: Observer, Strategy, Command.
class Singleton {
private static $instance;

private function __construct() {
// Закрытый конструктор предотвращает создание объекта через new
}

public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}

public function someBusinessLogic() {
// Некоторая бизнес-логика
}
}

// Использование Singleton
$singleton = Singleton::getInstance();
$singleton->someBusinessLogic();


Ставь 👍 и забирай 📚 Базу знаний
🤔 Как расшифровывается REST?

REST (Representational State Transfer) — это архитектурный стиль взаимодействия систем через HTTP. Он основан на представлении ресурсов как URL и использовании стандартных HTTP-методов (GET, POST, PUT, DELETE) для работы с этими ресурсами.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Какое отличие у протоколов tcp и udp?

Это два основных транспортных протокола в интернете. Они имеют разные характеристики и используются для различных целей.

🚩Основные отличия

🟠Надежность
TCP: Обеспечивает надежную передачу данных. Он использует механизмы установления соединения, подтверждение получения (ACK), контроль потерь пакетов, повторную передачу потерянных пакетов и контроль потока. Это гарантирует, что данные будут доставлены корректно и в правильном порядке.
UDP: Не обеспечивает надежную передачу данных. Нет подтверждений получения, нет повторной передачи потерянных пакетов и нет контроля потока. Это делает передачу менее надежной, но более быстрой и с меньшими накладными расходами.

🟠Установление соединения
TCP: Перед началом передачи данных устанавливается соединение с помощью процедуры "трехстороннего рукопожатия" (three-way handshake). Это означает, что обе стороны сначала обмениваются сигналами SYN и ACK для установления соединения.
UDP: Не требует установления соединения. Пакеты (датаграммы) просто отправляются к получателю без предварительного установления соединения.

🟠Порядок доставки
TCP: Обеспечивает доставку данных в правильном порядке. Если пакеты приходят в неправильном порядке, TCP собирает их в правильном порядке перед передачей приложению.
UDP: Не гарантирует порядок доставки. Пакеты могут приходить в произвольном порядке, и приложение должно обрабатывать их соответствующим образом, если это необходимо.

🟠Пропускная способность и задержки
TCP: Из-за механизмов контроля потока и подтверждений имеет большие накладные расходы и, следовательно, может быть медленнее. Это особенно заметно на сетях с высокой задержкой или потерей пакетов.
UDP: Из-за отсутствия контроля потока и подтверждений имеет меньшие накладные расходы, что может привести к меньшим задержкам и большей пропускной способности. Подходит для приложений, где важна скорость, а не надежность.

🟠Применение
TCP: Используется для приложений, где важна надежность и порядок передачи данных, таких как веб-браузеры (HTTP/HTTPS), электронная почта (SMTP, IMAP, POP3), файловые передачи (FTP), удаленный доступ (SSH).
UDP: Используется для приложений, где важна скорость и где потеря некоторых пакетов не критична, таких как потоковое видео и аудио (VoIP, IPTV), онлайн-игры, службы доменных имен (DNS).

🚩Примеры использования

TCP
HTTP/HTTPS: Веб-серфинг
SMTP: Отправка электронной почты
IMAP/POP3: Получение электронной почты
FTP: Передача файлов
SSH: Безопасный удаленный доступ


UDP
DNS: Запросы доменных имен
VoIP: Передача голоса через IP
IPTV: Потоковое видео
Онлайн-игры: Быстрая передача данных игровой логики
NTP: Синхронизация времени


Ставь 👍 и забирай 📚 Базу знаний
🤔 Что известно о Unit-тестах?

Это тесты, проверяющие отдельные единицы кода (обычно функции, методы или классы) в изоляции от внешних зависимостей.
Особенности:
- Быстрые, запускаются локально.
- Должны быть предсказуемыми и детерминированными.
- Не используют базу данных, сеть или файловую систему (для этого есть интеграционные и e2e-тесты).
- Помогают отлавливать баги на раннем этапе и облегчают рефакторинг.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Слово "global" для чего используется?

Ключевое слово global используется в PHP для доступа к глобальным переменным внутри функций.

🚩Как работает `global`?

Доступ к глобальной переменной внутри функции
$counter = 10; // Глобальная переменная

function increment() {
global $counter; // Доступ к глобальной переменной
$counter++;
}

increment();
echo $counter; // ✅ 11


Использование нескольких глобальных переменных
$a = 5;
$b = 10;

function sum() {
global $a, $b;
$b = $a + $b; // Меняем глобальную переменную $b
}

sum();
echo $b; // ✅ 15


🟠Альтернативный способ – `$GLOBALS`
Можно использовать суперглобальный массив $GLOBALS, который хранит все глобальные переменные.
$x = 3;
$y = 7;

function multiply() {
$GLOBALS['y'] = $GLOBALS['x'] * $GLOBALS['y'];
}

multiply();
echo $y; // ✅ 21


🚩Когда `global` – плохая идея?

Глобальные переменные усложняют отладку (их можно случайно изменить).
Функции становятся зависимыми от внешних данных (плохо для тестирования).
Лучше передавать переменные через аргументы функции.
Альтернативный способ (без global)
function increment($counter) {
return $counter + 1;
}

$counter = 10;
$counter = increment($counter);
echo $counter; // ✅ 11


Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое Cookies?

Это небольшие файлы, которые хранят данные на стороне клиента (в браузере). Они используются для:
1. Идентификации пользователя и управления сессиями.
2. Сохранения предпочтений пользователя.
3. Отслеживания активности пользователя на сайте.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 В чем преимущества асинхронного шифрования?

Асинхронное шифрование (асимметричная криптография) использует пару ключей:
Открытый (public key) – используется для шифрования данных.
Закрытый (private key) – используется для расшифровки данных.

Этот метод отличается от симметричного шифрования, где один и тот же ключ используется и для шифрования, и для дешифровки.

🟠Безопасный обмен ключами
- В симметричном шифровании нужно передать секретный ключ, что создаёт риск его перехвата.
- В асимметричном шифровании передаётся только открытый ключ, а закрытый ключ никогда не покидает владельца.

🟠Цифровая подпись – гарантия подлинности данных
- Можно подписывать данные закрытым ключом, а затем любой человек может проверить их подлинность с помощью открытого ключа.
$data = "Важное сообщение";
$privateKey = openssl_pkey_get_private(file_get_contents("private.pem"));
$publicKey = openssl_pkey_get_public(file_get_contents("public.pem"));

// Создаём подпись
openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);

// Проверяем подпись
$valid = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);

echo $valid ? "Подпись верна" : "Подпись недействительна";


🟠Возможность шифрования без предварительного контакта
- В симметричном шифровании обе стороны должны сначала договориться о ключе.
- В асимметричном шифровании можно просто использовать открытый ключ получателя без предварительного обмена секретами.

🟠Используется в SSL/TLS для безопасного соединения
- Когда вы заходите на сайт с https://, браузер использует асимметричное шифрование для установки защищённого соединения с сервером.
- После этого браузер и сервер могут использовать симметричное шифрование (быстрее), но начальный обмен ключами происходит безопасно.

🚩Как это работает?

1. Браузер запрашивает у сервера его открытый ключ.
2. Шифрует случайный симметричный ключ и отправляет его серверу.
3. Сервер расшифровывает его закрытым ключом и использует для дальнейшей защиты соединения.

Ставь 👍 и забирай 📚 Базу знаний
🤔 Чем класс отличается от объекта?

1. Класс — это шаблон или "чертёж", описывающий свойства и поведение объектов.
2. Объект — это экземпляр класса, созданный с использованием его структуры.
3. Класс определяет, что объект может делать, а объект выполняет это поведение.
4. Класс — это абстракция, объект — конкретное воплощение.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥3
🤔 Что такое транзакции?

Это последовательности операций с базой данных, которые рассматриваются как единое целое. Они обеспечивают целостность данных, гарантируя, что либо все операции в транзакции выполнены успешно, либо никакие изменения не будут применены, если произошла ошибка.

🟠Atomicity (Атомарность)
Гарантирует, что все операции в рамках транзакции будут выполнены полностью или не будут выполнены вовсе. Если любая из операций внутри транзакции не удалась, все изменения откатываются.
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;


🟠Consistency (Согласованность)
Обеспечивает перевод базы данных из одного согласованного состояния в другое. Транзакции должны оставлять базу данных в корректном состоянии, удовлетворяющем всем правилам и ограничениям.

🟠Isolation (Изолированность)
Обеспечивает изолированность транзакций друг от друга. Это означает, что результаты промежуточных операций одной транзакции невидимы для других транзакций до завершения первой транзакции.

🟠Durability (Долговечность)
Гарантирует, что изменения, внесённые успешно завершённой транзакцией, будут сохранены в базе данных даже в случае сбоя системы.

🚩Использования транзакций

🟠Перевод денег между счетами
Необходимо убедиться, что обе операции (списание и зачисление) выполнены успешно, чтобы избежать ситуации, когда деньги списаны, но не зачислены.
BEGIN TRANSACTION;

UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

COMMIT; -- Если обе операции прошли успешно
-- ROLLBACK; -- Если произошла ошибка


🟠Создание заказа в интернет-магазине
Важно убедиться, что все связанные операции (добавление записи о заказе, обновление статуса товаров, запись данных о платеже) выполнены успешно.
BEGIN TRANSACTION;

INSERT INTO orders (user_id, order_date) VALUES (1, NOW());
UPDATE products SET stock = stock - 1 WHERE product_id = 101;
INSERT INTO payments (order_id, amount) VALUES (LAST_INSERT_ID(), 99.99);

COMMIT; -- Если все операции прошли успешно
-- ROLLBACK; -- Если произошла ошибка


Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Что известно про букву D в SOLID и её связь с интерфейсами?

D означает Dependency Inversion Principle — принцип инверсии зависимостей.
1. Модули верхнего уровня не должны зависеть от модулей нижнего уровня, оба должны зависеть от абстракций.
2. В коде это реализуется через интерфейсы: классы работают с интерфейсами, а не с конкретными реализациями.
3. Это упрощает тестирование и замену модулей без изменения основного кода.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3
🤔 Что такое extend?

В PHP extends используется для наследования классов. Он позволяет одному классу (дочернему) наследовать свойства и методы другого класса (родительского).

🚩Пример наследования через `extends`

Базовый пример (extends)
class Animal {
public function makeSound() {
return "Какой-то звук";
}
}

class Dog extends Animal {
public function makeSound() {
return "Гав-гав!";
}
}

$dog = new Dog();
echo $dog->makeSound(); // ✅ "Гав-гав!"


Использование parent:: для вызова родительского метода
class Animal {
public function makeSound() {
return "Какой-то звук";
}
}

class Cat extends Animal {
public function makeSound() {
return parent::makeSound() . " Мяу-мяу!";
}
}

$cat = new Cat();
echo $cat->makeSound(); // ✅ "Какой-то звук Мяу-мяу!"


Наследование свойств
class User {
protected string $role = "Гость";

public function getRole() {
return $this->role;
}
}

class Admin extends User {
protected string $role = "Администратор";
}

$admin = new Admin();
echo $admin->getRole(); // ✅ "Администратор"


Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое полнотекстовый индекс?

Это структура данных, оптимизирующая поиск текстовой информации в базе данных.
1. Используется для эффективного поиска по словам или фразам в текстовых полях.
2. Применяется в MySQL, PostgreSQL, ElasticSearch и других системах.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Как работает зацепление?

Зацепление (coupling) — это степень зависимости одного модуля от другого. В PHP (и вообще в разработке) мы стремимся уменьшить зацепление, чтобы код был гибким, удобным для тестирования и сопровождения.

🚩Виды зацепления

🟠Слабое зацепление (Loose Coupling) – Хорошо
- Модули мало зависят друг от друга.
- Можно заменять части системы без изменений в других частях.
- Используется интерфейсы, DI (Dependency Injection), события.
interface Logger {
public function log($message);
}

class FileLogger implements Logger {
public function log($message) {
echo "Запись в файл: $message\n";
}
}

class DatabaseLogger implements Logger {
public function log($message) {
echo "Запись в базу: $message\n";
}
}

class User {
private $logger;

public function __construct(Logger $logger) {
$this->logger = $logger;
}

public function register($name) {
echo "Регистрация пользователя: $name\n";
$this->logger->log("Пользователь $name зарегистрирован.");
}
}

// Можно легко менять логгер без изменения класса User
$user = new User(new FileLogger());
$user->register("Иван");

$user = new User(new DatabaseLogger());
$user->register("Петр");


🟠Жёсткое зацепление (Tight Coupling) – Плохо
- Модули сильно связаны, нельзя поменять один без изменения другого.
- Код трудно тестировать и расширять.
- Используется жёсткая привязка классов внутри других классов.
class FileLogger {
public function log($message) {
echo "Запись в файл: $message\n";
}
}

class User {
private $logger;

public function __construct() {
$this->logger = new FileLogger(); // Жесткая зависимость!
}

public function register($name) {
echo "Регистрация пользователя: $name\n";
$this->logger->log("Пользователь $name зарегистрирован.");
}
}

// User всегда использует FileLogger, его нельзя легко заменить
$user = new User();
$user->register("Иван");


Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Что такое медленный запрос?

Это запрос, выполнение которого занимает больше времени, чем заданный порог.
1. Причины: отсутствие индексов, сложные объединения, большой объём данных.
2. Оптимизация: использование индексов, анализ плана выполнения (EXPLAIN) и уменьшение объёма данных.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 Что реализует класс Datetime?

Класс DateTime в PHP предоставляет удобные инструменты для работы с датами и временем. Он заменяет устаревшие функции date(), strtotime() и делает код более читаемым и гибким.

🚩Что умеет `DateTime`?

Создавать даты и время.
Изменять, прибавлять, вычитать дни, месяцы, годы.
Преобразовывать дату в строку (format()).
Работать с часовыми поясами (DateTimeZone).
Сравнивать даты (diff()).
Преобразовывать в Unix Timestamp (getTimestamp()).

🚩Примеры использования `DateTime`

1⃣Создание объекта DateTime
$date = new DateTime(); // Текущая дата и время
echo $date->format('Y-m-d H:i:s'); // 2025-02-24 15:30:00


2⃣Создание DateTime с конкретной датой
$date = new DateTime('2023-12-31 23:59:59');
echo $date->format('d.m.Y H:i'); // 31.12.2023 23:59


3⃣Прибавить / Вычесть дни, месяцы, годы (modify())
$date = new DateTime('2024-01-01');
$date->modify('+1 month'); // Добавить 1 месяц
echo $date->format('Y-m-d'); // 2024-02-01

$date->modify('-10 days'); // Вычесть 10 дней
echo $date->format('Y-m-d'); // 2024-01-22


4⃣Разница между датами (diff())
$date1 = new DateTime('2024-01-01');
$date2 = new DateTime('2025-01-01');

$diff = $date1->diff($date2);
echo $diff->days; // 366 (разница в днях)
echo $diff->y; // 1 (разница в годах)


5⃣Работа с часовыми поясами (DateTimeZone)
$date = new DateTime('now', new DateTimeZone('America/New_York'));
echo $date->format('Y-m-d H:i:s'); // Время в Нью-Йорке


6⃣Преобразование DateTime в Timestamp (getTimestamp())
$date = new DateTime('2024-01-01');
echo $date->getTimestamp(); // 1704067200 (Unix-время)


7⃣Создание DateTime из Timestamp (setTimestamp())
$date = new DateTime();
$date->setTimestamp(1704067200);
echo $date->format('Y-m-d H:i:s'); // 2024-01-01 00:00:00


Ставь 👍 и забирай 📚 Базу знаний
🤔 Какая разница между self и this?

self в PHP используется для обращения к текущему классу, включая статические методы и свойства, тогда как this ссылается на конкретный экземпляр класса. self подходит для работы с общими (статическими) членами класса, а this — для доступа к данным объекта. self не может использоваться для динамических данных объекта, в отличие от this.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2
🤔 Почему магические методы называются магическими?

Магические методы в PHP называются так, потому что они автоматически вызываются в определённых ситуациях, без явного вызова в коде.

🚩Примеры магических методов и их "магия"

🟠`__construct()` – вызывается при создании объекта
Магия: вызывается автоматически, когда создаётся объект.
class User {
public function __construct() {
echo "Создан новый пользователь!";
}
}

$user = new User(); // ✅ Выведет "Создан новый пользователь!"


🟠`__toString()` – вызывается при попытке вывести объект как строку
Магия: PHP сам вызывает этот метод, если echo или print пытаются вывести объект.
class Car {
public function __toString() {
return "Это машина!";
}
}

$car = new Car();
echo $car; // ✅ Выведет "Это машина!"


🟠`__get()` и `__set()` – перехватывают доступ к несуществующим свойствам
Магия: вызываются, если пытаемся получить или установить значение для несуществующего свойства.
class Person {
private array $data = [];

public function __get($name) {
return $this->data[$name] ?? "Нет такого свойства";
}

public function __set($name, $value) {
$this->data[$name] = $value;
}
}

$p = new Person();
$p->age = 30; // ❌ age не объявлен, но __set() сохранит его!
echo $p->age; // ✅ Выведет 30, хотя свойства age нет


🟠`__call()` – вызывается при вызове несуществующего метода
Магия: PHP автоматически вызывает __call(), если метод не найден.
class Robot {
public function __call($name, $arguments) {
return "Метод '$name' не существует!";
}
}

$r = new Robot();
echo $r->walk(); // ✅ Выведет "Метод 'walk' не существует!"


Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Что такое горизонтальное шардирование?

Горизонтальное шардирование разделяет данные на отдельные шарды по строкам, распределяя их между несколькими серверами. Это позволяет увеличивать масштаб за счёт добавления новых серверов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥1
🤔 Для чего нужно пространство имен в PHP?

Пространства имён (namespace) в PHP используются для разделения кода и предотвращения конфликтов имён классов, функций и констант.

🚩Почему нужны `namespace`?

Избегают конфликтов имён (если два разных файла объявляют одинаковые классы).
Упрощают организацию кода (структура похожа на файловую систему).
Работают с автозагрузкой (PSR-4) – Composer использует namespace для загрузки файлов.

🚩Пример использования `namespace`

Без пространства имён – конфликт классов
// Файл: models/User.php
class User {
public function getRole() {
return "Пользователь";
}
}

// Файл: controllers/User.php
class User {
public function getRole() {
return "Администратор";
}
}

// Ошибка! PHP не знает, какой User использовать.
$user = new User();


С namespace – классы разделены
// Файл: models/User.php
namespace App\Models;

class User {
public function getRole() {
return "Пользователь";
}
}

// Файл: controllers/User.php
namespace App\Controllers;

class User {
public function getRole() {
return "Администратор";
}
}

// Используем классы с указанием namespace
$modelUser = new App\Models\User();
echo $modelUser->getRole(); // ✅ "Пользователь"

$controllerUser = new App\Controllers\User();
echo $controllerUser->getRole(); // ✅ "Администратор"


🟠Импорт (`use`) – сокращает длинные пути
Вместо длинных App\Models\User, можно импортировать
use App\Models\User;

$user = new User(); // PHP понимает, что это App\Models\User


🟠Работа с функциями и константами
Пространства имён работают не только с классами, но и с функциями и константами.
namespace Utils;

function hello() {
return "Привет!";
}

echo hello(); // ✅ "Привет!"
echo \Utils\hello(); // ✅ "Привет!" (полный путь)


Ставь 👍 и забирай 📚 Базу знаний
🤔 Какой принцип нарушает Active Record?

Active Record нарушает принцип единственной ответственности (SRP) из SOLID.
1. В Active Record бизнес-логика и операции работы с базой данных объединены в одном классе.
2. Это усложняет поддержку, тестирование и расширение кода.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3🔥1
🤔 Почему symfony а не yii larevel?

Выбор между Symfony, Laravel и Yii зависит от множества факторов: сложности проекта, требований к производительности, удобства работы, документации и экосистемы. Давайте разберём, почему Symfony может быть предпочтительным вариантом.

🟠Гибкость и модульность (по сравнению с Laravel и Yii)
Symfony не монолитный, он построен на компонентах, которые можно использовать по отдельности.
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

$routes = new RouteCollection();
$routes->add('home', new Route('/home'));


🟠Производительность и масштабируемость
Symfony изначально создавался с акцентом на производительность и расширяемость.

🟠Современная архитектура (чем Laravel и Yii хуже)
Symfony следует чистой архитектуре SOLID и DDD (Domain-Driven Design).
Что это даёт
Чистый код (меньше "магии", как в Laravel).
Удобное тестирование (Mock объектов, KernelTestCase).
Поддержка CQRS, Event-Driven, Hexagonal Architecture.
class UserService {
private UserRepository $repo;

public function __construct(UserRepository $repo) {
$this->repo = $repo;
}

public function createUser(string $email): User {
return $this->repo->save(new User($email));
}
}


🟠Корпоративные решения (где Laravel и Yii не подходят)
Symfony часто используется в крупных проектах и государственных системах.

🟠Поддержка и сообщество
Symfony поддерживается разработчиками из SensioLabs и сообществом Symfony.
Laravel больше зависит от одного разработчика (Taylor Otwell).
Yii меньше поддерживается и отстаёт в развитии.

Ставь 👍 и забирай 📚 Базу знаний
💊4🤔2