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

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

я как обычно предлагал метод оценки по производной появления запросов%)
а вообще есть есть фнти-ддос софт, товарищи хабряне?
snort
О ХЕК, как только программер входящий
вдруг пальцем у виска покрутит,
и с словом "Циско юзать не пытались?",
скажет, что для себя не видит здесь работы...

Короче по башке молотом, потом к компу приковать пожизненно, и подобные топики появляться перестанут.
Ибо это настоящий КЛАД ^_^
А твоя производная - для наивных школьников ^_^
> Отказ от регулярных выражений даёт существенный прирост в производительности.

Блин, не хотел ничего писать, но это просто убило. Это как раз «для детей, которые знают PHP» ^_^
+1. XML-парсеры тоже сами пишете :))
Чего сложного-то? Обычная работа с файлами + парсинг, а размер файла не имеет значения, хоть 1 мег, хоть 100
А почему должно быть сложно? У каждого работадателя свои требования
работодателя )
Ощутимая часть кандидатов писала код, который работал с данным файлом вместо 40 секунд 10 минут и более
php красивше, потому что сишный синтаксис - наше всё!!!
от же ж, 10% говоришь :) видимо я со своими вопросами про всякий шардинг еще года три никого не найду :/

ps. мы с тобой и Фишером на веборубе вечерком в боулинге беседовали, было приятно познакомиться =)
Привет :-)

Я помню по имени только фишера и фиксера, остальных только в лицо :-)
ну фиксер это я и есть, тут то ли ник занят был то ли просто заюзал свой "альтернативный" =)
Привет!

Мне тоже было приятно познамиться
> что он опытный разработчик и «собаку съел» в области web-программирования.

Это показывает лишь то, что он опытный _всего_лишь_кодер_ (умеющий хотя бы минимально мыслить логически, или, что самое страшное, изначально заточенный под эту задачу). То, что он "«собаку съел» в области web-программирования" - ничего не говорит.

Для решения этой задачи достаточно опыта практической разработки (в основном работа со строками) на любом ЯП.

Создается впечатление, что программисты ТМ пытаются победить hi-load грубой силой - типа "мы не будем применять PCRE, а распарсим все термоядерными строковыми функциями":). Конечно, это здорово, но, кроме этого, есть кеширование, и его вклад в производительность трудно переоценить.

Сложность идеального кеширования, обеспечивающего максимум эффективности, стремится к бесконечности. Это - тонна событий, влияющих на ререндеринг малых и больших, а также вложенных (причем часто рекурсивно) частей кеша. Для того, чтобы программисты не потерялись в борьбе с этой сложностью по мере разрастания проекта, нужна понятная, логичная, гибкая МОДЕЛЬ. Если конечно он раз и навсегда не рисуется в UML`е. Но думаю, что попаду пальцем в небо, сказав, что в данном случае нифига никто ничего в UML`е не рисует :)

