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

Контакт для рекламы: @sendme_ads
Download Telegram
🤔 В чем заключается обработка ошибок и исключений?

Это механизм выявления и реагирования на непредвиденные ситуации в коде.
- Ошибки (Errors) – критические сбои (OutOfMemoryError, StackOverflowError).
- Исключения (Exceptions) – проблемы в логике (NullPointerException, IOException).
Обрабатываются с помощью try-catch-finally, throw, throws, а также глобальных обработчиков (onError, fallback strategies).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 По какому принципу бы старались разделять модули, если находились бы не на уровне классов, а выше?

Если говорить о разделении модулей на более высоком уровне, чем классы, то мы ориентируемся на архитектурные принципы. Основной подход — разделение ответственности (Separation of Concerns, SoC).

🚩Основные принципы разделения модулей

🟠SRP (Single Responsibility Principle, Принцип единственной ответственности)
- Каждый модуль решает только одну задачу.
- Например, отдельно: модуль аутентификации, модуль работы с БД, модуль обработки заказов.

🟠MVC (Model-View-Controller)
- Разделение приложения на модель (логика данных), представление (интерфейс), контроллер (управление логикой).
- Например, в Laravel:
- Models/ — работа с данными
- Views/ — шаблоны
- Controllers/ — обработка запросов

🟠Чистая архитектура (Clean Architecture, Hexagonal, Onion)
- Модули делятся на уровни, где:
- Центральная часть — доменная логика (независимая от фреймворка).
- Внешние слои — адаптеры, API, базы данных.
- Код становится гибким и легко тестируемым.

🟠DDD (Domain-Driven Design, Предметно-ориентированное проектирование)
- Разделение по бизнес-контексту (Bounded Contexts).
- Например, в интернет-магазине:
- Модуль заказов (Orders)
- Модуль оплаты (Payments)
- Модуль пользователей (Users)

🟠Микросервисная архитектура
- Разделение системы на отдельные сервисы, которые общаются через API.
- Например:
- auth-service (регистрация, вход)
- order-service (работа с заказами)
- payment-service (оплата)
- Удобно при высокой нагрузке и масштабировании.

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

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2
🤔 Что делает бэк-слеш перед глобальными функциями?

В PHP бэкслеш (\) перед именем функции или класса указывает, что мы обращаемся к глобальному пространству имён. Это важно, если код находится внутри namespace.

🚩Почему это важно?

🟠Пространства имён могут переопределять глобальные функции
Если внутри namespace есть функция с таким же именем, то PHP будет искать её внутри пространства имён, а не в глобальном пространстве.
namespace App;

function strlen($str) {
return "Фейковая длина строки";
}

echo strlen("Hello!"); // Выведет: "Фейковая длина строки"


🟠Бэкслеш заставляет PHP искать функцию в глобальном пространстве
Пример использования \ для вызова стандартной функции PHP
namespace App;

function strlen($str) {
return "Фейковая длина строки";
}

echo \strlen("Hello!"); // Выведет: 6 (из стандартной библиотеки PHP)


🟠Используется для ускорения работы кода
PHP не будет искать функцию внутри namespace, а сразу возьмёт глобальную версию. Это немного ускоряет выполнение.
namespace App;

$t1 = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
time(); // PHP ищет в namespace, потом в глобальном
}
$t2 = microtime(true);
echo "Обычный вызов: " . ($t2 - $t1) . " секунд\n";

$t1 = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
\time(); // PHP сразу берёт глобальную функцию
}
$t2 = microtime(true);
echo "С бэкслешем: " . ($t2 - $t1) . " секунд\n";


Ставь 👍 и забирай 📚 Базу знаний
🔥1
🤔 Что делает бэкслеш перед глобальными функциями?

Бэкслеш (\) используется для обращения к глобальным функциям или классам, чтобы избежать их переопределения в текущем пространстве имён.
Например, \strlen() вызовет глобальную функцию strlen, а не её версию из текущего namespace.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥3
🤔 В чем преимущество hash индекс и btree индекс?

Hash-индексы и B-Tree-индексы являются двумя типами индексов, используемыми для ускорения операций поиска в базах данных. Оба типа имеют свои преимущества и недостатки в зависимости от конкретных сценариев использования.

🚩Hash-индексы

➕Быстрый доступ по точному совпадению
Hash-индексы обеспечивают очень быстрый доступ к данным при выполнении точных поисков (например, SELECT * FROM table WHERE column = 'value'). Время поиска практически константное (O(1)), что делает такие запросы очень эффективными.
➕Простота реализации
Hash-индексы просты в реализации и не требуют сложных структур данных для управления.

