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

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

Все зависит от области! Игродел за секунду напишет решение, программист десктопных приложений на java или c# напишет, наверное, за то же время, а вот вэб программист наверное будет долго думать. И все дело в том что для первых двух категорий обычный код тот, который для вэб программистов фраймворк.
Бездарных игроделов существует дюжинное количество. Десктопных — не меньшее. Вот с вебными всё действительно много хуже и для их поиска надо указать что нужен нод.жс, паттерны проектирования и знание алгоритмической сложности. И всё равно 90% приходящих не могут на клочке бумаги обсёрвабл нарисовать.
по большей части Вы правы, но везде есть свои нюансы. У игроделов плохой программист, это тот который плохо знает математику-физику. Но зато у игроделов намного все серьезней с проектированием, сильнее даже чем у обычных серверистов, которые пишут сервера для сайтов-приложений. Они просто не могут не разбираться в DDD, чего не всегда хватает дескопщикам, хотя им математика нужна меньше чем архитектура.
А вот в вэбе DDD это вообще как Йоулупукки для российских детей, чье имя может если не рассмешить, то даже напугать. Но тут я не говорю о людях которые пришли в вэб из других java c# с++ языков. И в этом не их вина, они свято верят что разработчики фраймворков просто боги которые лучше всех знают как нужно делать и если они делают так, то это единственно верное решение. То есть они учатся на увиденном. Да и куда скрыть тот факт что jQ и всякие верстки для cms до сих пор являются приоритетными.
А вот в вэбе DDD это вообще как Йоулупукки для российских детей, чье имя может если не рассмешить, то даже напугать. Но тут я не говорю о людях которые пришли в вэб из других java c# с++ языков.

Не преувеличивайте. В мире PHP уж точно DDD имеет место быть. Будущий мажорный релиз Symfony в частности обещает упрощения разработки по DDD.

Даже такой бесполезный ларавельщик-пыхобыдлокодер как я и то юзает DDD и сейчас буду пихать интеракторы в органайзер и материться что laravel не все зависимости в контекст инжектировал по интерфейсам и писать для них сервис-провайдеры которые позволят DI отрезольвить их.

Это… это… это же потрясающе! О_о
О.О Я боюсь спросить сколько ушло на написание этого кода :-)
Там еще и 159 ишуков заведено, люди докер, к примеру, требуют :D

А в docker'е надо WildFly Swarm, как минимум.

Это просто прекрасно! Не думал, что смогу рыдать от смеха глядя на код)

ну а серьёзно, я вот не видел других вариантов решения, где предусматривается изменение требований к работе системы, например на fizz-buzz-heraz, где последнее выдавать при делимости на 7

Есть у меня, конечно, наколеночное решение с хардкодом, но это не наш метод! :)
Я не согласен, задание очень простое, кто не может его сделать в редакторе до 10 минут — не программист, а оператор компьютера. Я такие задачи не делаю, все что мне понадобилось — это перепроверить в гугле, что % проверяет кратность и все.

Проблема в том, что новое поколение ребят с курсов задают такой вопрос «А что, Jquery это тоже Javascript? Не может быть!».
Если человек пошёл на курсы — значит не смог освоить самостоятельно, что само по себе довольно странно.

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

Как бы там ни было, странно самостоятельно усвоить университетские курсы. Всетаки, там не 1 или 2 области, а много.
Во время учёбы мне не раз приходила в голову мысль, что если бы мне просто дали список того, что нужно знать для приобретения квалификации инженера, я запросто изучил бы это сам. В конце концов, какая разница, по лекциям учиться или по учебникам?

Если же Вы намекаете на «корочку», то я с трудом верю, что где-то котируется корочка JQuery-разработчика…
если бы мне просто дали список того, что нужно знать для приобретения квалификации инженера, я запросто изучил бы это сам

Это есть, и называется сдать экзамены экстерном.

Немного не так оно есть, как в комментарии. Списки эти в пригодном для самоподготовки виде с боем нужно выбивать из деканатов/кафедр. По крайней мере лет 20 назад.

Не знаю… В моем ВУЗе такие вещи описывались в программах по предмету xyz, обновлялись регулярно и лежали на сервере кафедры бери-не хочу. Нам, заочникам, было на руку.
PS 2014 год.

Меня всегда на форумах удивляла фраза: "да на кой мне этот js, есть же jq!"

"да на кой мне этот asm, есть же c++!"

Хоть это и шутка, но несогласным хочу напомнить, что ассемблер это тоже язык программирования. И если с jQuery аналогия неточная, то с каким-нибудь TypeScript вполне. jQuery можно считать аналогом CRT, без CRT тоже можно программы писать.

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

Академически — да, ассемблер это транслятор. А язык программирования называется "язык ассемблера".


Но если не придираться к словам, то слово "ассемблер" может прекрасно обозначать оба понятия.

То есть, стековый процессор и DSP чип, это один и тот же ассемблер, верно?
Язык программирования без стандарта, это не язык программирования, вам не гарантируют ни метод адресации, ни даже наличие регистров, возьмите мультиклет, к примеру с его ассемблером.
Фактически, вы пытаетесь меня убедить, что x86 ассемблер, в виду его распространённости следует считать идолом ассемблера, я с этим не согласен. Если же речь не про x86, то совершенно не понятно что вы понимаете под языком ассемблера, может быть лисп машины в чипе, которые вполне себе ассемблер, потому что хардварны?

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


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

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

Все языки можно называть ассемблерами. А любой конкретный из них будет ассемблером.

Я не буду с вами спорить, вы этой фразой очень сильно понизили планку разговора, пэтому я сомневаюсь что он вам вообще интересен. Для остальных оставлю выдержку непосредственно связанную с языками, по которой можно саморазвиватсья в данном вопросе.
Форма Бэкуса — Наура (сокр. БНФ, Бэкуса — Наура форма) — формальная система описания синтаксиса, в которой одни синтаксические категории последовательно определяются через другие категории.

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

А ещё в русском языке есть мир холодильников, которое имеет вполне понятный смысл и я не буду одёргивать человека, когда мне говорят как к этому месту пройти, но когда человек начинает мыслить категориями таких миров, сам генерируя подобный контекст, потому что смысл он не понимает, но уже все так говорят, то промолчать я не могу.
И да, писать можно и в ассемблере который имеет почти всегда встроенный редактор и для ассемблера, можно даже писать машинные коды. Если вы не слишком заморачиваетесь правилами русского языка, то можно писать в машинных когдах и на ассемблере, но «язык программирования» это конкретное понятие, которое даже не эквивалентно просто языку, до которого его сокращают, что почти всегда позволяет контекст. К чему заметка-то? Я не о правилах русского языка, я computer science, формальные грамматики, алгоритмы, языки программирования… не чувствуется связь, конекст какой-нибудь, не? И как-то страно, что алгоритм имеет определение, и язык программирования тоже и можно рассждать не в стиле, что мой дедушка так гвоорил и мне завещал?

Это разные диалекты одного языка и он разный на разных процессорах, C более стандартизован, а вариантов Бейсика — великое множество, Паскаля поменьше.


Фактически, вы пытаетесь меня убедить, что x86 ассемблер

Нет. фактически вы приписываете оппоненту свои фантазии, ибо x86 (другого не знаете?) ранее упомняут не был.

Я и машинные коды, в тетрадке в клетку, писал под z80 не имея ассемблера. Это было сказано, только что бы понять что подразумевает оппонент под своими словами. Если вам хочется перйти на личности, пишите в личку.

А я писал на языке ассемблера и в голове транслировал в машкоды — у меня был ассемблер или я им был? :) Тем не менее, в подавляющем большинстве случаев по контексту слово "ассемблер" ассоциируется вполне однозначно, уточнений "программа?", "язык?", "для какой архитектуры?", "какой диалект?" практически всегда не делаю.

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

