Я был недоверчив, когда прочитал это наблюдение у Реджинальда Брейтуэйт:
Как и у меня, у автора возникают проблемы с тем фактом, что 199 из 200 претендентов на каждое задание программирования не могут писать код вообще. Повторяю: они не могут писать никакого кода вообще.
Автором, которого он имеет в виду, является Имрана Гхори, который, очевидно, отворачивается от многих программистов, которые не могут написать простую программу:
После немалых проб и ошибок я обнаружил, что люди, которые испытывают проблемы с написанием кода, не просто борются с большими проблемами, или даже с небольшими проблемами (например, создают реализацию связанного списка). Они испытывают проблемы с решением крошечных задачек.
Поэтому я решил разработать вопросы, которые могут идентифицировать такого рода разработчиков, и придумал класс вопросов, который я называю «Вопросы FizzBuzz», в честь игры, в которую дети часто играют (или их заставляют играть) в школах Великобритании. Примером проблемы Fizz-Buzz является следующее:
Напишите программу, которая печатает числа от 1 до 100. Но для кратных трём значений «Fizz» вместо номера и для кратных пяти «Buzz». Для чисел, одновременно кратных трём и пяти — «FizzBuzz».
Большинство хороших программистов должны иметь возможность написать на бумаге программу, которая делает это за пару минут. Хотите знать что-то страшное? Большинство выпускников компьютерных наук не могут. Я также видел, что кандидаты на старшего программиста потратили более 10-15 минут, чтобы написать решение.
Дэн Кегель имел аналогичный опыт найма программистов начального уровня:
Удивительно большая доля претендентов, даже обладающих степенями магистра и докторов наук в области компьютерных наук, не справляются, кода их просят решить простейшие задачи программирования. Например, я лично опросил выпускников, которые не могут ответить «Напишите цикл, который считает от 1 до 10» или «Какой номер после F в шестнадцатеричной системе?» Менее тривиально я брал интервью у многих кандидатов, которые не могут использовать рекурсию для решения реальной проблемы. Это базовые навыки; любой, у кого их нет, вероятно, недостаточно много программировал.
Выступая от имени инженеров-программистов, которые должны взять интервью у потенциальных новых сотрудников, я могу с уверенностью сказать, что нам надоело разговаривать с кандидатами, которые в программировании ни в зуб ногой. Если вы можете успешно написать цикл, который идет от 1 до 10 на каждом языке вашего резюме, может сделать простую арифметику без калькулятора и может использовать рекурсию для решения реальной проблемы, вы уже опережаете многих!
Между Реджинальдом, Дэном и Имраном я начинаю немного волноваться. Я более чем готов дать поблажки новоиспеченным программистам на старте их карьеры. Все должны начать где-то. Но меня беспокоит и возмущает то, что любой так называемый программист будет претендовать на работу, не имея возможности писать простейшие программы. Это пощечина каждому, кто зарабатывает на жизнь программированием.
Значительный разрыв между теми, кто может программировать, и теми, кто не может программировать, хорошо известен. Я предполагал, что тот, кто подает заявку на работу, как программист, уже пересек эту пропасть. По-видимому, это неразумное предположение. Видимо, предварительное отсеивание кандидатов вопросами типа FizzBuzz просто необходимо, иначе мы будем бездарно тратить кучу времени на собеседования с программистами, которые таковыми не являются.
Чтобы вы не подумали, что тест FizzBuzz слишком прост и ослепительно намеренно легкий, комментатор к сообщению Имрана отмечает его эффективность:
Я бы не хотел, чтобы интервьюеры отклонили тест [FizzBuzz] как слишком легкий. По моему опыту, действительно поразительно, сколько кандидатов неспособны к простейшим задачам программирования.
Может быть, глупо начинать интервьюировать программиста, не глядя вначале на его код. В Vertigo нам требуется образец кода, прежде чем мы перейдем к этапу собеседования по телефону. И наше собеседование на месте включает небольшое упражнение по кодированию. Ничего сложного, просто базовое упражнение, позволяющее проработать задание о создании небольшого приложения за час или около того. Несмотря на то, что было одно или два заметных всплеска, по большей части эта стратегия работала хорошо для нас. Это позволяет нам сосредоточиться на реальной разработке программного обеспечения в интервью, не прибегая к утомительным вопросам-головоломкам.
Жаль, что вы должны сделать столько предварительных проверок, чтобы позволить себе роскошь интервьюировать программистов, которые действительно могут программировать. Было бы смешно, если бы это было не так грустно. Я не поклонник сертификации, но меня действительно удивляет, что Стив Макконнелл был чем-то занят со всеми своими разговорами о создании истинной профессии программиста.
PS
Предлагаю попробовать решить приведенную ниже задачу на JavaScript, засекая потраченное время. Опрос-то анонимный, обманывать совсем нет смысла. Правильный вариант ответа тут. Признаюсь, что у меня ушло 67 минут, применяя гугление. Правда какую-то часть времени высиживал по японской методе — самые нелепые предположения и примерка их к задаче, наверняка есть более изящное решение. Еще какую-то часть времени потратил на причесывание индусского кода. Действительно ли нас так много? :)
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.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Комментарии (512)
mobi
17.05.2017 12:31+15Странные варианты ответа. А где «менее чем за 10 минут»?
comerc
17.05.2017 12:33Справедливо. Убрал "более чем", теперь работает округление.
OlegFX
17.05.2017 12:41+710 минут — большой порог, в изначальном тексте говорилось о паре минут на полное решение, лично у меня где-то так и ушло. Правда, писал на Go.
comerc
17.05.2017 12:47-2Боюсь, что многие не осознают ошибку. Судя по количеству заявленных правильных ответов. Наверно надо бы предложить задержку в 1 секунду.
lpre
17.05.2017 13:38+5Each print must be asynchronous call console.log function with a 50ms delay.
Скорее всего, это вы не осознаете, что это условие неоднозначно, и не обязательно требует задержки 50ms между каждым принтом.
mayorovp
17.05.2017 14:54+2Все равно не вижу проблем.
[...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 минуты без гугла, причем большая часть времени ушла на постоянные взгляды в условие на английском. Можно и понятнее написать — но это уже не на время.
vasIvas
17.05.2017 15:12+1Код классный ровно настолько же на сколько он является классным примером того что если писать в таком стиле, то и за десять лет не сможешь развиться как программист. Есть много высказываний что если можно сделать просто, то зачем усложнять. А после появляются люди, которые пишут по десять лет, но так и не могут самостоятельно написать приложение целиком с нуля, ведь они даже не вникали в архитектуру. Я запомню, хотя сам бы так не догадался, у меня мышление устроенно по другому. Я не могу уже думать без автоматической декомпозиции.
mayorovp
17.05.2017 15:16+1А кто вам сказал что я всегда пишу в таком стиле?
У этой задачи есть 4 решения.
- Через async/await
- Через библиотеку async
- Через рекурсию
- Через reduce
Первые два — понятные и красивые, но первое требует babel или tcs для старых браузеров, а второе — отдельной библиотеки. Подключать их дольше, чем писать решение.
Варианты 3 и 4 — одинаково ужасны, но не требуют дополнительных инструментов.
PS кстати, прочтите решение еще раз. Там вообще-то есть декомпозиция.
vanxant
18.05.2017 09:44А ещё можно через SetIntverval и замыкание труЪ-олдскул стиле…
comerc
18.05.2017 09:55Покажите пример кода, пожалуйста!
mayorovp
18.05.2017 10:03+4!function() { var n = 0; var interval = setInterval(function() { if (n++ == 100) return clearInterval(interval); // ... console.log(...); }, 50); }()
vanxant
18.05.2017 20:29+2Самое смешное, что это вообще единственный вариант, который таки решает грёбаную задачу полностью, как ожидалось.
Задержка 50мс для 100 элементов как бы неявно предполагает, что последняя надпись будет выведена через 5 секунд (5000 миллисекунд), плюс-минус точность таймеров операционной системы.
И это только setInterval.
Во-первых, setTImeout на 50 мс вызывается не ранее, чем через 50 мс, но чаще — более.
Во-вторых, если мы не под QNX сидим, у нас практически никогда ОС не выдаст событие таймера ровно через 50 мс. В винде по умолчанию например таймер тикает 64 раза в секунду, это 15.6мс в каждом тике. Т.е. в случае setTimeout на 50 вы будете получать в реальности один тик каждые 62 милисекунды. Нефиговая такая погрешность в 24%, не так ли?
Ну дальше ещё браузер своё откушает (ему нужно самому интерфейс перерисовать, анимации всякие покрутить, сборщик мусора запустить), потом запустит event loop для вашего скрипта, и только потом дойдёт до собственно вашего обработчика.
Так что любой код на setTimeout будет выполнятся секунд 7 вместо 5.mayorovp
18.05.2017 20:35Это все от задачи зависит. Например, если задержка является эмуляцией сетевого запроса — то только новый setTimeout после предыдущего будет корректным.
MetaDriver
19.05.2017 09:08Проверьте в хроме, плиз.
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); } }
CrazyNiger
19.05.2017 09:36А что проверяем-то? То что хром умеет к переменной 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мс между вызовами, хотя до первого чуть-больше.MetaDriver
19.05.2017 19:54А что проверяем-то? То что хром умеет к переменной 50 прибавлять?
Да не, это я ступил. Сорри. Хром сам умеет выводить таймштамп перед логами. https://www.screencast.com/t/Wj4Wedqfrh
Я уже настолько привык к этой фиче, что забыл, что это не настройка по умолчанию.
Cryvage
18.05.2017 14:59А что такого ужасного в рекурсии?
Вроде бы короткий и понятный код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 );
mayorovp
18.05.2017 15:28Мой код настолько же понятен. И точно так же не забивает стек.
Но цикл через await все равно понятнее.
Cryvage
18.05.2017 17:36Так я же и не говорил, что ваш код чем-то плох. По поводу стека написал просто потому, что забивание стека это «классический» недостаток рекурсии. А в данном случае этого недостатка нет.
Naik_Trofimov
20.05.2017 13:12-6Извините, но я не понимаю причем тут таймер(/задержка), если в задачи про него ничего не написано?
Напишите программу, которая печатает числа от 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"); }
bogolt
21.05.2017 14:26+3Ваш си++ слишком уж добр. Это не компилируется, во-первых у функции мейн должен быть возвращаемый тип int, во-вторых нет инклюдов, в третьих — cin служит для ввода информации, для вывода cout.
Теперь по более серьезному — i / 3 % 10 это вообще что у вас? Проверка делится ли (i/3) без остатка на 10? А зачем? В задаче нужно проверить делится ли i без остатка на 3 и на 5, то есть i % 3 == 0 было бы достаточно.
system(«pause») — си++ он может запускаться на разных платформах но этой строкой кода вы намерство прибили программу к винде.kloppspb
21.05.2017 17:44+2этой строкой кода
Насколько я понимаю, её наличие — отличительная черта студентов, которые с C++ знакомы исключительно по копипасте лекций (по которым system(«pause») проходит красной нитью из года в год, из вуза в вуз).mayorovp
21.05.2017 18:36Это отличительная черта программистов, которых заставили писать консольное приложение, или даже убедили что консольные приложения — это круто, но которым забыли объяснить как эту самую консоль правильно запускать...
Да, обычно это студенты или школьники. Но не обязательно.
grossws
21.05.2017 20:09Часть ещё используют
getc
/gets
, тут от препода зависит, видимо. Мало у кого видел, чтобы этого не было вообще. Видимо, не осиливают в vs поставить соответствующую галочку, чтобы терминал не закрывался автоматически.Peacemaker
22.05.2017 22:52Не подскажете, где эту галочку поставить? Если скомпиленый бинарник в консоли запускать, а не из студии, консоль тоже не закроется?
mayorovp
23.05.2017 09:13+1Окно консоли же закрывается не потому что программа завершилась — а потому что не осталось процессов, связанных с этим окном (т.е. все программы завершились).
Если вы запускаете программу из командной строки, то процесс командной строки (cmd.exe) остается привязан к консольному окну пока вы не напишете команду exit.
0xd34df00d
22.05.2017 22:16-1Да и сам алгоритм странный, три ветвления со вложенностью, когда можно двумя без вложенности. Это печальнее, на мой взгляд.
mayorovp
23.05.2017 09:15Алгоритм там как раз самый оптимальный, хоть это и экономия на спичках.
0xd34df00d
23.05.2017 20:31Почему? Почему бы сначала не проверить на делимость на 3, а потом — на 5 (или наоборот, смотря в каком порядке fizzbuzz выводить)?
mayorovp
23.05.2017 21:02Так он же так и проверяет...
0xd34df00d
23.05.2017 21:09А, круто, я умудрился вчера не заметить ветку с печатью
i
. Тогда да, согласен.
Naik_Trofimov
26.05.2017 11:36Ну в Vs2005, на котором нас обучали на первых порах, мы работали через void main(), препод все боялся и не давал нам сложные материалы чтоб не было глупых вопросов, но сейчас я понимаю что будь по другому, я бы не словил минуса. Когда уже начали изучать MFC уже перешли на новые визуалки а там и не смотрели как там был стандартно инициализирован main. Только сейчас заметил что перед main() у меня ничего не стоит… торопился.
На счет инклюдов думал и решился их не писать. А с cin/cout дырявая башка, дай пирожка, вечно путаю.
Про i/3%10, что первым пришло в голову, опыта не хватило додуматься.
system(«pause») то же самое что и выше, можно конечно с getchar().
А с кроссплатформенностью никогда не встречался, вот и не задумываюсь перед тем использовать одно или другое. Всю жизнь на винде, так и помру с ней.
Могу сказать только спасибо, иначе даже сам не смог бы понять с чего так заминусовали.kloppspb
26.05.2017 19:52+1новые визуалки а там и не смотрели как там был стандартно инициализирован main
В продолжение соседней ветки комментариев: написание кода «на бумажке» как раз и позволяет отличить программистов от тех, за которых «визуалка» думает :)
А с кроссплатформенностью никогда не встречался
Тут дело даже не в кросплатформенности. Есть, например, знание языка C, а есть «умение писать на С под Windows». Есть умение думать, а есть умение мышевозить в каком-нибудь билдере или что там сейчас. Это совершенно разные вещи, и все они нужны. Но второе в обоих случаях — не программирование.
xGromMx
17.05.2017 15:25+1куда лучше юзать Array.from => Array.from({length: 100}, (_, i) => i + 1)…
Ну и вообще изучить синтаксис async/await
aristarh1970
18.05.2017 07:59+1Смотрю и не понимаю (с JS ушел полностью на Javu лет 15 назад и эти новомодности не застал) — а зачем городить огород с массивам/мапами и прочем? Че просто не пробежать for-ом, с тремя if-ами в нем?..
mayorovp
18.05.2017 08:20В простой цикл на js нельзя включить задержку (в версиях языка до ES2017).
faiwer
18.05.2017 11:26+1А оно надо? У меня ушло 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)); }
На красоту и оптимальность не претендую. Писал на скорую руку прямо в отладчике. Но тут как раз простой цикл.
mayorovp
18.05.2017 12:26Ваше решение почти такое как у меня, вся разница — только в месте вычисления строки для вывода.
Zibx
17.05.2017 12:32-1Таки менее 10 минут. Результат идентичен, но я в процессе использовал массив который быстро наполнил, а потом выводил сдвигая указатель на начало пока он не кончился. В ответе решение с разновидностью «генератора» что лучше.
jok40
17.05.2017 12:39+2Но для кратных трех значений «Fizz» вместо номера и для кратных пяти «Buzz».
Написано по-русски, но совершенно непонятно. Я бы тоже, пожалуй, не смог решить задачу, если бы условие выглядело таким образом.
APXEOLOG
17.05.2017 12:443 минуты. В правильном варианте принты хоть и асинхронные, но последовательные, я делал параллельные — это считается надеюсь?
comerc
17.05.2017 12:53Покажите код, пожалуйста. Интересно же!
CrazyNiger
17.05.2017 12:58+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); }
arthurdrapeza
19.05.2017 09:10я тоже параллельные делал, вот решение:
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); } }
APXEOLOG
17.05.2017 12:59+3for (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); }
CrazyNiger
17.05.2017 13:11Хм… был уверен, что при таком коде во всех вызовах i=101, но как оказалось, если i объявлен через let, а не var, то замыкается его текущее значение.
EviGL
20.05.2017 22:30Я ещё не привык рассчитывать на 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); }
comerc
17.05.2017 13:20-7Ваш код выплевывает все значения сразу. Попробуйте изменить задержку на 1 секунду, чтобы увидеть ошибку.
APXEOLOG
17.05.2017 13:28+6Each print must be asynchronous call console.log function with a 50ms delay
В задаче не указано, что задержка должна быть от каждого предыдущего принта, а не от точки старта. Я изначально понял эту задачу именно так, поэтому так и реализовал.
Да, скорее всего разумнее было бы делать задержку между вызовами, тем не менее — неточность в задании я трактовал в свою пользуhaldagan
18.05.2017 11:54Аналогично.
Более того (ИМХО) решение автора не удовлетворяет условию в том виде, как он его трактует.
В его случае задержка также должна быть уменьшена время выполнения кода предыдущего шага.
В текущем примере это слабо заметно, но, думается мне, что если поставить «Number.MAX_SAFE_INTEGER» вместо 100, то можно будет увидеть, что время между первым и последним выводом будет не Number.MAX_SAFE_INTEGER*50, а на несколько миллисекунд больше.
rijk
18.05.2017 11:54-1А вот и мой код
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);
Leg3nd
17.05.2017 13:38+2Согласен, условие по поводу асинхронности вывода сформулировано двояко, я тоже так понял.
Juma
17.05.2017 12:45But 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
Итого, решение не правильно (не соответствует условию). И за сколько в итоге вы решили? (Если это ваше решение)DorianPeregrim
17.05.2017 12:48Признаюсь, что у меня ушло 67 минут, применяя гугление
Juma
17.05.2017 12:56+2На тот момент когда я смотрел, решение по ссылке
было(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);comerc
17.05.2017 12:50+1Гы-гы. Спасибо! Исправил.
Juma
17.05.2017 13:01+1Не подумайте что я придираюсь. Просто решил задачу, сверил результат. Не совпадает.
Начал искать ошибку. Не у меня.comerc
17.05.2017 13:30Всё правильно. Это как на выпускном экзамене в школе. Один из класса выполнил все пять задач, но допустил арифметическую ошибку. В итоге все равно оценка 4.
armavox
17.05.2017 12:56Написал на 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
MacIn
17.05.2017 16:53-2Как минимум, не то, то, что все условия проверяются дважды. Не то то, что условие дележа на 15 вынесено отдельно, хотя этот случай решается сам собой — просто два последовательных вызова.
dskozin
17.05.2017 17:24Ошибка что не на JavaScript. ) Автор задачи хочет подловить испытуемого на задержке вывода значения. При неправильном коде это приведет к тому что последнее значение переменной выведется на экран 100 раз.
GlukKazan
18.05.2017 09:18Простите, но где здесь:
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?3vi1_0n3
18.05.2017 09:22Видимо, console.log function подразумевает
Lailore
18.05.2017 09:35Это есть только в javascript? И вообще этот метод относиться к стандартной библиотеке js?
mayorovp
18.05.2017 10:08В javascript и языках на его основе. Само название метода несет в себе наследие браузера, где консоль — нечто опциональное. В языках, которые начинали как языки системного программирования такой метод не может называться log, он будет называться write или print :-)
Да, он относится к стандартной библиотеке.
GlukKazan
18.05.2017 10:14Тестовое задание должно быть сформулировано максимально чётко.
И должно «подразумевать» подобным образом минимальное количество ограничений.
В противном случае, это просто неуважение к кандидату.mayorovp
18.05.2017 10:16+1Я думаю, конкретно это задание было придумано для проверки именно js-разработчиков. Т.е. язык программирования не попал в цитату потому что уже был указан в наименовании вакансии.
GlukKazan
18.05.2017 10:31Скорее всего. И я прекрасно понимаю, где именно здесь разложена «засада» по сравнению с оригинальным «FizzBuzz». Более того, я допускаю, что такие задачи могут быть полезны при собеседовании юниоров, но… получив такую задачу (например на собеседовании) без соответствующего уточнения, я оставляю за собой право решать её на любом языке. Например на C# или на Lisp-е или на чём-то ещё более экзотическом. В результате, вполне может получиться как здесь. И это будет даже не сознательный троллинг, а просто защитная реакция.
grossws
18.05.2017 11:31Строго говоря, это можно считать методом стандартной библиотеки в современных браузерах и nodejs. Например, в IE <= 9
console.log
не отпределён (undefined
) пока не открыты dev tools.
Другой стандартный пример js без
console.log
:
-> % jjs jjs> console.log("test"); <shell>:1 ReferenceError: "console" is not defined jjs>
streetflush
17.05.2017 17:56Не смог распознать сарказм, поэтому
1. GoTo
2. Лишние проверки
3. Нет асинхронности и задержки
terrier
17.05.2017 12:57+5Перевод ужасен, извините.
Автором, которого он имеет в виду, является Имрана Гхори
который, очевидно, отворачивается от многих программистов
люди, которые борются за код,
самопровозглашенные старшие программисты
терпит неудачу во время интервью
их просят выполнить основные задачи программирования
не могут запрограммировать свой путь из бумажного мешка.
кто пишет программное обеспечение для жизни.
и так далее и тому подобноеcomerc
17.05.2017 13:00Перевод ужасен, извините.
Знаю :( Я совсем не переводчик. Очень впечатлила статья. Не мог удержаться.
saluev
17.05.2017 16:09+1Судя по переводу, вы под впечатлением не особо поняли даже её текст.
comerc
17.05.2017 18:09Как любят повторять в одной конторе, где мне посчастливилось трудиться: критикуешь-предлагай.
haldagan
25.05.2017 10:47+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» — Я более чем готов (пойти на уступки / дать поблажки) новоиспеченным программистам на старте их карьеры.
comerc
26.05.2017 11:40Большое спасибо. Внёс правки. Рассчитываю на вашу помощь в дальнейшем.
shurupkirov
27.05.2017 08:00а я вот только что решил потыкать англоязычные ссылки и был весьма удивлен, что вся статья базируется на статьях 2005-2007 годов
очень странный временной откат в статье на злободневную тему, вероятность достоверности данных низкая
MacIn
17.05.2017 16:55самопровозглашенные старшие программисты
Тут все верно — в оригинале так же self-proclaimed. Ну, «старшие» некий аналог Senior, допустимый по контексту, кмк.terrier
17.05.2017 18:31«Самопровозглашенный» в русском языке почти исключительно про государства. Имеется в виду, что старшие программисты сами себя так называют, но на деле старшими не являются.
То есть «так называемые старшие программисты» или «люди, которые называли себя старшими программистами» или что-то более изящное. Но «Самопровозглашенные» не пойдет.comerc
17.05.2017 18:38-3Спасибо, поправил: "кандидаты на старшего программиста".
MacIn
17.05.2017 18:58+1Это тоже неверно, даже более неверно, чем предыдущий вариант. Смысл именно в том, что эти люди объявили себя старшими сами. «Кандидаты» — совсем иное.
comerc
17.05.2017 19:47кандидаты, подававшие резюме на вакансию «Senior developer»
poxvuibr
20.05.2017 15:29+3Вы подсмотрели неправильный перевод. Самопровозглашённые было гораздо лучше, потому что верно отражало смысл. Зря вы его убрали :)
bano-notit
20.05.2017 19:09Ну мне тоже самопровозглашённые понравилось больше, но тут сказали эксперты переводчики, к которым я себя не отношу, что этот перевод не правильный, поэтому автор и исправил.
MacIn
17.05.2017 18:56+2Официально — да, но по смыслу подходит замечательно — все то же самое «сам себя назначил». Будь то монарх, государство, или что-то еще, такое же патетическое. Как по мне, такое легкое косноязычие проходит как pun, именно так я воспринял эти слова в переводе.
terrier
17.05.2017 19:38Не, в переводе лучше либо придумать изящную формулировку, выражающую иронию по отношению к «старшим» программистам, либо уж передавать смысл.
Впрочем, окей, если бы это была единственная проблема с переводом — сошло бы за немного тяжеловесный каламбур.
Inine
17.05.2017 19:48Как фигура речи и «самопровозглашенные» неплохо выглядит. А так вообще, вполне подойдет слово «самозванцы».
ACPrikh
18.05.2017 08:41Самозванцы тоже мимо. Это про царей. И вообще, одним из умений хорошего программиста является умение понимать нечёткие техзадания или «хотелки». Особенно для самостоятельных, работающих без аналитического отдела. Так что умение работать с нечеткими формулировками я бы отдельно оценивал.
Впрочем, речь в статье об элементарной неграмотности. Увы, это так. Это случилось от того, что вместо аналитических способностей оценивается соответствие неким абстрактным требованиям. Причем имеющим малое отношение к реальным нуждам программирования. Решение принимают люди, далекие от программирования. HR, коммерсы. У них не то, что понятия нет о программировании, они говорят на другом языке, мыслят по другому.
Armleo
17.05.2017 12:595 минут на решение. Мне 17 на работу возьмёте? :) Эти задачи может решить любой школьник просто почитав w3schools до конца. Если это единственное препятствие на собеседовании (нет последующих этапов) то набёрете много новичков.
Danik-ik
22.05.2017 07:59Если внимательно прочитать данный материал (очень важно для программистов, и Вы этот микротест провалили), можно понять, что элементарные задачи на очевидные умения нужны на предварительном отборе, чтобы не тратить Время на серьёзное собеседование с самозванцами.
Akuma
17.05.2017 13:02Поправьте описание на русском, чтобы там было указано про 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 «программистов», которые не могут вообще ничего написать на это задание.comerc
17.05.2017 13:07Строго говоря, вы не решили задачу, как и я. Мы вместе допустили ошибки на этапе знакомства с задачей (у меня было перепутано Kiss и Miss).
LekaOleg
17.05.2017 13:02После прочтения задания в голове уже сложилась картина решения и кода, написал на листке бумаги, потом сравнил с Вашим примером, отличие только в том что Вы написали на новом ECMA, ну и реализаций можно было бы придумать даже несколько вариантов (но это уже так для интереса).
Спасибо за статью!
Filippok
17.05.2017 13:19Около года назад, вдохновившись этим, напилил real mode fizzbuzz. Потратил на это чуть более часа.
shurupkirov
17.05.2017 13:21js знаю поверхностно
поэтому без всяких 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); }}
comerc
17.05.2017 13:25-1И это неправильный ответ :)
shurupkirov
17.05.2017 13:36+1И что тут неправильного? Если вы про
Each print must be asynchronous call console.log function with a 50ms delay.
, то я как бы и не владею полноценно js
Это уже нюанс, на решение которого надо потратить еще чуток времениcomerc
17.05.2017 18:17+2Ну нельзя же быть наполовину беременной, например.
shurupkirov
18.05.2017 08:22-2соглашусь, но.
- я не программист ни разу, на задание потратил 4 минуты
- исходя из п.1 с огромной вероятностью следует, что тот, кто программист — напишет этот код быстрее и добавит асинхронность вывода с задержкой.
А значит автор статьи гиперболизирует проблему и ее нет
mayorovp
18.05.2017 08:29+1Проблема не в том, что программисты не справляются с задачей — а в том что "не программисты" приходят на собеседования на должности программистов и иногда даже их принимают.
shurupkirov
18.05.2017 08:34Насколько я понял из статьи, все собеседующиеся имеют какие-то должности, спец.образование. Если все же ситуация имеет вероятность часто быть, то я бы сделал вывод о том, что
а) проблема с образованием (отсутствие качественно проверки и т.п.)
б) проблема в перенасыщенности информацией, когда люди на простых задачах впадают в ступор, но при этом отлично решают более сложные задачи
zodchiy
17.05.2017 13:23Где-то в конце десятых пропал термин кодер. Остался только негативный термин говнокодер или быдлокодер.
Все стали программистами — 1с-программистами, css-программистами, html-программистами.
Прочитал первые 10 страниц книги по программированию, и уже программист.
Мало того, я считаю 90% текущих программистов отнести к кодерам.
А кодеру незазорно не смочь создать решение.VolCh
17.05.2017 17:42+1Квалификация "программист" присваивается выпускникам ПТУ согласно действующим нормативным документам.
mayorovp
17.05.2017 17:47Человека, который не сумел написать FizzBuzz, нельзя отнести даже к кодерам.
zolern
17.05.2017 13:25+1В том-то и вопрос, что масса програмистов учили и умеют синхронный код программировать. Почему так мало смыслят в асинхронное программирование на бумаге — вот это совсем другая тема и как-то не очень корректно путать топлое с мягким.
VladGum
17.05.2017 13:27-2FizzBuzz.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);
tzlom
17.05.2017 13:28Вот как вы думаете, это задание написано криво и моё решение имеет право на жизнь, или я дурак?
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 секунду, после чего уже прочёл решениеcomerc
17.05.2017 13:36-3Попробуйте изменить на 1000 мс. Ваш вариант выплевывает в консоль все ответы сразу.
tzlom
17.05.2017 16:40+2Я знаю, но в задании нигде не сказано что он должен делать задержку между последовательными ответами, там сказано что каждый вывод на консоль должен быть асинхронным и с задержкой в 50мс.
Правильное окончание задания звучало бы как «между выводами чисел должна быть не блокирующая задержка в 50 мс»
punkkk
17.05.2017 17:13-1Задержка должна быть между шагами вывода, а не перед выплевыванием.
Вместо var x=s; можно было бы перед s написать let, а не var и использовать s на вывод. :)
youlose
21.05.2017 13:26+1setTimeout измеряет задержки в миллисекундах, потому у вас получилось увеличить задержку только на 1 миллисекунду
dmitry_dvm
17.05.2017 13:29Мысленно представил, как сделал бы на шарпе через пару условий или свитчей, но подумал, что это, наверное, костыльно и есть способы лаконичнее, однако в ответе именно такой.
Думаю, за пару минут не уложился бы, но за 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); } }
dmitry_dvm
17.05.2017 13:44continue; после каждого ифа забыл… А тут еще и задержка какая-то всплыла. В общем прошу считать вышенаписанный камент недействительным и вообще меня тут не было.
mayorovp
17.05.2017 15:01Ну, на шарпе задержка как раз не проблема. Можно хоть Thread.Sleep, хоть await Task.Delay использовать.
Вот на старых версиях js необходимость задержки полностью перекореживает код.
k0rsh
17.05.2017 13:46+1Аналогично, зашел сначала с шарпа. Минут пять потратил. Если я правильно понял про асинхронность, то мой вариант ниже:
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)); }
mayorovp
17.05.2017 15:03-2Зачем, ну зачем IsDivisableBy? Что оно делает?
Это на тут случай если кто-то не знает что в шарпе делает оператор
%
?
Не говорю уже про
? true : false;
...k0rsh
17.05.2017 15:38В принципе, всё делалось ряди погони за удобочитаемостью. Не меняя времени, затраченного на решение, можно было добавить сахарку за счет 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(); }
mayorovp
17.05.2017 15:42-1Почему вы в таком случае пишите
s += ...
, а неs = string.Concat(s, ...)
?WNeZRoS
17.05.2017 17:09-2Ещё больше «сахара»:
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) // ...
mayorovp
17.05.2017 17:19+1Вы правда считаете такое хорошим кодом — или издеваетесь?
WNeZRoS
17.05.2017 18:06Тут вроде про код кажущийся чем-то сложным ветка, а не про элегантное решение в 3 строки.
mayorovp
17.05.2017 19:18Т.е. вы считаете нормальным намеренно раздувать код, чтобы он начал казаться чем-то сложным?
k0rsh
17.05.2017 19:40Речь, скорее, о демонстрации на данном примере из собеседования, что кроме решения непосредственно задачи можно ещё показать умение пользоваться методами расширения, yield return'ом и async/await.
Ясное дело, что решение с минимальным читаемым кодом — это про другое.mayorovp
17.05.2017 19:45+2Нет. Задачи класса FizzBuzz проверяют именно тот факт, что вы в принципе в состоянии писать код и держать при этом простой код простым.
Написание FizzBuzzEnterpriseEdition на собеседовании будет провалом.
grossws
18.05.2017 00:55Вспомнилась прекрасная серия от Kyle Kingsbury (aka Aphyr): Reversing the technical interview, Hexing the technical interview и Typing the technical interview. Крайне рекомендую к прочтению всем у кого с английским более-менее.
mayorovp
18.05.2017 05:51+3У этой серии есть два перевода на Хабре:
Заклиная техническое интервью
Типизируя техническое интервью
Danik-ik
22.05.2017 08:46-1"Если бы я нанимал программиста" :), я бы сто пудов предпочёл того, кто не будет усложнять простое. Ибо нужен человек, который решает задачи за минимальную цену, а не "изображает из себя профессионала" (намеренное усложнение простой задачи вряд ли можно назвать иначе). Профессионал способен дозировать усилие (умное слово YAGNI).
bano-notit
17.05.2017 21:56Уже скидывали тут решеньеце этой задачки на реально сложном и не понятном...
sshikov
17.05.2017 21:58А вам про что в посте написали? Не верите? Ну вот оно… теже яйца, только в профиль
ijsgaus
18.05.2017 01:17-1class 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(); } }
Так вроде проще.
k0rsh
17.05.2017 13:41+1Хоть и не жабаскриптер, но можно else if превратить вот в такую конструкцию:
if (n % 5 === 0) {
s += 'Kiss';
}
console.log((s==='')? n: s);
s1im
17.05.2017 13:42+2Циклом правильную задержку не сделать, рекурсией элементарно решается
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);
osmirnov
17.05.2017 14:13Любителям однострочников:
for (let i = 1, s = ''; i < 101; i++) (s = (i % 3 ? '' : 'Miss') + (i % 5 ? '' : 'Kiss')) && setTimeout(function() { console.log(s); }, 50 * i);
Aingis
17.05.2017 14:46По сути в пять строчек нормально пишется:
пятистрочникvar i = 1, interval = setInterval(function() { console.log((i % 3 == 0 ? 'Miss' : '') + (i % 5 == 0 ? 'Kiss' : '') || i) if (i++ >= 100) clearInterval(interval) }, 50)
deniskreshikhin
17.05.2017 14:45+3Это пощечина каждому, кто пишет программное обеспечение для жизни.
Это пощечина каждому, кто зарабатывает на жизнь программированием.
Fen1kz
17.05.2017 15:01+2Сначала сделал через 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мс"?
IonianWind
17.05.2017 15:06LOL
(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);
mayorovp
17.05.2017 15:13Внешний Promise у вас — лишний, достаточно было
(async timeout => ... )(50)
IonianWind
17.05.2017 15:23Действительно, спасибо
Пока не привык до конца к 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);
mayorovp
17.05.2017 15:27А теперь async лишний :-)
IonianWind
17.05.2017 15:31Чорт %) Пора отдохнуть )
(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);
mayorovp
17.05.2017 17:36Пожалуйста, поясните причину минусов, а то я не понимаю что я сказал не так.
SirEdvin
17.05.2017 15:06Each print must be asynchronous call console.log function with a 50ms delay.
У меня вот на это уйдет большая часть времени. Более, того, я даю 100% гарантию, что не напишу такое на собеседовании, так как:
- Во многих языках работа с асинхронными вызовами не такая простая. Привет от python 3.4, например.
- Зачем?
mayorovp
17.05.2017 15:12Потому что в этой задаче console.log заменяет собой асинхронный вызов. Вы не верите, что в реальной работе вам однажды понадобится сделать подряд 100 асинхронных вызовов?
Ohar
17.05.2017 17:09Если понадобится — под это берётся модуль/библиотека, иногда самописная.
Такие вещи не пишутся в проекте.mayorovp
17.05.2017 17:17Ну так и надо взять библиотеку, это правильное решение (одно из)! А не заявлять, что задача слишком сложная и ее не получится написать на собеседовании.
SirEdvin
17.05.2017 22:25- Я сказал, что задача сложная для тех, кто не работает в языках, в которых асинхронные вызовы приняты. Давайте я вам предложу решить эту задачу на python 3.4 или, например, на Free Pascal?
Обычно выбор библиотеки от проекта к проекте отличается, и какой смысл предлагать человеку сделать то, что он 100% не будет использовать ни на вашем проекте, ни вполне возможно, на других, а потом говорить "ну… это похоже на реальную задачу". В какой реальной задаче мне нужно будет самому написать такой код?
- Касательно библиотек. Внезапно, но я довольно часто не помню синтаксис, команды и прочее для библиотек, которые использую редко. Более того, я часто могу не помнить, как та или иная функция называется или какие ей нужны параметры и их порядок. И это нормально даже для senior разработчика, а мы говорим про джуна. У него, очевидно, может вполне не получится написать правильный код на листочке, а особено если он еще сверху оденет либу.
mayorovp
17.05.2017 23:02+1Я сказал, что задача сложная для тех, кто не работает в языках, в которых асинхронные вызовы приняты. Давайте я вам предложу решить эту задачу на python 3.4 или, например, на Free Pascal?
Для тех языков, где асинхронные вызовы не приняты, такой задачи просто не будет. Обсуждаемая тут задача в текущей формулировке — это именно что задача на js.
Обычно выбор библиотеки от проекта к проекте отличается, и какой смысл предлагать человеку сделать то, что он 100% не будет использовать ни на вашем проекте, ни вполне возможно, на других, а потом говорить "ну… это похоже на реальную задачу". В какой реальной задаче мне нужно будет самому написать такой код?
Надо решать эту задачу любым методом. Смысл тут — в проверке что вы вообще знаете что такое асинхронный код.
У него, очевидно, может вполне не получится написать правильный код на листочке, а особено если он еще сверху оденет либу.
Так пусть пишет за компьютером...
SirEdvin
17.05.2017 23:22Так пусть пишет за компьютером...
А вы не сталкивались с:
- Нам нужно что бы ты не гуглил, а решал задачу
- С докой каждый может
- IDE не используй
И так далее?
Cryvage
18.05.2017 15:44+2Первый пункт на собеседовании ещё можно понять и простить. Но если мне скажут, что я не должен использовать документацию или IDE, то я, наверное, встану и уйду.
Ну и в конце концов, можно дать человеку компьютер без доступа к Интернету, с голой операционкой и простым текстовым редактором. Я, например, вообще не могу писать код на бумаге. Стоит мне открыть скобу, как я её тут же закрываю. Строки я обычно пишу не последовательно, нужна возможность добавлять строки сверху, или в середину. Написав какое-нибудь длинное выражение, понимаю что результат мне нужен в нескольких местах, и надо его сохранить в переменную. И еще много всего в таком духе. Так что без IDE это одно, а на бумаге это уже совсем другое. Чтобы нормально писать код на бумаге нужно специально тренироваться. Процесс слишком отличается.faiwer
18.05.2017 15:47+1На бумаге это ещё ничего. А вот когда просят в google docs. Да ещё и фокус из окна нельзя уводить, а то вдруг ты гуглишь чего, негодяй. Бррр. В Hola так собеседуют. Я больше не задачки их решал а с отступами в "коде" воевал. Хорошо хоть не в Paint-е.
Mysterious
17.05.2017 15:35-2Ну на коленке так на коленке…
for(let i=0;i<101;i++)console.log(i%3||i%5?(i%3?(i%5?i:"Buzz"):"Fizz"):"FizzBuzz")
maxru
17.05.2017 15:50Я правильно понял, что каждый следующий вывод в консоль должен отстоять на 50мс от предыдущего?
Mysterious
18.05.2017 09:11-1Неправильно. В условиях ничего о задежке не говорится не усложняйте себе жизнь. А те говноревьюверы которые говорят что надо через промисы и вообще в отдельный класс и обернуть в слушатель а потом еще и 2х сторонний байдинг прикрутить и вообще ваш скрипт не похож на новый фреймворм, а нам сказали что вы профессионал… идут лесом.
mayorovp
18.05.2017 10:10+2Write 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.
Mysterious
19.05.2017 12:46-3В тексте статьи:
Напишите программу, которая печатает числа от 1 до 100. Но для кратных трём значений «Fizz» вместо номера и для кратных пяти «Buzz». Для чисел, одновременно кратных трём и пяти — «FizzBuzz».
saluev
17.05.2017 16:08+6нам надоело разговаривать с кандидатами, которые не могут запрограммировать свой путь из бумажного мешка
Если вы можете успешно написать цикл, который <...>, вы уже опережаете пакет!
Что?comerc
17.05.2017 18:27Благо, что есть профессиональный перевод. Исправил методом копипаста.
lasthand
18.05.2017 09:59Ну вот, а я уже разошелся программировать путь из мешка — если громкие звуки то затаиться, пауза, вернуться к началу, иначе проверить ближнюю стенку на целостность, если просвета нет, то проверить наличие ключей в карманах…
А тут вдруг «ни в зуб ногой». Это же скучно!
vird
17.05.2017 16:11-2Покажите код (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.Fen1kz
17.05.2017 16:21-2Я придумал 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
mayorovp
17.05.2017 16:28С чего бы это бесило программистов на чистом JS?
vird
17.05.2017 16:30+1https://fossbytes.com/most-loved-and-most-hated-programming-languages/
1. Visual Basic 6
2. VBA
3. CoffeeScriptmayorovp
17.05.2017 17:38+1По ссылке нет доказательств того, что именно эта возможность бесит программистов на чистом js.
Кроме того, лично для меня дико звучит сама идея что программист может ненавидеть язык за наличие в нем каких-то фич, обычно не любят либо отсутствие фич, либо непривычный синтаксис.
comerc
19.05.2017 08:58Для меня необ'яснимая загадка, чем не нравится coffescript подавляющему большинству
maeris
19.05.2017 13:10Думаю, дело в том, что он не вводит ничего нового в язык, а синтаксис меняет, причём ещё и в сторону некрасивого Ruby. Его использование говорит о том, что программист не квалифицирован оценивать соотношение рисков и пользы от добавления в проект дополнительной зависимости. В таком ключе реакция большинства на coffeescript должна быть очевидной.
yarric
17.05.2017 16:33+9Так и не понял, при чем тут заморочки конкретно JavaScript к умению программировать.
springimport
17.05.2017 16:51Написал решение с циклом и потом понял прикол с рекурсией.
На самом деле, для js-разработчиков асинхронное программирование musthave. Иметь скилы работы с асинхронным кодом это хорошо, но если на сервере не нужно работать с ним, то что, вешаться? Поэтому странно судить всех по 1 критерию.
bano-notit
17.05.2017 22:02А где это на сервере нету асинхронных вызовов?
VolCh
17.05.2017 22:17-1В Apache :)
А если серьёзно, то "нету" и "не нужно работать с ними" (вся асинхронность скрывается ОС и рантаймом как в PHP по дефолту) — две большие разницы.
bano-notit
18.05.2017 20:44Ну окей. Тогда понятно почему у php программеров, которые пытаются на js писать встают волосы (личный опыт).
VolCh
19.05.2017 13:34От опыта зависит. Я чуть ли не 20 лет назад матерился из-за отсутствия в PHP более менее нормальной асинхронности, доступной на среднем шаред-хостинге. Что-только не выдумывал, включая запросы скрипта самого себя через HTTP :)
comerc
17.05.2017 23:57Еще в Метеоре асинхронность скрыта за ширмой фреймворка, например.
bano-notit
18.05.2017 20:43Ну тк там есть асинхронность, просто она скрыта. Но там возвращается вопрос того, что всё равно нужно знать, что это и как это использовать.
Ohar
17.05.2017 17:05Как-то так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 ) }
JekaMas
17.05.2017 17:24-5Тот редкий миг, когда понимаешь, что в лоб решение на 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 минут ушло.
А по теме статьи — да, проблема есть, но я не понимаю, зачем давать такие задания после ознакомления с кодом кандидата. А это бывает, к сожалению, часто. Как и тестовые задания на несколько дней…
Mispon
17.05.2017 18:04C#
for (var i = 1; i <= 100; i++) { var message = string.Empty; if (i % 3 == 0) { message = "Miss"; } if (i % 5 == 0) { message += "Kiss"; } Console.WriteLine(message); Thread.Sleep(50); }
Verren
17.05.2017 18:04А что если пренебречь временной погрешностью и сделать в стиле С решение?
function wait(msecond) { var timeStart = Date.now(); var timeStop = timeStart + msecond; for (;;) if (Date.now() > timeStop) break; } for (var i=1;i<=100;i++) { var num = i; var res3 = (num % 3 === 0) ? 'Kiss' : ''; var res5 = (num % 5 === 0) ? 'Miss' : ''; console.log((res3 || res5) ? res5 + res3 : num); wait(50); }
evkin
17.05.2017 18:10+3Интересно, мне одному глаза режет двойная проверка условия и лишние соединения строк? Почему то никто не предложил чуть более оптимизированный вариант внутреннего цикла:
if (y % 3 == 0) { console.log((y % 5 == 0) ? "MissKiss" : "Miss"); } else { console.log((y % 5 == 0) ? "Kiss" : y); }
Timmmm
17.05.2017 22:41+2Зато стало сложнее воспринимать код
evkin
18.05.2017 19:42мне тяжело воспринять фразу «сложнее воспринимать код», который состоит из 5 строчек))))
EviGL
20.05.2017 22:52+1Вы предположили, что сравнение строк в этой задаче в проде вдруг станет критической по производительности процедурой, выполняемой на микроконтроллере с 1кб памяти.
Другие предположили, что задача пойдёт в реалии веб-дева, где завтра может прийти заказчик и сказать «Знаешь, там при делении не на 3 и 5 надо выводить MissKiss, а на 47 и 82. И ещё на 25 выводить Bingo!» и поэтому максимально прозрачно перевели условия в код, не экономя сравнения.
С искусственными задачами всегда так, кто что додумал, тот так и сделал. Хотя из условий задачи (JavaScript), по умолчанию, я бы не стал экономить на копеечных операциях.
VaalKIA
18.05.2017 03:59Не одному, но я бы писал через промежуточную переменную, но с асинхами не рабтаю:
var out_str: String; begin ... if (value % 5) = 0 then out_str:="Miss"; if (value % 3) = 0 then out_str:=out_str+"Kiss"; Print(out_str); end
Типа такого.evkin
18.05.2017 19:44Я джавист, поэтому выделять переменную, да и еще и генерить несколько строк в результате их соединения, для меня лютый оверхед, если можно просто вынести их как константы)))
sumanai
18.05.2017 20:20-1лютый оверхед
Замерить сможете?evkin
19.05.2017 01:51+1Ну, давайте попробуем:
Код тестаpackage test; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import java.util.concurrent.TimeUnit; @State(Scope.Thread) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public class MyBenchmark { @Benchmark public void testOptMethod(Blackhole bh) { for (int y = 0; y < 100; y++) { if (y % 3 == 0) { bh.consume(y % 5 == 0 ? "MissKiss" : "Miss"); } else { bh.consume(y % 5 == 0 ? "Kiss" : Integer.toString(y)); } } } @Benchmark public void testMethod(Blackhole bh) { for (int y = 0; y < 100; y++) { String outStr = ""; if ((y % 5) == 0) outStr="Miss"; if ((y % 3) == 0) outStr=outStr + "Kiss"; bh.consume(outStr.isEmpty() ? Integer.toString(y) : outStr); } } }
VaalKIA
19.05.2017 05:21Ну вообще-то переменная в Паскале выделяется вне цикла, для этого есть специальный раздел var. Если вы спросите, а как можно выделить позже, то отвечу — можно, но не везде. Например, был такой ТМТ Паскаль, там есть очень хороший оператор declare, позволяющий делать это в любом месте. Так что тест не совсем идентичен, хотя за результат — спасибо, всегда интересно знать, что потенциально понятный тебе язык — незнаком на самом деле.
maeris
19.05.2017 13:14+1Конкатенация строк создаёт новую строку в любом языке. Такие же проблемы были бы и на С++. В этой задаче просто не стоит использовать +=.
mayorovp
19.05.2017 13:26Разница в том, что в Паскале (да и в С++ при использовании std::string) копирование строки происходит не только при конкатенации, но и при простом присвоении, из-за чего конкатенация теряет свою относительную стоимость.
maeris
22.05.2017 01:55Неправда, в С++ есть move semantics. Если строка создана как temporary и присваивается в переменную, копирования не будет.
evkin
19.05.2017 15:14Конечно же правильно вынести переменную вне цикла.
Можно даже сделать её полем класса (но это не самый лучший вариант, т.к. код становиться не многопоточным).
Проблема в том, что соединение строк — это всегда создание нового объекта в джаве и соответствующие копирование памяти 2х строк, в новый буфер.
sumanai
20.05.2017 00:42Просто подумалось, что оптимизатор нивелирует разницу между этими двумя вариантами. Оказывается, я его переоценил.
Ogoun
17.05.2017 19:39-2names = { 1: "Fizz", 2: "Buzz", 3: "FizzBuzz" } for x in [(i, int(i%3==0) + (int(i%5==0)<<1)) for i in range(0,100)]: print(x[0] if x[1] == 0 else names[x[1]])
vadimr
17.05.2017 22:03+2Да, я тоже подумал, что наиболее красиво будет условие сформулировать таким образом. Хотя наиболее удобочитаемо — проверить тупо три раза. В этом и есть настоящая изюминка задачи.
Lailore
18.05.2017 10:40-2Это не изюминка, а проверка на скилл. Два или три IF это базовая оптимизация, которая говорит о том, думает ли человек вообще о производительности. Удобочитаемость совершенно не страдает. Код который привел Ogoun пошел еще дальше, и оптимизировал использование оперативной памяти. И это хорошо. Когда много такого кода видишь, то все тоже удобочитаемо. Признайтесь, вы же вообще не задумывались/искали профайлером сколько нагружают память и GC спам обычных строк?
mayorovp
18.05.2017 10:51Не обязательно вот так выкручиваться с массивами для того чтобы просто избежать аллокации строк.
Lailore
18.05.2017 10:57Вот так может и ненадо, но иметь коллекцию нужных строк и переиспользовать их — шаг в правильном направлении
mayorovp
18.05.2017 11:00+2Не вижу преимуществ перед обычными строковыми литералами, до тех пор пока каждый из них встречается всего 1 раз.
VolCh
18.05.2017 11:06Более того, движки всё умнее становятся, и вполне могут оптимизировать сами если несколько раз строка одна строка встречается.
mayorovp
18.05.2017 12:34Я говорил не про оптимизацию, а про поддержку кода. Нетривиальная неименованная магическая константа в коде, которая встречается более одного раза — путь к ошибкам.
Lailore
18.05.2017 11:18тут есть конкатенация без использование массива
mayorovp
18.05.2017 12:33Не во всех решениях. В моем, например, ее нет.
Что лишняя конкатенация строк — это нехорошо, я с вами согласен. Но, во-первых, эта задача слишком простая чтобы конкатенация успела стать проблемой — а во-вторых, не обязательно настолько корежить код чтобы от нее избавиться.
vadimr
18.05.2017 11:06Я не столько про память думал, сколько вообще про красоту кода. Противно два раза подряд проверять одно и то же. А сыграть это может, если целые числа заменить на какие-нибудь активные объекты (имеющие конструкторы, или вычисляющиеся в результате вызова функций, или асинхронно изменяющиеся).
Уважаемого товарища Ogoun я бы взял на работу без дальнейшего интервью, если бы он написал на собеседовании такой код, сопроводив замечанием об удобочитаемости (даже несмотря на ошибку на единицу в range). Видно, что программист дельный.Lailore
18.05.2017 11:20И да, я посыпаю голову пеплом. Так как не знаком с языком не увидел, что здесь используется все теже три условия. Остается только оптимизация памяти…
vadimr
18.05.2017 11:26Он проверяет каждое деление по одному разу, в то время как большинство других примеров дважды проверяют делимость на 3.
Lailore
18.05.2017 11:29Я про то, что в коде есть три "==", и в худших случаях все три условия будут проверяться. Можно сделать в два условия.
А то что тут типографическую показывают, «какой я молодец» по типу
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')}
Это вообще трындец с 4 проверкамиvadimr
18.05.2017 11:52А, ну в печати-то, конечно, можно дальше оптимизировать. Я про саму схему проверки.
maeris
19.05.2017 13:17А ещё можно избавиться от &&, который в ассемблере всё равно будет дополнительным условием. Достаточно вспомнить, что если что-то делится на 3 и 5, то оно делится на 15.
mayorovp
19.05.2017 13:27+1И вам тоже стоит посмотреть бенчмарк — https://jsperf.com/misskiss
Проверка делимости на 15 работает медленнее чем две проверки делимости на 3 и на 5.
mayorovp
18.05.2017 13:10+1Нельзя оптимизировать код без бенчмарков — очень легко завести оптимизацию не в ту сторону.
Вот и вы зачем-то считаете проверки, из чего делаете вывод о "трындеце" c 4 проверками. А на самом деле операция обращения к элементу массива или свойству объекта съедает намного больше времени чем какая-то проверка. По крайней мере, в Хроме.
Вот сравнение: https://jsperf.com/misskiss
Lailore
18.05.2017 13:42Изините, я кажется запутался и сломал страничку своей ревизией =(
А теперь по теме:
Я почти испугался =) Только я постоянно говорил про проверки, а самый быстрый результат как раз с 2 проверками. И конечно массив проигрывает константам, но на грани погрешности(у меня пару раз выигрывал) 2%. Массив нужен уже для больших задач, когда GC и аллокации начинают давить на мозг.
var names = ["Miss", "Kiss", "MissKiss"] for (var i=1; i<=100; i++) { if (i%5==0) { if(i%3==0) console.log(names[2]); else console.log(names[1]); } else { if(i%3==0) console.log(names[0]); else console.log(i); } }
mayorovp
18.05.2017 13:45Зачем? Что вы ускоряете столь странным образом?
Lailore
18.05.2017 14:02Этот вариант использует «самые быстрые две проверки», но использует массив, что бы не разбрасываться памятью и он по сути не уступает самому быстрому варианту(две проверки с константами)
mayorovp
18.05.2017 14:04Каким образом исходный вариант "разбрасывался памятью"?
Lailore
18.05.2017 14:12Конечно я усложнил пример, для этой маленькой задачи.
Разбрасываться начнет, когда эти строчки («Miss», «Kiss», «MissKiss») будут использоваться из разных источников и в разных частях программы.
Тоесть в моем утрированном случае по всюду будут зааллоцированы строки «Kiss», вместо того, что бы ссылаться на одну строку.
mayorovp
18.05.2017 13:47И заметьте: там было два варианта, в который вообще не было проверок.
Один из них (switch) по скорости — немного хуже чем вариант с 4 проверками, второй (array 15) — и вовсе является самым медленным!
PS вы ничего не сломали, вы выпустили новую ревизию бенчмарка. Только немного странную :-)
Lailore
18.05.2017 14:02switch это куча проверок. И хорошо работает только на огромных вариациях. При маленьком количестве это все разворачивается в иф елсе(верно для c#, js незнаю)
А насчет array 15 это класическая ошибка новичков, из-за которой кеш процессора постоянно промахивается, из-за непоследовательного обращения к элементам + там не значения, а лямбды
Вот что я об этом думаю)
Alexs177
18.05.2017 00:00-3for (var i=0; i< 20; i++){ 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)} }
Очень простое решение, минуты 3, после пива и при том что Python изучаю. Это серъёзно про 199 из 200 не могут написать?tangro
18.05.2017 12:28-1Очень простое, но очень неэффективное: 2 лишних сравнения, 2 лишних вычисления остатка от деления, один лишний if и 2 лишних else.
Alexs177
18.05.2017 21:39Напишите более эффективное решение раз уж критикуете.
tangro
19.05.2017 10:38+1Так тут такие выше и ниже уже написаны. Просто посмотрите на код и задайте себе вопросы: а нужно ли в нём дублирование проверок «i%3 ==0» и «i%5 ==0»? Может быть можно по одному раз проверять? Нужны ли в двух местах кода строки «Miss» и «Kiss» — возможно, будет достаточно по одному их экземпляру? И код вырисовывается сам.
serginho
18.05.2017 00:13+4Мне кажется, что даже правильный ответ в статье не совсем правильный. Ибо между выводами не 50мс, а 50мс + (время работы функции). Чтобы вызовы были действительно асинхронными, я думаю, правильнее будет писать так
Lailore
18.05.2017 10:43Тоже это заметил в решениях. Но правильный путь это подготовить результаты, а в нужное время лишь брать их. В js завезли многопоточность? Можно мультипоточно заполнять очередь?
VolCh
18.05.2017 11:44-1Можно относительно легко организовать два псевдопотока — один заполняет очередь, а другой читает из неё по интервалу 50мс.
const queue = []; const interval = window.setInterval(() => { console.log(queue.shift()); if (queue.length === 0) { window.clearInterval(interval); } }, 50); for(let i=1; i<=100; ++i) { let str; if (i % 3 === 0) { if (i % 5 === 0) { str = 'KissMiss'; } else { str = 'Kiss'; } } else if (i % 5 === 0) { str = 'Miss' } else { str = i; } Promise.resolve().then(() => queue.push(str)); }
nexmean
18.05.2017 01:17+1Задачу решил меньше чем за 5 минут, ограничен я был в решении только скоростью печати. Если честно не представляю как на подобное можно больше часа потратить.
const fn = () => { for (let i = 1; i <= 100; i++) { setTimeout((number) => { if (number % 3 === 0 && number % 5 === 0) { console.log('MissKiss') } else if (number % 3 === 0) { console.log('Miss') } else if (number % 5 === 0) { console.log('Kiss') } else { console.log(number) } }, i * 50, i) } } fn()
MooNDeaR
18.05.2017 04:27Я вообще с трудом представляю, почему на хабре статья про FizzBuzz имеет 150+ комментариев, а не заминусована в хлам.
Ruslan_aia
18.05.2017 07:00Комменты выше, где такую задачу решают с промисами, асинхронностью, дополнительными функциями, переменными, проверок потом этих переменных и прочей жестью, напоминают мне консольный Hello World на VB6:
Option Explicit Declare Function AllocConsole Lib "kernel32" () As Long Declare Function FreeConsole Lib "kernel32" () As Long Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" _ (ByVal hConsoleOutput As Long, lpBuffer As Any, ByVal _ nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, _ lpReserved As Any) As Long Declare Function Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) As Long Private Sub Main() 'create a console instance AllocConsole 'get handle of console output Dim hOut As Long hOut = GetStdHandle(-11&) 'output string to console output Dim s As String s = "Hello, World!" & vbCrLf WriteConsole hOut, ByVal s, Len(s), vbNull, vbNull 'make a pause to look at the output Sleep 2000 'close the handle and destroy the console CloseHandle hOut FreeConsole End Sub
3vi1_0n3
18.05.2017 08:48-2#!/bin/bash for i in {1..100} do a=0 [ $(( $i % 3 )) -eq 0 ] && echo -n 'Fizz' && a=1 [ $(( $i % 5 )) -eq 0 ] && echo -n 'Buzz' && a=1 [ $a -eq 1 ] && echo done
Таки меньше 10 минут3vi1_0n3
18.05.2017 08:55-3Я прошу прощения, что не на джава-скрипте, просто задачка подходит для любого языка просто отлично
mwizard
18.05.2017 11:48+3паузы и асинхронные вызовы забыли. В bash это было бы с
&
иwaitpid
.3vi1_0n3
18.05.2017 13:45Тогда как-то так
#!/bin/bash console.log(){ local i=$1 local result="" a=0 [ $(( $i % 3 )) -eq 0 ] && result+='Fizz' && a=1 [ $(( $i % 5 )) -eq 0 ] && result+='Buzz' && a=1 [ $a -eq 0 ] && result+="$i" echo $result } for i in {1..100} do ( sleep 0.05 console.log $i ) & done wait
Даже console.log естьmwizard
18.05.2017 13:50Но если у меня правильно работает интерпретатор bash в голове, то это код не будет ждать между выводами значений — вместо этого он подождет 50 мс только при запуске, а потом выплюнет все сразу, т.к. sleep происходит вомножестве подпроцессов одновременно. Нужно, чтобы паузы были между выводами, но при этом чтобы каждый вывод был асинхронным.
3vi1_0n3
18.05.2017 14:58Вы уверены, что в условии так написано?
mwizard
18.05.2017 15:00Абсолютно уверен, посмотрите дискуссию в этом посте :) Просто пауза перед выводом любых значений не добавляет в задачу сложности.
3vi1_0n3
18.05.2017 15:12Можно, поменять местами wait и done, но это все равно будет не совсем то. В результате накладных расходов еще на 0.4 секунды. Спасибо за уточнения
Enmity
18.05.2017 09:05-2а про тернарные условия все забыли :<
for(int i=1; i<=100;i++) {System.out.println(i % 5 == 0 && i % 3 == 0 ? "MissKiss" : i % 5 == 0 ? "Kiss" : i % 3 == 0 ? "Miss" : i);}
daemonhk
18.05.2017 10:36-3PHP, 4 минуты
for($i=1;$i<=100;$i++){ if($i%3==0 && $i%5==0){ echo "KISSMISS"; echo "\n"; }elseif($i%3==0){ echo "MISS"; echo "\n"; }elseif($i%5==0){ echo "KISS"; echo "\n"; }else{ echo $i; echo "\n"; } }
daemonhk
18.05.2017 11:19-1Я так понимаю, минусы получают за:
1. Другие языки
2. Неоптимизированность кода
Но задача решена ведь, в чем проблема? Да, можно уложиться в меньшее кол-во строк, но это уже потом, после того, как получится правильное решение. Или у нас набег лютых ненавистников PHP?grossws
18.05.2017 12:10+3Минусы получают те, кто не справился с чтением условия, где сказано про асинхронный вывод результата. И даже прочитав комментарии не способен понять почему решение неверно.
Goodkat
18.05.2017 10:38Интересно.
Задачка с подвохом.
Я вот тоже набрал текст за 2 минуты в консоли браузера, а потом прочёл, что надо асинхронно.
Сделал асинхронно, а потом увидел, что хотя вывод через console.log и был верным, но первый вызов функции пишет в консоль результат undefined, что абсолютно корректно, но портит вывод.
«Правильное» решение по ссылке из статьи тоже пишет undefined в самом начале, так что его я бы тоже не засчитал.comerc
18.05.2017 10:43+2Undefined пишет консоль браузера, показывая вам возврат по об'явлению функции
mayorovp
18.05.2017 10:57Это особенность именно что интерактивной консоли. При запуске из скрипта первого undefined не будет.
SergeyUstinov
18.05.2017 11:16— T SQL
declare @i int;
set @i = 1;
CREATE TABLE #test ([Step] int, [Result] nvarchar (10));
WHILE @i <= 100
BEGIN
INSERT INTO #test
select
@i as [Step]
,case
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) and cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'FizzBuzz'
when cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'Buzz'
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) then 'Fizz'
else cast (@i as nvarchar)
end as [Result]
;
set @i = @i + 1;
END
select [Result] from #test;
Потратил 20 минут… Плохо…mwizard
18.05.2017 12:37И задержки нет :) Правда, я даже не знаю, как сделать задержку в T-SQL, разве что через UDF?
MINYSMOAL
18.05.2017 19:31зачем таблицу создавать?
DECLARE test TABLESergeyUstinov
22.05.2017 13:00-1А иначе вывод некрасивый :)))
Result ------------------------------ 1 (1 row(s) affected) Result ------------------------------ 2 (1 row(s) affected) Result ------------------------------ Fizz (1 row(s) affected) Result ------------------------------ 4 (1 row(s) affected) Result ------------------------------ Buzz (1 row(s) affected) Result ------------------------------ Fizz (1 row(s) affected)
и т.д.mayorovp
22.05.2017 13:05Да с чего бы такой вывод был из табличной переменной-то?
SergeyUstinov
22.05.2017 13:23Какая табличная переменная?
Вот первый вариант (просто написал «в лоб», обычно циклы для таких задач не использую):
declare @i int; set @i = 1; WHILE @i <= 100 BEGIN select case when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) and cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'FizzBuzz' when cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'Buzz' when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) then 'Fizz' else cast (@i as nvarchar) end as [Result] ; set @i = @i + 1; END
Вывод не понравился и немного доработал.mayorovp
22.05.2017 13:25Цитирую:
зачем таблицу создавать?
DECLARE @test TABLE
SergeyUstinov
22.05.2017 13:42Чтобы сделать более красивый вывод.
Или вопрос звучит как: «Почему таблицу, а не табличную переменную?»
Я с табличными переменными обычно не работаю, в основном с временными таблицами. Вот и создал временную таблицу.
Select… Into… в данном случае работать не будет — мы селект выполняем 100 раз.
devalone
18.05.2017 11:38-1Это же троллинг такой, да? Как можно на это потратить больше 10 секунд? Ну ладно, если человек редко пишет что-то связанное с математикой, ему понадобится вспомнить, что % — это остаток от деления, может нагуглить, чтоб убедиться, это максимум 5 минут. Но не 67 же! С другой стороны, если ситуация и вправду такая печальная, у меня будет больше шансов устроиться на работу :)
devalone
18.05.2017 12:16+1Минусы от jquery-программистов?
mwizard
18.05.2017 12:21+1для того, чтобы за 10 секунд набрать приблизительно 400 знаков, не считая пробелы, вы должны просто необыкновенно быстро печатать. Но несколько минут — да, реалистичная оценка.
devalone
18.05.2017 12:29Я имел ввиду продумывание алгоритма. И да, в первоначальной задаче не указан язык, на C++ это будет примерно 250)
mwizard
18.05.2017 12:32Позвольте вас вызвать на поединок — я хочу посмотреть, как вы выполните условие с асинхронностью (каждый print в отдельном потоке), уложившись в 250 знаков без учета whitespace. Только без читерства с созданием одной огромной строки из смеси пробелов и tab-ов, в которой закодирована остальная реализация :)
Продумывание да, 10 секунд от силы, согласен.
devalone
18.05.2017 13:05На js не пишу, но как вариант что-нибудь такое
var i=1;function doIt(){var r="";if(i% 3== 0|| i% 5== 0){if(i% 3== 0){r+= "Miss"};if(i% 5== 0){r+= "Kiss"}}else {r+= i};console["log"](r);i++;if(i<= 100){setTimeout(doIt,50)}}doIt()
182 символаmwizard
18.05.2017 13:05на C++ это будет примерно 250)
Но это не C++ :)
devalone
18.05.2017 13:18Так на C++ не было условия задержки, асинхронности и многопоточности, если без них, то вот:
#include <iostream> int main() { for(int i = 1; i <= 100; i++) { if (i % 3 == 0 || i % 5 == 0) { if (i % 3 == 0) std::cout << "fizz"; if (i % 5 == 0) std::cout << "buzz"; } else std::cout << i; std::cout << std::endl; } }
Можно поизвращаться с оптимизацией
#include <iostream> int main() { for(int i = 1; i <= 100; i++) { bool ch1 = i % 3; bool ch2 = i % 5; if (!ch1) std::cout << "fizz"; if (!ch2) std::cout << "buzz"; if(ch1 && ch2) std::cout << i; std::cout << std::endl; } }
по идее переменные будут регистровыми и процессору на пару операций меньше нужно будет делать, но по факту всё упрётся в медленный вывод на экран. А многопоточность конечно можно добавить и не сильно много символов будет, но смысла от неё в этой задаче не будет никакого.mwizard
18.05.2017 13:20Ну так и на JS смысла от задержки нет никакого, как, впрочем, и у самой задачи нет особого смысла. Просто нужно так сделать :)
MooNDeaR
18.05.2017 19:54-1#include <iostream> #include <future> using namespace std; auto&& s=cout; void f(int i) { this_thread::sleep_for(chrono::milliseconds(50)); if (!(i%15)) s << "MissKiss"; else if (!(i%3)) s << "Miss"; else if (!(i%5)) s << "Kiss"; else s << i; s << endl; if (i == 100) return; return async(f, ++i).get(); } int main() { async(f,1).get(); return 0; }
~275-300 символов и 15 минут из которых 10 потрачено на попытки ужать в 250 символов, но это возможно только если выкинуть заголовочники.MooNDeaR
18.05.2017 20:07-1#include <iostream> #include <future> using namespace std; auto&& s=cout; int f(int i) { this_thread::sleep_for(chrono::milliseconds(50)); if(!(i%15))s<<"MissKiss"; else if (!(i%3))s<<"Miss"; else if (!(i%5))s<<"Kiss"; else s<<i;s<<endl; return i<100?async(f,++i).get():0; } int main() { return async(f,1).get();; }
Всё. Теоретический минимум 285 символов без учета переноса строк. 257, если не считать пробелы.
VovanZ
22.05.2017 20:30+2асинхронностью (каждый print в отдельном потоке)
Для асинхронности не нужны отдельные потоки.
mwizard
18.05.2017 11:47Ровно пять минут, и то это долго. В гугл не смотрел, т.к. без необходимости. Запускать в
node --harmony
.Lailore
18.05.2017 12:10-1Вы по моим наблюдением побили рекорд. Даже не четыре, а пять проверок условий вместо двух Оо
faiwer
18.05.2017 12:16+4@Lailore, я всё никак в толк не возьму, вы шутите или таки серьёзно? Объясните мне неразумному, какой смысл акцентировать внимание на количестве примитивных условий в JS-коде, который на каждую итерацию создаёт новый анонимный метод и promise? Если уж пытаться где-то сэкономить, то уж точно не на вот таких вот проверках. А если вспомнить ещё во что превращается async-await код (конечный автомат, нечто вроде большого switch-case), то вам наверное вообще поплохеть должно? )
mwizard
18.05.2017 12:20ну, на практике т.к. тут нет closure в
function sleep
, поэтому новый анонимный метод не будет создаваться каждый раз — вместо этого движок один раз скомпилирует шаблон функции и будет использовать его в дальнейшем. Но да, в этом была суть моего комментария чуть ниже вашего.
И в данном случае тут async/await ни во что не превращается, т.к. node 7.9.0 уже умеет async/await из коробки. Ну и в принципе в ES6 окружении это уже скорее были бы генераторы… не знаю даже, что хуже :)
faiwer
18.05.2017 12:27поэтому новый анонимный метод не будет создаваться каждый раз — вместо этого движок один раз скомпилирует шаблон функции и будет использовать его в дальнейшем
Понимаю, оптимизациям быть. Но думаю это тоже не совсем "бесплатно".
И в данном случае тут async/await ни во что не превращается, т.к. node 7.9.0 уже умеет async/await из коробки.
Ну дык в AST будет тот же самый конечный автомат? Разве нет? Тут с пол года назад публиковали статью, как на основе generators в Edge js-движок добавили async-await (первыми). Там это детально расписывалось.
mwizard
18.05.2017 12:34+1Бесплатного ничего не бывает — скорее всего, несколько итераций цикла у движка займет анализ того, что поведение функции не меняется, т.к. не сорвется ни одна проверка на деоптимизацию (я не помню, как называются эти внутренние assert-ы, увы). Если бы fizzbuzz выполнялся на хотя бы тысячах итераций, возможно, это было бы заметно.
Ну дык в AST будет тот же самый конечный автомат?
Не-а, именно в AST будет ровно то же, что видно глазами. Вы имели в виду IR, Intermediate Representation — там, возможно, мог бы быть конечный автомат, но не факт, т.к. async-функции имеют более сложную семантику, чем одна перезапускающаяся функция с параметром, равным состоянию автомата. Но я понимаю, к чему вы — async-функции можно выразить через генераторы, а генераторы в свою очередь можно выразить через конечные автоматы. Результат будет монструозным, и с повсеместным введением поддержки ES5 в нем больше нет необходимости.
Lailore
18.05.2017 12:20Да, с этим я согласен. Свой вариант решения этой проблемы я описал тут
faiwer
18.05.2017 12:36Но правильный путь это подготовить результаты, а в нужное время лишь брать их.
Категоричное утверждение. Каждой задаче свой инструмент. Каждому инструменту — свой стиль, свои требования. Когда вы пишете js-код, то чаще всего, правильнее будет написать:
- простой
- очевидный
- легко расширяемый и легко тестируемый
код. Перед задачами, которые решаются на этом языке, чаще всего стоит несколько другие требования, чем, скажем, перед теми, кто пишет на C++. И если стоимость такой вот оптимизации (время=деньги) не превалирует над преимуществами от этого решения, то эта оптимизация ? пустая трата денег. В JS когда речь заходит о производительности, обычно есть места, которые могут ускорить работу нагруженного участка на порядок или более. И почти всегда это не спички, а аллокация в цикле или что-нибудь в таком духе.
Lailore
18.05.2017 12:53И я конечно с вами соглашусь, я сам когда пишу функции в азуру на раз не трачу много времени. Но это же хабр, и пусть пример такой простой, но я очень люблю читать подобные обсуждения. Ведь такие разборы примера могут натолкнуть меня, джуна, супер пупер звезду, на мысль, как глубока кроличья нора.
Если что, то выше обсуждают ассамблер. Люблю хабр.
mwizard
18.05.2017 12:16+4Вы еще
x <= 100
в проверки посчитайте, будет шесть. Какой смысл экономить на сравнениях, когда в функции используется передача управления в event loop? Это называется "микрооптимизация", или "экономия на спичках".
Цель проверки — сделать быстро и читабельно. Посильную помощь оптимизатору, явно указав результат сравнений как константы, я оказал. И я могу быть не прав, но на мой взгляд, мой пример кода на порядок читабельнее решений типа этого.
vadimr
18.05.2017 22:24-1Ваш код более читабельный, но код по ссылке менее хрупкий (fragile).
Ваш код (и другие приведённые здесь подобные ответы) порождает раздумья сопровождающего его программиста вот над какой проблемой: если мы в одном месте поменяли, например, by3 на какое-то другое условие, надо ли проводить такую же замену в другом месте? Эта дилемма возникает при кодировании совершенно на пустом месте, потому что постановка задачи её не предопределяет, и в коде по ссылке её просто нет.CrazyNiger
19.05.2017 09:50+1by3 объявлен через const, потенциальные «другие места» заканчиваются в конце блока на пять строчек.
vadimr
19.05.2017 09:54Ну в реальной жизни-то будет посложнее задача и побольше кода. А паттерны в голове у программиста – те же самые.
mwizard
19.05.2017 10:03Отвечу вам контрпримером. Если нужно будет добавить новое условие, по которому в случае деления на 7 без остатка надо выводить "Piss" — сколько изменений потребуется в моем коде и сколько в "менее хрупком"?
vadimr
19.05.2017 10:22Вопрос же не в том, сколько символов и в каком месте менять, а в том, как это заметить. Вы описываете внесение двух изменений: добавление проверки делимости на 7 и добавление вывода строки «Piss». Очевидно, обе эти вещи надо где-то прописать. В Вашем случае они будут находиться в одной строке, а в примере выше – в разных строках, но это ничего не меняет.
Если говорить о новых изменениях, представьте себе, например, что заказчик решил буквально чуть-чуть уточнить условия задачи и ввести список чисел, которые делятся на 3, но не относятся к категории Fizz, делятся на 5, но не относятся к категории Buzz и т.п., в результате чего условия by3 и by5 – это теперь запросы к базе данных исключений из правил, которые занимают по 10 минут.
Тут можно много чего напридумывать.mwizard
19.05.2017 10:48+1А вот перечисленное вами — еще одна из причин, почему "программисты не могут программировать".
Речь не только об отсечении тех, кто никогда строчки кода не набрал, речь еще и о тех, кто в размышлениях на тему "а что если деление на 3 будет в будущем реализовано как длительное обращение к базе данных, надо предусмотреть механизм для этого", "а вдруг у заказчика появится необходимость добавить новые условия, и еще настраивать их через конфиг-файл, давайте сделаем декларативный DSL для определения делителей и требуемого действия", и т.д. заходит в дебри полного паралича, т.к. никогда не получится сделать идеально гибкое решение, которое предусмотрит все возможные будущие юзкейсы, которые, возможно, никогда не наступят.
И это уже называется "оверинжиниринг".
vadimr
19.05.2017 11:12-2Идеал недостижим, но определённые предпосылки вполне можно создать без особых затрат.
mayorovp
19.05.2017 11:32+1Вот когда заказчик уточнит условия задачи — тогда и будем думать что с этим делать. Пока что надо просто оставить будущим коллегам понятный код.
faiwer
18.05.2017 11:51+1Читая споры про эти 50ms в условиях задачи мне волей не волей вспомнился ACM. Когда я был ещё студентом, и пытался участвовать в ACM нашей недокоманде очень сильно не хватало знания языка. Я его понимал на уровне beginner, а мои товарищи на уровне lower intermediate. В итоге на олимпиадки мы ездили со здоровенным техническим англо-русским словарём. Тяжеленным таким. Все задачи на английском. Авторы задач никогда не утруждали себя в том, чтобы максимально очевидно и понятно донести до студентов задачу. Все задачи заключали в себе такой текст, что если хорошо приглядеться и призадуматься, то каких-то вольностей толкований условий не остаётся. Но это разве что для native speaker-ов. Для всех остальных это было серьёзной преградой. Многие тонкости лежали за той гранью лингвистики, которую мы могли осилить. На тот момент было очень обидно, ибо ситуации когда какая-нибудь едва приметная мелочь переворачивала всё вверх ногами были весьма частыми.
maeris
19.05.2017 13:23+3Да, тоже когда-то от этого страдал. В ретроспективе это даже кажется правильным. Согласитесь, программисты без знания английского языка никому не нужны. Если не преподают необходимый английский на достаточном уровне, то команда АСМ займёт места намного ниже, и это скажется на рейтинге вуза.
faiwer
19.05.2017 13:32Согласитесь, программисты без знания английского языка никому не нужны.
С этим не соглашусь. Мне вообще кажется, что сейчас очень большая потребность в относительно слабых и немощных программистах, способных разворачивать готовые коробочные решения и подтачивать их под нужды малого бизнеса. И всё это за сравнительно небольшие деньги. Во всяком случае, я наблюдаю это сплошь и рядом. Эта область процветает.
Сразу отмечу, что считаю, что программисты это те люди, ключевой задачей которых является написание программного кода, вне зависимости от качества такой работы. Т.е. я стараюсь судить об этом термине как о профессии. Если человек зарабатывает этим на жизнь (есть спрос на такой труд).
Lailore
19.05.2017 13:39И в этом большая проблема =( Это портит имя профессии. Тут надо ввести новое название, как например: есть врач, а есть фельдшер.
faiwer
19.05.2017 13:44А вы вспомните про "Тыжпрограммист, холодильник мне почини". Не вижу особого смысла в большом разнообразии названий. Понимающий народ начнёт плавать (как сейчас происходит в англ. языке). А непонимающий всё также будет объединять всё то, что связано с компьютерами в одну отрасль :)
faiwer
19.05.2017 14:10Перечитал свой комментарий. Какой-то он высокомерный получился, я вовсе не это хотел донести :) Поэтому уточню: эти самые готовые коробочные решения, в случае если они популярны, как правило располагают большим количеством русскоязычной документации и разного рода статей, на том же хабре. И можно быть весьма успешным специалистом в этой области без достаточных познаний в языке.
Это, правда, не отменяет того факта, что хороший (даже очень хороший) программист может обладать весьма зачаточными знаниями языка, и читать зарубежные материалы через "боль и страдания" (но таки читать, куда же он денется). Ну хотя бы потому, что самые легендарные бессмертные издания давно уже переведены, а сама работа не подразумевает под собой лингвистических изысков. Но такой программист будет постоянно испытывать неудобства.
В целом, моё мнение, невысокий уровень языка как среди IT-ов, так и среди народа в целом во многом обеспечен тем, что ареал и "популяция" языка (русского) огромные. Насколько я помню, русскоязычные интернеты идут вторым номером среди всех языковых интернетов (после англ, разумеется). Поэтому острой необходимости учить какой-либо другой язык не стоит. А человек по природе своей — ленив.
kloppspb
19.05.2017 13:49+1программисты без знания английского языка никому не нужны
Я, например, его не знаю. В школе учил французский с 8 лет :) и т.д. Всё, что есть — самообучение в процессе кнопкотыркательства. Маны читаю, SO/форумы тоже, могу что-то написать, но попросите поговорить или воспринять информацию на слух — могут быть проблемы.
Это ни разу не называется «знать язык», но такой уровень никак не мешает быть программистом.
Другое дело что сейчас можно встретить «программистов», которые «Hello, World» не только написать не могут, но и перевести на русский…mayorovp
19.05.2017 14:39И такого уровня знания английского достаточно для понимания условий всех задач на финале :-)
SSul
18.05.2017 14:22А Вы не пробовали знаки препинания расставлять когда задание пишете? «Но для кратных трём значений «Fizz» вместо номера...» пять минут потратил чтобы понять, что же здесь хотят)
Beshanoe
18.05.2017 14:52+2? \ _ (?) _ / ?
function KissMiss(next = 1, msg = ((next % 3?'':'Miss') + (next % 5?'':'Kiss')) || next) { next++ <= 100 && setTimeout(() => (console.log(msg), KissMiss(next)), 50) } KissMiss()
haldagan
19.05.2017 12:17+4Мне так понравилось ваше решение, что я взял на себя смелость сделать его чуть более лаконичным и чуть более человекопонятным.
Сначала я просто думал избавиться от путающих неподготовленного человека тернарных операторов, но потом решил, что лучше уж избавиться сразу ото всех операций сравнения.
Плюс вы слишком расточительно относитесь к размеру кода в целом и к размерам имен переменных в частности.
Представляю вам решение задания без единой операции сравнения(а не только с отсутствующими if/switch/тернарками):
(K=(n,m='Miss',k='Kiss',s=[[m+k,k,k],z=[m,n,n],z,z,z][n%5][n%3])=>{p=(101-n++);p/=p;try{eval(p+''+p);setTimeout(()=>(console.log(s),K(n)),50)}catch(e){}})(1)
Скрытый текстНа правах шутки.haldagan
19.05.2017 19:38Чуть оптимизировал и сократил еще на 6 символов: https://codepen.io/anon/pen/xdyBZq
Если кто знает более красивое решение вместо eval'a — отпишитесь, пожалуйста.
procode
18.05.2017 17:16-4Да ну блин, дурь всё это, для молодняка членомерки.
Реальные задачи как правило требуют совсем других качеств, нежели умение составлять алгоритмы на скорость.
Сейчас на первом месте способность к совместному кодированию в рамках единой концепции(фреймворка).mwizard
18.05.2017 20:52+4Уважаемый, вы не поняли суть. Это не проверка умения быстро составлять "алгоритмы" (алгоритмы у fizzbuzz, серьезно?). Это своеобразный smoke test, чтобы отличить программиста (любого уровня) от человека, который умеет с умным видом говорить баззворды.
И только если кандидат проходит эту элементарную проверку, уже имеет смысл спрашивать о чем-то другом.
procode
19.05.2017 12:33Я понятия не имею что такое «с умным видом говорить баззворды» :)
В общем, наверное я действительно не понял в чем суть сабжа.
Какой смысл человеку не умеющему писать программы устраиваться на работу программистом? *ритор.*kloppspb
19.05.2017 12:43+4Какой смысл человеку не умеющему писать программы устраиваться на работу программистом?
Так они же себя программистами вполне считают.
VolCh
19.05.2017 13:40Он-то считает, что умеет — отличные оценки в дипломе и работающий сайт на ВордПресс
Quarc
18.05.2017 20:56Увы, почти 15 минут.
#include <iostream> #include <future> #include <chrono> #include <thread> using namespace std; int main() { for (int i = 1; i <= 100; ++i) { async(launch::async, [=](){ this_thread::sleep_for(chrono::milliseconds(50)); if (i % 3 == 0) { cout << "Miss"; if (i % 5 == 0) { cout << "Kiss"; } } else { if (i % 5 == 0) { cout << "Kiss"; } else { cout << i; } } cout << endl; }); } return 0; }
hhg
19.05.2017 21:50А я вот на c++ с ходу не осилил :(
#!/usr/bin/env perl use strict; use threads; use Time::HiRes qw( usleep ); sub out_tomorrow{ my ($delay,$str)=@_; usleep($delay*50000); print $str; threads->detach(); } for( my ($i,$c3,$c5)=(1,2,4); $i<=100; $i++, $c3--, $c5-- ){ my $s = ( ( (!$c3) || (!$c5) ) ? '' : $i ) . ( $c3 ? '' : ($c3=3,"Fizz") ) . ( $c5 ? '' : ($c5=5,"Buzz") ) . "\n" ; threads->create( {'void' => 1}, \&out_tomorrow, $i, $s ); } while( threads->list(threads::running) ){};
AIxray
19.05.2017 20:37И хоть я уложился в менее 10 минут, я всё равно не могу считать себя программистом, т.к. программисты бывают разные, вот когда научусь писать математические задачи под цели NASA то да возможно, а так можно сказать необъективно все эти тесты, другими словами надо учитывать, что порог вхождения в программирование с каждым годом по факту усложняется, но и методы программирования упрощаются. Вообщем. Что хочу сказать, учиться, учиться и ещё раз учиться писать АЛГОРИТМЫ.
VolCh
20.05.2017 14:03Большинству программисто особо сложные алгоритмы писать (составлять) на практике редко приходится — алгоритмы решения задач даются в ТЗ от аналитиков и прочих экспертов предметной области. Им (нам) остаётся их закодировать, алгоритмизируя в основном лишь технические вопросы, типа как обрабатывать фатальные ошибки, а не решения бизнес-задач.
Hare8Bit
19.05.2017 21:49+220 минут без гугления =)
(function f(i, max){ setTimeout(() => { console.log( i % 15 == 0 ? 'MissKiss' : i % 5 == 0 ? 'Kiss' : i % 3 == 0 ? 'Miss' : i ); if (i + 1 <= max) f(i + 1, max); }, 50); })(1, 100);
zorro1211
20.05.2017 05:31-1Менее 10 минут:
Array(30).fill().forEach((x, i) => { const val = i + 1; const log = val => setTimeout(() => { console.log(val); }, i * 1000); if (val % 3 == 0 && val % 5 == 0) { return log('FizzBuzz'); } else if (val % 3 == 0) { return log('Fizz'); } else if (val % 5 == 0) { return log('Buzz'); } return log(val); })
Ещё вот такого варианта не видел в ответах:
(async function () { for (let i of Array(100).keys()) { await new Promise(res => {setTimeout(res, 50)}); const val = i + 1; const mod3 = val % 3; const mod5 = val % 5; if (mod3 && mod5) console.log(val); else { if (!mod3) {console.log('Miss');} if (!mod5) {console.log('Kiss');} } console.log('----'); } }())
bano-notit
20.05.2017 19:11Вариант с async/await был, но у вас он не правильный, потому что не учитывает деление на 15 (MissKiss).
zorro1211
21.05.2017 16:31Кстати да, разница в мелочах, нужно было быть внимательнее.
При делении на 15 у меня же выводит и Miss и Kiss? Или не нравится что в разных строчках?mayorovp
21.05.2017 18:38Конечно же не нравится. Просили-то в одной...
zorro1211
22.05.2017 05:51Думаю не особо и просили, но раз надо, значит надо:
(async function () { for (let i of Array(100).keys()) { await new Promise(res => {setTimeout(res, 50)}); const val = i + 1; const mod3 = val % 3; const mod5 = val % 5; let out = ''; if (mod3 && mod5) out = i + 1; else { if (!mod3) {out += 'Miss';} if (!mod5) {out += 'Kiss';} } console.log(out); } }())
hengenvaarallinen
20.05.2017 20:065 минут. Еще 5 на то, чтобы удостовериться, что правильно поняла условие задачи.
function missKiss(x) { if (x > 100) return; if (x % 15 === 0) console.log("MissKiss"); else if (x % 3 === 0) console.log("Miss"); else if (x % 5 === 0) console.log("Kiss"); else console.log(x); setTimeout(fizzBuzz, 1000, x+1) } missKiss(1);
faiwer
20.05.2017 21:12Хм. Сколько лет уже пишу на JS, но никогда бы не подумал, что сигнатура
setTimeout
включает в себя...rest
параметры, которые будут переданы в указанный метод. Полез гуглить ? и правда, оно так и работает. Но не все сайты с js-документацией об этом знают. Правда IE10+.
VovanZ
20.05.2017 21:59VM535:7 Uncaught ReferenceError: fizzBuzz is not defined
setTimeout(fizzBuzz, 1000, x+1)
— вот здесь вы вызываете функциюfizzBuzz
, которая у вас нигде не определена.hengenvaarallinen
21.05.2017 00:37Да, писала с физзбазз, а для сайта переделала на мисскисс, и не везде заменила
VovanZ
20.05.2017 21:50Задача намеренно составлена так, чтобы было непонятно, нужно просто сделать 50мс задержку перед каждым вызовом
console.log
или нужно чтобы между вызовами прошло 50мс.
Я предположил второе и угадал, видимо в этом и был подвох. Но в реальной жизни я бы задавал уточняющие вопросы, конечно же.
Наколенное решение за пару минутmiss_kiss = function(i) { if(i % 3 == 0) { return 'Miss' } if(i % 5 == 0) { return 'Kiss' } if(i % 3 == 0 && i % 5 == 0) { return 'MissKiss' } return i.toString() } foo = function(i, limit) { if(i < limit) { setTimeout(function() { console.log(miss_kiss(i)); foo(i + 1, limit); }, 50); } } foo(1, 101);
Virviil
21.05.2017 08:30-3"Почему программисты не могут программировать" — вот это скандал!!!!
Открываю стаью, только тут замечаю в тегах
JavaScript
....
Закрываю статью
Tuerer
21.05.2017 10:50-1fizzbuzz задача за 2:42 мин for (let i = 1; i <= 100; i++) { if (i % 15 === 0) { console.log('FizzBuzz') continue } else if (i % 3 === 0) { console.log('Fizz') continue } else if (i % 5 === 0) { console.log('Buzz') continue } console.log(i) }
Dimensi
21.05.2017 17:40+1Синхронное решение и тратить на это 3 минуты больно много)
Tuerer
23.05.2017 08:50Вот оно нутро комментаторов хабра. В статье написано что это нужно сделать в асинхронных потоках или за определенное время. Суть статьи в том, что люди, которые приходят работать не в состоянии написать это вообще в каком либо виде (Автор даже выделил это эмоционально), а не написать идеальные алгоритмы, скорость которых 0.00001с. В каких проектах вы вообще работали и насколько сложные писали алгоритмы?
mayorovp
23.05.2017 09:16+1В статье написано что это нужно сделать в асинхронных потоках
… а вы этого не сделали.
MacIn
24.05.2017 15:15-1Не в асинхронных потоках, а асинхронный вызов. Допустим, это не JS, и мы делаем вывод в буферизованный канал. Т.е. сами вызовы — синхронные, но мгновенно возвращающиеся, плюс задержка.
overlordhatiman
21.05.2017 17:40-4Соре за с++ просто я скрипт не знаю написал на 1 что попалось.Задача простая вот код, выводит все в консоль решил меньше 5 минут, использовал гугл для остатка от деления.Думаю на других языках не сложнее, принцип тот же
Код:
#include using namespace std;
main(void)
{
for(int i=1;i<=100;i++){
if(i%3==0 && i%5==0)
cout<<«MissKiss»<<endl;
else if(i%3==0)
cout<<«Miss»<<endl;
else if(i%5==0)
cout<<«Kiss»<<endl;
else cout<<i<<endl;
}
}Lailore
21.05.2017 23:57-2неужели с++ такой отвратительный на вид? Даже хуже obj-c?
bano-notit
24.05.2017 17:20неужели <любой яп> такой плохой
Вот эта фраза сразу показывает, что человек нифига не знает про ЯП :D
Не может быть ЯП отвратительным на вид. Его синтаксис может быть непонятным, но это дело только личного отношения, а точнее собственного чувства мнимого превосходства над кем-то...Lailore
25.05.2017 08:24+1Я не сказал ни слова про «превосходство». И я знаю что код на плюсах может выглядеть в разы лучше, чем этот. Мой коммент был направлен именно в эту сторону.
И да, синтаксис может быть отвратительным. Brainfuck тому явный пример. Или вы и тут будете утверждать, что это только мое личное отношение?bano-notit
25.05.2017 15:28-1Brainfuck нормальный язык, всего его хайпят, хотя есть яп, которые вообще рвут шаблоны, а bf очень даже нормальный.
И всё же это ваше личное отношение. Не может быть яп плохой, каждый яп делается под свои цели, и только если он с ними не справляется, его можно считать отвратительными, Вы таких явно не знаете.Lailore
25.05.2017 19:45Я знаю один! Он должен был уметь простую арифметику и ветвления. Я так и не доделал его.
bano-notit
25.05.2017 19:56Кто должен? Вы о чём?
Lailore
25.05.2017 21:11Вы таких явно не знаете.
Я знаю один!
Я так и не доделал его.
bano-notit
25.05.2017 21:16+1А… Ну окей, я то знаю доделанный, который точно будет выглядеть очень нехорошо.
symbix
21.05.2017 20:453 минуты без гугления. В цикле считается строка output сразу, по таймауту console.log.bind(console, output).
itsfriiman
21.05.2017 21:31-1Новичок. Ушло 30 минут. Многовато…
for (var i=1; i <= 100; i++){ if (i%3 === 0 && i%5 === 0){ setTimeout(function() { console.log("MissKiss"); }, i * 50); } else if (i%3 === 0){ setTimeout(function() { console.log("Miss"); }, i * 50); } else if (i%5 === 0){ setTimeout(function() { console.log("Kiss"); }, i * 50); } }
neskazhui
21.05.2017 23:06-2Интересный тест. Решил попробовать свои силы, хоть я и не программист, не веб-дизайнер и вообще, никак не связан с кодом и скриптами. Написал на php за 3 минуты 32 секунды.
$fizzbizz = array(); for($i=0;$i<101;$i+=3) $fizzbizz[$i] = 'Fizz'; for($i=0;$i<101;$i+=5) $fizzbizz[$i] .= 'Buzz'; for($i=0;$i<101;$i++) if(empty($fizzbizz[$i])) $fizzbizz[$i] = $i; unset($fizzbizz[0]); ksort($fizzbizz); print '<PRE>'; print_r($fizzbizz) print '</PRE>';
Правда, на отладку вывода ушло ещё 11 минут 18 секунд из-за простейшей опечатки и последующего перфекционизма. Итого 14 минут 50 секунд. Хуже, чем я думал, но всё же могу утешить Реджинальда и Инрама.
Скажете, код избыточно нагружает процессор? Зато программиста не нагружает :-)neskazhui
21.05.2017 23:29Почитал доп.условие про асинхронность и задержку вывода. Думал-думал, но так и не понял, что значит «асинхронно».
youlose
21.05.2017 23:55Это значит что код отработал сейчас, а вывелось попозже. В данном случае в задаче попросили чтобы между выводом каждого из значений была задержка 50мс. Особая сложность возникает именно в языке JS, потому что там нет возможности сделать это синхронно, плюс там очень странные области видимости переменных =)
P.S. у вас в ответе выводятся лишние теги, из-за которых задача считалась бы решённой неверно.
P.P.S. Ваш код выводит ворнинги
mayorovp
22.05.2017 06:39Это для javascript термины.
VolCh
22.05.2017 12:33На PHP можно писать асинхронно :)
mayorovp
22.05.2017 12:47Но если для js асинхронное программирование нужно каждому, то в PHP это уже продвинутый уровень.
youlose
22.05.2017 13:11Оно не нужно (в редких случаях нужно), просто нет альтернатив (может быть и можно через async/await что-то придумать, но это сложно понимается при разборе кода)
mayorovp
22.05.2017 13:20async/await является упрощением асинхронного программирования, а не заменой.
И принципиальное отсутствие альтернатив как раз и означает что его нужно знать всем.
svet1
22.05.2017 09:17В свое время решал на собеседованиях, решил даже тесты запилить быстрой проверки чужих заданий: https://github.com/DarkScorpion/FizzBuzz
matraskin
22.05.2017 15:37+1У меня на написание кода ушло примерно 60 минут, но так как я не «настоящий программист» то мне простительно.
П.С. Штатными методами 50 мс задержку сделать не получилось, только кратную 1 сек. Собственно поэтому и получилось так много времени на выполнение задания.
&НаКлиенте Процедура FizzBuzz() Оповещение = Новый ОписаниеОповещения("ВывестиСообщение", ЭтотОбъект); Для ы = 1 По 100 Цикл Остаток3 = ы / 3 - Цел(ы / 3); Остаток5 = ы / 5 - Цел(ы / 5); Если Остаток3 = 0 и Остаток5 = 0 Тогда ТекстСообщения = "FizzBuzz"; ИначеЕсли Остаток3 = 0 Тогда ТекстСообщения = "Fizz"; ИначеЕсли Остаток5 = 0 Тогда ТекстСообщения = "Buzz"; Иначе ТекстСообщения = Строка(ы); КонецЕсли; Оповещение = Новый ОписаниеОповещения("ВывестиСообщение", ЭтотОбъект, ТекстСообщения); ПоказатьПредупреждение(Оповещение, ТекстСообщения, 1); КонецЦикла; КонецПроцедуры &НаКлиенте Процедура ВывестиСообщение(ТекстСообщения) Экспорт Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = ТекстСообщения; Сообщение.Сообщить(); КонецПроцедуры
yuyaee
22.05.2017 15:37-2Вот мой вариант, за 3:22 сек:
function missKiss(from, to, delay) { if(from <= to) { setTimeout(function() { missKiss(from + 1, to); console.log([from % 3 ? '' : 'Miss', from % 5 ? '' : 'Kiss'].join('') || from); }, delay); } } missKiss(1, 100, 50);
DGrain
22.05.2017 22:53Не очень «правильное» решение, но вместе с толпой выложу.
var i = 1; var interval = setInterval($_$, 50); function $_$(){ var m = !(i%3), k = !(i%5); console.log(!m && !k? i : ( m ? "Miss" : '' ) + ( k ? "Kiss" : '')); if(++i > 100) clearInterval(interval); }
DarkGenius
23.05.2017 08:55-2Прочитал комментарии касательно предложенной в конце задачи — и ужаснулся.
Кто-то цепляется к погрешности в миллисекундах (если уж на то пошло, то абсолютной точности в принципе нельзя достичь из-за особенностей исполнения кода JS), другие предлагают для решения простой задачи перегруженный и усложненный код в стиле «вырвиглаз». Показательно в плане ответа на вопрос «Почему программисты не могут программировать».
Dark_Tower
25.05.2017 00:47Извините но такие сказки что программисты не могу программировать(199 из 200) меня задолбали.
Получается что только 0.5% могут писать код. Извините, но это же бред.
Откуда тогда столько приложений, сайтов у кучи людей свои проекты на Гитхабе?
Все это напиминает поиски мифического 10X программиста. Да еще чтоб хотел зарплату ниже рынка.
mayorovp
25.05.2017 06:54+3Вы бы пост прочитали сначала. Там объясняется откуда получается такая цифра.
А еще почитайте комментарии, тут много таких набралось.
vasIvas
Все зависит от области! Игродел за секунду напишет решение, программист десктопных приложений на java или c# напишет, наверное, за то же время, а вот вэб программист наверное будет долго думать. И все дело в том что для первых двух категорий обычный код тот, который для вэб программистов фраймворк.
Zibx
Бездарных игроделов существует дюжинное количество. Десктопных — не меньшее. Вот с вебными всё действительно много хуже и для их поиска надо указать что нужен нод.жс, паттерны проектирования и знание алгоритмической сложности. И всё равно 90% приходящих не могут на клочке бумаги обсёрвабл нарисовать.
vasIvas
по большей части Вы правы, но везде есть свои нюансы. У игроделов плохой программист, это тот который плохо знает математику-физику. Но зато у игроделов намного все серьезней с проектированием, сильнее даже чем у обычных серверистов, которые пишут сервера для сайтов-приложений. Они просто не могут не разбираться в DDD, чего не всегда хватает дескопщикам, хотя им математика нужна меньше чем архитектура.
А вот в вэбе DDD это вообще как Йоулупукки для российских детей, чье имя может если не рассмешить, то даже напугать. Но тут я не говорю о людях которые пришли в вэб из других java c# с++ языков. И в этом не их вина, они свято верят что разработчики фраймворков просто боги которые лучше всех знают как нужно делать и если они делают так, то это единственно верное решение. То есть они учатся на увиденном. Да и куда скрыть тот факт что jQ и всякие верстки для cms до сих пор являются приоритетными.
VolCh
Не преувеличивайте. В мире PHP уж точно DDD имеет место быть. Будущий мажорный релиз Symfony в частности обещает упрощения разработки по DDD.
iit
Даже такой бесполезный ларавельщик-пыхобыдлокодер как я и то юзает DDD и сейчас буду пихать интеракторы в органайзер и материться что laravel не все зависимости в контекст инжектировал по интерфейсам и писать для них сервис-провайдеры которые позволят DI отрезольвить их.
Filippok
Есть вот такой вариант:
https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
AstarothAst
Это… это… это же потрясающе! О_о
Ckpyt
О.О Я боюсь спросить сколько ушло на написание этого кода :-)
AstarothAst
Там еще и 159 ишуков заведено, люди докер, к примеру, требуют :D
grossws
А в docker'е надо WildFly Swarm, как минимум.
marsermd
Это просто прекрасно! Не думал, что смогу рыдать от смеха глядя на код)
kolemik
ну а серьёзно, я вот не видел других вариантов решения, где предусматривается изменение требований к работе системы, например на fizz-buzz-heraz, где последнее выдавать при делимости на 7
Есть у меня, конечно, наколеночное решение с хардкодом, но это не наш метод! :)
Dimash2
Я не согласен, задание очень простое, кто не может его сделать в редакторе до 10 минут — не программист, а оператор компьютера. Я такие задачи не делаю, все что мне понадобилось — это перепроверить в гугле, что % проверяет кратность и все.
Проблема в том, что новое поколение ребят с курсов задают такой вопрос «А что, Jquery это тоже Javascript? Не может быть!».
Zenitchik
Если человек пошёл на курсы — значит не смог освоить самостоятельно, что само по себе довольно странно.
Deosis
Если человек пошёл в университет — значит не смог освоить самостоятельно, что само по себе довольно странно.
qVOLKq
Как бы там ни было, странно самостоятельно усвоить университетские курсы. Всетаки, там не 1 или 2 области, а много.
Zenitchik
Во время учёбы мне не раз приходила в голову мысль, что если бы мне просто дали список того, что нужно знать для приобретения квалификации инженера, я запросто изучил бы это сам. В конце концов, какая разница, по лекциям учиться или по учебникам?
Если же Вы намекаете на «корочку», то я с трудом верю, что где-то котируется корочка JQuery-разработчика…
TimsTims
Это есть, и называется сдать экзамены экстерном.
VolCh
Немного не так оно есть, как в комментарии. Списки эти в пригодном для самоподготовки виде с боем нужно выбивать из деканатов/кафедр. По крайней мере лет 20 назад.
MacIn
Не знаю… В моем ВУЗе такие вещи описывались в программах по предмету xyz, обновлялись регулярно и лежали на сервере кафедры бери-не хочу. Нам, заочникам, было на руку.
PS 2014 год.
bano-notit
Меня всегда на форумах удивляла фраза: "да на кой мне этот js, есть же jq!"
michael_vostrikov
"да на кой мне этот asm, есть же c++!"
michael_vostrikov
Хоть это и шутка, но несогласным хочу напомнить, что ассемблер это тоже язык программирования. И если с jQuery аналогия неточная, то с каким-нибудь TypeScript вполне. jQuery можно считать аналогом CRT, без CRT тоже можно программы писать.
VaalKIA
Ассемблер, это не язык программирования, это транслятор в машинные коды и какой он будет, завист от того, какие машинные коды есть и какова архитектура процессора. Если вы хотите собирательное название, то можно говорить «языки низкого уровня», но при этом не понятно о чём речь. Есть, конечно, технологии на стыке, типа PI-код, или виртуальная машина типа JVM, которые могут иметь конкретный стандарт, но тогда про них конкретно и надо упоминать.
mayorovp
Академически — да, ассемблер это транслятор. А язык программирования называется "язык ассемблера".
Но если не придираться к словам, то слово "ассемблер" может прекрасно обозначать оба понятия.
VaalKIA
То есть, стековый процессор и DSP чип, это один и тот же ассемблер, верно?
Язык программирования без стандарта, это не язык программирования, вам не гарантируют ни метод адресации, ни даже наличие регистров, возьмите мультиклет, к примеру с его ассемблером.
Фактически, вы пытаетесь меня убедить, что x86 ассемблер, в виду его распространённости следует считать идолом ассемблера, я с этим не согласен. Если же речь не про x86, то совершенно не понятно что вы понимаете под языком ассемблера, может быть лисп машины в чипе, которые вполне себе ассемблер, потому что хардварны?
mayorovp
Нет, я хочу вас убедить в том, что не надо придираться к словам когда их смысл хорошо понятен из контекста.
Языки ассемблера для некоторого стекового процессора, DSP чипа и x86 — это три разных языка. Каждый из них, согласно правилам русского языка, можно назвать языком ассемблера или просто ассемблером, одинаковыми они от этого не станут.
VaalKIA
Исключите слово язык из фразы «язык ассемблера» и включите множественное число.
Согласно правилам русского языка, можно назвать их ассемберами, или просто ассемблерами, одинаковыми они от этого не станут, и вот тут я уже придираюсь. Потому что речь шла о языках, а не правилах русского языка.
mayorovp
Все языки можно называть ассемблерами. А любой конкретный из них будет ассемблером.
VaalKIA
Я не буду с вами спорить, вы этой фразой очень сильно понизили планку разговора, пэтому я сомневаюсь что он вам вообще интересен. Для остальных оставлю выдержку непосредственно связанную с языками, по которой можно саморазвиватсья в данном вопросе.
michael_vostrikov
В русском языке есть выражение "написано на ассемблере", которое имеет вполне понятный смысл. Как-то странно, что вы одни части русского языка учитываете, а другие игнорируете)
VaalKIA
А ещё в русском языке есть мир холодильников, которое имеет вполне понятный смысл и я не буду одёргивать человека, когда мне говорят как к этому месту пройти, но когда человек начинает мыслить категориями таких миров, сам генерируя подобный контекст, потому что смысл он не понимает, но уже все так говорят, то промолчать я не могу.
И да, писать можно и в ассемблере который имеет почти всегда встроенный редактор и для ассемблера, можно даже писать машинные коды. Если вы не слишком заморачиваетесь правилами русского языка, то можно писать в машинных когдах и на ассемблере, но «язык программирования» это конкретное понятие, которое даже не эквивалентно просто языку, до которого его сокращают, что почти всегда позволяет контекст. К чему заметка-то? Я не о правилах русского языка, я computer science, формальные грамматики, алгоритмы, языки программирования… не чувствуется связь, конекст какой-нибудь, не? И как-то страно, что алгоритм имеет определение, и язык программирования тоже и можно рассждать не в стиле, что мой дедушка так гвоорил и мне завещал?
Pakos
Это разные диалекты одного языка и он разный на разных процессорах, C более стандартизован, а вариантов Бейсика — великое множество, Паскаля поменьше.
Нет. фактически вы приписываете оппоненту свои фантазии, ибо x86 (другого не знаете?) ранее упомняут не был.
VaalKIA
Я и машинные коды, в тетрадке в клетку, писал под z80 не имея ассемблера. Это было сказано, только что бы понять что подразумевает оппонент под своими словами. Если вам хочется перйти на личности, пишите в личку.
VolCh
А я писал на языке ассемблера и в голове транслировал в машкоды — у меня был ассемблер или я им был? :) Тем не менее, в подавляющем большинстве случаев по контексту слово "ассемблер" ассоциируется вполне однозначно, уточнений "программа?", "язык?", "для какой архитектуры?", "какой диалект?" практически всегда не делаю.
VaalKIA
Если человек записывает на бумаге цифры, на каком языке он это делает?
Почему запись программы не может быть просто в машинных кодах или в мнемониках комманд процессора? Я например, совершенно точно писал машинные коды, потому что не было кода установки энного бита в байте и я по маске модифицировал три бита в самом коде комманды, превращая конкретную установку в нужную мне. Не зная, за что отвечают биты в коде комманды такое нельзя сделать, опираясь только на мнемонику.
Pakos
Что не делает из языка ассемблера не язык программирования (низкоуровневый).
VaalKIA
Читаю интернет, будем считать что спор я проиграл. Я не знаю, когда в транслятор сборщик(assembler) кода запихнули рекурсию и он стал не транслировать мнемоники собирая машинные коды, а внезмпно собирать-собираемое записанное на собираемое. Пусть будет Ассемблер ассемблера, раз уж интернет уже думает так же. Я из другого мира. Тема закрыта.
michael_vostrikov
Я думаю, в контексте статьи понятно, что речь идет про язык ассемблера
VaalKIA
Совершенно верно, но ключевое слово здесь «машинно-ориентированный», что приобретает некоторый смысл при указании в контексте арихтектуры и совершенно не несёт никакой конкретики в абстрактном плане. Это всё равно как сказать, естественный язык, в контексте нации можно понять, что это английский или может быть японский, но без контекста даже не понятно, используется ли там голос, или это естественность глухонемых.
Сам же смысл языка программирования в абстрагировании от архитектуры, в том, что он чётко сформулирован и есть понимание что в нём можно делать, что нельзя. А если этих правил нет (выше я приводил пример, что даже регистров может не быть, не говоря уже про способы адресации и троичную логику как в Сетунь), может это всё-таки не язык?
mayorovp
Вы пропустили словосочетание "высокого уровня"
VaalKIA
Не имеет значения насколько сильно вы абстрагировались, я уже упоминал хардварную реальзиацию лисп, в которой ассемблер фактически повторяет лисп, но от этого не перестаёт быть всего лишь транслятором, нет синтаксиса — нет языка программирования.
VolCh
Это ваше личное понимание. Может имеет какое-то отношение к языкам высокого уровня (но далеко не во всех из них есть полная абстракция от архитектуры даже в таких базовых вещах как размер целого числа), но к языкам условного среднего (C например или Forth) и низкого (машинные языки, ассемблеры) точно не относится. Лишь немногие из популярных языков высокого уровня создавались изначально с целью полностью абстрагироваться от архитектуры, да и то подавляющее большинство пошло путем спецификации виртуальной машины, в машинный язык или ассемблер которой транслируется язык высокого уровня, то есть по сути язык не абстрагирован от архитектуры машины, а наоборот, жёстко привязан к одной-единственной, просто машина виртуальная, сама абстрагирует от реального железа.
VaalKIA
Хорошо, зайдём с другой стороны, опишите правила «языка ассемблера», как на нём писать?
VolCh
На разных диалектах по разному :)
mayorovp
Которого их?
vadimr
Опишите правила «языка Бейсик».
michael_vostrikov
Смысл языка программирования в возможности написания программ. Абстракция это уровень выше, и относится только языкам программирования высокого уровня, а не ко всем.
Язык ассемблера для x86 это один язык программирования, для ARM это другой. В пределах одного языка есть синтаксис и есть правила, что можно делать и что нельзя.
VaalKIA
Даже в рамках одной архитектуры существуют ассемблеры с разным синтаксисом, например синтаксис АТ&Т вам о чём-нибудь говорит?
Кроме того, написание программ возможно и без всякого языка и транслятора, прямо в машинных когдах, смысл же языка программирования именно в синтаксисе, что вы упрямо отрицаете.
Например вики:
Ну можете назвать машинные коды языком кодов, если вам так хочется и закончим на этом тему. Для меня же нет языка ассемблера, есть машинный код, есть ассемблер или транслятор и есть язык программирования обозначающий формальные правила.
michael_vostrikov
Вот в той статье, откуда вы привели определение, есть фраза "пользовались непосредственно машинным кодом,… который принято считать языком программирования первого поколения".
И нет, смысл языка программирования не в синтаксисе, а в возможности записи компьютерных программ. У русского языка есть синтаксис, но он не является языком программирования. Также, не каждый формальный язык является языком программирования.
И у любого ассемблера есть свой синтаксис. C ваших же слов:
VaalKIA
Любая запись сама по себе имеет какой-то синтаксис. Под синтаксисом языка программированя я имел ввиду формальные правила, прошу прощения за сумбур.
Зато ассемблер — использовался.В той же статье, откуда я привёл описание, написано:
Читаем дальше:
Моё мнение о этой статье: писал человек который хочет систематизировать всё и вся не разбираясь в предмете. Но цитата которую привёл я — важна и не сама по себе, а в связи. Почитайте про формальные грамматики, про то, как описываются языки программирования. Вообще, я не вижу смысла в нашем споре, если вы хотите называть языком и машинные коды и IDE, это ваше право. Я очень хорошо высказал своё мнение в письмах, более подробно разжевать мою позицию уже нельзя. И думаю, что вы её прекрасно поняли.
nekt
Мне на собеседовании как-то объявили, что если я не знаю тонкости jq, я не знаю js :(
bano-notit
Значит не туда собеседовались, а может и туда, просто сейчас фраза не так всплыла, но, если это какая-то маломальская дизайнерская студия, то там знания jq просто обязательны, и для них это является очень большим фактором, но если при этом они сказали, что незнание библиотеки является незнанием языка, то это уже точно маломаломаломальская дизайн студия с теми, кто сам не знает js...
kloppspb
Угумсь.
Тут вон (и не только тут — регулярно) люди возмущаются, что их заставляют код на бумажке карандашом писать, без гугла и подсказок IDE. Куда не кинь — везде клин. А результат один: либо ты программист, либо погулять вышел.
bano-notit
Ну скажем так, код на бумашке писать — дело первых программистов, вроде Ады) А мне это тупо не удобно, но я понимаю, что мне IDE только в помощь дана, она за меня ничерта не придумает. Поэтому к таким тестам я отношусь вполне нормально. Меня больше прикалываются такие тесты:
Такие задания реально интересны и показывают насколько у тебя бошка думает, а вот тесты типа
Вот это мрак, направленный чисто на знание библиотеки, а не оценки твоих умственных способностей.
kloppspb
Это тест насколько человек способен думать самостоятельно, без подсказок. Никто тут не требует идеального решения задачи, и вообще решения :)
Не могу не вспомнить :-)
MacIn
«Писать на бумажке» — это, к тому же, вовсе необязательно значит написать компилируемый, абсолютно правильный код. Мы, в конце концов, не в эпоху устройств подготовки данных и перфокарт живем. Это может быть блок-схема, плгоритмический язык, да просто веральное описание алгоритма. По крайней мере, мне именно так видится нормальное «собеседование с кодом на бумажке».
bano-notit
Стоп, а обычно пишут на реальном коде? Я просто обычно использовал помесь python и js, ибо читаемость в python больше, а на js собеседуюсь...
MacIn
Я как раз об аргументе противной стороны — «мне», мол, «в реальных условиях, IDE и компилятор подсказывать будут».
matraskin
Не раз замечал, что придумываешь один алгоритм, а когда начинаешь его реализовывать, то получается несколько иначе. Иногда кардинально иначе.
И да, ИДЕ, очень сильно ускоряет написание кода и корректирует ход мыслей в правильном направлении.
MacIn
Написание кода — да, но тут речь об алгоритме. Если проверяют, может ли человек составить алгоритм — да пусть хоть блок-схемы или диаграммы Несси-Шнейдермана рисует.
Мне кажется, что при корректной разработке сверху-вниз такого быть не должно.
michael_vostrikov
Ну тут еще вопрос, что больше показывает способность думать самостоятельно) Когда человек сам пишет решение задачи, с которой он возможно уже сталкивался и потратил какое-то время на поиск этого решения, или когда человек ищет информацию в интернете, а значит точно ее не знает, и потом полученные знания правильно применяет для решения задачи.
Я конечно преувеличиваю, но по-моему этот тест не очень показательный.
kloppspb
В этих тестах нет ничего, что человек не знает, и что нужно гуглить. Фактически, это именно smoke test. Если уж он пришёл на собеседование, то обязан знать и уметь :) Не раз уже обсуждалось, один из примеров, которые привожу:
michael_vostrikov
Ну это в ваших тестах нет ничего такого. Я просто к тому, что в общем случае это утверждение не истинно. Это зависит от задачи.
Например, индекс ближайшего по значению элемента я найду. А вот какой-нибудь хитрый алгоритм обхода графа с заданными требованиями по времени и памяти уже вряд ли, надо будет информацию поискать.
kloppspb
Общий случай — это как средняя температура по больнице, ни о чём :)
Задача таких тестов в первую очередь в отсеве на самом первом этапе. До фига и больше людей, которые только думают, что меют какое-то отношение к программированию, и по резюме это не всегда понятно.
Ну а с другой стороны, даже по отношению к такой задаче:
уже можно отличить специалиста (или «принцессу») от «просто погулять вышел», безо всяких гуглов :)
vasIvas
И не нужно понимать буквально, я не о всех же говорю, а в общей массе.