🚩B-Tree-индексы

➕Поддержка диапазонных запросов
B-Tree-индексы поддерживают операции поиска по диапазону и сортировку (например, BETWEEN, >, <, ORDER BY). Данные в B-Tree отсортированы, что делает такие запросы возможными и эффективными.

➕Сбалансированность
B-Tree автоматически поддерживает балансировку, что обеспечивает стабильную производительность для всех операций (поиск, вставка, удаление).

➕Универсальность
B-Tree-индексы поддерживают широкий спектр операций и типов данных, включая текстовые данные, даты и числа.

🟠Hash-индекс
Подходит для сценариев, где часто выполняются точные запросы равенства, например, поиск пользователя по уникальному идентификатору или email.
CREATE INDEX idx_email_hash ON users USING HASH (email);

SELECT * FROM users WHERE email = 'example@example.com';


🟠B-Tree-индекс
Подходит для сценариев, где часто выполняются диапазонные запросы, сортировка или комбинированные условия.
CREATE INDEX idx_name_btree ON users (name);

SELECT * FROM users WHERE name BETWEEN 'A' AND 'M';


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

1. Base64: для передачи бинарных данных в текстовом формате.
2. URL Encoding: преобразование специальных символов в безопасный формат для URL.
3. ASCII и Unicode: для кодировки символов.
4. JSON и XML: для структурирования данных.
5. UTF-8: стандарт кодировки текста.


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

В PHP можно организовать обработку данных порциями разными способами, в зависимости от того, с чем именно мы работаем: с базой данных, файлами или массивами. Основные методы:
SQL-запрос с LIMIT и OFFSET
Чтение файла построчно (fgets(), SplFileObject)
Итерация по массиву с array_chunk()
Использование генераторов (yield)

🟠Постраничная выборка в SQL (`LIMIT` + `OFFSET`)
При работе с базой данных мы можем загружать данные порциями с помощью LIMIT и OFFSET
$limit = 10;  // Количество записей на страницу  
$offset = 0; // Смещение (номер страницы * $limit)

$sql = "SELECT * FROM users ORDER BY id LIMIT $limit OFFSET $offset";
$result = $pdo->query($sql)->fetchAll();


Альтернативный вариант – постраничная выборка без OFFSET
$last_id = 0;
$sql = "SELECT * FROM users WHERE id > $last_id ORDER BY id LIMIT $limit";


🟠Чтение файла порциями (`fgets()`, `SplFileObject`)
При работе с большими файлами можно читать их построчно, а не загружать в память целиком.fgets() – чтение построчно
$handle = fopen("large_file.txt", "r");
while (($line = fgets($handle)) !== false) {
echo $line;
}
fclose($handle);


SplFileObject – более удобный способ
$file = new SplFileObject("large_file.txt");
while (!$file->eof()) {
echo $file->fgets();
}


🟠Разделение массива на порции (`array_chunk()`)
Если у нас массив данных, можно разбить его на части
$data = range(1, 100);
$chunks = array_chunk($data, 10);

foreach ($chunks as $chunk) {
print_r($chunk); // Выведет массивы по 10 элементов
}


🟠Генераторы (`yield`) – ленивый способ
Генераторы позволяют возвращать элементы по одному, не загружая всё в память сразу.
function getData() {
for ($i = 1; $i <= 100; $i++) {
yield $i; // Возвращает по одному значению
}
}

foreach (getData() as $num) {
echo $num . "\n";
}


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

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


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

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

🚩Виды типизации

🟠Статическая типизация:
Типы переменных известны и проверяются на этапе компиляции. Примеры языков: Java, C++, TypeScript.
🟠Динамическая типизация:
Типы переменных определяются и проверяются во время выполнения программы. Примеры языков: Python, JavaScript, PHP.
🟠Сильная типизация:
Язык строго следит за типами, не позволяя неявные преобразования между ними. Примеры языков: Haskell, Java.
🟠Слабая типизация:
Язык допускает неявные преобразования между типами. Примеры языков: PHP, JavaScript.

PHP — язык с динамической и слабой типизацией, но с версией 7.0 и выше появилась возможность использовать строгую типизацию.
$number = 10;
$number = "ten"; // PHP позволяет это, так как тип переменной может изменяться


С PHP 7.0 можно использовать строгую типизацию для функций и методов. Это позволяет явно указывать, какого типа аргументы и возвращаемое значение должны быть.
declare(strict_types=1); // Включает строгую типизацию

function add(int $a, int $b): int {
return $a + $b;
}

echo add(2, 3); // Работает
// echo add(2, "3"); // Ошибка, так как второй аргумент не является целым числом


🚩Плюсы

➕Предотвращение ошибок:
Типизация помогает обнаруживать ошибки на ранних этапах разработки, таких как попытка выполнения некорректных операций с данными.
➕Улучшение читаемости и поддержки кода:
Явное указание типов делает код более понятным и предсказуемым, что облегчает его поддержку и развитие.
➕Оптимизация выполнения:
Статически типизированные языки позволяют компиляторам оптимизировать выполнение кода, так как типы известны на этапе компиляции.
➕Документирование кода:
Типизация служит дополнительной документацией, помогая разработчикам понять, какие данные ожидаются и возвращаются функциями и методами.

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

Создать ветку в Git можно:
1. Командой git branch <имя> – создаст новую ветку.
2. git checkout -b <имя> – создаст и сразу переключится.
3. git switch -c <имя> – альтернатива checkout.
4. В графических интерфейсах (GitKraken, SourceTree) – создание через UI.
5. В удаленном репозитории (GitHub, GitLab) – через web-интерфейс


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

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

🟠Атомарность (Atomicity)

Гарантирует, что все операции в рамках одной транзакции либо выполняются полностью, либо не выполняются вообще. Если какая-либо часть транзакции не может быть завершена, система откатит все уже выполненные операции, возвращая базу данных в состояние, которое существовало до начала транзакции. Это "всё или ничего".

🟠Согласованность (Consistency)

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

🟠Изолированность (Isolation)
Определяет способ одновременного выполнения множества транзакций без оказания влияния друг на друга. Это свойство предотвращает проблемы, связанные с одновременным доступом, такие как "грязное чтение", "неповторяющееся чтение" и "фантомное чтение". СУБД обычно предлагают различные уровни изоляции, которые могут быть настроены в зависимости от нужд приложения.

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

Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Как настроить autoload через Composer?

Composer предоставляет механизм автоматической загрузки классов (autoload), который позволяет не писать вручную require.
Основные шаги:
1. Использовать PSR-4 или PSR-0 – правила именования классов.
2. Настроить autoload в composer.json – указать, какие пространства имен использовать.
3. Выполнить composer dump-autoload – обновить автозагрузку после изменения файлов.
4. Использовать require 'vendor/autoload.php' – подключить автозагрузку в проекте.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍4🔥1
🤔 Что делают self и static?

В PHP self и static используются внутри классов для обращения к их свойствам и методам, но работают по-разному. Давайте разберёмся в их назначении и отличиях.

🚩self

Используется для обращения к собственным методам и свойствам класса. Оно не учитывает наследование и всегда ссылается на тот класс, в котором написано.
class A {
public static function who() {
echo "Я класс A\n";
}

public static function call() {
self::who(); // Вызываем метод who() внутри того же класса
}
}

class B extends A {
public static function who() {
echo "Я класс B\n";
}
}

B::call(); // Выведет: "Я класс A", а не "Я класс B"


🚩static

Работает динамически, учитывает класс, из которого вызван метод. Это полезно в наследовании.
class A {
public static function who() {
echo "Я класс A\n";
}

public static function call() {
static::who(); // Используем static вместо self
}
}

class B extends A {
public static function who() {
echo "Я класс B\n";
}
}

B::call(); // Выведет: "Я класс B"


Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 В чём суть абстрактного класса?

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

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

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

🚩Зачем нужен Middleware

🟠Управление запросами
Может изменять или проверять запросы перед передачей их в приложение. Например, оно может проверять наличие валидных токенов доступа для аутентификации или осуществлять проверку прав доступа.

🟠Перехват ответов
Также может изменять ответы перед тем, как они будут отправлены пользователю, например, добавлять нужные заголовки HTTP или сжимать данные.

🟠Логирование и мониторинг
Оно может записывать информацию о запросах и ответах для анализа трафика или обнаружения ошибок.

🟠Обработка ошибок
Часто используется для централизованной обработки ошибок, позволяя управлять ошибками элегантно и единообразно.

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class CheckAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (!Auth::check()) {
return redirect('/login');
}

return $next($request);
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Какие паттерны знаешь?

В программировании и разработке ПО существует множество паттернов проектирования, включая:
- Порождающие: Singleton, Factory, Builder, Prototype.
- Структурные: Adapter, Decorator, Facade, Proxy, Bridge.
- Поведенческие: Observer, Strategy, Command, State, Template Method, Iterator, Mediator.
Эти паттерны помогают решать общие проблемы проектирования, повышая уровень абстракции и уменьшая связность компонентов?


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2
🤔 Какие могут быть проблемы от Join'а?

Использование JOIN в SQL может привести к нескольким проблемам, особенно при работе с большими таблицами. Рассмотрим основные из них.

🟠Производительность (нагрузка на БД)
Чем больше данных соединяется, тем больше ресурсов требуется.
Проблема: JOIN создаёт временную таблицу в памяти, что замедляет запрос. Если нет индексов, соединение идёт через полный перебор (Nested Loop Join), что очень медленно.
Решение:
Добавить индексы на поля, по которым идёт соединение.
Использовать EXPLAIN для анализа запроса.
EXPLAIN SELECT * FROM users JOIN orders ON users.id = orders.user_id;


🟠Дублирование строк (Картезианское произведение)
Если используется JOIN, но нет условия соединения (ON), запрос создаст все возможные комбинации строк.
Проблема:
SELECT * FROM users, orders;


Решение
Всегда указывать ON или USING:
SELECT * FROM users JOIN orders ON users.id = orders.user_id;


🟠Потеря данных при `INNER JOIN`
INNER JOIN возвращает только совпадающие строки, из-за чего можно потерять данные.
Проблема
SELECT users.id, users.name, orders.id AS order_id  
FROM users
INNER JOIN orders ON users.id = orders.user_id;


Решение: Использовать LEFT JOIN, если нужны все пользователи, даже без заказов:
SELECT users.id, users.name, orders.id AS order_id  
FROM users
LEFT JOIN orders ON users.id = orders.user_id;


🟠Медленный `JOIN` на `TEXT` или `VARCHAR`
JOIN по строковым полям (VARCHAR, TEXT) работает медленнее, чем по числовым (INT).
Проблема
SELECT * FROM users JOIN orders ON users.email = orders.email;


🟠Несовместимость типов данных
Если соединяются таблицы с разными типами данных (INT vs VARCHAR), может быть скрытое приведение типов, которое замедляет запрос.
Проблема
SELECT * FROM users  
JOIN orders ON users.id = orders.user_id;


Решение
- Убедиться, что типы данных совпадают (INT = INT).
- Привести к нужному типу:
SELECT * FROM users  
JOIN orders ON users.id = CAST(orders.user_id AS INT);


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

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


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

Анонимные классы в PHP были введены в версии 7.0 и позволяют создавать одноразовые объекты без необходимости предварительного объявления класса. Они имеют несколько преимуществ и предназначены для решения ряда задач в программировании. Вот основные причины и случаи, для которых они были придуманы:

🚩Зачем придумали анонимные классы

🟠Упрощение кода
Анонимные классы позволяют создать класс на месте, в том же файле, где он используется, без необходимости его предварительного определения. Это упрощает и сокращает код, особенно для одноразовых задач.
$logger = new class {
public function log($message) {
echo $message;
}
};

$logger->log("Hello, World!"); // Выведет: Hello, World!


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

🟠Использование одноразовых объектов
Анонимные классы удобны, когда нужно создать объект для одноразового использования, например, в тестах, или для передачи в функции или методы.
function handleRequest($handler) {
$handler->process();
}

handleRequest(new class {
public function process() {
echo "Processing request";
}
}); // Выведет: Processing request


🟠Более гибкая реализация интерфейсов и абстрактных классов:
Анонимные классы могут реализовывать интерфейсы или наследовать от абстрактных классов, предоставляя быстрый способ создать конкретные реализации на месте.
interface Logger {
public function log($message);
}

$logger = new class implements Logger {
public function log($message) {
echo $message;
}
};

$logger->log("Logging message"); // Выведет: Logging message


🟠Улучшение тестирования
В юнит-тестах анонимные классы позволяют быстро создавать мок-объекты (mock objects) для тестирования без необходимости создавать отдельные классы для каждой тестовой ситуации.
class Service {
private $logger;

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

public function execute() {
$this->logger->log("Service executed");
}
}

$mockLogger = new class {
public function log($message) {
echo "Mock: " . $message;
}
};

$service = new Service($mockLogger);
$service->execute(); // Выведет: Mock: Service executed


Ставь 👍 и забирай 📚 Базу знаний
🤔 Какие типы БД бывают?

Базы данных делятся на реляционные (SQL) и нереляционные (NoSQL). Реляционные базы данных (например, MySQL, PostgreSQL) хранят данные в виде таблиц и используют SQL для запросов. Нереляционные базы данных (например, MongoDB) используют разные модели данных (документы, ключ-значение и т.д.), что делает их более гибкими для работы с большими объёмами данных и неструктурированной информацией.

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