В общем, хочу выразить мое давно укоренившееся мнение: комфортное выживание и существование в hi-load`е опирается в первую очередь на грамотную МОДЕЛЬ. А модель опирается на людей, которые могут ее создать или полностью в нее врубиться.

Если кодер может быстро парсить строки, и минимально думать башкой в рамках одного-двух массивов - это еще не значит, что он может грамотно врубаться в целостное сложное web-приложение. (Хотя с другой стороны, "фундаментальныйъ программистъ" может иногда жоско тормозить:)

Должен конечно, сказать, что во-первых, никаких тем я здесь не спалил. Во-вторых, все изложенное выше - IMHO ;)

Но подход к тестированию спецов в ТМ мне нифига непонятен, хотя чувствуется, что истина где-то рядом... Эх, может быть juks хотя бы минимально спалит тему, очень интересно...

PS: кто помнит пост Алексея Рыбака про задачи на собеседовании для PHP-программера (где про трех программистов и горы) - запостите плиз ссылку... что-то не могу найти этот шедевр...
Согласен с Вами
Описанное задание имеет отношение скорее всего к администрированию apache (nginx) + iptables, нежели к вебпрограммированию. А php здесь всего лишь средство реализации.
90% людей, говорили, что знают что такое ddos web-сервера как свои пять пальцев и ухмыляясь просили им даже про это не рассказывать.
мне кажется, что 90% людей на собеседовании, да и вообще в жизни не умеют говорить: "Я этого не знаю."
ps кстати я бы решал задачу при помощи connlimit и recent, без парсинга логов. Думаю, что аналог connlimit и recent должен быть и в freebsd.
Тут надо ещё понимать, что мы ищем людей, которые нам действительно нужны, с которыми мы сработаемся.

Один человек решал задачу ну предельно долго, не терял при этом самообладания, не впадал в параною, не огрызался, оставался человеком. Я ему сделал несколько подсказок, видно было что он соображает, просто не может собраться.

В итоге оказался как раз из тех, кто нужен.

Это текст ++не про программирование++ и не про решение конкретной задачи на php, а про поиск людей. Почему никто не читает, о чём речь?
я прекрасно понял, что текст ++не про программирование++. Мое видение конкретной задачи было добавлено исключительно к слову. В первую я хотел посетовать, что люди часто боятся признаться, что чего-то не знают, тем самым вводят работодателя в заблуждение, а сами попадают в неловкие ситуации.
Сказать больше: некоторые откровенно пускают пыль в глаза
так никогда не говорить "я это не знаю" учат все современные книжки по психологии, бизнесу или т.п. Вот люди и бояться... Хотя лично у меня больше уважения к человеку, кто честно скажет все. Хотя... при первом знакомстве фраза "я этого не знаю" может действительно запомниться и привести к неправильному мнению о человеке. Ох трудно все, трудно в этом мире :)
Не стоит так низводить книжки по психологии. =)
По большей части там наоборот раскрываются механизмы почему люди боятся казаться не идеальными. И это большая тема для многих диссертаций от "маски, которые мы носим" до "причины сценического волнения".
Если текст не про программирование и не про решение конкретной задачи на php, то "решение, которое сам написал", здесь не уместно.
Совершенно верно. Задача достаточно проста.
Но люди при этом умудрялись делать следующие вещи:
1) $f = file($fname) - очень круто для 80Mb-файла
2) Делать невъ*ый массив частоты запросов, а потом сортировать его
3) Создавать сложную иерархию классов в нескольких файлах

Конечно, съел человек собаку или нет таким тестированием выявить нельзя. Для этого есть испытательный срок. Но отсеять 90% уж совсем неадекватных людей можно, вполне.
На всем съесть собаку не возможно. Это всего лишь частная задача. Потом готовиться к атакам нужно заранее. А тут уже нужен человек, который будет не лениться и попробует поиграться со временем выполнения скрипта и его оптимизнуть (т.е. тут важнее ответственность у человека, чем знание какая команда выполняется быстрее).
Потом есть такой тип людей, которые могут часами сидеть оптимизировать задачу, но к цели не придвинуться. Т.е. люди, которые не результат делают, а придумают себе внутренний мир и в нем роются. Это тип людей такую задачу могут "щелкнуть" как орешек, но работать в команде они не смогут. Потом окажется, что они и спроектировать архитектуру простую не смогут нормально и в чужом коде разобраться, и т.д.
В общем, считаю, что собеседование проводить по одной задаче это не есть гуд.
Либо давать эту задачу наряду с другими и смотреть, как человек в общем мыслит, либо ее вообще не давать:)
Это одна из, до неё доходило только после личной беседы и просмотра резюме.
про четырех =)
raa.livejournal.com/68519.html
Спасибо.
>>> Однажды года четыре был на собеседовании в одной крупной конторе, ребята программили на перле-пхп, просто делали какие-то веб-проекты, никакой там не рокет сайнз. Начали спрашивать про алгоритмы - я честно говорю хуй чего помню надо будет погуглю или возьму Кнута. Один грит (огонь в глазах!): дык Кнут у нас - вообще настольная книга! В общем, я приложил очень много усилий, чтобы не ответить: ну и мудак.

Блин, эту статью надо наизусть выучить ^_^
fh = fopen($fname, 'r');

говорите, код работал? опечаточко)
да, спасибо
Хех, а я бы на шеле реализовывал. Что-то типа:
$ tail -n N access_log | awk {'print $1'} | sort | uniq -c | grep -v 'google_ip' | sort -nr | head -n M
Получаем список самых частых ИП адресов. Играяссь числами N и M можно брать N последних запросов к серверу и получить M самых ярых пользователей. Почти гарантировано наяривать будут в основном ддосеры, причем их количество запросом будет отличаться на порядок от количества запросов нормальных людей (количество будет выведено первым).
удобно, но задачу-то надо реализовать на php...все равно я б регулярными пользовался, а то строки типа
"$st = strpos($string, '[') + 1;" читать трудно
регулярными раза в полтора-два себя на время накажете
К счастью не доводилось сталкиваться с ддосом, но мне кажется вы не там ужимаете время.
Я бы потратил пол часа на анализ самого лога. Мне кажется, что ддос программы не особо умны, они либо будут открывать одну и ту же страницу много раз, либо открывать только определенные файлы, например вызывать html/php файлы, но не спрашивать картинки. Спрашивать картинки, но не брать их из кеша (не будет ответов 301/302 на эти IP адреса). В любом случае, можно при помощи нескольких грепов получить в разы меньший входящий список, обработка которого займет намного меньше времени.

Кстати, было бы интересно сравнить скорость и результативность работы варианта на PHP, варианта на руби и варианта на шеле.
Я не знаю, как на PHP, но на perl регулярные выражения обычно работают быстрее всего. Другое дело, что одну и ту же задачу можно решить как невероятно медленным регулярным выражением, так и очень быстрым (а чтобы научиться писать эффективные регулярные выражения лучше всего почитать Фридла). Причём это доходит до маразма - я когда-то писал оптимизированный парсер ответов DNS-сервера (был нужен для задачи типа "очень быстро отресолвить веcь .com/.net/.org", да и просто по приколу было), так самый эффективный вариант выглядит так:

# Обработчик ответов от DNS-сервера:
{ my $d = qr/[^\x00\xc0-\xff]*(?:\x00|[\xc0-\xff].)/xms;
sub IO {
  my ($self, $io) = @_;
  die "Oops. DNS resolver just died: $io->{err}" if $io->{events} & $ERR;
  my ($id,$flags,undef,$an) = unpack 'nnnn', my $pkt = delete $io->{in_buf};
  # Молча игнорируем "неправильные" пакеты - с неизвестным ID (вероятно,
  # дубликаты уже принятого ответа посланные в ответ на наши перепосылки
  # запроса по $TO_DNS_RESEND) и с известным ID но несовпадающим host
  # (либо глюк DNS-сервера, либо ID-шка слишком быстро "перекрутилась").
  return if !$DNS[$id];
  return if $pkt !~ s/^.....\x01......\Q$DNS[$id]{_host}\E.\x01..//xms;
  my $query = $DNS[$id];
  # Если кому-то ещё нужен результат... :)
  if (defined $query->{cb}) {
    # Обработать ошибки ресолвинга.
    if ($flags &= 0x0f) {
      run_callback(@{ $query }{'cb','method','host'}, undef,
        dualvar(-1, 'dns error: '.($flags==3 ? 'NXDOMAIN' : 'SRVERROR'))
      );
    }
    elsif (!(  ($pkt =~ s/^[^\x00\xC0-\xFF]*(?:\x00|[\xC0-\xFF].).\x01........//s) ||
          (($an > ($pkt =~ s/\G$d.(?:[\x02\x05\x0C].{8}$d|\x06.{8}$d$d.{20}|\x0F.{8}..$d)//sog)) &&
          ($pkt =~ s/^$d.\x01.{8}//so)) )) {
      run_callback(@{ $query }{'cb','method','host'}, undef,
        dualvar(-1, 'dns error: NODATA')
      );
    }
    # IP подкрался незаметно...
    else {
      run_callback(@{ $query }{'cb','method','host'},
        sprintf('%d.%d.%d.%d', unpack 'CCCC', $pkt)
      );
    }
  }
  $DNS[$id] = undef;
  return;
}}

Безусловно, к "хорошему стилю" и "читаемому коду" упаковка деталей протокола DNS внутрь регулярного выражения отношения не имеет никакого, но... работает очень шустро, и в процессе его разработки было "a lot of fun"! :)
аплодирую стоя
Думаю язык надо выбирать под задачу.
Из PHP вызывать ipfw как-то не хорошо: должен быть разрешен system, выключен safe mode и у запускающего юзера должны быть права рута.
Странно, почему люди не привыкли читать текст. Этот код написан в момент острой необходимости. В качестве задачи это требовало только проявления логики.
В одном случае вы пишите про острую необходимость, в другом - про использование данной задачи в качестве тестовой на собеседовании.
Если бы мне предложили такую задачу на собеседовании, я подумал бы о компании плохо.
Я сказал, что до того, как действительно понадобилось, я сам не реализовывал решение. В учебных целях system не нужен, конечно.

Не все верят, что это можно решить в 30 строк, поэтому приложил пример.

Так что причём здесь system? Причём здесь safe mode? Причём здесь root?
При том, что это не задача PHP работать с логами. Есть более предназначеные для них языки, в часности - одна строка шелом, которую я не поленился и привел.
За это у меня теперь отрицательная карма, хороший у вас способ убеждать.
Это не я
Ваш подход понравился. Добавил кармы. =)
Спасибо всем кто добавил кармы!
Поражает количество гумна от людей, которые сами наши тестовые задания слили :-)
Коллеги, в посте не обсуждение способов борьбы с ddos. Собеседуя сисадмина никто и не предложит ему писать код на php! Смотрите на задачу в отрыве от проблематики. Это же тестовое задание. Оно нужно для того, чтобы быстро и с минимальными затратами определить уровень соискателя. Не зацикливайтесь на словах про ddos :)
Возможно ламерский вопрос: кэш от ddos не спасает?
В общем - нет. Вот, последний раз хабр ддосили запросами простейшего txt файла.
верно.
а то все начали пиписьками сразу меряться :)
stpos, substr фуууу моветон :) preg_match и preg_replace решают ...
Они медленнее :)
Отдельный strpos и substr конечно быстрее чем отдельный preg_match, только вот preg_match-ем можно распарсить строку в крошки за один вызов, тогда как substr-ов на такую строку может потребовать десяток. Конечно довольно глупо использовать perl регулярные выражения тупо для проверки "а нет ли в строке a подстроки b" или для вырезания подстроки с точно известной позицией. Но в случае мало мальски сложного разбора использование их - ламеризм. Имхо.
Минусят я так понял те, кто Perl-совместимые регуляры плохо знает? :)
Кто читает, о чём речь.
Занимательно, если при этом web-программисту самому деается возможность разбираться что считать ДОС атакой и как блокировать соединения.
А если это ему сообщается, то задача очень простая.
Более того, задача вовсе не web-программирования, а как раз административного серверного программирования. Обычная алгоритмическая задачка.
Не стоит проецировать всё на себя.

По этим кроется и понимание того, с чем сталкивается любой человек, серьёзно погружавшийся в разработку интернет-проектов или просто обладающий способностью мыслить. К сожалению, мы не mail.ru, мы не можем взять и дешевого студента и профессионала, дать каждому соответствующую работу, у нас элементарно недостаточно для этого рабочей площади.

Кому нужен такой кадр, которому дела нет до рациональности, которые весь мусор хранит в кеше и считает это нормальным решением? Или что это за подход при котором человек не знает, как устроена проблематика немного за пределами его непосредственной компетенции?
По большому счету, не нужно лезть в написание PHP/Perl скриптов - достаточно примитивного скрипта на шелле, который делает netstat, забирает список айпишников, от которых поднято >2(3) соединений, и добавляет их в файлик blockips (included в конфиг pf) с последующим pfctl -f /etc/pf.conf
работает на ура при ДДоС ~80МБит/с (с большими не сталкивался).
простите, что немного сумбурно: если писать подробнее, получается много букв :)
p.s. все вышесказанное есть мое личное мнение и мое личное решение, которое успешно используется мной на shared-серверах.
p.s.s. размер лога апача в 80МБайт - извините, циферка маловата. реально суточный лог весит на порядок больше. а если из-за оверлоада logrotate не сможет отработать...
А какое самое главное условие? Быстрее забанить DDоSеров или быстрее пропарсить файл? Мне кажется, что тут связь совсем неочевидная.
Главное сделать хоть что-то работающее! Как писал juks даже это получается далеко не у всех.
В таком случае, усолвие задачи вообще не важно:) Можно говорить об абстрактных вещах (например, умение думать как программист). Ни о какой web-разработке речи, как я понимаю, не идёт. В общем, тему, на мой взгляд, можно закрывать:)
А вот где бы взять большой лог файл для тестирования производительности?
Сгенерировать его самостоятельно при помощи php
Приведённый вами код забанит всех сколько-нибудь активных пользователей на моём сайте. И так, думаю, будет со многими веб2.0 сайтами. Вы не сбрасываете счётчик $status[$ip]['count']. А скрипт устроен так, что каждый раз, когда пользователь сделал два запроса с маленькой паузой, счётчик увеличивается. В вашем скрипте предел равен пяти, что достигается очень быстро. А на сайте, где при загрузке страницы сразу идёт обращение по ajax к серверу для подгрузки данных, реальные пользователи будут попадать под эту мясорубку без разбору. Особо "повезёт" тем, у кого шустрый канал.

А по существу: плохо по такой специфической задаче делать выводы о кандидате. В общем, всё уже и так объяснили выше.
Почитайте, что написано в условии, это, вроде не сложно
Прочитал. Подумал. Не понял. Видимо, я бы вам не подошёл, жаль.
Был бы благодарен, если бы вы указали мне на мою ошибку.
Мне кажется, проблема в том, что вы не можете абстрагироваться от каких-то проектов, веб-два-нолей, аяксов. В задаче точно сформулированы условия. Помните школьный учебник физики, где были задачи типа: "Два бруска соеденины через блок веревочкой. Один находится на горизонтальной поверхности, а второй на наклонной, под углом 23 градуса"? У вас же не возникает вопросов зачем так соединили брусочки, почему так, а не иначе, какой подшипник используется в блоке. Вы просто забываете обо всем этом и решаете точно то, что вас просят. Тут точно так же нужно поступить.
А вот свою эрудицию и свой взгляд на глупость задачи можно высказывать после того, как все у вас заработало в пределах поставленной задачи.
Ну я же не написал, что задача глупая. Просто меня немного смущает, что решение задачи явно опирается на какие-то особенности конкретного сайта, о которых не говорится. Вот и вы про то же - мол задача поставлена предельно ясно. Извините, я так не считаю.
Почему конкретного? :-)

Этот скрипт удалось удачно испытать при атаке на лепрозорий, статистика тогда собиралась правда долго: примерно за 7 часов собралось 1500 адресов, потому что их было реально много и постоянно подключались новые.
Разве я задал эти параметры в виде константы? Их не трудно поменять. Гугол и Яндекс заблокируются с вероятностью 70% если не исключить их адреса, но это не страшно в данном случае.

Вообще мы не склонны делать резкие выводы подошёл/не подошёл.

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

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

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

На самом деле, это решение нетрудно доработать в сторону отдельных баллов за разные события. Просто как оно есть в моём исполнении - оно близко к исполнению в рамках собеседования: некоторый стресс и нехватка времени.
Ну это уже скорее оценка личностных качеств человека - один честно скажет, что задача ему не интересна. Другой промолчит и напишет фигню. В любом случае конечно, ваше право выбирать для найма тех людей, с которыми потом можно будет адекватно общаться и работать.
Если важна скорость, подобные задачи решаются средствами Си. Алгоритм тут простой и Сишник справится с ним гораздо быстрее.
А вообще подобную задачку дают в mail.ru на собеседовании.
Лично я считаю что «качество php» у человека, который претендует на звание web разработчика гораздо менее приоритетнее, чем «качество sql».
Исторически сложилось, что юзаю MySQL и она меня полностью устраивает, лично я в свою контору без замедлений беру людей, которые могут оптимизировать запрос:
«SELECT id, name FROM users ORDER BY RAND() LIMIT 10»
Делающий выборку 10 случайных пользователей по базе, скажем, в 1 000 000 записей.
UPDATE users SET Rand=rand() WHERE 1
SELECT id, name FROM users ORDER BY RAND() LIMIT rand(),10
образно. Тут главное выдавать перемешаных пользователей, а не уникальность перемешания. На каком этапе и кто перемешивает.. лично мне по барабану.
Это частный случай с существующим полем ’rand’ (кстати во втором запросе ошибка, как понимаю, ORDER BY rand). Можно обойтись и без перестройки индексов (а как следвствие — и локов при большой нагрузке на некоторых хранилищах). Да и прийдется знать общий объем базы, чтобы LIMIT rand(), 10 не привысил число строк. Т.е. перейдя от «образного» вида к реалиям, способ окажется не самым эффективным.
Перестройку индексов можно делать и раз в неделю.
а LIMIT rand() это образно я сказал.
А вообще рандом ассес очень тормозит.
лучше написать
SELECT id, name FROM users WHERE Rand>somerand ORDER BY rand LIMIT 0,10
Желаемый рандом даст, а работать будет в разы быстрее
Можно без доп. полей. Правда, с подзапросами, но тем не менее запрос будет выполняться без using filesort и прочих тормозов.
Хотя, это уже совсем другая история.
Оптимизации SQL приходится учить самому. При нормальной задаче на этом сливается 99% людей, по умолчанию большинство просто ставят индексы на полях, где, как им кажется, они должны быть.

Вас взяли в mail.ru? Я там почти полтора года отработал
Неа, сказали что перловый прогер из меня некудышный и что могу расчитывать на должность верстальщика. И то и другое для меня было не новостью, но на верстальщика я не пошел.
Там всё сильно зависело от того, кто собеседование проводит и сколько соикатель просит денег. Там очень любят дешёвых кадров. Это место оптимальное для того, чтобы поработать годик, набраться опыта и пойти в нормальную компанию.
Денег просил не то чтобы много, но больше чем предлагали, хотя за меньшее жить и комфортно работать в Москве врядли получилось бы.
Приятно, собеседование проводили сами Андрей Баранов и… мля… вылетело из головы =) короче тоже известный и крутой дядька =)
Ваня, наверное :-)

Эти да, те ещё опускальщики. Календарь небось попросили на mysql вывести или лог прочитать?
Календарь просили =) Опускать опускали, но я тоже не промах =)
Интересный вопрос был про поиск минимального смещения в sql одним запросом, так и не решил, а потом и вовсе забил =) Но вообще мне понравилось. По крайней мере лучше, чем в нафанькеных конторах. Там вообще ересь всякую спрашивали.
Да, если здесь опубликовать задачу про календарь, то местные боты вообще с грязью смешают.

Ну какой от неё практический смысл? Почему программист должен строить календарь, да ещё и средствами mysql, когда они, эти календари, в ларьках союзпечати продаются?

Проблема Вани и Андрея в том, что эта задача про календарь не соотвествует уровню проектов самой компании.
Что правда то правда, ни одного практического применения тем задачкам (как, впрочем, любым другим в любых других конторах за частным исключением) нет. Но тем не менее задачи интересные =) т.е. всем, конечно, ясно, что машину проще и быстрее собрать другой машиной. Но Роллс-Ройс так не считает =)
И с уровнем mail.ru тоже, конечно, согласен. Но насколько я понял, пока был там, они малое решают. Они лишь исполняют. Могу ошибаться.
Нет, я имел в виду, что шучу, в ответ тому, что говорят здесь про мою. Задача нормальная.

Основная проблема mail.ru - унылая серая повседневность. Делать то, что "схавают" при любом раскладе.
На знание sql была вторая задача
Покажите =) очень интересно
Задачи на sql пока не рассекречены :-)
juks, а скинь в личку, обещаю никому не показывать =) спортивный интерес.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Интересно, а если бы Хабр не DDOS-или, а, скажем, заразили бы вирусом, который в каждый пост и каждый коммент в базе вставил бы код рекламного баннера, вы бы на собеседовании кандидатам предлагали решать задачи, как пробежаться по всей базе и вычистить вредоносный код, чтобы при этом не положить сервер?

Те задачи, которые задаются на собеседовании (то есть, еще не факт, что их вообще нужно задавать) должны быть максимально универсальными, и служат только для того, чтобы выяснить сильные и слабые стороны кандидата. В данном же случае, проверяется только умение кандидата работать с файлами и строками. И, скорее всего, 90% говорили, что-то типа "Я не знаю, как читать журнал потоково", и вы их на этом разворачивали...

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

Не сочтите за выкобенивание или какое-то нытье, просто рассуждаю вслух. Лично меня бы такое тестовое задание ввело бы в ступор своей абсурдностью. И, скорее всего, я бы не пошел работать в компанию, которая предложила такое задачние просто потому, что не хочу 40 часов в неделю писать парсеры логов (:
Интересный у вас подход к поиску работы. То есть приходите вы на собеседование. Вам предлагают задачку типа этой, а вы им в ответ: "Вы что это мне тут суёте. Разве можно так собеседование проводить.". И не важно, что вы пришли потому, что вам действительно интересны проекты компании. Как же так. Разве можно работать в компании, которая ТАК собеседует кандидатов.
Вот из 4 абзацев текста вы, безусловно, выбрали правильный (:

Дело в том, что когда я устраиваюсь на работу, я оцениваю компанию, а компания оценивает меня.
Именно поэтому в моем комментарии 3 абзаца про то, как компания оценивает меня, и что для компании такой подход может оказаться не самым правильным, а последний абзац про то, что на мою оценку компании факт такого задания, безусловно, повлияет.
Что-то мне кажется, здесь собирается армия обиженных и униженных на собеседованиях :-)
Как это не удивительно, но именно так и происходит! Кандидаты выслушав задание, посидев за компьютером 15 минут начинают говорить, что задача оторвана от реальности, что решать ее нет смысла, потому что с ддосом нужно бороться не так, что данная задача не показывает их истинного уровня и т.д. и т.п.. Мне кажется, что говорить всё это можно только после того, как задача успешно решена. До тех пор - это все отмазки.
ну как бы не они себя поставили в такие условия :) Вы им говорите: "решите задачку", они ее решить не могут, вы на них смотрите косо, практически "гуляй вася", тут человеку, который не реализовал себя до конца хочется и "поговорить". Если бы вы, примеру, сразу предоставили ему список задач, то он бы и не напрягся, возможно, что не решил одну из списка...
Т.е. я хочу сказать, что тут можно говорить много о том, как ведут себя другие люди и "нам с ними работать". Но ведь Вы ничего не говорите как Вы преподносите все это для человека. Может такие ситуации, когда человеку остается только оправдываться, Вы сами и спровоцировали? а? Может же быть такое.
В этом топике прозвучало куча непонимания для чего эта задача от людей, которые уже прочитали куча предложенных тут решений (и уже знают ответ на нее). Но тем не менее, у них возникают негативные эмоции. Это как раз пример того, как они поняли, что Вы от них хотите. Т.е. этот негатив спровоцировали Вы :) (Вы - всмысле Хабр и Ко).
приходите к нам и вы убедитесь, что никто ни на кого косо не смотрит :) Мы максимально дружелюбны.
спасибо за предложение, может попозже и прийду ;)
P.S. Ходил на встречу в ВШЭ, где выступали ваши ребята - произвели хорошее впечатление :)
Взял имеющийся под рукой журнал Apache размером в 5,7 МиБ.

Запустил предложенный автором вариант. Куча ошибок. Вместо IP-адреса скрипт получает куски GET-запросов. Может, у меня какой-то неправильный формат журнала?..

Ну ладно. Немного подправил, заработало. 33 секунды (слабый компьютер, ага).

Написал свой вариант, используя preg_match_all('/^([^ ]+).+\\[([^\\]]+)\\] "([^"]+)"/', $string, $matches, PREG_SET_ORDER). 35 секунд. Где же обещанное падение производительности в полтора раза? Наверно, я что-то делаю не так?..

Немного оптимизовал, сделав сначала выделение IP-адреса при помощи одного выражения, а затем (если этот адрес ещё не заблокирован) парсинг остальной части строки при помощи другого выражения. 32 секунды. Нет, определённо что-то я делаю неправильно! Ведь мой скрипт с использованием регулярных выражений (что, между прочим, означает гибкость и наглядность в задании шаблона строки журнала) работает быстрее, чем эталонный!

Эх, не работать мне в «Тематические Медиа»...
Об чём и речь. Только мне для подобного вывода достаточно было взглянуть в код начиная с 11 строки и далее. За что мой комментарий получил 4 минуса (и это ещё не предел) :)
Не доводилось ли вам слышать про статистическую погрешность?

У нас всё дело подразумевало имеющийся файл размером 330 мегабайт. Приведенный скрипт на моём настольном компьютере обрабатывает его за 250 секунд. И это не есть самый быстрый вариант, просто это быстрее чем 10 или 20+ минут, с чем приходилось сталкиваться.

Например, если выделять ip-адрес регулярным выражением вида /^([^ ]+)/, то время работы увеличивается на 10 секунд, если вида /^(.+?) /, то на 20.

Если хранить адрес в виде целого числа, то время работы не уменьшается вовсе.
Разумеется, доводилось.

Поэтому я запускал скрипты по десятку раз и брал среднее время.

А также протестировал на журналах, сгенерированных случайным образом.
Протестировал на 57-мебибайтовом файле.

Ваш скрипт: 109 с.
Мой скрипт с одним регэкспом: 149 с.
Мой скрипт с двумя регэкспами: 105 с.
Я, на самом деле, уже написал, что моя реализация не есть рекордная, ещё время зависит от реализации регулярных выражений (preg, ereg, ДКА, НКА).

Уж думаю, при желании на несколько секунд подвинуть время можно.

Опубликуйте ваш вариант, я сравню на своём компьютере.
Так ведь и я не утверждал, что мой вариант самый оптимальный.

Код:

if(!preg_match_all('/^([^ ]+) (.+)$/', $string, $matches, PREG_SET_ORDER)) continue;
$ip = $matches[0][1];

if(isset($status[$ip]['blocked'])) continue;

if(!preg_match_all('/\\[([^\\]]+)\\] "([^"]+)"/', $matches[0][2], $matches2, PREG_SET_ORDER)) continue;
list($full, $time, $doc) = $matches2[0];

$time = strtotime($time);
Думаю, этот спор придётся отложить, у меня ваш вариант почему-то работает на 30 секунд дольше (я заменил только данные строки). Ни в коем случае не хочу вас обидеть, возможны разные ньюансы. Каждый запуск почти 4 минуты — отрывает от работы.

Как раз такой подход к задаче на собеседовании я ценю.
Нюансы наверняка существуют :)

В любом случае я лишь хотел заметить, что утверждение, будто регулярные выражения работают куда медленнее, как минимум спорно.
чего-то я вообще перестал понимать тему разговора.
Я думал мы обсуждаем "вот что нужно знать, чтобы у нас работать" или т.п.
А теперь у меня складывается ощущение, что тут просто хитрый способ найти несколько хороших и бесплатных решений для нагоревшей проблемы атак :))
А может это новый способ находить работника...кто знает... :)
НЛО прилетело и опубликовало эту надпись здесь
Оценивать наличие ворнингов как-то правильней в случае, когда задача решалась дома или просто за большее количество времени в менее стрессовой обстановке.

Не сложно внести пару изменений, чтобы от них избавиться, что я и сделал.
НЛО прилетело и опубликовало эту надпись здесь
Вы правы, ворнингов быть не должно, это то же самое, что в перле use strict; use warnings; как правило хорошего тона.

Мне стоило лучше подготовить код с тех пор как я его написал :-)
ребята по мне парсить access.log апача просто бессмысленно. можно ведь в реалтайме забирать инфу из нетстата или тцпдампа . 1500 ботов это даже не ддос , я имел дело с ситуацией когда ддос атака выжирала 80% со 100 мегабитного канала , access.log тогда за несколько часов вырос больше чем на гиг , ваш парсер справиться с этим? далее. допустим ддос начался часов в 10 вечера и вы обнаружили это в 7 утра , логично , что логротэйт уже был и размер аксэслога уже несколько гигов . нормальный бот нет к этому времени уже сменит большую часть ip'ников . и что будет делать ваш скрипт ? закрывать доступ для ip с которых уже несколько часов ничего не идет?
вы меня простите но такой метод по моему абсолютно бесполезен , тем более , что есть несколько готовых решений и защита от ддоса предостовляеться еще и на уровне хостера .
Притормозите и осмотритесь вокруг :-)

Это действительно задача не для системного администратора/инженера по сетевой безопасности.

Это прежде всего задача для php-разработчика, которая и в практических условиях может принести толк при атаках до 1000 ботов.

А если действительно интересно знать, как лучше всего поступить, то стоит копать в сторону анализа полей получаемого трафика, боты в этом смысле палятся однозначно в большинстве случаев.

Нам нужна была задача для разработчиков, нетривиальная задача, которую они с большей степенью вероятности раньше не встречали. Не более.
мысль понял , но нельзя не согласиться , что анализ входящего трафика всеже эффективнее, да и кострукция $fh = fopen($fname, 'r'); если я не ошибаюсь подгружает фаил в память полностью. т.е. даже при 80 метровом акксеслоге выжираеться сразу 80 метров памяти , а если вы сидите на шареде , то ваш сайт отправят в суспенд еще до того как ддос кончиться.
Помещает в память не fopen, а file
пасиб , буду знать))
Хотя, если ввести разные баллы за разные действия, скажем не только временной критерий но и критерий запроса одинаковых документов, запроса только документов определённого типа, то от 1000 ботов вполне можно уйти к 10000+.
На решение давалось от часа, до двух времени (в зависимости от хода мысли человека), последний раз она была решена за 1 час 20 минут. Всего решили задачу примерно 10% соискателей.
афигеть - сидеть больше часа решать задачу... видать у вас очень много свободного времени, что можете себе позволить на собеседовании тратить более часа на решение только одной! задачи.

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

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

Но это довольно нормальная практика для других компаний: ~2 часа времени.

Остальные факторы, как то коммуникативность, стрессоустойчивость, порядочность можно оценить во время разговора и во время решения задачи.
просто задача достаточно не тривиальная и просить ее решить в пределах собеседования(когда и так человек нервничает) - это само по себе достаточно большой стресс...

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

Именно поэтому стараемся не доводить каждого претендента до решения задачи, это действительно отнимает время, хотя пока кандидат решает, все работают.
ясно. еще не плохо получается давать такие задачки на дом, а потом на месте разбираться - причем не важно, сам решил он ее или нет - главное чтобы понимал о чем речь и умел отстоять свою точку зрения(причем важен то сам процесс)
Про нетривиальность и стресс вы правы. Хотя, большинство местного населения подходит ко всему в стиле "ерунда! я такое сделал бы за 5 минут" :-)

На дом давали в основном тем, кто на момент собеседования находился далеко от дома, ну и соотвественно оценка решения была много строже.

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

Но мне как-то кажется что условие с задачей о перевороте строки несколько неточное: получается что в программе может быть только один указатель на массив, в котором n байт текста + завершающий символ 0, и что нельзя создавать или пользоваться чем-либо ещё, то есть вообще ничем, даже переменной для хранения промежуточного указателя или организации цикла.
То есть, чтобы даже перекидать все символы через завершающий, нужен цикл, а для цикла переменная, а это - тоже дополнительная память.
Статья-то может и хорошая, только я её так и не увидел, у меня у одного такое ? Там пусто.
Вот что мне выводит:
There is currently no text in this page, you can search for this page title in other pages or edit this page
Только что было. Какой-то умник всё потёр, а откат там выключен для гостей, видимо.
Написал на perl'e (в принципе мой основной язык разработки), лог апача 21.5мб с использованием регулярок, на ноутбуке - 0.82 секунды :) Это первая версия, на написание ушло около 10минут. Щас ради спортивного интереса произведу оптимизацию :) О результатах отпишу.

p.s. Я не хочу холиваров по поводу языков и "меренья членов", просто делюсь своими результатами.
Я сам, по большому счёту, больше люблю перл, как средство творческого самовыражения и разработки :-)
НЛО прилетело и опубликовало эту надпись здесь
Час это номинально. На практике доходило до двух
НЛО прилетело и опубликовало эту надпись здесь
http://habrahabr.ru/info/help/

wiki больше не будет, как скоро не будет и старого хабра
мне не нравится вот этот кусок
$dot = strrpos($doc, ".");
$dot = $dot ? strlen($doc) - $dot : 0;
if(!$dot || $dot > 5)
понятно, что надо игнорировать тех, кто дёргает статику в обход кеша (ну, кстати, тоже с натяжкой), но условие на длину куска документа после точки, вообще говоря, совсем некорректное. то есть понятно, что у вас оно будет работать, но а если б были всякие index.php вместо index.html :)
Привет!
Ну как-то да, косвенно это, но не хотелось перечислять все возможные расширения.

Варианты принимаются :-)
мда... лохота ужасная....
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории