Как стать автором
Обновить

Комментарии 432

Такое ощущение, что сейчас это тред – учиться проходить собеседования, а не программировать. Знать ответы на вопросы собеседования, но не применить их на практике ни разу.
Я видел собеседования, где программисты не могли сказать, чем отличается объект от класса, процедурный подход от объектно-ориентированного. Вот, что важно.

Я нисколько не умаляю информации в этой книге, я просто не очень доволен ситуацией в области.
скоро будут агентства, которые будут за Вас ходить на собеседование, а может и кодить :)
Спрос порождает предложение.
Почему бы и нет? На «эстраде» у нас уже давным-давно такая ситуация.
тьфу-тьфу-тьфу, конечно
Анекдот в тему:

Нанимает американский генерал летчиков на работу. Заходит немец.
Рассказывает, сколько налетал, в каких операциях участвовал.
Генерал спрашивает:
— А сколько ты хочешь получать?
— 3 тысячи долларов.
— А на что ты их потратишь?
— Ну как? Одну в банк положу, одну — семье, одну себе.
Заходит англичанин. Тоже рассказывает, сколько налетал, в каких
операциях участвовал.
— А сколько ты хочешь получать?
— 4 тысячи долларов.
— А на что ты их потратишь?
— Ну как? Одну в банк положу, две — семье, одну себе.
Заходит русский. Генерал спрашивает:
— Сколько налетал?
— Нисколько.
— ???
— В каких операциях участвовал?
— Ни в каких.
— ???!!!
— А сколько получать хочешь?
— 9 тысяч.
— А зачем тебе столько?
— Ну как? Три — Вам. Три — себе. А за три немец летать
согласился.
Я бы поменял здесь русского на еврея.
Так в был же пост недавно вроде, в Британии агенты ходят за тебя.
Они не собеседуются, они назначают встречу работнику с работодателем.
Как в анекдоте: «Три тыщи Вам, три мне, а за тыщу согласен индус работать».
Эх, не обновил страницу перед отправкой.
НЛО прилетело и опубликовало эту надпись здесь
Учиться проходить собеседования надо :(
меня несколько удивляет и то, как многие конторы проводят собеседования — задавая вопросы о том, чего в работе и близко не используют. поэтому часто главное собеседование пройти — а работать сможешь
это да
в книге как раз и написаны ответы на вопросы типа «чем отличается объект от класса, процедурный подход от объектно-ориентированного» :)
Просто прохождение собеседования часто зависит не от навыков программирования, а от социальных навыков. Тебя могут завернуть, если ты, там, вяло руку рекрутеру пожал, или смело в глаза не смотрел.
Или задаются пространные вопросы типа чем отличается php 5.3 от php 5.2.

Нафига? Человек должен понимать код, писать код, уметь правильно мыслить и уметь учиться (или гуглить). Всё. Я встречал туеву кучу людей, которые блестяще проходили собеседование на php программиста, приходили на рабочее место и сдувались, потому что блестящая теория не давала им бонуса к практике.

Вот по себе скажу — если мне вопрос зададут, я не смогу, например, ответить чем ООП отличается от процедурного метода. Тем не менее в мозгах я это понимаю и одинаково хорошо пишу как в одном так и в ином направлении. Но на вопрос не отвечу. Потому что думаю не так.

Как то так, вот…
НЛО прилетело и опубликовало эту надпись здесь
По-этому я предпочитаю перед собеседованием принять на душу=)
пространные вопросы типа чем отличается php 5.3 от php 5.2.


Я этот вопрос задаю на собеседовании, что бы понять на сколько человеку интересно то чем он занимается. Если человеку действительно интересно, то он постоянно следит за новинками в области, а потом подходит к руководству и говорит: «Надо на нашем выделенном сервере обновить php и я даже готов исправить все баги на всех наших 5-10 сайтах, которые всплывут после перехода. Зато, я больше времени сэкономлю используя современные технологии». Но если человек ходит на работу ради ЗП и молча делает всё то что ему приказывают, то ему новые технологии до лампочки и тем более он не будет изучать: ООП, паттерны, tdd,…
Главное — писать код, который будет работать без сбоев. Если будет участок работ, где система, скажем, будет в разы стабильнее работать без ООП — глупостью будет стремиться за новинками в ущерб стабильности и производительности.

Поэтому более интересным был бы вопрос не в разнице версий, а, скажем «какую бы вы предложили версию для реализации %problemName% и почему?».
имхо.
какую бы вы предложили версию для реализации %problemName% и почему?.

Для всех возможных задач правильным ответом будет: «самую последнюю» (php 5.4). Почему бы и нет? Не вижу смысла использовать старые динозавры.
А вы можете придумать задачу для решения которой лучше было бы использовать старое древнее php4?

Вы не поверите сколько php-программистов не могут ответить на вопрос «какая самая последняя стабильная версия пхп?», потому что им пофиг — им лишь бы быстрее дожить до выходных, получить ЗП и пойти в бар с друзьями.
Я вот например не знал, что последняя — 5.4
Потому что до сих пор у всех заказчиков — 5.2 и менять не собираются. И только один из последних заказов проскочил — переписать 5.2 на 5.3

В конце концов, если вы — компания, где рядовой программист может прийти, сказать «а давайте обновимся, адаптация — с меня» и компания бесспорно согласится, то вы — очень дружелюбная к разработчику компания. Сочтите за комплимент. ))

Да и вообще — писать код чтобы дожить до выходных — я такого отказываюсь понимать. Это должен быть или очень скучный вялотекущий проект, или сотрудник, которому не нравится работа. По первому вопросу — стоит рассмотреть возможность заинтересовать сотрудника, по второму… Второй вообще как бы удивляет — такого человека и принять то не должны были. Или убрать если всё так плохо. Но он есть. Где собака порылась — непонятно.
Может выбирать особо не из чего, а проект(ы) малоинтересные, вот работа и не нравится.
А я вот толком не помню уже, что изменилось в 5.3 — давно это было. Особенно в плане потери обратной совместимости нюансы. Так-то глобально можно сказать — нэймспэйсы, анонимные функции, замыкания, сборщик циклических ссылок. А вот посмотрел список и вижу что многое забыл, например: goto (про него вообще забыл :) ), LSB (казалось что в 5.2 он уже был), константы в глобальном нэймспейсе, ?:, и т. п. В общем я сейчас озабочен совместимостью своего 5.3 кода с 5.4, чем с 5.2.

Не пройду ваше собеседование?
Пройдёте :) goto — зло, по этому хорошо что про него забыли. Наизусть учат когда готовятся к собеседованию по таким книжкам. Изменений в php5.3 было очень много — запомнить всё не возможно, да и было это 3 (!!!) года назад.
Когда мне на собеседовании озвучивают что «Goto зло»
У меня сразу возникает куча вопросов
1. «А вот объяснить почему оно зло можете?»
Ну или давайте с другого конца —
2. «Вы используете break для прерывания цикла?»
или вот еще
3. «Как часто в методах и функциях которые вы пишите вы используете больше одного return?»
и последнее
4. «а причем здесь goto?»

И break, continue, goto а также «несколько точек выхода из метода (return)» нарушают принципы структурного программирования.
Когда люди во всю нарушая принципы структурности в своем коде, говорят что «goto зло» мне это напоминает курильщиков марихуанны, которые ратуют за смертную казнь наркоманам.
Continue break — ИМХО удобны и полезны больше чем вредны
множественный выход из функции — вреден почти всегда (например чтобы добавить логгер перед завершением метода придется копипастить его перед каждым return), в поддержку него можно только назвать проверка входных данных и выход до основного блока
goto — после того как ввели break а некоторых языках и break N то придумать хоть какую нибудь задачу где он был бы полезен стало мягко говоря проблематично

Я это к чему веду. Если человек голословно заявит при мне что goto зло, но при этом не может объяснить почему — то сие заявление я скорее запишу ему в минус чем в плюс
это применимо не только к goto, а к абсолютно любому утверждению. я вообще-то всегда считал, что любые однозначные/категоричные утверждения, которые не могут быть хоть немного внятно объяснены — это минус.
есть даже шутка-мысль такая — чем меньше человек делает категоричных заявлений, тем менее смешно он выглядит в будущем.
== 3. Какими способами можно перенаправить страницу в PHP?
кроме двух указанных есть ещё один через meta refresh

== 13. Обязательно ли писать ?> в конце скрипта?
Так как есть завязка на пхп версии 4, то этот ответ имеет два варианта, а не один, как указано
в пыхе 4.х обязательно

== 17. Какая разница между функциями echo и print в PHP?
echo не функция, а часть языка (statement), print функция.

и вобще ответы устаревшие по отношению к 5.3… 5.4

но если честно, вопросы по мануалу, а их редко задают
Пролистав дальше: это какой-то шаблонный справочник совсем для нубов, в школе на экзаменах могут такие вопросы задавать, но не на собеседовании.
У вас в школе PHP преподавали? Мы дальше шестнадцатеричной системы не ушли.
В мои школьные года пхп не существовал в зачатках. Но нам преподавали, кажется, основы паскаля.
Его до сих пор преподают, хотя учителя большей частью сами толком программировать не могут.
вы закончили школу раньше 94 года?
позже. но писать, на каком там, пхп 3.0 было удовольствие как сайты на баше :)
Что и 4 даже не застали?
в школе нет.
Это вы просто сайты на Си не писали. PHP3 был вполне нормальным процедурным языком, ориентированным на веб.
Я на перле писал за то :) А сейчас вот переписываю часть сайта на плюсах.
Ну я выбирал между PHP3 и Perl, когда понял, что писать сайты на СИ как-то не очень правильно.
==== 3. Какими способами можно перенаправить страницу в PHP?
==кроме двух указанных есть ещё один через meta refresh

А еще есть заголовок Refresh
refresh это метатег
а заголовок — location
wiki wiki… w3c
Если refresh-это всего лишь метатег, то что же означают слова «http-equiv» в его конструкции?

Возможно, вы об этом забыли, но каждый метатег, определяемый через http-equiv, является аналогом одноименного заголовка HTTP.
ага вспомнил, я подумал что тот кому я ответил перепутал location с refresh
ну тогда если не перепутал, получается есть еще один способ, заголовок location :)
Читай внимательнее!

В книге были приведены два способа:
1. Заголовок Location
2. javascript

romy4 добавил третий — meta refresh

Я (тот, кому вы ответили) добавил четвертый — заголовок refresh

Какой «еще один способ» вы нашли?
все верно. вам бы лишь бы придраться? я не читал эту книгу и не искал сколько там ответов дано
4 способ: meta http-equiv=«location»
Да когда вы читать научитесь, для начала хотя бы тот комментарий, на который отвечаете.
Во-первых, это не 4 способ, а пятый!

А во-вторых, этот «способ» не работает (по крайней мере, в Chrome)
Ведь это же сто процентный тупняк вот вы спрашиваете у человека на с-нии
Какими способами можно перенаправить страницу в PHP?

