Ниже — разбор очередных вопросов и задачек, которые могут попасться на собеседовании на должность middle-php-developer-a. Мне вопросы и задачки показались не сложными, справился со всеми, ответы ниже.

(!) Если вы хотите качественно подготовиться к собеседованиям на должность веб-разработчика php, рекомендую скачать мою авторскую книгу на эту тему. Здесь разобраны все популярные вопросы и задачи, которые встречаются на собеседованиях. Вопросы/задачи собраны с реальных интервью, пройденных мной на протяжении последних 5+ лет. Все вопросы и задачи подробно разобраны.

/**/


Вопросы

  • Есть опыт написания API для интеграции с внешними системами ?

    • можно привести пример любой реализованной API…

  • Можно ли в интерфейсы добавлять свойства/константы ?

    • свойства — нет, константы — да

  • Можно ли наследовать интерфейсы?

    • да

  • Для чего нужны абстрактные классы?

    • Абстрактные классы — это такие классы, которые не могут создавать объекты и нужны лишь для того, чтобы дополнить работу основных классов и избавить нас от повторяющегося кода.

  • Что такое магические методы? Перечисли основные.

    • __construct() — при создании нового объекта класса, __destruct() — вызывается при уничтожении объекта класса, __get() — при попытке получить значение несуществующего свойства объекта, __set() — при попытке установить значение несуществующего свойства объекта, __call() — при попытке вызвать несуществующий метод объекта, __toString() — при попытке преобразовать объект в строку, __clone() — при клонировании объекта, __isset() — при проверке существования свойства объекта, __unset() — при удалении свойства объекта.

    • [ wiki ]

  • Что такое трейты?

    • Трейты Трейты (англ. traits) — это механизм обеспечения повторного использования кода в языках с поддержкой единого наследования. Они позволяют разработчику повторно использовать наборы методов и свойств в нескольких независимых классах. Трейт похож на класс, но создать экземпляр трейта невозможно. Он предназначен для группирования функционала, который потом используется в разных классах. [ блог , wiki ]

  • Можно ли подключить трейт в трейте?

    • можно

  • Зачем нужны генераторы ?

    • для экономии памяти при работе с большими объемами данных (память выделяется лишь на текущую порцию данных) [ блог , wiki ]

  • Зачем нужны транзакции?

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

      Транзакции позволяют надежно модифицировать данные в многопользовательских системах, обеспечивают целостность и непротиворечивость данных. [ wiki ]

  • Какие есть виды индексов в БД?

    • Простые и составные (по одному или нескольким полям)

    • По типам:

      • B-tree — индексы на основе сбалансированных деревьев (B-деревьев)

      • Hash-индекс — индекс на основе хеш-таблицы, быстрый поиск по равенству.

      • R-дерево — пространственный индекс для геометрических данных.

      • Индексы на основе bitmask — устанавливают биты по определенным правилам.

      • Плоские файлы — простой индекс в виде отсортированного файла значений.

      • Индексы по триграммам — для поиска похожих текстовых значений.

      • Полнотекстовые индексы — инвертированные списки слов для поиска в тексте.

      • Multi-index — несколько вложенных индексов разных типов.

      • Индексы по выражениям — виртуальные индексы, зависящие от логики приложения.

      • Кластерные индексы — сортируют данные физически. [ блог , wiki ]

  • В чем разница между операторами where и having ?

    • WHERE ставит условия на строки, возвращаемые из исходных таблиц запроса.

    • HAVING ставит условия на строки, возвращаемые из сформированного результата (например, после группировки с GROUP BY). [ блог , wiki ]

  • Зачем нужно кеширование?

    • для ускорения работы приложений: нет необходимости обращаться к ресурсу, если данные по нему закешированы

  • Какие паттерны знаешь/используешь?

    • Достаточно назвать 3-5 паттернов , их разбор тут: [ блог , wiki ]


Задачи

Задача №1: “Лучшие книги”

Дамп БД:

create table if not exists book_rating (
  book_id int,
  country int,
  rating int
);
 
insert into book_rating (book_id, country, rating) values
(1, 1, 5),
(1, 1, 5),
(1, 2, 5),
(1, 1, 4),
 
(2, 1, 5),
(2, 2, 5),
(2, 2, 4),
(2, 1, 5),
 
