- Собеседование php-developer (вопросы и ответы)
- Что нового в PHP 7.*
- Типы данных
- Type hinting + strict mode
- Строгое и нестрогое сравнение
- Работа с ссылками
- Copy-on-write
- Run time error handling
- Замыкания
- Функции по работе с массивами
- Функция list()
- Область видимости переменной
- Область видимости свойства/метода/константы класса
- Final классы и методы
- Позднее статическое связывание
- Магические методы
- Динамические переменные
- Генераторы
- Reflection API
- Autoloader
- APC/APCu
- OPcache
- PSR standards
- Composer
- XDebug
- Rest API
- Тесты
- Инкапсуляция/наследование/полиморфизм
- Абстрактные классы/методы
- Интерфейсы
- Traits
- GRASP шаблоны
- Паттерны банды четырех
- SOLID
- Databases
- Docker
- HTTP и другие протоколы
- Авторизация и аутентификация
- Тестовое задание для PHP разработчика на испытательном сроке
- Аннотация
- Гостевая книга
- Гостевая книга. JavaScript и работа с файлами.
- Гостевая книга. Регулярные выражения.
- Гостевая книга. JavaScript и AJAX.
- Требования
- Собеседование на PHP разработчика. Более 100 вопросов для Junior, Middle и Senior
- Junior
- Middle
Собеседование php-developer (вопросы и ответы)
Так уж получилось, что в этом году я прошел ряд собеседований на позицию PHP разработчика, чего я не делал уже несколько лет. Будучи человеком ленивым практичным, перед собеседованием я попытался найти сборники вопросов-ответов, но все найденное было довольно старым, поэтому я решил сам подготовить список вопросов, которые встречал.
Обычно в статьях такого рода даются полные ответы на вопросы, но если вы собеседуетесь на достаточно серьезную позицию, краткой выжимки будет явно недостаточно и необходимо довольно глубоко понимать сам вопрос, поэтому я в основном вставил ссылки на документацию или статьи по описываемым вопросам.
PHP
Что нового в PHP 7.*
Эх, помню времена когда рассказывал в чем отличие между 4 и 5 версиями, в глаза никогда не видев 4-ю, старые традиции нужно соблюдать, вопрос встречается почти на всех собеседованиях, и хоть никто не ожидает, что вы вспомните дословно в какой версии какие изменения произошли, в целом эту информацию стоит знать:
Типы данных
Хотя PHP это динамический язык, все же все данные в нем имеют четкие типы:
Скалярные типы:
Type hinting + strict mode
Как логичное продолжение темы типов и строгой типизации, которая пришла вместе с php 7.*, нужно знать о разнице между строгой и нестрогой типизацией, подробности в документации.
Строгое и нестрогое сравнение
Нужно понимать разницу между нестрогим сравнением (сравнение значений без учета типа данных) и строгим сравнением (с учетом типа данных), которую довольно хорошо отражает данная табличка. Отдельно стоит выделить строгое и нестрогое сравнение объектов.
Работа с ссылками
Ссылки в PHP — это, грубо говоря, способ получить доступ к одной и той же переменной (области памяти) под разными именами.
Основные операции которые можно совершать с ссылками:
Это было верно до php5, но сейчас передается только идентификатор объекта (документация).
Если вкратце, если вы создали объект, и передали его в функцию, внутри которой вы сделали
это не значит что оригинальный объект тоже обнулится, вы все так же можете с ним работать. А вот если вы явно передали объект по ссылке — то это действие “обнулит” и оригинальный объект.
Copy-on-write
Каждый раз передавая переменную в функцию её значение (теоретически) должно быть скопировано. Это может не быть проблемой для данных типа integer или float, но представьте, что вы передаете в функцию массив, содержащий десять миллионов значений. Для того чтобы избежать этого в PHP используется парадигма копирования-при-записи (copy-on-write). Так, на самом деле, при передаче массива его копирование не происходит до того момента, пока вы не захотите изменить что либо в этом массиве. Статья с более детальным объяснением.
Run time error handling
В 7-й версии php произошли ряд изменений которые касаются иерархии ошибок (больше информации по иерархии), в остальном ожидается что соискатель будет знать как отлавливать исключения, или даже сможет написать свой собственный error_handler.
Замыкания
Они же анонимные функции, наиболее полезны в качестве значений callback-параметров, документация. Есть хорошая, хотя и немного старая статья о работе с замыканиями на Хабре.
Функции по работе с массивами
Часто просят назвать все функции по работе с массивами которые вы помните на память. И хотя, по моему мнению, этот вопрос чуть более чем бессмысленный, перечень функций можно повторить по документации.
Функция list()
Благодаря изменениям в PHP 7.1 функцией стало пользоваться удобнее, как следствие используют ее чаще, всю информацию можно найти в документации.
Область видимости переменной
В большинстве случаев, все переменные имеют только одну область видимости, исключение составляют глобальные/суперглобальные переменные которые, как ясно из названия, доступны везде, а также статические/константы.
Область видимости свойства/метода/константы класса
Определяется при помощи ключевых слов public (видно всем), protected (доступен только текущему классу или его наследникам) или private (доступен только текущему классу), и может применяться как для свойств/метода, так начиная и с PHP 7.1 для констант класса. Подробнее в документации.
Final классы и методы
Разместив ключевое слово final перед объявлениями методов класса, можно предотвратить их переопределение в дочерних классах, а в случае объявления самого класса как final — его невозможно будет унаследовать. Такие классы и методы призваны защитить чувствительный код от изменений, а сам код становится проще поддерживать.
Подробнее в документации.
Позднее статическое связывание
Выражается в разнице между вызовом self:: и static. «Позднее связывание» означает что static:: будет вычисляться в ходе исполнения и может быть переопределен в классах — наследниках. Подробнее в документации.
Магические методы
В PHP без магии совсем никуда, поэтому у нас есть методы которые позволяют реализовать дополнительный функционал объекту, переопределить стандартное поведение объекта (к примеру __serialize()/__unserialize() ), или же поведение объекта в нетипичных для него ситуациях (__toString()) и другие.
Документация, и хорошая, хоть и немного устаревшая статья на хабре.
Динамические переменные
Вы можете передать имя одной переменной в другую, а затем использовать эту переменную “динамически”.
Их следует использовать с большой осторожностью, так как они могут значительно усложнить как чтение, так и поддержку кода (зачастую без запуска кода невозможно понять что в переменной), однако они могут быть очень полезны в абстракциях. Подробнее в документации.
Генераторы
Генераторы (ключевое слово yield) создают простые итераторы позволяя экономить память в ситуациях, когда вам необходимо перебрать большой объем данных. Их может быть немного сложно понять, ровно до того момента как вы напишите свой генератор.
Описание в документации, и есть довольно старая (однако с того момента синтаксис генераторов не изменился) и хорошая статья на хабре.
Reflection API
Кратко говоря, это способность взглянуть внутрь своего (или чужого кода), узнать какие у класса есть переменные, методы, константы, сделать их при желании публичными. Данная способность активно используется фреймворками (например в симфони для автогенерации dependency injection) и библиотеками. Описание в документации и разумеется статья на хабре.
Autoloader
Обычно, на проектах очень редко необходимо самому реализовать автозагрузку классов, однако для компаний которые все решения пишут самостоятельно (например большие корпорации, которые не хотят работать с открытыми кодом), или каких то особенных проектов это актуально. К тому же может быть полезно понимать как это работает.
Или Standard PHP Library — набор классов (структуры данных, итераторы, исключения, классы для обработки файлов), интерфейсов и функций для решения стандартных задач. Как правило, знание наизусть библиотеки не требуется, но понимать из чего она состоит стоит хотя бы для личного развития. Подробнее в документации — www.php.net/manual/ru/book.spl.php
APC/APCu
Alternative PHP cache (APC) или альтернативный кеш без опкода (APCu) — бесплатный кеш с открытым исходным кодом, предназначенный для кэширования и оптимизации промежуточного кода PHP. В основном используется для сохранения вычислений между запросами. Документация:
OPcache
Улучшает производительность PHP путём сохранения скомпилированного байт-кода скриптов в разделяемой памяти, тем самым избавляя PHP от необходимости загружать и анализировать скрипты при каждом запросе. Официальная документация, а так же очень хорошая статья как это все работает на Хабре.
PSR standards
PHP Standards Recommendations — стандарты оформления кода, а также интерфейсы для стандартных задач. Используются данные стандарты во всех (известных мне) фреймворках, и облегчают взаимодействия между разными библиотеками. Официальная документация а также хорошая статья на Хабре.
Composer
Менеджер зависимостей, а также инструмент реализующий автозагрузку кода библиотек и самого приложение. Может помочь в оптимизации и ускорении приложения для продакшена.
XDebug
Большинство разработчиков использует это расширения для облегчения работы с кодом или же его оптимизации, основные знания здесь — как его настроить и запустить, с этим поможет следующая статья blog.denisbondar.com/post/phpstorm_docker_xdebug.
Rest API
REpresentational State Transfer — архитектурный подход который позволяет организовать взаимодействие между приложениями используя все возможности HTTP. Хорошая статья на эту тему, а также различия REST и SOAP.
В контексте API нужно понимать основные форматы обмена данными, чаще всего это XML и JSON.
Тесты
В основе всех unit тестов лежит PHPUnit (насколько мне известно), и на сегодняшний день, уметь и знать как писать тесты является обязательной частью разработки. Многие фреймворки (тот же Symfony) предлагают свои обертки и решения для тестирования. Вот хорошая статья о лучших инструментах для тестирования.
Инкапсуляция/наследование/полиморфизм
Абстрактные классы/методы
Интерфейсы
Интерфейс, в отличие от абстрактного класса, не может содержать поля и методы, имеющие реализацию – он описывает только сигнатуры метода, которые должны реализовать его наследники. В отличие от того же абстрактного класса, класс может реализовывать одновременно множество интерфейсов.
Официальная документация, и хорошая статья на хабре.
Traits
Трейт очень похож на класс, но предназначен для группирования функционала и его дальнейшего переиспользования во множестве классов, которые не могут быть связаны одним абстрактным классом. Иногда еще говорят, что трейт — это способ реализовать множественное наследование в PHP.
Так как каждый класс может реализовать множество трейтов, могут возникать конфликты когда один и тот же метод реализован в разных трейтах и/или самом классе. Подробней о трейтах в документации.
GRASP шаблоны
General Responsibility Assignment Software Patterns — шаблоны проектирования для решения общих задач. В отличие от паттернов из Банды Четырех, GRAPS шаблоны не имеют выраженной структуры, четкой области применения и конкретной решаемой проблемы, а лишь представляют собой обобщенные подходы/рекомендации/принципы, используемые при проектировании дизайна системы.
Паттерны банды четырех
Тема паттернов обширна, на нее написано уже много статей, и пытаться описать это в нескольких предложениях просто невозможно. Мне нравится этот ресурс — refactoring.guru/ru/design-patterns/catalog, но при необходимости вы можете воспользоваться этой ссылкой.
SOLID
Его спрашивают все, но спрашивают по-разному.
Плохой вариант — вас просят зачитать на память принципы и их определения.
Хороший — вам называют принцип, и просят объяснить его, описать примеры использования, придумать реальную ситуацию когда тот или иной принцип чем то поможет. Такой вариант, по моему мнению, намного лучше дает понять уровень кандидата и его реальное понимание принципов.
На Хабре можно найти десятки действительно хороших статей по этим принципам, поэтому я даю ссылку на medium.
Keep it simple, stupid — хороший принцип, вся суть которого уже содержится в названии, подробнее можно узнать здесь.
Don’t repeat yourself — принцип, описывающий что необходимо переиспользовать код везде, где это возможно. Подробнее здесь.
Databases
Хорошую статью на тему SQL баз данных можно найти здесь. Вопросы по NoSql базам в моем случае обычно встречаются на примере MongoDB. В случае с ElasticSearch обычно используются библиотеки-обертки, общую информацию можно почерпнуть из статьи на Хабре.
In memory хранилища (те что хранят значения в оперативной памяти) — memcached и/или redis (чаще всего), как правило работа с ними осуществляется через библиотеки-обертки, если вы хотите разобраться в вопросе подробнее, разумеется есть статья на Хабре.
Docker
Очень важный инструмент который использовался почти на всех проектах (в моем случае). И хотя зачастую настраивается он единожды за проект, основные понятия и принцип работы с ним нужно знать. Лично мне для собеседования нравится эта статья.
HTTP и другие протоколы
Разумеется, любой веб-разработчик должен знать и понимать как работают протоколы передачи данных (как минимум протоколы верхнего уровня). Тема большая и в несколько предложений ее сложно уместить, на Хабре есть обширная статья на эту тему.
Авторизация и аутентификация
Авторизация — предоставление прав на выполнение определённых действий, а также процесс проверки прав при попытке выполнения этих действий.
Аутентификация — процедура проверки подлинности, например проверка подлинности пользователя путем сравнения введённого им пароля.
Важно понимать разницу между авторизацией и аутентификацией, как они реализуются при использовании session и cookies, JSON Web Tokens (JWT) и др.
Тестовое задание для PHP разработчика на испытательном сроке
После прохождения собеседования (ох и бурное обсуждение получилось), для разработчика наступает испытательный срок. Это один из самых тяжелых этапов для человека на новой работе — идет адаптации с новым коллективом, нескончаемый поток новых знаний, которые с трудом успеваешь усваивать, да еще и тестовое задания, и оно не из простых…
Не буду ходить вокруг да около, а напишу какое оно есть, и надеюсь на Ваши комментарии:
Данное тестовое задание скорей всего больше подходит для junior разработчика, чем для матерого волка seniorа.
Аннотация
Гостевая книга
Гостевая книга. JavaScript и работа с файлами.
К базовой функциональности, следует добавить следующие возможности:
Гостевая книга. Регулярные выражения.
Гостевая книга. JavaScript и AJAX.
Требования
P.S. На картинке изображен двигатель Стирлинга, wikipedia частенько дает пищу для ума.
Upd: очень правильный комментарий появился на моём блоге:
народ, вы видимо не понимаете, на кого это задание рассчитано. Человек с опытом ЕСТЕСТВЕННО не будет его делать по двум причинам: а) не захочет тратить время и б) ему его не дадут.
но реалии таковы, что это часто-густо вообще первое более-менее объёмное задание соискателя на должность junior php developer.
поэтому 80 часов даётся не для того, чтобы он это задание просто сделал, а чтобы привёл реальность (свои знание) в соответствие с галочками в своём резюме напротив php, html, css, js, ajax, mysql.
по выходу получаем некий интегральный показатель как скилованости так и обучаемости и умения гуглить.
собственно с этоим задание справляется.
а кандидаты, которым есть что показать, естественно идут сразу в проекты.
Собеседование на PHP разработчика. Более 100 вопросов для Junior, Middle и Senior
Собрал список вопросов, по которым можно подготовиться к собеседованию или которые можно спросить у дипломированного PHP-разработчика. Конечно, список, не является исчерпывающим. Больше вопросов с кодом в нашем телеграм-канале @phpquiz. Погнали по вопросам!
Junior
Основы
Какие основные операции с использованием ссылок?
Назовите простые типы данных, поддерживаемые в РНР?
Что такое инкремент и декремент, в чем разница между префиксным и постфиксная инкрементом и декрементом?
Что такое рекурсия?
В чем разница между =, == и ===?
Какие знаете принципы ООП?
Какая система типов используется в PHP? Опишите плюсы и минусы.
Чем отличаются ключевые слова: include и require, mysql_connect и mysql_pconnect?
Что такое абстрактный класс и чем он отличается от интерфейса?
Может ли абстрактный класс содержать частный метод?
Какие модификаторы видимости есть в РНР?
Какие магические методы вы знаете и как их применяют?
Что такое генераторы и как их использовать?
Что делает оператор yield?
Что такое traits? Альтернативное решение? Приведите пример.
Опишите поведение при использовании traits с одинаковыми именами полей и / или методов?
будут доступны частные методы trait в классе?
можно компоновать traits в trait?
Расскажите об обработке ошибок и исключения (try catch, finaly и throw).
Что такое type hinting, как работает, зачем нужен?
Что такое namespace и зачем они?
Сравнение значений переменных в РНР и подводные камни? Приведение типов. Что изменилось в PHP 8 в этом контексте?
Как работает session в РНР, где хранится, как инициализируется?
Cуперглобальные массивы. Какие знаете? Как использовали?
Сравните include vs required, include_once vs required_once.
Что означает сложность алгоритма?
Что такое замыкание в PHP? Приведите пример.
Какая разница между замыканием в PHP и JavaScript?
Что такое позднее связывание? Расскажите о поведении и применения static.
Расскажите о SPL-библиотеку (Reflection, autoload, структуры данных).
Расскажите о принципах SOLID.
Расскажите о шаблонах GRASP.
Расскажите о Dependency Injection: что такое DI-контейнеры? Какие есть варианты реализаций?
Что вам известно о MVC?
Что вам известно о шаблонах GoF?
Что вам известно о шаблонах, которые применяются в ORM?
Напишите / расскажите на PHP пример реализации паттерна Singleton.
Что такое Docker? Каков принцип его работы?
Что такое LAMP / NAMP?
Расскажите о regexp.
Расскажите о SSH-протокол.
Что нового появилось в PHP 8?
Какие версии PHP до сих пор поддерживаются?
В чем разница между GET и POST?
Какие еще HTTP-методы знаете?
Чем отличаются операторы BREAK и CONTINUE?
Есть ли разница между одинарными и двойными кавычками?
Что такое cookie и зачем они используются?
Что нельзя хранить в cookie и почему?
Какую среду разработки предпочитаете и почему?
Какой командой добавить изменения?
Какой командой зафиксировать изменения?
Какой командой отправить изменения в удаленный репозиторий?
Базы данных
Что такое транзакция?
Что такое нормализация?
Что такое денормализации? Для чего она нужна?
Какие типы связей в базе данных?
Что означает утверждение о том, что СУБД поддерживает контроль ссылочной целостности связей?
Если используемая вами СУБД не поддерживает каскадные удаления для поддержки ссылочной целостности связей, что можно сделать для достижения аналогичного результата?
Что такое первичный и внешний ключи?
Какие различия между первичным и уникальным ключами?
Какие типы JOIN и в чем различия?
Что такое курсоры в базах данных?
Что такое агрегатные функции SQL? Приведите несколько примеров.
Что такое миграции?
Расскажите о связи друг к другу, один ко многим, многие ко многим.
Зачем используют оператор группировки GROUP BY?
В чем разница между WHERE и HAVING? Приведите примеры.
В чем разница между операторами DISTINCT и GROUP BY?
Для чего нужны операторы UNION, INTERSECT, EXCEPT?
Опишите разницу типов данных DATETIME и TIMESTAMP.
Какие вы знаете двигатели таблиц и чем они отличаются?
Какие способы оптимизации производительности баз данных знаете?
Что такое партицирование, репликация и шардинг?
Чем отличаются SQL от NoSQL базы данных?
Какие бывают NoSQL базы данных?
Какие типы данных есть в MySQL?
Разница между LEFT JOIN, RIGHT JOIN, INNER JOIN?
Разница между JOIN и UNION?
Что такое индексы? Как они влияют на время выполнения SELECT, INSERT?
Что такое хранимые процедуры, функции и триггеры в MySQL? Для чего они? Приведите примеры использования.
Как организовать сохранность вложенных категорий в MySQL?
Практические задания
Спроектируйте базу данных для хранения информации о книгах и их авторов. Напишите запрос для выборки всех авторов и количества написанных ими книг.
Есть матрица 3 × 3. Посчитайте диагонали, только парные / нечетные числа в диагоналях.
Ваш приложение выдает 500 ошибку. Опишите последовательность поиска проблемы.
Напишите функцию, которая определяет, слово является палиндромом.
Какой результат выдаст такой код и почему: If (-1) print «True» else print «False»
Какой результат выдаст такой код и почему: var_dump (array_merge ([2 => ‘a’], [3 => ‘b’]));
Есть массив товаров в случайном порядке с указанием производителей. Напишите метод для его сортировки, чтобы максимальное количество первых товаров соответствовала такому критерию: каждый следующий товар должен производителя, отличного от предыдущего.
Есть массив Integer, напишите возможные способы, как увеличить каждый элемент на единицу (1).
Order
User
Напишите запрос для увеличения значения column1 на 1 для id = 2
Напишите цикл for так, чтобы аргумент цикла менялся в геометрической прогрессии.
Что выведут выражения:
print (!! «false»)
print (!! true)
print ((int) ‘125g7’)
print ((int) ‘x52’)
Результат выполнения функции? Как исправить результат?
in_array (1, [0, ‘0’, true])
Напишите класс с реализацией всех возможных способов строгой типизации данных с учетом возможностей PHP 8.
Middle
Основы
Как передаются переменные (по значению или по ссылке)?
Какие процессы происходят, когда пользователь вводит в браузере URL?
Что такое вариативная функция или spread-оператор?
Какие типы уязвимостей знаете? Как от них защищаться?
Что такое идемпотентность метода? Какие HTTP-методы являются идемпотентными для REST?
Что такое stateless?
SOAP vs REST. В чем разница?
Какие методы авторизации используют для построения API?
Что может содержать интерфейс?
Класс содержит свойство, которое, в свою очередь, является объектом. Что будет содержать это свойство в клонированный объект: ссылка на тот же дочерний объект или копию дочернего объекта? Что нужно сделать, чтобы это изменить?
Что такое Mock? Где используют и зачем?
Опишите реализацию одного из шаблонов проектирования.
Как хранятся данные в redis / memcached?
Расскажите о целесообразности применения redis / memcached для кэширования. Какие плюсы и минусы?
Назовите различия между nginx и apache.
Что такое opcash? Как он работает?
Что такое JIT? Как он работает?
Зачем нужно ключевое слово final?
Что нового в РНР 7/8?
Что такое SOLID, DRY, KISS, YAGNI?
Назовите паттерны проектирования, с которыми приходилось работать.
Что такое простая фабрика?
Что такое Service Layer и где его следует применять?
Как устроен Singleton и почему его считают антипатерном?
Что такое идемпотентность?
Опишите жизненный цикл HTTP-запроса?
Что такое куча и стек?
Что такое рефлексия?
Что такое хэш-функция и где она используется?
Как применяются очереди в РНР?
Как в общих чертах работает opcache?
Чем отличаются модульные тесты от интеграционных?
Что такое трейты? Как применять на практике?
Как разрешить конфликты при использовании trait?
Как работает автозагрузки классов?
В чем разница между стеком и очередью?
Расскажите о Unit Tests (required), Functional Tests (optional). Моки и стаб в PHP.
Представим ситуацию, в которой нам нужно вызвать частный метод, как это сделать?
Опишите разницу между PHP-FPM и PHP на сокете.
Как бы вы реализовали загрузки больших отчетов с большим количеством данных (файлы от 1 гигабайта до N гигабайт).
Как бы вы импортировали 50-гигабайтный файл xml в базу данных?
Почему после PHP 5 идет сразу 7, куда делась 6?
Есть ли разница между self и this в PHP?
У нас есть важный PHP-файл, его надо запускать каждые 20 секунд, как бы вы это сделали?
Как расшифровать 644 в правах на файл в Linux?
В чем разница между merge и rebase?
Какой командой можно сделать ресет изменений, не потеряв их?
Что такое stash и зачем он нужен?
Базы данных
Какая разница между MyISAM i InnoDB? В каких случаях и лучше применять?
Как найти и оптимизировать «тяжелые» запросы?
Какие типы индексов?
Как хранить координаты точки на карте в БД?
Какие типы индексов бывают в RDBMS?
Какое свойство полей БД нужно учитывать при выборе типа индекса?
Когда следует использовать индексы, преимущества и недостатки?
Что такое план выполнения запроса и как его узнать?
В чем разница между типами данных CHAR и VARCHAR в SQL?
Каково назначение транзакций? Расскажите о принципе работы.
Назовите 3-4 нормальные формы реляционных БД.
Каково назначение репликации? Какие типы связей и в чем разница между ними?
Что такое индексация? Какие типы индексов? Какой смысл их использовать?
Что такое полнотекстовый поиск в MySQL? Как он реализуется?
Что такое cursor в MySQL-процедурах?
Расскажите о RabbitMQ или Gearman.
Что знаете о Solr / ElasticSearch?
Что такое deadlock MySQL?
Влияет ли порядок JOIN на план выполнения MySQL-запроса?
Практические задания
Вам нужно спарсить продукты и их цены с интернет-магазина. С помощью чего будете это делать и какие основные нюансы нужно учесть?
Для сайта пользователей необходимо сделать механизм добавления и отображения аватарок. Как бы вы его реализовали?
Какой результат выдаст такой код:
Какие модификаторы доступа допустимые в реализации метода getName
Реализуйте очередь сообщений, используя MySQL для хранения данных. Как избежать ситуации, когда несколько воркеров получат в обработку одинаковое сообщение?
Есть мануал на API с курсом валют. Нужно найти минимумы-максимумы за 5 лет, а потом то же, но с разбивкой по месяцам.
Напишите архитектуру, которая основывается на базовой абстракции. Дочерние классы расширяются с помощью интерфейсов. Реализацию одинаковых методов выполните, используя трейты (реализовывать в абстракции).