Привет! Обещали — делаем: продолжаем серию мини-квизов, посвященных разным языкам программирования в нашем блоге (предыдущие: 1 (на знание Python, PHP, Golang и DevOps), 2 (полностью по Go)). Сегодняшний выпуск посвящён PHP.
Под катом — восемь вопросов, немного приключений программиста Брэда, одна странная последовательность и клёвый мерч в качестве призов. Квиз проходит до 4 июля.
UPD 2: Как и договаривались, выкладываем разбор заданий викторины. Пояснения скрыли под спойлером после правильных ответов. Если у вас остались вопросы, задавайте их в комментариях.
UPD: Мы закончили принимать ответы. Спасибо всем, кто поучаствовал! Мы готовим разбор заданий. Ответы на них — внутри текста, а победители и призеры под спойлером.
![](https://habrastorage.org/r/w1560/webt/hl/vl/mb/hlvlmbuspwzejtuo2yaj4nvgfo4.png)
Первому, кто правильно ответит на них, отправим набор сувенирки Авито: футболку с php-слоном, носки и холиварные кости (можно будет погадать, на каком бэкенд-языке и фронтенд-фреймворке будет написан ваш новый проект).
Десяти другим правильно ответившим отправим Авито-носки. Разыграем с помощью рандомайзера. Он же определит, к кому поедут ещё две футболки и набор костей.
![](https://habrastorage.org/r/w780q1/webt/mk/ar/6n/mkar6n1lx_hdo4nti5tcnwq-feq.jpeg)
Что выведет код:
Варианты ответов:
Что выведет код:
Варианты ответов:
Однажды программист Брэд решил портировать одну библиотеку с Go на PHP, чтобы собрать звёзд на GitHub, и задался вопросом:
Возможна ли следующая конструкция?
Варианты ответов:
Какой алгоритм сортировки используется в сердце PHP для таких функций, как sort и тд?
Варианты ответов:
Есть код:
Вопрос: есть ли разница между возвращаемыми значениями getLambda и getLambda2?
Варианты ответов:
Что выведет код:
Варианты ответов:
Что выведет код:
Варианты ответов:
Что выведет код:
Варианты ответов:
Ответы на вопросы выложим апдейтом к посту в среду, 4 июля. Если будете решать — кладите ответы под спойлер, чтобы не портить другим фана. И не забывайте проверять личку Хабра после окончания квиза.
Enjoy!
Под катом — восемь вопросов, немного приключений программиста Брэда, одна странная последовательность и клёвый мерч в качестве призов. Квиз проходит до 4 июля.
UPD 2: Как и договаривались, выкладываем разбор заданий викторины. Пояснения скрыли под спойлером после правильных ответов. Если у вас остались вопросы, задавайте их в комментариях.
UPD: Мы закончили принимать ответы. Спасибо всем, кто поучаствовал! Мы готовим разбор заданий. Ответы на них — внутри текста, а победители и призеры под спойлером.
Победители и призеры PHP-викторины
egor_nullptr
Мы случайным образом выбрали десять лучших участников, допустивших не больше двух ошибок в ответах: Dimd13, slimus, alexchromets, Donquih0te, TexElless, SamDark, AdmAlexus, voiceofnoise, Raz-Mik, Serj_By.
Запись розыгрыша
Тем, кто допустил всего одну ошибку, мы дополнительно дарим холиварные кости, с которыми можно решить на каком бэкенд-языке и фронтенд-фреймворке писать ваш новый проект/или переделать старый. Их получают: DjSebas, TexElless, Turik-us, offlinewan, voiceofnoise, andrey_96, delight-almighty.
Победитель
egor_nullptr
Призеры
Мы случайным образом выбрали десять лучших участников, допустивших не больше двух ошибок в ответах: Dimd13, slimus, alexchromets, Donquih0te, TexElless, SamDark, AdmAlexus, voiceofnoise, Raz-Mik, Serj_By.
Запись розыгрыша
Бонус!
Тем, кто допустил всего одну ошибку, мы дополнительно дарим холиварные кости, с которыми можно решить на каком бэкенд-языке и фронтенд-фреймворке писать ваш новый проект/или переделать старый. Их получают: DjSebas, TexElless, Turik-us, offlinewan, voiceofnoise, andrey_96, delight-almighty.
![](https://habrastorage.org/webt/hl/vl/mb/hlvlmbuspwzejtuo2yaj4nvgfo4.png)
Правила игры
Первому, кто правильно ответит на них, отправим набор сувенирки Авито: футболку с php-слоном, носки и холиварные кости (можно будет погадать, на каком бэкенд-языке и фронтенд-фреймворке будет написан ваш новый проект).
Десяти другим правильно ответившим отправим Авито-носки. Разыграем с помощью рандомайзера. Он же определит, к кому поедут ещё две футболки и набор костей.
![](https://habrastorage.org/webt/mk/ar/6n/mkar6n1lx_hdo4nti5tcnwq-feq.jpeg)
Вопросы и варианты ответов
Вопрос 1
Что выведет код:
<?php
$a = [1, 2, 3];
foreach($a as &$value) {}
foreach($a as $value) {}
print_r($a);
Варианты ответов:
- Array(1, 2, 3)
- Array(1, 2, 2)
- Array(3, 2, 1)
- Ошибка
Правильный ответ
Array(1, 2, 2)
Объяснение
Поскольку в php переменные созданные в цикле остаются жить после его завершения, к началу второго цикла переменная $value — это ссылка на последний элемент массива. Во время итерации последнего foreach значения из массива записываются в его последний элемент (т.к. $value — это ссылка). Так будет выглядеть массив на каждой итерации второго цикла:
1. [1, 2, 1]
2. [1, 2, 2]
3. [1, 2, 2]
1. [1, 2, 1]
2. [1, 2, 2]
3. [1, 2, 2]
Вопрос 2
Что выведет код:
<?php
function sowCrops() { return 'wheat'; }
function millWheat() { return 'flour'; }
function bake($flour) { return 'cupcake'; }
function generator() {
$flour = yield millWheat();
$wheat = yield sowCrops();
return bake($flour);
};
$gen = generator();
foreach ($gen as $key => $value) {
echo $key . ' => ' . $value . PHP_EOL;
}
echo $gen->getReturn();
Варианты ответов:
0 => flour 1 => wheat
0 => wheat 1 => flour 2 => cupcake
0 => flour 1 => wheat cupcake
cupcake
Правильный ответ
4.
0 => flour
1 => wheat
cupcake
Объяснение
No comments. Просто немного мудрёный пример с генераторами.
Вопрос 3
Однажды программист Брэд решил портировать одну библиотеку с Go на PHP, чтобы собрать звёзд на GitHub, и задался вопросом:
Возможна ли следующая конструкция?
<?php
print_r(...(new Foo()));
Варианты ответов:
- Да, класс Foo должен реализовать интерфейс Traversable
- Да, класс Foo должен реализовывать методы интерфейса ArrayAccess
- Нет, будет ошибка, аргумент ...-оператора должен быть массивом
Правильный ответ
1. Да, класс Foo должен реализовать интерфейс Traversable
Объяснение
Тут всё просто. Из документации Argument Unpacking:
Массивы и объекты, реализующие интерфейс Traversable могут быть распакованы в список аргументов при передаче в функцию с помощью оператора ...
Вопрос 4
Какой алгоритм сортировки используется в сердце PHP для таких функций, как sort и тд?
Варианты ответов:
- нерекурсивный mergesort
- heapsort (вариация smoothsort Эдсгера Дейкстры)
- quicksort с разбиением по медиане из трех
- introsort
Правильный ответ
4. introsort
Объяснение
Используется introsort. Исходный код можно посмотреть на Гитхабе. В документации есть упоминание об использовании quicksort, но тут нет противоречия, ведь introsort — гибридный алгоритм сортировки, где при малом количестве элементов используется сортировка вставкой, а позже используется более быстрый алгоритм: quicksort или heapsort.
Вопрос 5
Есть код:
<?php
class Factory {
public function getLambda(): Closure {
return function () {
printf("Here I am (%s)!\n", get_class($this));
};
}
public function getLambda2(): Closure {
return static function () {
printf("Here I am (%s)!\n", get_class($this));
};
}
}
Вопрос: есть ли разница между возвращаемыми значениями getLambda и getLambda2?
Варианты ответов:
- В одном случае использовано ключевое слово static :), но оно никак не влияет
- Результат getLambda2() нельзя привязать к какому-нибудь объекту
- Так нельзя писать: будет синтаксическая ошибка «Syntax error: static keyword used in wrong context»
- Closure из getLamda2() можно привязывать (bindTo) только к классам
Правильный ответ
2. Результат getLambda2() нельзя привязать к какому-нибудь объекту
Объяснение
Метод getLambda2() возвращает статическую анонимную функцию, которую нельзя привязать к объекту через ->bindTo() метод. Их использование редко встречается в коде, но всё же
Вопрос 6
Что выведет код:
<?php
$a = true;
$b = false;
$c = $a and $b;
$d = $a && $b;
var_dump($c);
var_dump($d);
Варианты ответов:
bool(false) bool(false)
bool(false) bool(true)
bool(true) bool(true)
bool(true) bool(false)
Правильный ответ
4.
bool(true)
bool(false)
Объяснение
Разница между && и and в приоритете. Выражение $d = $a && $b работает как $d = ($a && $b). А вот выражение $c = $a and $b работает иначе и может быть представлено в виде (($c = $a) and $b).
Вопрос 7
Что выведет код:
<?php
$a = 'a';
for ($i = 0; $i < 40; $i++) {
echo $a++, PHP_EOL;
}
Варианты ответов:
- Будут выведены цифры от 0 до 39, а также Warning: A non-numeric value encountered in на каждой итерации
- Каждая итерация выведет ‘a’ + Warning
- Странная последовательность:
a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af ag ah ai aj ak al am an
Правильный ответ
3. Странная последовательность:
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
an
Объяснение
Не все знают, но оператор инкремента можно применять к символам. Из документации:
PHP следует соглашениям Perl (в отличие от С) касательно выполнения арифметических операций с символьными переменными. Например, в PHP и Perl $a = 'Z'; $a++; присвоит $a значение 'AA', в то время как в C a = 'Z'; a++; присвоит a значение '[' (ASCII-значение 'Z' равно 90, а ASCII-значение '[' равно 91).
Вопрос 8
Что выведет код:
<?php
class TestMe {
public function test()
{
if (0) {
yield 32332;
}
return [1,2,3];
}
}
$t = new TestMe();
foreach ($t->test() as $id) {
echo $id, PHP_EOL;
}
echo "The end", PHP_EOL;
Варианты ответов:
1 2 3 32332 The end
1 2 3 The end
The end
32332 The end
Правильный ответ
3.
The end
Объяснение
С первого взгляда может показаться, что функция не возвращает генератор, потому что yield выражение недостижимо. Однако, любая функция содержащая yield выражение автоматически становится функцией-генератором. В оригинальном RFC так и написано. В момент первой итерации генератор начинает выполнять код функции с самого начала до первого доступного yield выражения, но поскольку его нет, генератор заканчивает свою работу, так и не передав какие-либо данные в цикл.
Подведение итогов
Ответы на вопросы выложим апдейтом к посту в среду, 4 июля. Если будете решать — кладите ответы под спойлер, чтобы не портить другим фана. И не забывайте проверять личку Хабра после окончания квиза.
Enjoy!