а он тебе ответ:
2. Используя JavaScript…

по моему очень смешно
Не тупняк, а один из способов как можно перенаправить страницу в PHP.
ага с помощью ЯваСкрипта :) браво!!!
Это всего лишь один из нескольких способов.
это все шутка перво-апрельская? :) или это такой тонкий троллинг?
ну не толстый же!
Если уж придираться, то print тоже языковая конструкция, а не функция: print 'helo world';
Если уж так копать, то да. Но echo парсится как языковая конструкция (language token T_ECHO), а print как функция, что ищется в массиве функций области видимости global.
T_PRINT.
ы. вы правы совершенно.
и в конечном итоге сводится к ZEND_ECHO_SPEC_TMP_HANDLER которая выводит переменную.
Вы действительно это мне отвечаете? =)
Нет, конечно: )
придраться ко всему можно, было бы желание :)
> а часть языка (statement)
функция в императивном ЯП это тоже statement. Print тоже не функция, они все конструкции языка.
== 25.
Ряд Фибоначчи выводится за сложность O(2^n), хотя можно за O(n).
Это кстати хороший тест на инерцию мышления:
24. Напишите рекурсивную ф-ю ХХХХ
25. Напишите ф-ю Фибоначчи
Ну рекурсивно с динамикой, да.
Просто энное число Фибоначчи и вовсе за логарифмическое время можно посчитать.
И даже за константное, если точность не важна.
Спасибо, вы мне на весь вечер настроение подняли.
ua.php.net/manual/en/function.print.php Я просто на всякий случай здесь оставлю, почитайте описание, там черным по белому говорится что принт — не функция. И это в мануале.
да и сам интерпретатор такого же мнения
$ php -a
Interactive shell

php > var_dump(function_exists('print'));
bool(false)
чёрт, комент предыдущий не отправился. Да, вы правы. print сводится к вызову ZEND_ECHO_… в конечном итоге.
еще как задают
Это печельно, что такие вопросы порой являются порогом прохождения по вакансии.
печально, но это так :) что есть то есть.
Это не книга, а некий текст, завернутый в PDF. В книгах не бывает такого количества ошибок правописания.

Обратите внимание на третий вопрос: «Какими способами можно перенаправить страницу в PHP?». Судя по ответу, подразумевается перенаправление браузера на другую страницу. Вопрос сформулирован некорректно.

Мне это творение кажется низкокачественным.
Там не только грамматические ошибки.
Вот к примеру еще такие вещи есть:

Как задать красный цвет для всех элементов, имеющих класс red?
.red { background-color:white; }
нашел вредный совет:

21. А как перевернуть массив без функции array_reverse?
Например, так:
<?php
$arr = array(‘h’, ‘e’, ‘l’, ‘l’, ‘o’);
$reversed = array();
for ($i=0; $i<count($arr); $i++) array_unshift($reversed, $arr[$i]);
for ($i=0; $i<count($reversed); $i++) echo “$reversed[$i]”;
?>


считать count($arr) в каждой итерации не ок.
Да и вариант не оч человеческий выбран:
for ($i=count($arr)-1; $i<=0; $i++) { $reversed[] = $arr[$i]; }
Для массива hello world это по-барабану, даже на массиве с тысячей элементов. Сложность count($arr) константная, а не линейная. На пикосекунду дольше, чем вызов переменной со значением размера.
Ну мне кажется что человек который так пишет в примерах будет использовать такой подход и в реальном коде.
минусующие сосните тунца, сперва разберитесь в исходниках пыха.

PHP_FUNCTION(count) → zend_hash_num_elements() → return ht->nNumOfElements;
Да это ведь горе-оптимизаторы. У них запросы к базе без индексов в цикле, а тормозит из-за неправильного count.
И двойных кавычек, ага.
Кстати, КО подсказывает, что производительность двойных кавычек в новых версиях тоже изменилась, причём, судя по поведению токенайзера PHP, который выделяет токены в двойных кавычках, выражения внутри двойных кавычек теперь тоже компилируются заранее, а поэтому есть вероятность, что это будет работать быстрее. И это подтверждает, к примеру, такой тест:

<?php
define('NUM', 1000000);
$start = microtime(true);
for ($i = 0; $i < NUM; $i++);
$for_time = microtime(true) - $start;

$some_str = "Hello world!";

echo "For loop time: " . round($for_time, 3) . " sec\n";

$start = microtime(true);
for ($i = 0; $i < NUM; $i++);
echo "Empty stmt time (should be 0): " . round(microtime(true) - $start - $for_time, 3) . " sec\n";;

$start = microtime(true);
for ($i = 0; $i < NUM; $i++) {
	"hello world $for_time $i $for_time $i $for_time $i $some_str $some_str";
}
echo "Double quotes: " . round(microtime(true) - $start - $for_time, 3) . " sec\n";

$start = microtime(true);
for ($i = 0; $i < NUM; $i++) {
	'hello world ' . $for_time . ' ' . $i . ' ' . $for_time .' ' . $i . ' ' . $for_time . ' ' . $i . ' ' . $some_str . ' ' . $some_str;
}
echo "Single quotes: " . round(microtime(true) - $start - $for_time, 3) . " sec\n";


Результаты:

$ php bench.php 
For loop time: 0.097 sec
Empty stmt time (should be 0): -0.005 sec
Double quotes: 2.183 sec
Single quotes: 2.891 sec
Всегда использовал одинарные кавычки, не потому что они быстрее, а потому, что shift не надо нажимать.
Ваши тесты немного ошибочные. Дело не в разных кавычках, а в том, что в варианте с одинарными кавычками используется оператор конкантенации, из-за которого вы и получаете разницу в 0.7 сек. Если в варианте с двойными кавычками использовать ту же конкатенацию, то время выполнения двух вариантов должно сравняться.
Не согласен, как раз и были очень известные тесты, в которых говорилось, что конкатенация быстрее интерполяции переменных в двойных кавычках. Моё утверждение было о том, что это более неверно, причём уже довольно давно.
А, ну да, с 2001 года многое изменилось :)
что это более неверно, причём уже довольно давно.

Да, эти тесты уж слишком известные. Когда уже их удалять с сервера.
Особо доверчивых после прочтения сложно переубедить, аргументы о замшелости статьи не помогают, трясти начинает, когда в качестве аргумента дают пруф на эту статью. А начальство переубеждать сложнее всего (было у меня с кавычками).
Любопытно.
Если же уменьшить количество переменных до 4, то конкатенация и двойные кавычки выравниваются по скорости.
Ещё уменьшить — конкатенация быстрее.

PHP5.3.5
Похоже на правду.
Резюмируя, как это часто бывает, правильны оба вывода сразу, каждый при своих условиях:
конкатенация в малых количествах быстрее переменных в двойных кавычках, однако с ростом числа участвующих переменных конкатенация оказывается медленнее.
Клева, можно не парица оказывается. Похоже ето знание ко мне пришло как в известной истории про «здесь так принято» :)
И все таки, как тогда обьяснить это?
просто переменная $num: поиск в массиве переменных, возврат значения
count($data): поиск переменной $data, возврат значения $data, вызов count для $data, возврат к-ва элементов $data.

в два раза больше действий
Там скорее будет проблема в array_unshift, нежели в чем-то другом
Хоть бы кто-нить написал про ошибку )
Там же не $i++, а $i--
Чтобы не ошибаться — пишите так:
for ($i = count($arr); $i--;} {
    $reversed[] = $arr[$i];
}
for ($i=count($arr); $i-->0;)

мне так больше нравится :) Как будто $i стремится к нулю )
Здрасьте! С какой стати там должно быть а $i-- ??
В моем варианте:

for ($i=count($arr)-1; $i>=0; $i--) { $reversed[] = $arr[$i]; }

Там еще и условие выхода не правильное )
ааа))
Это действительно вопросы для собеседований? о_О В моем говноколледже спрашивали примерно то же на экзаменах, правда про C++.
бывает :)))))))))
И это собеседование по PHP! :)
Если коротко, то устаревшая хрень…
Мал, что устаревшая, так ещё и не точная хрень…
Если еще короче, то просто хрень
> В чем различия между четвертой и пятой версиями PHP?
Кажется уже пора спрашивать в чем отличие 5.4 от 5.3 и от 5.2.
пора, но некоторые до сих пор спрашивают отличие 5 от 4…
31. Нарисуй форму для отправки файла…
Разве не корректней использовать move_upload_file вместо copy?
и корректно, и правильно. Человек будет забивать темп загруженными файлами делая copy.
Не будет. После завершения скрипта загруженные файлы, если они не были перемещены, неважно каким образом, будут подчищены сами.
Да, мой баг. Но copy делает лишнюю работу.
Какую? В случае, если tmp и хранилище на разных разделах, а это зачастую так и есть, работа будет производиться одинаковая.
Да нет, далеко не часто.
Я чаще встречал хостинги, где tmp для виртуалхоста лежит на том же диске, даже в директории юзера, который хостится. Использование общего tmp чревато дырами.
Разница:

copy:
1. копирует файл

move_upload_file:
1. проверяет этот файл есть?
2. проверяет загружен ли он пхп через пост?
3. копирует файл
4. удаляет файл