Что не делает из языка ассемблера не язык программирования (низкоуровневый).

Читаю интернет, будем считать что спор я проиграл. Я не знаю, когда в транслятор сборщик(assembler) кода запихнули рекурсию и он стал не транслировать мнемоники собирая машинные коды, а внезмпно собирать-собираемое записанное на собираемое. Пусть будет Ассемблер ассемблера, раз уж интернет уже думает так же. Я из другого мира. Тема закрыта.

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


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

Вы пропустили словосочетание "высокого уровня"

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

Это ваше личное понимание. Может имеет какое-то отношение к языкам высокого уровня (но далеко не во всех из них есть полная абстракция от архитектуры даже в таких базовых вещах как размер целого числа), но к языкам условного среднего (C например или Forth) и низкого (машинные языки, ассемблеры) точно не относится. Лишь немногие из популярных языков высокого уровня создавались изначально с целью полностью абстрагироваться от архитектуры, да и то подавляющее большинство пошло путем спецификации виртуальной машины, в машинный язык или ассемблер которой транслируется язык высокого уровня, то есть по сути язык не абстрагирован от архитектуры машины, а наоборот, жёстко привязан к одной-единственной, просто машина виртуальная, сама абстрагирует от реального железа.

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

На разных диалектах по разному :)

Которого их?

Опишите правила «языка Бейсик».

Смысл языка программирования в возможности написания программ. Абстракция это уровень выше, и относится только языкам программирования высокого уровня, а не ко всем.


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

Даже в рамках одной архитектуры существуют ассемблеры с разным синтаксисом, например синтаксис АТ&Т вам о чём-нибудь говорит?
Кроме того, написание программ возможно и без всякого языка и транслятора, прямо в машинных когдах, смысл же языка программирования именно в синтаксисе, что вы упрямо отрицаете.
Например вики:
Язык программи́рования — формальный язык

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

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


К первому поколению (англ. first-generation programming language, 1GL) относят машинные языки — языки программирования на уровне команд процессора конкретной машины.

И нет, смысл языка программирования не в синтаксисе, а в возможности записи компьютерных программ. У русского языка есть синтаксис, но он не является языком программирования. Также, не каждый формальный язык является языком программирования.


И у любого ассемблера есть свой синтаксис. C ваших же слов:


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

В той же статье, откуда я привёл описание, написано:
Фактически, эти термины в то время не использовались.
Зато ассемблер — использовался.
Читаем дальше:
языки программирования… лучше представлять как среды разработки

Моё мнение о этой статье: писал человек который хочет систематизировать всё и вся не разбираясь в предмете. Но цитата которую привёл я — важна и не сама по себе, а в связи. Почитайте про формальные грамматики, про то, как описываются языки программирования. Вообще, я не вижу смысла в нашем споре, если вы хотите называть языком и машинные коды и IDE, это ваше право. Я очень хорошо высказал своё мнение в письмах, более подробно разжевать мою позицию уже нельзя. И думаю, что вы её прекрасно поняли.
Мне на собеседовании как-то объявили, что если я не знаю тонкости jq, я не знаю js :(

Значит не туда собеседовались, а может и туда, просто сейчас фраза не так всплыла, но, если это какая-то маломальская дизайнерская студия, то там знания jq просто обязательны, и для них это является очень большим фактором, но если при этом они сказали, что незнание библиотеки является незнанием языка, то это уже точно маломаломаломальская дизайн студия с теми, кто сам не знает js...

Значит не туда собеседовались, а может и туда, просто сейчас фраза не так всплыла

незнание библиотеки является незнанием языка

Угумсь.
Тут вон (и не только тут — регулярно) люди возмущаются, что их заставляют код на бумажке карандашом писать, без гугла и подсказок IDE. Куда не кинь — везде клин. А результат один: либо ты программист, либо погулять вышел.

Ну скажем так, код на бумашке писать — дело первых программистов, вроде Ады) А мне это тупо не удобно, но я понимаю, что мне IDE только в помощь дана, она за меня ничерта не придумает. Поэтому к таким тестам я отношусь вполне нормально. Меня больше прикалываются такие тесты:


напишите на <придуманный язык/язык, который вообще не связан с предметом собеседования> программу, выполняющую <какое-то задание>

Такие задания реально интересны и показывают насколько у тебя бошка думает, а вот тесты типа


с помощью jq вставьте 3 разных случайных числа от 6 до 21 в блоки #test, .test и третий найденный b

Вот это мрак, направленный чисто на знание библиотеки, а не оценки твоих умственных способностей.

Ну скажем так, код на бумашке писать

Это тест насколько человек способен думать самостоятельно, без подсказок. Никто тут не требует идеального решения задачи, и вообще решения :)
мрак, направленный чисто на знание библиотеки

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

Стоп, а обычно пишут на реальном коде? Я просто обычно использовал помесь python и js, ибо читаемость в python больше, а на js собеседуюсь...

Я как раз об аргументе противной стороны — «мне», мол, «в реальных условиях, IDE и компилятор подсказывать будут».
Не раз замечал, что придумываешь один алгоритм, а когда начинаешь его реализовывать, то получается несколько иначе. Иногда кардинально иначе.
И да, ИДЕ, очень сильно ускоряет написание кода и корректирует ход мыслей в правильном направлении.
Написание кода — да, но тут речь об алгоритме. Если проверяют, может ли человек составить алгоритм — да пусть хоть блок-схемы или диаграммы Несси-Шнейдермана рисует.

и корректирует ход мыслей в правильном направлении.

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

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


Я конечно преувеличиваю, но по-моему этот тест не очень показательный.

В этих тестах нет ничего, что человек не знает, и что нужно гуглить. Фактически, это именно smoke test. Если уж он пришёл на собеседование, то обязан знать и уметь :) Не раз уже обсуждалось, один из примеров, которые привожу:

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

Ну это в ваших тестах нет ничего такого. Я просто к тому, что в общем случае это утверждение не истинно. Это зависит от задачи.


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

Общий случай — это как средняя температура по больнице, ни о чём :)

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

Ну а с другой стороны, даже по отношению к такой задаче:

хитрый алгоритм обхода графа с заданными требованиями по времени и памяти

уже можно отличить специалиста (или «принцессу») от «просто погулять вышел», безо всяких гуглов :)
И не нужно понимать буквально, я не о всех же говорю, а в общей массе.
Странные варианты ответа. А где «менее чем за 10 минут»?

Справедливо. Убрал "более чем", теперь работает округление.

10 минут — большой порог, в изначальном тексте говорилось о паре минут на полное решение, лично у меня где-то так и ушло. Правда, писал на Go.

Боюсь, что многие не осознают ошибку. Судя по количеству заявленных правильных ответов. Наверно надо бы предложить задержку в 1 секунду.

Each print must be asynchronous call console.log function with a 50ms delay.

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

Да, я уже понял — тынц

Хуже того, там не сказано, должна ли быть задержка перед первым принтом.

именно

Все равно не вижу проблем.


[...Array(100)].map((_, i) => i+1).reduce((x, y) => x.then(() => new Promise(resolve => {
    if (y % 3 == 0 && y % 5 == 0) console.log("MissKiss");
    else if (y % 3 == 0) console.log("Miss");
    else if (y % 5 == 0) console.log("Kiss");
    else console.log(y);
    setTimeout(resolve, 50);
})), Promise.resolve())

Написал за 2 минуты без гугла, причем большая часть времени ушла на постоянные взгляды в условие на английском. Можно и понятнее написать — но это уже не на время.

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

А кто вам сказал что я всегда пишу в таком стиле?


У этой задачи есть 4 решения.


  1. Через async/await
  2. Через библиотеку async
  3. Через рекурсию
  4. Через reduce

Первые два — понятные и красивые, но первое требует babel или tcs для старых браузеров, а второе — отдельной библиотеки. Подключать их дольше, чем писать решение.


Варианты 3 и 4 — одинаково ужасны, но не требуют дополнительных инструментов.


PS кстати, прочтите решение еще раз. Там вообще-то есть декомпозиция.

А ещё можно через SetIntverval и замыкание труЪ-олдскул стиле…

Покажите пример кода, пожалуйста!

!function() {
  var n = 0;
  var interval = setInterval(function() {
      if (n++ == 100) return clearInterval(interval);

      // ...

      console.log(...);
  }, 50);
}()
Самое смешное, что это вообще единственный вариант, который таки решает грёбаную задачу полностью, как ожидалось.
Задержка 50мс для 100 элементов как бы неявно предполагает, что последняя надпись будет выведена через 5 секунд (5000 миллисекунд), плюс-минус точность таймеров операционной системы.
И это только setInterval.
Во-первых, setTImeout на 50 мс вызывается не ранее, чем через 50 мс, но чаще — более.
Во-вторых, если мы не под QNX сидим, у нас практически никогда ОС не выдаст событие таймера ровно через 50 мс. В винде по умолчанию например таймер тикает 64 раза в секунду, это 15.6мс в каждом тике. Т.е. в случае setTimeout на 50 вы будете получать в реальности один тик каждые 62 милисекунды. Нефиговая такая погрешность в 24%, не так ли?
Ну дальше ещё браузер своё откушает (ему нужно самому интерфейс перерисовать, анимации всякие покрутить, сборщик мусора запустить), потом запустит event loop для вашего скрипта, и только потом дойдёт до собственно вашего обработчика.
Так что любой код на setTimeout будет выполнятся секунд 7 вместо 5.

Это все от задачи зависит. Например, если задержка является эмуляцией сетевого запроса — то только новый setTimeout после предыдущего будет корректным.

Проверьте в хроме, плиз.

function kissMiss(){
  for(let i = 1, t=50; i<=100; i++, t+=50) {
    setTimeout(()=>{
		let  s = '';
		s = !(i%3) ? 'Miss': '';
		s += !(i%5) ? 'Kiss': '';
		s = s ? s : i;
		console.log(t +' >> '+s);		
	},t);
  }
}
А что проверяем-то? То что хром умеет к переменной 50 прибавлять?
Наверно вот такой код имелся ввиду:

function kissMiss(){
   let startTime = new Date();
  for(let i = 1, t=50; i<=100; i++, t+=50) {
    setTimeout(()=>{
		let  s = '';
		s = !(i%3) ? 'Miss': '';
		s += !(i%5) ? 'Kiss': '';
		s = s ? s : i;
		console.log((new Date() - startTime) + ' >> ' + t +' >> '+s);		
	},t);
  }
}


Но по большому счеты, эксперимент показывает что setTimeout вполне подходит, у меня в хроме ровно 50мс между вызовами, хотя до первого чуть-больше.
А что проверяем-то? То что хром умеет к переменной 50 прибавлять?

Да не, это я ступил. Сорри. Хром сам умеет выводить таймштамп перед логами. https://www.screencast.com/t/Wj4Wedqfrh
Я уже настолько привык к этой фиче, что забыл, что это не настройка по умолчанию.
А что такого ужасного в рекурсии?

Вроде бы короткий и понятный код
function PrintRangeWithDelay( begin, end, delay ){
    var recursion = function( current ){
        if( current > end ) return;
        setTimeout( function( ){
            var miss = "";
            var print = "" + current;
            if( current % 3 === 0 ) print = miss = "Miss";
            if( current % 5 === 0 ) print = miss + "Kiss";
            console.log( print );
            recursion( ++current );
        }, delay );
    };
    recursion(begin);
}

PrintRangeWithDelay( 1, 100 ,50 );


И за счёт setTimeout стек не забивается.

Мой код настолько же понятен. И точно так же не забивает стек.


Но цикл через await все равно понятнее.

Так я же и не говорил, что ваш код чем-то плох. По поводу стека написал просто потому, что забивание стека это «классический» недостаток рекурсии. А в данном случае этого недостатка нет.
Извините, но я не понимаю причем тут таймер(/задержка), если в задачи про него ничего не написано?
Напишите программу, которая печатает числа от 1 до 100. Но для кратных трём значений «Fizz» вместо номера и для кратных пяти «Buzz». Для чисел, одновременно кратных трём и пяти — «FizzBuzz»


Это я решил на добром С++
main()
{
  for(int i=0;i<100;i++)
  {
  if(i/3%10 == 0)
    if(i/5%10 == 0)
      cin<<"FizzBuzz"<<endl;
    else
      cin<<"Fizz";
  else 
    if(i/5%10 == 0) cin<<"Buzz"<<endl;
    else 
      cin<<i<<endl;
  }
  system("pause");
}

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

Ваш си++ слишком уж добр. Это не компилируется, во-первых у функции мейн должен быть возвращаемый тип int, во-вторых нет инклюдов, в третьих — cin служит для ввода информации, для вывода cout.
Теперь по более серьезному — i / 3 % 10 это вообще что у вас? Проверка делится ли (i/3) без остатка на 10? А зачем? В задаче нужно проверить делится ли i без остатка на 3 и на 5, то есть i % 3 == 0 было бы достаточно.

system(«pause») — си++ он может запускаться на разных платформах но этой строкой кода вы намерство прибили программу к винде.
этой строкой кода

Насколько я понимаю, её наличие — отличительная черта студентов, которые с C++ знакомы исключительно по копипасте лекций (по которым system(«pause») проходит красной нитью из года в год, из вуза в вуз).

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


Да, обычно это студенты или школьники. Но не обязательно.

Часть ещё используют getc/gets, тут от препода зависит, видимо. Мало у кого видел, чтобы этого не было вообще. Видимо, не осиливают в vs поставить соответствующую галочку, чтобы терминал не закрывался автоматически.

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

Нет конечно, с чего бы?

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


Если вы запускаете программу из командной строки, то процесс командной строки (cmd.exe) остается привязан к консольному окну пока вы не напишете команду exit.

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

Алгоритм там как раз самый оптимальный, хоть это и экономия на спичках.

Почему? Почему бы сначала не проверить на делимость на 3, а потом — на 5 (или наоборот, смотря в каком порядке fizzbuzz выводить)?

Так он же так и проверяет...

Ну в Vs2005, на котором нас обучали на первых порах, мы работали через void main(), препод все боялся и не давал нам сложные материалы чтоб не было глупых вопросов, но сейчас я понимаю что будь по другому, я бы не словил минуса. Когда уже начали изучать MFC уже перешли на новые визуалки а там и не смотрели как там был стандартно инициализирован main. Только сейчас заметил что перед main() у меня ничего не стоит… торопился.
На счет инклюдов думал и решился их не писать. А с cin/cout дырявая башка, дай пирожка, вечно путаю.
Про i/3%10, что первым пришло в голову, опыта не хватило додуматься.
system(«pause») то же самое что и выше, можно конечно с getchar().
А с кроссплатформенностью никогда не встречался, вот и не задумываюсь перед тем использовать одно или другое. Всю жизнь на винде, так и помру с ней.
Могу сказать только спасибо, иначе даже сам не смог бы понять с чего так заминусовали.

Проблема вашего кода — не в void main, а в том, что тип вообще не написан.

В сообщений написано что я это уже поздно заметил
новые визуалки а там и не смотрели как там был стандартно инициализирован main

В продолжение соседней ветки комментариев: написание кода «на бумажке» как раз и позволяет отличить программистов от тех, за которых «визуалка» думает :)
А с кроссплатформенностью никогда не встречался
Тут дело даже не в кросплатформенности. Есть, например, знание языка C, а есть «умение писать на С под Windows». Есть умение думать, а есть умение мышевозить в каком-нибудь билдере или что там сейчас. Это совершенно разные вещи, и все они нужны. Но второе в обоих случаях — не программирование.
Ну, а я полез на VB6 такое писать.)) Сейчас и мне минусов подкинут.

Особенно, если после десятка-другого человек, прочитав комментарии и т. п., не осилите прочитать условие.

куда лучше юзать Array.from => Array.from({length: 100}, (_, i) => i + 1)…
Ну и вообще изучить синтаксис async/await

Cинтаксис async/await не работает в старых браузерах, а babel подключать — дольше, чем решать задачу.


Array.from делает абсолютно то же самое, что и spread operator.

Ну тот факт что не нужен лишний map ну и еще пару нюансов

Не понял за что вас заминусили, спасибо за идею с reduce и [...Array(n)]

Но ваш код не идеален. Тут достаточно двух условий

А задачи писать идеальный код и не стояло.

Смотрю и не понимаю (с JS ушел полностью на Javu лет 15 назад и эти новомодности не застал) — а зачем городить огород с массивам/мапами и прочем? Че просто не пробежать for-ом, с тремя if-ами в нем?..

В простой цикл на js нельзя включить задержку (в версиях языка до ES2017).

… зато можно синхронно повесить 100 setTimeout с задержкой i*50. Не айс, конечно, но технически можно.

Да, для этой задачи это тоже правильное решение будет.

А оно надо? У меня ушло 4:20 как раз на вот это:


let q = v => new Promise(resolve => setTimeout(() => 
    { 
        console.log(v); 
        resolve(); 
    }, 50));
let p = Promise.resolve();

for(let i = 1; i <= 100; ++ i)
{
    let msg = i;
    if(i % 3 === 0 && i % 5 === 0) msg = 'MissKiss';
        else if (i % 3 === 0) msg = 'Miss';
            else if (i % 5 === 0) msg = 'Kiss';
    p = p.then(() => q(msg));
}

На красоту и оптимальность не претендую. Писал на скорую руку прямо в отладчике. Но тут как раз простой цикл.

Ваше решение почти такое как у меня, вся разница — только в месте вычисления строки для вывода.

И создавать строчку каждый раз необязательно

НЛО прилетело и опубликовало эту надпись здесь
Вы не читаете ветку?)
y % 3 == 0 && y % 5 == 0 эквивалентно y % 15 == 0

Вообще ненужно

Нет, математику прогуливал интерпретатор. Если посмотреть бенчмарк — то становится видно, что в Хроме условие y % 3 == 0 && y % 5 == 0 работает быстрее чем y % 15 == 0!

Кстати, почему так? Оптимизатор/кеш выносит за блок условий результаты «y % 3 == 0» и «y % 5 == 0» и второй раз это не считает? Тогда где у вас «типо» 4 проверки на самом деле их 3. И третья совсем крошечная "&&"

Скорее всего так и есть.

Таки менее 10 минут. Результат идентичен, но я в процессе использовал массив который быстро наполнил, а потом выводил сдвигая указатель на начало пока он не кончился. В ответе решение с разновидностью «генератора» что лучше.

Покажите код, пожалуйста. Интересно же!

Вот тут есть одна реализация.
Но для кратных трех значений «Fizz» вместо номера и для кратных пяти «Buzz».
Написано по-русски, но совершенно непонятно. Я бы тоже, пожалуй, не смог решить задачу, если бы условие выглядело таким образом.

Купить палку колбасы, если будут яйца — купить десяток

А потом эти недопрограммисты идут на хабр и сливают карму адекватным людям.

Потому задание оставил на английском. Знаю, что переводчик из меня никакой.

«Между» применено не к месту. Должно быть что-то вроде «Как и X, Y, Z, я начинаю немного волноваться»

3 минуты. В правильном варианте принты хоть и асинхронные, но последовательные, я делал параллельные — это считается надеюсь?

Покажите код, пожалуйста. Интересно же!

Думаю. почти как мой.
for (let i = 1; i <= 100; i++) {
	let print = '';
	if (i % 3 == 0)  {
		print = 'Miss';
	}
	if (i % 5 == 0)  {
		print += 'Kiss';
	}
	if (!print) {
		print = i;
	}
	(function(text){
		setTimeout(function(){
			console.log(text);
		}, 50 * i);
	})(print);
}
я тоже параллельные делал, вот решение:
for (var i = 1; i <= 100; i++) {
  if (i % 3 === 0 && i % 5 === 0) {  
    setTimeout(print('miss kiss'), 1000);	   
  } else if (i % 3 === 0) {
    setTimeout(print('miss'), 1000);   
  } else if (i % 5 === 0) {
    setTimeout(print('kiss'), 1000);   
  } else {
    setTimeout(print(i), 1000);
  }	
}    

function print(str) {
  return function() {
    console.log(str);
  }
}

Они не параллельные, они последовательные, просто не упорядоченные.

for (let i = 1; i <= 100; i++) {
  setTimeout(() => { 
    var r = ""; 
    r += i % 3 == 0 ? "Miss" : "";
    r += i % 5 == 0 ? "Kiss" : "";
    r = (r.length == 0) ? i : r;
    console.log(r); 
  }, 50);
} 
Хм… был уверен, что при таком коде во всех вызовах i=101, но как оказалось, если i объявлен через let, а не var, то замыкается его текущее значение.
Я ещё не привык рассчитывать на ES6, поэтому по привычке написал костыль для этой темы:

function printNum(num) {
    if (num % 3 == 0 && num % 5 == 0) {
        console.log("MissKiss");
    } else if (num % 3 == 0) {
        console.log("Miss");
    } else if (num % 5 == 0) {
        console.log("Kiss");
    } else {
        console.log(num);
    }
}

function makePrintNum(i) {
    return function () {
        printNum(i);
    }
}

for (var i = 1; i <= 100; i++) {
    setTimeout(makePrintNum(i), i * 50);
}

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

Each print must be asynchronous call console.log function with a 50ms delay

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

Да, убедительно.

Аналогично.

Более того (ИМХО) решение автора не удовлетворяет условию в том виде, как он его трактует.

В его случае задержка также должна быть уменьшена время выполнения кода предыдущего шага.
В текущем примере это слабо заметно, но, думается мне, что если поставить «Number.MAX_SAFE_INTEGER» вместо 100, то можно будет увидеть, что время между первым и последним выводом будет не Number.MAX_SAFE_INTEGER*50, а на несколько миллисекунд больше.
А вот и мой код
function ExecR(i) {
        var wrtext = "";
        if (i % 3 == 0) wrtext = "Miss";
        if (i % 5 == 0) wrtext += "Kiss";
        if (wrtext == "") wrtext = i;
        console.log(wrtext);
        if (i < 100) window.setTimeout(function () { ExecR(i + 1); }, 50);
    }
ExecR(0);
Согласен, условие по поводу асинхронности вывода сформулировано двояко, я тоже так понял.
But for multiples of three print «Miss» instead of the number and for the multiples of five print «Kiss»
т.е. кратное 3 = Miss
кратное 5 = Kiss
А у вас по ссылке (n % 3 === 0)? 'Kiss'
т.е. 99 = Kiss, 100 = Miss

Итого, решение не правильно (не соответствует условию). И за сколько в итоге вы решили? (Если это ваше решение)
Признаюсь, что у меня ушло 67 минут, применяя гугление
На тот момент когда я смотрел, решение по ссылке
было
(function fn(n) {
if (n <= 100) setTimeout(() => {
let s = (n % 3 === 0)? 'Kiss': '';
if (n % 5 === 0) {
s += 'Miss';
} else if (s === '') {
s = n;
}
console.log(s);
fn(++n);
}, 50);
})(1);

Т.е. задача еще не решена (решена не правильно), и время значит еще идет.

Гы-гы. Спасибо! Исправил.

Не подумайте что я придираюсь. Просто решил задачу, сверил результат. Не совпадает.
Начал искать ошибку. Не у меня.

