Привет, Хабр!
Собственно, а все ли поняли мем?
Человек прошел обучение, отбор посредством собеседования, имеет багаж знаний. После освоения навыков, набравшись практики (в наши дни стать junior-разработчиокм без практики нереально) добравшись до цели в виде трудоустройства. Не успев толком продышаться сразу сталкивается с такой вещью как бизнес процессы. Пытается понять что от него хотят коллеги по работе и как тут вообще все устроено. Он чувствует растерянность. Но тут стоит оговориться что бизнес это конкурентная среда. Там всем приходится непросто. Смотрите: программист это ремесленник, инструмент которым он пользуется сложный и не понятный - это его собственный мозг. Своим мозгом он обслуживает бизнес процессы. Решает задачи за счет которых приложение работодателя остается в рабочем состоянии и развиваются с точки зрения прибыли. Поток этих задач такой, что нет времени плавно погружаться в процесс, надо срочно в бой. Если вы не знакомы с программированием, взгляните на примеры кода и вы примерно ощутите тоже самое что junior-разработчик в свой первый рабочий день.
Если ИТ вас заинтересовало
С мемом вроде понятно, но раз мы на Хабре, давайте копнем глубже. Представим что junior-разработчик чувствует после того как открывает книгу на 900 страниц что-бы разобраться в PHP (к слову пропорционально количеству вкладок в браузере). Думаю ощущения эти мягко говоря так себе. Открывать все это он вынужден по причине огромного количества языковых конструкций в проекте. За неимением опыта разработчику тяжело погрузиться в уже выстроенную работу с языком. И давайте поговорим зачем вообще нужно понимать что делает код.
Как понять, какая информация из книги может пригодиться в работе?
Наверное более общий ответ на этот вопрос - любая информация, которая на практике улучшает ваш бизнес процесс.
В случае с айти одной из метрик бизнес-эффективности кода будет производительность.
Давайте откроем книгу и прочитаем (это без меня) про генераторы в PHP, а следующим шагом оптимизируем функцию-рекурсию.
Для наглядности я беру распространенную в ИТ сообществе задачу с собеседований - получения числа из последовательности Фибоначчи.
function fib($num)
{
if ($num < 2) {
return $num;
}
debug_print_backtrace();
return fib($num - 1) + fib($num - 2);
}
Простая рекурсия - каждый вызов функции вызывает (добавляет в стек) еще две точно такие же функции, но с другим параметром $num и так пока не будет справедливо неравенство $num < 2.
Изучив генераторы и ключевое слово yield мы можем переписать рекурсию так:
function fibGenerator($n) {
debug_print_backtrace();
if ($n === 0) {
yield $n;
return;
} else {
yield $n + ($n - 1);
}
yield from fibGenerator($n - 1);
}
foreach (fibGenerator(7) as $x) {
var_dump($x);
}
Кода стало больше, он стал менее понятным, но давайте разберемся как на эти изменения в коде отреагирует PHP. И зачем нужно понимать как работает ваш код.
Это легко проверить наглядно. Отдельное спасибо PHP за такую легкость - нам нужно только вызывать функцию debug_print_backtrace();
Проверяем наглядно
Хочу заострить внимание что генератор это не функция а итерируемый объект который вернула нам функция содержащая команду yield.
Для примера возьмем число с порядковым номером 7 в последовательности Фибоначчи и посчитаем его 2 способами, через функцию-рекурсию и генератор.
Стек функции-рекурсии:
λ php -f C:\xampp\htdocs\fib.php
#0 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(6)
#1 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(5)
#1 C:\xampp\htdocs\fib.php(9): fib(6)
#2 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(4)
#1 C:\xampp\htdocs\fib.php(9): fib(5)
#2 C:\xampp\htdocs\fib.php(9): fib(6)
#3 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(3)
#1 C:\xampp\htdocs\fib.php(9): fib(4)
#2 C:\xampp\htdocs\fib.php(9): fib(5)
#3 C:\xampp\htdocs\fib.php(9): fib(6)
#4 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(3)
#2 C:\xampp\htdocs\fib.php(9): fib(4)
#3 C:\xampp\htdocs\fib.php(9): fib(5)
#4 C:\xampp\htdocs\fib.php(9): fib(6)
#5 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(4)
#2 C:\xampp\htdocs\fib.php(9): fib(5)
#3 C:\xampp\htdocs\fib.php(9): fib(6)
#4 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(3)
#1 C:\xampp\htdocs\fib.php(9): fib(5)
#2 C:\xampp\htdocs\fib.php(9): fib(6)
#3 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(3)
#2 C:\xampp\htdocs\fib.php(9): fib(5)
#3 C:\xampp\htdocs\fib.php(9): fib(6)
#4 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(4)
#1 C:\xampp\htdocs\fib.php(9): fib(6)
#2 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(3)
#1 C:\xampp\htdocs\fib.php(9): fib(4)
#2 C:\xampp\htdocs\fib.php(9): fib(6)
#3 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(3)
#2 C:\xampp\htdocs\fib.php(9): fib(4)
#3 C:\xampp\htdocs\fib.php(9): fib(6)
#4 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(4)
#2 C:\xampp\htdocs\fib.php(9): fib(6)
#3 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(5)
#1 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(4)
#1 C:\xampp\htdocs\fib.php(9): fib(5)
#2 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(3)
#1 C:\xampp\htdocs\fib.php(9): fib(4)
#2 C:\xampp\htdocs\fib.php(9): fib(5)
#3 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(3)
#2 C:\xampp\htdocs\fib.php(9): fib(4)
#3 C:\xampp\htdocs\fib.php(9): fib(5)
#4 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(4)
#2 C:\xampp\htdocs\fib.php(9): fib(5)
#3 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(3)
#1 C:\xampp\htdocs\fib.php(9): fib(5)
#2 C:\xampp\htdocs\fib.php(40): fib(7)
#0 C:\xampp\htdocs\fib.php(9): fib(2)
#1 C:\xampp\htdocs\fib.php(9): fib(3)
#2 C:\xampp\htdocs\fib.php(9): fib(5)
#3 C:\xampp\htdocs\fib.php(40): fib(7)
Стек генератора:
λ php -f C:\xampp\htdocs\fib.php
#0 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
#0 C:\xampp\htdocs\fib.php(11): fibGenerator(6)
#1 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
#0 C:\xampp\htdocs\fib.php(11): fibGenerator(5)
#1 C:\xampp\htdocs\fib.php(11): fibGenerator(6)
#2 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
#0 C:\xampp\htdocs\fib.php(11): fibGenerator(4)
#1 C:\xampp\htdocs\fib.php(11): fibGenerator(5)
#2 C:\xampp\htdocs\fib.php(11): fibGenerator(6)
#3 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
#0 C:\xampp\htdocs\fib.php(11): fibGenerator(3)
#1 C:\xampp\htdocs\fib.php(11): fibGenerator(4)
#2 C:\xampp\htdocs\fib.php(11): fibGenerator(5)
#3 C:\xampp\htdocs\fib.php(11): fibGenerator(6)
#4 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
#0 C:\xampp\htdocs\fib.php(11): fibGenerator(2)
#1 C:\xampp\htdocs\fib.php(11): fibGenerator(3)
#2 C:\xampp\htdocs\fib.php(11): fibGenerator(4)
#3 C:\xampp\htdocs\fib.php(11): fibGenerator(5)
#4 C:\xampp\htdocs\fib.php(11): fibGenerator(6)
#5 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
#0 C:\xampp\htdocs\fib.php(11): fibGenerator(1)
#1 C:\xampp\htdocs\fib.php(11): fibGenerator(2)
#2 C:\xampp\htdocs\fib.php(11): fibGenerator(3)
#3 C:\xampp\htdocs\fib.php(11): fibGenerator(4)
#4 C:\xampp\htdocs\fib.php(11): fibGenerator(5)
#5 C:\xampp\htdocs\fib.php(11): fibGenerator(6)
#6 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
#0 C:\xampp\htdocs\fib.php(11): fibGenerator(0)
#1 C:\xampp\htdocs\fib.php(11): fibGenerator(1)
#2 C:\xampp\htdocs\fib.php(11): fibGenerator(2)
#3 C:\xampp\htdocs\fib.php(11): fibGenerator(3)
#4 C:\xampp\htdocs\fib.php(11): fibGenerator(4)
#5 C:\xampp\htdocs\fib.php(11): fibGenerator(5)
#6 C:\xampp\htdocs\fib.php(11): fibGenerator(6)
#7 C:\xampp\htdocs\fib.php(14): fibGenerator(7)
Сразу видно, насколько стек генератора меньше. Если просто стека вызова для вас недостаточно, попробуйте на своем компьютере получить число из последовательности под порядковым номером 100. В случае с рекурсивной функцией можете смело ставить кофе в турке на вашу рабочую станцию и ждать, пока он сварится. А для генератора это будет всего 100 вызовов!
Генератор помогает нам сэкономить производительность при обработке последовательностей (читайте массивов).
Итоги
Мем смешной, ситуация страшная.
Используя новые знания из книги мы оптимизировали код PHP.
Думаю что не каждый тимлид ответит вам на вопросы про генераторы. Хотелось бы обсудить это в комментариях.
В следующей статье попробуем применить генератор на реальной бизнес задаче и порассуждаем про знания в ИТ.
Совет начинающим как послесловие
Оценивайте себя не только с точки зрения технической подкованности, но и смотрите на свою эффективность в бизнес процессах.
Не будьте в перспективе тимлидом, который за свою карьеру не читал профильных книг. Пытайтесь взглянуть на привычные вещи по другому, через новые знания. Обращайте внимание на свои коммуникативные навыки. Обмен опытом и коммуникация в команде - важная часть процесса разработки! Развивайте себя и тем самым будет развиваться бизнес, на который вы работаете. Кто знает, может когда-то найденные вами ответы в книгах будут спрашивать на собеседованиях.