Чувствуете разницу кто делает лишнюю работу? Не говорите глупостей, просто достаточно перед тем как что-то написать, почитать _официальный_ мануал по пхп, для того чтоб увидеть разницу и не выглядеть как человек которому эта книга нужна.
1 вопрос, а насколько корректно использовать вместо них rename? В случае если файлы на одном и том же локальном диске — будет ли копирование? А если они на разных томах? Судя по Changelog-у здесь начиная с 5.3.1(win) и 4.3.3(linux) должно сработать.
использовать можно хоть побайтовое чтение собственным расширением, написанным на сях. только зачем? move_uploaded_file сам всё делает. или я неправильно понял вопрос? :)
Ну если верить taliban-у, то move_uploaded_file всегда копирует файл. Если я правильно понимаю rename, то переименовывание файла должно быть существенно быстрее, нежели копирование (особенно если речь идёт о каких-либо больших файлах, к примеру видео).
А вы лучше не верьте, а смотрите исходники. Мой ответ чуть ниже.
Вот тут уже не вкурсе, но вообще как человек выше говорил все же уместней использовать move_upload_file, именно из-за проверки ее на загруженность через пост, чтоб не скопировать «подсунутый» файл.
Если посмотреть исходники, то внезапно можно обнаружить, что move_uploaded_file пытается сделать ренейм и только в случае если ренейм сфейлился, то копи+анлинк.
Сталкивался с тем, что если скрипт заперт в DOC ROOT`е, то copy не сможет достать файл, а move_uploaded_file сможет.
Вот она, сермяжная правда!
move_uploaded_file лучше в целях безопасности вроде как.
не корректней.
Чего вдруг?
А как перевернуть массив без нее?
Это как моя любимая задачка на строку-перевертыш.

$arr = array(‘h’, ‘e’, ‘l’, ‘l’, ‘o’);

for ($i = 0; $i < floor(count($arr)/2); $i++)
{
    $tmp = $arr[$i];
    $arr[$i] = $arr[count($arr)-$i-1];
    $arr[count($arr)-$i-1] = $tmp;
}
Вот, на мой взгляд, более элегантное решение:
	$source = array( 50 , 40 , 30 , 20, 10);
	$pieces = count($array)-1;
	$reversed = array();
	while($pieces >= 0) {
		$reversed[] = $source[$pieces--];
	}

Результат:
Array (
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
    [4] => 50
)
Всё зависит от требований. Решение перед вашим зато памяти дополнительной потребляет лишь в размере одной временной переменной. А у вас второй массив в памяти.
Может быть, может быть. Но, скажу честно, от конструкции floor(count($arr)/2) меня почему-то передёрнуло.
в школе стандартные алгоритмы на паскале не реализовывали чтоли?
Или, наоборот, поэтому и передернуло? :)
Таким примером можно показать что недавно использовал активно паскаль, а как сделать оптимальнее в php не знаешь.
В школе, вы удивитесь, мы писали на Ассемблере. Но это был «кружок для избранных», остальные с горем пополам осваивали Бэйсик.
Более того она будет вычисляться каждую итерацию, неоптимальненький ответ.
Совершенно верно. Идет расчет на расход памяти. В идеале еще можно сделать через SplFixedArray, но я посчитал это излишним.
Преимущества такого подхода:
1. Минимум писанины
2. Наглядность
3. count() вычисляется всего один раз (в отличие от остальных примеров у автора и в комментариях)
4. Всего одна математическая операция — декремент. Нет путаницы в вычислениях, не нужен дебаг.

Я понимаю, что это микрозадача. Но по стилю её решения сразу видно какой реальный опыт имеется у человека за плечами и каким образом этот «стиль» может сказаться на его фактической работе.
3. count() не вычисляется, он уже хранится вычисленным. А функция просто его возвращает.

Недостаток этого подхода: в случае массива в 20мб и выделенной памяти в 32мб — ваше решение упадёт, а решение выше, хоть с десятком каунтов, будет работать.

Говорю же — всё зависит от требований и ограничений.
Теоретически — да. На практике с массивами по 20Мб я просто не сталкивался и ничего не могу сказать о нагрузке при таких операциях. И ещё сразу появилась мысль, что если внутри ворочаются такие массивы, то не всё хорошо с архитектурой самого приложения.
Я с вами совершенно согласен, что такие массивы это или кривота, или исключение из правил. Но я хотел указать на то, что «более элегантное» это оценка настолько качественная, что в отрыве от требований к решению использовать её стоит очень и очень осторожно :-)
Задачи бывают разные
Моё любопытство настаивает на примере подобной задачи =)
Такие задачи носят не постоянный характер, но встречаются.
В данный момент занимаемся переносом данных из доморощенной CRM в Salesforce. Данные переносятся по филиалам, до 100+тыс клиентов. В БД есть клоны, необходимо при переносе их склеить, поиск идент по ФИО и телефонам. Данные по телефонам хранятся как ввели. С помощью SQL решаемо, но долго, оказалось дешевле загрузить все в массивы и сравнить.
Разделяй и властвуй.
Это я к тому, что решение данной конкретной задачи в рамках корпоративной системы на локальном сервере с парой гигов оперативы носит абсолютно банальный характер.
Другое дело — если мы работаем в рамках виртуального хостинга на довольно ограниченных ресурсах. По образу и подобию можно было бы представить перелив данных из морально устаревшего, но довольно крупного интернет-магазина на новую архитектуру.
Да, задачка не из разряда «2+3», но это уже боевые условия и боевые задачи, которые должны решаться исходя из тех ресурсов, которые имеются на данный момент. И практика показывает, что на каждую конкретную задачу есть не менее трёх очевидных путей решения, не говоря уже о нестандартных. И тут уже важно выбрать самый оптимальный из них, а не спорить о том, чей говнокод отработает быстрее.

Суть всех холиваров в том, что они абстрагированы от реальных условий. Кто элегантнее заебенит функцию или класс, кто при обработке огромных массивов данных на доли секунды превзойдёт своего предшественника — это просто пиписькомер. Каждый день в боевых условиях настоящий программист должен принимать решения — какой путь более оптимален с поправкой на реальное положение вещей. Если он принимает верные решения — это хороший программист. Если он не может удержать в своём сознании все связи классов и модулей, не может хотя бы приблизительно оценить нагрузки и не может предсказать поведение системы в тех или иных условиях, он — плохой программист. Такая вот простая, но одновременно очень доступная мораль.
Парсер Excel-файла на 40000 строк и примерно 15 столбцов может сожрать до полугигабайта в оперативке.
Плохой парсер! Фу!
Предвещая претензии и аргументы — а чем не устраивает CSV?
Не важно хранится или нет. Вызов функции — сравнительно долгая операция в ПХП.
«Но по стилю её решения сразу видно какой реальный опыт имеется у человека за плечами».

В том то и дело. Получив опыт в highload-проектах, я стал сделить за памятью в скриптах.
$source = array( 50 , 40 , 30 , 20, 10 );
$rev = array();
while ( count ( $source ) ) $rev[] = array_pop( $source );
Это вы сейчас мой пример сократили до трёх строк, да?
вот только php вроде как оптимизирует использование памяти при присовении значения одной переменной другой, не проверял с массивами. На хабре статья была.
Во второй строке ошибка.
Три count в цикле — не есть гуд.
Частично согласен, но не могли бы вы пояснить, чем именно, к примеру 3 count — не гуд, а 3 арифметические операции — гуд?

Это я к тому, что не совсем понятно, почему вы заострили внимание именно на count, а не на арифметику с `-1`, которую точно так же можно убрать выше.
Я не говорил, что арифметика — гуд. Count в глаза бросился, да и все.
Я плохо разбираюсь в компиляторах, а в интерпретаторах и подавно, но разве count не оптимизируется во всех языках, которые только существуют? Или хотя бы в тех, о которых можно говорить в приличном обществе?
<?php

$iterations = 100001;

$arr = array('h', 'e', 'l', 'l', 'o');
$t1 = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
	$arr = reverse1($arr);
}
$t1 = microtime(true) - $t1;
var_dump($arr);
var_dump($t1);

$arr = array('h', 'e', 'l', 'l', 'o');
$t2 = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
	$arr = reverse2($arr);
}
$t2 = microtime(true) - $t2;

var_dump($arr);
var_dump($t2);

function reverse1($arr) {
	for ($i = 0; $i < floor(count($arr)/2); $i++)
	{
		$tmp = $arr[$i];
		$arr[$i] = $arr[count($arr)-$i-1];
		$arr[count($arr)-$i-1] = $tmp;
	}
	return $arr;
}

function reverse2($arr) {
	$c = count($arr);
	for ($i = 0; $i < floor($c/2); $i++)
	{
		$tmp = $arr[$i];
		$arr[$i] = $arr[$c-$i-1];
		$arr[$c-$i-1] = $tmp;
	}
	return $arr;
}


Вывод:
array
  0 => string 'o' (length=1)
  1 => string 'l' (length=1)
  2 => string 'l' (length=1)
  3 => string 'e' (length=1)
  4 => string 'h' (length=1)

float 2.8682391643524

array
  0 => string 'o' (length=1)
  1 => string 'l' (length=1)
  2 => string 'l' (length=1)
  3 => string 'e' (length=1)
  4 => string 'h' (length=1)

float 1.7087500095367

Ок, понял. Для полноты картины, можете сделать тест, который в теле цикла не изменяет массив?
Пустой цикл? Или как?
Пустой может как-то иначе соптимизироваться, что-то внутрь надо поместить, хоть арифметику простую. Смысл в том, чтобы сам массив не изменялся.
Вас это интересовало?

<?php

$iterations = 100001;
$t1 = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
	$a = 1;
}
$t1 = microtime(true) - $t1;
var_dump($t1);

float 0.038902044296265
Не-не-не :)

Меня интересует сравнение

for ($i = 0; $i < $count($arr); $i++) {
$a = $arr[$i];
}


и

$iterations = count($arr);
for ($i = 0; $i < $iterations; $i++) {
$a = $arr[$i];
}


PS: я не PHPшник, возможны ошибки :)
<?php

$array = range(0, 100000);

$t1 = microtime(true);
for ($i = 0; $i < count($array); $i++) {
	$a = $array[$i];
}
$t1 = microtime(true) - $t1;
var_dump($t1);

$t1 = microtime(true);
$c = count($array);
for ($i = 0; $i < $c; $i++) {
	$a = $array[$i];
}
$t1 = microtime(true) - $t1;
var_dump($t1);

float 0.24822592735291

float 0.046469926834106
Понял, спасибо. Хотя, конечно, странно, всегда считал, что такие вещи должны автоматом оптимизироваться.
каким образом интерпретатор бы оптимизировал такую вещь?
Повторю, я очень мало знаю о PHP, но мне кажется, что используется не обычная построчная интерпретация.
а давайте просто достанем и померяемся

тестирующий, не побоюсь этого слова, фреймворк (PHP 5.4.0 with Xdebug v2.2.0rc1):
$arr = range(0, 100500);
$start = xdebug_time_index();
// code...
echo xdebug_time_index() - $start . ' ' . memory_get_peak_usage();


результаты:
for ($i = 0; $i < floor(count($arr)/2); $i++)
{
    $tmp = $arr[$i];
    $arr[$i] = $arr[count($arr)-$i-1];
    $arr[count($arr)-$i-1] = $tmp;
}

0.63774108886719 8691144

$rev = array();
while ( count( $arr ) ) $rev[] = array_pop( $arr );

0.60788989067078 9214832

$count = count($arr);
for ($i = 0; $i < floor($count/2); $i++)
{
    $tmp = $arr[$i];
    $arr[$i] = $arr[$count-$i-1];
    $arr[$count-$i-1] = $tmp;
}

0.19419097900391 8691048

$count = count($arr);
for ($i = intval($count / 2) - 1; $i >= 0; $i--)
{
    $tmp = $arr[$i];
    $arr[$i] = $arr[$count-$i-1];
    $arr[$count-$i-1] = $tmp;
}

0.041511058807373 8691048

$pieces = count($arr)-1;
$reversed = array();
while($pieces >= 0) {
    $reversed[] = $arr[$pieces--];
}

0.039575099945068 14038952

for ($l = 0, $r = count($arr) - 1; $l < $r; ++$l, --$r)
{
    $t = $arr[$l]; $arr[$l] = $arr[$r]; $arr[$r] = $t;
}

0.03570294380188 8690680

$arr = array_reverse($arr);

0.014595031738281 14038056
Из нестандартных (array_reverse) мой вариант занял почётое второе место. Я, честно сказать, польщён, ибо код писался «на коленке» и без всяких мыслей о «померяться».
count не считает, он просматривает специальную переменную (или вызывает функцию, если это итератор). По сути, он быстрый.
Этого я не знал. Но это не отменяет факта, что count в теле цикла замедляет процесс.
$arr = array(‘h’, ‘e’, ‘l’, ‘l’, ‘o’);
$arr = explode( ''@some_uniq_symbol@'', strrev( implode('@some_uniq_symbol@', $arr) ) );
Я не использовал функцию array_reverse =)
$arr = array(‘h’, ‘e’, ‘l’, ‘l’, ‘o’); //init
$arr = array(‘o’, ‘l’, ‘l’, ‘e’, ‘h’); //reversed

:)
этапять :)))))
Не знаю, лично для меня после прочтения этой книги многое разложилось по полочкам. На собеседовании человек всегда может немного растеряться, а освежить некоторые знания всегда полезно.
А Вас не пугает, что там некоторая информация устарела, а некоторая была изначально неверной?
я читал только то, что мне было интересно и немного не понятно. Всё читать конечно бессмысленно.
Вы не ответили на мой вопрос.

Вот Вы, насколько я понял, не считаете себя профессионалом в PHP, как вы определите, что в этой книжке верно и правильно? А там есть такие моменты.
Мы ведь все думаем, что человек должен не просто прочитать список вопрос-ответ, но и осознать прочтенную информацию?

Даже человек который учит PHP, даже если для себя. Видимо в книге есть сомнительные куски кода и даже ошибки, однако грамотный читатель должен проверять неочевидные для себя моменты на практике.
Т.е. то, что в «книге» есть косяки — это нормально. А тот кто каждый пункт не перепроверил, тот сам дурак?
Да нет, абсолютно не правильный вывод.

Просто это не энциклопедия. Я, например, сейчас изучаю «Cambridge grammar for First Certificate» — кажется, что Кэмбриджу можно доверять полностью, в отличие от Андрея Шевченко, однако, я всегда дополнительно изучаю неочевидные для меня вещи. Или случаи, когда употребление каких-то конструкций для меня просто подозрительно.

Смысл прочтения без осознания прочитанного = 0.
Не путайте. Осознание != проверка каждого высказывания. Неочевидное != ошибочное.
Ну не знаю. Если бы в инструкции к револьверу было что-нибудь про «выстрелить себе в ногу для проверки на холостые» я бы задумался =)
Потому что, у вас есть теоретическое знание о револьверах, которого достаточно, чтобы представить, что может произойти, если патрон окажется боевым.

А вот если бы вы не знали, вы бы могли и последовать инструкции. Речь об этом. Просто знание про револьвер более распространённое и более наглядное, проще представить, а знание про ЯП — менее распространённое, менее наглядное, и сложнее обнаружить инструкции, аналогичные выстрелам в ногу для проверки холостых.
Склоняюсь перед Вашей волей.
Просто я уже десяток лет изучаю стили и языки программирования, и каждый «мануал» по привычке вызывает у меня долю недоверия и желание проверить всё на практике.
Von lict Jovi, non licet bovi — Что очевидно профессионалу совершенно не очевидно новичку. Немножко не точно, зато в тему.
Конечно я не профессиональный PHP-программист! Я там себя не буду считать никогда, потому что нет предела совершенству! Т.к. большую часть своей короткой жизни я изучал C#, то некоторые моменты мне были яснее некуда, но некоторые моменты стоили того, чтобы их прочесть и осознать. Если для меня что-то покажется не таким, каким я это видел до этого, я спрошу на работе, правильно ли это или нет.
А, если не покажется? Но это будет тем не менее неправильным, а Вы запомните так как есть?
Т.к. я всё-таки ещё учусь, то подвергаю сомнению всё, что не соотносилось с моей деятельностью на C#
Эта «книга» подходит для теста типа «найдите, что здесь не так», а не для обучения.
Никто и не спорит. Но это не меняет факта, что там есть вещи, которые могут знать не все. И я говорю не только о примерах кода, но и собственно ответах на вопросы.
А кто не даёт Вам читать мануал? Там явно больше вещей, которые могут знать не все.

Насколько хорошо Вы знаете английский?
На уровне того, что преподавали в институте
Узнайте тогда что такое ZCE и найдите соответствующую книгу. Это будет гораздо полезнее.
Ничего ответить на такое не могу
Какая конкретно информация устарела?
Подходит только при собеседовании на вакансию начинающего кодера, проверяются только базовые вещи и уровень владения мануалом.
именно на начинающий уровень и рассчитано.
Если честно хрень какая-то, у меня спрашивали паттерны, оптимизация под highload, системы контроля версий, phpDoc ну и еще что-то, уже не помню
на собеседовании на джуниора?
Угу.
33. Используя конструкцию switch, написать функцию boo, принимающую
одно число в качестве аргумента. Если это число равно 2, функция должна
вывести слово “Двойка”, если 3 – “Тройка”, в остальных случаях – “Фигня ка-
кая-то”.
<?php
function boo($num) {
switch($num) {
case “2”:
echo “two!”;
break;
case “3”:
echo “three!”;
break;
default:
echo “shnyaga!”;
break;
}
}
boo(2);
?>


Тваюжмать :((
Я всегда буду пользоваться предпросмотром
Я всегда буду пользоваться предпросмотром
Я всегда буду пользоваться предпросмотром
… и тегом <source>
что не так?
> «Фигня какая-то»
> echo “shnyaga!”;

Если вы называете этот документ «книгой», думаю, данные выражения не слишком в ней уместны.
А что, на собеседованиях говорят «Извольте, господин»? Или все же «шняга»?
Отличная штука. :) Пусть как можно больше чуваков её вызубрят, можно будет легко таких отсеивать на собеседованиях. Например, в вопросе #22, где используется strlen(), можно тестируемому подсунуть кириллическую строку в UTF-8 и посмотреть, как он удивится, когда заученный пример отработает некорректно. :)

Приходилось собеседовать довольно много разработчиков, и основываясь на своём опыте могу сказать, что хороших рарзработчиков удавалось найти и без таких вопросов. :)
Попадался мне такой супер герой шутник с кириллицей на собеседовании. Сидит улыбается, ждет, что я буду делать. Я ему говорю, у Вас тут iconv не хватает, лучше заменить на mb_strlen.

И о чудо! Он мне говорит — «Неправильно! Нужно использовать другую кодировку!»

У Вас «супергерой шутник» в какой–то негативной коннотации приведено. :)

Так или иначе, если собеседование предполагает тестирование на месте, у меня есть простой тест на знание PHP и MySQL, через который я сам когда–то проходил при приёме на работу разработчиком. Тест простейший (делается за 10–15 минут), но за последние 5 лет его использования не дал ни одной осечки: на прошлом месте работы все разработчики, которые его выполняли, были приняты на работу и отлично себя проявляли.

Но в последнее время уже и тестов не требуется, как правило: достаточно послушать, как и что человек рассказывает о задачах, которые ему приходилось решать, и можно, в общем–то, получить достаточное представление о его квалификации и вменяемости.
Существует ли универсальная защита от SQL-инъекций?
Про Prepared statements ни слова, зато есть strip_tags. О_о.
Вы что не знали что это универсальная защита? Нет тэгов нет иньекций!
ВСЁ перечислять совершенно не обязательно. Книга рассчитана на уровень начинающего.
Сейчас автор начитается комментов и выпустит второе издание)
таки да! я уже записываю критику :)
Вывести только те магазины, которые находятся во Львове и/или Харькове:
SELECT * FROM shops WHERE area=”Львов” AND area=”Харьков”

Это гениально! Ничего, что результат будет 0 строк по определению? Вообще на этапе разбора запроса? =)
> находятся во Львове и/или Харькове

В соответствии с бизнес-требованиями следовало запрос написать соответственно:

WHERE area=”Львов” AND/OR area=”Харьков”
AND тут вообще не катит. Не может быть одно поле быть одновременно и «Львов» и «Харьков»
Это просто разрыв шаблона какой-то.
С бизнес требованиями все нормально, в них ничего нет про одно поле.
не может. ошибка :( бывает…
поправим :)
Ещё уберите rand и используйте mt_rand.
откуда убрать? зачем?
Из кода. Это плохой генератор.
На моем недавнем собеседовании работодатель был явно под влиянием этой книги.
половина работодателей такие :)
Местами немного устарело, но в целом очень и очень неплохо.
Хотя бы, нет вроде, идиотских вопросов: «что выведет на экран $i++ -$i-- * ++$j» и всякого такого

А вообще по-моему, для первоначального отсева лучше небольшое тестовое задание.
Все равно нет гарантий, что человек будет практически полезен в данной конкретной организации в конкретном коллективе в конкретных проектах.
вопрос типа «чему равно $i после выражения $i+= $i++ + ++$i» — очень неплохой. на относительно простом примере можно увидеть понимание основ и финтов ушами. и если человек вообще не может ответить, то дальше можно ничего не спрашивать.
А где описано, над чем оперирует унарный оператор `++`, над значением или над ссылкой?

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

$i = 5;
$i+= $i++ + ++$i;


а он сразу зависает, потому что в «книге» из топика такое не описывалось — вердикт очевиден.
Ну я просто как бы уже не джуниор давно, гхм.

А вопрос всё равно плохой. С новичком можно обсудить тему для новичков, с неновичком — можно обсудить темы для неновичков. А этот вопрос лучше не обсуждать ни с кем :-)
Пример из маунала:
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5

Каких таких основ и финтов?)
Проверка навыка «умение разбираться в чужом коде» в действии же :-)
наличие навыка гадания в чужом коде, скорее ;)
конечно же, все устраиваются на работы, где нету ни строки legacy-кода, где есть полная и актуальная документация, где не приходится переписывать какие-то устаревшие куски кода, где не приходится допиливать какую-то мелкую фичу. да, если кругом только такие работы, то умение разбираться в чужом коде — лишнее. в противном случае это весьма полезный скилл.
Это шутка ведь была :-)

Я согласен, что это полезный и очень крутой навык (тут уже не ирония, недавно видел как человек в огромном и новом для него проекте за считанные секунды нашёл нужный код).
Единственным верным ответом на него, имхо, может быть только следующее: я никогда так не напишу, а если встречу в чужом коде, то трогать не буду пока работает. И только в случае реальной надобности тронуть, аккуратно разберусь.

В жизни не поверю что серьезный разработчик каждый день пишет или видит подобные извраты и, соответственно, помнит все тонкости языка. Не, если нужен именно code monkey, знающий только один язык и учивший мануал, вместо получения опыта реально работы, тогда другой разговор.
что выведет на экран $i++ -$i-- * ++$j

Оно выведет из себя программиста, поддерживающего этот говнокод.
а что именно устарело?
Многие вещи, которые я считаю устаревшими или спорными, тут уже, в принципе, описали. А многое слишком субъективно и очень спорно, не хотелось бы разводить флейм. Наверное, я лучше как соберусь и оформлю свои мысли, пришлю вам в личку, если вы, конечно, не против. В целом все очень хорошо, я даже знаю одного человека, который уже проводил собеседование по вашим вопросам :)
Может всем хабросообществом напишем книгу?)
Логичнее будет помочь с переводом документации на php.net
Пожалуй с вами я согласен
39. Есть массив a = array(тут много элементов). Проходим по массиву циклом for (i=0; i<=count(a); i++). Можно ли как-нибудь ускорить цикл?
Да.
1) Вынести count(a) в отдельную переменную;
2) Считать массив с конца циклом for (i=count(a); i>=0; i--).

foreach уже запретили?
Очень показательно, что второе решение в принципе рассматривается решением. Другими словами — код, по идее автора книги, предназначен не для того, чтобы решать конкретную задачу (для которой, почти наверняка, обход в обратном порядке неприемлем или приведёт к переписыванию тела цикла), а просто для того, чтобы радовать глаз
Это собеседование, поэтому тут не конкретные задачи решаются, а проверяется понимание того как работает цикл (в данном случае) и можно ли его в принципе написать иначе как (i=0; i<=count(a); i++). Напомню, что собеседование на джуниора.
Тем более. Не нужно пудрить джуниору мозг, а то он прочитает вашу книгу и поверит, что обход с последнего элемента массива происходит быстрее.

Хотите узнать про принципы — спросите в явном виде, как обойти массив с конца, не притягивайте за уши всякую фигню.
Это вопрос РЕАЛЬНОГО собеседования и ответ про обход массива с последнего элемента — РЕАЛЬНЫЙ ответ собеседующего в качестве правильного ответа :) А книга основана на РЕАЛЬНЫХ вопросах и ответах, сколь бы дурацкими они не были.
Даже если это реальный вопрос, то НЕЛЬЗЯ отвечать на него подобным образом. Просто потому что у вас нет тела цикла.

> в качестве правильного ответа
Ну значит и собеседующий, и собеседуемый друг друга стоят. Ибо НЕЛЬЗЯ такой ответ принимать правильным.

Программисты решают реальные задачи, а философией занимаются философы.

Более того, вариант 2 является частным случаем варианта 1. Какой смысл говорить о том, о чём уже сказали?
И причем здесь foreach, если вопрос «Можно ли как-нибудь ускорить цикл for»?
Можно сбросить еще одну итерацию, написав i < count(a), т.к. счет идет с нуля до count(a)-1.
притом, что это самый быстрый способ обойти массив, собственно для этого он и придуман.
— Как быстрее всего доехать до Киева на поезде?
— Да зачем на поезде, на самолете же быстрее! Он же для этого и придуман!
— Но мне нужно на поезде…
Мало того, что ответы на вопросы не полные и не правильные, так еще и вопросы для собеседования детские. Меня шманали по ООП, нагрузки, linux, mysql (join'ы и их отличия друг от друга и др.), варианты кеширования, JS: как быстрее ищет, по id или классу и так далее, jquery, ajax и др. Логика, быстрые и правельные решения.
Это было собеседование на джуниора?
Да
Ух сколько критики! Но это и хорошо. Сделаем «Издание второе. Дополненное и переработанное» :)
Всецело одобряю задумку. Может набросать по-быстрому сайтик с вопросам-ответами для собеседований? Типа, собеседование на «пэхапэшника» и вопросы пользователей с рейтингами. Если рейтинг уходит в негатив, то вопрос скрывается. То же для всяких монтажников-админов-бухгалтеров. По-моему, удобно!
хорошая идея
На фоне Вашей книги, у многих появилась возможность блестнуть умом :)

Во втором издании код отформатируйте, пожалуйста, а еще лучше — подсветите.
ок
Приходилось ли Вам проводить собеседования?
нет
И Вы автор этой книги?
похоже на то :)
Этого я и боялся.: )
Да бояться не стоит :)
И сколько собеседований Вы прошли? :)
много)
Успешно?
когда как :)
это печально
Числа Фибоначчи нельзя получать при помощи рекурсии. Я всегда считал, что именно в этом подвох.
В любом случае, сборник очень даже хорош. Спасибо!
Когда ждать второе издание? Будете ли писать где-нибудь в github? Можно поучаствовать?
Естественно :) Становитесь соавтором.
Где происходит написание? Можно линк на гитхаб (или куда то-ещё)?
У меня еще нет аккаунта на гитхабе. Я сперва переделаю книгу с учетом озвученной здесь критики :)
Ну, в общем, как Вам будет удобнее. В гитхаб (или bitbucket-закрытые бесплатные репозитории) в формате markdown можно писать, он удобный, а перед выходом переводить в PDF. Многие книги так и писались, о них тут (на хабре) писалось.
Либо просто могу дописывать свои вопросы и присылать по старинке по электронной почте.
а пока можно прислать по почте или скайпу свои вопросы :) я пока буду импрувить то, что есть :)
И вообще, предлагаю в конце сделать приложение — примеры реальных тестовых заданий из реальных фирм. У меня скопилось немного.
насчет приложения — отличная идея. давайте сделаем.
Это почему нельзя?
Сложность алгоритма примерно C^n.
Например, для вычисления всего лишь 5000-го числа фибоначчи нужно выполнить 3,9803*10^1020 операций.
Тысяча нулей — это очень, очень, очень много.
Насколько я понимаю, для вычисления 5000-го числа Фибоначчи требуется всего 5000 операция сложения — выполнится быстро (у меня получилось 0.012 с.). Проблема в том, что результат получится очень большой и не влезет в стандартные числовые типы данных.
проблема не в числовых типах данных, а в stack overflow -)
В моём случае как раз в типе данных. При генерации 50 миллионов чисел у меня таки вылезла ошибка java.lang.OutOfMemoryError: Java heap space, но я подозреваю, что при необходимости это можно подкрутить в jvm.
Неверно. Я взял рекурсивный код из книги и добавил счётчик. Вот, что вышло.
<?php
$counter=0;
function fibonacci($n)
{
	global $counter;
	$counter++;
	if ($n < 3) {
		return 1; 
	} else {
		return  fibonacci($n-1) + fibonacci($n-2);
	}
}
for ($n = 1; $n <= 40; $n++) {
	$counter=0;
	echo(fibonacci($n) . "  ");
	print " Операций: ".$counter.'
';
}


Вот вывод строк 27, 28, 29, 30, 31
196418 Операций: 392835
317811 Операций: 635621
514229 Операций: 1028457
832040 Операций: 1664079
1346269 Операций: 2692537

После этого прошло 30 секунд и скрипт умер. 32-е число найдено не было.
Попытка найти 40-е число Фибоначчи без лимита по времени приводит к долгим размышлениям. На самом деле, до сих пор думает. Находить 5000-е не буду.
Таким образом, пример из книги просто-напросто неспособен найти 100-е число, к примеру.
Додумалось
102334155 Операций: 204668309
Для 40-го числа это очень, очень много.
Ого. Книгу я не смотрел, на самом деле. Просто на Ваш комментарий обратил внимание и не подумал, что он к конкретному примеру из книги относится. :)
Вчитался в код… Да, так бы я не додумался написать.
5000 операций сложения — это как раз правильный подход. А в книге — не совсем правильный пример. Вернее, совсем неправильный.
Ответы на вопросы по собеседованию PHP

5. В чем различие между PHP4 и PHP5

Автор не назвал самого главного — _несовместимых_ изменений. По крайней мере одно (и самое главное, ИМХО) я могу назвать — теперь объекты представляют из себя не _значение_, а ссылку на значение, где значением выступает экземпляр объекта. Присваивание $b = $a больше не делает полной копии объекта, а копируется лишь ссылка на него.

7. О типизации данных в PHP

Интересно привести пример, когда эта динамическая типизация вредит:

следите за руками
$a = 0;
$b = null;
$c = «0»;
и вот, что получается:
$a == $b, $a == $c, $a != $b

Вот, что я могу сказать о динамической типизации в пхп :).

8. Сколько типов данных в пхп:

Правильный ответ: хз, но у int (integer) в 32-х и 64-х битных версиях разные диапазоны макс. значений, что играет роль в работе, к примеру, функции filesize, которые возвращают «int» (в самом коде PHP используется long, чтобы хранить «int»).

11. Что такое конструктор (класса)

В PHP4, если метод класса называется также, как и сам класс, то он вызывается перед тем, как new вернет инстанс соответствующего объекта. То же самое работает и в PHP5 из соображений обратной совместимости, но при этом было выбрано более удобное название — __construct, а также введены __destruct, __clone и т.д.

21. Как перевернуть массив без использования array_reverse

Не надо этого делать из соображений эффективности работы. Если очень хочется, то можно вот так:

for($i = count($arr) — 1; $i >= 0; $i--) $new_arr[] = $arr[$i];

Этот код перевернет массив с сохранением строковых ключей, если они были (об этом в вопросе ничего не было сказано, значит предполагаем, что это возможно)

22. Как перевернуть строку:

Однобайтовая кодировка: strrev
Многобайтовая (UTF-8):

$tmp_str = iconv(«UTF-8», «UTF-16», $str);
$new_str="";
$chars = strlen($tmp_str) / 2;
for($i=$chars-1; $i >= 0; $i--) $new_str .= $tmp_str[$i*2].$tmp_str[$i*2+1];
$new_str=iconv(«UTF-16»,«UTF-8»,$new_str);

Только такой вариант будет работать за O(N), вариант с простым mb_substr доя UTF-8 будет давать O(N^2), к сожалению

Написано с телефона
> Только такой вариант будет работать за O(N)

А подскажите сложность iconv() в её текущей реализации?
Должна быть O(N), поскольку он просто проходит строку последовательно
Я не смог найти информацию о производительности iconv(), поэтому решил провести бенчмарк предложенной ниже реализации strrev (в одну строчку):
<?php
$strings = array();
for ($i = 1; $i <= 100; $i++) {
	$strings[] = str_repeat('а', 1000 * $i);
}

foreach ($strings as $str) {
	$start = microtime(true);
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
	echo ((microtime(true) - $start) * 1000) . "\n";
}


График времени от номера итерации вот такой:


По мне так чистый O(N)
Реализация с mb_substr, чтобы не было вопросов:

<?php
$strings = array();
for ($i = 1; $i <= 100; $i++) {
	$strings[] = str_repeat('а', 100 * $i);
}

mb_internal_encoding("UTF-8");
function mb_strrev($str) {
	$len = mb_strlen($str);
	$new_str = '';
	for ($i = $len - 1; $i >= 0; $i--) $new_str .= mb_substr($str, $i, 1);
	return $new_str;
}

foreach ($strings as $str) {
	$start = microtime(true);
	mb_strrev($str);
	echo ((microtime(true) - $start) * 1000) . "\n";
}


Надеюсь, все юзают этот график:
«Надеюсь, все узнают этот график»
Я делал отдельные бенчмарки по производительности оператора ".=" в PHP, можете мне поверить на слово, время работы ".=" в PHP — это O(1), а значит время работы цикла с ".=", в результате которого получается длина строки N, составляет (грубо) O(N). Поэтому проблема именно в mb_substr(), что не должно удивлять, если подумать над тем, как реализовать substr для строки с переменной длиной одного символа, кроме как пройтись по всей строке с самого начала.
И теперь ещё реализация от Joomla (за время, близкое к O(1), но намнооого медленней):

<?php
$str = str_repeat('а', 99) . 'б';

mb_internal_encoding("UTF-8");
function utf8_strrev_joomla($str){
    preg_match_all('/./us', $str, $ar);
    return join('',array_reverse($ar[0]));
}

function utf8_strrev_mb($str) {
	$len = mb_strlen($str);
    $new_str = '';
    for ($i = $len - 1; $i >= 0; $i--) $new_str .= mb_substr($str, $i, 1);
    return $new_str;
}

function utf8_strrev($str) {
	return iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
}

$start = microtime(true);
for ($i = 0; $i <= 10000; $i++) {
	utf8_strrev_joomla($str);
}
echo "Joomla: " . round(microtime(true) - $start, 5) . " sec\n";

$start = microtime(true);
for ($i = 0; $i <= 10000; $i++) {
	utf8_strrev_mb($str);
}
echo "Mb:     " . round(microtime(true) - $start, 5) . " sec\n";

$start = microtime(true);
for ($i = 0; $i <= 10000; $i++) {
	utf8_strrev($str);
}
echo "My:     " . round(microtime(true) - $start, 5) . " sec\n";

$start = microtime(true);
for ($i = 0; $i <= 10000; $i++) {
	strrev($str);
}
echo "Plain:  " . round(microtime(true) - $start, 5) . " sec\n";

$ref = utf8_strrev_joomla($str);

if ($ref != utf8_strrev_mb($str)) echo "Mb is incorrect\n";
if ($ref != utf8_strrev($str)) echo "My is incorrect\n";
if ($ref != strrev($str)) echo "Plain is incorrect\n";


Длина строки 10 символов:
Joomla: 0.06649 sec
Mb:     0.05858 sec
My:     0.02206 sec
Plain:  0.00231 sec
Plain is incorrect


Длина строки 100 символов:
Joomla: 0.5095 sec
Mb:     0.67563 sec
My:     0.04836 sec
Plain:  0.00398 sec
Plain is incorrect


Вывод: используйте мою реализацию для UTF-8, как самую быструю, но если вам не надо UTF-8, то используйте strrev, оно ещё в 10 раз быстрее. Ну и не используйте реализацию через mbstring на больших строках (на 1000 байт разница становится очень ощутимой) — график я привел выше.
Моя исходная реализация (через ".=") обладает сложностью O(1), но работает за такое же время, как и вариант с Joomla (кстати, та же реализация используется почти везде, где я видел в гугле).
Вы не совсем честно оцениваете работу через mbstring. Следующая реализация на mbstring дает примерно такой же результат по времени что и реализация через iconv.
function utf8_strrev_mb2($str) {
    return mb_convert_encoding( strrev( mb_convert_encoding($str, 'UTF-16BE', 'UTF-8') ), 'UTF-8', 'UTF-16LE');
}

А аналогичный вашему варианту mbstring код на iconv у меня выполняется в 10 раз дольше.
function utf8_strrev_iconv2($str) {
    $len = iconv_strlen($str, "UTF-8");
    $new_str = '';
    for ($i = $len - 1; $i >= 0; $i--) $new_str .= iconv_substr($str, $i, 1, "UTF-8");
    return $new_str;
}
Да, имелось ввиду «очевидное» решение в виде mb_substr, я согласен, можно использовать либо только расширение mbstring, либо только iconv в данном случае — это не принципиально.
Сорри, про строковые ключи забыл удалить — в исходном примере был приведен обычный массив
<?
$test = 'Тест';

$end  = strlen($test)-1;
$half = strlen($test)>>1;

$test = iconv('utf-8', 'utf-16le', $test);

for ($i = 0; $i < $half; $i++) {
    list($test[$i], $test[$end-$i]) = array($test[$end-$i], $test[$i]);
}

echo iconv('utf-16be', 'utf-8', $test);
Ну кстати, есл использовать этот трюк, то и strrev подойдет :)
Я понял задачу как «strrev» недоступен.
Вроде как заголовок был «Как перевернуть строку», про strrev я ничего не говорил :)
То есть:
function utf8_strrev($str) {
return iconv("UTF-16LE", "UTF-8", sttrev(iconv("UTF-8", "UTF-16BE", $str)));
}
Тут есть опечатка, если что, правильная функция вот (sttrev -> strrev):
function utf8_strrev($str) {
    return iconv("UTF-16LE", "UTF-8", strrev(iconv("UTF-8", "UTF-16BE", $str)));
}
Хм,

$a = 0;
$b = null;
$c = "0";

echo ($a == $b);
echo ($a == $c);
echo ($a == $b);


Результат: 111
Или я вас неправильно понял?
Прошу прощения, с телефона писал, в последнем примере, конечно же, $b != $c, иначе получается повторение первого условия
По поводу 7:

$a == $b //TRUE if $a is equal to $b after type juggling
Читаем мануал.

Поэтому пример о типизации невалидный.
Я не понял, в чём проблема с примером (кроме того, что я повторяю $a == $c два раза вместо того, чтобы в конце сравнивать $b и $c)?
Ну вот комментарий: >> Интересно привести пример, когда эта динамическая типизация вредит
Далее используется оператор сравнения "==" вместо "==="

В мануале четко скзано: оператор "==" сравнивает значения ПОСЛЕ приведения типа.
Т.е в вашем примере интерпретатор поступает четко по правилам.

Т.е если считать что ето «вредное поведение», то по той же логике можно считать вредным и например такое поведение:

$i = 3;

if ($i > 2 || exit()) {
echo 'hello';
}


// Выведет hello

В чем схожесть этих двух примеров? В том что программист сознательно отстреливает себе ногу, но возмущается тому что ему разрешают это делать.
Я лишь говорю о том, что благодаря слабой динамической типизации в PHP, как и в Perl, нельзя писать, к примеру, следующее для проверки строки на пустоту:
$str = "0";
if ($str) echo 'EMPTY';
else echo 'NOT EMPTY';

if (empty($str)) echo 'EMPTY';
else echo 'NOT EMPTY';


А нужно писать, к примеру, так:
if (strlen($str)) echo 'EMPTY';
else echo 'NOT EMPTY';


Я считаю, что эта тема важна (по крайней мере, я писал СУБД на PHP, и такие «тонкости» были весьма неприятны), и, по-моему, есть и другие примеры, где приведение типов в PHP приводит к тому, что a == b, b == c, но a != c, и не надо мне рассказывать про оператор тройного равенства — он нужен только при сравнении, когда вам заранее известен тип, а в остальных случаях, как мне кажется, его использование вредно, поскольку, к примеру, любой встроенной функции в PHP спокойно можно передать строку вместо числа и она будет нормально сконвертирована в число, а если вы будете внутри функции на PHP проверять числа на тройное равенство, то вы упустите такой момент и ваша функция будет просто работать нестандартно и, скорее всего, просто неправильно.
Прошу прощения, правильный код:
$str = "0";
if (!$str) echo 'EMPTY';
else echo 'NOT EMPTY';

if (empty($str)) echo 'EMPTY';
else echo 'NOT EMPTY';

if (!strlen($str)) echo 'EMPTY';
else echo 'NOT EMPTY';


Очень жаль, что я не могу сразу отредактировать свой комментарий, чтобы поправить ошибки :)
я понял мысль, но c empty() должно работать
Мало ли, что оно там должно, я вам говорю о том, как оно на самом деле работает. В PHP есть много интересных моментов, и если вы с ним работаете 8 лет, то вы их будете находить (как и в любом другом языке, естественно :))

$ cat test.php
<?php
$str = '0';
if (empty($str)) echo "Empty\n";
else echo "Not empty!\n";
$ php test.php
Empty
Я наверно не понял примера :) Но ваш скрипт работает так как я ожидал :D
Ну, строка, в которой записано «0», очевидно, не пустая, а empty() возвращает при этом true, что некорректно. А работает-то оно в любом случае, вопрос только в том, корректен ли результат :))
>> $a == $b, $a == $c, $a != $b

неверно.

$a == $b, а вот $b != $c :)
Я даже кандидатам в джуниоры не задаю вопросов вроде echo vs print и т.п. Предвижу в ближайшее время наплыв выпускников славной академии Шаг и прочих компьютерных колледжей, почитавших сей славный мануал, и желающих $1k+ (Харьков).
Одни задают, другие не задают. В любом случае, вопрос про echo vs print — это вопрос с реального собеседования.
Ни на один вопрос не ответил бы, да и не отвечу, хотя на мне куча проектов на старичке php. Как же так?
даже на «Как перевернуть строку?» :)
Дело в том, что задача переворачивания строки с реальностью не имеет ничего общего.
Половина тех вопросов, которые задают на собеседованиях не имеет ничего общего с реальностью :) Но их же все равно задают…
>Что такое динамические переменные
Как бы все переменные

>Назови и опиши пять любых типов ошибок PHP
Не разбираюсь в типах ошибок php, знаю английский и в состоянии отличить notice от error, да и вообще век exceptions

>В чем различия между четвертой и пятой версиями PHP?
Какая разница? Если я этого не буду знать это как-то навредит мне при решении проблем? Один из глупейших вопросов собеседований. Суть то ведь в том, что какая может быть разница «какой вообще язык использовать для решения задачи» — выбор всегда падает на наиболее доступный и наиболее легкий вариант для решения текущей проблемы, да и таковых проблем может быть несколько, и для каждой свой язык.

>Поддерживает ли РНР множественное наследование?
traits

>Как перевернуть строку/массив/блабла?
Эти вопросы натянуты до нитки, потому что в реале такие проблемы встают редко, и как правило решаются гуглом (как и большинство проблем с незнанием языка), если свой перегретый мозг сделать это не в состоянии

>ряд чисел фибоначчи
С перепугу человек может и не вспомнить что такое ряд чисел фибоначчи

>Как в JavaScript вывести на экран число, которое будет меняться, например,
каждую секунду?
никак, на клиентском javascript-движке интервал может сбиваться и вести себя хаотически

>SELECT * FROM shops WHERE area=”Львов” AND area=”Харьков”
А ничего что результат будет нулевым?)

>.red { background-color:white; }


>Как подключить JQuery к веб-странице?
А что — jquery какая-то особенная javascript-библиотека

>Суть jQuery в том, чтобы отбирать элементы HTML-страниц и выполнять над ними определенные действия.
Да да да

>Выбрать все отмеченные чекбоксы
По идее проверять чекбокс на отмеченность надо так: $(mycheckbox).is(':checked');

>HTML5 знаешь? Нарисуй что-нибудь.
Ага, html5 это язык для рисования

>Как сделать сылку на имейл?
«Сылка», «имейл» — не понимат

>Что такое сериализация?
«Это процесс перевода какой-либо структуры данных в последовательность битов.» Да да да, вы хотя бы читайте то, что копипастите. Я конечно понимаю что русская википедия вроде как «авторитетный» источник, но посмотрите в ту же en.wikipedia.org/wiki/Serialization — тут то ответ дан правильный и развернутый!

>> Какая разница? Если я этого не буду знать это как-то навредит мне при решении проблем?

Разницы совершенно никакой, но книга про вопросы на собеседованиях, а такой вопрос некоторые задают.

>> С перепугу человек может и не вспомнить что такое ряд чисел фибоначчи

не вспомнит — написать на бумаге чтобы понял и повторить вопрос.

>> А что — jquery какая-то особенная javascript-библиотека

не важно, пусть будет хоть MooTools.

>> Да да да

Да да да

>> Ага, html5 это язык для рисования

Для рисования — карандаши.
34. … выведите индексы …
Выводятся значения.
В 34 ошибка
SELECT * FROM price BETWEEN 100000 AND 180000
спс.
15. Не только __call, но и traits.
21. А почему не «foreach ($a as $v) array_unshift($b, $v);»?
22. implode(array_reverse(str_split($a)));
28. Почему только print_r, а не var_dump, json_encode, implode, ver_export? И объяснить, в чём между ними разница.
33. Функция. Почему она должна вывести (echo) а не вернуть (return)?
34. array_walk($arr, function($i){ if ($i%5===0)echo $i.PHP_EOL;});
37. Вообще наглая ложь. Любая переменная (кроме скаляра размера машинного слова) передается по ссылке. Только если при этом не указан амперсанд, при изменении этой переменная будет создан клон в памяти.
39. foreach.
40. $max = 0; array_walk($arr, function($i) use (&$max){ if ($max<$i) $max=$i;});

По остальным главам: не понятно, почему XSS описан в разделе MySQL. Нет вопроса о проверке переменной на существование в JS, про замыкания и области видимости.
Ваше implode(array_reverse(str_split($a))) накрошит в какашку строку с многобайтными символами UTF-8.
Отличное замечание, но:
— strrev тоже накрошит.
— такие задачи чаще возникают при обработке байтовых потоков, а не текстовых строк.
— для разбиения UTF строк лучше использовать другие механизмы, например preg_split("~~u",$a).
Я и не предлагаю использовать голый strrev, мой вариант выше.
>> 33. Функция. Почему она должна вывести (echo) а не вернуть (return)?

А почему вернуть, а не вывести?

>> 34. array_walk($arr, function($i){ if ($i%5===0)echo $i.PHP_EOL;});

Отлично. Добавил. И сразу вопрос: чем echo $i.PHP_EOL лучше echo "$i";?

>> 39. foreach.

Причем foreach, если вопрос о том, как ускорить цикл for?
33. Книга рассчитана на чайников и джуниоров, у них в мозгу полюбому такий подход отложится. Подобные места в чудом коде — это всегда геморрой в сопровождении. Из-за таких горе-функций потом приходятся использовать ob_start и ob_get_clean. Это в частности касается даже стандартной var_dump, для которой почти каждый разработчик пишет обертку, которая дампит в файл. Функция должна возвращать значение, а не печатать его. Напечатать всегда успеем.

34. Странный вопрос. А чем echo $arr[$i]."</br>" (синтаксис автора, правильно естественно <br/>) лучше echo $i.PHP_EOL? Php не завязан на html. Скрипты тестировал в консоли («php -a»), поэтому в примере используется PHP_EOL. А к подходу к обработке массива это не имеет никакого отношения.

39. Написать foreach — это не способ ускорить for? К тому же, count() и итерация $i — настолько незначительны, что тут даже вряд ли что-то заметно ускорится. Это такая же экономия на спичках, как одинарные каывчки вместо двойных. Чтобы убедиться в этом, можно подключить профайлер, например xhprof.

Ну и ещё одно замечание. В книге везде используются английские косые кавычки вместо php-шных. Копипаст такого кода не работает. Это неудобно.

Надеюсь, эти замечания помогут улучшить качество материала в книге.
29. В чём разница между функциями count() и sizeof()?

Ответ не соответствует официальному мануалу и реальному поведению интерпретатора.
>> 18. Что делает функция eval()?
>> eval() вычисляет строку как PHP-код

правильный ответ:
eval() делает зло!
евал делает зло когда текст для евала пришел неизвестно откуда, иначе, если текст провереный и 100% ваш, евал зло не может сделать по определению. Хотя я не могу придумать ни одного момента где он может понадобиться.
eval делает зло хотя бы потому, что его невозможно отдебажить.
если уж код проверенный и на 100% ваш, то почему его не написать как обычный код?
Ну Вы ведь не собираетесь в евал совать тонны строк? А отдебажить можно результат евала. А как его использовать я не знаю, я им никогда не пользовался, всегда находил замену. Хотя видел цмс которые читали файл в переменную и евалили ее =) Совеобразный инклуд.
Помнится мне в фреймворке Kohana до версии 3, eval() использовался для эмуляции возможности перегрузки методов стандартных классов фреймворка. Там это выглядело примерно так (воспринимайте пример как псевдокод):

if (!class_exists('Arrays'))
{
eval('class Arrays extends Kohana_Arrays {}');
}

Но это следствие поддержки PHP 4, в Kohana 3+ такого непотребства нет.
4. Нужно алертом вывести какое-то сообщение, спустя 3 секунды после запус-
ка скрипта. Как это сделать?
Так:
setTimeout(‘alert(“Hello’, 3000);

Очень много опечаток
спасибо. поправлю
Лично из своего опыта собеседований могу сказать, что вопросы могут быть с бухты-барахты, и чаще всего смотрят не только на твои знания а и на то какой ты человек. Если ты понравился начальству(HR манагеру или кто там собеседует) +у тебя еще и норм знания — возьмут.
К примеру, мне давали задания а не вопросы, создать таблицу с юзерами, альбомами, постами, связать их, или логические задачи, задачи на внимательность, один раз пошутили и задали задачу Эйнштейна(там где 5 домов, 5 национальностей и т д), я тоже пошутил — расписал и ответил :D бывает начинают просить написать функцию конекта к БД прямо вот счас, листок, ручку тебе дают, пиши, и спрашиваю все, а что за знак доллара, а зачем, а почему и т д(и их хочется убить нафиг попросить удалится), но все равно, даже если проходишь все тесты на 10000000000% не факт, могут не взять потому что ты к примеру хочешь 1к у.е, а предыдущий готов работать за 950, хоть знаний меньше, и все приплыли.
Странно. До сих пор ни одного крика насчет: «Я PHP программист, что это вы мне javascript и css подсовываете?». Неужто любители «чистого» PHP за пару месяцев поменяли свое мнение. Я был бы в восторге.
Сразу за вашим комментом =)
Добавлю свои 5 копеек. Был по обе стороны баррикад на собеседованиях на должности PHP-разработчиков.

Сначала в целом о вопросе собеседования в подобном ключе. Если такое собеседование будет проводиться для ребят совсем зелёных, которые из своего «портфолио» ничего не могут показать по одной простой причине — потому что его просто нет, то такое собеседования ещё можно было бы рассматривать как один из этапов и/или методов отсева кандидатов. Но для опытных разработчиков такое собеседование само по себе бессмысленно, и, я бы даже сказал, — оскорбительно.

Теперь о книге и описанных в ней вопросах и ответах… Разберём некоторые пункты этого спорного творения (в соответствии с нумерацией вопросов в оригинале).

1. Какая разница между функциями sort(), asort() и ksort()?

Вопрос на зубрение php manual. Нет, ну понятное дело, что понимать, что эти функции вероятнее всего сортируют массивы было бы очень неплохо, но помнить все функции конкретного языка — какой смысл? Есть же справочник, он нужен как раз для того чтобы не держать всё это в голове.

3. Какими способами можно перенаправить страницу в PHP?

Во-первых «перенаправить страницу» это что за сленг такой кривой? Перенаправить можно и нужно запрос, а страница — документ, который PHP в числе прочих вариантов может отдать в ответ на полученный запрос.

А во-вторых — строго говоря в PHP есть только один способ — посылка заголовков перенаправлений. В ответе же приведён почему-то вариант с отправкой строки с JavaScript, который на клиенте должен будет выполнить перезагрузку указанного URL. Какое отношение этот способ имеет к PHP? А если речь о клиенте, который JavaScript не воспроизводит? Почему не приведён вариант с выводом страницы с HTML-перенаправлением мета-тегом, который, если уж на то пошло, более универсален.

6. Что такое тип данных?

Привел школоло? Причём тут вообще PHP? Давайте спросим у кандидатов ещё о том, что такое переменные, чем целые числа отличаются от дробных, сколько будет 2 + 2?

10. Есть ли разница между self и this в php?

Более идиотского ответа на этот вопрос ещё, честно говоря, не встречал.

Правильный ответ:
$this — это ссылка на сам объект, а self — на текущий класс. Вот и вся разница, и именно исходя из неё эти два идентификатора могут применяться.

11. Что такое конструктор?

Что это за шалупонь в ответе?

Ответ должен содержать прежде всего чёткое определение: «Конструктор — это метод класса вызываемый при создании экземпляра класса (объекта)». Ну для чистоты ответа можно ещё добавить «при помощи ключевого слова new» (чтобы отделить от клонирования).

Всё остальное в ответе лишнее, так как про конструкторы можно много чего ещё рассказать, но вопрос был поставлен так чтобы собеседуемый дал определение.

16. Какая разница между require(), require_once(), include() и include_once()?

«require() включает в страницу заданный файл»
Куда, простите, включает? Что это за странная терминология?

17. Какая разница между функциями echo и print в PHP?

Какой практический смысл этого вопроса?

И так далее и тому пободное. Ну это никуда не годится. Этот список вопросов мог бы вполне употреблять на зачёте или экзамене по курсу обучения языку, но на собеседовании мне кажется очень сомнительным практическая ценность многих вопросов, а также формулировки вопросов и ответов. Я на месте кандидата на собеседовании с таким списком вопросов связался бы с руководством компании-нанимателя и поставил бы перед ним вопрос о служебном соответствии лица, которое проводит такое собеседование или внедрило его в практику процедуры найма, так как квалификация этого лица мне кажется довольно сомнительной.
Вопрос о разнице между версиями PHP — это тоже относится к вопросу о знании мануала наизусть.
Да там много вопросов, которые дают ответы на знание каких-то теоретических частностей. Разница между 4 и 5 версией PHP в принципе вопрос конечно ёмкий и важный, но если человеку не предстоит уже писать на 4 версии (а вероятность этого стремится к 100 %), зачем ему знать отличия досконально? С тем же успехом можно спрашивать чем 4 отличается от 3 — может только ради проверки интереса к изучению истории.
А вот не соглашусь. Любой проект, который начинался N лет назад, будет вынужден столкнуться с тем, что там есть старый код, под старые версии PHP, и надо понимать, как это работает, и почему, и как это переписать с учётом новых возможностей. Если вы разрабатываете решения «под ключ», то тут тем более важно знание того, в каких версиях PHP что появилось (и что не сломали в более новых версиях), чтобы у клиентов всё работало. Так что, хоть вы и гордо называете себя «вебмастером», вы явно не профессиональный PHP-программист.
… где N больше 3. Сейчас уже 4 версия практически нигде не используется.
Таких проектов много, тот же Хабр или Badoo
Не буду спорить, но я считаю, что про 4 надо уже забыть как про ископаемое.
Согласен, надо забыть, если не нужно поддерживать/переписывать старый код. Если нужно, то эти знания пригодятся.
По собственному опыту: переход с 4 на 5 надо просто сделать один раз волевым решением, а не бесконечно поддерживать эту рухлядь. В реальности оказывается, что необходимо переписать лишь до 10 % кода, но кода влияющего на многие архитектурные решения, однако в дальнейшем этот шаг отразится на проекте только положительным образом.

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

Если специалист проводящий собеседование считает необходимым спросить у конкретного кандидата о понимании различий между 4 и 5 версией PHP, то может ли вообще в этом случае идти речь о найме этого человека на должность разработчика, которому предстоит переписывать архитектуру проекта? По-моему это какая-то абстрактная ситуация, которая при воплощении в жизни говорит, что «что-то не так в королевстве датском».
Знание отличий между PHP4 и PHP5 может просто говорить о том, что человек не первый день пишет на PHP, и даже просто этого, как мне кажется, должно быть достаточно, чтобы можно было задавать такой вопрос, если требуется большой опыт работы от человека.
Так себе и представляю это. =)

— У вас большой опыт работы с PHP?
— Да, очень!
— Ок.


Ну не смешно ли? Если у человека есть большой опыт, то его можно проверить гораздо более эффективными методами, чем такими… «не мягкими» вопросами. А вот как раз блестящие ответы на вопросы о различиях 4 и 5 версии PHP совсем не гарантируют, что человек может хорошо писать код, элегантно решать реальные задачи и попросту не рожать горы говнокода.
Не, ну это же не означает, что нужно задавать только один вопрос :). Просто если человек действительно с этим сталкивался, то вы скорее всего это поймете. И если он сталкивался, значит он с PHP работает очень давно
Так я о том и говорю, что смысл подобного диалога отсутствует.

Если нужен новичок «на вырост», то вероятно серьёзными задачами его мучить не предстоит в ближайшее время, соответственно нет нужды его терзать синтетическими вопросами.

Если же нужен «тяжеловес» на передовую — ну так его распознать будет гораздо проще «по мандату и регалиям», то есть каким-то реальным его работам и результатам, а вот вопросами вроде разницы между версиями PHP мало того что ничего путнего не узнать, так ещё и можно человека просто отпугнуть, а то и просто оскорбить.
Омг, люди, 165 в избранном, вы же себе хуже делаете.
Наверное многие добавили в избранное чтобы комментарии почитать :)
уже 393
446
2. Как в JavaScript вывести на экран число, которое будет меняться, например, каждую секунду?
hey = 1;
function foo() {
document.write(hey);
hey++;
}setInterval(“foo()”, 1000);

Закрыл и дальше не читал.
9. Существует ли универсальная защита от SQL-инъекций?
Один из ответов: stripslashes()
Это книга вредных советов?

Вообще (за редким исключением) это не те вопросы, которые я спрашиваю на собеседованиях.
А какие спрашиваете?
Сделай то, то и то. Например, реализуй паттерн, сделай полупрозрачность при наведении, исправь уязвимость. 20 минут, интернетом пользоваться можно.
Это умные интервьюеры такое спрашивают :) Но ведь часто попадаются и другие, которые спрашивают всякую фигню, на которую хочешь — не хочешь, а приходится отвечать :)
Если спрашивают всякую фигню — надо задуматься о том, а работа, которая стоит за этим собеседованием не будет ли тоже всякой фигнёй, да ещё и с начальством, которое не парит ни в технических ни в организационных вопросах.
Неправильно написал, следует читать:
«… о том, а какова будет работа, которая стоит за этим собеседованием? Не будет ли она...»
у меня когда-то давно было похожее собеседование. одним из заданий была реализация навигации по файловой системе с использованием рекурсии. времени тоже было 20 минут, интернетом тоже пользоваться можно было :)
причем собеседователь даже уточнил — если ты полностью стащишь готовое решение в интернете — тоже хорошо, ибо если человек вместо написания велосипеда может найти готовое решение — в этом нет ничего плохого. потом, правда, зада пару вопросов по моей писанине, чтоб понять-таки что я понимаю кроме поиска решений в интернетах, но это уже лирика :)
Я сторонник такого подхода: вообще спрашивать ничего подобного не надо. Надо дать человеку какую-то небольшую реальную задачу из области реальной предстоящей практики, посмотреть как он её решит и уже по исходнику можно проводить какой-то разбор полётов.

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

А вот этот «экзамен» не нужен никому из сторон.
Ну, например, вот такой:
$a=0;
if($a=$b)
    echo "ку!";
else
    echo "кю!";
кю!
Именно :)
А вот некоторые, зашоренные всякими фреймворками, моделями, шаблонизаторами и т.п., на таких элементарных вещах сбиваются.
хороший вопрос. включу в исправленную версию :)
Поясните, пожалуйста, почему кю?
Ведь присваивание возвращает присвоенное значение, в данном случае $b. Но не известно чему оно равно. Если оно не определено, то это ошибка; если null или любое другое значение, приводящееся к false, то кю.
А оно предупреждает что $ не определено и выводит кю

Notice: Undefined variable: b in D:\XAMPP\htdocs\a.php on line 4
кю
Хм. Всего лишь Notice…
$b
Прошу прощения, a и b перепутал местами.
Да, написанный пример решения не имеет.
Очень даже имеет, по умолчанию переменные имеют значение null, поэтому ответ всё равно такой же.
Вопрос об этом не дает мне покоя на одеске %) Я тоже считаю что там null, но мануал говорит «Uninitialized variables have a default value of their type depending on the context in which they are used — booleans default to FALSE, integers and floats default to zero, strings (e.g. used in echo) are set as an empty string and arrays become to an empty array.».
Вот это меня, как постепенно изучающего рельсы (и REST) поразило:
>6. А какие еще есть методы кроме GET и POST и для чего они используются?
>GET и POST – это основные методы передачи данных. Есть еще PUT и DELETE, но ими никто не пользуется.

Вроде как наоборот — их нет, но все хотят ими пользоваться. И пишут костыли — обёртки.
Да я в курсе, что они есть в HTTP. Проблема в том, что
<form method="PUT">

написать нельзя никак.
ajax не катит?
Что-то типа:

$.ajax({
type: 'PUT',
url: '/test/test1.html',
data: 'ffddf=fdfd',
success: function(data) {
$('.result').html(data);
alert('Load was performed.');
}
});

Вполне катит.
Только http method определяет не метод передачи данных, а указывает действие над ресурсом. поэтому, что вопросы, что ответы по данной теме в книжке — полная бессмыслица. :)
Насколько я помню, различие между include и require в том, что require подключает файлы на начале этапа выполнения, а include во время интерпретации. Очень удивило написанное в «книге». Поправьте меня, если я не прав.

А вообще, в целом впечатление — такая книга хороша как мануал «для чайников», но раздел о ООП надо ставить первым.

И не дай бог такой книжкой будут пользоваться работодатели при проведении собеседования
Вы не правы.
Некогда, в стародавние времена, было так, как написали вы.
Сейчас обе функции идентичны, кроме уровня ошибки.
ru2.php.net/manual/ru/function.include.php
Документация ниже также относится к выражению require().
Конструкция include() выдаст warning, если не сможет найти файл; поведение отлично от require(), который выдаст фатальную ошибку.
Спасибо, давно это было, хоть переучивайся))
в 34-м ошибка

вместо
echo $arr[$i].””;

надо
echo $i.””;
спс
исправлю
Что-то я решил взяться и самому написать такое, в другом формате учитывая, что опыт собеседования со стороны работодателя у меня всё-таки есть. И это не будет шпаргалкой на тему «как пройти собеседование».
я бы наверное спросил «Почему вы выбрали похапе?»
И какой правильный ответ, по-вашему?
«Не смог осилить питон и руби»
— Почему Вы стали программистом?
— Не смог осилить %другая_профессия%.

Да?
и шо дальше?
Скажу честно, не осилил Perl. Вернее, после сравнения двух гостевых мне показалось, что после С/++ мне легче будет осилить PHP. Про Python и Ruby в 1999-м и не слышал. Про Ruby уж точно.
Ребята, холивар детектед.
Отправляйтесь к первым комментариям, в них есть хоть какой-то смысл.
Спасибо за статью и за книгу. Мне как студенту который только начинает познавать языки программирования легко прочитать такой простой материал и даже узнать много нового.
Хорошая книга, 3 нужных и полезных вещи для себя почепнул.
Какие?
где ответ на вопрос «сколько теннисных мячиков поместится в этой комнате?»

Есть ещё интересны вопрос по mySql. Есть таблица с полем
id: 9, null, 3
Что вернут avg(id), sum(id), count(id), count(*)
напишите правильный ответ про мячики — включу в книгу :)
Да, вопрос про агрегатные функции в SQL очень актуален.
По наблюдениям, %90 из тех, кто на собеседовании заявляет что знает SQL, можно отсеять вопросами про группировки, агрегатные функции, ну having туда же.
А что заявлять если простые SELECT/INSERT/UPADTE/DELETE знаешь «наизусть», а когда требуются группировки и т. д., лезешь в ман?
так и говорить
GET и POST – это основные методы передачи данных. Есть еще PUT и DELETE, но ими никто не пользуется.
GET и POST – это основные методы передачи данных. Есть еще PUT и DELETE, но ими никто не пользуется.

Нда… А следующий вопрос мог быть как раз про SOAP.
тьфу. Сверху должен быть вопрос:
16. А какие еще есть методы кроме GET и POST и для чего они используются?
Пойду спать. REST.
иди
завтра же покажу коллегам два важных момента — это echo vs print и вопрос про цикл for.
нужно задавать их кандидатам, если отвечают на эти вопросы, сразу «всё, спасибо, мы вам позвним».
в первом вопросе пункт 2) «ассоциированный массив» начинает резать слух, кто-нибудь вообще слышал, чтобы употребляли такое словосочетание?
Угу, «ассоциативный».
Вышла обновленная версия книги по PHP. Как всегда, бесплатно качаем ТУТ
хороший список различий
Сначала хотелось много написать по поводу текста… Но потом подумал. И, если Вам такой труд поможет развиться, то работайте над ним. Никто Вас не сможет остановить.

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

Публикации