Всё правильно. Это как на выпускном экзамене в школе. Один из класса выполнил все пять задач, но допустил арифметическую ошибку. В итоге все равно оценка 4.

Написал на VBA (под рукой)
код
Sub main()
Dim i As Integer


        For i = 1 To 100
            If (i Mod 3 = 0) Or (i Mod 5 = 0) Or (i Mod 15 = 0) Then
                If i Mod 15 = 0 Then
                    Debug.Print "KISSMISS"
                    GoTo Line1
                End If
                If i Mod 3 = 0 Then
                    Debug.Print "KISS"
                    GoTo Line1
                End If
                 If i Mod 5 = 0 Then
                    Debug.Print "MISS"
                    GoTo Line1
                End If
                
            End If
            Debug.Print i
Line1:  Next

End Sub




За 2-3 минуты. Что здесь не так? (я не настоящий сварщик, но готов учиться на ошибках)
Как минимум, не то, то, что все условия проверяются дважды. Не то то, что условие дележа на 15 вынесено отдельно, хотя этот случай решается сам собой — просто два последовательных вызова.
Ошибка что не на JavaScript. ) Автор задачи хочет подловить испытуемого на задержке вывода значения. При неправильном коде это приведет к тому что последнее значение переменной выведется на экран 100 раз.

Это если со скоупами напутать...

Простите, но где здесь:
Write a program that prints into console the numbers from 1 to 100. But for multiples of three print «Miss» instead of the number and for the multiples of five print «Kiss». For numbers which are multiples of both three and five print «MissKiss». Each print must be asynchronous call console.log function with a 50ms delay.
Хоть слово про JavaScript?
Видимо, console.log function подразумевает
Это есть только в javascript? И вообще этот метод относиться к стандартной библиотеке js?

В javascript и языках на его основе. Само название метода несет в себе наследие браузера, где консоль — нечто опциональное. В языках, которые начинали как языки системного программирования такой метод не может называться log, он будет называться write или print :-)


Да, он относится к стандартной библиотеке.

Тестовое задание должно быть сформулировано максимально чётко.
И должно «подразумевать» подобным образом минимальное количество ограничений.
В противном случае, это просто неуважение к кандидату.

Я думаю, конкретно это задание было придумано для проверки именно js-разработчиков. Т.е. язык программирования не попал в цитату потому что уже был указан в наименовании вакансии.

Скорее всего. И я прекрасно понимаю, где именно здесь разложена «засада» по сравнению с оригинальным «FizzBuzz». Более того, я допускаю, что такие задачи могут быть полезны при собеседовании юниоров, но… получив такую задачу (например на собеседовании) без соответствующего уточнения, я оставляю за собой право решать её на любом языке. Например на C# или на Lisp-е или на чём-то ещё более экзотическом. В результате, вполне может получиться как здесь. И это будет даже не сознательный троллинг, а просто защитная реакция.

Вы невнимательно прочитали задание. Только и всего. "Предлагаю решить задачу на JavaScript".

Я читал постановку задачи на английском. Несколько раз и очень внимательно.
Предлагаю закончить эту дискуссию.

Строго говоря, это можно считать методом стандартной библиотеки в современных браузерах и nodejs. Например, в IE <= 9 console.log не отпределён (undefined) пока не открыты dev tools.


Другой стандартный пример js без console.log:


-> % jjs
jjs> console.log("test");
<shell>:1 ReferenceError: "console" is not defined
jjs>
Не смог распознать сарказм, поэтому
1. GoTo
2. Лишние проверки
3. Нет асинхронности и задержки
Перевод ужасен, извините.
Автором, которого он имеет в виду, является Имрана Гхори

который, очевидно, отворачивается от многих программистов

люди, которые борются за код,

самопровозглашенные старшие программисты

терпит неудачу во время интервью

их просят выполнить основные задачи программирования

не могут запрограммировать свой путь из бумажного мешка.

кто пишет программное обеспечение для жизни.


и так далее и тому подобное
Перевод ужасен, извините.

Знаю :( Я совсем не переводчик. Очень впечатлила статья. Не мог удержаться.

Судя по переводу, вы под впечатлением не особо поняли даже её текст.

Как любят повторять в одной конторе, где мне посчастливилось трудиться: критикуешь-предлагай.

критикуешь-предлагай


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

люди, которые борются за код

«struggle to code» — испытывают проблемы с написанием кода
Они борются с крошечными проблемами

«They struggle with tiny problems» — испытывают проблемы с решением крошечных задачек
терпит неудачу во время интервью

«fail (during interview) when asked to carry out basic programming tasks» — Не справляются, кода их просят решить простейшие задачи (на собеседовании)
Я более чем готов сократить ограничения

«I'm more than willing to cut freshly minted software developers slack at the beginning of their career» — Я более чем готов (пойти на уступки / дать поблажки) новоиспеченным программистам на старте их карьеры.

Большое спасибо. Внёс правки. Рассчитываю на вашу помощь в дальнейшем.

а я вот только что решил потыкать англоязычные ссылки и был весьма удивлен, что вся статья базируется на статьях 2005-2007 годов
очень странный временной откат в статье на злободневную тему, вероятность достоверности данных низкая

Есть 1 ссылка на статью 2014 и одна на 2016 год :D

При желании можно интерпретировать результаты опроса, что за прошедшие 10 лет уровень программистов вырос. :)

самопровозглашенные старшие программисты

Тут все верно — в оригинале так же self-proclaimed. Ну, «старшие» некий аналог Senior, допустимый по контексту, кмк.
«Самопровозглашенный» в русском языке почти исключительно про государства. Имеется в виду, что старшие программисты сами себя так называют, но на деле старшими не являются.
То есть «так называемые старшие программисты» или «люди, которые называли себя старшими программистами» или что-то более изящное. Но «Самопровозглашенные» не пойдет.

Спасибо, поправил: "кандидаты на старшего программиста".

Это тоже неверно, даже более неверно, чем предыдущий вариант. Смысл именно в том, что эти люди объявили себя старшими сами. «Кандидаты» — совсем иное.

Как лучше?

Самоназванный или самозванец
кандидаты, подававшие резюме на вакансию «Senior developer»

подсмотрел тут

Вы подсмотрели неправильный перевод. Самопровозглашённые было гораздо лучше, потому что верно отражало смысл. Зря вы его убрали :)

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

Официально — да, но по смыслу подходит замечательно — все то же самое «сам себя назначил». Будь то монарх, государство, или что-то еще, такое же патетическое. Как по мне, такое легкое косноязычие проходит как pun, именно так я воспринял эти слова в переводе.
Не, в переводе лучше либо придумать изящную формулировку, выражающую иронию по отношению к «старшим» программистам, либо уж передавать смысл.
Впрочем, окей, если бы это была единственная проблема с переводом — сошло бы за немного тяжеловесный каламбур.

Ну "самопровозглашенный" по отношению к людям, а не государствам и звучит как ирония, разве нет?

Именно так! Даже если это вышло случайно, получилась микро-шутка, так что — к месту.
Как фигура речи и «самопровозглашенные» неплохо выглядит. А так вообще, вполне подойдет слово «самозванцы».
Самозванцы тоже мимо. Это про царей. И вообще, одним из умений хорошего программиста является умение понимать нечёткие техзадания или «хотелки». Особенно для самостоятельных, работающих без аналитического отдела. Так что умение работать с нечеткими формулировками я бы отдельно оценивал.

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

5 минут на решение. Мне 17 на работу возьмёте? :) Эти задачи может решить любой школьник просто почитав w3schools до конца. Если это единственное препятствие на собеседовании (нет последующих этапов) то набёрете много новичков.

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

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

Писал в консоли хрома, поэтому не пугайтесь форматирования, у него жутко неудобно писать несколько строк.
Это «синхронный» вариант. Минут 5 и то из-за того, что копировал эти Kiss/Miss из задания.