(3, 1, 4),
(3, 1, 5),
(3, 2, 4),
(3, 2, 5);

Найти книги у которых только пятерки в стране 1?

Решение

Для поиска книг, которые имеют только оценки 5 в стране 1, можно использовать следующий запрос:

SELECT book_id
FROM book_rating 
WHERE country = 1
GROUP BY book_id
HAVING MIN(rating) = 5 AND MAX(rating) = 5;

# Или проще:
select * from book_rating 
where country = 1 
group by book_id
HAVING MIN(rating) >= 5;

Этот запрос сгруппирует записи по book_id и отберет только те группы, где минимальный и максимальный рейтинг равны 5.

Таким образом в результат попадут только книги, которые имеют в стране 1 только оценки 5.

(звезда) Экспериментируем с live-coding тут


Задача 2: Сумма всего массива

Найти сумму всех значений массива, со сложной (вложенной/иерархической) структурой.

<?php

/*
Найти сумму всех значений массива.
*/

class Task
{
    public function main(array $array): int
    {

    }

    public function __invoke()
    {
        $testData = [
            100,
            [
                200,
                300,
                [
                    50,
                    [
                        50,
                        [
                            300,
                        ],
                    ],
                ],
            ],
            200,
            [
                300,
                [
                    100,
                    [
                        100,
                        100,
                        200,
                    ],
                ],
            ],
        ];

        $result = $this->main($testData) === 2000;
        echo '[' . ($result ? 'OK' : 'FAIL') . "]n";
    }
}

(new Task())();

Решение:

    public function main(array $array): int
    {
         $ret = 0;
      
         foreach($array as $el) {
             if(is_array($el)) {
                 $ret += $this->main($el);
             } else {
               $ret += $el;
             }
         }

         return $ret;
    }

Доп. вопрос: а как обойтись тут без рекурсии?

  • можно так:

 public function main(array $array): int
  {
    $sum = 0;
    
    array_walk_recursive($array, function($value) use (&$sum) {
      $sum += $value;
    });
    
    return $sum;
  }
  • еще вариант — сделать массив линейным и далее сложить элементы как обычно (но тут тоже рекурсия…):

    public function makeLinearArray(array $arr, array &$ret) 
    {
          $ret = [];
         foreach($array as $el) {
             if(is_array($el)) {
                 $this->main($el, $ret);
             } else {
               $ret[] = $el;
             }
         }
    }
  
  • решение автора: можно брать в исходном массиве по одному элементу (через array_shift , array_pop) и обрабатывать их

<?php
// ...
    public function main(array $array): int
    {
        $result = 0;
        
        while (count($array)) {
            $value = array_shift($array);
            if (is_array($value)) {
                $array = array_merge($array, $value);
            } else {
                $result += $value;
            }
        }

        return $result;
    }

(звезда) Экспериментируем в live-режиме тут


Задача 3: “Светофор“

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

<?php

class Task
{
    const GREEN = 'green';
    const RED   = 'red';

    public function main(string $date): string
    {
      
    }

    public function __invoke()
    {
        $testData = [
            '2023-01-01 00:02:12' => self::GREEN,
            '2023-01-01 00:04:00' => self::RED,
            '2023-01-01 00:35:30' => self::GREEN,
            '2023-01-01 00:44:59' => self::RED,
        ];
        foreach ($testData as $date => $expectation) {
            $result = $this->main($date) === $expectation;
            echo '[' . ($result ? 'OK' : 'FAIL') . "] {$date}-{$expectation}n";
        }
    }
}

(new Task)();

Решение

<?php

class Task {

  const GREEN = 'green';
  const RED = 'red';

  public function main(string $date): string {
    $datetime = new DateTime($date);
    $minutes = $datetime->format('i');

    if ($minutes % 5 < 3) {
      return self::GREEN;
    } else {
      return self::RED;  
    }
  }
  
  public function __invoke() {
    // tests
  }
}

(new Task())();

(звезда) Экпериментируем с лайв-кодом тут


PS: ищите другие мои заметки/разборы вопросов с собеседований, в моем блоге

Tags

Нет Ответов

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

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

Рубрики


Подпишись на новости
👋

Есть вопросы?