Comments 49
Спасибо, читать статью легко и просто, но могли бы написать пример который вы даете?
Ну да, читать такие длинные и информативные статьи к кучей примеров всегда легко и просто!
Эх, была, не была :)
Все равно хотел менять задачи. Из теста они уже есть в инете, а устной еще не было.
Итак.
Дан массив неограниченной вложенности, нужно написать функцию, которая выведет его в виде вложенного списка с отступами, пропорциональными глубине, и текущем путем к элементу.
Вызов showMenu(menu);
должен выдавать HTML-код, как по адресу
Массив:
Все равно хотел менять задачи. Из теста они уже есть в инете, а устной еще не было.
Итак.
Дан массив неограниченной вложенности, нужно написать функцию, которая выведет его в виде вложенного списка с отступами, пропорциональными глубине, и текущем путем к элементу.
Вызов showMenu(menu);
должен выдавать HTML-код, как по адресу
Массив:
menu = [ 'simple item', [ 'title' => 'Complex item', 'items' => [ 'simple item2', 'simple item3', [ 'title' => 'Another complex item', 'items' => [ '...' ] ] ] ] ];
После всех вопросов про «инкапсуляция, полиморфизм, наследование, B+-tree с упором на SOLID + DRY + IoC» — вы даете такие тестовые задачки? )
Зачем же так мучить соискателя )
Зачем же так мучить соискателя )
ну да, в этой задаче сплошной SOLID. хочу заметить что D(ependency injection) в SOLID это и есть IoC. и какой смысл доказывать кандидату что перед ним не девочка HR? опытного человека можно отпугнуть навсегда такими вопросами. не лучше ли о чем-то более серьезном и соответственно интересном пообщаться?
DI это разновидность IoC, если быть строгим, как я это понимаю. IoC еще можно делать через контейнеры и другими хитрыми способами, всякие Service LocatorЫ и тд.
Спрашиваю потому, что знающий и __понимающий__ эти принципы, считай, владеет и принципами-паттернами, и ему не нужно втолковывать кучу вещей.
А доказывать никому не нужно, просто нужно настроить человека на технический лад :)
Спрашиваю потому, что знающий и __понимающий__ эти принципы, считай, владеет и принципами-паттернами, и ему не нужно втолковывать кучу вещей.
А доказывать никому не нужно, просто нужно настроить человека на технический лад :)
Нет, вопросы про B+tree стоят вот так.
1. Сначала, что такое индекс в БД, зачем нужен, как устроен.
(одно предложение)
2. А знаете ли что такое B+tree.
(если ДА, то что, одним предложением. дополнительные пару вопросов, если чел врет, что знает)
(если нет, идем дальше).
и все :)
А задача потому, что человек разогрет, мозг работает в техническом контексте, а не отвечания на вопросы про люки и «как вы видите себя через 3 года» (=повторение заученных ответов).
Рекурсия заставляет в голове представить обход одного уровня этого массива, а затем правильный уход в рекурсию.
Впрочем, есть и методы решения через жопу, но мы ведь не о них :)
1. Сначала, что такое индекс в БД, зачем нужен, как устроен.
(одно предложение)
2. А знаете ли что такое B+tree.
(если ДА, то что, одним предложением. дополнительные пару вопросов, если чел врет, что знает)
(если нет, идем дальше).
и все :)
А задача потому, что человек разогрет, мозг работает в техническом контексте, а не отвечания на вопросы про люки и «как вы видите себя через 3 года» (=повторение заученных ответов).
Рекурсия заставляет в голове представить обход одного уровня этого массива, а затем правильный уход в рекурсию.
Впрочем, есть и методы решения через жопу, но мы ведь не о них :)
>полчаса поговорить с кандидатом, чтобы он понял, что перед ним не HR-девочка
… а тимлид-девочка? :)
… а тимлид-девочка? :)
Я сначала спрашиваю о себе, потом даю FizzBuzz, и если он решает, то перехожу к теории и далее.
Пару раз пробовал идти далее, когда не решают FizzBuzz, но эта стратегия провальная.
Пару раз пробовал идти далее, когда не решают FizzBuzz, но эта стратегия провальная.
Иногда важно посмотреть за ходом мыслей человека.
Как он решает незнакомую задачу.
А не простая оценка «решил» или «не решил».
Как он решает незнакомую задачу.
А не простая оценка «решил» или «не решил».
Все-таки «люки» нужны.
На них можно посмотреть насколько нестандартно человек мыслит.
Но нужна своя задачка, чтобы человек заранее не знал ответ.
На них можно посмотреть насколько нестандартно человек мыслит.
Но нужна своя задачка, чтобы человек заранее не знал ответ.
Это все очень интересно, но многие веб-программисты в состоянии решать поставленные перед ними задачи без знания указателей и тонкостей реализации индексов в базах данных. Безусловно, те, которые знают про все, что вы у них спрашиваете, абстрактно лучше как программисты, но ведь и дороже в итоге как правило. А если стоит задача скажем вьюшки в джанге собирать до посинения, или там в каком php-фреймворке ковыряться, то зачем платить больше?
А как часто вы собеседуете людей, превосходящих вас по уровню? Или вакансии такого в принципе не подразумевают?
+1, тоже интересен ответ на этот вопрос.
Прошерстив сотни резюме, проведя десятки собеседований, хочу поделиться
да, я не написал ни одной рекурсии в громадном проекте :) зато без указателей не обошлось. видимо я не прошел бы собеседование :)
мой критерий гораздо проще. вот задача, вот нотбук — реши ее. и потом объясни решение. Если чел написал вложенный цикл а на вопрос зачем сказал — мне надо быстро а 99% смартфонов в этом месте не загнутся — это факт принять его на работу.
мой критерий гораздо проще. вот задача, вот нотбук — реши ее. и потом объясни решение. Если чел написал вложенный цикл а на вопрос зачем сказал — мне надо быстро а 99% смартфонов в этом месте не загнутся — это факт принять его на работу.
Shrek is Love, Shrek is life.
Вот я читаю подобные статьи и думаю. Может я еще зеленый (да, да, я такой, студент еще), но ведь главное умение программиста — вникать в задачу/технологию и генерировать идею ее разрешения/быстро осваивать.
Почему на собеседованиях никогда не проверяют эти качества, а проверяют то, что уже точно умеет человек? То есть конечно ясно, что есть какая-то база, которую нужно знать, но вот я на пример не знаю нормально регулярки, просто в силу того, что не часто с ними сталкивался, зато точно знаю как решить задачку с рекурсией. Хотя должен заметить когда-то плохо знал как с рекурсией обращаться, а в дальнейшем даже понравилось.
Почему на собеседованиях никогда не проверяют эти качества, а проверяют то, что уже точно умеет человек? То есть конечно ясно, что есть какая-то база, которую нужно знать, но вот я на пример не знаю нормально регулярки, просто в силу того, что не часто с ними сталкивался, зато точно знаю как решить задачку с рекурсией. Хотя должен заметить когда-то плохо знал как с рекурсией обращаться, а в дальнейшем даже понравилось.
История из жизни
Проходил собеседование на практику в небольшой фирме занимающейся разработкой сайтов. За час до собеседования понял что ничего не знаю про джойны. Ну вообще ничего, просто никогда не требовались.(нет, циклами в запросах я не обходился, просто не требовалось) И как назло интернет в метро плохо ловил, ничего прочитать так и не смог. Приехал, перенервничал, наделал глупых ошибок, вроде вместо strlen использовал count. Пообещали созвониться до конца недели.
Выйдя — понял что все скорее всего провалил. Около входа в метро стоит ростикс — зашел, сел, разобрался с джойнами быстро и отослал тестовые задания, в решенном виде. Уж не знаю повлияло ли это на решение — мне на следующий день предложили работу. По своим причинам в итоге отказался.
Сейчас с джойнами разобрался, но эта история, как мне кажется показывает одно из решающих и важных умений программиста — как обучаемость.
Выйдя — понял что все скорее всего провалил. Около входа в метро стоит ростикс — зашел, сел, разобрался с джойнами быстро и отослал тестовые задания, в решенном виде. Уж не знаю повлияло ли это на решение — мне на следующий день предложили работу. По своим причинам в итоге отказался.
Сейчас с джойнами разобрался, но эта история, как мне кажется показывает одно из решающих и важных умений программиста — как обучаемость.
Поддерживаю это мнение. Все знать не возможно, да и не нужно — для этого есть документации, интернет,… А вот умение быстро обучаться и находить решения задач является решающим для отличного веб програмиста. И конечно же, человек должен любить свое дело. А все остальное приложится;)
Для джуниора обучаемость — основной фактор, это да.
Но блин, сейчас любой студент, пять лет бухавший ягу и годик проработавший младшим подаваном в какой-нибудь говноконторке, из которой в итоге был уволен за прогулы и непроходимую тупость, мнит себя как минимум синиором, если не тимлидом, и желает соответствующую личку.
А компаниям чаще всего нужны не джуниоры и не синиоры, а просто готовые программисты. Которые не просто могут за один день разобраться с джойнами, а которые собаку на этих джойнах съели и соотвественно могут написать этот джойн за 1 минуту, причем правильно, и пойти решать другие задачи.
В конечном счете для компании все упирается в деньги. Успевает нанятый программист за месяц закрыть столько тасков, чтобы компания отбила его зарплату в три раза, или не успевает. (Только не надо думать, что «три конца» это много и компания слишком много кушать, нет. «Один конец» съедают налоги и праздники с отпусками, а второй — содержание организации, включая аренду офиса, зарплаты таких бесполезных, но необходимых нахлебников как бухгалтера, юристы и сейлзы).
Но блин, сейчас любой студент, пять лет бухавший ягу и годик проработавший младшим подаваном в какой-нибудь говноконторке, из которой в итоге был уволен за прогулы и непроходимую тупость, мнит себя как минимум синиором, если не тимлидом, и желает соответствующую личку.
А компаниям чаще всего нужны не джуниоры и не синиоры, а просто готовые программисты. Которые не просто могут за один день разобраться с джойнами, а которые собаку на этих джойнах съели и соотвественно могут написать этот джойн за 1 минуту, причем правильно, и пойти решать другие задачи.
В конечном счете для компании все упирается в деньги. Успевает нанятый программист за месяц закрыть столько тасков, чтобы компания отбила его зарплату в три раза, или не успевает. (Только не надо думать, что «три конца» это много и компания слишком много кушать, нет. «Один конец» съедают налоги и праздники с отпусками, а второй — содержание организации, включая аренду офиса, зарплаты таких бесполезных, но необходимых нахлебников как бухгалтера, юристы и сейлзы).
Согласен. Но в таких статьях не пишут кого ищут на работу. Какой уровень? Человек может отлично знать SQL, но никогда не иметь дело с ORM. Да, он разберется, но тонкостей не знает, и скорее всего часть возможностей сразу использовать не будет, а пользоваться query-builder'ом.
Опять же, возможно мое наивное мнение, но как мне кажется программисту нужно знать хорошо базу + какие-то специализированные вещи. Кто-то хорошо рефакторит и тесты пишет. А кто-то левой рукой сервер поднимает, а правой базу оптимизирует. Я утрирую, но мысль ясна. Мне казалось идеальная команда состоит из таких программистов, где каждый умеет и могет, но каждый лучший в какой-то своей области.
И тогда так и писать в требованиях — нужен человек отлично знающий следующие технологии. Тогда студенты вроде меня не будут тратить ваше время. Но в требованиях четко пишут — отличное знание *стек технологий*, думаю соискатели, о которых отзываются дурно в таких статьях думают так: «ну что php54, ну трейты — понимаю. SQL… да, джойнить умею, связи строить тоже могу, индексы вроде правильно ставлю, не дурак… JS — да, синтаксис знаю, замыкания прототипы умею, jquery в каждом проекте использую», а когда приходят — закидывают вопросами о которых в требованиях и в помине небыло.
Зачем веб-программисту знать красно-черные деревья и указтели — я не совсем понимаю. Такое зашито глубоко в языки и это уже совсем не веб-программирование.
Опять же, возможно мое наивное мнение, но как мне кажется программисту нужно знать хорошо базу + какие-то специализированные вещи. Кто-то хорошо рефакторит и тесты пишет. А кто-то левой рукой сервер поднимает, а правой базу оптимизирует. Я утрирую, но мысль ясна. Мне казалось идеальная команда состоит из таких программистов, где каждый умеет и могет, но каждый лучший в какой-то своей области.
И тогда так и писать в требованиях — нужен человек отлично знающий следующие технологии. Тогда студенты вроде меня не будут тратить ваше время. Но в требованиях четко пишут — отличное знание *стек технологий*, думаю соискатели, о которых отзываются дурно в таких статьях думают так: «ну что php54, ну трейты — понимаю. SQL… да, джойнить умею, связи строить тоже могу, индексы вроде правильно ставлю, не дурак… JS — да, синтаксис знаю, замыкания прототипы умею, jquery в каждом проекте использую», а когда приходят — закидывают вопросами о которых в требованиях и в помине небыло.
Зачем веб-программисту знать красно-черные деревья и указтели — я не совсем понимаю. Такое зашито глубоко в языки и это уже совсем не веб-программирование.
А какже пиремущества и недостатки третьей нормальной формы и её отличия от формы Бойса-Кодда?
Ну такие вопросы тоже можно задавать, просто если я вижу, что человек не пугается слов O(N) — могу и спросить, почему quicksort это O(NlogN). Но если человек не шарит, а мы беседуем про индексы — спрашиваю на воображение и понимание, что один алгоритм решает задачу для 10 элементов за столько действий, а другой за столько*дохрена, и почему первый лучше.
UFO just landed and posted this here
Я бы внес поправки.
Интервью состоит изтрех пяти частей, занимает 30-60 минут.
1. Рассказ программиста о себе.
2. Короткие вопросы на кругозор.
2.1. Рассказ работодателя о себе.
2.2. Ответы работодателя на вопросы соискателя.
3. Решение задач
Вы же не раба выбираете.
Интервью состоит из
1. Рассказ программиста о себе.
2. Короткие вопросы на кругозор.
2.1. Рассказ работодателя о себе.
2.2. Ответы работодателя на вопросы соискателя.
3. Решение задач
Вы же не раба выбираете.
Вот честно, какую-то фигню устраиваете.
Достаточно выпить с человеком пару чашек кофе за ненапряжной беседой, чтобы понять, подходит он или нет.
Достаточно выпить с человеком пару чашек кофе за ненапряжной беседой, чтобы понять, подходит он или нет.
[irony] Я вам так про ООП расскажу, сами поверите, что оно лучше всех, даже если привыкли писать в функциональном стиле. [/irony]
Бывают и такие гуру, что говорят, аки твой соловей. А попросишь написать решение простой задачи на ООП (только рассуждавший про Стратегию не знает, зачем она нужна конкретно тут и как ее написать) — молчание в ответ.
Платят за красивые слова писателям, а за красивый РАБОТАЮЩИЙ код — программистам.
Бывают и такие гуру, что говорят, аки твой соловей. А попросишь написать решение простой задачи на ООП (только рассуждавший про Стратегию не знает, зачем она нужна конкретно тут и как ее написать) — молчание в ответ.
Платят за красивые слова писателям, а за красивый РАБОТАЮЩИЙ код — программистам.
Если вы расскажите так, что я вам поверю — значит у вас определённо талант убеждать людей. Хорошего менеджера, как и хорошего программиста, не так-то просто и найти.
По большому счёту, текущие знания (в пределах разумного, разумеется) не так важны, если вы планируете длительное сотрудничество с человеком. Гораздо важнее его социальные навыки, в том числе: обучаемость, мотивация, адекватность, способность к самокритике.
Можно и обезьяну научить программировать, но только что с ней потом делать?!
По большому счёту, текущие знания (в пределах разумного, разумеется) не так важны, если вы планируете длительное сотрудничество с человеком. Гораздо важнее его социальные навыки, в том числе: обучаемость, мотивация, адекватность, способность к самокритике.
Можно и обезьяну научить программировать, но только что с ней потом делать?!
По моему не такому большому опыту, на целый час прикинуться обучаемым и горящим глазами проблем нет, а вот долго маскироваться в работе нет.
Одновременно, чем больше компания, тем более готовых спецов она хочет к себе брать, чтобы они быстрее окупали себя и делали продукты мирового уровня.
Зато закосить под умного на испытательный срок с гуглом можно, а вот перед батареей вопросов устоять нельзя, особенно с задачей. Либо вы супербыстро гуглите и вникаете :)
А обучаемость и все остальное прекрасно видны на первой неделе. Один ставит софт сразу, ковыряет, задает __осмысленные__ вопросы, работает на совесть. Второй ставит три дня, задает кучу глупых вопросов, сам не старается, ждет, что за него сделают все сразу.
Это не выявишь на собеседовании, и не нужно :)
Одновременно, чем больше компания, тем более готовых спецов она хочет к себе брать, чтобы они быстрее окупали себя и делали продукты мирового уровня.
Зато закосить под умного на испытательный срок с гуглом можно, а вот перед батареей вопросов устоять нельзя, особенно с задачей. Либо вы супербыстро гуглите и вникаете :)
А обучаемость и все остальное прекрасно видны на первой неделе. Один ставит софт сразу, ковыряет, задает __осмысленные__ вопросы, работает на совесть. Второй ставит три дня, задает кучу глупых вопросов, сам не старается, ждет, что за него сделают все сразу.
Это не выявишь на собеседовании, и не нужно :)
Всё верно говорите: нужно брать самых адекватных на испытательный срок, и уже на первой неделе станет понятно, кто и чего стоит.
Задачи в процессе интервьюирования (надеюсь, Мицгол не увидит), как и вообще технический допрос (а это именно допрос), говорят то том, что вы по-умолчанию не доверяте потенциальному сотруднику. На мой скромный взгляд, это очень плохая практика; доверительные отношения должны изначально строиться на доверии и партнёрстве.
Задачи в процессе интервьюирования (надеюсь, Мицгол не увидит), как и вообще технический допрос (а это именно допрос), говорят то том, что вы по-умолчанию не доверяте потенциальному сотруднику. На мой скромный взгляд, это очень плохая практика; доверительные отношения должны изначально строиться на доверии и партнёрстве.
Ну тогда вконтакте, который месяц собеседует людей, ваще им не доверяют?
Мир, увы не идеален :((
Мы пробовали давать более сильный тест, но люди его не заполняют, влом. Поэтому часть вопросов перекочевала в устное интервью. Оно, кстати, одно, а не три. Вот три интервью — это реально задница ИМХО. Допросы :)
Мир, увы не идеален :((
Мы пробовали давать более сильный тест, но люди его не заполняют, влом. Поэтому часть вопросов перекочевала в устное интервью. Оно, кстати, одно, а не три. Вот три интервью — это реально задница ИМХО. Допросы :)
Вконтакте стал показателем… эм… чего-то вообще?
Согласен, мир не идеален и, благодаря задачам на интервью, вы делаете его его менее идеальным, отсеивая и тех, кто не может от волнения собраться с мыслями, и тех, кто не знает решения, но в целом быстро схватывает, и тех, кто готов на вас сутками пахать, лишь бы войти в одну из ваших команд.
2 интервью, я считаю — идеально. Первая кружка кофе — с HR'ом, который отсеит совсем неадекват, ненавязчиво узнает про основные ценности человека, снимет напряжение, подготовив кандидата ко второму интервью. Вторая кружка — с техническим специалистом, который просто «за технологии» поговорит с кандидатом и которому не составит труда понять, вольётся ли человек в команду. Смотрите, что получилось: мы из допроса с пристрастием сделали милую, светскую беседу, по окончанию которой, ни одной стороне не нужно будет снимать напряжение Корвалолом или крепкими алкогольными напитками.
Согласен, мир не идеален и, благодаря задачам на интервью, вы делаете его его менее идеальным, отсеивая и тех, кто не может от волнения собраться с мыслями, и тех, кто не знает решения, но в целом быстро схватывает, и тех, кто готов на вас сутками пахать, лишь бы войти в одну из ваших команд.
2 интервью, я считаю — идеально. Первая кружка кофе — с HR'ом, который отсеит совсем неадекват, ненавязчиво узнает про основные ценности человека, снимет напряжение, подготовив кандидата ко второму интервью. Вторая кружка — с техническим специалистом, который просто «за технологии» поговорит с кандидатом и которому не составит труда понять, вольётся ли человек в команду. Смотрите, что получилось: мы из допроса с пристрастием сделали милую, светскую беседу, по окончанию которой, ни одной стороне не нужно будет снимать напряжение Корвалолом или крепкими алкогольными напитками.
2-ая задача (JavaScript)
// Приветствуются конструктивные замечания по коду
function problem2(input) {
var openIndex = input.indexOf('{');
if (openIndex === -1) return [input];
var result = [''];
while (openIndex !== -1) {
var firstPart = input.substring(0, openIndex);
var parts = [];
var openCount = 0;
for (var i = openIndex + 1, length = input.length; i < length; ++i) {
if (input[i] === '{')
++openCount;
else if (input[i] === '}') {
--openCount;
if (openCount < 0) {
parts.push(input.substring(openIndex + 1, i));
input = input.slice(i + 1);
break;
}
}
else if (openCount === 0 && input[i] === '|') {
parts.push(input.substring(openIndex + 1, i));
openIndex = i;
}
}
var newResult = [];
parts.forEach(function (part) {
problem2(part).forEach(function (partResult) {
result.forEach(function (resultItem) {
newResult.push(resultItem + firstPart + partResult);
});
});
});
result = newResult;
openIndex = input.indexOf('{');
}
if (input.length > 0) {
result.forEach(function (element, index, array) {
array[index] = element + input;
});
}
return result;
}
И часто в ваших проектах приходится писать такие алгоритмы?
иногда бывает и сложнее :)
вообще, лексический анализатор — весчь :)
вообще, лексический анализатор — весчь :)
работу ищете?
Не претендуя на скорость и оптимальность, на скорую руку набросал свой вариант:
2 задача
var parseExpression = function(str) {
var openBracket, closeBracket, variants, head, tail;
var result = [];
closeBracket = str.indexOf('}');
if (closeBracket === -1)
return str;
openBracket = str.substr(0, closeBracket).lastIndexOf('{');
if (openBracket === -1)
return str;
variants = str.substr(openBracket+1, closeBracket - openBracket - 1).split('|');
head = str.substr(0, openBracket)
tail = str.substr(closeBracket + 1);
for(var i=0; i < variants.length; i++) {
result.push(parseExpression(head + variants[i] + tail));
}
return [].concat.apply([], result).filter(function(elem, pos, self){return self.indexOf(elem) == pos});
}
Красивое решение. Мне так сделать и в голову не пришло.
Ради интереса сравнил производительность: jsfiddle.net/EzwkA/
Ради интереса сравнил производительность: jsfiddle.net/EzwkA/
Вопросы — сборная солянка для поиска многорукого шивы: он у нас и кодит отлично и дизайн и юних заадминит и NF6, а в перерывах деревья напишет. Да не простые а, наверное какие-то именно веб-tree.
Когда я вижу такие интервью мне становится понятно, что у интервьюера или какие то комплексы или он просто не понимает кто ему нужен.
Когда я вижу такие интервью мне становится понятно, что у интервьюера или какие то комплексы или он просто не понимает кто ему нужен.
Если вы, как один мой знакомый, который сказал — я хочу писать только на JS и больше ни на чем, то вы сильно отстали от мира. Web-программирование это зоопарк технологий. Без понимания, что такое индексы в СУБД, вы не сможете оптимизировать большую часть проектов под highload. Не зная HTML/CSS вообще, вы не то что не сможете сделать супер frontend MVC интерфейс — банальную верстку, где статусы элементов определяются классами, не сможете оживить.
Без понимания рекурсии и указателей — ну, вон, выше прекрасно написали в тему.
Поэтому нужны профи. Многоруких шива как раз НИКТО обычно не проверяет — берут подешевке, и дают все, что попало, заставляя разбираться поверхностно.
А деревья с наскоку не понять, как это не удалось вам в этом комменте (гуглить binary tree, если интересно)
Без понимания рекурсии и указателей — ну, вон, выше прекрасно написали в тему.
Поэтому нужны профи. Многоруких шива как раз НИКТО обычно не проверяет — берут подешевке, и дают все, что попало, заставляя разбираться поверхностно.
А деревья с наскоку не понять, как это не удалось вам в этом комменте (гуглить binary tree, если интересно)
Ну не знаю-не знаю) Я на 1 курсе учусь, второкурснику писал лабу, по бинарным деревьям. У его одногруппников поспрашивал — какую-то ахинею несли, вроде «нужны просто чтобы показать что такие есть», когда разобрался и поиск и сортировку и все что нужно было написал, заинтересовали другие разновидности, но пока нет времени разобраться. А бинарные деревья можно сказать с наскоку понял, у меня не графов, ни матана ничего нормального небыло еще.
ls | grep "test"Што-о-о?! То есть `ls *test*` не подходит в качестве правильного ответа?
Хорошо, если человек это скажет, я тогда доспрошу, как это сделать с grep. Или что-нибудь с xargs — find. | xargs rm (удаление дохренища файлов в папке, когда rm дохнет, чит-хак-неправильно-но-работает)
Чтобы понять, как человек понимает строку — просто одну команду, или знаменитую философию unix тоже читал и даже тыкал (не только патч Бармина, ха ха).
Чтобы понять, как человек понимает строку — просто одну команду, или знаменитую философию unix тоже читал и даже тыкал (не только патч Бармина, ха ха).
Посмотрел я на приведенный JS код, на то как все в одну кучу смешано, как ошибки во входной строке не обрабатываются, как выражения не оптимизируются. И, в основном с целью с parser combinators поиграться, переписал на Scala. Мухи получились отдельно, котлеты отдельно, потом еще оптимизацию прикрутил.
2-ая задача (Scala)
import scala.util.parsing.combinator._
import scala.util.parsing.input.CharSequenceReader
sealed abstract trait Expr {
def allStrings: List[String]
def isLiteral = false
def isEmpty = false
}
case class Literal(s: String) extends Expr {
override def allStrings: List[String] = List(s)
override def isLiteral = true
}
case object Empty extends Expr {
override def allStrings: List[String] = Nil
override def isEmpty = true
}
case class Multi(es: List[Expr]) extends Expr {
override def allStrings: List[String] = es.flatMap(_.allStrings)
}
case class Concat(es: List[Expr]) extends Expr {
override def allStrings: List[String] = allStrings(List(""), es)
private def allStrings(prefixes: List[String], es: List[Expr]): List[String] = es match {
case Nil => prefixes
case h :: t => allStrings(for (p <- prefixes; s <- h.allStrings) yield p + s, t)
}
}
trait ExprParsers extends RegexParsers {
override val skipWhitespace = false
def literal: Parser[Literal] = """[^{|}]+""".r ^^ { Literal(_) }
def multi: Parser[Multi] = "{" ~> repsep(cexpr, "|") <~ "}" ^^ { l => Multi(l.distinct) }
def concat: Parser[Concat] = (mexpr +) ^^ { Concat(_) }
def cexpr: Parser[Expr] = concat
def mexpr: Parser[Expr] = literal | multi
}
trait ExprOptParsers extends ExprParsers {
override def cexpr: Parser[Expr] = super.cexpr ^^ { _ match {
case Concat(List(x)) => x
case Concat(l) if l.forall(_.isLiteral) => Literal(l.map(_ match {case Literal(t) => t}).mkString)
case Concat(l) if l.exists(_.isEmpty) => Empty
case x => x
}}
override def mexpr: Parser[Expr] = super.mexpr ^^ { _ match {
case Multi(Nil) => Empty
case Multi(List(x)) => x
case Multi(l) if l.exists(_.isEmpty) => Empty
case x => x
}}
}
object Parser extends ExprOptParsers {
private lazy val main: Parser[Expr] = phrase(cexpr)
private def parse(s: String): Expr = main(new CharSequenceReader(s)) match {
case Success(e, _) => e
case NoSuccess(m, n) => throw new IllegalArgumentException("Parsing error at " + n.pos + "\n" +
n.pos.longString + ": " + m)
}
def printAll(s: String): Unit = {
val p = parse(s)
println(p.allStrings.mkString("\n"))
println(p)
}
def shouldFail(s: String): Unit = {
try {
val p = parse(s)
} catch {
case e: IllegalArgumentException => println(e.getMessage)
}
}
def main(args: Array[String]): Unit = {
shouldFail("{")
shouldFail("}")
shouldFail("")
printAll("тест")
printAll("тест {тест}")
printAll("{тест} {тест}")
printAll("{тест {тест}}")
printAll("{}")
printAll("{{{{{{{{{{тест {тест}}}}}}}}}}}")
printAll("{A | B | C} тест")
printAll("{A | B} {A | B}")
printAll("{A |A | B} {A | B| B}")
printAll("{Пожалуйста|Просто} сделайте так, чтобы это {удивительное|крутое|простое} тестовое предложение {изменялось {быстро|мгновенно} случайным образом|менялось каждый раз}.")
printAll("{Пожалуйста|Просто} сделайте так, чтобы это {удивительное|крутое|простое} тестовое предложение {изменялось {быстро{}|мгновенно} случайным образом|менялось каждый раз}.")
}
}
Sign up to leave a comment.
Вариант эффективного интервью