let n = 1;
let interval = setInterval(() => {
if (n % 3 == 0 && n % 5 == 0) {console.log('MissKiss');}
else if (n % 3 == 0) {console.log('Kiss');}
else if (n % 5 == 0) {console.log('Miss')}
else {console.log(n)};
n++;

if (n == 101) {clearInterval(interval)}
}, 50);


Но вообще странно, где он берет 99 «программистов», которые не могут вообще ничего написать на это задание.

Строго говоря, вы не решили задачу, как и я. Мы вместе допустили ошибки на этапе знакомства с задачей (у меня было перепутано Kiss и Miss).

После прочтения задания в голове уже сложилась картина решения и кода, написал на листке бумаги, потом сравнил с Вашим примером, отличие только в том что Вы написали на новом ECMA, ну и реализаций можно было бы придумать даже несколько вариантов (но это уже так для интереса).
Спасибо за статью!
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
OS-free version, да :-) (BTW, через xlat оно проще было бы в print_one_num)
	pusha
	xor ah, ah
	mov dl, al
	mov cl, 15
	div cl

Ну что ты будешь делать, а...?

Да, пофейлил тест :(

Fixed :3

js знаю поверхностно
поэтому без всяких let и функций


var i, a, b;
for (i=1; i<101; i++) {
a=i % 3;
b=i % 5;
if (a==0 && b==0) {
console.log('MissKiss');
} else if (a==0) {
console.log('Miss');
} else if (b==0) {
console.log('Kiss');
} else {
console.log(i);
}}

И это неправильный ответ :)

И что тут неправильного? Если вы про


Each print must be asynchronous call console.log function with a 50ms delay.

, то я как бы и не владею полноценно js
Это уже нюанс, на решение которого надо потратить еще чуток времени

Ну нельзя же быть наполовину беременной, например.

соглашусь, но.


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

Проблема не в том, что программисты не справляются с задачей — а в том что "не программисты" приходят на собеседования на должности программистов и иногда даже их принимают.

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

Где вы в тексте данной статьи нашли про 50см?

про 50 см нигде, про 50 мс — в задании

Где-то в конце десятых пропал термин кодер. Остался только негативный термин говнокодер или быдлокодер.
Все стали программистами — 1с-программистами, css-программистами, html-программистами.
Прочитал первые 10 страниц книги по программированию, и уже программист.
Мало того, я считаю 90% текущих программистов отнести к кодерам.
А кодеру незазорно не смочь создать решение.

Квалификация "программист" присваивается выпускникам ПТУ согласно действующим нормативным документам.

Пора вводить понятие категорий.
Инженер корпоративных систем 3 разряда.
Инженер веб-решений 7 разряда.
И прочее.

В нормативных документах категории есть :)

Даже стало интересно, дайте ссылочку, если не трудно.
Смотрите по слову ОКПДТР. Интересно, что классификатор допускает такие должности, как «пятый помощник программиста», «участковый программист», «районный программист» и «горный программист» :)

Человека, который не сумел написать FizzBuzz, нельзя отнести даже к кодерам.

Кодер пишет то, что ему скажут и так, как ему скажут. Решением задачи, а тем более оптимизацией решения занимается программист.

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

Правда ваша.

В том-то и вопрос, что масса програмистов учили и умеют синхронный код программировать. Почему так мало смыслят в асинхронное программирование на бумаге — вот это совсем другая тема и как-то не очень корректно путать топлое с мягким.

FizzBuzz.py (нужно только расставить отступы согласно вложенности):
for i in range(1,101,1):
if i % 3 == 0 and i % 5 == 0:
print("FizzBuzz");
elif i % 3 == 0:
print("Fizz");
elif i % 5 == 0:
print("Buzz");
else:
print(i);

Вот как вы думаете, это задание написано криво и моё решение имеет право на жизнь, или я дурак?
for(var i=1; i<=100; ++i){
    var s = '';
    if(i%3==0){
	s = 'Miss';
    }
    if(i%5==0){
	s = s+'Kiss';
    }
    if(s=='') s = i;
    setTimeout(( function(){ var x = s; return function(){ console.log(x) }})(), 51);
}


Вишенкой на торте задержка в 51мс, потому что когда я полез смотреть решение сразу увидел строку
// Боюсь, что многие не осознают ошибку. Судя по количеству заявленных правильных ответов. Попробуйте изменить задержку на 1 секунду.

и недоумевая таки изменил её на 1 секунду, после чего уже прочёл решение

Попробуйте изменить на 1000 мс. Ваш вариант выплевывает в консоль все ответы сразу.

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

Правильное окончание задания звучало бы как «между выводами чисел должна быть не блокирующая задержка в 50 мс»
Где в тесте статьи есть про 50мс?
Задержка должна быть между шагами вывода, а не перед выплевыванием.

Вместо var x=s; можно было бы перед s написать let, а не var и использовать s на вывод. :)
setTimeout измеряет задержки в миллисекундах, потому у вас получилось увеличить задержку только на 1 миллисекунду
Мысленно представил, как сделал бы на шарпе через пару условий или свитчей, но подумал, что это, наверное, костыльно и есть способы лаконичнее, однако в ответе именно такой. Думаю, за пару минут не уложился бы, но за 10 вполне.

Не поленился и накарябал, не подглядывая в жс, в 10 минут уложился.
Заголовок спойлера
var range = Enumerable.Range(1, 100);

foreach (var item in range)
{
    if (item % 3 == 0 && item % 5 == 0)
    {
        Console.WriteLine("FizzBuzz");
    }

    if (item % 3 == 0)
    {
        Console.WriteLine("Fizz");
    }

    if (item % 5 == 0)
    {
         Console.WriteLine("Buzz");
    }

    else
    {
        Console.WriteLine(item);
    }
}


continue; после каждого ифа забыл… А тут еще и задержка какая-то всплыла. В общем прошу считать вышенаписанный камент недействительным и вообще меня тут не было.

Ну, на шарпе задержка как раз не проблема. Можно хоть Thread.Sleep, хоть await Task.Delay использовать.


Вот на старых версиях js необходимость задержки полностью перекореживает код.

Аналогично, зашел сначала с шарпа. Минут пять потратил. Если я правильно понял про асинхронность, то мой вариант ниже:

   static void Main(string[] args)
        {
            for (int i = 0; i <= 100; i++)
            {
                string s = "";
                if (IsDivisableBy(i, 3))
                {
                    s += "Kiss";
                }
                if (IsDivisableBy(i, 5))
                {
                    s += "Miss";
                }
                if (s.Length == 0)
                {
                    s = i.ToString();
                }
                PrintAsync(s);
                Thread.Sleep(50);
            }

            Console.ReadKey();
        
        }

        static bool IsDivisableBy(int sourceNum, int divisor)
        {
            return ((sourceNum % divisor) == 0) ? true : false;
        }

        static async void PrintAsync(string s)
        {
            await Task.Run(() => Console.WriteLine(s));
        }

Зачем, ну зачем IsDivisableBy? Что оно делает?


Это на тут случай если кто-то не знает что в шарпе делает оператор %?


Не говорю уже про ? true : false;...

Написать
s += ((i % 3) == 0) ? "Kiss" : "";

слишком просто :))
В принципе, всё делалось ряди погони за удобочитаемостью. Не меняя времени, затраченного на решение, можно было добавить сахарку за счет extension method для int:

        public static bool IsDivisableBy(this int source, int divisor)
        {
            return ((source % divisor) == 0 ? true : false);
        }

тогда тело цикла было бы как раз более читаемо с применением ?:
                string s = "";
                s += (i.IsDivisableBy(3) ? "Kiss" : "");
                s += (i.IsDivisableBy(5) ? "Miss" : "");
                if (s.Length==0)
                {
                    s = i.ToString();
                }

Почему вы в таком случае пишите s += ..., а не s = string.Concat(s, ...)?

Ну можно и через concat(), согласен :)
Ещё больше «сахара»:
public static IEnumerable<string> Names(this int index)
{
   if (index.IsDivisableBy(3))
      yield return "Kiss";
   if (index.IsDivisableBy(5))
      yield return "Miss";
}

string s = string.Concat(i.Names());
if (s.Length == 0)
// ...

Вы правда считаете такое хорошим кодом — или издеваетесь?

Тут вроде про код кажущийся чем-то сложным ветка, а не про элегантное решение в 3 строки.

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

Речь, скорее, о демонстрации на данном примере из собеседования, что кроме решения непосредственно задачи можно ещё показать умение пользоваться методами расширения, yield return'ом и async/await.
Ясное дело, что решение с минимальным читаемым кодом — это про другое.

Нет. Задачи класса FizzBuzz проверяют именно тот факт, что вы в принципе в состоянии писать код и держать при этом простой код простым.


Написание FizzBuzzEnterpriseEdition на собеседовании будет провалом.

"Если бы я нанимал программиста" :), я бы сто пудов предпочёл того, кто не будет усложнять простое. Ибо нужен человек, который решает задачи за минимальную цену, а не "изображает из себя профессионала" (намеренное усложнение простой задачи вряд ли можно назвать иначе). Профессионал способен дозировать усилие (умное слово YAGNI).

Уже скидывали тут решеньеце этой задачки на реально сложном и не понятном...

А вам про что в посте написали? Не верите? Ну вот оно… теже яйца, только в профиль

class Program
    {
        static async Task FizzBazz()
        {
            for (var i = 1; i < 101; i++)
            {
                await Task.Delay(50);
                switch ((i % 3, i % 5))
                {
                    case var t when t.Item1 == 0 && t.Item2 == 0:
                        Console.WriteLine("MissKiss");
                        break;
                    case var t when t.Item1 == 0:
                        Console.WriteLine("Miss");
                        break;
                    case var t when t.Item2 == 0:
                        Console.WriteLine("Kiss");
                        break;
                    default:
                        Console.WriteLine(i);
                        break;
                }
            }
        }

        static void Main(string[] args)
        {
            FizzBazz().Wait();
            Console.ReadKey();
        }
    }


Так вроде проще.
Хоть и не жабаскриптер, но можно else if превратить вот в такую конструкцию:

if (n % 5 === 0) {
s += 'Kiss';
}
console.log((s==='')? n: s);
Циклом правильную задержку не сделать, рекурсией элементарно решается
const delay = 50, f = function _f(i) {
	if (i > 100) return;
	setTimeout(() => {
		let s = '';
		if (i % 3 === 0) s += 'Miss';
		if (i % 5 === 0) s += 'Kiss';
		console.log(s ? s : i);
		_f(++i);
	}, delay);
};
f(1);
Это уже было на Хабре: https://habrahabr.ru/post/298134/
Любителям однострочников:
for (let i = 1, s = ''; i < 101; i++) (s = (i % 3 ? '' : 'Miss') + (i % 5 ? '' : 'Kiss')) && setTimeout(function() { console.log(s); }, 50 * i);
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Сначала сделал через setTimeout 50, потом прочитал, что это неправильно, перепугался и сделал через промисы.


var printOne = (i) => new Promise((resolve) => setTimeout(() => {
  if (i % 3 === 0 && i % 5 === 0) {
    console.log('MissKiss')
  } else if (i % 3 === 0) {
    console.log('Miss')
  } else if (i % 5 === 0) {
    console.log('Kiss')
  } else {
    console.log(i)
  }
  resolve();
}, 50));

var printIteration = (i) => {
  if (++i > 100) return;
  return printOne(i)
    .then(() => printIteration(i));
}

printIteration(0);

Может отредактировать условие задачи чтобы сразу было понятно что они должны друг за другом следовать по 50 мс, а не просто "каждый console.log — асинхронный через 50мс"?

LOL


(timeout => new Promise(async res => {
    for (let i = 1; i <= 100; i += 1) {
        await new Promise(cb => setTimeout(cb, timeout));

        if (!(i % 5) && !(i % 3)) {
            console.log('MissKiss');
        } else if (!(i % 5)) {
            console.log('Kiss');
        } else if (!(i % 3)) {
            console.log('Miss');
        } else {
            console.log(i);
        }
    }
    res();
}))(50);

Внешний Promise у вас — лишний, достаточно было (async timeout => ... )(50)

Действительно, спасибо
Пока не привык до конца к async/await
Более оптимальный код, плюс уточнил по условию, что console.log должен быть вызван асинхронно


(async timeout => {
    for (let i = 1; i <= 100; i += 1) {
        const log = async str => new Promise(cb => setTimeout(() => {
            console.log(str);
            cb();
        }, timeout));

        if (!(i % 5) && !(i % 3)) {
            await log('MissKiss');
        } else if (!(i % 5)) {
            await log('Kiss');
        } else if (!(i % 3)) {
            await log('Miss');
        } else {
            await log(i);
        }
    }
})(50);

А теперь async лишний :-)

Чорт %) Пора отдохнуть )


(async timeout => {
    for (let i = 1; i <= 100; i += 1) {
        const log = str => new Promise(cb => setTimeout(() => {
            console.log(str);
            cb();
        }, timeout));

        if (!(i % 5) && !(i % 3)) {
            await log('MissKiss');
        } else if (!(i % 5)) {
            await log('Kiss');
        } else if (!(i % 3)) {
            await log('Miss');
        } else {
            await log(i);
        }
    }
})(50);

Пожалуйста, поясните причину минусов, а то я не понимаю что я сказал не так.

Each print must be asynchronous call console.log function with a 50ms delay.

У меня вот на это уйдет большая часть времени. Более, того, я даю 100% гарантию, что не напишу такое на собеседовании, так как:


  1. Во многих языках работа с асинхронными вызовами не такая простая. Привет от python 3.4, например.
  2. Зачем?

Потому что в этой задаче console.log заменяет собой асинхронный вызов. Вы не верите, что в реальной работе вам однажды понадобится сделать подряд 100 асинхронных вызовов?

Ну так и надо взять библиотеку, это правильное решение (одно из)! А не заявлять, что задача слишком сложная и ее не получится написать на собеседовании.

  1. Я сказал, что задача сложная для тех, кто не работает в языках, в которых асинхронные вызовы приняты. Давайте я вам предложу решить эту задачу на python 3.4 или, например, на Free Pascal?
  2. Обычно выбор библиотеки от проекта к проекте отличается, и какой смысл предлагать человеку сделать то, что он 100% не будет использовать ни на вашем проекте, ни вполне возможно, на других, а потом говорить "ну… это похоже на реальную задачу". В какой реальной задаче мне нужно будет самому написать такой код?


  3. Касательно библиотек. Внезапно, но я довольно часто не помню синтаксис, команды и прочее для библиотек, которые использую редко. Более того, я часто могу не помнить, как та или иная функция называется или какие ей нужны параметры и их порядок. И это нормально даже для senior разработчика, а мы говорим про джуна. У него, очевидно, может вполне не получится написать правильный код на листочке, а особено если он еще сверху оденет либу.
Я сказал, что задача сложная для тех, кто не работает в языках, в которых асинхронные вызовы приняты. Давайте я вам предложу решить эту задачу на python 3.4 или, например, на Free Pascal?

Для тех языков, где асинхронные вызовы не приняты, такой задачи просто не будет. Обсуждаемая тут задача в текущей формулировке — это именно что задача на js.


Обычно выбор библиотеки от проекта к проекте отличается, и какой смысл предлагать человеку сделать то, что он 100% не будет использовать ни на вашем проекте, ни вполне возможно, на других, а потом говорить "ну… это похоже на реальную задачу". В какой реальной задаче мне нужно будет самому написать такой код?

Надо решать эту задачу любым методом. Смысл тут — в проверке что вы вообще знаете что такое асинхронный код.


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

Так пусть пишет за компьютером...

Так пусть пишет за компьютером...

А вы не сталкивались с:


  • Нам нужно что бы ты не гуглил, а решал задачу
  • С докой каждый может
  • IDE не используй

И так далее?

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

Первый пункт на собеседовании ещё можно понять и простить. Но если мне скажут, что я не должен использовать документацию или IDE, то я, наверное, встану и уйду.
Ну и в конце концов, можно дать человеку компьютер без доступа к Интернету, с голой операционкой и простым текстовым редактором. Я, например, вообще не могу писать код на бумаге. Стоит мне открыть скобу, как я её тут же закрываю. Строки я обычно пишу не последовательно, нужна возможность добавлять строки сверху, или в середину. Написав какое-нибудь длинное выражение, понимаю что результат мне нужен в нескольких местах, и надо его сохранить в переменную. И еще много всего в таком духе. Так что без IDE это одно, а на бумаге это уже совсем другое. Чтобы нормально писать код на бумаге нужно специально тренироваться. Процесс слишком отличается.

На бумаге это ещё ничего. А вот когда просят в google docs. Да ещё и фокус из окна нельзя уводить, а то вдруг ты гуглишь чего, негодяй. Бррр. В Hola так собеседуют. Я больше не задачки их решал а с отступами в "коде" воевал. Хорошо хоть не в Paint-е.

Что мешает гуглить с другого устройства?

Мне помешала честность. Но это нюансы. Тут сам подход смерительной рубашки раздражает. Стресс-эффект что-ли хотят? )

Ну на коленке так на коленке…
for(let i=0;i<101;i++)console.log(i%3||i%5?(i%3?(i%5?i:"Buzz"):"Fizz"):"FizzBuzz")

Я правильно понял, что каждый следующий вывод в консоль должен отстоять на 50мс от предыдущего?

Да, правильно. Остальные варианты понимания условия слишком простые.

Неправильно. В условиях ничего о задежке не говорится не усложняйте себе жизнь. А те говноревьюверы которые говорят что надо через промисы и вообще в отдельный класс и обернуть в слушатель а потом еще и 2х сторонний байдинг прикрутить и вообще ваш скрипт не похож на новый фреймворм, а нам сказали что вы профессионал… идут лесом.
Write a program that prints into console the numbers from 1 to 100. But for multiples of three print "Miss" instead of the number and for the multiples of five print "Kiss". For numbers which are multiples of both three and five print "MissKiss". Each print must be asynchronous call console.log function with a 50ms delay.
В тексте статьи:
Напишите программу, которая печатает числа от 1 до 100. Но для кратных трём значений «Fizz» вместо номера и для кратных пяти «Buzz». Для чисел, одновременно кратных трём и пяти — «FizzBuzz».

Это другая задача.

Вы бы хоть исправили ошибки за гуглом.



Или это гугл у вас научился?

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

Если вы можете успешно написать цикл, который <...>, вы уже опережаете пакет!

Что?
Ну вот, а я уже разошелся программировать путь из мешка — если громкие звуки то затаиться, пауза, вернуться к началу, иначе проверить ближнюю стенку на целостность, если просвета нет, то проверить наличие ключей в карманах…
А тут вдруг «ни в зуб ногой». Это же скучно!
Покажите код (iced-coffee-script):
for i in [1 .. 100]
  if i % 3 == 0 and i % 5 == 0
    console.log "MissKiss"
  else if i % 3 == 0
    console.log "Miss"
  else if i % 5 == 0
    console.log "Kiss"
  else
    console.log i
  await setTimeout defer(), 50

А самое бесящее всех программистов на чистом JS
Вот это всё можно было сделать еще задолго до ES6.

Я придумал burning-hot-espresso-script.


Это как ваш кофескрипт, но для удобства символы можно писать в любом порядке (shuffle(str.split('')).join(''))
Транспилятор сам разберется какой символ куда поставить


=t
lol0

l f"ls=so iio o c
ciorct  0.l =l%ds1[Kw s% n laoe s 3   e s i
 "elei  0iie%ea.i  i  %    amns"0"cKoii=si  0, =.o.  so3o    lse]   M5. .fsfsgons

e (g r 5e 
n  )
euiliTess n  e  =fn e" M 5=  ggdi  oli"s fe0o o0=t1
Прикольно, но уже есть async await в js через babel через webpack.

С чего бы это бесило программистов на чистом JS?

По ссылке нет доказательств того, что именно эта возможность бесит программистов на чистом js.


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

Для меня необ'яснимая загадка, чем не нравится coffescript подавляющему большинству

Думаю, дело в том, что он не вводит ничего нового в язык, а синтаксис меняет, причём ещё и в сторону некрасивого Ruby. Его использование говорит о том, что программист не квалифицирован оценивать соотношение рисков и пользы от добавления в проект дополнительной зависимости. В таком ключе реакция большинства на coffeescript должна быть очевидной.

Так и не понял, при чем тут заморочки конкретно JavaScript к умению программировать.

Написал решение с циклом и потом понял прикол с рекурсией.


На самом деле, для js-разработчиков асинхронное программирование musthave. Иметь скилы работы с асинхронным кодом это хорошо, но если на сервере не нужно работать с ним, то что, вешаться? Поэтому странно судить всех по 1 критерию.

А где это на сервере нету асинхронных вызовов?

В Apache :)


А если серьёзно, то "нету" и "не нужно работать с ними" (вся асинхронность скрывается ОС и рантаймом как в PHP по дефолту) — две большие разницы.

Ну окей. Тогда понятно почему у php программеров, которые пытаются на js писать встают волосы (личный опыт).

От опыта зависит. Я чуть ли не 20 лет назад матерился из-за отсутствия в PHP более менее нормальной асинхронности, доступной на среднем шаред-хостинге. Что-только не выдумывал, включая запросы скрипта самого себя через HTTP :)

Ну тк там есть асинхронность, просто она скрыта. Но там возвращается вопрос того, что всё равно нужно знать, что это и как это использовать.

Как-то так
function missKiss () {
    for (let i = 1; i < 100; i++) {
        const triply = i % 3 === 0,
              fivy   = i % 5 === 0

        switch (true) {
            case triply && fivy:
                print('MissKiss');
                break;
            case triply:
                print('Miss');
                break;
            case fivy:
                print('Kiss');
                break;
            default:
                print(i);
        }
    }
}

function print (what) {
    setTimeout(
        () => {
            console.log(what);
        },
        50
    )
}

Тот редкий миг, когда понимаешь, что в лоб решение на golang аккуратнее, чем js:
package main

import (
	"bytes"
	"fmt"
	"strconv"
	"time"
)

func print(ch <-chan string, delay time.Duration, done chan struct{}) {
	for toPrint := range ch {
		time.Sleep(delay)
		fmt.Println(toPrint)
	}

	close(done)
}

const (
	miss = "Miss"
	kiss = "Kiss"
)

func main() {
	printCh := make(chan string, 100)
	doneCh := make(chan struct{})
	buf := bytes.Buffer{}

	go print(printCh, 50*time.Microsecond, doneCh)

	for i := 1; i <= 100; i++ {
		if i%3 == 0 {
			buf.WriteString(miss)
		}
		if i%5 == 0 {
			buf.WriteString(kiss)
		}
		if buf.Len() == 0 {
			buf.WriteString(strconv.Itoa(i))
		}

		printCh <- buf.String()
		buf.Reset()
	}

	close(printCh)
	<-doneCh
}


На все около 7 минут ушло.
А по теме статьи — да, проблема есть, но я не понимаю, зачем давать такие задания после ознакомления с кодом кандидата. А это бывает, к сожалению, часто. Как и тестовые задания на несколько дней…