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

Контакт для рекламы: @easyoffer_adv
Download Telegram
🤔 Что такое middleware?

Middleware в PHP — это компонент, который обрабатывает HTTP-запросы и ответы на пути между сервером и конечной точкой. Каждый middleware может модифицировать запрос, ответ или остановить выполнение цепочки, отправив ответ напрямую. Они используются для выполнения задач, таких как аутентификация, логирование, обработка ошибок и кэширование. Middleware широко применяется в современных фреймворках, таких как Laravel, для разделения логики обработки запросов.

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

При развёртывании приложения в Docker важно минимизировать время сборки и оптимизировать слои контейнера.

🟠Использовать `.dockerignore`
Не копировать лишние файлы в контейнер (например, node_modules, .git, vendor, .env).
.git
node_modules
vendor
.env
*.log


🟠Оптимизировать `Dockerfile` (Меньше слоёв, кэширование)
Плохо (лишние слои, без кэширования)
FROM php:8.2-cli

WORKDIR /app

COPY . . # Копирует ВСЕ файлы (долго и некэшируемо)
RUN composer install
RUN npm install
RUN npm run build


Хорошо (разделение слоёв, кэширование)
FROM php:8.2-cli

WORKDIR /app

COPY composer.json composer.lock ./
RUN composer install --no-dev --prefer-dist # Используем кэширование слоёв

COPY package.json package-lock.json ./
RUN npm install --only=production && npm cache clean --force

COPY . . # Копируем код ПОСЛЕ установки зависимостей (чтобы кэширование работало)
RUN npm run build


🟠Использовать `multi-stage builds` (если контейнер весит много)
Позволяет уменьшить размер конечного образа, убрав ненужные файлы и инструменты.
# 1-й этап: сборка зависимостей (Node.js)
FROM node:18 as frontend
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

# 2-й этап: финальный образ
FROM php:8.2-cli
WORKDIR /app
COPY --from=frontend /app/dist /app/public # Берём только готовые файлы
COPY . .
CMD ["php", "artisan", "serve", "--host=0.0.0.0"]


🟠Использовать `docker build --cache-from`
Позволяет использовать кеш из предыдущих сборок.
docker build --cache-from=myapp:latest -t myapp .


🟠Оптимизировать `docker-compose` (если используется)
Перенести volume для vendor и node_modules на хост, чтобы не скачивать их в контейнере.
services:
app:
build: .
volumes:
- .:/app
- /app/vendor # Чтобы composer install не запускался каждый раз
- /app/node_modules # Чтобы npm install не замедлял перезапуск


🟠Использовать `Alpine Linux` (если важен размер образа)
Alpine – лёгкая версия Linux (~5 MB), подходит для PHP, Nginx, Node.js.
FROM php:8.2-fpm-alpine


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Какие могут быть проблемы от JOIN'а?

Объединение таблиц через JOIN может вызвать:
- Снижение производительности – если таблицы большие и нет индексов, выполнение запроса может быть долгим.
- Дублирование данных – неправильное соединение может привести к множеству дублирующихся строк.
- Рост потребления памяти – большие JOIN'ы могут потреблять много оперативной памяти и временных файлов.
- Блокировки и конкуренция – если JOIN выполняется на обновляемых данных, могут возникать блокировки записей.
- Сложность оптимизации – сложные JOIN'ы труднее индексировать и оптимизировать.


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

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

🚩Основные особенности замыканий

🟠Доступ к внешним переменным
Функция может использовать переменные из внешнего контекста, в котором она была создана.
🟠Сохранение состояния
Замыкания могут сохранять состояние между вызовами.

🟠Инкапсуляция
Замыкания могут использоваться для создания частных данных и методов.

🚩Примеры замыканий в различных языках программирования

🟠JavaScript
В JavaScript замыкания используются очень часто. Рассмотрим простой пример:
function createCounter() {
let count = 0; // внешняя переменная

return function() { // внутренная функция
count++;
return count;
}
}

const counter = createCounter(); // создаем замыкание
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3


🟠Python
В Python замыкания также поддерживаются:
def create_counter():
count = 0

def increment():
nonlocal count
count += 1
return count

return increment

counter = create_counter()
print(counter()) # 1
print(counter()) # 2
print(counter()) # 3


🟠PHP
В PHP замыкания реализуются через анонимные функции и использование use:
function createCounter() {
$count = 0;

return function() use (&$count) {
$count++;
return $count;
};
}

$counter = createCounter();
echo $counter(); // 1
echo $counter(); // 2
echo $counter(); // 3


🚩Применение замыканий

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

🟠Инкапсуляция
Замыкания позволяют скрывать переменные и методы внутри функции, предоставляя интерфейс для взаимодействия с ними.

🟠Обработка событий
В языках, таких как JavaScript, замыкания часто используются в обработчиках событий для доступа к контексту, в котором был назначен обработчик.

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

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

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


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

Сложность функции можно оценить с помощью Big O (O-нотация) – это способ понять, как увеличивается время работы функции при росте входных данных.

🚩Определение сложности по Big O

Константные операции (+, -, *, /, if, return) считаются за O(1).
Циклы (for, while) увеличивают сложность** (например, for на N итераций → O(N)).
Вложенные циклы (for внутри for) дают O(N²).
Рекурсия учитывается как глубина рекурсии.

🚩Примеры расчёта сложности

Простая функция (O(1)) – не зависит от входных данных
function addNumbers($a, $b) {
return $a + $b;
}


Линейная сложность O(N) (цикл)
function printNumbers($n) {
for ($i = 0; $i < $n; $i++) {
echo $i;
}
}


Квадратичная сложность O(N²) (вложенные циклы)
function printPairs($n) {
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n; $j++) {
echo "($i, $j) ";
}
}
}


Логарифмическая сложность O(log N) (деление пополам, бинарный поиск)
function binarySearch($arr, $target) {
$left = 0;
$right = count($arr) - 1;

while ($left <= $right) {
$mid = floor(($left + $right) / 2);

if ($arr[$mid] == $target) {
return $mid;
} elseif ($arr[$mid] < $target) {
$left = $mid + 1;
} else {
$right = $mid - 1;
}
}
return -1;
}


Факториальная сложность O(N!) (перебор всех вариантов)
function factorial($n) {
if ($n == 1) return 1;
return $n * factorial($n - 1);
}


🚩Как считать сложность функции с разными действиями?

Если в функции разные действия, считаем их отдельно и берём наибольшую сложность.
function complexFunction($n) {
// O(1)
$sum = 0;

// O(N)
for ($i = 0; $i < $n; $i++) {
$sum += $i;
}

// O(N²)
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n; $j++) {
echo "Hello";
}
}

return $sum;
}


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

Это запись событий, ошибок и действий приложения в журнал для диагностики и анализа.
1. Логи помогают отслеживать выполнение кода, анализировать сбои и выявлять узкие места.
2. Используются различные уровни логов: INFO, DEBUG, ERROR.
3. Это важный инструмент для отладки, мониторинга и аудита системы.


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

Strict mode (Строгий режим) в PHP — это режим, который заставляет PHP строго проверять типы аргументов в функциях.

По умолчанию PHP автоматически преобразует типы (например, "10" превращается в 10), но в строгом режиме такая конвертация запрещена — если тип не совпадает, будет ошибка.

🚩Как включить strict mode?

Строгий режим включается в начале PHP-файла с помощью:
declare(strict_types=1);


🚩Пример работы strict mode

Без строгого режима (PHP сам меняет типы)
function sum(int $a, int $b) {
return $a + $b;
}

echo sum("5", 10); // 15 (PHP сам превратит "5" в 5)


Со strict mode (жёсткая проверка типов)
declare(strict_types=1);

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

echo sum("5", 10); // ❌ ФАТАЛЬНАЯ ОШИБКА!


🚩Зачем нужен strict mode?

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

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

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


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

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

🚩Основные цели

🟠Выявление ошибок и дефектов
Найти и исправить ошибки, которые могли возникнуть в ходе разработки. Это помогает предотвратить сбои в работе программы.

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

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

🟠Обеспечение пользовательского опыта
Убедиться, что конечные пользователи получат продукт, который удовлетворяет их потребности и ожидания, обеспечивая тем самым положительный пользовательский опыт.

🚩Типы

🟠Функциональное тестирование
Проверка того, что каждый компонент системы работает в соответствии с требованиями.
🟠Нефункциональное тестирование
Проверка аспектов, не связанных напрямую с функциональностью, таких как производительность, безопасность, удобство использования и т.д.
🟠Юнит-тестирование
Тестирование отдельных компонентов или модулей кода.
🟠Интеграционное тестирование
Проверка взаимодействия между различными модулями или компонентами системы.
🟠Системное тестирование
Полная проверка всей системы в целом.
🟠Приемочное тестирование
Проверка системы на соответствие бизнес-требованиям и готовность к использованию конечными пользователями.
use PHPUnit\Framework\TestCase;

class CalculatorTest extends TestCase {
public function testAdd() {
$calc = new Calculator();
$this->assertEquals(4, $calc->add(2, 2));
$this->assertEquals(0, $calc->add(-1, 1));
}
}

class Calculator {
public function add($a, $b) {
return $a + $b;
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Реализация Fibonacci с рекурсией или без?

1. С рекурсией: проще написать, но требует больше памяти из-за вложенных вызовов.
2. Без рекурсии: итеративный метод или использование динамического программирования, эффективнее с точки зрения производительности.
3. Выбор зависит от задачи: рекурсия подходит для демонстрации, итерация — для практических целей.


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

декремент — это операция, используемые для увеличения или уменьшения значения переменной на единицу соответственно.

🚩Декремент


Оператор уменьшает значение переменной на единицу. Он представлен двумя минусами (--). Так же, как и инкремент, декремент бывает двух видов:

🟠Префиксный декремент (`--x`)
Сначала уменьшает значение переменной на единицу, затем возвращает новое значение.
🟠Постфиксный декремент (`x--`)
Возвращает текущее значение переменной, а затем уменьшает его на единицу.

<?php
$x = 10;
$y = 10;

// Пример префиксного инкремента
echo ++$x; // Выводит 11, x теперь равен 11

// Пример постфиксного инкремента
echo $y++; // Выводит 10, y теперь равен 11
echo $y; // Выводит 11

// Пример префиксного декремента
echo --$x; // Выводит 10, x теперь равен 10

// Пример постфиксного декремента
echo $y--; // Выводит 11, y теперь равен 10
echo $y; // Выводит 10
?>


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

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


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

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

🚩Нормализация

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

🚩Цели нормализации

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

🚩Этапы нормализации

1⃣Первая нормальная форма (1NF)
Удаление повторяющихся групп и дублирующихся данных.
2⃣Вторая нормальная форма (2NF)
Устранение частичной зависимости данных от составного ключа.
3⃣Третья нормальная форма (3NF)
Устранение транзитивной зависимости (когда данные зависят не от первичного ключа напрямую, а через другие поля).
4⃣Далее
BCNF (нормальная форма Бойса-Кодда) и другие более сложные формы.

🚩Денормализация

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

🚩Цели денормализации

🟠Ускорение чтения данных
Объединение таблиц или добавление дублированных данных уменьшает количество соединений (JOIN) между таблицами.

SELECT o.OrderID, c.CustomerName, p.ProductName, p.ProductPrice
FROM Orders o
JOIN Customers c ON o.CustomerID = c.CustomerID
JOIN Products p ON o.ProductID = p.ProductID;


Ставь 👍 и забирай 📚 Базу знаний
🤔 Какие структуры данных в программировании существуют?

Основные структуры:
- Линейные: массивы, списки, очереди, стеки.
- Нелинейные: деревья, графы.
- Ассоциативные: хеш-таблицы, словари.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 В чем преимущество 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';


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

1. Класс DateTime в PHP предоставляет объектно-ориентированный способ работы с датой и временем.
2. Он позволяет создавать, изменять, форматировать и сравнивать даты.
3. Также включает функционал для работы с временными зонами через класс DateTimeZone.
4. Упрощает работу с датами благодаря методам, таким как add(), sub(), и форматированию с помощью format().


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

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

🚩Зачем нужен полнотекстовый индекс?

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

🚩Как работает полнотекстовый индекс?

🟠Индексация
Когда создаётся полнотекстовый индекс, база данных анализирует текстовые данные, разбивает их на слова (токены) и сохраняет их в особой структуре индекса.
🟠Поиск
При выполнении запроса база данных ищет совпадения среди токенов в индексе, а не в самом тексте.
🟠Релевантность
Полнотекстовый индекс учитывает частоту появления слов и их позицию, чтобы выдавать результаты, наиболее соответствующие запросу.

🚩Использование полнотекстового индекса в MySQL

🟠Создание полнотекстового индекса
Полнотекстовый индекс можно создавать для столбцов типа CHAR, VARCHAR, или TEXT.
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
content TEXT,
FULLTEXT(title, content)
);


🟠Поиск с использованием полнотекстового индекса
Для выполнения полнотекстового поиска используется оператор MATCH ... AGAINST.
SELECT * 
FROM articles
WHERE MATCH(title, content) AGAINST('PHP tutorial');


🟠Модели поиска
Natural Language Mode: Поиск слов и фраз с учётом их важности.
Boolean Mode: Позволяет использовать логические операторы (например, + для обязательных слов, - для исключаемых).
Query Expansion: Автоматически расширяет запрос с помощью синонимов или связанных слов.
SELECT * 
FROM articles
WHERE MATCH(title, content) AGAINST('+PHP -Java' IN BOOLEAN MODE);


🚩Ограничения полнотекстового индекса

🟠Минимальная длина слова
По умолчанию слова короче 3 символов игнорируются (это настраивается).
🟠Стоп-слова
Некоторые часто встречающиеся слова (например, "and", "the") исключаются из индексации.
🟠Чувствительность к языку
Важно учитывать настройки языка для анализа текста.
🟠Поддержка типов данных
Полнотекстовые индексы доступны только для текстовых полей.

🚩Плюсы

➕Быстрый поиск по большим объемам текста.
➕Удобная работа с нерелевантными данными (например, похожими словами).
➕Возможность вычисления ранжирования (релевантности) результатов.

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

PHP 8 усилил строгую типизацию, добавив поддержку объединённых типов (Union Types). Также введены типы mixed и static, расширяющие возможности определения данных. Улучшена работа с привидением типов, исключая двусмысленности, чтобы снизить вероятность ошибок.

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

Если говорить о разделении модулей на более высоком уровне, чем классы, то мы ориентируемся на архитектурные принципы. Основной подход — разделение ответственности (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 (оплата)
- Удобно при высокой нагрузке и масштабировании.

Ставь 👍 и забирай 📚 Базу знаний
🔥1
🤔 Что запрещает final?

Модификатор final запрещает наследование класса, если он указан перед его объявлением.
Если final используется для метода, он запрещает переопределение этого метода в дочерних классах.


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