Java Jun нынче не торт

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

Например, прошу упростить следующее выражение:

!(!a || b)

80% не могут этого сделать! Редкий КПИ-шник вспоминает, что есть такое правило де Моргана, про закончивших НАУ или 2-недельные курсы по джава (что почти одно и то же и == 0) я вообще молчу. Это же базовое правило булевой алгебры! О чем тогда говорить дальше с человеком? Как он собирается работать программером?

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

И вообще, почему все сразу ломятся в java программеры — это сравнительно сложный язык, сложная инфраструктура, много legacy кода в котором сложно разбраться без опыта. Imho, начинать надо с чего-то попроще. Например с ... ну, вы сами знаете.

Какой выход? Пока что вижу только один и всем его рекомендую: Coursera, Udacity и пр. Абсолютный минимум — парочка курсов по алгоритмам (есть даже с кодом на java) и прочитать «Clean Code»!

Дорогие джуны, прежде чем идти на собеседование, убедитесь что вы хорошо знаете как минимум следующее:
1. Булева алгебра, правило де Моргана
2. big «O» notation, оценка сложности и скорости алгоритмов и структур данных в Java
3. Как работает HashMap
4. Что такое рекурсия и как написать обход дерева
5. что такое DRY, KISS, extract method
6. ... (добавляйте в комментах)

И тогда наши собеседования будут проходить в более оптимистичном ключе и у Украины будет шанс обогнать Индию по качеству и количеству IT-шникв.

Disclaimer: Мнение автора может не совпадать и не выражать мнение фирмы, в которой он работает

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn

Лучшие комментарии пропустить

Похвастались бы грантом каким-то или победой на Imagine CUP, слабо?
Это вам не джунов терроризировать.Я и сам в состоянии задать вам 5 заданий на собеседовании, которые вы не решите и я заявлю о вашей полнейшей непригодности к программированию на Java, только вот я не вижу смысла самоутверждаться за счет людей, которые чего-то не знают и в поиске работы.

Правило «Я начальник — ты дурак» слегка устарело, вам не кажется?

Если человек не сталкивался с каким-то алгоритмом или куском API по работе, то его надо за это покарать? Если вы от нефиг делать решаете задачки, в то время как другие чуваки годами фиксят баги на JSP не делает вас выше других.

АААААааааааааааааааа! Опять дeбильные вопросы которые требуются только на собеседовании. Причем чем больше у собеседующего травма тем больше его интересуют побитовые подробности. И таким вот подходом травмируют джунов.
Вот это всё

1. Булева алгебра, правило де Моргана
2. big «O» notation, оценка сложности и скорости алгоритмов и структур данных в Java
3. Как работает HashMap
4. Что такое рекурсия и как написать обход дерева
за овер 10 лет ни разу не нужно было. И я уже перестал даже эту фигню повторять перед собеседованиями. Т.к. если такое спрашивают то мне с такими не по пути.

Вообще весь процесс найма от хр до собеседования травмирован. Более чем в 90 процентов случаев.

И что самое интересное, джуниора возьмут на проект, где надо будет фиксить вёрстку и писать на яваскрипте.

Вставлю свои 5ть копеек.
1. Не стоит спрашивать именно правило Де Моргана, не все помнят, как оно там называется. Просто даете пример логического выражения где кол-во not зашкаливает да и все. Хотя похоже вы так и делаете.
2. Не стоит привязывать этот вопрос к конкретному языку. Человек который знает и понимает сложность алгоритмов разрулит сие на раз в любом языке. Ибо знает что это важно и что нужно искать, что бы почитать и быть в курсе.
3. Опять таки стоит ли спрашивать про конкретную реализацию? Не будет ли лучше спросить что такое Hash и попросить назвать одну из возможных реализаций. Конечно, попросив дать оценку сложности основных операций.
4. Как то шибко в лоб. Может лучше задачу подобрать, ну например ... навскидку ... возвести x (int) в степень y (uint). Просто тут вы можете сделать несколько шагов сначала в лоб, потом спросить сложность, потом попросить улучшить и так далее.
5. Я бы не спрашивал аббревиатуры. Ну блин не знает человек их, так что теперь. Ну только если сии не написана в CV у собеседуемого. Лучше спросить нечто такое — опишите структуру и дизайн подход вашего самого удачного кода. Ну или как то так. Не загоняйте собеседника в рамки, дайте ему простор и возможность для самостоятельного выбора.

Я обычно делаю так:
1. Бла бла бла расскажите о себе и один точный вопрос по чему-то указанному в CV, наугад что бы проверить насколько CV реально.
2. Две алгоритмические задачи — простая и сложная. Причем писать код можно на любом языке, но обязан быть код!!! В процессе написания и идет разговор про сложность алгоритмов и так далее.
3. В конце стандартное — опишите идеальное место работы для вас, лучшее что вы сделали и так далее.

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

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

Все написанное касается дисциплины Software Developer. Мои знания ограничиваются только этой дисциплиной.

Я готов голыми руками оторвать яйца тому, кто будет в реальной задаче упрощать выражение
!(!a || b)
Да, с точки зрения математики это можно делать. Но как насчёт обратного преобразования? Ведь в один прекрасный момент (пятница, вечер, ASAP) понадобится прочитать код и понять что он делает. Если логика записана так, как поставлена задача — читаешь код быстро. А если «упростили» — сам чёрт ногу сломит.

Дальше больше. Упростил — круто, сэкономил пару наносекунд. Но... с вероятностью 10% допустил ошибку в упрощении. Учитывая плохую читаемость кода — найдут её нескоро.

Добавляем небольшой факт: большинство логических выражений относятся к ветвлению кода. И твой «упрощённый» код попадает... ну скажем в перехватчик исключений, которое возникает с вероятностью 1 из 100 000 000 и должно срочно разослать SMSку. Естественно этот кусочек кода будет выпилен из автоматического тестирования (чтобы не слать SMSку каждый раз). Либо она будет подменена записью в лог, если не задан номер телефона куда слать. И в первый день твоего отпуска, когда ты летишь на Бали... этот код выставляется в продакшен. Из-за ошибки в 1 знак (забыл «!») вероятность отправки SMSки составляет уже не 1, а 99 999 999 из 100 000 000.

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

А всего-то требовалось — написать логику в исходном виде.

// Кто программирует на java знает, что компилятор САМ оптимизирует логический код.
// (a!=null && !a) — не вызовет ошибки в случае a=null.
// А теперь упростите это выражение, и оцените его читаемость! А ведь это лишь одна маленькая операция. В реальном коде их сотни и тысячи.

Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

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

>Например, прошу упростить следующее выражение:
>!(!a || b)
>80% не могут этого сделать!

омг О_О, да 80% моих однокурсников смогут сделать :/, видно хорошо нам вдолбили на 1м курсе на ПТЦА :)

Я не понимаю, к чему этот срач и недовольство топикстартера. Есть такой факт, что многие новички начинают изучение программирования не с SICP, а всего лишь с технологий, «практики». Среди уже опытных спецов очень много тех, кто так и продолжает работать и смотреть на процесс через призму технологий, а не программирования как такового: люди знают десяток фреймворков, но не знают что такое замыкание. Кто-то так и остается таким быдло-практиком, а кто-то наверстывает потом. Необходимо решить кто именно нужен для данной работы — люди с академическим бекграундом или мастера-формошлепы. И те, и другие необходимы для своих целей.

Рассмешил.
Чаще всего как раз встречаются быдло-теоретики: на собеседовании стройно отвечают, а начнут код писать — ни архетиктуры нормальной, ни паттернов, сплошной говнокод и костыли.

Люди с академическим бекграундом...
Люди с академическим бекграундом с половине случаев не могут найти работу по специальности, т.к. бекграунд вроде и есть, а делать они ничего не умеют. Вообще.
Такие люди очень напоминают футбольных фанатов, которые сидят дома перед телевизором и кричат «Ну, кто ж так бьет!», или кухарок, которые рвуться управлять государством.

Для того, чтобы разобраться в нюансах работы «всего лишь технологий» нужны годы. 10 популярных Java-фреймворков — это лет 5 работы. И за это платят деньги. А ваше хваленое Computer Science к реальному програмированию не имеет никакого отношения! Никто не возьмет на работу человека просто и дипломом SC, у которого нет опыта. Разве что стажером :)

Между «знаю, как надо» и «умею, как надо» лежат годы кропотливого труда. Не стоит выдавать одно за другое.

Это другое. Зачем там передергивать-то? Я не говорил о «философах» и «кухарках».

Для того, чтобы разобраться в нюансах работы «всего лишь технологий» нужны годы.
Нюансы работы, архитектура, паттерны — это ли не то, что предполагает глубокого изучения, и даже условно говоря «теории»? А вот когда JavaScript за полчаса изучают и начинают с jQuery, продолжая так работу годами — это проблемы.
Я сам формошлеп, и четко это осознаю, вижу проблемы которые мне мешают работать, потому «хваленым CS» — увы, это не про меня.

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

Ну да, мы ж на доу про политику только...

Например, прошу упростить следующее выражение:
!(!a || b)
Редкий КПИ-шник вспоминает, что есть такое правило де Моргана, про закончивших НАУ

А что там де Морган говорил? Не о том ли, что выражение упрощается, если переменным дать осмысленные имена?

Знание нескольких принципов освобождает от знания множества фактов

Жаль только, что реальное программирование больше основано на практических навыках, чем на «знаниях» фактов.

ТС, давайте поиграем в ситуации.

1) Есть два кандидата. Первый (даже вне зависимости от того, звучала ли рекомендация воспользоваться какими-либо общеизвестными правилами в самом вопросе) сам говорит о том, что тут следует применить правило де Моргана и быстро на бумажке без ошибок крапает упрощенное выражение. Второй кандидат, даже если упомянуть при нем о де Моргане, максимум может представить себе седовласого негра с бородкой, и уж ни о каких его правилах ни сном, ни духом не ведает, но хорошо нахмурившись, зажмурившись, пару-тройку минут бормоча что-то себе под нос и считая на руках пальцы таки тоже выдает на бумажке правильный ответ. Кого из них возьмете?

2) Считаете ли достаточным умение правильно указать на оценку сложности приведенного алгоритма среди пары-тройки заведомо неверных вариантов (т.е. тестирование от обратного)?

3) Будет ли достаточно ответа «это кода оно это... само себя того... ну вызывает!»?

Будет ли достаточно ответа «это кода оно это... само себя того... ну вызывает!»?

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

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

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

3. Нет, недостаточно. Абсолютный минимум — хотя бы уметь факториал или фиббоначи рекурсивно написать.

Был у меня забавный случай на одном собеседовании. задали мне задачку, отсортировать здоровенный файлик (содержимое — символы). А у меня в ВУЗе как раз алгоритмы сортировки были. «Ага!» сказал я, и нахреначил быструю сортировку. «Не, не вариант» — «Почему?» — «Ну а чтобы ты делал, если бы в файле были только символы 0 и 1?». Вот тут то до меня и дошло.
Так что кроме знаний, ВУЗ приносит и некую деформацию — привычку делать по методичке (надо сказать — не всегда это плохо).

P.S. ну нафига рекурсию иллюстрируют факториалом? for(i=1, p=1; i<=N; p*=i++) куда проще выглядит. Обход дерева или закрашивание фигуры куда нагляднее показывает прелесть рекурсии.

“Ну а чтобы ты делал, если бы в файле были только символы 0 и 1?”
А можна детальніше?

Объект сортировки — символы. Т.е. из 01010101 нужно получить 00001111

Ні, я задачу зрозумів. А от «Вот тут то до меня и дошло.» до мене не здається дішло. :(
Я б порахував кількість «0» і переписав весь файл. А от що ви придумали?

Я б порахував кількість «0» і переписав весь файл.
точно

То шо в вашей методичке нет en.wikipedia.org/...i/Counting_sort проблемы автора методички. Читать надо Knuth, D. E. (1998), The Art of Computer Programming, Volume 3: Sorting and Searching (2nd ed.), Addison-Wesley, ISBN 0-201-89685-0. Section 5.2, Sorting by counting, pp. 75–80, and historical notes, p. 170. а не методички местного мега препода (а в нашем городе их еще пытаются впарить обязательно).

Ой ну таки кто такой ваш Кнут против местного Ивана Петровича. Вот ваш Дональд в 70х работал на военном заводе в СССР? Нет? То-то же!
А то ещё договоритесь скоро, что можно и самому без универа выучится.

То шо в вашей методичке нет en.wikipedia.org/...i/Counting_sort проблемы автора методички
Наглядный пример того, что утолщение методички все таки не заменяет необходимость думать межушным нервным узлом. :) Решение еще проще, даже если надо действительно отсортировать, а не просто посчитать нолики.

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

Если речь идет о файле из ноликов и единиц, то проще канонічного каунт сортинга будет каунт сортинг без внешнего цикла (см. посчитать нолики), а если каунт сортиг по ключам (Pigeonhole sort) то для 0/1 проще будет партишен (идем с двух концов массива и меняем местами нолики единички, стоящие не на своих местах)

ну нафига рекурсию иллюстрируют факториалом?

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

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

не лиспом единым
для Эрланга хвостовая рекурсия — почти единственный способ организовать цикл

Хорошо, предложите какой-то более адекватный пример. Мне действительно интересно. :)

Я уже упоминал — обход дерева, заливка фигуры. Простые и интуитивные алгоритмы.

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

Ну на мой взгляд задание на знание правила Де Моргана на собеседовании не верно по моему глубокому убеждению. В реальном приложении если Вы встречайте названия переменных a и b то это уже должно Вас натолкнуть на мысль, что может стоит изменить их название для начала, а потом уже оптимизировать что-либо (при изменении названия мы уже делаем один шаг на встречу истине — наша задача обретает контекст). Об этом кстати писал автор, упомянутый Вами (© Clean Code, Robert C. Martin — Avoid Disinformation). Куда важнее на собеседовании увидеть, по моему глубокому убеждению, как человек может выходить за рамки вопроса. Например я бы этот вопрос перефразировала так:
Есть в куске кода выражение:
if (!(signedOut && untrustedIp))
Что бы Вы могли сказать по этому выражению? Что Вам в нем хочется улучшить, и хочется ли вообще?
В ответ ожидала бы услышать вопрос от кандидата: A в каком контексте записано данное выражение? Это бы уже прибавило ему балов. Я бы показала остальную часть метода. И если контекст метода подсказывает, что данное выражение используется, чтобы проверить, авторизирован ли пользователь в системе, то как вариант ответа можно было бы получить if (authorized). Мне кажется такой ответ куда важней, чем вопрос в стиле: if (!(a && b)) с ответом на него: if (!a || !b)). Для меня что вопрос что ответ в этом случае не имеют реальной практической пользы...
Но опять же, такие вопросы, какие автор этого топика задает, мне кажется не стоит задавать новичкам, может даже и более окрепшим. Потому как все мы когда-то такими были/есть, просто некоторые быстро забывают, что такое собеседование... Куда важней задавать вопросы, которые раскрывают кандидата получше и создают свободную атмосферу. Например вести диалог только исходя из его предыдущего опыта и посмотреть, на сколько глубоко он окунался в темы, которые были ему интересны как вариант...
В любом случае спасибо за интересный технический топик и искренне желаю Вам успехов в подборе ребят на проект!

Ну на мой взгляд задание на знание правила Де Моргана на собеседовании не верно по моему глубокому убеждению.
Не знание законов де Моргана свидетельствует что человек человек забил на универ с первой же пары. Но суть даже не в этом, суть в том что человек не может преобразовать простое булевское выражение, а это уже печально см dou.ua/...ic/9765/#467568
то как вариант ответа можно было бы получить if (signedIn). Мне кажется такой ответ куда важней, чем вопрос в стиле: if (!(a && b)) с ответом на него: if (!a || !b))
Есть 2 подхода к написанию кода, скорее даже к внесению изменений в код:
1) Разобраться в чем суть, понять бизнес-процесс
2) Сделать так чтобы код работал (проходили тесты, КуА сказали что все ок и тд)
Вариант 1 хорош для написания большого куска задачи. Для небольших изменений/задач подход 2 более эффективен. Надо понимать как решать задачу. И незнание базовых вещей, таких как булевская алгебра, очень сильно усложняют применение второго подхода, поэтому полученные ответы сравнивать не совсем корректно.
Потому как все мы когда-то такими были/есть
Аргумент просто супер: Вам что не жалко котенка? А будь вы на его месте?
Я правильно понял ситуацию?
.
Задавать можно любые вопросы, если они помогают прояснить ситуацию. Если ТС способен оценить по ответам на эти вопросы человека, то почему бы их не задать.
Проблема большинства противников (которых я встречал) подобных вопросов в том что они считают, что важен именно правильный ответ на вопрос (как в универе на зачете). Но куда важнее как человек отвечает.
Простой пример с О-нотацией: человек не должен помнить наизусть стоимость операций для всех стандартных структур (но было бы не плохо :) ), но если он может путем размышлений оценить это прямо на собеседовании — это очень хорошо. Тут же важно как он отвечает — того кто заучил ответы довольно часто легко распознать. С другой стороны человек может не знать ответ, не придумать его на собеседовании и сказать это прямо через обозримое время, а может сидеть и «втыкать в бумажку» пока вы его не остановите, и тут снова же надо понять что значил первы и/или второй вариант.
.
Пункты 1,4 и 5 вполне применимы к джунам, пункт 2 и 3 условно применимы. Суть простая: азы надо знать! Если человек не знает азов, он будет делать очень не хорошие ошибки и тут не столь важно это врач который ампутирует не то что надо, или маляр который не правильно покрасит стену.

Да, Богдан, Вы правы. Перед тем, как задать вопрос на собеседовании я думаю о человеке, которому его задаю и для чего я его собственно задаю. Мне все равно, ходил ли человек в универ, или нет, и на какие пары, техническая ли у него специальность там или вообще отсутствует. Гораздо важней для меня то, что человек проявляет активный интерес к разработке/тестированию (об этом может свидетельствовать, например, наличие у него проектов на github или блог, статья(и) технического характера) и по ходу общения он не вызывает у меня сомнений в том, что он сработается с коллективом. Такие моменты, как правило Де Моргана и др. быстро усвоятся в процессе работы любым адекватным человеком при хорошем коллективе, и я в этом уверенна. Ну, по крайней мере, отношения в нашей компании на этом строятся.
Если бы я была на таком собеседовании, то, скажу честно, мне было бы не интересно отвечать на вопросы, перечисленные автором топика, и не только потому, что я не помню ответов на некоторые из вопросов, я в них просто вижу некую беспорядочность, из которой не совсем понятно, чем придется заниматься на проекте. Цели вопросов очень разбросаны: от низкого уровня имплементации, до умения писать красивый код. По моему убеждению красивый код не всегда является оптимальным, а за частую и наоборот, да и чувство прекрасного на каждом из уровней должно быть свое иначе может получится и не совсем оптимально, и не совсем красиво.

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

>> Аргумент просто супер: Вам что не жалко котенка? А будь вы на его месте?
Я всегда отдаю себе отчет в том, что собеседуя к себе в команду ребят нахожусь с ними в разном состоянии спокойствия, из-за чего стараюсь подобрать индивидуальных подход к каждому, а не следовать какому-то определенному списку вопросов.

что в любом случае нужно понимать контекст задачи, не зависимо от ее объема, сроков и пр.,
Нет. Надо выполнить задачу. Если вам уже досталась маленькая/конктретна задача, не имеет смысла тратить время на понимание бизнес-процесса иногда достаточно просто поменять код так чтобы ваша задача была решена и при этом не поломались другие сценарии.
Простой пример: в некотором месте был захардкожен текст, вам не надо понимать в каком контексте этот текст выводится, задача просто протянуть до этого места необходимые данные (бандл с переводами, например).
так как подход быстро сделал и забыл — эгоистичен по своей природе, так как снимет проблему с Ваших плеч но может создать проблему в будущем и не обязательно для Вас.
Нет, не эгоистичен, ибо не снимает ответственности.
Суть в том что есть вещи которые __надо__ делать на автомате (тот же пример с 3+5 и 5+3). Подход «сделал и забыл» — это очень круто, если «сделал и забыл, а оно работает».
из-за чего стараюсь подобрать индивидуальных подход к каждому, а не следовать какому-то определенному списку вопросов.
Индивидуальный подход — это правильно, но проверить базу все равно надо.
.
Такие моменты, как правило Де Моргана и др. быстро усвоятся в процессе работы
Форум ДОУ демонстрирует что у некоторых это за всю жизнь не «усваивается». Тут много людей которые приводят частный пример, как доказательство всеобщности, например. Снова же проблема не в самих законах де Моргана, а в том что человек не смог раскрыть скобки (за разумное время). Тут есть 2 варианта:
1) Претендент — Умственно Опережающий, так сказать.
2) Претендент не имеет достаточной базы.
Случай 1 — это те кого надо отсеять. Случай 2, тут сложнее, если вы готовы платить человеку пока он будет обучаться с 0, то вперед.
.
Гораздо важней для меня то, что человек проявляет активный интерес к разработке/тестированию
Вы рискуете :) Интерес — это дело временно. Профессионализм куда постояннее. И если человек не удосужился поискать «основные вопросы на собеседования» и не удосужился разобраться как работает ХешМапа, хоть на общем уровне, есть вероятность того что он будет с подобным же рвением выполнять и поставленные на работе задачи.
Если вам уже досталась маленькая/конктретна задача, не имеет смысла тратить время на понимание бизнес-процесса
Боря, ну так а зачем тогда тратить 5 лет жизни на какую-то муть, ради маленькой/конкретной задачки? Между прочим, «упростить булево выражение» в гугле сразу накидает кучу применимых правил.
И если человек не удосужился поискать «основные вопросы на собеседования»
Вас HR часом не кусал?
ну так а зачем тогда тратить 5 лет жизни на какую-то муть, ради маленькой/конкретной задачки?
Дарагой СТО, оказывается что задачи бывают разные. И если человек не способен эффективно выполнять часть из них (некоторый класс), большую часть — это проблема. Очень печально что СТО не понимает, что задачи надо дробить как можно мельче.
№ 2 Начинаю понимать откуда у вас эта неприязнь к вопросам из CS — у вас неверное нет ВО. Бо если б было то вы бы знали на что тратятся эти 5 лет :)
UPD.
Между прочим, «упростить булево выражение» в гугле сразу накидает кучу применимых правил.
С двух раз вы не осилили ответить на вопрос: dou.ua/...ic/9765/#467568
Может сейчас ответ придумали?
№ 2 Начинаю понимать откуда у вас эта неприязнь к вопросам из CS — у вас неверное нет ВО. Бо если б было то вы бы знали на что тратятся эти 5 лет :)
Боря, боюсь по-своей же классификации вы даже на подающего надежды джуна не тянете.

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

боюсь по-своей же классификации вы даже на подающего надежды джуна не тянете.
Да я крут! А может расскажете мне про «мою же классификацию»?
Ну а насчет вопроса — делайте, вы ведь понимаете, что такое не согласовывается(и в данной ситуации не несет особого смысла).
Товарищ Царев, могли бы написать привычно «Что?», а то как-то слив у вас совсем не забавный.
Да я крут! А может расскажете мне про «мою же классификацию»?
Вы рискуете :) Интерес — это дело временно. Профессионализм куда постояннее. И если человек не удосужился поискать «основные вопросы на собеседования» и не удосужился разобраться как работает ХешМапа, хоть на общем уровне, есть вероятность того что он будет с подобным же рвением выполнять и поставленные на работе задачи.

Круто, и где тут классификация? И где в ней определен класс «подающего надежды джуна»?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public class CustomerAccount
    {
        private ISpecification<CustomerAccount> _hasReachedRentalThreshold;
        private ISpecification<CustomerAccount> _customerAccountIsActive;
        private ISpecification<CustomerAccount> _customerAccountHasLateFees;

        public CustomerAccount()
        {
            _hasReachedRentalThreshold = new HasReachedRentalThresholdSpecification();
            _customerAccountIsActive = new CustomerAccountStillActiveSpecification();
            _customerAccountHasLateFees = new CustomerAccountHasLateFeesSpecification(); 
        }

        public decimal NumberOfRentalsThisMonth { get; set; }

        public bool AccountActive { get; set; }

        public decimal LateFees { get; set; }

        public bool CanRent()
        {            
            ISpecification<CustomerAccount> canRent = _customerAccountIsActive.And(_hasReachedRentalThreshold.Not()).And(_customerAccountHasLateFees.Not());

            return canRent.IsSatisfiedBy(this);             
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public class HasReachedRentalThresholdSpecification : CompositeSpecification<CustomerAccount> 
    {
        public override bool IsSatisfiedBy(CustomerAccount candidate)
        {       
            return candidate.NumberOfRentalsThisMonth >= 5;        
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public class CustomerAccountStillActiveSpecification : CompositeSpecification<CustomerAccount>  
    {
        public override bool IsSatisfiedBy(CustomerAccount candidate)
        {
            return candidate.AccountActive;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public class CustomerAccountHasLateFeesSpecification : CompositeSpecification<CustomerAccount>  
    {
        public override bool IsSatisfiedBy(CustomerAccount candidate)
        {
            return candidate.LateFees > 0;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public abstract class CompositeSpecification<T> : ISpecification<T>
    {
        public abstract bool IsSatisfiedBy(T candidate);

        public ISpecification<T> And(ISpecification<T> other)
        {
            return new AndSpecification<T>(this, other);
        }
      
        public ISpecification<T> Not()
        {
            return new NotSpecification<T>(this);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public interface ISpecification<T>
    {
        bool IsSatisfiedBy(T candidate);
        
        ISpecification<T> And(ISpecification<T> other);        
        
        ISpecification<T> Not();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public class AndSpecification<T> : CompositeSpecification<T>
    {
        private ISpecification<T> _leftSpecification;
        private ISpecification<T> _rightSpecification;

        public AndSpecification(ISpecification<T> leftSpecification, ISpecification<T> rightSpecification)
        {
            _leftSpecification = leftSpecification;
            _rightSpecification = rightSpecification;
        }

        public override bool IsSatisfiedBy(T candidate)
        {
            return _leftSpecification.IsSatisfiedBy(candidate) && _rightSpecification.IsSatisfiedBy(candidate);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASPPatterns.Chap5.Specification.Model
{
    public class NotSpecification<T> : CompositeSpecification<T>
    {
        private ISpecification<T> _innerSpecification;

        public NotSpecification(ISpecification<T> innerSpecification)
        {
            _innerSpecification = innerSpecification;
        }

        public override bool IsSatisfiedBy(T candidate)
        {
            return !_innerSpecification.IsSatisfiedBy(candidate);
        }
    }
}

Ну и? Вижу DSL, функции без сайд-эффектов, в чем сложность протестировать?

Я готов голыми руками оторвать яйца тому, кто будет в реальной задаче упрощать выражение
!(!a || b)
Да, с точки зрения математики это можно делать. Но как насчёт обратного преобразования? Ведь в один прекрасный момент (пятница, вечер, ASAP) понадобится прочитать код и понять что он делает. Если логика записана так, как поставлена задача — читаешь код быстро. А если «упростили» — сам чёрт ногу сломит.

Дальше больше. Упростил — круто, сэкономил пару наносекунд. Но... с вероятностью 10% допустил ошибку в упрощении. Учитывая плохую читаемость кода — найдут её нескоро.

Добавляем небольшой факт: большинство логических выражений относятся к ветвлению кода. И твой «упрощённый» код попадает... ну скажем в перехватчик исключений, которое возникает с вероятностью 1 из 100 000 000 и должно срочно разослать SMSку. Естественно этот кусочек кода будет выпилен из автоматического тестирования (чтобы не слать SMSку каждый раз). Либо она будет подменена записью в лог, если не задан номер телефона куда слать. И в первый день твоего отпуска, когда ты летишь на Бали... этот код выставляется в продакшен. Из-за ошибки в 1 знак (забыл «!») вероятность отправки SMSки составляет уже не 1, а 99 999 999 из 100 000 000.

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

А всего-то требовалось — написать логику в исходном виде.

// Кто программирует на java знает, что компилятор САМ оптимизирует логический код.
// (a!=null && !a) — не вызовет ошибки в случае a=null.
// А теперь упростите это выражение, и оцените его читаемость! А ведь это лишь одна маленькая операция. В реальном коде их сотни и тысячи.

Вы идеей когда-нибудь пользовались? Там такие упрощения делаются автоматически, вероятность ошибки 0%. Эти упрощения делаются не для оптимизации кода, а для рефакторинга и облегчения ее читабельности человеком, и как правило после упрощения становится ясной логика «синьера» который ее накрутил.
А чтобы не сбылся ваш ночной кошмар про Бали, надо тесты писать.

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

Паттерны: Composite, Specification. Ну это типа логика делегируется отдельным классам, которые проверяют логическое утверждение на основе чего-то. Из этих классов собирается аггрегат, используя кастомные логические Not, Or, And. Таким образом гораздо легче логику тестировать. Я хоть и не тестировал никогда, но по такому принципу писал. Ну ты понял короче?

Т.е. вы какгбе намекаете что существует такой код, который нельзя покрыть тестами? И про его валидность все верят на слово разработчику? А бедняга разработчик регулярно просыпается по ночам в холодном поту с мыслью «я не там поставил запятую!». %(====)

Не, ну я так прикинул, что дофига гемора нужно, чтобы протестировать какой-нибудь метод в котором внутри есть, что-то типа !(a == !b) && !(a != b), где а и b, что-то тоже большое. Можно сразу тестировать логическое выражение.

Упростим: !(a == !b) && !(a != b) => !(a == !b) && (a == b) => false во всех случаях

упс, опечатался !(a == !b) && !(a != b) => (a != !b) && (a == b) => (a==b) && (a==b) => a == b

Забей. Я вообще не про то. Смотри на пример из книжки.

Вот это «упс, опечатался» и подтверждает то, о чём выше сказал Алексей Пение.

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

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

В таких случаях line coverage конечно будет 100% но нет гарантии что вы учли все комбинации значений и покрыли все ветвления. Мы на проекте пробуем использовать mutation тестирование, оно дает более реальную информацию по покрытию. Еще более изощренный вариант — property-based тестирование типа www.scalacheck.org, но это уже требует значительных усилий на освоение. Поэтому иногда лучше упростить

!(a == !b) && !(a != b)
до
a == b
, когда кейс становится очевидным даже для написавшего
В таких случаях line coverage конечно будет 100% но нет гарантии
Везде, где идёт обработка данных(у которых есть constraints/крайние значения или разбитие на классы еквивалентности) 100% line coverage гарантий не даёт. Там нужен какой-то data-coverage, что-ли ...
Поэтому иногда лучше упростить
!(a == !b) && !(a != b)
Я к такому отношусь немножко категоричней и считаю что такое коммитить нельзя вообще, т.к. такой код чреват крешами в продакшине с последующими ночным дебагом и вырыванием рук :)
Если такое уже в закоммиченом коде: тоже упрощать, но только не в пятницу и на скорую руку и гарячую голову(тогда уж лучше не трогать).

Для упрощения idea/resharper/прочие умные ide в помощь, ну или подсказка друга.

mutation тестирование
property-based тестирование
не пользовал, надо будет глянуть.

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

Пусть это всего лишь 1%. В ВУЗе это даже не повлияет на оценку, человек с 1% ошибок будет отличником! Но пусть он пишет код из 100 подобных упрощений. А потом тесты к нему.
УГАДАЙ с одного раза, будет ли в анализе ТО ЖЕ САМОЕ логическое выражение?
УГАДАЙ с одного раза, человек будет упрощать его ЗАНОВО, или скопипастит?
Так вот, средняя вероятность ошибки составляет 100%

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

А теперь посмотрим с обратной стороны: Пусть логическое выражение выполняется 0.01нс, а в неупрощённом виде — 0.015нс. Его использует 1000 пользователей в сутки. Следовательно, за 10 лет пользования экономия составит... менее 1 милисекунды! Машинного времени. И лишь в случае 100% загрузки процессора чистой логикой (без ввода-вывода, прерываний, параллельных вычислений).

А сколько времени потратил кодер для ИЗУЧЕНИЯ булевой алгебры? Сколько для тренировки знаний? Сколько на СОБЕСЕДОВАНИЯ и подготовку к ним? Сколько на упрощение логики? Сколько на её чтение? Сколько на написание теста? Сколько на их многократный прогон при каждом чихе? Сколько времени тестера на учёт результатов? Сколько времени потратил владелец продутка на простой??? Сколько времени потратила поддержка на успокоение клиента «мы всё исправим в кратчайшие сроки»? Сколько времени потратили онсайт-сотрудники? И всё потому, что один «синьййор» был настолько самый умный, что оптимизировал код ради суммарной экономии 1мс за всю жизнь кода. И да, увидев ПОЧЕМУ не работал код — я потрачу немного времени чтобы оторвать яйца автору.

Когда ж вы перестанете делать за компьютер его работу?

Бгг, помню случай был, где «автоматическая упрощалка» таки ломала код (из за одной кривонаписанной внешней библиотеки).
Я написал большими буквами комментарий, что такой код там должен быть. Но синьйоры ж комментариев не читают, особенно если в иде то желтеньким подсвечено...

20 лет назад: «вы все еще используете goto?»
наши дни: «вы все еще используете null?»

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

И представь себе, во вложенных циклах всё так же встречается необходимость меток. А попытка их обойти будет «через жoпу» и приведёт к нечитаемому коду.

Естественно этот кусочек кода будет выпилен из автоматического тестирования (чтобы не слать SMSку каждый раз)
шепну вам по секрету: mockito

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

P.S. У меня тут завёлся тёзка, оказывается:) заранее прошу не путать нас.

Вставлю свои 5ть копеек.
1. Не стоит спрашивать именно правило Де Моргана, не все помнят, как оно там называется. Просто даете пример логического выражения где кол-во not зашкаливает да и все. Хотя похоже вы так и делаете.
2. Не стоит привязывать этот вопрос к конкретному языку. Человек который знает и понимает сложность алгоритмов разрулит сие на раз в любом языке. Ибо знает что это важно и что нужно искать, что бы почитать и быть в курсе.
3. Опять таки стоит ли спрашивать про конкретную реализацию? Не будет ли лучше спросить что такое Hash и попросить назвать одну из возможных реализаций. Конечно, попросив дать оценку сложности основных операций.
4. Как то шибко в лоб. Может лучше задачу подобрать, ну например ... навскидку ... возвести x (int) в степень y (uint). Просто тут вы можете сделать несколько шагов сначала в лоб, потом спросить сложность, потом попросить улучшить и так далее.
5. Я бы не спрашивал аббревиатуры. Ну блин не знает человек их, так что теперь. Ну только если сии не написана в CV у собеседуемого. Лучше спросить нечто такое — опишите структуру и дизайн подход вашего самого удачного кода. Ну или как то так. Не загоняйте собеседника в рамки, дайте ему простор и возможность для самостоятельного выбора.

Я обычно делаю так:
1. Бла бла бла расскажите о себе и один точный вопрос по чему-то указанному в CV, наугад что бы проверить насколько CV реально.
2. Две алгоритмические задачи — простая и сложная. Причем писать код можно на любом языке, но обязан быть код!!! В процессе написания и идет разговор про сложность алгоритмов и так далее.
3. В конце стандартное — опишите идеальное место работы для вас, лучшее что вы сделали и так далее.

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

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

Все написанное касается дисциплины Software Developer. Мои знания ограничиваются только этой дисциплиной.

Спасибо! Дельно! Поделитесь что спрашиваете про debugging skill

это очень зависит от seniority. разговор был про junior. так что просто попрошу рассказать пример чего и как он дебажил / отлаживал. и если junior понимает, что «step through code» это клево и полезно, но это далеко не конец истории. мне кажется это уже громадный плюс!

Эта тема должна плавно перетекать в разговор о «выстраданном убеждении» в необходимости и полезности ТДД.

Немного рационального зерна о джунах в этой статье: habrahabr.ru/post/210072
Про гуру смазано, но джун/мид/синьйор описаны хорошо.

Хех, давайте і я поміряюсь зашлю свій варіант:

    public static String transform(String input) {
        int insertPos = 0;

        boolean insideNumber = false;

        byte[] array = input.getBytes();

        for (int i = 0; i < array.length; i++) {
            boolean test = (array[i] >> 4) == 3;
            if (test) {
                if (!insideNumber && (insertPos != 0)) {
                    array[insertPos++] = ',';
                }
                array[insertPos++] = array[i];
            }
            insideNumber = test;
        }

        return new String(array, 0, insertPos);
    }

Какие-то зеленые джуночеловечки забили оффтопом все обсуждение. Аааааа памагите!

да ладно, люди хоть расчехлились, а то только о политике, да о зарплатах

это силы самообороны джунов

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

а смысл тогда в ветках вообще, если все отвечают в одну?

Тут много комментариев про задачу с запятыми и ее решения. Было бы cohesive сбросить это в одну ветку.

на входящей строке dou.ua/...ic/9765/#468398, javascript; выполнялось в Chrome 34@i5 3.2 GHz
jsperf.com/...ng-extra-commas
split(/[, ]+/).join(",")
427 op/sec ~ 2.5ms
replace(/[, ]+/g, ",")
574 op/sec ~ 1.8ms
что я сделал не так?

что я сделал не так?
Не сравнил с остальными имплементациями на своем компе :)

как общее кол-во операций посмотреть, или как вы op/sec переводите в мс?

перевожу в лоб: 1 / (op/sec value) === sec/op
конечно, это не совсем корректно, так как игнорируется время разовой записи входящих данных в переменную. лол.

что я сделал не так?
сделай в ие и в лисе

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

IE максимум что может — разорвать себе пукан, пытаясь выполнить любой Javascript или отобразить верстку. Помои, а не ПО.

Со всем согласен. Я только хотел сказать, что браузеры очень уж разные www.sitepen.com/...ce-an-analysis . Лично я на текущий момент разбирался только с сорцами лисы.

ололо. всячески рекомендую посмотреть 11 версию.
там даже профайлер на уровне гугловского.

И дебаггер хорош, и не только в 11 версии...

Лично мне было интересней написать генератор рандомной строки в миллион символов с запятыми, на это ушло где-то около 15ти минут, вот что получилось:
ruby

string = (0...1_000_000).map { [alph[rand(alph.length)], ","][rand(2)] }.join
по сути запятые выкидываються одной строкой тоже)
string.chars.map { |c| c = '' if c == ","; c }.join
Если у кого то установлен руби, то померьте мне пожалуйста : 3
С виртуалки (одно ядро пентиума, и 1,5 ОЗУ) на 1_000_000 символов, пишет мне такой результат:
Made in: 2.224215623
Что бы протестить по быстрому:
class Tmp
	def replace_commas(s)
	  start = Time.now
	  r = s.chars.map { |c| c = '' if c == ","; c }.join
	  endy = Time.now
	  time = endy - start
	  puts "Made in: #{time}"
	  puts "Replaced string: \n" + r
	end
end
alph = 'a'..'z'
alph = alph.to_a

string = (0...1_000_000).map { [alph[rand(alph.length)], ","][rand(2)] }.join
p string
p string.length

t = Tmp.new.replace_commas(string)
Лично мне было интересней написать генератор рандомной строки в миллион символов с запятыми, на это ушло где-то около
1 минута python:
''.join(random.sample((string.digits + ',' * 10 + ' ') * 100000, 100000))

я смотрю в питоне вообще кодить не надо... Знай сиди себе зп получай )

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

Із лекції SICP. Кожна мова програмування — це я гра «Шахи». Ви зможете вивчити за кілька хвилин правила гри, але навряд станете гарним гравцем. (Трохи сам інтерпретував).

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

Вот и я говорю, пишите джуны на питоне, не боритесь с системой :)

ну такое, булевую алгебру в пайтоне вроде не отменили, хотя я совсем другое спрашиваю на собеседовании

А чем это принципиально круче очевидного и супербыстрого варианта на джаве?

    Random r = new Random();
    StringBuilder s = new StringBuilder();
    for(int i = 0; i < 100000; i ++) {
      int n = r.nextInt(20);
      s.append(n > 9 ? ',' : n);
    }
супербыстрого варианта на джаве?
Супербыстрый это через char[] вместо StringBuilder.

НУ я имею в виду по сравнению с супертормозом на питоне.

там ниже чуть быстрее вариант, ну и давайте меряться временем (после выходных)

Кстати, посмотрел твой доклад, вы что храните все свои данные в mysql? Как вы тогда каскадинг без хадупа и с mysql используете?

вы что храните все свои данные в mysql?
Да.
Как вы тогда каскадинг без хадупа и с mysql используете?
Каскадинг юзается с хадупом. Результат хадуп агрегации ложится в базу. За месяц на среднюю табличку получается несколько гигабайт. На ХХХХ проекте еще мало репортинг данных, так что проблем с перформансом мускула нету.

Есть похожий проект, который 4 года в проде, там 1 табличка выросла до 1ТБ (постгрес). Там пришлось делать партишенинг чтобы укорить выборку. Помогло.

Кстати в презентации не написано почему вы не выбрали взрослую и нормальную NoSql BD вроде Cassandra?

Я об этом рассказывал во время доклада. Кассандра хендлит около 10к рек/сек с временем ответа ~8мс. Для нашего проекта 8мс многовато. Да и 10к рек/сек не очень круто.

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

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

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

Потому что тебе пришлось крутить велосипеды с решардингом
Согласен. Но по времени это 1 чел-день на разработку. Который сэкономил как минимум 1 одну ноду. В долгосрочной перспективе это очень хорошая экономия средств.
А еще на редисе ты можешь элементарно потерять данные, если мастер ляжет.
Часть данных. Но для нас это не критично, так что тут проблемы нету.

Вообще выбор был из Redis, Cassandra, Voldemort, DynamoDB, Memcached. Победил Redis. Как по перф. так и важной фичей — atomicIncrement, которую мы активно юзаем.

(string.digits + ’,’ * 10 + ’ ’) * 100000
это исходный сет «0123456789,,,,,,,,,, » размножается 100 000 раз(2 Мб данных вместо 21 байта?), а потом на базе этого сета генерируется строка из 100 000 раз рандомно выбранных его символов?

так точно. Что вас так поразило?
Для восстановления душевного равновесия:

import random
import string 


def get_rand_dou(n):
    for _ in xrange(n):
        yield random.choice(string.digits + ',' * 10)

''.join([i for i in get_rand_dou(100000)])

Что вас так поразило?
генерация 2,1 Мб текста ради 100 Кб результата :)

Часто время программиста дороже экономии памяти. Но возможно извернуться так, чтобы сэкономить память засчёт производительности программиста и/или кода. Ну и в философии питона — напиши прототип за 10 минут, погоняй, отладь, и если появится нагрузка — перепишешь на Си. Всё как дядя Кнут завещал, говоря о преждевременной оптимизации. :)

Часто время программиста дороже экономии памяти.
Круто у вас там в питоне. Все вот это:
погоняй, отладь, и если появится нагрузка — перепишешь на Си.
У вас делаетсо за 0 времени (и соответственно 0 денег) :)

ну переписать работающую вещь всяко быстее, чем написать новую по ТЗ. Всё лучше, когда есть прототип)
а модный питон чем хорош, что его реализацию запилили уже под большое количество платформ.
т.е. «перепишешь на С» может оказаться банальным «добавили типизацию, скомпилили Cython», или «заюзали numpy — получили 10х профит в критической секции», или «писали изначально на Jython»

ну переписать работающую вещь всяко быстее, чем написать новую по ТЗ.
Нет, особенно если часть спецификации утеряна, что бывает в __больших__ (с большим количеством бизнес-правил) проектах очень часто.
т.е. «перепишешь на С» может оказаться банальным «добавили типизацию, скомпилили Cython», или «заюзали numpy — получили 10х профит в критической секции», или «писали изначально на Jython»
Ок:
У вас делаетсо за 0 времени (и соответственно 0 денег) :)
?
Проблема в том что многие свою криворукость оправдывают:
Всё как дядя Кнут завещал, говоря о преждевременной оптимизации.

Ну в __больших__ проектах с утерянными спецификациями в случае оптимизаций и на C будет такой же, если не больший ад, разве нет?

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

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

Почитайте увлекательную (правда, древнюю) статью Джоэла Спольски, особенно в части про преимущества языков с автоматическим управлением памятью, у него весьма убедительные аргументы, на мой взгляд. russian.joelonsoftware.com/...ttheWaronA.html

Ну и во всяких яндексах да стартапах такое часто практикуют, сам сталкивался — тоже все повально дураки там?

И да, конечно есть задачи, для которых только си, только хардкор и никаких скриптов на выстрел нельзя подпускать. Но это свой класс задач, и туда с питоном, вроде, никто не лезет (микроконтроллеры всякие, компиляторы и прочие системные штуки).

Ну, зато пишется дольше, требуется выше квалификация и больше опыта и легче выстрелить себе в ногу, а потом долго и упорно искать, где память не так выделил или не убрал за собой.
Вон человек чуть выше отстрелил себе 2.1 Мб (по подсчетам Евгений Козлов). :)
Не проще ли прогонять сначала алгоритм на pseudocode-like-прототипе
Круто, пишите алгоритм, но правильный алгоритм. А не идо-код. И тут не важно на чем Ц или питон, надо писать на том на чем умеешь.
Ну и во всяких яндексах да стартапах такое часто практикуют, сам сталкивался — тоже все повально дураки там?
Стартапы дело такое. А вот можно ссылку на то чтобы в яндексе говняли откровенно индусский код, а потом его переписывали. Очень интересно было бы почитать.
.
Но это свой класс задач, и туда с питоном, вроде, никто не лезет
Есть у меня догадка, что вы нафантазировали что мой пост — это наезд конкретно на питон. Если так, то вы ошиблись.
Круто, пишите алгоритм, но правильный алгоритм. А не идо-код. И тут не важно на чем Ц или питон, надо писать на том на чем умеешь.
Работали когда-нибудь в условиях меняющихся спецификаций, особенно если проект «живой», ещё не до конца всем ясно что и как именно нужно делать (своего рода, проект в сфере R&D), чтобы он «выстрелил»? Я работал. Там сначала пишешь один правильный алгоритм, всё хорошо, потом выясняется, что алгоритм должен быть такой же правильный, но немного другой по смыслу. И так может быть несколько раз.
С последним совершенно согласен. :) Верно абсолютно, писать надо на том, на чём умеешь лучше всего.
Стартапы дело такое. А вот можно ссылку на то чтобы в яндексе говняли откровенно индусский код, а потом его переписывали. Очень интересно было бы почитать.
Вот слайды Руслана Гороховецкого про то, как делали погоду в Яндексе, где он рассказывает, что писали на Python и переписывали критичные части на C++. www.slideshare.net/...rokhovetsky-ekb
Можете глянуть видео по этому докладу. Ещё, если не ошибаюсь, я слышал что у них с картами похожая история была, но не уверен, давно видео это смотрел.
Есть у меня догадка, что вы нафантазировали что мой пост — это наезд конкретно на питон.
Да нет, просто дал себе волю пофилосовствовать вслух с хорошим собеседником. :)
что писали на Python и переписывали критичные части на C++
Та я не это спрашивал, я спросил:
говняли откровенно индусский код, а потом его переписывали
Переделать код который уткнулся в производительность платформы (в нашем случае конкретный интерпретатор питона) — это условно-нормальный вариант (тут скорее философский вопрос).
Написать заведомо говнокод, а потом переписывать его под другую экосистему — это уже диагноз.
.
Возвращаемся к началу разговора:
Часто время программиста дороже экономии памяти.
Если программист делает свою работу хорошо, то таки можно доставить памяти на железку и мы сэкономили деньги на оплате программиста. Если как в нашем случае (2.1Мб), то мы попадаем в двойне (возможно втройне): — первый раз на переписывание на генераторы,
— 1.5-раз когда упремся в сборку мусора в генераторе (не знаю как оно в питоне),
— второй раз когда упремся в интерпритатор/среду.
Просто наблюдение питонисты/рубисты/прочая_хипстота любят показывать красивый код __даже в ущерб__ здравому смыслу.

А теперь понял вас, простите что не с сразу. Согласен. Здравый смысл нужен. И там, где участок заведомо критичный и писать лучше сразу оптимально, и там, где выполняется редко и никогда в ограничение не упрётся — тогда подойдёт самый очевидный и быстрый в написании вариант, без забот об оптимизации — быстро написал и забыл.

Но да, часто идут исключительно по второму варианту, это да, клиника.

7) Что такое селективность?
8) Как работает бинарное, балансированное дерево.

А что такое селективность?

Че уж, пусть красно-черное дерево балансируют на собеседовании, прямо код пишут. При этом если запутаются — тыкать пальцем и хохотать.

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

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

И как «правило Де Моргана» позволяет длину транзакции уменьшить?

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

И как «правило Де Моргана» позволяет длину транзакции уменьшить?
Задача собеседования не выявить обладает ли человек всей необходимой информацией. Задача — определить общий уровень кандидата. Уровень ВО — это один из показателей, в случае с синьорами, он отходит на второй план, в случае с джунами, ВО — это один из первых показателей.
Знание (умение применять, а не знание названия) правил де Моргана — это __один из__ тестов на уровень ВО. Вопросы про ЛинкедЛист и АррейЛист — так же (к слову, что бы там не говорили про заучить ответы, тех кто заучил видно практически всегда).
Уровень ВО — это один из показателей

У меня был один интерн, ему недавно курс по concurrency читали по Brian Goetz. Мы его усадили писать юнит-тесты — так он все рвался lock-free писать, с адскими race conditions. Каждое код ревью длилось по неделе — т.к. он отказывался слово «synchronized» использовать. На собеседовании уровень ВО продемонстрировал, несомненно. Писать читабельный и рабочий код не умеет.

Печалька. Вот только зачем вы это рассказали?

На собеседовании уровень ВО продемонстрировал, несомненно. Писать читабельный и рабочий код не умеет.
А вы знаете значение словосочетания:
один из показателей
?
Помимо уровня ВО, надо смотреть еще на 100500 параметров. В том же числе и оценивать психологическую готовность работать (выполнять работу), довольно часто «заводных апельсинов которые мечтают сходу написать гугл за 15 мин» можно определить за время собеседования.
И как «правило Де Моргана» позволяет длину транзакции уменьшить?

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

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

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

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

Булевая алгебра — «дорогостоящие вычисления»? С современными компиляторами?

регулярно смотритесь в зеркало и публикуете своё «селфи» в виде таких реплик

Ну да, свое превосходство надо демонстрировать превращая собеседование в телевикторину.

Булевая алгебра — «дорогостоящие вычисления»?

Простой пример. Так называемый метод Блейка для поиска другой тупиковой ДНФ выглядит так: если у нас есть A*C + B*not©, мы можем прибавить (OR) к ним A*B и смысл выражения не изменится.
Но тот же приём можно применить и в обратном направлении — убрав такое A*B.
Я сталкивался с подобным неоднократно в многоэтажных выражениях. Раскрытие в какую-то из нормальных форм и упрощение полученного приводило к тому, что некоторые условия просто выбрасывались.

Ну да, свое превосходство надо демонстрировать превращая собеседование в телевикторину.

Чтобы понять, почему этот аргумент бессмысленный, представьте себе, что Вас интервьюер спрашивает, чему равно 2*2 (и он знает, что половина кандидатов не может на это ответить, зато потом что-то бросают через плечо про викторину).

Правила раскрытия отрицаний в булевских выражениях должны быть известны каждому, кто претендует на то, что понимает, чем AND отличается от OR. Можно не знать их названия, но если кто-то не знает их сути — он непригоден для профессии. Поэтому я тут всецело с автором топика.

Но тот же приём можно применить и в обратном направлении — убрав такое A*B.
Я сталкивался с подобным неоднократно в многоэтажных выражениях.

Мне уже давно интересно, почему эрудиты-теоретики пишут «многоэтажные выражения», которые потом упрощать надо? Часто в C коде вижу — по пять строк в if. Вот таких людей на собеседовании и надо гнать поганой метлой.

Можно не знать их названия, но если кто-то не знает их сути — он непригоден для профессии.

Ну не надо путать понимание логических операторов и вопросы на эрудицию. Есть намного более внятные способы спросить — например, просто попросить написать код.

Мне уже давно интересно, почему эрудиты-теоретики пишут «многоэтажные выражения», которые потом упрощать надо? Часто в C коде вижу — по пять строк в if.

Наверно, потому, что задача действительно сложная и надо учитывать именно этот набор факторов и именно в такой комбинации? (риторический вопрос)

Конечно, в задаче типа «отреагировать на нажатие кнопки на экране переходом по ссылке» такого не будет. Но посмотрите код, например, стека TCP. (Мне такая область ближе, чем веб.) Или у меня сейчас задача взаимодействия с удалёнными исполнителями заданий, причём с необходимостью учёта слабоуправляемых переходов между состояниями исполнителей, двумя каналами информирования (синхронным и асинхронным) с обгонами между ними, возможностью обрыва протокола на любой фазе. Местами получаются, да, сложные выражения. Или раскладываются в пол-экрана постепенной проработки условий, и так бывает. Реальность — она, знаете ли, разнообразная.

Вот таких людей на собеседовании и надо гнать поганой метлой.

Я не сомневаюсь, что в Duppa Govnosite Ltd. так и сделают. Но не потому, что выражение сложное, а потому, что начальник его просто не поймёт, как бы ни старался. :)

Есть намного более внятные способы спросить — например, просто попросить написать код.

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

Наверно, потому, что задача действительно сложная и надо учитывать именно этот набор факторов и именно в такой комбинации? (риторический вопрос)

Нет. Всегда можно:
а. Выделить подвыражения в переменные.
б. Разделить один if на несколько.

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

Да ладно. Там этот талант сам от экрана на 5 минут отвернется и не сможет в логике разобраться.

а. Выделить подвыражения в переменные.

І як це допоможе читаності? Якщо воно не прокоментовано хоча в головних подробицях — ясніше не буде.

Да ладно. Там этот талант сам от экрана на 5 минут отвернется и не сможет в логике разобраться.

Не бачу приводів для такого висновку.

Якщо воно не прокоментовано хоча в головних подробицях — ясніше не буде.
Если нужны комментарии, значит код уже пахнет...

ой-ой.
самодокументирующий код и все дела?

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

Не вижу никакого обоснования для этого утверждения — по крайней мере для «наукоёмкого» (советским термином) кода, который составляет заметную часть моей работы.
В нём совершенно нормально, что комментарии по объёму больше самого кода и содержат утверждения вида «реализуется алгоритм KPTGGX по варианту Z+ по результатам тестирования в тикете #402125», или «тут проверка условия A обязательна до условия B из-за неизбежных побочных эффектов» — в общем, всего, что лучше иметь перед глазами при анализе кода тем, кто в теме общей задачи, но не помнит специфику реализации именно данного места.
Разумеется, для одноразовых поделок (которых сейчас 99% ушло в веб) комментарии не нужны — потому что сам код никому больше и не нужен. Но меня не интересует такой опыт данной области.

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

И да, отсутствие комментариев != отсутствие документации.

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

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

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

И да, отсутствие комментариев != отсутствие документации.

Лучшая внутренняя документация, как показала мировая практика, строится таки на основании подходов стиля javadoc. А это те же комментарии.

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

И это тоже один из возможных методов. Но знание его обычно коррелирует со знанием правил де Моргана (даже не зная их название).

А можно ли вам отправить парочку перспективных потенциальных джунов на собеседование? Просто интересно пройдут или нет т.к. собеседование в CV ходят слухи еще то :)

ОК после праздников направлю парочку. Спасибо.

Что первое в голову пришло. Может не самый быстрый вариант, но много ли надо времени что бы одну строку написать?)
ruby

s = ’’,,,,12,,,2,3142,32,,245,2,5,45,256,3,64,,,,,,,,,,,,,467467467,467,46,74,674,6,,,,,,2342,3,,3234,,2,2,,,234234′
[16] pry(main)> def replace_commas(s)
[16] pry(main)* start = Time.now
[16] pry(main)* r = s.chars.map { |c| c = ’’ if c == ’,’; c }.join
[16] pry(main)* endy = Time.now
[16] pry(main)* puts “Made in: #{endy — start}” + r
[16] pry(main)* end
=> :replace_commas
[17] pry(main)> replace_commas s
Made in: 0.00072

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

Ну я просто решил показать что в ruby можно сделать одной строкой:

s.chars.map { |c| c = ’’ if c == ","; c }.join
Мерятся скоростью не могу, т.к. я сижу на старом пентиуме, на одном ядре и с виртуалки : )
Вообще конечно интересно было бы сравнить результаты, но это должен делать один и тот же человек на одном и том же железе, для большей объективности.

Но сама строка красива, спору нет.

Быстрый пайтон вариант

s = "",,,534,,,,2,3,,,,3,24,5,,4,33,,,,5,,3,,3,,54,,,,,3,,3,,,,,"
def java_sasai():
    return ','.join(t for t in s if t > '1')
>>>timeit('java_sasai()', setup='from kk import java_sasai', number=1000)/1000
0.004397132832998978

4 ms 100k символов.

А судя по коду, только строка указанная в условии. Впрочем, мы не знаем, какой у тебя компьютер :)

тут dou.ua/...ic/9765/#468394 пастебины с входом выходом,
тут dou.ua/...ic/9765/#468237 машина

А можешь сделать 1М символов и сравнить с любой из джавовских имплементаций на своей машине?

всё линейно 6.4 ms на 100к, 6.4 sec на 1m

Так с джавовской будешь сравнивать?

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

мне че-то кажется, что оно из ,3,24,512, сделает ,3,2,4,5,1,2,

agreed, подправил алгоритм

входная строка pastebin.com/w7UKB8XB
fixed algo:

def func_recover():
    return ','.join(t.replace(' ','') for t in s.split(',') if t > '1')

новый замер

>>> from timeit import timeit
>>> timeit('func_recover()', setup='from kk import func_recover', number=1000)/1000
0.00648861759400097

выходная строка pastebin.com/LiidZuNw

6.4 ms на 100к

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

Че-то мы пока что не увидели, что он ее уделывает. Может ты протестишь у себя в равных условиях джава и питон реализации?

А зачем вы набираете джунов? Если вы считаете, что они незнают «элементарного», то берите минимум миддла. Или мы такие умные что такие жадные?

Ну, не все безнадежны, встречаются и достойные кандидаты

Вариант на Haskell:

import Data.List

javaSucks :: [Char] -> [Char]
javaSucks str = intersperse ',' $ filter (\x-> x > '1') str  

main = do
	print $ last.javaSucks $ ",,,534,,,,2,3,,,,3,24,5,,4,33,,,,5"

Выборка из статической уже сгенеренной рандомно строки размером в 100к символов (обрезанной из-за понятных соображений)

kperevozchikov@kperevozchikov-desktop:~$ time ./wih
'5'

real	0m0.004s
user	0m0.004s
sys	0m0.000s

4 ms

Вариант Макса на Пайтоне

import re
import random
s = " , 4, 3, 5,,,,4,,34,,,,3,,,2,,5,,,534,,,,,,,3,,"
s = s * 20000
list_s = list(s)
random.shuffle(list_s)
s = ''.join(list_s)
print(len(s))
 
 
def func_recover():
    return ','.join([t for t in re.split(',\s*', s) if t])
>>> from timeit import timeit
>>> timeit('func_recover()', setup='from kk import func_recover', number=1)
940000
0.11709021199931158
>>> 

11 ms на 940000 символов

Ниочем. Я щас на сишке влеплю красавца. Не побьете.

но ведь все утверждают что жава быстрее пайтона
и вообще гвидоскрипт ни на что не способен

Тоже чесались руки собрать без единого call на чистом С. )
Но решил молодежи оставить — люблю такие меряния пиписьками, в моей юности они очень сильно развивали.
.
Кстати можно усложнить задачу — то же условие, но не использовать посимвольный перебор ни в явном, ни в скрытом виде.

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

там не было генератора, я всего лишь умножил вашу строку в 2000 раз и перемешал её
dl.dropbox.com/...lection_004.png
dl.dropbox.com/...lection_005.png

hotfix (выше на самом деле 117 ms на 940000 символов и один вызов)

from timeit import timeit
>>> timeit('func_recover()', setup='from kk import func_recover', number=1000)/1000
0.012066998903999775

Для тех, кто не верит в любовь с первого раза

Пф... теж мені проблема. Ось я бачив авторитетного монсіньйора який не знав що значить слово брутфорс і навіть не чув хто такий Тюрінг і його машина. І це не в якісь там недоконторці а лідеру ринку.

Sensei и Alex Chuprikoff делят первое место.
Иван Мазепов на втором
Пупкин — третье место

Прикольно задача о написании кода за 3 минуты переросла в соревнования по скорости :) :) .

Хех, технари. Нет чтоб сложность алгоритмов прикинуть — так они реализации сравнивают.

проявите себя, сравните сложности алгоритмов.

А что там их сравнивать? У вас по сути два алгоритма:
— разобрать/собрать
— Пройтись по-символьно.
Оба О(n), но «разобрать/собрать» растет быстрее примерно в 2 раза.
Остальное — уже погрешности реализации.

вот мой модифицированный алгоритм, он рвет всех на части. мне как трейни простительно не знать в чем преимущество StringBuilder перед переопредилением строк.

 static String mobileMobileImpl(String inputString) {
    String correctString = "";
    StringBuilder temp = new StringBuilder("");
    inputString = inputString.replaceAll("\\s", ",");
    boolean digitCatch = false;
    for (int i = 0; i < inputString.length(); i++) {
      char currentChar = inputString.charAt(i);
      if (currentChar != ',') {
    	temp.append(inputString.charAt(i));
        //correctString = correctString + currentChar;
        digitCatch = true;
      } else {
        if (digitCatch) {
          temp.append(',');
          //correctString = correctString + ',';
          digitCatch = false;
        }
      }
    }
    String result = temp.toString();
    return (result);
    }

условие изначальной задачи ж было «написать за 3 минуты (или за 6?)» ;)

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

StringBuilder
работает на порядок быстрее. ну и плюс некоторые люди научилис вставлять код )))

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

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

Где-то так gist.github.com/...4e9fffc3080b69b
Если в решении хакера заменить строку на билдер, получаем нового победителя

а можете протестировать еще и вот это? :)

   char[] c1 = a.toCharArray();
        char[] c2 = new char[c1.length];
        int p1 = 0;
        boolean f = false;
        boolean f2 = true;

        for (int i = 0; i < c1.length; i++) {
            if (c1[i] == ' ') continue;
            if (c1[i] != ',') {
                if (f && !f2) {
                    c2[p1++] = ',';
                    f = false;
                }
                c2[p1++] = c1[i];
                f2 = false;
            } else {
                f = true;
            }
        }

        String result = String.valueOf(c2);

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

да что тут писать? конечно не больше 6 мин.
Ну пакаж

вечером гляну. А то тут днем все-таки работа работается, некогда задачки решать длиннее чем на 5 минут :)

Это еще что, ко мне приходят синьеры которые не могут в деревья и связные списки!

а что это связанные списки ? вернее что с ними делать, а то в лекциях беркли разжовывают детально Slist подклас List и потом Tlist, что со списками делать то ?

Реализацию написать. С одним методом add.

	public static String test(String arg, char escapeChar) {
		 char[] arr = arg.toCharArray();
		 StringBuilder sb = new StringBuilder(arr.length);
	   for(int i=0; i < arr.length; ){
             if(Character.isSpaceChar((int)arr[i])){
                i+=1;
                continue;
             }
	    if(arr[i]== escapeChar){
		while((++i < arr.length 
                     && (Character.isSpaceChar((int)arr[i]) || escapeChar == arr[i])));
                if(i != arr.length){
                    sb.append(escapeChar);
                }
                continue;
	    }
			sb.append(arr[i]);
			i+=1;
		}
		return sb.toString();
	}
эконом вариант
Sensei, size:[1] done in: 0ms
Sensei, size:[10] done in: 0ms
Sensei, size:[100] done in: 0ms
Sensei, size:[1000] done in: 1ms
Sensei, size:[10000] done in: 17ms
Sensei, size:[100000] done in: 25ms
StringBuilder sb = new StringBuilder(arr.length);
Вот и секрет успеха :)

А вот и сам код тестирования алгоритмов, думал написать интерфейс, от него реализовать несколько видов алгоритмов со своим toString, но стало жутко впадлу, просто вызываем нужную реализацию в main и меняем имя автора, reality hacker, мне за вас стыдно:

public class DouStringQuoteBuilder {

    private static Random random = new Random();

    public static void main(String[] args) {
        int testSizes[] = {1, 10, 100, 1000, 10000, 100000};

        for (Integer size : testSizes) {
            long currentTime = System.currentTimeMillis();

            mobileMobileImpl(populateRandomizedString(size));

            long elapsedTimeInMiils = System.currentTimeMillis() - currentTime;
            System.out.println("Mobile mobile, size:[" + size + "] done in: " + elapsedTimeInMiils + "ms");
        }

    }

    static String mazepaImpl(String param) {
        return param.replaceAll("[,\\s]+", ",").replaceAll("^,|,$", "");
    }

    static String realityHackerImpl(String param) {
        StringTokenizer t = new StringTokenizer(param, ", ", false);
        String s = "";
        while(t.hasMoreTokens()) {
            if (s.length() > 0) s += ",";
            s += t.nextToken();
        }
        return s;
    }

    static String pupkinImpl(String param) {
        String[] arr = param.split("[,+\\s+]");
        String correctString = "";
        if (arr.length > 0) {
            StringBuilder builder =  new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                if (arr[i].length() > 0) {
                    builder.append(arr[i]).append(",");
                }
            }
            builder.delete(builder.length()-1,builder.length());
            correctString = builder.toString();
        }
        return correctString;
    }

    static String mobileMobileImpl(String inputString) {
    String correctString = "";
    inputString = inputString.replaceAll("\\s", ",");
    // correctString=correctString.replaceAll(",,,,", ",");
    // correctString=correctString.replaceAll(",,,", ",");
    // correctString=correctString.replaceAll(",,", ",");
    // correctString=correctString.replaceAll(",,", ",");
    // char comma=',';
    boolean digitCatch = false;
    for (int i = 0; i < inputString.length(); i++) {
      char currentChar = inputString.charAt(i);
      if (currentChar != ',') {
        correctString = correctString + currentChar;
        digitCatch = true;
      } else {
        if (digitCatch) {
          correctString = correctString + ',';
          digitCatch = false;
        }
      }
    }

    return (correctString);
    }

    static String populateRandomizedString(int length) {
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(generateRandomChar());
        }
        return sb.toString();
    }

    static char generateRandomChar() {
        return randomNumberOrQuote(generateRandom());
    }

    //конкретная цифра не имеет значения, важно лишь цифра или запятая
    private static char randomNumberOrQuote(boolean random) {
        return (random ? ',' : '4');
    }

    private static boolean generateRandom() {
        return random.nextBoolean();
    }

}

у меня на вот это ругается
private static Random random = new Random();
return random.nextBoolean();
что я делаю не так ?

статические переменные класса низзя использовать в нестатических методах.
У меня везде статика только из-за main.
И кстати переменной внутри метода нельзя присвоить модификато доступа: private/protected/public.
Если у вас рандом внутри статического метода, то просто.

return newRandom().nextBoolean()
, я вынес рандом на уровень класса, чтобы не создавать много лишних и ненужных объектов.

не знаю про шо это вы но я решил проблему добавление этого
import java.util.StringTokenizer;
import java.util.Random;
после замены в моем методе присвоение сткрокой на

temp.append(input.charAt(i));
мой метод стал самым быстрым.
статические переменные класса низзя использовать в нестатических методах.
facepalm.jpg

Каждый день использую «статические переменные класса» в «нестатических методах», а оказывается низзя

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

В жизни разные ситуации бывают:

import java.util.Random;
import java.util.StringTokenizer;

public class DouStringQuoteBuilder {

    private static Random random = new Random();

    public static void main(String[] args) {
        long testSizes[] = {100000, 1000000};

        for (Long size : testSizes) {
            long currentTime = System.currentTimeMillis();
            
            for(long i = 0; i < size; i ++) {
            	realityHackerImpl(populateRandomizedString(10));
            }

            long elapsedTimeInMiils = System.currentTimeMillis() - currentTime;
            System.out.println("Mobile mobile, size:[" + size + "] done in: " + elapsedTimeInMiils + "ms");
        }

    }

    static String mazepaImpl(String param) {
        return param.replaceAll("[,\\s]+", ",").replaceAll("^,|,$", "");
    }

    static String realityHackerImpl(String param) {
        StringTokenizer t = new StringTokenizer(param, ", ", false);
        String s = "";
        while(t.hasMoreTokens()) {
            if (s.length() > 0) s += ",";
            s += t.nextToken();
        }
        return s;
    }

    static String pupkinImpl(String param) {
        String[] arr = param.split("[,+\\s+]");
        String correctString = "";
        if (arr.length > 0) {
            StringBuilder builder =  new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                if (arr[i].length() > 0) {
                    builder.append(arr[i]).append(",");
                }
            }
            builder.delete(builder.length()-1,builder.length());
            correctString = builder.toString();
        }
        return correctString;
    }

    static String mobileMobileImpl(String inputString) {
    String correctString = "";
    inputString = inputString.replaceAll("\\s", ",");
    // correctString=correctString.replaceAll(",,,,", ",");
    // correctString=correctString.replaceAll(",,,", ",");
    // correctString=correctString.replaceAll(",,", ",");
    // correctString=correctString.replaceAll(",,", ",");
    // char comma=',';
    boolean digitCatch = false;
    for (int i = 0; i < inputString.length(); i++) {
      char currentChar = inputString.charAt(i);
      if (currentChar != ',') {
        correctString = correctString + currentChar;
        digitCatch = true;
      } else {
        if (digitCatch) {
          correctString = correctString + ',';
          digitCatch = false;
        }
      }
    }

    return (correctString);
    }

    static String populateRandomizedString(int length) {
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(generateRandomChar());
        }
        return sb.toString();
    }

    static char generateRandomChar() {
        return randomNumberOrQuote(generateRandom());
    }

    //конкретная цифра не имеет значения, важно лишь цифра или запятая
    private static char randomNumberOrQuote(boolean random) {
        return (random ? ',' : '4');
    }

    private static boolean generateRandom() {
        return random.nextBoolean();
    }

}

realityHacker: 595ms
vasya pupkin: 1126ms
mazepa: 1656ms

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

Ок, твоя имплементация рулит на строках в 10 символов :) У меня регекс долго компилируется, зато потом быстрее. Можешь сделать

populateRandomizedString(10000)
чтобы проверить

А зачем? Помоему в реальности намного чаще приходится обрабатывать очень много коротких строк а не одну огромную.

Ок, твоя имплементация рулит на строках в 10 символов :) У меня регекс долго компилируется, зато потом быстрее.
Не совсем gist.github.com/...9b#file-out-txt
Сейчас еще настрою окружение и проверю вариант с кешированым регекспом (ибо реплейсАлл, вроде как, компилируется каждый раз)

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

Плохому танцору всегда что-то мешает.

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

Сам себе придумал короткие строки?
Конкатенация чистых стрингов — это фейл уровня trainee, их после этого на работу не берут, а ты гордишься.....

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

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


String correctString = Arrays.stream(a.split("[,+\\s+]"))
.filter(s -> s.length() > 0)
.collect(Collectors.joining(","));
При этом работает достаточно ок.
мой вариант с стрингбилдером уделывает всех
если бы бабушке да пуй, то она была бы дедушкой... Чувак, ты облажался и потом еще начал доказывать что такого вида конкатенация это ок. А сейчас вдруг оправдываться решил. Ха.
Моя реализация первая была изначально написана с ориентиром на максимальную читабельнось и удобство написания.
Но твои попытки написать на джава 7 вызвали кровавые слезы у меня
Чувак, ты облажался и потом еще начал доказывать что такого вида конкатенация это ок. А сейчас вдруг оправдываться решил. Ха.
Да, я писал тот код после полуночи, и поленился посмотреть в интернетиках оптимизируется ли цикл, грызите меня бандерлоги.

size = 10

Benchmark                               Mode   Samples         Mean   Mean error    Units
o.s.MyBenchmark.mazepaImpl             thrpt       200      696,571       17,631   ops/ms
o.s.MyBenchmark.realityHackerSBImpl    thrpt       200     4577,596      309,637   ops/ms

Чистый выигрыш в 20 раз, и чего и следовало ожидать.

Пока результат такой (для длинны 10_000):

Benchmark                               Mode   Samples         Mean   Mean error    Units
o.s.MyBenchmark.mazepaCachedImpl       thrpt       200        1,511        0,026   ops/ms
o.s.MyBenchmark.mazepaImpl             thrpt       200        1,622        0,009   ops/ms
o.s.MyBenchmark.realityHackerSBImpl    thrpt       200        4,221        0,038   ops/ms

все же хакер проиграл в любом из бенчмарков.
подкиньте в ваш еще 3-4 реализации, которые сюда запостили — интересно же.

вот это, вот это хо сравнить с другими еще :)

char[] c1 = a.toCharArray();
        char[] c2 = new char[c1.length];
        int p1 = 0;
        boolean f = false;
        boolean f2 = true;

        for (int i = 0; i < c1.length; i++) {
            if (c1[i] == ' ') continue;
            if (c1[i] != ',') {
                if (f && !f2) {
                    c2[p1++] = ',';
                    f = false;
                }
                c2[p1++] = c1[i];
                f2 = false;
            } else {
                f = true;
            }
        }

        String result = String.valueOf(c2);
все же хакер проиграл в любом из бенчмарков.
Ты их неверно читаешь, наоборот выиграл, 0.038 опс/мс самый лучший результат
подкиньте в ваш еще 3-4 реализации, которые сюда запостили — интересно же.
Код тут: gist.github.com/...otebuilder-java
Как сделать проект тут: openjdk.java.net/...code-tools/jmh
Чувак который умеет делать бенчмарки тут: twitter.com/shipilev

Победа уходит Ивану Мазепову.
вот результаты вычислений 4-х приведенных алгоритмов по запятым:

Reality hacker, size:[1] done in: 0ms
Reality hacker, size:[10] done in: 0ms
Reality hacker, size:[100] done in: 0ms
Reality hacker, size:[1000] done in: 6ms
Reality hacker, size:[10000] done in: 180ms
Reality hacker, size:[100000] done in: 6809ms

Pupkin, size:[1] done in: 7ms
Pupkin, size:[10] done in: 1ms
Pupkin, size:[100] done in: 0ms
Pupkin, size:[1000] done in: 4ms
Pupkin, size:[10000] done in: 29ms
Pupkin, size:[100000] done in: 84ms

Mobile mobile, size:[1] done in: 9ms
Mobile mobile, size:[10] done in: 0ms
Mobile mobile, size:[100] done in: 0ms
Mobile mobile, size:[1000] done in: 6ms
Mobile mobile, size:[10000] done in: 242ms
Mobile mobile, size:[100000] done in: 3807ms

Mazepa, size:[1] done in: 3ms
Mazepa, size:[10] done in: 0ms
Mazepa, size:[100] done in: 1ms
Mazepa, size:[1000] done in: 6ms
Mazepa, size:[10000] done in: 48ms
Mazepa, size:[100000] done in: 46ms

круто ) . Спасибо за сравнение

public static String GetResult(String input){
        StringBuilder temp = new StringBuilder("");
        int len = input.length();
        int i = 0;
        while(input.charAt(i) == ',')
            i++;
        for(; i < len;i++){
            if(input.charAt(i)!=',' || (i + 1 < len && input.charAt(i+1) != ',')){
                temp.append(input.charAt(i));
            }
        }
        String result = temp.toString();
        return result;
    }
Еще такой можешь потестить?
Alex Chupikov, size:[1] done in: 0ms
Alex Chupikov, size:[10] done in: 0ms
Alex Chupikov, size:[100] done in: 0ms
Alex Chupikov, size:[1000] done in: 8ms
Alex Chupikov, size:[10000] done in: 9ms
Alex Chupikov, size:[100000] done in: 23ms

правда через раз выпадает:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1

в этой строке:

 while(input.charAt(i) == ',')

ээ, нужно добавить && i < len

Да что же я невезучий такой. Надо так:
while(i < len && input.charAt(i) == ',')

пофиксилось, ноздря в ноздрю с Sensei-ем.

вот результаты вычислений 4-х приведенных алгоритмов по запятым:
Ну раз вам нечем занятсо openjdk.java.net/...code-tools/jmh

ну да, повозившись полчаса с параметрами командной строки можно уже приступать к диагностированию WTF-ов

после небольшой замены

temp.append(input.charAt(i));
Mobile mobile, size:[1] done in: 2ms
Mobile mobile, size:[10] done in: 0ms
Mobile mobile, size:[100] done in: 0ms
Mobile mobile, size:[1000] done in: 2ms
Mobile mobile, size:[10000] done in: 5ms
Mobile mobile, size:[100000] done in: 14ms

Друзья, я устал от троллинга и предложений померяться пипками и на оффтопы вообще отвечать не собираюсь.
Хочу ответить всем кто считает что «программист может обойтись без знания рекурсии, O(n) и пр». Да может, но никогда ваша карьера не выйдет дальше формошлепства и ковыряния в индусском коде. Вам это надо? Быть миддлом в бодишопе — это все о чем вы мечтали? Может лучше сразу сменить профессию?
Миллионы индийцев готовы от зари до зари за копейки колбасить рутинную работу, так что эта ниша в любом случае занята и в этом нам их не переплюнуть.
А в это же время амеры и европейцы пишут Spring, Akka и Memcached... Никогда нам не доверят писать что-то сложнее УГ-сайта, пока мы сами к этому не будем готовы.

Дык вопрос то не в Мемкешд, вопрос в том что вы собеседуете джуниора на позицию верстальщика сайтов...

Просто нужно как-то отсеивать случайных людей. Зачем ломать им жизнь?

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

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

и через год колбасенья формочек он подрастет и уволится от вас потому что он не хочет колбасить формочки. Нужно отдавать себе отчет в том какие у вас задачи и кто вам для этого нужен. Вы ведь не берете МВА для ведения 10-ка СПД-шников

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

Та ладно, все через это прошли и выжили. Набить руку на чем то надо все равно, изучить bash, maven, git и пр. На это все нужно время

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

Люди умеющие учится способны самостоятельно выучить обычный яваскрипт и накидать инфраструктуру для клиентского MVVM за неделю
Ололо. Накидав при этом собственный «лучший» аналог backbonejs. не протестированный и не документированный.
Хороший вброс, зачет.

Из вашего поста понятно где не нужны эти скиллы.
Но Вы так и не написали где в Украине они будут нужны. В конторах, которые любят писать свои логгеры, спринги и другие велосипеды?

Да что там жуниоры... синьйоры нынче ответы на эти вопросы не знают! :-)

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

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

и потом со всем этим идти фиксить баги в бангалорском JSP ага

Не знаю как где, а в CV достаточно много интересных проектов. Иначе я бы тут не работал :)

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

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

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

ровно на половину, первая часть правда, вторая шутка

А вот это, шо ты сказал, оно реально бывает или просто набор крутых слов из ФП?

Прочитать книгу по Хаскеллу? Реально, конечно

Бампну ко я старенькую тему.
Граждани такие умные, которые знают что не надо спрашивать (в том числе и те кто не согласны со списком ТСа),
напишите какие вопросы таки __надо__ спрашивать dou.ua/...ums/topic/3419

... Вот так и сидят два дурака. Один вопросы нагуглил, второй ответы.

Бессовестно утащил в цитатник

никто не способен знать всё, любой узкопрофильный специалист опережает универсала в несколько раз.

я считаю, что благоразумно быть честным перед собой и соискателем, если проект про фикс верстки — то так и сказать, не требуя знания Apache MQ, Scala и Python «про запас». С другой стороны если делают внутренности файлового/почтового сервера, то без потоков (thread+stream), сокетов и эффективных файловых операций никак.

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

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

Так что смысла в «10 лучших вопросов для Java собеседования» я не вижу.

у Украины будет шанс обогнать Индию по качеству и количеству IT-шникв.
Тут к месту вспомнилась фраза из одного фильма:
если хочешь увеличить количество, то придется пожертвовать качеством, причем конкретно пожертвовать
Правда тогда
5 лет обучения на it-факультетах
явный оверхед.

И что самое интересное, джуниора возьмут на проект, где надо будет фиксить вёрстку и писать на яваскрипте.

безусловно, за 3-4 года он ни разу не увидит ни хэш-мапы, ни строки SQL ни великой и ужасной многопоточности...... совок блин в головах.

Вы хорошо представляете как вытесняющая многозадачность работает? Вот так чтобы на собеседовании поговорить? А ведь видите её постоянно. Можно еще обсудить какие-нибуть calling conventions (вы же, чай, компилятор/линкер вызываете?) — какие регистры какая сторона обязана сохранить.
Если человек с мозгами — надо будет — разберется с булевой алгеброй. А если человек заучил булевую алгебру — еще не значит что он хороший программист (возьмет и начнет лепить её где не надо).

вот вы постоянно используете ОС, вы наверняка держите в голове все прерывания, а также структуру ядра? это же так профессионально.

3. Как работает HashMap

А мені цікаво що тут я повинен був відповісти. Ніхто не підкаже ?

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

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

код у тебя не читабельный, слова не понимабельны. что такеое иквелс — это ключ или то что после ключа ?

Ты Вася Пупкин еще не указал хеши равны а иквалс разный у ключей или у значений?

у ключей. Во втором же сообщении уточнил

Ви до речі так і не дали відповіді.

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

Думаю правильный ответ будет «Хорошо работает план выполяет».

я джава джун. Я даже ни одной книги по ней не прочел, только посмотрел курс стендфорда и 13 лекций с беркли. Вот я вчера вот забадяжил для удаления лишних запятых из строки вот такую процедурку. Я знаю что можна сделать изящное решение которое преобразует строку винда " , 4, 3, 5,,,,4,,34,,,,3,,,2,,5,,,534,,,,,,,3,," в вид «4,3,5,4,34,3,2,5,534,3» но мне некогда придумывать заново этот красивый алгоритм. Поэтому побыстрому написал вот такое. Можете поцепить на грудь свою медаль синьора, сесть за комп и написать красивый алгоритм и потом сказать сколько времени у вас заняло. Потом такой же алгоритм напишу я, и если мой работает быстрее или более изящно, или вы потратите на написание и отладку больше 6 минут (то что внизу написанно за 3 минуты включая поиск гогла), то вы свою медаль синьора отдаете мне.

private String CorrectComas (String inputString){
		String correctString="";
		correctString=inputString.replaceAll("\\s", ",");
		correctString=correctString.replaceAll(",,,,", ",");
		correctString=correctString.replaceAll(",,,", ",");
		correctString=correctString.replaceAll(",,", ",");
		correctString=correctString.replaceAll(",,", ",");	
		return(correctString);
	}

кавычки естественно везде вот такие "

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

о чем был этот пост ? как я понимаю 6 минут не хватает для написания посимвольного перебора строки и отладки до рабочего состояния даже синьору. может применим какоето из правил морганы ? или вы сеньйор только по хитрым вопросам. А ведь разбор строк учат на 2ом или третем занятии по С.

Вот еще один пример воинствующего невежества. Может кто-нибудь хочет такого дерзкого джуна себе в команду? Будет много споров, рассуждений, вызовов на «слабо». А то скукота — сидят, кодят...

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

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

я не могу вставить весь код, только разбор строки

попытка 2

	private String CorrectComas (String inputString){
		String correctString="";
		inputString=inputString.replaceAll("\\s", ",");
	//	correctString=correctString.replaceAll(",,,,", ",");
	//	correctString=correctString.replaceAll(",,,", ",");
	//	correctString=correctString.replaceAll(",,", ",");
	//	correctString=correctString.replaceAll(",,", ",");
		//char comma=',';
		boolean digitCatch=false;
		for(int i =0;i<inputString.length();i++){
			char currentChar = inputString.charAt(i);
			if (currentChar!=','){
				correctString=correctString+currentChar; 
				digitCatch=true;
				}
			else { if (digitCatch) {
					correctString=correctString+',';
					digitCatch=false;
					} 
			}
		}
			
		return(correctString);
	}

Не знаю как в Java работают строки, если так же как в .NET, то это O(N*N), хотя должно решаться за O(N)

correctString=correctString+currentChar;
Каждый раз новую строку создаешь. Гугли StringBuilder/StringBuffer (какой-то из них в джаве обсолит, не помню)

Я изложил свои критерии по которым я бы отбирал людей с которыми бы мне было легко работать. а меряться пипками — это оффтоп.

используйте тег «< code >» для обрамления кусков кода

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

Не, Габи, в этом единственном посте чувак таки прав :) Был у меня печальный опыт... вернее, не у меня, а в соседней команде, так это просто угар какой-то. Даже наблюдая со стороны за всеми этими разборками на повышенных тонах работать практически невозможно. Понимаешь, всё это «А вот я считаю, что *вытирая пену с уголков рта*!!!!!1111111......» в умеренных дозах можно простить девочкам-гуманитариям, которые собрались решить, что же таки хотел сказать автор какой-нибудь нетленки, но не кодерам в опенспейсе ;)

гогл про регулярку ничего не знает, за 6 минут сможете ?

Звідки ця дурниця про 6 хвилин ? Вас десь аж так женуть в шию ?
А якщо у Вас буде більше 20 ком Ви додасте цикл ?
Сгенеруйте собі файл в пару мегабайт і побачете що Ваш алгоритм проходить его декілька разів і ні разу не эфективний.
Навіть близько.

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

На строці в 80 символів ? :D
Ви кажете Ви джун, а де саме Ви працюєте ?

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

я ниде не працюю, джаву учу для смены работы, книжек пока не читал, поэтому я типа и есть типичный джун
вы тогда trainee/студент, на джуна нужно 6 мес. реальных (не домашних) проектов

блин, даунгрейднули меня что ли ??? обидна )))

я думал что джун — это самый слабый програмист. оказалось что есть еще и трейни )))

ничего страшного, век живи — век учись. Главное не словить звездочку как ТС.

Не сумуйте.
Є ще continuous delivery manager

Сгенеруйте собі файл в пару мегабайт і побачете що Ваш алгоритм проходить его декілька разів і ні разу не эфективний.
Навіть близько.

для того чтоб обращать внимание на такие “тонкости”, надо знать

big “O” notation, оценка сложности и скорости алгоритмов
но, как сказал джун, это глупости и нафик не надо никому :)

String correctString = Arrays.stream(a.split("[,+\\s+]"))
.filter(s -> s.length() > 0)
.collect(Collectors.joining(","));

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

я когда вижу ваш код, на меня нападает депресняк. потому что в тех видео по джаве которые я смотрю никаких стримов нет и я чувствую что учу какую то не ту джаву. можна код под 7ую ?

        String[] arr = a.split("[,+\\s+]");
        String correctString = ""; 
        if (arr.length > 0) {
            StringBuilder builder =  new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                if (arr[i].length() > 0) {
                    builder.append(arr[i]).append(",");
                }
            }
            builder.delete(builder.length()-1,builder.length());
             correctString = builder.toString();

        }

а как вставить код ? у меня чего то рубит после 2х строк

ура, наконец-то я понял как это делается )))

посмотри мое эллегантное решение вверху, 5 минут с отладкой. согласись что ты перемудрил ?

это то что «попытка 2 » ? Стринги имьютебл в джаве, а вы их посимвольно соединяете. Да, умный компилятор заменит это все на стрингбилдер, но все же. Да и так, какой смысл обрабатывать посимвольно, если вдруг в огромной строке будет всего пару запятых?

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

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

"23432423432324,,,4324234444444444444,,,,4444444444444444433,"

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

сравните.
напишите рандомный генератор строк и сгенерьте строку 1 млн символов, затем возьмите свой метод и метод пупкина и засеките по очереди используя System.currentTime(), вообще ничего сложного.

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

Щас бошка не варит на ночь, завтра вам запощу полную реализацию со статистикой, покером и куртизанками.

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

так в строку можна по максимуму 255 символов, разве нет ?
0_о Вы до джавы на паскале программировали чтоли?
на с
Тогда все же непонятно, зачем ограничивать себя строками в 255 символов )

а разве там не zero terminated string?

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

так в строку можна по максимуму 255 символов, разве нет ? .
шото вы гоните, если в Java нет ограничения на длину строк — зачем вы его вводите? Это же не Cobol с венгерской записью и длиной строк 255 символов.

В реальных задачах есть куски с ограничениями там где не надо и наоборот — например фигачит мыло 400 символов ссылаясь RFC 1982 года — бред? покажите мне хоть одно мыло такой длины!!!

А теперь представьте идут операции со строками.

то что я написал, но оно будет работать и с миллионом и с большим.
уже сегодня я протестирую ваш алгоритм на выборках: 1000, 10000, 100000 и если повезет на ляме, но шото мне подсказывает, что оно будет долго считать. Будет настроение — забодяжу свой алгоритм на Groovy, я теперь в основном на нём пишу.

По самым быстрым подсчетам оно свалится на строке с 96 запятыми подряд

там вверху есть листинг с разбором строки который я назвал «более изящным» и который будет с любой длинной. но написание такого кода требует концентрации или у вас должна быть гдето заготовка.

не стоит гнаться за скоростью, мы же не на олимпиаде для прыщавых задр*тов, лучше написать качественно (прогнав тесты) и поддерживаемо, чем за 6 минут, а потом целый день сраться на DOU.

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

Ага, а потом юзер этого стартапа ловит Unhandled exception, и на этом недолгие мучения стартапа завершаются

Ниче страшного, главное красивую презентацию сделать :)

И главное — в живую ничего не показывать :)
www.youtube.com/...h?v=IW7Rqwwth84

Почитайте труды Роберта Мартина и Стива Макконелла, Фаулер тоже не помешает. Они пишут, что в начале проекта команда работает быстро, вываливая тонны г*внокода, но через несколько месяцев они начинают ползти как улитка, т.к. изменение в одном месте ломает поведение в нескольких других (если они покрыты тестами), в особо запущенных случаях при достижении критической массы костылей и хаков, проект можно выбрасывать.

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

а где ты видел что бы проект жил больше 3-5 лет на одном движке ? из них гдето 5-10 месяцев на запуск прототипа для проверки гипотез, +10 месяцев для запуска первой коммерческой полноценной версии, остальные 2-3 года вылизвывание старых багов и доделка новых функций. При этом со 2-3 года начинается работа по миграции на новый хард или новый софт или новую базу или новую джаву.

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

Учись двоечник пока я жив:

StringTokenizer t = new StringTokenizer(a, ", ", false);
 String s = "";
 while(t.hasMoreTokens()) {
   if (s.length() > 0) s += ",";
   s += t.nextToken();
}

Кто ж так строки собирает?

(посмотрел линк внизу) Интересно... А можешь показать в какой байткод оно компилируется? У меня такое впечатление, что там toString() на каждой итерации

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

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

констант никак, логарифм + перерасход памяти.
Стринги тоже можно так-же конкатенировать на самом деле, за логарифмическое количество итераций

*Amortized* constant
Можно-то можно, но мы же о конкретном примере говорим? Как там оракл или опен дждк скомпилирует твой код? Давай на байткод глянем. Я бы посмотрел, но у меня дждк не установлен

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

Я писал:

Amortized constant time <b>на каждый ресайз</b>.

Так че, будем смотреть байткод?

А какая разница какое амортизированное время вставки для оценки сложности всего алгоритма?

Так че, будем смотреть байткод?
Гуглится на раз два: kosi2801.freepgs.com/...catenation.html

Ну так по твоей ссылке и говорится, что СтрингБилдер лучше, потому что при использовании конкатенации происходит:

 18  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [26]
 21  invokespecial java.lang.StringBuilder(java.lang.String) [32]
 24  ldc <String "abc"> [35]
 26  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [37]
 29  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [41]
То есть на каждой итерации создается новый стрингбилдер, который перегоняется обратно в строку. Даже хуже чем просто строки складывать :)
То есть на каждой итерации создается новый стрингбилдер, который перегоняется обратно в строку. Даже хуже чем просто строки складывать :)
Это все экономия на спичках, во время сплита строки тоже уже создалось N обьектов.

Ну так а ты еще N создашь :) В общем, я думаю, мы друг друга поняли

Amortized constant time <b>на каждый ресайз</b>.
Кстати очевидно именно на каждый ресайз никакой константы нету. Если говорить о вставке, то при вставке N элементов происходит log(N) рисайзов. При оценке рисайза в N операций, получается всего Nlog(N) операций на рисайзы, или в среднем(амортизированное значение) — лог(N) операций на вставку. Конечно на рисайз приходится не N операций, а меньше в среднем, но математика неочевидна откуда они взяли константу.

Ну там соль в том, что при каждом ресайзе нужно копировать существующие элементы. А так как массив увеличивается каждый раз в два раза, то при последовательной вставке ко времени ресайза n-элементного массива для вставки n+1-го элемента будет произведено n + n/2 + n/4 + ... (все предыдущие ресайзы) ... + 1 <= 2*n
То есть общее число операций копирования будет O(n), значит амортизированное (усредненное) время вставки будет O(1).
Впрочем, стрингбилдер не копирует посимвольно, поэтому O(log(m)) — таки правильная оценка общей стоимости алгоритма :)

while(t.hasMoreTokens()) {
if (s.length() > 0) s += “,”;
s += t.nextToken();
}
в цикле так строки не конкатят, только бюльдер
String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.
docs.oracle.com/...ang/String.html
String s = "";
где здесь токенайзер?

Ты о чем? В доке говорится что когда ты пишеш «+», ява на самом деле юзает StringBuilder

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

Зависит от умности компилера и сложности цикла. Он может посмотреть что строка не читается нигде и заюзать один StringBuilder

Ага, тесты Gabriel Angelos-а выше показали кто тут двоешник :) :)

string output = string.Join(",", input.Replace(" “, ”").Split(",").Where(s => s != ""))

тогда можно обойтись без линкью — сплит с параметром StringSplitOptions.RemoveEmptyEntries

Полезно знать! Спасибо

Во-первых, это отвратительно.
Во-вторых, вы учли только первые 3 минуты которые вы потратили. Если вы останетесь на этом проекте, то вангую ещё неделю или даже две, которые вы обязательно потратите из-за этого «изящного решения»

ТС, конечно перегнул палку — джуну сейчас лучше бы подучить английский, чем путаться в

big «O» notation
, но ваш пример это... ну нельзя так короче.

та шо вы говорите, это решение работает даже на 20 запятых и думаю что если добавить еще строку на 5 запятых то оно и на 80 будет работать. ну а кроме этого я тут уже другое решение выложил, но оно требовало концентрации, тогда как первое решение простое как топор.

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

Упирайтесь, на здоровье.

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

return inputString.replaceAll("[,\\s]+“, “,”).replaceAll("^,|,$", "");

после правки кавычек заработало, все четко. это как я понимаю и есть регулярные выражения. ^ - это типа начало, $ — это конец, а что вот это значит ,|, ?

^, - запятая в начале строки
,$ — запятая в конце строки.
| - означает «или»

а вроде ^ - это просто начало, а $ — это просто конец. я подозреваю ,|, - это любое количество повторяющихся запятых, с минимумом 2.

Все, что слева и справа от «|», нужно воспринимать как единое целое — «^, OR ,$»
То есть «запятая сразу после начала» ИЛИ «запятая сразу перед концом»

и как ,,,, отличается от ,,,4,, ? или там где то написанно что повторяется знак ?

replaceAll("[,\\s]+«, «,»)
меняет последовательности пробелов и запятых на одну запятую
.replaceAll("^,|,$«, «„)
убирает запятые сначала и с конца. В С# я бы просто сделал str.Trim(“,»), но в джаве вроде trim() только пробелы чикает

самое изящное решение ! хотя я вколбасил в код типу [\\s,]{1,}

Да, регуляркой изящнее всего выглядит. Только задача ж была «шоб за 3 минуты написать» :) . Я регулярку за 3 минуты не умею :)

джава — отстой.

string input = " , 4, 3, 5,,,,4,,34,,,,3,,,2,,5,,,534,,,,,,,3,,";
string output = string.Join(",", input.Split(new[] { ’ ’, ’,’ }, StringSplitOptions.RemoveEmptyEntries));

че, 8-я тоже уже умеет в одну строку писать )
String correctString = Arrays.stream(a.split("[,+\\s+]")).filter(s -> s.length() > 0).collect(Collectors.joining(","));

','.join([t for t in re.split(',\s*', x) if t])

Может сразу на Python-джуна переходить?

Тут вже домовились, що це рівень trainee :/

Такого когнитивного диссонанса я давно не испытывал. Как водится, вначале прочел опус ТСа, который, скажу честно, меня немного вывел из себя. Но дойдя до этого куска г0внкода простого решения © обычной задачи (тм) и сопроводительного текста к нему я начинаю подумывать о том, не стать ли адептом принять ли точку зрения ТСа.

Код хреновый вовсе не потому, что для наименования методов была выбрана самая не кошерная на мой взгляд конвенция, не потому, что само название означает буквально «пофиксить коматозника», и даже не потому, что реплейсы можно было вызывать «по цепочке» без ненужного присваивания в каждой строке... И, OMFG, даже не из-за быстродействия! Все вышеперечисленное оставим для разбора воинствующим эстетам и Grammar Nazi, тем более, что д’Артаньян аффтор заведомо подстраховался, дав понять, что код хоть и смердит, зато был написан за 3 минуты, а все, кто не сможет написть идеальный код для решения этой же задачи за 6 минут — рваные потрепанные... не правы. Цимес-то как раз в том, что код являет собой ярчайший пример треша, угара и содомии не решает поставленной задачи вопреки непонятно откуда взявшейся уверенности автора в обратном.
Если бы речь шла конкретно о строке «4, 3, 5,,,,4,,34,,,,3,,,2,,5,,,534,,,,,,,3,,», а не о «строке вида...», решение было бы ровно следующим:

private function String CorrectComas()
{
    return "4,3,5,4,34,3,2,5,534,3";
}
но коль уж мы обсуждаем действительно общее решение, какого, простите, черта и чем руководствуясь аффтор большинство присутствующих уверовало, что любое число N дает 1 при N/4/3/2/2?
Проблемы начинаются от последовтельностей запятых длиной в 35 символов и выше, кто не верит, дружно компилим в уме запускаем вот такую бодягу:
import java.util.Arrays;

public class Bullshit
{
   
    private static String CorrectComas(String inputString)
    {
        String correctString="";
        correctString=inputString.replaceAll("\\s", ",");
        correctString=correctString.replaceAll(",,,,", ",");
        correctString=correctString.replaceAll(",,,", ",");
        correctString=correctString.replaceAll(",,", ",");
        correctString=correctString.replaceAll(",,", ",");   
        return(correctString);
    }
     
    public static void main(String[] args)
    {
        int l;
        for (int i=1; i<=1000; i++)
        {
            char[] chars = new char[i];
            Arrays.fill(chars, ',');
            if ( (l = CorrectComas(new String(chars)).length()) >  1 )
                System.out.println(i + " > " + l);
        }
    }
   
}

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

Ради всего святого, в моск меня трахать не надо! Я не ваша целевая аудитория. Мой пример вполне говорит сам за себя, наслаждайтесь.

ок, последний вопрос как у вас 2*2*3*4 вышло < 35 ?

Давайте только не будем из моего упрощения делать аксиому, ОК? Ход мысли там более чем понятен и при неточной записи.

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

Дорогая редакция.
У меня с монитора начал сочиться жир! Это нормально?

Если мсье угодно повалять дурака вместо того, чтобы тупо запустить семпл, угощайтесь:
((int)(N/4)+N%4)/(((int)N/3)+N%3)/(((int)N/2)+N%2)/(((int)N/2)+N%2)
Подсказка: не будет это равно единице при всех значениях N, и сбоить оно начнет таки с 35-ти (=2).

UPDATED:
Даже не так, а вот сяк:
(int)(((int)(((int)(((int)(N/4)+N%4)/3)+((int)(N/4)+N%4)%3)/2)+((int)(((int)(N/4)+N%4)/3)+((int)(N/4)+N%4)%3)%2)/2)+((int)(((int)(((int)(N/4)+N%4)/3)+((int)(N/4)+N%4)%3)/2)+((int)(((int)(N/4)+N%4)/3)+((int)(N/4)+N%4)%3)%2)%2
Выраженьице вполне в духе исходного примера, ну а чо, одни ж ведь простые операторы. Enjoy ))

отдашь мне свой статус сеньора если оно таки с 48 ?

А почему не три почки и две печени?

И кто сказал, что тот выкидыш на пять строк реплейсов — простой код? Окститесь! Тот факт, что вы ничего сложнее не в состоянии прочесть за меньшее время вовсе не говорит о простоте вашего примера (даже если бы он с какой-то великой радости ВНЕЗАПНО работал как следует).

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

01 02 03 04 05
16 17 18 19 06
15 24 25 20 07
14 23 22 21 08
13 12 11 10 09
так как я был ещё более неопытным чем сейчас (от слова «совсем»), то провёл сорок минут в попытках красиво напечатать сие используя циклы, массивы, возможность изменения размера мартицы и выравнивания символов в строке.
Гордо показав в конце свой говнокод и результаты его работы (только наша кучка осилила задание, мы молодцы!!11) я услышал:
— не правильно
— 8-О
— правильное решение задачи «просто вывести на экран»:
println('01 02 03 04 05');
println('16 17 18 19 06');
println('15 24 25 20 07');
println('14 23 22 21 08');
println('13 12 11 10 09');

Вот.
В чём был урок? В том, что нефиг изобретать сущности сверх необходимого)

зы. но решение с реплейсами мне не нравится

Отличный пример различного понимания ТЗ исполнителем и составителем.

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

В данной задаче налицо различное понимание задачи: программисты vs тестеры/заказчики/менеджеры.
Последние считают, что если есть мокап сайта (тестовые html-шаблоны страниц с CSS-кой), то 90% работы уже сделано и программисты только в танки катают.
Также и здесь, завтра они потребуют вывести матрицу 1000×1000, а послезавтра миллион х миллион, а в конце недели сделать в форме кота.

Вам же рот не зашили — узнавайте, что и как будет. Тем более в старт-апе это архи полезный навык.

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

Для примера возьмите какую-нибудь простенькую задачку на 2-3 часа, например «конвертация валюты друг в друга при плавающем курсе» и реализуйте это в одном методе, ничего не рефакторя. Уверяю вас, через 1,5-2 часа работа зайдет в тупик, если без Unit-тестов, то еще раньше.

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

Подход что вы привели годится для университетских задач воинствующих теоретиков и подходе: «сделал и забыл».

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

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

У даному випадку викладач, мабуть, був також не зовсім правий . Компромісним варіантом, як на мене, був би хардкод двовимірного масиву і цикл з виводом на 3 стрічки.

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

import sys


def distance(x, y, size):
    return x + y if x >= y else 4 * size - x - y


def snake_matrix(size, first=1):
    vertexes = size + 1
    m = [[0] * vertexes for _ in range(vertexes)]
    for x in range(vertexes):
        for y in range(vertexes):
            depth = min((x, y, size - x, size - y))
            level_start = first + sum(4*(size - 2*d) for d in range(depth))
            m[y][x] = level_start + distance(x - depth, y - depth, size - 2*depth)
    return m


if __name__ == "__main__":
    for row in snake_matrix(int(sys.argv[1])):
        print "println('" + " ".join("%02d" % v for v in row) + "');"

Едва ли намного дольше чем копипастить, м? Зато, чувствуешь себя человеком :)

$.\snake_matrix.py 4
println('01 02 03 04 05');
println('16 17 18 19 06');
println('15 24 25 20 07');
println('14 23 22 21 08');
println('13 12 11 10 09');

$.\snake_matrix.py 5
print('01 02 03 04 05 06');
print('20 21 22 23 24 07');
print('19 32 33 34 25 08');
print('18 31 36 35 26 09');
print('17 30 29 28 27 10');
print('16 15 14 13 12 11');

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

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

Моя имха — задачу нужно решать настолько просто, настолько позволяют условия.

Бачу такі варіанти рішення:
Це не може бути настільки просто:
1. Згадане рішення із прінтами

Викладач буде приймати код, згадай «тиЖпрограміст» усе-таки :
2. Хардкод одновимірного масиву і цикл з виводом на 3 стрічки.
2. Хардкод двовимірного масиву і цикл з виводом на 3 стрічки.

Для «тиЖпрограміст» і любителів ускладнювати собі життя:
3. Варіант приведений вище на пітоні.
4. Значення в матриці формують спіраль Архімеда. Визначення значень у полярній системі координат ))(варіація #3)

Згоден про переваги #1, але через («тиЖпрограміст», красиво, масштабовано, співмірні витрати часу із #1) я б вибирав варіанти #2 або #3 ))

Скажите, а где в условии задачи вы нашли слова «матрица» и «размер»? Когда вас просят вывести на экран «Hello world» — тоже закономерности ищите?

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

А про «Hello world» это вам лучше сюда: habrahabr.ru/post/133087

То что просили вывести на экран — это набор символов. Остальное — уже ваше воображение, которое зачем-то расширило задачу.

www.youtube.com/...h?v=RirqnBUQTEU :)

которое зачем-то расширило задачу.
Затем, что сложные задачи интереснее тривиальных. Или от чего по-вашему у людей тоска от формошлепства и хочется биг дату и хайлоад? А вам бы всё по рукам бить...
И я повторюсь, важно соблюдать баланс, вы же, похоже, стремитесь к одной из крайностей.
В данной задаче оба решения могут быть уместны в зависимости от контекста. В учебных задачах контекст, обычно, до конца не ясен и студент додумал его так, что уместно более сложное, но универсальное решение, не вижу в этом проблемы. Что хотел сказать преподаватель, конечно, тоже понятно.
И я повторюсь, важно соблюдать баланс, вы же, похоже, стремитесь к одной из крайностей.
Важно знать, что конкретно тебе нужно сделать. Оправдание «я думал что...» — весьма печальная вещь.
В учебных задачах контекст, обычно, до конца не ясен и студент додумал его так, что уместно более сложное, но универсальное решение, не вижу в этом проблемы.
Если бы так было только в учебе, то и я проблемы не видел бы...

Вважайте, що це зроблено для того, щоб завтра не почати розмовляти на хінді

О, боюсь тогда сделано крайне топорно. Во-первых матрица только квадратная, во-вторых нет способа ввести иной «путь» вывода.

1. Легко додати
2. Це вже заявка більше ніж на junior

2. Це вже заявка більше ніж на junior
Ой да ладно, свой первый транслятор формул я написал в 10 классе (заметьте, интернета у меня тогда не было). А уж с переводом в польскую нотацию там и вовсе нечего делать.

К тому же, согласитесь, проблема (задача) не зависит от того, кто её решает.

Но суть не в этом. Суть в том, что мы решаем проблему, которой нет.

свой первый транслятор формул я написал в 10 классе (заметьте, интернета у меня тогда не было)
да-да, держите, пожалуйста, нас в курсе

Ну вот, это уже совсем другой разговор, а то набор символов, набор символов... :)

Во-первых матрица только квадратная, во-вторых нет способа ввести иной «путь» вывода.
Ну, зато там можно определить значение в любой точке без всяких обходов, но, если хотите все такое переменное, пожалуйста:
import sys
from operator import getitem


SHIFTS = ((0, 1), (1, 0), (0, -1), (-1, 0))


def shift(point, shift):
    return tuple(p + s for p, s in zip(point, shift))


def get_nested(lst, index):
    return reduce(getitem, index, lst)


def set_nested(lst, index, value):
    get_nested(lst, index[:-1])[index[-1]] = value


def snake_matrix(a, b, shifts=SHIFTS, point=(0, 0), value=1):
    m = [[None] * a for _ in range(b)]
    last = None

    while last != point:
        last = point
        for sh in shifts:
            while True:
                set_nested(m, point, value)
                next_point = shift(point, sh)
                try:
                    if get_nested(m, next_point) is not None:
                        break
                except IndexError:
                    break
                value += 1
                point = next_point
    return m

if __name__ == "__main__":
    for row in snake_matrix(int(sys.argv[1]), int(sys.argv[2])):
        print "println('" + " ".join("%02d" % v for v in row) + "');"
 $ ./snake_matrix2.py 5 5
println('01 02 03 04 05');
println('16 17 18 19 06');
println('15 24 25 20 07');
println('14 23 22 21 08');
println('13 12 11 10 09');
$ ./snake_matrix2.py 10 5
println('01 02 03 04 05 06 07 08 09 10');
println('26 27 28 29 30 31 32 33 34 11');
println('25 44 45 46 47 48 49 50 35 12');
println('24 43 42 41 40 39 38 37 36 13');
println('23 22 21 20 19 18 17 16 15 14');
Можно, очевидно, чтоб и так и эдак, но лень :)

ай-ай-ай, какой ленивый непредусмотрительный программист.
А пока будете делать транслятор формул (хотя я не уверен, что это лучший способ ввода «узора»), я тут ещё возможных вариантов накидал:
1. Выбор куда выводить — монитор, файл, принтер, э. почта
2. Возможность многопоточной сборки матрицы на вычислительном кластере.

Як порядний, ви маєте зробити людині гарну пропозицію

АААААааааааааааааааа! Опять дeбильные вопросы которые требуются только на собеседовании. Причем чем больше у собеседующего травма тем больше его интересуют побитовые подробности. И таким вот подходом травмируют джунов.
Вот это всё

1. Булева алгебра, правило де Моргана
2. big «O» notation, оценка сложности и скорости алгоритмов и структур данных в Java
3. Как работает HashMap
4. Что такое рекурсия и как написать обход дерева
за овер 10 лет ни разу не нужно было. И я уже перестал даже эту фигню повторять перед собеседованиями. Т.к. если такое спрашивают то мне с такими не по пути.

Вообще весь процесс найма от хр до собеседования травмирован. Более чем в 90 процентов случаев.

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

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

Ну предложите свою модель собеседования, если моя для вас «фарс».

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

А что делать если у собеседуемого травма?

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

Тогда для собеседуемого самое главное что нужно, это осознать что она есть, действительно у него, и что нужно что-то с ней делать.

Какой логический кульбит перевел ваш праведный гнев с темы собеседований на содержание сайта фирмы где я работаю?

То что ваша фирма это очердная серая фирма в которой не создают жавы и дотнеты.

Зайдите еще на сайты епама, люксофта, проведите сравнительный контент-анализ, нам очень интересно

Именно что разницы нет. поэтому вот это:

1. Булева алгебра, правило де Моргана
2. big «O» notation, оценка сложности и скорости алгоритмов и структур данных в Java
3. Как работает HashMap
4. Что такое рекурсия и как написать обход дерева
не нужно.

для создания магазинов с корзиной на вордпрессе — нет.

Ну а кто собеседует? Прогер, которого оторвали от написания кода? Ну так он себе товарища по перекурам собеседовать будет. Чтоб поговорить можно было. О разнице между версиями, новинках в технике, булевой алгебре, порешать задачки на логику. Знаю контору, где обязательным вопросом был вопрос о игре в танки(и если кандидат играл — это был БОЛЬШОЙ плюс).

Какой профит ему искать нужного компании человека?

когда собеседовался на работу в москве в 2001 году, в конце интервью с двумя солидными дядька один из которых потом подвез меня на 600 слк до метро, в конце интервью был вопрос — какие у вас хобби, на что я ответил — в принципе хобби нет, ну разве что в кваку 3 зарубиться в клубе на всю ночь . Дядьки расплылись до ушей- о, так ты колбасер !!! а у нас тут по пятницам чемпионат. Кажись я тогда у них за год заработал как в украине за 8 лет, при этом в украине я работал в миддлом в лидерах рынка.

Как минимум такой прогер не будет брать себе обузу, за которого этому же прогеру и придется по вечерам все рефакторить и дебажить

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

по вечерам все рефакторить и дебажить

Одно дело ревьюить чела который читал «Clean Code» и согласен с его принципами, и другое дело, если попадется гиперактивный красавчег, который будет до хрипоты спорить «да и так все работает»

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

а якщо це танки конкуруючої фірми?

Я бы лучше выдавал до собеседования маленькое задание на 4-8 часа и чтобы кандидат его сделал как хотел и на чем хотел, потом принес и обсудили, чем как дыбилы сидеть и писать код на бумажке, хотя на реальной работе работать в IDE и, скорее всего, запускать на серваке. «Компиляция» кода на бумажке это отдельная песня, такие дауны все еще существуют.

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

зачем тратить время, если человек не слышал про рекурсию, то 4-8 часов его не спасут, да и копипаст нагугленного решения никому не нужен.

у вас в конторе обрублен интернет, чтобы работники ничего не нагуглили и все написали сами, угадал?

Никому не нужен коллега копипастер-говнокодер, нужен человек понимающий что он делает.

Не юзаете stackowerflow, все из головы? Не было мысли, что из головы бывает говнокод похуже, чем с гугла?

дочитайте вторую часть предложения к которому вы оппонируете

Вопрос был в другом, вы не копипастите?

веселый ты парень Виталий, хоть раз ты использовал рекурсию в реальном проекте ? ну хоть раз в жизни ?

вы не поверите, но да, неоднократно

а когда стек переполнялся у JVM — кого вы обвиняли в своих неудачах?

для этого как раз и есть пункт 2: оценка сложности алгоритма. а в скале еще и @tailrec

позвольте поинтересоваться как оценить сложность рекурсивного алгоритма используя О-большое чтобы не выскочить за ограничение JVM ?
капец как интересно.

ну раз вы создали топик и делаете какую-то видимость знатока, то потрудитесь описать своими словами, т.к. бросание ссылок на главную страницу корсеры попахивает сливом.

1>

Никому не нужен коллега копипастер-говнокодер, нужен человек понимающий что он делает.

2>

www.coursera.org

А не копипастер-говнокодер вы, часом? :) А своими словами пересказать, с пониманием того, что вы делаете? Чтобы самую суть, просто и понятно (ведь профессионала от балбеса отличает то, что он сможет объяснить сложные вещи даже пятилетнему ребёнку, ибо понимает в чём суть и может найти аналогии).

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

Ви так і не відповіли.
Між тим питання, як оцінити об’єм данних, який від вас може не залежати, для того щоб використати рекурсію, досить цікавий

какой именно алгоритм нужно оценивать? для большинства агоритмов такие оценки есть. например: ru.wikipedia.org/...трая_сортировка

Если вам это действительно инересно, а не потроллить, то лучший курс который я знаю — это www.coursera.org/course/algo. Там как раз даются общие методики разработки и оптимизации алгоритмов, типа «Divide and conquer» и критерии оценки их сложности и производительности.

а когда стек переполнялся у JVM — кого вы обвиняли в своих неудачах?
Того кто использовал рекурсию не там где надо. :)
Есть довольно много задач (я с такими сталкивался) где вложенность будет в пределах 10.

В таких випадках можна і китайською практикою скористатись, а якщо массив вироджений, то його сама машина може розгорнути в китайський варіант.
А рекурсію машина розгорне?

Я про unrolling loops

3) Control flow optimizations
The following optimizations analyze the flow of control within a method (or specific sections of it) and rearrange code paths to improve their efficiency:

Code reordering, splitting and removal
Loop reduction and inversion
Loop striding and loop-invariant code motion
Loop unrolling and peeling
Loop versioning and specialization
Exception-directed optimization
Switch analysis

Тобто питання про те, чи спрацює


Tail recursion elimination
на тих
довольно много задач
чи ні?
Я про unrolling loops
В таких випадках можна і китайською практикою скористатись
Обход дерева — задача для которой рекрсивный подход довольно естественный. При чем тут размотка цикла я не особо понимаю.

А я про те, що деякі задачі можна вирішити циклами, а не рекурсією.
А далі, при деяких сталих параметрах, ці цикли будут оптимізовані.
І постає питання — чи буде оптимізована рекурсія, так як будуть оптимізовані цикли?
А конкретніше, йдеться про саме ті задачі, про які ви сказали

довольно много задач (я с такими сталкивался)
А конкретніше, йдеться про саме ті задачі, про які ви сказали
Эти самые задачи, которые сводятся к обходу дерева или некоторые итерирование по структурам на подобии “связных списков”. Такие задачи более естественно решать через рекурсию. Тот же ForkJoin — это “рекурсивный стиль”.
Рекурсия вообще интересная штука: вроде как все просто но почему-то много людей не способны ей пользоваться (похожая ситуация с указателями или джавскриптом)
І постає питання — чи буде оптимізована рекурсія, так як будуть оптимізовані цикли?
В Java нет даже TCO, вроде как. Если б он был, то для них можно сделать все оптимизации которые есть для циклов.
Но раз уж мы заговорили про “реальный мир”, то в реальном мире вы уверены что оптимизации циклов, такие как размотка, существенно повлияют на производительность (в ДжВМ, для не большого количества “итераций”)

как unrolling loops сработает для цикла while? не собираетесь же вы дерево неизвестного размера обходить циклом for?

я так понимаю, речь о генерации из
for(i = 0; i< 2; i++) do();
такого:
do();
do();
do();

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

там где впадлу писать итеративную реализацию и хочется козырнуть.
например при вычисление числа Фибоначчи JVM падает уже на 11000м числе по StackOverflowError. Можно еще быструю сортировку забодяжить рекурсией, но работать это будет лишь на маленьких массивах, на больших — переполнится стек.

Коли навчався в школі, то зазвичай компілювали на папірці. Тому для мене — це ностальгія.
Особисто я переконаний, що потрібно давати практичне завдання. Якщо у кандидата нічого не вийшло з працевлаштуванням то, йому в знак компенсації витраченого часу можуть дати код-ревю, що для початківця є важливим. А решта, мабуть даремна трата часу.

Приятно видеть единомышленника. Обычно местная братва тут же пытается получить деньги за тестовое задание. Как по мне — глупость и маразм. Рад, что хоть вы понимаете смысл.

деньги за тестовое задание

 — вполне разумная тактика. «С поганой овцы хоть шерсти клок».

наскільки я зрозумів, там ситуація зворотня: людина виконала тестове завдання і хоче отримати за це гроші.

Крім того, кандидат-початківець може прокачати додаткові скіли і заповнити прогалини в своїх знаннях.
Із задоволенням згадую практичне завдання, коли продавав резюме на першу роботу. Завдання зводилося до усіх операцій із деревовидними (ієрархічними) структурами.

Т.к. если такое спрашивают то мне с такими не по пути.
Ну и слава богу. Works both ways.

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

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

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

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

Нажаль не всі пройшли курс «справжнього програміста» у вузі. Деякі почали з «Самоучитель C++ за 21 день» і далі робота-робота-робота. Тому і пропустили/призабули таке.

Але якщо вже показали і потім не використовують — бить нада!

P.S.: Спасибі за Правила де Моргана.

Похвастались бы грантом каким-то или победой на Imagine CUP, слабо?
Это вам не джунов терроризировать.Я и сам в состоянии задать вам 5 заданий на собеседовании, которые вы не решите и я заявлю о вашей полнейшей непригодности к программированию на Java, только вот я не вижу смысла самоутверждаться за счет людей, которые чего-то не знают и в поиске работы.

Правило «Я начальник — ты дурак» слегка устарело, вам не кажется?

Если человек не сталкивался с каким-то алгоритмом или куском API по работе, то его надо за это покарать? Если вы от нефиг делать решаете задачки, в то время как другие чуваки годами фиксят баги на JSP не делает вас выше других.

Если кричат «дурак» — не обязательно оборачиваться

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

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

ОК, тогда вам как эксперту простая задачка (решать без помощи компьютера) а в голове. Что выведет следующая программа:

public class MyClass {

    private static boolean initialized = false;

    static {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                initialized = true;
            }
        });
        t.start();
        try {
            t.join();
        } catch (InterruptedException e) {
            throw new AssertionError(e);
        }
    }

    public static void main(String[] args) {
        System.out.println(initialized);
    }

} 

Да, и если вы джун, то не стоит писать в cv что вы знаете Multithreading&Concurrency, только насмешите.

Да, и если вы джун, то не стоит писать в cv что вы знаете Multithreading&Concurrency, только насмешите.
Ой-йой. Какая классная тема, надо поискать свое первое резюме, вы так же свое поищите, много интересного прочитаете. :)
.
UPD.
Multithreading&Concurrency — далеко не каждый синьор будет «иметь право написать» (если по гамбурскому счету).
Вопрос в том что надо понимать что должен знать джун и синьор для того чтобы написть такое в резюме, и что наборы необходимых знаний у них будут отличаться (это относится к любому пункту резюме)

ТС сдулся, непосильная задачка на потоки оказалась.

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

ну раз наш знаток съехал, то поясняю JLS 12.4.2
возможно 4 исхода:
1) класс не инициализирован
2) класс инициализируется текущим потоком — рекурсивный запрос инициализации
3) класс инициализируется другим потоком
4) класс уже проинициализирован.
приводить перевод всего описания — бесмысленно, проще глянуть в JLS, но с большой степенью вероятности будет deadlock, программа ничего не выведет на консоль и зависнет.

Мораль: до*баться можно к любому, даже к Джеймсу Гослингу (отец Java), поскольку даже он не писал самолично все API и не знает всех задр*чек. Профессиональный программист отличается от умного тем, что пишет простой и поддерживаемый код, использует простые и очевидные решения, а не старается проявить свой богатый внутренний мир.
Умный же на задачу вывести сумму 2-х чисел пишет абстрактную фабрику, пытаясь внутри доказать теорему Ферма на ассемблере. Для олимпиадных задач — отличный вариант, но не для крупных проектов.

Вы как раз привели пример «здротного» вопроса для собеседования и меня же им попрекаете. Что такого эзотерического в знании об устройстве hashmap? как это помешает писать простой и чистый код?

про хэш-мапу нужно просто рассказать, что нужно соблюдать контракт equals + hashcode, подробнее, у Блоха отлично расписано аж 3 главы в Effective Java и джун разберется и вы умным покажитесь. Как план?

А вы сами в состоянии реализовать одну или несколько хэш-функций, которая будет давать выборку объекта по ключу близкой к О(1) ? :-)

ах, ну да, точно. Я пару раз попробовал — оба раза дедлок был, но чет не допер сразу почему. %)

6. а и b сидели на трубе, а упало, б пропало. Что осталось на трубе?

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

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

Болить серце за людей? Что-то Тимошенко вспомнилась.
Конечно пост для толковых ребят, все видно по названию «жава жун нынчне не торт».

Заголовок — для привлечения внимания, это да. Но не думал, что привлеку столько троллей.

Внизу отвечали линком на ВольфрамАльфа уже. Вместо ИЛИ должно быть И

я не джавист — и написал ответ в булевой форме

В данном конкретном случае ведь

a & !b

и
a && !b

эквивалентны

На мою упереджену думку, проводити еквівалентність бінарних і не бінарних порівнянь без обмеження типів данних неможливо.
Тобто, можна порівняти массив з логічним типом і отримати бознащо

а тут видно что оба операнда бинарные. Так как отрицание (!) только с булеанами и работает в джаве

Вибачаюсь. Я гадав, що & це побітова операція в java

я тут заинтересовался намеками idOne на подвох и слегка покопал. вот тут все в одном месте: stackoverflow.com/...boolean-in-java
1. бинарные операторы нормально работают с булевскими типами(ожидаемо), но
2. перестает работать short-circuit evaluation и все операнды вычисляются. что может привести к побочным эффектам(ну, если автор кода рассывал почему-то на short-circuit)
3. приоритет другой в сравнении с логическими операторми && и ||, без скобок могут быть проблемы при смеси бинарных и логических
----
чисто для информации.

ну то что short-circuit evaluation не работает — то это я знаю и, по этому, написал «эквивалентны» (по результату) а не равны. А вот про разный приоритет не знал, если честно. Спасибо за ссылку.

Не знаю что в НАУ, но при их колледже где учусь (компьютерных технологий и экономики, бывш. радиомех) мне объясняли правило де Моргана и знаю его. Может, это таки от человека зависит?

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

Хм, а вам когда-нибудь приходилось использовать это самое правило де Моргана?
Я к тому, что запись условия должна читаться как строчка в ТЗ, а не быть некоторым преобразованием, т.к. это облегчит понимание кода.

а вам когда-нибудь приходилось использовать это самое правило де Моргана?
Постоянно. От только суть в том что я не думаю «надо применить правилА де Моргана», оно просто должно быть. А если человек не может преобразовать простое булевское выражение — это уже вопрос (аналогично если не может сказать равны ли 3+5 и 5+3)
Я к тому, что запись условия должна читаться как строчка в ТЗ, а не быть некоторым преобразованием, т.к. это облегчит понимание кода.
Вот простое условие:
!(a==null || a.isEmpty())
Оно могло появится как результат «переноса ТЗ», так и в следствии рефаторинга. Мне бы хотелось переписать его так:
a!=null  && !a.isEmpty()
Я могу это сделать или нет? И за сколько моего рабочего времени вы готовы заплатить для принятия это решения?
А если человек не может преобразовать простое булевское выражение — это уже вопрос (аналогично если не может сказать равны ли 3+5 и 5+3)
Вопрос в том, за сколько это лечится. Бывают ситуации, когда человек просто раньше с таким не сталкивался(мы ведь о джунах?). Можно попробовать перевести ситуацию из абстрактных «a» и «b» в какие-нибудь привычные чекбоксы.

Если ситуация после подобных подсказок исправляется, и следующий пример человек весело щелкает — ну и отлично.

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

Можно попробовать перевести ситуацию из абстрактных «a» и «b» в какие-нибудь привычные чекбоксы.
Хотелось бы это послушать :) Напоминаю:
мы ведь о джунах?
Перефразирую то что вы сказали:
Джун может быть не способен исправить/изменить кусок кода, но при этом должен __на слух__ нормально воспринимать описание поведения УИ.
человек просто раньше с таким не сталкивался
Если человек раньше не сталкивался с такими простыми вещами, то возникают вопросы о том что он делал в ВУЗе (философия/логика есть даже у гуманитариев).
.
Короче говоря, лично мне гораздо интереснее понять что же человек знает (его сильные стороны)
Мы все еще про джунов говорим? И чего же джун может принести полезного вам в команду. Мне и правда интересны примеры, всегда думал что джун — это инвестиция + энергия для развития.
.
вот только зачем?
Вот простое условие:
!(a==null || a.isEmpty())
Оно могло появится как результат «переноса ТЗ», так и в следствии рефаторинга. Мне бы хотелось переписать его так:
a!=null && !a.isEmpty()
Я могу это сделать или нет? И за сколько моего рабочего времени вы готовы заплатить для принятия это решения?
Джун может быть не способен исправить/изменить кусок кода, но при этом должен __на слух__ нормально воспринимать описание поведения УИ
Угу, вконтактиком пользуется ж.
всегда думал что джун — это инвестиция
Точно. Надо же понимать, во что вкладываешь? А то бывает приходит интервьювер с собеседования, спрашиваешь его — «ну что?» — «А, дурень, того не знает, этого...» — «А что он знает?» — «...»
Точно. Надо же понимать, во что вкладываешь? А то бывает приходит интервьювер с собеседования, спрашиваешь его — «ну что?» — «А, дурень, того не знает, этого...» — «А что он знает?» — «...»
Стихи Пушкина он знает. Перефразирую: Приведите реальный пример, когда ответ на вопрос «А что джун знает?» помогал при приеме на работу.

Эм... всегда?
Зачем мы нанимаем человека на работу?
1. Закрыть проблему. Хотя нет, джунов для этого не нанимают
2. Разгрузить ключевого сотрудника. Нанимать на такое джунов? Сомнительно...
3. Выращивание спеца. О, это вроде для джуна. И тут очень важно понимать, в кого ентого джуна можно вырастить, чем он интересуется и тд.
4. Продолжите...

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

Эм... всегда?
Стихи Пушкина он знает.
Берете?

Знание стихов Пушкина является подмножеством множества возможных знаний, однако это подмножество не пересекается(в моем случае) с множеством «полезных для работы» знаний и умений.

с множеством «полезных для работы» знаний и умений.
Замечательно. Вот обладает наш джун 1 из 10 «полезных для работы» знаний и умений. Круто! 2-мя,3-мя. Его можно брать или лучше подождать того у кого будет хотя бы 6?

Я же не знаю, сколько вы готовы инвестировать и ситуацию на рынке «ваших» джунов. Решайте уж сами.

Хотя лично для меня, если человек легко схватывает подсказки и учится «на глазах» — то пойдет и 0 из 10.

Смотрите, допустим у нас есть множество N — нужные знания и умения, множество K — знания и умения кандидата, множество Q — вопросы собеседования.

Тогда, задача собеседования оценить множество N⋂K. Однако в большинстве случаев, результатом собеседований (почему-то) является Q\K (Идеальным считается, если Q\K = ∅). При том что условие N⊇Q выполняется довольно редко. А в особо запущенных случаях так и вовсе N⋂Q = ∅.

Хотя лично для меня, если человек легко схватывает подсказки и учится «на глазах» — то пойдет и 0 из 10.
Поздравляю, вас надо увольнять, ибо вы не способны сформировать адекватные требования к кандидату. :)
При том что условие N⊇Q выполняется довольно редко.
Если у вас с этим проблемы, то возьмите у ТСа пункты 1, 4 и 5 (если сами не знаете № 1, то возьмите 4 и 5). Они проверяют общий уровень человека.
Поскольку я уверен в вашей компетентности, то даю подсказку пункт 4 — это неплохой способ проверить как человек «учится и схватывает», при правильной постановке задачи.

Богдан, просто перечитайте мой комментарий. Можно даже всю ветку.

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

Ответ на вопрос «что джун знает» всегда помогает при приеме на работу. Потому что он скорее всего не знает все остальное, удобно.

Ответ на вопрос «что джун знает» всегда помогает при приеме на работу. Потому что он скорее всего не знает все остальное, удобно.
Приведите реальный пример, когда ответ на вопрос «А что джун знает?» помогал при приеме на работу.

Ок, на ваши сообщения больше не отвечаю, всех благ )

Ок, на ваши сообщения больше не отвечаю, всех благ )
Ок, слив засчитан, и вам не хворать :)

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

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

А нафига исправлять программистами кривого продукт-овнера? К тому же, замечено, что в результате проработки ТЗ многие проблемы решаются до того, как будут запрограммированы :)

А нафига исправлять программистами кривого продукт-овнера?
Интересный вы CTO, аднака.

Да, не люблю изолентой проблему заматывать.

в формошлепстве довольно частая ситуация: было простое условие. не реализовывать же стратегию из-за одного if, верно? а потом — еще одна исключительная сиутация, добавим. и еще одна. и когда озаряет «да что ж это за дерьмо-то, в котором не разобраться», там уже «a && !b || (c || (d && !a))». и да, де Моргана вполне можно заюзать. хотя, с таблицей истинности проще. упростил — опять только два условия :)
и да, я в курсе про рефакторинг «extract method».

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

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

Да могут конечно. Вопрос-то прежде всего в том, какую цель вы преследуете.

По списку в конце, да тут многие синьйоры этого не знают :)

Молодежь не та, при Сталине такого не было, все относительно. В 2006 описанная вами ситуация уже была.
И подобная история не только с джунами.

Какой выход? Пока что вижу только один и всем его рекомендую: Coursera, Udacity и пр.
А еще можно попытаться понять ситуацию :)
Java developer в CyberVision, Inc.
У сайбера своеобразная репутация. Не исключено что все стоящее забирают Епам и компания, которые довольно плотно сотрудничают с универами и репутация у них получше.
.
Дорогие джуны, прежде чем идти на собеседование, убедитесь что вы хорошо знаете как минимум следующее
И снова все относительно. Я считаю что все вами перечисленное надо, но при этом могу придумать по одной причине почему оно не нужно.
Еще надо учитывать стрессовость ситуации, для многих собеседование — это стресс.
ИМХО, проверять знания, в смысле набор информации, у джуна не есть эффективно. Надо смотреть как он умеет обучаться и думать (проверять способность работать с правилами вывода). Задачка на обход дерева — это как раз классно для такой цели, просто не надо ставить на человеке крест если он без направляющих не написал ее.

Я обобщил опыт с нескольких мест работы, не только с текущего.

В целях повышения образованности хочу спросить: !(!a || b) => (a ^ b), да?

Познавательно.

Это же базовое правило булевой алгебры!
— а практическая ценность в повседневной работе, от таких задачек, имеется? Как-то неправильно рассуждать о логическом мышлении человека по таким выражениям, уж на Java точно. Математику вычеркнуть, имхо :D

Вам видимо не доводилось встречать нечто вида: assertEquals(a, Boolean.TRUE);

Это валидное java — выражение. Кто не знает, тому в джависты пока рано. Упрощать такие выражения проиходится чуть ли не каждый день по десятки раз. Даже фича есть в Intellij для этого.

Ну это понятно. И/ИЛИ/тру/фальш.. но не подумал бы, что для этого нужно применять «правило де Моргана».

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

Ну если Вам приходится упрощать подобные выражения достаточно часто (на сколько я поняла — у себя на проекте), то не наталкивает ли это Вас на мысль, что может быть Вы не правильные вопросы на собеседовании задаете своим кандидатам?

нет, говнокод нам достается в наследство, а мы его искореняем

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

Якщо б я вас інтерв’ювив, то після такого запитання одразу б попросив на вихід.

Візьмеш на роботу, а потім у коді живуть отакі монстри: !(a && (b||!c)) || !d) && (e || !f).

Це не логічне мислення, це основа основ боротьби зі складністю!

Если эти монстры порождены не ФГМ писавшего их, а бизнес логикой, часто такие монстры имеют смысл. В противном случае требование может измениться например с b||!c на b||c, а девелопер, который будет поддерживать этот код потратит немало приятных минут, пытаясь понять, как бизнес логика соотносится с простеньким логическим выражением, предварительно заботливо минимизированным методом Квайна-Мак-Класки.

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

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

У комментариев есть одна проблема — они могут не соответствовать коду.

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

без правила никто не смог, даже с наводящими примерами, проверено

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

Наизусть не обязательно, но нужно уметь сделать аргументированный и осознанный выбор реализации
bigocheatsheet.com
javadevelopersenior.com/...collections.pdf

о спс надо будет почитать

Подписаться на комментарии