Comments 734

Идею про красные труселя и белую капибару записал в книжечку.
Никто не знает, где можно взять белую капибару в аренду?
С человеком все ясно: конфликтный, смотрим следующего.
Почему зачерпывать ложкой к себе это недостаток?
Основная проблема любой методологии собеседований — уход от личной ответсвенности через формализм. Чтобы собрать хорошую команду — нужен особый талант, на стыке глубокого технического понимания процессов и психологии, а это чертовски редкое сочетание для рекрутеров и интервьюеров. Встретить подобных людей можно разве что в качестве основателей стартапов с уже имеющимся стартаперским бекграундом (лично проводящих собесеование), но, практически, никак среди сотрудников отвечающих за найм в крупных компаниях.
Другое дело, что большинство не может. Вот попробуйте сами. Только честно. Вслух. Рассказ минут на 5. Вот чтобы сами себя взяли на работу после этого.
Ну а для людей без опыта все равно придется спрашивать что-то из теории. Хотябы выборочно. Возможно даже предложить человеку самому решить про что рассказывать.
Ну а для людей без опыта все равно придется спрашивать что-то из теории
Кстати. Вот в этой части как раз прошу своим языком описать, как человек понимает, что такое X (DNS, например), и как оно работает. И сразу уточняю, что книжное и википедийные определения меня не сильно интересуют, если не знают — можно не напрягаться. Если знают — я не откажусь услышать.
Ну или прошу примерный алгоритм на пальцах, как система отработает при использовании этой технологии.
Человек и так стресс испытывает (первая же работа! У меня ладони были мокрые в первый раз), а вот ещё и чисто теоретическое тут вспомнить может быть проблемой. Не экзамен в универе, всё же.
Я прошу человека нарисовать блок-схему решения квадратного уравнения. При этом сразу предупреждаю что гуглом пользоваться можно, но я буду наблюдать.
вопрос задаю обычно или юниорам или «матерым».
Вторым скорее для проверки психологического фактора.
Очень многие начинают бычится, мол «это смешно, задавать МНЕ такие простые вопросы».
Ну и потом когда (не если а когда) я найду к чему придраться, то у человека будет вторая возможность провалиться начав спорить что это все не важно, и вопросы у меня тупые.
Если человек напишет без гугла, да еще и без ошибок («идеально»), то я прям даже не знаю что делать. Такого никогда не было. Но пути решения, поведенческие реакции, сообразит ли человек исправить все оплошности после первого наводящего вопроса, или будет кивать головой дальше пока я все сам не назову — это важно, да. Не так важно как практические навыки, и реальные знания (не энциклопедические), но важно.
Это сродни текущему скандалу по «50% женщин». Отличная идея это ваше равенство.
Поощрять талантливых женщин, геев и лесбиянок — выгодно всем, ведь ты получишь ценные кадры которые страдают от предрассудков в другом месте, они получат хорошее место… Но если идею развить до конца, то мы получим «50% женщин-программистов», а это чистый фейл.
Я думаю что все эти олимпиадные собеседования имеют свои корни из таких вот небольших вкраплений теории и викторины. А потом «немножко» выродились в викторину. Плюс рекрутеру проще зазубрить количество пинов у сим-памяти, когда сейчас уже диммы чем научиться определять что рекрутируемый способен без документации разобраться какие джампера нужно ставить для какого процессора (ну какой он есть личный пример, по софту ни разу не собеседовался непрофессионалами).
Блок схема — это немного другое.
А приведенное вами решение, например, выдаст ошибку, если вы неправильно дали ответ, потому что в случае комплексных корней у вас x_1 будет равен x_2, так как для комплексных чисел корень работает по другому.
Самый простой способ провалиться на этом вопросе — отказаться его делать обидевшись что мол слишком простой вопрос. Чаще всего это были «я ж специалист, я ж курсы окончил!».
Нарисовать блоксхему или не спрашивая «а можно» написать псевдокод? — это тоже показатель того как человек в спокойной обстановке будет оформлять код. Не псевдокод, а накидать общую идею, как у вас (в комменте можно, в задаче на собесе нельзя, но такие тоже были) — давайдосвидания.
Полезет в гугл смотреть «гост оформления блок-схем» — любопытный факт, надо повнимательнее посмотреть что тут у нас: задрот или педант? Ну а озвученными вами типичными вопросами про комплексные корни и деление на ноль — это очень важный водораздел. Вообще не подумать что бывают исключения и писать в лоб — четко показывает уровень человека. Понял после уточнения «вы уверенны что все учли» — другой показатель. Опять таки как именно он будет писать/рисовать, искать, исправлять — ход мысли виден. Корень и деление это такие вещи которые вызывают вопросы автоматом, при написании. Ожидать нестандартного окружения (комплексные числа например) и не озвучить это вслух или в пояснительной записке к решению — гораздо большее зло, чем вообще не подумать о проблемных данных. Решение на тяп-ляп и попытка померяться длиной полового органа с собеседующим. Нафик, нафик. Ну или попытка оправдаться, что тоже жирный минус.
Я вот, например, каждый день сталкиваюсь со всем, что в этой задаче используется: процесс сбора требований, выбор подхода к решению задачи, обсуждение того, какие граничные случаи учитывать, а какие нет, и многое другое. Задача явно проверяет именно это, а не умение «рисовать блок-схемы»
Тогда прошу пояснить, какой из двух вариантов «задрот» или «педант» ассоциируета с «ему важнее шашечки и мы с ним не поедем»
Я просто со своей стороны считаю, что слова «блок-схема» еще более ругательные, чем «сортировка пузырьком». И постараюсь держаться одальше от конторы, где это просят на собеседовании.
Дракон идет по лесу с блокнотом. Навстречу бежит волк.
Дракон (глядя в блокнот): Так, волк, сегодня вечером в 9.00 приходишь на
поляну к дубу, где я тебя съедаю. Записываю тебя. (записывает) Есть
вопросы?
Волк (испуганно): Н-нету…
Дракон: Хорошо, до девяти свободен.
Волк убегает, дракон идет дальше. Навстречу идет медведь.
Дракон (глядя в блокнот): Так, медведь, ты вечером занят?
Медведь (испуганно): Н-нет…
Дракон: Тогда в 9.00 приходишь на поляну к дубу, где я тебя съедаю.
Записываю тебя, медведь. (записывает) Есть вопросы?
Медведь: Н-нет…
Дракон: Так, до вечера свободен.
После этого дракон встречает лису, лося, ежа и т. д. — и всех записывает
на вечер на съедение. Идет дальше, навстречу бежит заяц.
Дракон (глядя в блокнот): Так, заяц, сегодня вечером в 9.00 приходишь на
поляну к дубу, где я тебя съедаю. Записываю тебя, заяц. (записывает)
Есть вопросы?
Заяц (робко): А м-можно не п-приходить?
Дракон: Можно. Тогда я тебя вычеркиваю. (вычеркивает)
Все кто спрашивает «а можно псевдокод (код) а то блок-схемы не помню / плохо рисую / не люблю?» получают от меня ответ: «Можно».
А вот лучший способ завалить собеседование с сортировкой пузырьком это «отказаться его делать обидевшись что мол слишком простой вопрос»
Слово «блок-схема» в задаче во многом «дань традиции», ибо я считаю что стал программистом именно с этой задачи. Я тогда пришел к системному программисту на маминой работе с тем вопросом который меня интересовал — я не мог понять для чего в микропроцессоре Z80 регистр R (если не путаю наименование). Вопрос кстати был не совсем уж глупый, и прошло довольно много лет пока я таки на практике понял что регенерация динамической памяти это не такая уж и мелочь, и когда процессор это сам умеет это хорошо… В общем я такой весь умный был, а этот старый еврей меня посадил блок-схему квадратного уравнения рисовать. Оно было сильно обидно когда тебя такое спрашивают в 11-м классе с математическим уклоном…
Вот когда я скрипя зубами нарисовал, и меня ткнули носом в граничные условия и т.п., я да, стал программистом). Не хорошим программистом, плохим программистом. Ничего не умеющим, но уже программистом.
Ну а так то оно не мешает. Кто не помнит что это — может спокойно нагуглить. Кто не может нагуглить — проявит психологические качества которые пойдут ему в минус. Если это будет единственный минус то и черт с ним, подскажу, но если я и так колебался, то даже это может повлиять.
Впрочем, я понятия не имею, чем вы вообще занимаетесь и какая ваша предметная область. Ожидать одинакового стиля мышления от веб-разработчика, хардкорного эмбеддщика и какого-нибудь теоретика CS — неразумно. Поэтому, например, для CS-теоретика эти несчастные комплексные числа вполне могут быть стандартным окружением. И sqrt у него что надо возвращает.
Вот кстати да, посыпаю голову пеплом). Собственно все остальное на фоне того уже не важно.
Не стоит так резко воспринимать это.
- отфильтровали по опыту и стэку
- нашли публичный код
- показали его разрабам
- позвали на собес, удостоверились, что он сам писал этот код
- взяли его
- тестовое задание (обычно для джунов, т.к остальным дорого тратить на это время. Либо оплачивать)
- писать и обсуждать код прямо на собеседовании
- устроить код-ревью чужого кода
- запросить зарихтовать кусочек коммерческого кода и прислать
писать и обсуждать код прямо на собеседовании
Возвращаемся к whiteboarding'у пузырька? :) ну, и стоило ли так напрягаться, статью целую писать, чтобы вернуться к простому незамысловатому и лёгкому для анализа способу?
Когда-то давно прочёл, а потом нашёл немало подтверждений, что есть люди которые могут писать код и люди, которые только говорят, что могут. Очевидно, самая первая задача стоит в том, чтобы отделить одних от других. Можно пойти сложным путём и пытаться понять это из пространных размышлений о коммерческом коде в вакууме. Но можно же просто попросить написать на бумажке "пузырёк". Не?
Если овладеть этой джедайской техникой, то собеседования становятся не нужны. Не?
Готов рассмотреть варианты.
То есть вы предлагаете притащить на собеседование компьютер? а какой именно? Я, вот, привык к аймаку с клавиатурой микрософт нейчурал 4000 и вертикальной мышкой. Покупаете ради кандидата? Поставить туда любимую иде кандидата, дать ему пол-дня для её настройки под себя и… и попросить написать бинарный поиск? Супер!
Ну, вот, видите, вы сделали первый шаг — от комфортного компьютера и привычной иде к абы-какому хламу и первому попавшемуся иде. Следующий логический шаг — для решения примитивной задачи зачем вам иде? Хватит бумажки и ручки. Это достаточный набор бля любого айтишника. Я уверен, вы справитесь. Мои дети в первом классе справляются с этим инструментарием. И вы справитесь. А если не справитесь… ну, тогда, наверное, нафиг вы нужны такой? ;)
Если интервьювер не подготовил ноут и хочет видеть, как я пишу код — он недостаточно хорошо подготовился к собеседованию.
Богатая идея! Надо попробовать начать отказываться от собеседований если интервьюер пришёл не в жёлтой рубашке — это значит он плохо подготовился.
Нет, серьезно. Если вы хороший специалист и рассчитываете на то что компания будет стараться создать вам хорошие условия (орешки в кофе-комнате, рабочий график для совы, работа из дома если похмелье, не суть), то давайте уже сразу с собеседования начинать «я лучше работаю в привычной среде, не возражаете если буду писать на своем компе?».

Chromebook:

Lenovo ThinkPad X1:

И ладно, я ничего не имею против, когда на 12" ноутбуке компактная кливиатура, но когда на 17" ноут лепят точно такую же клаву, хочется ругаться.
Не понимаю, как можно программировать за такими недоразумениями. Я не спорю, можно привыкнуть к необычной раскладке, но когда тебя сажают за ноутбук и видят, что ты не можешь набирать на нём код, не глядя на клавитуру, это может испортить впечатление.
Но тут есть такая особенность — все материалы с собеседования будут смотреть и другие люди. Вероятно, код им будет удобнее смотреть в виде google doc, а схемы и таблицы — в виде фото доски или листов, а не наоборот.
Лично я сначала у доски рисовал пару рисунков, объяснял решение и доказывал его корректность и сложность, после чего набивал код на ноуте параллельно с комментариями на тему тестирования, получалось быстро и удобно.
Только маркер и доска, только хардкор.
мне ноут не предлагали
Скорее всего, зависит от офиса. В Лондоне мне предлагали, в Цюрихе — нет.
Может, уже и вовсе эту практику прикрыли. Мне лично доска показалась гораздо удобнее, чем google doc на chromebook. На ней картинки и формулы удобно рисовать. Не могу я без картинок задачи решать.
Скорее всего, зависит от офиса. В Лондоне мне предлагали, в Цюрихе — нет.
Видимо, так и есть. Я был в Цюрихе, там не предлагали.
Мне лично доска показалась гораздо удобнее, чем google doc на chromebook. На ней картинки и формулы удобно рисовать. Не могу я без картинок задачи решать.
Так можно же совмещать? Картинки на доске, код в компьютере.
По-моему, так все и работают: картинки рисуют на доске, а код пишут в компьютере.
Так можно же совмещать? Картинки на доске, код в компьютере.
Я так и делал, но это оказалось неудобно. Стоишь у доски, объясняешь, потом садишься к компьютеру (ревьюеру тоже надо сесть), пишешь что-то, при этом надо периодически смотреть на доску, иногда возвращаться, что-то дописывать…
Нет уж, код обычно достаточно короткий, чтобы легко умещаться на доске, а использование маркера вызывает меньше дискомфорта, чем клавиатуры непривычной раскладки без емакса.
Если у кандидата нет лэптопа — сойдет любой, в любом случае это не то же что писать код на бумажке.
Disclaimer: я не против писания кода на бумажке на собеседовании, но ваш аргумент как-то не очень.
На собеседование со своим компьютером? Не, не приходило. Как не приходило просить крановщика прийти со своим башенным краном. :) в общем, я бы на такое собеседование не пошёл. Хорошо, что ни кто пока до такого не додумался :). И, главное, ради чего — ради написания пузырька/бинарного поиска или чего-то подобного? Мой аргумент о том, что нет смысла забивать гвоздь микроскопом. По-моему, он очень даже "очень". А вот "программист" настаивающий на том, что не в состоянии реализовать простейший алгоритм без любимой иде и гугла, как раз "не очень". Зачем такого брать не работу?
На собеседование со своим компьютером? Не, не приходило. Как не приходило просить крановщика прийти со своим башенным краном. :)
Ну у вас и аналогии… оО
Вот серьезно не понимаю что в этом криминального.
На последнее место работы когда устраивался — меня мой будущий тимлид спросил есть ли у меня лэптоп и смогу ли я его принести на собеседование (если нет — сказали дадут ихний)
Дали задание написать небольшой модуль кеширования и тесты для него (потом я узнал что это была упрощенная реальная задача в их проекте; старая задача, так что никакой бесплатной работы я там не делал) — нужно было посмотреть на мой подход к решению «боевых» задач.
В итоге это было одно из лучших мест где я когда-либо работал, а в первый день мне выдали новый лэптоп, с которого я вам сейчас и пишу :)
«программист» настаивающий на том, что не в состоянии реализовать простейший алгоритм без любимой иде и гугла, как раз «не очень»
Tут я с вами согласен, но аналогии у вас все равно дикие какие-то…
Я кстати как раз работал в большой западной компании занимающейся азартными играми (т.е. очень жестко регулируемая индустрия) — на собеседовании дали доступ к гостевому вайфаю, по временному пропуску провели на определенный этаж для собеседований и прочих мероприятий.
Вообще у нас многие на собственных ноутах работали — и ничего.
Проносить можно — никто обыск на входе не устраивает, но вот пользоваться личными телефоном и ноутбуками нельзя.
> провели на определенный этаж для собеседований
Наверное, всё дело именно в этом. Есть гостевые помещения, а есть рабочие (для подписавших NDA), и гостевые помещения изолированы от рабочих.
> Вообще у нас многие на собственных ноутах работали — и ничего.
С собой их забирали или оставляли на работе?
Проносить можно — никто обыск на входе не устраивает, но вот пользоваться личными телефоном и ноутбуками нельзя.
Опять же, как вы себе это представляете? Например вам приходит смс на телефон — что смотреть ее нельзя? Или нужно срочно ответить на звонок — на улицу пойдете?
Наверное, всё дело именно в этом. Есть гостевые помещения, а есть рабочие (для подписавших NDA), и гостевые помещения изолированы от рабочих.
Конечно, зачем пускать кого попало куда не следует (я это серьёзно)
С собой их забирали или оставляли на работе
С собой забирали конечно, и рабочие тоже с собой забирали.
На каждый была установлена какая-то следящая программа (вроде бы от МакАффи)
А чем компанию защитит тот факт что ноутбук нельзя заносить или выносить из здания? (опять же если это не завод как я написал ниже, ну и может быть в банке какие-то спец требования еще)
Доступа к боевым серверам/ключам у кого попало нету, как и к интранету из дома. Ограничивать разработчиков и так подписавших NDA из-за необоснованной паранойи? Лучше вложиться в нормальную безопасность на мой взгляд.
Если работа предполагает использование телефона, тогда выдаётся корпоративный телефон. Если же хочется поговорить по личному — тогда вне рабочего помещения.
> С собой забирали конечно, и рабочие тоже с собой забирали. На каждый была установлена какая-то следящая программа (вроде бы от МакАффи)
Вот всяких следящих программ мне ещё не хватало.
> А чем компанию защитит тот факт что ноутбук нельзя заносить или выносить из здания?
Во-первых, ноутбук с конфиденциальными данными может быть банально спёрт. Во-вторых, контакт внешней сети с интранетом будет, но не в реальном времени.
Все эти проблемы можно решить, но ценой некоторых неудобств для владельца ноутбука.
Реализуется такая политика разграничением предприятия на зоны — вам не дадут пойти погулять где хочешь. Сетевые ресурсы — все разделены, доступ контролируется. Рабочие машины строго регламентированной конфигурации, никакого маломальского софта без разрешения установить не дадут.
Телефон, конечно, не запрещено. Как и свой ноутбук — только интернета либо не будет, либо дадут гостевой.
Такие же требования к субподрядчикам: люди, работающие с данными гиганта, должны соблюдать определённости, машины должны быть проверены, сеть — защищена. Не хочешь подстраиваться — найдутся другие, кто подстроится, бюджеты при работе с гигантами, обычно, не детские.
Азартные игры — это не нефтеперерабатывающий завод.
Банк — тоже не нефтеперерабатывающий завод.
В России такое встречал иногда на гос предприятиях, которые являются стратегическими объектами, но там правда на проходной все отнимали — от флешек до ноутбуков.
Реализуется такая политика разграничением предприятия на зоны — вам не дадут пойти погулять где хочешь.
Обычно на собеседовании вам тоже не дают гулять где хочешь. Я бы даже сказал не предлагают.
Как и свой ноутбук — только интернета либо не будет, либо дадут гостевой.
Что я и описал в своем примере выше.
Т.е. моя мысль осталась там же — если на собеседовании на айтишную позицию запрещено использовать свой ноутбук — это скорее большая редкость, чем правило.
Всегда настораживало утерждение, что для старшего разработчика непозволительно дорого делать тестовые задания.
Как это возможно, что человек ищет работу, но не готов показать свои умения?
Менее стрессовый вариант, рефреймящий коммуникацию с экзаменационного шаблона (вы задаёте каверзный вопрос, кандидат подрывается искать ответ) на кооперативный (совместно обсуждаете сторонний код, ответственность за который на кандидате не лежит, он наконец может немного расслабиться, включить голову, раскрыть способности, покритиковав другого показать себя).
Искать недостатки в готовом неидеальном коде эмоционально проще, чем ваять свой идеальный. Для перфекциониста вайтбординг — ад.
Если уж сил нет как хочется проверить стрессоустойчивость, можно дать кандидату в морду. Заодно и свою проверить.
и в итоге удивиться, какой «некачественный» код прислал.
А если я в свободное время пишу не код, а фэнтези? Ссылку на раздел Самиздата присылать?
Планета Шелезяка ждёт Вас!
Так всё хорошо в меру ведь. Главное — правильно организовать своё время.
Потому что есть такие штуки, как тимбилдинг? Без него, например, может расти напряжение в колективе и прочее.
Дело не в принудительном, но если команда представляет собой разрозненных людей, то ей довольно сложно работать эффективно.
Например, если люди плохо знают друг друга, то они могут стеснятся поднять какую-то важную тему, например, о проблемах проекта и прочее.
А еще тимбилдинги не только уменьшают, но и увеличивают напряжение — зависит от очень многих факторов.
ДРы, корпоративные праздники и т.п. вполне можно и в рабочее время «после обеда» отмечать. При этом обязательно дать возможность асоциальным типам оставаться асоциальными. Ненавижу общения в группах больше трех человек.
Прям физически не могу. Но как руководящий работник делаю над собой усилие.
А тем кто не манагерит, тот должен иметь возможность откосить и не вызывать у окружающих отторжение по этому поводу.
А тимбилдинги в свободное время — зло несусветное. Нет, иногда можно, но лучше уж куда-то на недельку с семьями или еще что-то, чем «пиво по пятницам».
А давайте делать пьянки в рабочее время.Нормальные компании так и делают. Более или менее взрослому человеку нафиг не сдалось приезжать в выходной или задерживаться вечером, чтобы еще раз на коллег посмотреть вместо общения с семьей.
Или показывать саму программу, но не код.
К примеру, у меня весь код открыт, но он никому не нужен. Мои первые программы шли freeware (без опен-сорса) и количество их загрузок исчислялось десятками тысяч. Мои программы были полезны, а мой код — нет (вероятно, по причине его невысокого качества).
Оставьте в комментарии… любопытно почитать. :)
PS ну и ссылку на резюме в инфе об аккаунте стоит держать, никогда не знаешь, где найдёшь человека, которого можно порекомендовать hr-ом компании, в которой работаешь :)
Я присоеденюсь к комментатору ниже, обычно, с людьми, которые совсем не пишут код в свободное время довольно сложно, так как преславутые 20% компания не выделает.
Так как они выпадают из трендов и как следствие, становятся узкими проектами специалистами и довольно консервативнымы, что напрягает других членов команды.
А вообще, тренды, как правило, то еще не предсказуемое и малополезное нечто. Они постоянно мрут и становятся бесполезным грузом знаний, либо решают уже решенные проблемы. Другой вариант. Смотрел тренды Java, нужно было подтянуть свой уровень. Многое выглядело для меня просто как дикость и безумие, т.к. проблемы, которые решают трендовые методики просто не существуют в C# dotnet. Так, легко видно людей, которые пишут на новом для себя языке как на старом.
Мне кажется, вы совсем не поняли то, что я имел ввиду. Если обобщить, то я имел ввиду что-то в духе "Откуда человек будет знать о новой, крутой и очень полезном фрейморке/библиотеке/тулзе X, если в реальном проекте он им не пользуется, а в свободное время вообще не занимается программированием, а значит, у него банально нет времени для того, что бы рости как специалист вне проекта?"
Откуда же человек получает опыт? Если ему повезло работать в крутом проекте, в котором вот применяется довольно большое количество нужных штук, то понятно, но а вот если нет?
Откуда, скажем, человек, который работает на проекте с jQuery будет получать опыт с новыми javascript библиотеками, что бы потом предложить их использовать в проекте?
Писать код совсем не обязательно, чтобы было понимание. И опять таки — все что в тренде может полететь далеко и навсегда. Так было с кучей практик, кучей, уже макулатуры, что когда-то были примерами для подражания большинства программистов той среды. Что для меня попусту потраченное время.
Мне уже давно не обязательно получать опыт пробами для работы с тем, что я уже знаю. Просто потому, что dotNet + Unity + специфика работы железа перекрывает возможности обучения методом проб. Они просто развиваются быстрее, чем это всё можно опробовать. Но есть и +. Всё это можно найти в спецификации, статьях, патчнотах и прочем. Этого достаточно, чтобы изучить всё и знать, что использовать в следующий раз.
Ну и поставим вопрос по другому. Сколько благ вы создали такой деятельностью? Некоторые люди, что продвигают те или иные технологии, дорабатывают их, тестируют, пользуются — полезны. Но какова эффективность? Не лучше найти еще одну работу, раз уж у вас полно сил и времени?
Писать код совсем не обязательно, чтобы было понимание.
Это как? Я еще ни разу не видел продукт, на котором было написано "у нас такие то проблемы". Что бы знать, подойдет ли какой-то продукт, фреймоворк или библиотека для решения проблемы — нужно получить с ними реальный опыт, чтение документации — это хорошо, но оно почти не дает точной информации по продукту.
Какие блага? Я делаю такие вещи не для того, что бы создавать блага, я это делаю для развития себя как специалиста и для того, что бы попробовать технологии, которые мне понравились. Вот у себя в pet-project написал бота с использованием rethinkdb и в целом неплохо и удобно, и как оказалось, у rethinkdb в самом деле неплохой кластер. Но и есть ряд проблем, которые оказались довольно внезапными и, которые, пока еще решить мне не удалось, типо того, что иногда все нафиг виснет из-за rethinkdb. Откуда бы я еще об этом узнал?
Да, в первые годы это приносит много пользы, учишься лучшему пониманию языка, набиваешь навык. Но потом это становится всё менее эффективным. С точки зрения понимания различных технологий — есть смысл изучить пару новых языков и программирование именно в их стиле. Большую часть новых фич переносят из других языков, не всегда даже языков программирования.
Касательно популярных вещей, что уже прошли отборку сообществом и теперь хотя бы иногда нужны заказчику. Освоить новую технологию не = написать что-то стоящее. Можно просто опробовать различные части этого проекта и понять как они работают. Это скорее исследовательская деятельность, чем написание чего-то конкретного. Тут просто быстро и полно проверяешь как и что работает. Часто даже более полно, чем когда требуется что-то конкретное.
Сколько у вас ушло только на одну вещь? А ведь их полно. Всё во всей IT среде просто не хватит времени проверить. Как вы будете выбирать, какой инструмент использовать? Только среди того, что пробовали? Это, пожалуй, на 2 месте самых худших способов выбора инструментария.
Любые блага. Даже ваше развитие как специалиста — благо, нет? Чтобы развиваться как программист, не обязательно для этого писать код, тем более «для себя», как и быть в тренде необязательно. Можно решать логические задачи, можно читать книги и справочники, ту же документацию. Даже изучение не языков программирования может принести пользу при правильном подходе.
Сколько у вас ушло только на одну вещь? А ведь их полно. Всё во всей IT среде просто не хватит времени проверить. Как вы будете выбирать, какой инструмент использовать? Только среди того, что пробовали? Это, пожалуй, на 2 месте самых худших способов выбора инструментария.
А как вы предлагает? У вас, по факту есть два варианта: это hype-driven-development и использование опыта. Откуда вы возьмете людей, которые скажут вам "Да, технология X подходит на наш проект, потому что ..."?
тобы развиваться как программист, не обязательно для этого писать код, тем более «для себя», как и быть в тренде необязательно.
Это довольно странное заявление. То есть программист, который вроде как похож на инженера, не должен быть вкурсе последних новостей своей отрасли? Причем, в отличии от инженера, ему стоит их пощупать, так как у него хотя бы возможность есть.
Можно решать логические задачи, можно читать книги и справочники, ту же документацию.
Это абстрактные логические задачи, которые вам не очень помогут? Или документация, которая, обычно, сильно отличается от практики. Чтение документации о чем бы это не было бесполезно без практики.
Это скорее исследовательская деятельность, чем написание чего-то конкретного.
Ну так мы же не требует от всех крутые open-source библиотеки. Но, скажем, если я буду изучать какую-то специфическую БД, то почему бы мне не взять в дополнение к этому какой-то новый web-фрейморк на знакомом мне языке (или уже знакомый мне) и не написать на нем какой-то todo лист? Вполне исследовательская деятельность.
Я ни за что не начну верить только чужому опыту, когда на кону работа не одного человеко-месяца. Разве что от безысходности. Тут так же влияет психология — чаще выбирают просто знакомое, совсем не потому, что оно лучше.
Инженер-программист, не то чтобы похож — он и есть инженер. Не должен знать о новых технологиях, но может. Да, лучше если в курсе, но вот если архитектор может спроектировать систему водоснабжения, то он может спроектировать систему водоснабжения, знает он новые технологии или нет. Замечу так же, что новые технологии в программировании обычно дают прирост производительности всего в несколько % за год.
Инженер отличается от техника в том числе и тем, что может вообще никогда не пощупать и не увидеть то, что он спроектировал. В среде программистов возможен и 100% технический подход, и даже 100% инженерный.
Архитекторы часто делают то, что никто до них никогда не делал. Создают технологии, которые никогда и нигде не применялись. И у них нет возможности «потрогать» это. Я не считаю для себя невозможным в принципе инженерный подход — то бишь оценку и проектирование до исполнения.
Что здесь хотя бы необычного?
Абстрактные логические задачи могут принести больше пользы, если вы и так пишете код до 8 часов в день по рабочим дням. Это в карате силен тот, кто отработал один удар тысячи раз, а вот с мозгами работает иначе.
PS: Ничего против не имею. И даже за. Но и не считаю, что это стоит превозносить.
Дополнительно к этому, написание своих проектов позволяет выработать какие-то best practice и прочую мишуру, которую потом можно приности в проект, вроде анализаторов когда, подходов к unit-тестированию и прочему.
Писал же — в первое время это очень сильно помогает понять язык и набить навык.
Мне кажется, совсем полностью раз и на всегда нормально выботать их не получится.
Всякие docker, static-code analyze и прочие полезные штуки довольно часто появляются.
Например, для тестов вот относительно недавно выпустили такую штуку: https://pypi.python.org/pypi/elizabeth, которой довольно не хватало некоторым для написания тестов)
Можно обойтись и без этого или написать своё. Можно ту же 1000 технологию подключить, или выработать стиль и правила, что решат большую часть проблем. Вариантов много.
Я сам работаю с Unity и С#. Чем больше библиотек, тем больше мата. Иногда, чтобы внедрить новую либу, с учетом 5 необходимых, тратится столько времени, что быстрее написать своё решение. Возможно в вашей среде иначе? Я не знаю. Может и в этом наши различия?
Так же, как я уже говорил — в той же Java решают часто те проблемы, что уже решены в dotnet самой архитектурой(быть может в Java решена часть проблем, что есть в C#, но я не столь хорош в Java). Думаю, это так же может влиять.
Я сам работаю с Unity и С#. Чем больше библиотек, тем больше мата. Иногда, чтобы внедрить новую либу, с учетом 5 необходимых, тратится столько времени, что быстрее написать своё решение
Именно!
Вот потому надрачивание на библиотеки и фреймворки — считаю Культом Карго.
Кажется, не так давно(на деле больше года) говорили о проблеме в java, где было 1000 и 1 либа, иногда одна популярная либа была буквально в несколько строк.
Речь явно было про js (точнее про npm)
Я сам работаю с Unity и С#. Чем больше библиотек, тем больше мата. Иногда, чтобы внедрить новую либу, с учетом 5 необходимых, тратится столько времени, что быстрее написать своё решение. Возможно в вашей среде иначе? Я не знаю. Может и в этом наши различия?
Ну а у npm время внедрения — несколько секунд.
У Java при использовании gradle/maven (~99.5% проектов) время подключения новой библиотеки, кстати, тоже невелико и больше упирается в ширину интернет-канала.
И да, можете гордиться тем, что
в той же Java решают часто те проблемы, что уже решены в dotnet самой архитектурой(быть может в Java решена часть проблем, что есть в C#, но я не столь хорош в Java)
вот только это заблуждение.
Ну а у npm время внедрения — несколько секунд.
Это пока из-за них не произойдет каких-либо проблем. Обычно установить либу или плагин не проблема. Пока он один. Но т.к. спецификации нет, как нет и правил установки, то при большем количестве плагинов появляются конфликты наименований, доступа и т.д. Часть проблем видна сразу, часть легко определить, а часть незаметна и ждет релиза.
Это не заблуждение, а факт. Более того, некоторые проблемы(недостатки) есть у каждого языка, особенно если расширяется зона его применения. Часто о недостатках знают и сами разработчики — иначе бы языки не развивались.
сам так делаю, экономит кучу времени, как как соискателя, так и работодателя.
полное отсутствие публичного кода считаю минусом. вероятно, человек не очень любит профессию?
хотя для джунов такое приемлемо (еще не успели), тогда пишут тестовое.
— помыть полы
— помыть плиту
— помыть санузел
— помыть зеркала
— помыть обувь
— постирать кучу белья
— глажка… 3 рубашки запросто могут съесть 40 минут времени
— мытье окон
— готовка-готовка-готовка… да, я способен сварить борщ за 30 минут, но это… скажем так, надо быть в настроении и форме.
И это только тот список дел, что просто обязательно делать нужно. А про чистку системника я вообще молчу — мне его разобрать-смазать-собрать обходится часа в 4. Благо раз в 6-8 месяцев этот ужас.
А если сюда добавить всякие задачи уже по машине (которая на колесах), бабу, друзей — эм, не, нету свободного времени.
Я не к тому, что это все не проблемы, а к тому, что их, обчно, все же можно если и не решить, то, как минимум, сильно облегчить.
Проблема в другом. Ну вот нравится человеку готовить и убирать. Имеет право.
Ну вот нравится человеку готовить и убирать
Готовить? Ну раньше я был поваром (пришел из поваров в IT).
А вот уборка? Скажем так, благодаря тому, что не хотят применять хим-реагенты или иные способы борьбы с гололедом, а посыпают все солью и песком несколько лет к ряду, то в воздухе стал такой ад твориться… просто приоткрытое окно дает за неделю слой земли на подоконнике.
Про робо-пылесоса думал, но от этого он тупо умрет.
Сторонним людям я не доверяю — не хочу никого пускать туда, где живу (без крайней на то нужды — от замены лампочки до бурения стен/плитки я и сам справляюсь).
Окна вообще нужно мыть, когда грязь на них начинает раздражать.
Рубашку можно купить более суровую, но не требующую глажки, обувь протирать тряпочкой перед выходом — 1 минута и т.д.
Самое долгое в готовке — помыть-порезать.Это сильно зависит от того, что готовить. Если, скажем, куриную грудку на пару делать, то в мультиварке это выглядит как «за 30 секунд все загрузить, полчаса погулять, готово», а в обычной кастрюле на плите мало того, что придется варить вместо парения, так еще и отойти никуда нельзя — вдруг убежит? Да и пенку снимать надо.
А сейчас вроде и не педант-чистюля, но блин… если даже зубы не почищу перед сном, то лежать в кровати противно стало.
С возрастом способность тела переносить разные негативные факторы упала и за ним (телом) понадобился гораздо больший уход. От сбалансированного питания и тренажерки до основательного соблюдения гигиены.
А то без тренировок уже и в кресле сидеть не мог — все болело. Благо гантели/штанга/турник и т.д. спасли положение.
Более того, наличие большого количества открытого кода, написанного во время полной занятости (а не между работами и не в отпуске), во многих случаях говорит о том, что работодатель не контролировал нагрузку сотрудника, и он, мягко скажем, скучал на работе. Или забивал болт на работу, потому что она ему не нравилась, и переключался на пиление своей библиотеки. Возможно, поэтому он и ушёл из той организации.
Более того, наличие большого количества открытого кода, написанного во время полной занятости (а не между работами и не в отпуске), во многих случаях говорит о том, что работодатель не контролировал нагрузку сотрудника, и он, мягко скажем, скучал на работе.
А зачем сотрудника полностью нагружать? Нормальному работодателю должна быть интересна выполненная работа, а не жопочасы.
Когда работодатель нагружает сотрудника так, что у него не остаётся больше ни на что времени, это приводит к тому, что сотрудник теряет возможность изучать новые и интересные вещи. Как следствие — выгорание на работе и потеря квалификации, так как в программировании нужно постоянно изучать новые технологии и расширять кругозор.
Если сотрудник стал выполнять задачи не за 8 часов, а за 4 часа, а оставшиеся 4 часа скучал, это значит, что квалификация работника повысилась и надо что-то делать. И просто давать такому сотруднику больше задач — не вариант
Впрочем, со стороны работодателя, наоборот, рост квалификации сотрудника может быть нежелателен, т.к. для более квалифицированного сотрудника может просто не оказаться задач, и в итоге такой сотрудник уйдёт.
"Если сотрудник стал выполнять задачи не за 8 часов, а за 4 часа" — эмм, мы о программистах говорим или о грузчиках на складе? Грузчик может быстрее машину разгрузить и пойти отдыхать, пока следующая не приехала. А представить, что у программиста кончились задачи, я лично не могу. Их сотни висит в баг-трекере. Если прогаммист простаивает, это ошибка найма и убытки для бизнеса.
Если программист начал работать продуктивнее, он может делать больше (лучше) и претендавать на большую зарплату.
Саморазвитие — отдельный пункт, который должен либо по договору с работодателем либо планированием самого разработчика занимать N-ную часть рабочего процесса — и это может быть как pet project, так и изучение книг, напрсание статей, рефакторинг проекта… И это не 4 часа из 8, а максимум 1.
Если человек хочет свободное время, он работает сдельно. Положил ряд кирпичей, получил деньги.
Какое же это свободное время, если ты обязан сидеть его в офисе?
Почему убытки-то? Обоснуйте. Почему медленный программист, выполняющий объём задач за 8 часов выгоден, а быстрый программист, выполняющий тот же объём задач за 4 часа и требующий столько же денег — нет?
> Если программист начал работать продуктивнее, он может делать больше (лучше) и претендовать на большую зарплату.
Да, более эффективный сотрудник приносит больше прибыли, поэтому в интересах работодателя давать ему больше работы, компенсируя это увеличение нагрузки зарплатой. Но это может расходиться с интересами программиста, которому достаточно денег и он не согласен тратить больше времени на работу.
> максимум 1.
За 1 час ничего серьёзного сделать не получится.
За 1 час ничего серьёзного сделать не получится.
Серьезное вы делаете по основной работе. Если для вас это просто способ заработка и вам не интересен проект (был бы интересен, вам бы хотелось еще что-нибудь улучшить за оставшиеся 4 часа), то может быть стоит сменить работу?
Если прогаммист простаивает, это ошибка найма и убытки для бизнеса.Почему убытки-то? Обоснуйте. Почему медленный программист, выполняющий объём задач за 8 часов выгоден, а быстрый программист, выполняющий тот же объём задач за 4 часа и требующий столько же денег — нет?
Тут у нас, наверное, надопонимание. Я говорил о том, что плохо, когда задач не хватает, чтобы загрузить программистов. Если же ваше "сотрудник стал выполнять задачи" означало "сотрудник стал делать тот же объем работы за 4 часа, а оставшиеся 4 часа филонить при наличии других важных и срочных задач", то тут даже не знаю что сказать. Наверное то, что проект с такими сотрудниками вряд ли взлетит.
Это способ повысить свои знания и применить их на благо проекта. Половину времени решаются текущие задачи. А половину — делаются эксперименты, результаты которых не нужны прямо сейчас, но от которых будет польза в будущем.
> то может быть стоит сменить работу?
Нет. Я не соглашусь на работу, где надо работать по 8 часов в день. Ну ладно, может и согласшусь, но минимум за ~300-400к рублей в месяц.
> Тут у нас, наверное, надопонимание. Я говорил о том, что плохо, когда задач не хватает, чтобы загрузить программистов. Если же ваше «сотрудник стал выполнять задачи» означало «сотрудник стал делать тот же объем работы за 4 часа, а оставшиеся 4 часа филонить при наличии других важных и срочных задач», то тут даже не знаю что сказать. Наверное то, что проект с такими сотрудниками вряд ли взлетит.
В том-то и дело, что филонить не стоит. Наличие срочных задач действительно потребует недельку-две попахать, отложив свои проекту. Но это не должно быть нормой. Аврал — проблема руководства.
Почему убытки-то? Обоснуйте. Почему медленный программист, выполняющий объём задач за 8 часов выгоден, а быстрый программист, выполняющий тот же объём задач за 4 часа и требующий столько же денег — нет?
наверное имеется ввиду, что если «в среднем» программисты в фирме за 4 часа делают основную работу и 4 часа простаивают, то можно сократить штат программистов в два раза, и на этом сэкономить :)
ЗЫ если что я сторонник того, что программист работает не 8 часов, а программист работает головой :)
Ага, сократить штат в 2 раза и поднять оставшимся программистам зарплату в 2 раза.за удвоенный объём работы. Шило на мыло. Но при этом пропадает ещё один важный момент: запас производительности. В случае аврала в первом случае вы можете удвоить производительность программистов, во втором — нет.
Но при этом пропадает ещё один важный момент: запас производительности.
Типичные грабли, на которых висят истлевшие косточки многих молодых оптимизаторов. Не раз мною виданы случаи, когда Васю с Петей сокращают, потому что их работу смогут сделать Дима с Колей за полторы зарплаты. В случае факапа оказывается, что в сутках всего 24 часа, раз в два дня Диме желательно, все же, поспать, а Коля, вообще, в гробу видал переработки и заявления его осталось ждать недолго.
Если прогаммист простаивает, это ошибка найма и убытки для бизнеса.
Если программист начал работать продуктивнее, он может делать больше (лучше) и претендавать на большую зарплату.
Если у Вас два бегуна:
- стайер который бежит не быстро, но долго
- и спринтер который бежит быстро, но часто отдыхает
будет верхом идиотизма считать отдых спринтера "убытками для бизнеса".
может быть стоит сменить работу?
Это Вам стоит сменить работу по причине Вашей полнейшей профнепригодности в качестве IT-менеджера.
Захотелось попробовать какой-то новый язык/фреймворк? Скачали, развернули, почитали про синтаксис, мельком пробежали по стандартной библиотеке, придумали реалистичный сценарий применения, сваяли каркас, написали тесты (и стресс-тесты), погоняли, записали себе в блокнотик мысли о применимости решения и встретившихся на пути ограничениях. Всё. Выкладывать после этого этот каркас на гитхаб, чтобы будущий работодатель посмотрел на это убожество и решил, что я пишу так на всех языках? Извините, но нет.
Чтобы более менее нормально изучить C++, нужно 2-3 года практики.
Чтобы стать спецом по многопоточности и асинхронности, уметь грамотно построить архитектуру приложения и не допускать детских ляпов, тоже нужна практика, хотя бы год.
А шапочное знакомство с новыми технологиями ради строчки в резюме не принесёт практической пользы.
То что человек, тратит собственное время на что-то вне работы, говорит не о том, что ему здесь плохо и ему надо срочно уходить куда-то еще. Его вполне может устраивать текущее положение вещей на проекте. Это говорит скорее немного о ином: ей/ему интересны несколько областей разработки; просто чтобы всегда быть «в тонусе» и повышать свой профессиональный уровень гораздо быстрее, нежели его коллеги; иметь потенциальное преимущество перед другими кандидатами, при необходимости поиска работы (например, тебе могут закрыть глаза на необходимость тестовое задание и сразу перейти собеседованию).
П.С. А вообще, я не буду удивлен, если вдруг обнаружится, что человеку который тратил свое свободное время и занимался какими-либо проектами (или может даже поучаствовал в разработке существующих как-либо) получает более «вкусное» предложение о работе.
А вообще, я не буду удивлен, если вдруг обнаружится, что человеку который тратил свое свободное время и занимался какими-либо проектами (или может даже поучаствовал в разработке существующих как-либо) получает более «вкусное» предложение о работе.
Так и есть. Например, я никогда не работал фултайм, работал ровно столько, сколько хотел, а в свободное от работы время занимался своими проектами, которые мне интересны. При этом это был не фриланс, просто работодателям было все равно, как я трачу время, им были важны результаты.
В итоге сейчас мой доход существенно превышает зарплату, которую бы я мог получать при работе на полную ставку с жопочасами.
С другой стороны: семья, как ничто другое формирует самодисциплину, умение ценить и оценивать не со своей колокольни, а с практической точки зрения. Семья очень сильно развивает эмпатию. Ну и да — с семьёй вы станете менее «крутым» с технологической точки зрения. Но еще не встречал ни одного такого «менее крутого», который бы жалел о том, что не так «крут».
Вряд ли.
Когда переходил с проекта на проект, где невозможно показать код и обсуждать технические решения, помогали две вещи: несложные тестовые задания на 1-2 дня и устные технические собеседования. Задания обычно не под NDA и я их с чистой совестью использовал дальше для демонстрации хорошего кода, а некоторые и для своих нужд (например, сокращатель ссылок как тест и для себя)
На тостере дал ответ на такую же ситуацию https://toster.ru/q/449109#answer_1064583
Опять же, рекомендации, общие знакомые, участие в конференциях и т.п., что делает специалиста более заметным в своей сфере.
Или «пулл реквесты» — это решение каких-то задач из внутреннего трекера? Что тогда вас мотивирует решать такие (вполне возможно, даже абсолютно однообразные) задачи?
Или «пулл реквесты» — это проталкивание своих идей в проект? Как часто у вас возникают такие идеи? Не боитесь ли вы своей идеей сломать всю идею самого проекта? Как часто ваши идеи принимают?
Не факт, что это универсально и нравится каждому, но трудозатраты обычно небольшие, рисков немного. В небольшие проекты minor изменения принимают достаточно охотно.
Самый простой вид «вклада» — это исправление неточностей в документации.
Обычно их находишь, если внимательно изучаешь документацию.
Какова мотивация их править?
Если ваc эти недостатки в документации заставили потратить лишнее время,
может захотеться сделать так, чтобы другой человек не потратил этого времени.
Такие изменения отклоняют очень редко.
Что вам не хватает в существующих решениях?
Меня всегда удивляет позиция программистов, которые считают, что абсолютно всё уже написано до них.
Понятно, что далеко не все написано «до нас». Но действительно ли на это стоит тратить время? Приведите примеры, когда собственная разработка упростила вам жизнь, в отличие от уже существующих разработок
Ну и пример, например. :)
https://habrahabr.ru/post/275447/
Сделал для себя. Альтернативы либо отстой, либо проприетарные.
Приведите примеры, когда собственная разработка упростила вам жизнь, в отличие от уже существующих разработок
Пожалуйста.
При поездке к заказчику оказалось, что работающая по HTTP железка формирует расходящийся со стандартом HTTP ответ. Браузер страницу отображает, но HttpClient из C# бросает исключение, типа, ProtocolError. В итоге за 1.5 часа просто написал свой собственный HttpClient. И пофиг, что он поддерживает не всё, главное, что работает с железкой.
Реализация MySql протокола. По какой-то причине родной MySql connector перестал работать (причину уже не помню). За 2 дня по мануалам с офсайта сделал свою реализацию, к тому же с нужными мне свистоперделками, которых не было в оригинальном коннекторе (асихронная работа с сетью).
Собственный кросс-платформенный кооперативный планировщик для тасков в C#. Существующий не устраивал низкой производительностью — низкий IOPS при выполнении операций с сокетами из-за высоких накладных расходов на await и переключений контекста. В итоге увеличил IOPS почти на два порядка, написав обёртку для сокетов и избавившись от переключения контекста.
Заменил tbb::parallel_for на свою реализацию за счёт снижения накладных расходов. Это позволило не думать о гранулярности задач.
- Применение нейросети для увеличения разрешения изображений (своя реализация SRCNN — пощупать можно тут). Там всего-то 50 строчек кода до AVX оптимизаций. Ведь для того, чтобы просто использовать уже обученную нейросеть, не нужны все эти здоровенные фреймворки.
и т.д.
Видимо, я плохо сформулировал первый вопрос. Вопрос был в том, что вы делаете в отрыве от работы (либо напрямую не связанное с работой, что считать напрямую не связанной — остается за вами), а в том, что делаете для личных целей. Понятно, что все мы на работе пишем код, что-то оптимизируем, улучшаем и т.д. (правда, не все это рискуют выкладывать в open source)
Варианты «в целях саморазвития» и «для лучшего понимания каких-то концепций» — вы в принципе не рассматриваете?
Другое дело, если действительно идет речь о реально нужных проектах «для себя» или для кого-то еще. То есть, где опыт приближен к продакшену. Но тогда встает вопрос. где взять идеи для таких проектов (и время тоже)
Не холивара ради, просто какое-то смутное желание пощупать есть давно, а смысла как-то не нашлось (но подозреваю, что я этот самый смысл плохо искал)
на какого рода задачах ФП будет эффективнее (с точки зрения читаемости кода, стоимости написания и поддержки), чем ООП?
Мне кажется, странно ожидать магического буста эффективности при переключении на новую парадигму. Нужно время на адаптацию к новым идиомам, а не просто к новому синтаксису. Если вы не видите, где ФП вам бы больше подошло, возможно, стоит детально изучить какой-нибудь язык с интенсивной поддержкой ФП (F#, Scala, OСaml, etc.) и параллельно попробовать сделать что-нибудь простое с его помощью (любую задачу, которую давно хотелось сделать, но не доходили руки).
Большинство языков поддерживают несколько парадигм (и императивное, и ООП, и ФП), можно комбинировать подходы.
Я просто не верю, что саморазвитие может происходить за пределами продакшена
Ну вот вам пример из жизни — начал интересоваться устройством компиляторов (в универе только вскользь затрагивали)
Решил для общего развития написать собственный язык — посмотрел на ютубе кембриджский курс по компиляторам, написал свой язык.
В итоге стал лучше разбираться сразу в нескольких вещах: напр. как работает строгая типизация и контекст «под капотом», в структурах данных (деревьях), в работе со стеком/памятью и т.д.
Т.е. прокачал некоторые свои навыки, хотя сам проект никому особой пользы не принес.
Меня всегда удивляет позиция программистов, которые считают, что абсолютно всё уже написано до них.
Не знаю верить слухам или нет…
Но, слышал от нашего тим-лида, что есть люди, которые имеют привычку вместо написания кода гуглить подходящий код, а не найдя его могут глядя в глаза заявить, что "такое написать невозможно".
нормальные мидлы без перспективы роста. тоже полезны бывают )
Это вообще-то формальный водораздел между техниками и инженерами. Техник только применяет ранее описанное решение, инженер — ещё и выбирает, создаёт и обосновывает. Что, впрочем, не мешает инженерам применять типовые решения при соответствующем обосновании. Первый читает инструкции, второй, если надо, может написать их.
Просто надо использовать таких людей на соответствующих ролях и грамотно ограничивать их способность к "навредёжу".
Например, мы со знакомым обсуждали написание быстрого покерного калькулятора (5-7 карт). Одно из самых быстрых решений — использовать некоторый конечный автомат в виде массива, чтобы ранг комбинации вычислялся линейным кодом ...fsm[c3+fsm[c2+fsm[c1]]]… Это работало быстро, но массив fsm как-то надо сгенерировать. Можно найти готовое решение для семи карт Texas Hold`em.
Поиск по интернету ничего не дал, с другой стороны я не очень то и искал. Так возник проект yoo-ofsm где я реализовал построение таких конечных автоматов, что было использовано для семикарточного конечного автомата для омахи и 5-7 карточных автоматов для Six Plus Hold`em.
Также, занимаясь вопросами перебора комбинаций я перевёл на битовые операции известный алгоритм Д. Кнута. Получилась статься Битовая магия: получение следующего лексикографического сочетания. Нет, я вполне допускаю, что погуглив, можно найти этот код где-нить в дебрях интернета, но я сходу не нашёл, а самому написать не так чтобы и долго.
нашли публичный код
А если публичный код — это множество человек в GNU-проекте?
И как быть, если этот публичный код не связан с вакансией?
У меня, например, публичный код на C++ в качестве хобби, но у нас на него нет вакансий и на работе я его не использую.
CString — т.к. stl реализации не гарантируют корректную работу при многопоточности
Что означает "при многопоточности", и как именно CString исправляет ситуацию? В документации ничего про многопоточность не сказано https://msdn.microsoft.com/en-us/library/ms174288.aspx
std::string можно использовать в многопоточных программах. Проблемы будут только в том случае, если изменять объект строки из разных потоков без блокировок.
std::string можно использовать в многопоточных программах. Проблемы будут только в том случае, если изменять объект строки из разных потоков без блокировок.
std:string может иметь одну пакость — когда я пишу
string a="test";
string b;
b=a.
Я ожидаю, что a и b — два разных объекта. Но stl так может не думать — в целях снижения расходов памяти она может в b приравнять указатель на строку, хранящуюся в a. Если у меня a и b в разных потоках, то меня ждёт сюрприз. Вот тут это описано у Борескова: http://steps3d.narod.ru/tutorials/c-minus-minus.html
и как именно CString исправляет ситуацию?
Так MFC поддерживает мультипоточность и CString, соответственно, тоже. «The Microsoft Foundation Class (MFC) library provides support for multithreaded applications.» ( http://www.tutorialspoint.com/mfc/mfc_multithreading.htm )
Еще одним весьма неприятным сюрпризом является то, что в класса std::string (пол крайней мере во многих реализациях) быблиотека пытясь минимизировать выделение/освобождние/компирования памяти в многих случаях использует общий бефер для строк с одинаковым значеним.
Рассмотрим пример:
std::string a = "abc"; std::string b = a;
Для многих реализаций обе переменные a и b будут оказывать на один и тот же буфер в памяти, по-возможности, отслеживая моменты, когда необходимо «расщепить» общий буфер, дав каждой переменной по своей копии.
Однако в случае многонитевых приложений подобная политика запросто приводит к возникновению т.н. raise condition, например, одна нить может уничтожить одну переменную, а другая — что-то записать в нее. При этом сущесвтует вероятность того, что произойдет обращение к уже освобожденному блоку памяти и падению программы.
Можно, конечно возразить, что никто не обещал, что STL будет успешно работать в многонитевых приложениях. Однако в ряде реализаций не выдается даже предупреждения на стадии компиляции о возможных проблемах.
И если STL нельзя использовать в многонитевых приложениях (а многие реальные приложения являются многонитевыми, много Вы видели общаний что callback выдет вызван на той же нити, на которой Вы его поставили?
В данном случае попытка оптимизации приводит к скрытым и тяжело обнаруживаемым проблемам.
Это в каких таких махровых реализациях std::string cow?
Обоснуйте. Такое хранение строк в std::string в принципе недопустимо, т.к. к строкам можно обращаться посимвольно и эти символы менять. И сюрприз будет ждать даже если всё делается в одном потоке.
> Вот тут это описано у Борескова: http://steps3d.narod.ru/tutorials/c-minus-minus.html
String interning — нормальная вещь. Но для мутабельных строк его применять нельзя. Если какой-то компилятор решил это сделать для мутабельных строк, используя игры с флагами и CoW, то таким компилятором пользоваться не стоит. Сейчас так никто не делает.
то в каких таких махровых реализациях std::string cow?
Да, пишут, например, что в CGG такое встречается.
Обоснуйте. Такое хранение строк в std::string в принципе недопустимо, т.к. к строкам можно обращаться посимвольно и эти символы менять. И сюрприз будет ждать даже если всё делается в одном потоке.
Что именно обосновать? Такое хранение строк использовалось (поищите в инете — найдётся всё) и, как оказалось, и сейчас используется в MFC. Вот когда вы начнёте менять строки, вот тут они и будут разделены. Но не раньше. Теперь следите за потоком: например, потоку сервера нужен введённый в основном потоке порт сервера. Он что делает? Блокирует, скажем, мютексом, общую переменную и копирует строку себе в другую строку. Освобождает мютекст и планирует работать дальше с копией переменной. Но COW просто копирует указатель — строки-то одинаковы с его точки зрения. И тут основной поток убивает строку. :) Сюрприз.
Сейчас так никто не делает.
Никогда не знаешь, куда будет портироваться наработанный код.
Он что делает? Блокирует, скажем, мютексом, общую переменную и копирует строку себе в другую строку. Освобождает мютекст и планирует работать дальше с копией переменной. Но COW просто копирует указатель — строки-то одинаковы с его точки зрения. И тут основной поток убивает строку. :) Сюрприз.
Какой в этом случае сюрприз-то? COW не просто копирует указатель, но ещё и увеличивает счётчик ссылок. Строка удаляется только в том случае, если счётчик ссылок стал равен нулю. Причём инкремент в современных компиляторах будет атомарным, если собирать с правильными флагами.
Если у вас версия COW-строк, которая не умеет атомарно увеличивать счётчик, то копирования под мутексом должно быть достаточно для корректной работы.
копирования под мутексом должно быть достаточно для корректной работы.
Ещё подумал: нет, не достаточно. Потому что при вызове деструктора тоже атомарно нужно счётчик изменять, иначе память утекать будет. В общем, COW строки должны использовать атомарные счётчики ссылок для корректной работы в многопоточной среде.
И что самое обидное, CString всё-таки использует Copy On Write. :( Жаль, я был уверен, что указание использовать многопоточные dll заставит MFC не применять COW.
Придётся переписывать со своим классом строки. Жаль.
Я чего спрашиваю-то, вот есть у меня программа калибровки прибора. Ей нужны около 40 каталогов с данными вращений на стенде в разных плоскостях. Окей, загружаем всё это в память. Дальше эти данные нужно между собой усреднить, найти в них точки ступенек (где стенд делал паузу) и в этих точках усреднить показания по ступеньке, исключая переходный процесс между ступеньками. В результате получаются точки калибровочной кривой. По ним строится модель погрешности, по которой вычисляются отклонения от идеала и делается общая оценка качества калибровки. Вот и всё. Данных обрабатывается дофига и больше, но почти ничего вот из этого там нет и в помине. И вот ни разу не требовалось, как ни странно.
redmine не подходит — у нас XP, а ему нужна 7 минимум
Просто любопытно — почему Linux на одну из коробок не поставить? (ту же убунту)
На нем Redmine можно парой команд установить.
Насколько могу судить, всё началось с блог-поста yegor256, а Дэвид подключился уже потом.
Кроме того, когда я задаю задачки, они обычно совсем простенькие, по теме вакансии, но при этом меня не разу не интересует правильность ответа, но это всё магия и колдунство профайлинга.
Первым этапом не код писать, а парами-тройками разбирать постановку задач и декомпозировать для других команд.
Вторым этапом обсуждать между командами постановку, декомпозицию и прикидывать решения
Третьим — решать.
Получается технические навыки на втором этапе (частично) и третьем. Возможно отсеивание кандидатов, не способных понять задачу, согласовать между коллегами, выбрать решение — это важнее самого решения.
И и тестом на IQ не все так просто — да, в каждом конкретном случае он может давать сбой, но корреляция налицо и если Вы сможете предъявить высококлассного интеллектуала, который даст на тестах меньше 120, я буду крайне удивлен.
Так что резюме — ректрутингу нужен какой то формальный показатель, и лучше, чтобы он был связан с профессиональной деятельностью. Не знаю, как у Вас, но у меня нет времени час беседовать с каждым кандидатом и угощать его колой, наверное, мне просто меньше повезло в жизни.
у меня нет времени час беседовать с каждым кандидатом и угощать его колой, наверное, мне просто меньше повезло в жизни.
Самое страшное, что можно сделать – нанять в команду неподходящего человека. Час – очень короткое время для хорошего собеседования, круто, что автор поста успевает :)
Отдельно однако, рассмешил скриншот в пункте «Вообще-то это требуется на практике». Почему чуваку кажется, что CAP-теорема нужна только для создания своей базы данных? По большей части она применяется для анализа уже существующих распределенных систем. Или ему кажется, что хоть CAP, хоть создание собственной СУБД, хоть монадные трансформеры — это все одинаковый космос и выдумки очкариков, чтобы отвлечь айти-работяг от эпической битвы реакт вс ангуляр?
По зрелому размышлению вопрос в открытой формулировке «А что вы думаете о CAP-теореме?» вполне нормальный для человека, который будет проектировать хоть что-то распределенное. Хотелось бы узнать читал ли кандидат хоть какую-нибудь теорию по предмету. К сожалению, парней «от сохи», осваивавших предмет методом тыка в проектировании распределенных систем ждет много неприятных сюрпризов
Тема безусловно пережёванная, но воз и ныне там, отсюда и статья. =)
На Яндекс я повлиять не рассчитываю. В конце концов, у них очень свои кейсы и своя атмосфера. Я скорее пытаюсь сказать людям, что «вы — не Яндекс».
Ситуация с CAP-теоремой двоякая: с одной стороны — да, из этого можно приготовить интереснейший диалог про подкапотности баз данных. С другой стороны — зная, как интервьюеры обычно используют такие вопросы… (фигово используют, обычно даже бинарно: ты либо ответил, либо нет).
зная, как интервьюеры обычно используют такие вопросы…
Ну тогда вопросы не к вопросам, а к интервьюерам?
Как в анекдоте про стеклянный хрен.
Среагировал на фразу. Вообще Яндекс тоже не во всем Яндекс ) Их успех заложен в 2000-х годах. И с тех пор они мало полезного дали миру разработки, в отличии от того же Фейсбук. Хотя попытки были, да.
Мне больше интересен взгляд соискателя. Так вышло, что профессионально проходить собеседования научился раньше, чем стал разработчиком. Вы и сами знаете, что хитрые задачки не ставят целью получить правильные ответы. Банальное «оценить способность к рассуждению» часто является целью.
Но бывают наниматели, которые меряют соискателей по себе. Имею в виду технических лидов. Причем, подготовившись и зная ответы на свои хитрые вопросы, они оценивают соискателя на предмет «достоин ли предстать их светлы очи».
Пусть они умны, но такие ожидания, имхо, от недостатка жизненного опыта. Ты берешь человека, и скорее всего, будешь растить спеца под свои специфические потребности. То есть тебе нужна способная заготовка. Или тебе нужен универсальный специалист? Тогда при чем тут хитрая задача? Поменяйтесь местами с соискателем, и он задаст две подобных задачи, на которых у нанимателя не будет ответа.
Справедливости ради, я не часто встречал такое отношение, и оно не раздражает в случаях, если:
— вижу, что на позицию действительно требуются специфически подготовленные по теме люди. Например, это могли бы быть исследования в части поиска Яндекса, или тестирование безопасности у Касперского.
— компания столь шикарна, что за дверями очередь супер-профи соискателей. Но HR любой топ-компании скажет, что такой очереди нет.
— Хороший тимлид ищет человека, очень совместимого с ним. Позицию не разделяю, но понимаю.
В остальных случаях скорее сочту, что менеджмент в компании гниловат, и, вероятно, досрочно закончу собеседование (соискателя никто не лишал такого права).
Хороший тимлид ищет человека, очень совместимого с ним
Люди ищут окружение с совпадающей точкой зрения и похожим уровнем компетенции. С сомнением смотрят на тех, кто лучше (можно ли мне у него научиться быть лучше?) и на тех, кто хуже (способен ли он научиться быть как я?). Ну не все конечно. Есть открытые для улучшения и есть готовые улучшать других.
В книге Tribal Leadership хорошее объяснение с примерами.
Почему чуваку кажется, что CAP-теорема нужна только для создания своей базы данных? По большей части она применяется для анализа уже существующих распределенных систем. Или ему кажется, что хоть CAP, хоть создание собственной СУБД, хоть монадные трансформеры — это все одинаковый космос и выдумки очкариков, чтобы отвлечь айти-работяг от эпической битвы реакт вс ангуляр?
Именно так им всем и кажется. А потом появляются
Подтверждение — продукты. Которые раньше хотелось использовать, а сегодня они скорее навязываются. Яндекс-карты/навигатор — пробки стали врать сильно, зато подсели таксопарки, яндекс-маркет — кнопка «купить», а ассортимент сужен и развития в фильтрах (которые как раз и нужны для адекватного выбора) — нет, и т.д.
Которые раньше хотелось использовать, а сегодня они скорее навязываются.
Вы видимо забыли засилье яндекс бара. И чут ьпозже в 9 из 10 софтин галочку для установки чего-то еще от яндекса. В плане навязчивости нынешний яндекс это намного лучше того что было. В остальном, впрочем, не спорю.
Ну с Яндексом всё просто. Туда по инерции ломятся сильные выпускники лучших вузов, стремящиеся работать в "самой крутой" компании в стране.
Как следствие — они находятся в конкурентной среде таких же талантливых работников, что занижает ЧСВ работников и усиливает ЧСН (чувство собственной некомпетенции). Это сдерживает зарплатные ожидания работников. Крытые программисты в мелких компаниях вполне могут зарабывать больше.
Ну и ещё один момент: большинство программистских задач — рутина, и Яндекс здесь — не исключение. Это пример того, как ожидание не соответствует реальности.
конторой по зарабатыванию денег
Как будто что-то плохое.
И, блин, просто убило:
-Я: Можно сначала я хотя-бы на листочке, на достке вообще не комильфо — шея затечет, рука устанет?
-Разраб ТОП ру-айти компании: Нет!
P.S. Еще и ЗП низкая.
UPD: Я не справился с тегом sarcasm :(
Ну это прямо идиотизм какой-то. В гугле, вон, уже давно дают ноутбук и печатай на нем. Правда, без подсветки и автодополнения, но и компилировать не просят. Просто удобная замена доске.
— Ок, остался тест на 180 вопросов.
— Ха, не, не хочу.
— Ну и ладно, когда сможете приступить к работе?
P.S. Банк был хороший, работать я к ним не пошел, конечно
А что, если цель всех этих вопросов про деревья и алгоритмы сортировки (подставить нужный вариант) не для того чтобы проверить формальное знание алгоритмов, а просто для выяснения, есть ли математическая "соображалка" хоть какая-то и оценить ход мыслей, формализацию задачи и т.д.?
А, нет, показалось.
Нет материалов, показывающих корреляцию таких вопросов про деревья с тем, как человек у вас потом будет перформить. (Зато есть материалы, показывающие, что такой корреляции нет — я даже в статье привёл).
Зато есть материалы, показывающие, что такой корреляции нет — я даже в статье привёлЗначительная часть вашей статьи опирается на это исследование, однако:
- Эта статистика только по тем, кто смог пройти собеседование, т.е. уже набрал какой-то минимальный балл. Если бы всех заваливших собеседование брали на работу и делали performance review через полгода-год, возможно статистика была бы совсем другой и корреляция нашлась бы.
- Сами performance review носят очень большую долю случайности и представляют собой огромную проблему в плане объективности процесса. Может быть, даже большую проблему, чем собеседования. По каким-либо формальным метрикам оценить производительность работника практически невозможно (не считать же количество закрытых тикетов или, боже упаси, строк кода), и все сводится к субъективной оценке твоим начальником. В итоге получается огромный разброс от команды к команде. А как известно, случайные данные не будут коррелировать ни с чем. В нашей компании вообще из-за этого отказались от формальных performance review с выставлением числовой оценки сотруднику.
Так что, я не думаю, что из этого ислледования можно сделать вывод, что собеседование никак не предсказывает будущую производительность труда.
<holywar>
Ну вот опять 25. Почему все постоянно пишут, что алгоритмы никому не нужны. Если они не нужны вам, чтобы делать сайтики, то это не значит, что они не нужны никому. Я вот ни за что не возьму на работу человека, у которого есть высшее профильное образование, а он не знает, как оценить сложность алгоритма сортировки. Или высшее математическое без умения перемножить две матрицы на доске. Оба этих навыка мне нужны примерно раз в месяц, то есть постоянно. Отсутствие базовых навыков говорит о полном нежелании разбираться в том, как всё устроено.
Ну и логические задачки тоже могут быть полезны. Далеко не всем и не везде, но обычно в команде нужен хотя бы один круто соображающий человек для решения нестандартных проблем. Дебаг редко воспроизводящегося бага — очень сложная логическая задача, иногда нужны не инструменты и опыт, а просто мозги. Разумеется опыт первичен, а алгоритмы и логика вторичны, если вам нужен работник прямо сейчас. А вот для джунов всё наоборот — можно научить умного интересующегося человека, но раскачать логику «опытному» программисту на грани невозможного.
</holywar>
и большинство («все» в вашей терминологии) действительно делают сайтики. что поделать.
С большинством проблема — оно создаёт стереотипы и ожидания. И такие вот статьи укрепляют стереотипы, что можно особо не учиться и пойти работать, обесценивают высшее образование и тд и тп. Может вместо выкидывания вопросов из собеседования лучше просто поднять общий уровень и научить решать эти задачи? Может так мы поднимем общее качество софта, которым пользуемся?
Потому что плохое качество софта много чаще вызвано иными проблемами:
- проблемами коммуникации
- качеством процессов QA
- недостатком опыта у CTO
- проблемами менеджмента
- видением руководителей/инвесторов
- условиями рынка
Высшее образование тут тоже не поможет, к сожалению, хоть многие на него и уповают. Разработка сугубо практическое ремесло, да ещё и устаревает с адской скоростью.
Может вместо выкидывания вопросов из собеседования лучше просто поднять общий уровень и научить решать эти задачи? Может так мы поднимем общее качество софта, которым пользуемся?
но качество софта не связано с теоретической подготовкой в математике. или в другой «большой» науке. даже недостаточную подготовку по алгоритмике и железу я не могу назвать Главной Проблемой, Которую Надо Решать.
проблема в том, что нет именно инженерных дисциплин разработки софтверных систем. есть теория, которая простирается от высшей математики до конвейеризации вычислений. и есть миллионы программистов, пишущих плохой код (и создающих плохие системы). и между этими явлениями нет связующего звена. нет того, что позволяет однозначно ответить на вопрос «как решить мою задачу с вот этими параметрами?». из этого все сложности с наймом.
и это естественно, это из-за молодости всей сферы. я даже сходу не могу придумать какую-то другую сферу деятельности, в которой у человечества было бы настолько мало опыта. только понимая это, можно адекватно оценивать всё происходящее: рандомный найм, чехарду технологий, громоздкую архитектуру, пахнущий код, падающие приложения и сервисы…
Если я попаду к вам на работе и там надо умножать строчку на столбик каждый месяц — через пару месяцев я буду делать это свободно без гугла.
Но я не попаду к вам в компанию, потому что не пройду собеседование, т.к. не вспомню что матрицы умножаются строчкой на столбик.
Так еще и большинство школ с ВУЗами этот смысл не преподают, а отдают в виде «вот вам строчка на столбик».
Поэтому ждать, что соискатель на программиста сможет объяснить истоки матриц или кватернионов — бессмысленно. Большая часть не сможет. Даже те, кто регулярно использует.
Вы вот об этой книге? Давно хочу добраться до чего-то с нормальным объяснением того, что проходил в ВУЗе, но найти что-то достаточно понятное и не занудное чтобы не бросить на первых страницах пока не получалось.
В компании попроще список технических вопросов предсказуем, по моему скромному опыту спрашивают везде примерно одно и то же.
Насчет отличить зубрилочек, у многих даже не стоит такой задачи. Если пошли вопросы в таком духе, интервьюер с высокой вероятностью и ожидает ответа по учебнику.
Или высшее математическое без умения перемножить две матрицы на доске
А либы, либы то на что?
Как по мне, так более важной проблемой является как раз незнание/непонимание более абстрактных сущностей (специфичных для программирования), как принципы и подходы (GRASP/SOLID/<подставьте нужное>), зачем нужен рефакторинг, зачем бить проект на модули и пр.
Потому как если нужно перемножить матрицы, человек может почитать вики и научиться этому за час (а лучше подключить либу). А если нужно понимание, зачем нужна высокая модульность и почему не нужно всю логику лепить в один объект, то на это может уйти год и более.
Для программиста на первом месте не знания, а умение эти знания получать.
Потому как если нужно перемножить матрицы, человек может почитать вики и научиться этому за час (а лучше подключить либу)
Если внутри проекта вам нужно это сделать только один раз, то вы потратите гораздо больше времени на поиск и подключение этой либы, чем на написание и тестирование кода, если вы знаете, что такое матрицы и как их перемножать. Плюс лишняя зависимость — плохо.
Ну и в моей области (обработка изображений) практика показывает, что человек, который умеет жонглировать OpenCV, scipy и т.д, но не способен самостоятельно написать велосипед, профнепригоден. Он не понимает, как устроены эти функции под капотом и не способен решить нетривиальную задачу.
Зависит от задачи, никто не спорит. Речь шла про проект, где такие задачи возникают раз в месяц… а может вообще никогда. А вы приводите пример про обработку изображений. Понятно, что если ты каждый день работаешь с двумерными массивами, то подобные знания реально нужны.
И опять же, говоря про либы, я, конечно не говорил про OpenCV, драйверы и прочую "низкоуровщину". Умение сделать элегантный костыль или построить эффективный велосипед одинаково поощряется на низком уровне (абстракции) и порицается на высоком.
Абстракции это очень важно, но это два ортогональных навыка: абстракции программирования и математическая подготовка.
это два ортогональных навыка: абстракции программирования и математическая подготовка
Зависит от задач, вестимо. Если векторная алгебра и есть предметная область вашей программы, то наверное разработчику будет неплохо ее знать. Уж точно это не будет минусом.
А в приведенном вами примере это именно отсутствие умения получать знания, о чем я писал выше. Встретив непонятную задачу, человек поленился разобраться в предметной области, а написал велосипед на основе того, как понял. Даже знай он ответ именно на этот вопрос, накосячил бы в другом месте так же.
А в этом случае даже беглое гугление дало бы ответ, как это сделать правильно. То есть, как правильно умножать матрицы, или какую либу для этого использовать.
это два ортогональных навыка: абстракции программирования и математическая подготовка
На любимом тут Функциональном Программировании без хорошего знания математики, а именно лямбда-исчисления и всего с ним связанного, ничего толкового не напишешь.
Работать с готовой базой данных можно и без знания реляционной алгебры, но вот архитектору проектирующему базу её знание — крайне полезно.
тут скорее наоборот, проследите за собеседованиями в «топ-100» компаний. Умение разбивать на модули, и прочим архитектурным решениям, можно научить, и учат.
А вот есть «что-то такое»*, чему учить сложно, а может и дорого.
* Научить учиться, например.
А вот есть «что-то такое»*, чему учить сложно, а может и дорого.
* Научить учиться, например.
Я про это и написал же
Для программиста на первом месте не знания, а умение эти знания получать.
Не совсем про гуглеж, но отчасти и про него.
Я про то, способен ли человек, встретив новую для себя задачу, самостоятельно разобраться в ее предметной области и выбрать подходящее решение. Гуглеж здесь — только инструмент для получения информации. Вопрос еще и в том, сможет ли человек эту информацию грамотно использовать, а также сможет ли заглянуть "за рамки" задачи, чтобы решение было гибким и устойчивым, а не "в лоб".
А то бывают люди с отличной теоретической базой, но как доходит до чего-то нестандартного, так сразу ступор и "нас этому не учили".
И вот отсюда вопросы на собеседованиях, сможет ли человек «дойти» до решения сам, без помощи зала. Хотя пускай и с залом, но сам.
Фух, пришлось спалить контор, а то некоторые соискатели могут думать, что такими нерелевантными вопросами проверяют их память и насколько хорошо они когда-то зазубрили.
Да, ваша формулировка гораздо точнее описывает то, что я хотел сказать.
Тогда и вопросы на собеседовании и можно разделить на в. про "знать решения" и в. про "уметь находить решения". Первое, по-идее, требуется компании для получения краткосрочных выгод в ущерб долгосрочным, второе — наоборот.
Не знаю открою ли я опять тайну, сказав, что опытные компании комбинируют оба подхода на проверку знаний и навыков, а еще есть общие вопросы про «жизнь», которые бывают важнее технической части. Ну и еще важным этапом собеседований — это референсы, может конечно не у нас, не знаю к сожалению ли.
Количество специфических знаний растёт, сложность продуктов тоже. Сужается специализация.
Ко всему прочему последние 25 тысяч лет еще и мозг уменьшается.
Использовать готовые решения других людей — это ключ к прогрессу, который идет последние 10 тысяч лет. Знающие всё, но по чуть-чуть универсалы на рынке никогда не в цене.
Ну и известный факт того, что даже если взять такую простую вещь, как карандаш, то никто на фабрике, включая CEO, не знает, как от начала до конца произвести готовый продукт.
Знающие всё, но по чуть-чуть универсалы на рынке никогда не в цене.
… это потому что они там закупаются, а не продаются :-)
Про карандаш — некорректный пример. Знает как минимум технолог, возможно тех директор. Это же ежедневный процесс, он всегда на виду, всегда мониторится.
- Собеседование ведёт хозяин бизнеса или тех лид — работа моя
- Собеседование ведёт побарабанщик на зарплате — моя морда не достаточно красива/упитана/украшена/утатуирована/улыбается
тоже новояз какой-то?)
Американизм — американский сленг, кочующий в другие языки.
Так что деление как раз по языковому признаку.
Не соглашусь. Вонь можно перетерпеть, к ней можно привыкнуть, объективно она не страшна. Токсичность же уничтожает то, чего касается, обычно подразумевается что медленно, но верно. Ее неправильно терпеть, от нее нужно избавляться пока повреждения не слишком велики. Синонимом могла бы быть кислотность, но в таком смысле это слово я не встречал ни разу, никто просто не поймет.
И в данном случае предполагается именно мой вариант — подразумевается, по крайней мере я так понял идею автора, что такие практики собеседований не просто некрасивы или вызывают раздражение, но и наносят реальный вред.
Прямой вред компании, и косвенный, за счет уменьшения доступных мест — работнику. С одной стороны для работника это меньшая проблема, но при определенных условиях это все-таки проблема. Например если у кандидата нет опыта — большая часть компаний которая готова его взять будет так себе.
Ну и вообще раздражает же терять время на собеседования в таких компаниях. Если есть шанс изменить ситуацию, то почему бы не попытаться? Насколько я понимаю пост именно поэтому появился.
Но все-таки — вы согласны что слово "токсичные" здесь может подходить лучше чем "вонючие"?
… вы уж определитесь, мальта вы или кипр, а если вы действительно такие good guys, вам бы регулятора по серьёзней, ибо конкурентные преимущества то вроде бы есть, но 10k$ слать на кипр как-то стрёмно…
Сейчас объясним, зачем все это нужно. Набор и стоимость услуг для двух вариантов абсолютно одинаковые и не зависят от юрисдикции. Однако при открытии счета с минимальным депозитом мы предоставляем клиенту юрисдикцию на Кипре, поскольку она предлагает страховку до 20 тысяч евро. Мальтийская юрисдикция не дает подобной страховки, поскольку для открытия счета необходима категоризация клиента как professional, а это в свою очередь предполагает более строгие требования к клиенту.
Так что, как видите, нет никаких поводов опасаться за средства, когда они застрахованы надежным европейским регулятором. Если есть еще какие-то сомнения, вы всегда можете пообщаться со своим персональным менеджером, задать вопрос в нашу поддержку или почитать FAQ.
Ответ от HR:
Бывает так, что в процессе подбора условия меняются (разработчики и сами наверняка с таким сталкивались). Увы, Константин как раз попал в один из таких этапов. HR извинялась за долгую обратную связь. К сожалению, не всё проходит идеально, но мы работаем над тем, что бы прокачать процессы в этом плане. Постараемся больше не вызывать подобного опыта у соискателей.
Те, которые дают, никогда не пишут «ну, мы взяли парня который оказался чуть получше, собеседовался за час до вас».
Обязательно напишут… Что-то вроде того что выше.
Те, которые дают, никогда не пишут «ну, мы взяли парня который оказался чуть получше, собеседовался за час до вас».
Мне как-то написали. К той компании у меня после этого претензий не было никаких.
Мне кажется наиболее правильным описывать причины отказа только кандидатам, которые заинтересовали вас и которые чуть хуже того, кто прошел
Мне кажется наиболее правильным описывать причины отказа только кандидатам, которые заинтересовали вас и которые чуть хуже того, кто прошел
Что за дискриминация?
Соискатели могут отказываться от других должностей по той причине, что ждут вашего ответа.
Элементарный ответ «Извините, вы нам не подходите, желаем удачи в дальнейших поисках.» — это всё, что требуется. Нет надобности расписывать причины. Но сообщить кандидаты, чтобы он дальше мог планировать свою карьеру — это просто вежливость.
Я лично считаю, что FizzBuzz как раз-таки на удивление неплохой тест для начала диалога. :) Почитайте Джеффа Атвуда про это:
Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".
Most good programmers should be able to write out on paper a program which does this in a under a couple of minutes. Want to know something scary? The majority of comp sci graduates can't. I've also seen self-proclaimed senior programmers take more than 10-15 minutes to write a solution.
https://blog.codinghorror.com/why-cant-programmers-program/
Уверен алгоритм они напишут легко.
Правда я отлично проектирую и делаю распределённые нагруженные системы. Но вот первую линию обороны, где есть for — я не прохожу…
Не важнее, если производительность важна.
Да, но в условии задачи производительность не требуется. Придумывание самому себе в задаче дополнительных сложностей — отдельный и очень интересный факт о кандидате.
Такие кандидаты редкость и обычно результат их работы (в купе с менеджером) — это из коробки работающая система, поражающая точностью и скоростью, не требующая допилов.
Читабельность кода — важнее производительности
Из-за такого подхода и виснут постоянно интернет-браузеры — потому что каждый "умник" считает, что "производительность не важна" :(
PS Мне в прошлом году пришлось с матами разгребать несколько тысяч строк тормозного кода, который выглядит очень красиво и читабельно, но жутко тормозит. После оптимизации запрос исполнявшийся около часа, стал выполняться за пару минут.
Вот такое было недавно
const f = 'Fizz', b = 'Buzz', fb = f+b;
const pattern = [,,f,,b,f,,,f,b,,f,,,fb];
for(let num = 1; num<=100; )
for(let i = 0; i < 15 && num <= 100; i++, num++)
console.log( pattern[i] ? pattern[i] : num );
Постойте — это и есть вывод предазполненного массива.
Не всегда обязательно жертвовать читабельностью
Нооо… ведь этот код дурно пахнет!..
А что именно вам «пахнет»? (мне интересно).
В части строк нет пробелов, в части есть, по конвенции пробелы должны быть:
for(let num = 1; num<=100; )
for(let i = 0; i < 15 && num <= 100; i++, num++)
Здесь:
console.log( pattern[i]? pattern[i]: num );
наоборот лишние пробелы внутри скобок. Рекомендуется делать так:
console.log(pattern[i]? pattern[i]: num);
Так же по конвенции любой цикл, даже с однострочным телом, рекомендуется брать в фигурные скобки. Соответственно, из-за отсутствия скобок внешнего цикла нет отступов во внутреннем.
Кроме того, плохим тоном считается инициализировать переменные в одной строке, как то:
const f = 'Fizz', b = 'Buzz', fb = f+b; — тут опять нет пробелов вокруг '+'.
Возможно, Вам мои замечания покажутся придирками, но, как правило, это стандартные требования к оформлению кода.
Конвенция JS совпадает с конвенцией Java.
Насколько существенны были бы эти нарушения, если бы вы вели собеседование и принимали решение о приёме на работу?
for(var i = 0, j; i < 100; i += 15)
for(j = 0; j < 15 && i + j < 100;)
console.log(',,,F,,B,F,,,F,B,,F,,,FB'.split(',')[++j] || i + j);
True statement that should give you pause: Fizzbuzz is one of the most important technical advances ever by industry regarding hiring.
— Patrick McKenzie (@patio11) May 17, 2017
И да, если уж вам не нравится физз-базз писать, то ответьте на вопросы из моего комментария. Как ещё вы можете проверить, что человек умеет писать код, если он не будет при вас писать код?
Я не имею ничего против написания кода, я только против написания его там где никогда его не пишу и не буду писать за пределами собеседований. Откуда у меня появится навык писать код на бумажке если я этого никогда не далал? Относится это не только к доске/бумажке но и к предложениям писать его в виндовом блокноте, например.
Таки да, когда я разговариваю с людьми я пользуюсь человеческими языками :) Если нужно что-то пояснить до уровня «как оно работает» — простенькие блок-схемы да доске/листочках, но уж точно никак не код.
В конторе, где я проработал четыре месяца, был формальный запрет на комментарии в коде на человеческих языках.
Типа, фразы на человеческих языках имеют склонность толковаться неоднозначно, особенно — если язык комментариев неродной для программиста. ЯП же однозначен и заведомо знаком программисту не хуже родного.
Это просто самодурство начальства. То как разработчикам удобно делать свою работу должны решать разработчики, как максимум — те из начальства кто сам с ними этим занимается (ведущие разработчики, тимлиды).
Про однозначность ЯП могут утверждать разве что люди которые никогда не программировали (чего-то сложнее hello world). Точно так же — если человек программирует на ЯП много лет, вовсе не значит что он его поймёт так же как его понимают все остальные, передаю паменный привет нашим индийским коллегам…
Отладить код FizzBuzz?
Но в случае с FizzBuzz там же самые основные конструкции языка используются. Не должно быть никаких пробелм. Вы же цикл, например, без всяких IDE сразу синтаксически верно пишите? Так зачем вам IDE.
for (const i = 0; i < 100; ++i) {
if (i % 3 === 0) {
console.log('Fizz');
} else if (i % 5 === 0) {
console.log('Buzz');
} else if…
}
здесь я замечаю что что-то идет не туда, и начинаю зачеркивать на бумаге. А еще, ну какой const i? Конечно же let. Да и нумерация должна начаться с 1 а не 0. (Я потратил всего 15 секунд, не страшно)
Вторая попытка
for (let i = 1; i <= 100; ++i) {
let a = i % 3;
let b = i % 5;
if (a === 0 && b === 0) {
console.log('FizzBuzz');
} else if (a === 0) {
console.log('Fizz');
} else if (b === 0) {
console.log('Buzz');
} else {
console.log(i);
}
}
Пробуем…
Получилось.
Следующий шаг — перестать работать на результат.
Ну и на тему «мне это не нужно в работе» не хватает ссылки на статью Джоэля о текущих абстракциях.
UPD Ссылка на Козулю — это прекрасно, конечно
ЗА 15 лет в программирования я ни разу не видел, чтобы кто-то писал свой алгоритм сортировки.
Сам писал чисто ради интереса. Практической надобности никогда не было.
Про алгоритмы сортировки я знаю только потому, что шерстил эту тему когда готовился к собеседованию на интересный мне проект…
Обычно, стандартные реализации такого не позволяют, а бывают случаи, когда необходимо сортировать несколько массивов, где ключи в одном массиве, а данные в нескольких других (такой вывернутый на изнанку формат хранения может очень упростить векторизацию кода и дать существенные преимущества по скорости). Общего то итератора у них, понятное дело, нету, как и тривиального swap, поэтому стандартные реализации тут не применимы.
Пожалуй, необходимость сортировки такой структуры — это единственный (из тех, что я помню) случай в моей практике, когда мне пришлось модифицировать код сортировки, а не использовать стандартный std::sort.
Но, чтобы найти подходящую для модификации сортировку все-таки лучше иметь представления о существующих вариантах, чтобы случайно не взять пузырьковую :)
Кстати есть еще ситуации, когда понимание алгоритмов будет полезно. Есть алгоритмы не основанные на сравнениях — поразрядные сортировки (radix sort) и они могут работать за линейное время, что эффективнее традиционных сортировок на сравнениях (правда у них может быть больше константа, по этому на маленьких наборах данных поразрядная сортировка может проигрывать).
По этому, если мы имеем подходящие данные, то зная об этом можно попробовать взять поразрядную сортировку и получить прирост производительности ничего не меняя в основном алгоритме.
Обычно, стандартные реализации такого не позволяют, а бывают случаи, когда необходимо сортировать несколько массивов, где ключи в одном массиве, а данные в нескольких других
Можно сделать массив индексов [0, 1, ..., n - 1]
и сортировать его специальной функцией compare, которая смотрит в другие массивы. А потом применить полученную перестановку во всех остальных массивах.
Судя по минусу, не все поняли, о чём речь. Вот пример реализации идеи:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
template <typename T>
void permute_with(const std::vector<size_t>& perm, std::vector<T>& v) {
using std::swap;
const size_t n = perm.size();
std::vector<bool> visited(n);
for (size_t i = 0; i < n; i++) {
size_t prev = i, next = perm[i];
visited[prev] = true;
while (!visited[next]) {
visited[next] = true;
swap(v[prev], v[next]);
prev = next;
next = perm[next];
}
}
}
int main() {
std::vector<std::string> keys = {"four", "eight", "fifteen", "sixteen",
"forty two"};
std::vector<int> values = {4, 8, 15, 16, 42};
std::vector<size_t> indices(keys.size());
std::iota(indices.begin(), indices.end(), 0);
std::sort(indices.begin(), indices.end(), [&keys](size_t l, size_t r) {
if (keys[l] < keys[r]) return true;
return l < r;
});
permute_with(indices, keys);
permute_with(indices, values);
for (size_t i = 0, n = keys.size(); i < n; i++) {
std::cout << keys[i] << " => " << values[i] << "\n";
}
return 0;
}
if (keys[l] < keys[r]) return true;
return l < r;
Это, конечно, неправильно. Хотел сделать стабильную сортировку, должно быть так:
if (keys[l] < keys[r]) return true;
if (keys[l] == keys[r]) return l < r;
return false;
В нем даже не обязательно переставлять данные реально, если это не требуется, а можно использовать массив перестановок для получения реальных индексов данных.
P.S. Мне кажется или предложенный Вами алгоритм перестановки имеет квадратичную сложность?
Мне кажется или предложенный Вами алгоритм перестановки имеет квадратичную сложность?
Нет, сложность линейная, это довольно просто показать: ни из одной позиции своп не происходит больше одного раза благодаря массиву visited. Каждый раз, когда мы входим в цикл while, из перестановки вычёркивается один цикл.
Чтобы закручивать шурупы нужна отвёртка, а забивать гвозди — молоток.
Я предпочитаю работать с упорядоченными данными. Редко когда нужно вызывать sort(anything).
n_th_element(begin(), begin() + 500000, end()) — Тут элементы 500 000 – 500 200 гарантированно будут справа
partial_sort(begin() + 500000, begin + 500200, end())
А что за алгоритмом Вы пользовались, если не секрет?
Обычно, стандартные реализации такого не позволяют, а бывают случаи, когда необходимо сортировать несколько массивов, где ключи в одном массиве, а данные в нескольких других
nth_element
обычно использует вариант quickselect, которых относительно хорошо (O(N log N)) ведёт себя на патологических входах. Я бы предпочёл его наколенной реализации.
partial_sort
использует сортировку кучей, Для первый M результатов достаточно (M * log N + N) операций.
Справедливо для обеих сторон.
Тесты в Яндексе работают в качестве фильтра от дурака, а так же проверки на заинтересованность.
За время своей работы так же пришел к тому что важно вопросы на собеседовании приблизить к повседневным задачам на проекте, по этому считаю что человека нужно собеседовать на проект а не «проверять универсально».
Обычно я ещё даю кандидату небольшое тестовое задание (от силы на пару часов работы) максимально приближенное к реальному проекту. И прошу его сделать в течение недели. Оставляю ему свою электронную почту куда он может слать вопросы по мере выполнения задания. Этим я убираю стресс, так как человек работает в удобной для него обстановке в удобное для него время. Обычно по вопросам присылаемым мне на почту уже можно многое сказать о кандидате. Потом, если он все таки сделал задание (кстати тут отсеивается сразу процентов 50 кандидатов), мы беседуем с ним по его коду, он рассказывает почему реализовал все так а не иначе, что новое изучил в процессе выполнения задания.
Пока ещё (тут я стучу по дереву) все принятые мной кандидаты оправдали возложенные на них надежды и даже превосходили мои ожидания
Как по мне, как раз пример неадекватности, на которую сетуют в этом теме.
Большая часть специалистов не готова бесплатно писать тестовое задание.
Про то что у многих людей нет времени на тестовые ни дома ни на работе, я уже и не говорю.
Хотя есть компании, которые решили делать скрининг именно тестовым заданием на первом этапе, чтобы не тратить время технарей.
У них больше общего.
- боятся воды;
- тарахтят;
- сидят долго без дела, иногда приносят пользу;
- хорошо относятся к поглаживаниям, плохо — к постукиваниям (при исправной работе);
- имеют тактильно-визуальный интерфейс;
- юзер думает, что ими управляет;
- кормятся сами, достаточно лишь иметь источник питания;
- умеренно ремонтопригодны;
- не любят паденй со 2-го этажа, но со стола — не сильно недовольны.
1) 5-10 минутный звонок, общались о погоде, спорте и т.п, чисто что-бы составить общее впечатление и проверить знание языка (компания из европы). Программирования не касались, ибо зачем если список кейвордов есть в моем CV.
2) Мне дали необходимый доступ, к коду и списку задач, я начал работать за деньги (полный оклад), выполнил несколько задач включая одну/две из списка нерешаемых/сложных.
3) Через неделю от старта меня начали оформлять в компанию.
Итого, минимум потеря времени (и денег) с обеих сторон, нет глупых голоболомок и т.п.
В любом случае он выполнил какую-то работу для компании, это гораздо выгоднее других вариантов так как и компания деньги не зря потратила и человек рабочие задания пощупал и понял что ему делать будет нужно.
Я вот не пойму. Неужели концепция сортировки пузырьком настолько сложна, что забывается так быстро? Там ведь всего один if. Я это прочитал ещё в детстве и не забыл до сих пор, хотя реально писал сортировку последний раз лет 20 назад.
Или алгоритм Дейкстры для нахождения пути в графе. Там такой примитив в основе, что забыть это невозможно, хотя разумеется можно забыть само название.
Туда же разворот списка в памяти: если вы знаете что такое односвязный список, вы сможете его развернуть — это не рокетсаинс. И если у вас в резюме написано, что вы знаете C/ASM, но не можете сказать что такое односвязный список, то это как-то странно.
Обычно я такие вопросы задаю, чтоб начать разговор, зацепиться за общие знания (я ведь тоже не все алгоритмы знаю). Единственно я никогда не прошу писать код на бумажке (да я сам не напишу). Просто словами, знаками, иероглифами прошу рассказать алгоритм.
Неужели концепция сортировки пузырьком настолько сложна, что забывается так быстро?
Нет она просто настолько бесполезна в реальной работе. Это нормально забывать то, чем не пользуешься.
И если у вас в резюме написано, что вы знаете C/ASM, но не можете сказать что такое односвязный список, то это как-то странно.
Не уверен про С, но за все время программирования на АСМе я ни разу не писал ничего похожего на связный список. Конечные автоматы, что-то еще, но связный список то в нем зачем? Что это такое я конечно знаю, но точно не из АСМа
Ну да, асм-асму рознь. Если контроллеры программируешь, то со структрами за пределами стека скорее всего не столкнешься.
Единственно я никогда не прошу писать код на бумажкеПомню, я в 2000г участвовал в зональной олимпиате по программированию, дак мы там на бумажках программы писали, не знаю как проверяющие это компиллировали, но я взял 1-е место :), а по поводу бумажек согласен.
Помнится в те годы чтоб победить в зоналке достаточно было знать как ТурбоПаскаль запустить. Интересно какие там сейчас задачи.
Как мне было обидно, что я упустил призовое место на краевой из-за того, что у меня этот паскаль заглючил и генерил не верный код....
Провел в паскале годы — и ни с чем таким не сталкивался.
Расскажите подробнее?
Я тогда был молодым и глупым и не умел пользоваться дебагером (паскаль пользовал 3 месяца как, а до этого басик). Ну в общем вижу программа не работает так как ожидается, хотя она простенькая строк так в 300, со всеми отступами. Начинаю дебажить: код паршивый, как пользоваться дебагером не знаю, ну и вставляю writeln через строчку. Нахожу замысловатое условие, которое даёт false, а должно true. Сто раз пересчитываю на бумажке, сверяюсь — ничего: на бумажке тру, в паскале false. Пытаюсь разбить условие, чтоб понять какая его часть не сходится с ручным расчетом: выкидываю условия которые совпадают с бумажкой, оставляю, то что дает не верный ответ. Прихожу к парадоксу: условие типа a>3 даёт false при a:=4
Вот прям такой код (за синтаксис извинйте, я уже непомню его)
writeln(a);
if a>3 then writeln("Here");
Дает на выходе
4
Я как умная Маша сначала решил, что это я отлаживаю через задницу и просто что-то не так (ну не может же turbopascal врать). Короче трачу ещё минут 20 и осознаю, что все же нет, дело именно в условии. Ну дальше подход опытного школьника: выключить-включить. И о чудо, заработало! Я потом в документации к TP 7.1 нашел какие-то упоминания об ошибках в IDE сильно похожих на мою ситуацию (на краевой был TP7.0), но за давностью лет уж не помню подробности.
А беда в том, что на все эти изыскания я потратил время (порядка 40 минут), которого мне не хватило на заведому известную мне задачку.
Раз в год я участвовал в мейлрушном AI Challenge, и каждый раз приходилось вспоминать разницу скалярного/векторного перемножения векторов (а так же кто из них dot, а кто cross). Я хорошо помню зачем оно мне надо — чтобы рассчитать взаимодействие движущихся объектов исходя их векторов их скоростей (отталкивание, притягивания, столкновения и пр) и помню что это делается через «произведение векторов». Через 5 минут «освежения памяти» я все это вспоминаю и использую. А вот так вот спроси меня посреди рабочего дня — растеряюсь и не вспомню.
И так со многими вещами. Не кодил год на Си — подзабыл синтаксис typedef для функций. Быстро посмотрел примерчики — вспомнил. Долго java не использовал — подзабыл формат pom.xml. Не писал ничего околоигрушечного — подзабыл геометрию (формулы расстояния от точки до прямой и т.д.). Но могу в сжатые сроки «восстановить» свопнутый контекст.
Ну спроси я вас на собеседовании перемножение вектов и получи примерно вот такой ответ, как выше, мне бы этого хватило ибо вы явно понимаете о чем речь, хоть и не помните.
Попросите разработчика спроектировать тиндер или убер. Обсудите с ним частые проблемы в работе с очередями, сериализацией, сокетами.
А что если я скажу тебе, что в компаниях, которые на собеседовании спрашивают сортировки, графы и О-большое, на работе придётся* заниматься сортировками, графами и О-большим?
* Так же часто, как аналогичному разработчику в EXANTE приходится проектировать аналоги тиндер или убер.
* мнение автора комментария может не совпадать с мнением ТС.
Я воспринимаю посыл статьи, как неадекватность компаний в технических интервью. Хотя на моем опыте не сталкивался с такой «неадекватностью», всегда приятно поговорить о вечном.
Не, но кандидаты страдают тем же, думая, что они настолько хороши, что могут себе позволить собеседоваться в хорошие компании, в надежде, что их оценять их личные качества, амбиции и желания. Чем черт не шутит.
Вы вот вправду предпочли бы чтобы на собеседовании в Гугл вас бы спросили о частых проблемах систем, которыми пользуются миллиард пользователей?
Если бы я пришел в гугл на позицию инженера высоконагруженных систем — да. Точно лучше обсуждения книги по алгоритмам, которую я прочел на первом курсе универа и никогда не использовал. То же и про автономные автомобили. А если вы туда пришли на позицию джуна, студентом на стажировку например, то решать вы будете все равно более простые задачи и обсуждать тоже стоит именно их.
Да нет же, конечно я это понимаю. Это вы почему-то считаете что предлагается проверять конкретные очень специфические вещи. Правильно — взять реальную задачу, выкинуть из нее специфику, присущую конкретно работе здесь и обсуждать ее. Впрочем можно даже специфику не выкидывать — проверяется не опыт в решении именно таких задач, а подход человека к их решению.
Поэтому я могу не знать конкретных подводных камней в разработке конкретно гуглHibernate, но я должен иметь представление об области и понимать с какого края подходить к задачам, с которыми я буду сталкиваться. В идеале я должен знать хотя бы о части подводных камней, но это, конечно не всегда возможно. Иначе я бесполезен для данной компании.
Если я прочитал книжку об алгоритмах и могу их рассказать, то это совершенно не значит что я в состоянии придумать алгоритм решения задачи. Это даже не значит что я в состоянии вспомнить нужный алгоритм, если мне придется это делать (придется ли?). А вот если я могу рассказать как начать решать конкретную задачу, то я однозначно могу начать эту задачу решать, просто по определению.
А если вы попытаетесь совсем выдрать задачу из контекста и сформулировать в простом и наглядном виде, то и выйдет та самая стандартная задача на алгоритмы, которую дают в Фейсбуке или Яндексе.
Не всегда. Не случайно один из важнейших принципов в программировании — декомпозиция. Разбить большую задачу на мелкие подзадачи с набором условий возможно почти всегда, а когда невозможно, то появляются подозрения в ошибках архитектуры. Что тоже возможно, и иногда с этим приходится работать, впрочем. А раз возможно декомпозиция, то вполне нормально взять одну из таких мелких задача, немного обезличить ее чтобы не попасть под НДА, если это актуально и задать ее. Ну да, это делается не за 15 минут, к собеседованию интервьюверу нужно готовиться не меньше, а то и больше чем кандидату, но во всех областях и продуктах с которыми я сталкивался это было возможно.
Да, какой-то контекст нужен, бесспорно. Но, если собеседуется не джун без опыта, то обычно это человек, который уже имеет опыт в предметной области и ему знакомые базовые понятия и принципы. Что, кстати, и проверяется такой задачей в том числе. Если же человек утверждает что у него 6 лет стажа, но при этом не понимает стандартных вещей из предметной области, то что-то тут не так, не находите? Даже если у него были очень специфические и узкие задачи в весьма необычном коллективе, то это уже как минимум значит что он не интересуется индустрией в целом, что наводит на какие-то мысли. Хотя, конечно, могут быть исключения и только по этим признакам судить нельзя.
Во-первых, критикуют викторины, которые к типовым задачкам не относятся. Во-вторых, уайтбоардинг написание пузырька не получается при декомпозиции ни одной из задач с которыми я сталкивался в работе. А критикуют именно его. Также не получается разворачивание дерева или поиск зацикленности в односвязном списке, которые тоже любят спрашивать. Не получаются стандартные задачи, особенно, если учитывать бэкграунд. Еще раз — если я приду на позицию инженера высоконагруженных систем, то я однозначно должен знать хоть что-то об этой области. И это можно учитывать при постановке задач.
Вы статью вообще читали, которую комментируете?
- викторины («Какая функция библиотеки X обладает особенностью Y?»)
- головоломки («Вас уменьшили до размеров 5-центовой монеты и бросили в блендер. Ваш вес уменьшился так, что плотность вашего тела осталась прежней. Лезвия начнут вращаться через 60 секунд. Ваши действия?»)
- вайтбоардинг («whiteboarding» — когда код требуется писать на маркерной доске)
- алгоритмические («Разверните бинарное дерево на бумажке»)
- Викторины («Разверните бинарное дерево на бумажке», «Найдите кратчайший путь в графе») — плохи тем, что в них совершенно не надо думать. Ты или знаешь алгоритм, или нет
- На подумать («Дана матрица из 0 и 1 размера NxN, найдите самый большой по площади прямоугольник из 1 за как можно меньшую сложность», «Дана матрица размера NxN, в которой все строки и все столбцы отсортированы по неубыванию, найдите в ней число за O(N)») — хороши тем, что не требуют знания большого количества алгоритмов (обычно только ну самых базовых), зато нужно хорошенько подумать, как эти алгоритмы тут применить. Ну и шансы встретить уже знакомую задачу гораздо ниже
Вот по моему опыту, как раз всякие Google, Яндекс и иже с ними задают обычно алгоритмические задачи второго типа, а мелкие фирмы, пытающиеся просто следовать за трендом без понимания сути — первого.
Ну замените сортировку на разворачивание бинарного дерева из знаменитого твита (поправьте меня если перепутал алгоритм). Это много поменяет? Или вы не верите создателю Homebrew что его именно это на собеседовании в гугл спрашивали? Ну и викторины в гугле тоже были. Сейчас вроде уже нет, но были точно.
Ну а создатель Homebrew может быть отличным менеджером или визионером, но средним инженером. Видать не на ту позицию он в Google хотел.
Невероятно, но сами Google признали, что нет корреляции между тем, как кандидат показал себя на собеседовании, и тем, как он прошёл затем перформанс-ревью в процессе работы.
Ну это-то как раз не невероятно, а ожидаемо. У входного собеседования и перфоманс-ревью совершенно разные задачи и разные критерии для оценки.
Я ему возразил: «А вдруг понадобится рассчитать длину цепочки ДНК? Получается программист должен и биологию знать?»
Мне кажется, все эти вопросы по высшей математике или о внутреннем устройстве алгоритмов спрашивают только те, кто потратил время на их изучение и теперь ищет куда приткнуть полученные знания, демонстрируя кто здесь Альфа-программер: «Этот новичек даже второй закон Кирхгофа не знает… а вдруг завтра понадобится?»))
Мне кажется, все эти вопросы по высшей математике или о внутреннем устройстве алгоритмов спрашивают только те, кто потратил время на их изучение и теперь ищет куда приткнуть полученные знания, демонстрируя кто здесь
Это фундаментальные знания, которые в отличие от очередного новомодного фреймворка не устареют.
Вы из тех кто на собеседованиях устраивает допрос про доскональное знание очередного фреймворка?
Вроде, одного человека не придумавшего ничего лучше, чем устроить, в своё время, допрос на доскональное знание MFC (Microsoft Foundation Classes).
пожилым тимлидом, который сокрушался, что нынешнее поколение программистов не знает физику
Это означает, что он изначально был электронщик, переквалифицировавшийся в программиста. Для электронщика — это важно.
Я ему возразил: «А вдруг понадобится рассчитать длину цепочки ДНК? Получается программист должен и биологию знать?»
Если бы у нас были биологические компьютеры, то для аналога электронщика — это было бы действительно крайне важно.
Для меня важны паттерны и читабельность кода, но эти вещи напрямую связаны с программированием. Если стоит задача написать биржевого робота, то понимание всяких свечек, спредов и прогнозирование цены уж точно не должно входить в обязанности программиста. Для этого есть экономисты, которые консультируют программистов и помогают им перевести эти алгоритмы в программный код. Это мое личное мнение и я не претендую на то, что так должно быть везде. Мне просто кажется это самым адекватным подходом.
Математика — это не узкая предметная область, математика — это абстрагированные знания, которые можно использовать применив к конкретной предметной области.
Алгоритмы — это не то, что нужно тупо вызубрить, алгоритмы — это то, что программист должен уметь понимать и применять.
важны паттерны… эти вещи напрямую связаны с программированием
Они имеют такое же практическое отношение к работе как и знание алгоритмов — вполне можно успешно писать рабочий код не зная ни одного паттерна (лет десять назад я и термина такого никогда не слышал).
=> так что вопрос на знание паттернов по сути ничем не отличается от вопроса на знание пузырьковой сортировки.
PS алгоритмы — тоже напрямую связаны с программированием, потому написание программы на императивном языке программирования — это есть ничто иное как запись алгоритма на языке программирования.
Зачем заучивать реализацию?! O_O
Достаточно понимать принцип её работы.
Что будет являться достаточным пониманием принципа ее работы?
1) Она возвращает минимальное число из предоставленных аргументов;
2) Она возвращает минимальное число, действуя по алгоритму (далее идет описание алгоритма)
Ни 1, ни 2 не достаточно (в предположении, что описан алгоритм, а не реализация). Достаточное описание должно содержать контракт в том или ином виде (граничные условия на параметры и результат), описанное поведение при неверных параметрах.
Примерно так это можно делать, эмулируя проверку типов/интерфейса в JS:
numericAscendingSort(isValidNumber(arrayOfValues)));
PS: лично я не понимаю вопросы типа «а что будет если функцию вызвать с неверными аргументами?». Неважно что будет. Надо просто ее вызывать правильно)
Например, я ищу корни квадратного уравнения, с использованием функций арифметических операций. Я хочу, чтобы моя функция, получив неверный вход (например, один из коэффициентов равен NaN), выдала в качестве ответа NaN как флаг ошибки (ну вот удобно мне так). Если бы я не знал, что арифметические операции, получив на вход NaN, тоже выдают NaN, я бы написал что-то вроде
if (std::isnan(a) || std::isnan(b) || std::isnan(c)) {
return std::nan();
}
// Собственно, решение задачи
Но поскольку я знаю, как себя ведут арифметические операции, получив на вход NaN, я могу эту проверку просто опустить, получив более читаемый код.
Точно так же, если, например, я знаю, что функция для некорректного входа выкинет исключение, я могу никаких проверок перед вызовом не делать — оно поймается или приложение упадет, все довольны (ну, если я использую исключения в этом проекте). А вот если она выдает undefined behavior, проверка 100% необходима.
Но поскольку я знаю, как себя ведут арифметические операции, получив на вход NaN, я могу эту проверку просто опустить, получив более читаемый код.
Более читаемый для того, кто тоже с ходу помнит, как себя ведут арифметические операции, получив на вход NaN.
Второе правило Zen of Python гласит: «Explicit is better than implicit.»
вопрос на знание паттернов по сути ничем не отличается от вопроса на знание пузырьковой сортировки
Не совсем. В отличие от конкретных алгоритмов паттерны применяются значительно чаще в разных местах. Знание описания паттернов значительно увеличивает эффективность коммуникаций в команде — не нужно расписывать как ты что-то сделал или как предлагаешь сделать, достаточно сказать название паттерна и все в целом получили общее понимание. Естественно этого не всегда достаточно, но уже это способствует эффективности коммуникаций. Так что вопрос про известные паттерны — это фактически попытка понять насколько эффективно можно с этим человеком общаться в команде.
Интересно читать комментарии вроде: «я Senior Angular Developer и такие задачи оторваны от практики и вообще оскорбляют мои религиозные чувства...», «да это только студенты помнят...», «да уже же всё давно реализовано...» и т.п.
Я может быть сейчас скажу очевидную вещь, но эти задачки просто проверяют способность человека думать и решать проблемы. Большую часть из них вообще можно оторвать от конкретного языка программирования. Ты можешь, например, забыть какие-то свойства красно-чёрных деревьев, но их всегда уточнить в том числе и на собеседовании. Грубо говоря, никто (окей-окей, зануды, почти никто) на собеседовании не хочет проверить помнишь ли ты число пи до n-ного знака, интереснее знаешь ли ты что это и зачем, и сможешь ли при необходимости использовать. Ход твоих мыслей, варианты решения, вопросы которые ты задаёшь — это реальная ценность таких собеседований. Причём, максимальная оторванность от технологий и языков — это плюс. Технологии меняются, и человек с соответствующим уровнем инженерной культуры и мышлением без труда в них разберётся.
Вопрос только в том, кто нужен компании: обезьяна для решения бизнес задач, которая гуглит и копипастит или разработчик. Пока абстракция не потекла или страничка не начала загружаться два часа (потому что кто-то написал 6 вложенных for'ов :)) и рендеринг тормозить, можно говорить, что базовые знания не нужны, но вот когда это случится, знания очень даже пригодятся. Я при этом не хочу сказать, что гуглить это плохо, не думать и не понимать при этом, вот что гораздо хуже.
И ещё раз, это не просто какая-то ненужная в 99% случаев теория. Это фундаментальные знания, которые формируют тебя как профессионала и влияют на твоё мышление.
Только вот комментирующие забывают, что способность думать и решать проблемы сильно зависит от окружения и эмоционального состояния. Многие программисты — интроверты. И в условиях стресса покажут гораздо ниже результат, чем то на что способны. Так что я полностью согласен с автором статьи.
Устраиваем с кандидатами тестовый день рабочий. То есть они реально приходят на 1 день поработать в команде
Я бы послал тех, кто такое предложит, поскольку ради туманного обещания прерывать на день свою работу, это мягко говоря…
(Помню, как один гандон, предлагал на него пару месяцев бесплатно поработать по вечерам после основной работы в качестве испытательного.)
статистика такая, что тестовому дню рады все
Это какую Вы зарплату предлагаете, что такое предложение начинает благоухать как бесплатный сыр?! (насколько у вас там зарплата выше обычной?)
PS такое предложение стоит принять, только, если сидишь без работы и маешься от безделья.
И такое предложение на один день я принял будучи выпускником без работы.
Мне лично нравятся собеседования, на которых спрашивают алгоритмы и просят писать код. При этом я совершенно не считаю себя экспертом в алгоритмах, уж больно область широкая.
Мне кажется, критикующие неправильно понимают, что именно проверяется на таких собеседованиях. Проверяется вовсе не знание конкретных алгоритмов, а умение решать нестандартные задачи с помощью компьютера и писать простой понятный код.
Никто не ожидает, что вы решали задачу раньше или даже сходу знаете, как её решать, скорее наоборот. Интересно понять, как вы приходите к решению, как вы размышляете, как структурируете код, как его проверяете. Для решения большинства задач нужно знать лишь базовый минимум (сортировка, простейшие структуры данных, хэширование, обходы графа и бинарный поиск).
Является ли знание конкретного фреймворка важным? Я в этом сомневаюсь. У меня есть друг, которого я считаю очень умным парнем, и который очень переживал, когда устраивался моим коллегой. Потому что он никогда не работал с языками и базами данных, которые у нас использовались. Думаете, это повлияло на его продуктивность? Нет, он очень продуктивен, потому что он быстро учится (в частности, на код ревью) и логически подходит к решению новых проблем.
Запись кода на доске, а не в IDE, тоже имеет смысл: я лично чаще читаю код в браузере (например, код ревью чаще всего проходит в браузере). Безусловно, современные инструменты сглаживают разницу, но умение понимать код и пользоваться "внутренним интерпретатором" (а не внешним отладчиком IDE) я считаю очень важным для программиста.
P.S. На мой взгляд, создатель Homebrew сильно переоценивает значимость своего проекта в инфраструктуре Google.
Один из вопросов, который ему задали на интервью, звучал как «are you an ass man or a boob man». =)
Гибкий еврейский ответ с юмором, устраивающий любую из сторон :)
Такой вопрос он не столько про конкретный ответ, сколько про реакцию.
Если вы, например, устроите кипиш на тему сексизма (у вас есть такое право), контора может решить, что вы не впишетесь в их коллектив (у них есть такое право).
Ну, вполне возможно что человека вообще рекрутер нашел, а не он сам написал. Не факт что эта компания ему вообще нужна, но послушать что она может предложить — почему нет, может и зацепит.
Так что не обязательно, что _ниже предела ожиданий.
При собеседованиях в крупных конторах решение принимается коллегиально и/или многоуровнево.
Помню когда работал в гос.структуре, то народ принимали по простой схеме:
1 — я должен был найти кандидатов, кадровики мне помогали, но толку было мало.
2 — я предварительно с ними общался по скилсам, озвучивал вопросы по документам и т.п. (бюрократия мне была важнее скилсов, мне проще было человека подтянуть чем согласовать изменение в ДИ через министерство/главк). Общение буквально минут пять, на ходу.
3 — приводил кандидатов в отдел кадров, зав.кадрами (тетка умная, хоть и вредная) с ними общалась. Если она людей зарубала, то я говорил «мы вам позвоним», и провожал, если нет, то вел в отдел, наливал чай-кофе, конфетки, и болтал на профессиональные темы.
4 — когда набирался пул тех кто не был забракован, мы с кадровичкой садились и пересматривали анкеты оставляя 2-5 человек с нашими пометками, которые уже шли со мной на примем к начальнику. Реально это была уже формальность ибо по факту ни один начальник ни разу не завалил того кто подходил и мне и кадровичке, максимум спрашивал «ты точно уверен что _девочка_ справится?», но теоретически тоже могли бы валить. Но по честному мы учитывали систему ценностей конкретного начальника, так что вероятно это хорошая работа кадровички а не «сговорчивость» трех начальников.
Я собственно к чему? Конкретный кандидат должен попасть под ожидания ТРЕХ разных человек. И в реальности если человек будет исключительно хорошим кандидатом в моих глазах, то 99% что Борисовне он не понравится. И наоборот. Так что проходили только те кто был средним по всем трем шкалам.
Сам помню проходил собес аналитиком в банк. Текучка там была страшная. Первым этапом устраивали викторину. В целом оно было уместно — загнали 50 человек в зал, зачитывали вопросы (или тесты выдавали, не помню) — урезанный IQ плюс упрощенный жираф в холодильнике (не совсем, но тоже еще тот Перельман). Отфильтровывали не слишком жестко, на второй этап проходили примерно половина. Тут уже нач.отдела общалась, совсем бегло. Вылетело еще человек пять, остальных двадцать повели на собес к зам.управляющего, где были тоже кадровик и нач.отдела (моя будущая начальница). Вопросы были на коммуникацию и по предметной области по работе. Викторин больше не было.
Но опять таки — ни один с высокими способностями хоть в чем-то, через это сито не пройдет, ибо надо сразу кучей качеств обладать. Собственно те кто прошел — самые толковые все равно ушли.
Я свалил через два месяца во фриланс, и за это время все крутые спецы ушли или в другой банк или вообще в ЕБРР. Вот честно — на их месте, с сегодняшним опытом, я бы сам себя бы не взял. У меня на лице было написано что я очень быстро свалю. Вероятно их подкупил «лучший результат теста за время его существования»… нафик такие олимпиадники…
если я как тимлид увижу в репозитории мёрдж-реквест с наколеночным обходом графа или кастомной реализацией квиксорта, я с вероятностью 95% отклоню такой реквест с пометкой чувак, найди готовую библиотеку.
Вам не кажется, что для того, чтобы «увидеть» в репозитории наколеночный обход графа или квиксорт, ну просто необходимо представлять, как они выглядят, как алгоритм?
Я полностью поддерживаю подобный подход к собеседованиям и наша компания его активно использует, но! Мне кажется, нужен баланс, и если для работы хорошо бы представлять, чем одна сортировка лучше другой, то ничего страшного, если на интервью дали практическую задачку на понимание.
Из опыта: у меня работали, давно уже, товарищи, которых, когда попросили проимпортировать два здоровенных CSV файла со связанной информацией в БД, рисовали алгоритм O(N^2), а потом ну очень долго удивлялись, почему же за 12 часов работы только половина проимпортировалась. И для них просто «вау!» было, когда на следующее утро показываешь, как можно сделать O(N) алгоритм (конечно, не используя O-large notation, чтобы не тянуть за собой всю теорию), который всю задачку сводит к каким-то 6 минутам пыхтения жесткими дисками… И, конечно, вопросы: «а как ты это придумал???» Ну вот, сейчас этому, говорят, и в школах учат…
Были, конечно, и обратные примеры, когда computer science PhDs воротили подобие Aho-Corasick поиска с пре-компиляцией регулярных выражений в задачке, в которой ообычный exec и grep отрабатывали за доли секунды.
Так что, фокусироваться, конечно же, нужно на практике. Если человек с «крутым» образованием, важно проверить, что он не усложняет решения и, грубо говоря, пользуется grep когда это работает. Если с «менее крутым» — то что не начнет изобретать неоптимальные вещи и реализовывать руками примитивный пузырьковый сорт, когда под рукой какой-то boost лежит…
Статья вышла радикальной просто поскольку целью я ставил сдвинуть вашу точку зрения, заставив задуматься. Здесь работает правило «чтобы огромный зал услышал вас со сцены, вам стоит кричать».
Такую задачу и именно для таких целей можно решить мысленно. Таких задач можно задать целых десять за пол часа-час собеседования и быстро оценить примерный уровень и даже знание стека технологий в разных направлениях. Пару раз был на таких собеседованиях. Это интересно и, что немаловажно, если получится включиться в задачи, то уже ничего не мешает.
С досками или кодингом за это время оценить что-то значимо нереально.
Когда вы даете объявление о вакансии, на него откликнется около 50 человек:
- 10 джентльменов удачи — эти парни ничего не знают и не умеют, но их привлекает высокая зарплата. На собеседование они пришли на авось (вдруг повезет), даже без надежды, что их примут. Этих ребят сразу видно по тусклым глазам и невнятным ответам, и принять их на работу может только полный неудачник.
- 10 суперменов, страдающих переизбытком квалификации — эти кадры хороши настолько, что сами понимают, что у вас им не место. Они умеют намного больше, чем вам надо, и просят намного больше, чем вы готовы дать.
- 20 ребят, которые крутятся около темы, но не имеют достаточного опыта. У них есть желание учиться и они способны освоить то, что от них требуется. Даже деньги их интересуют не столько, сколько возможность просочиться в профессию. Не прогадаете, если возьмете, хотя с ними поначалу придется немного повозиться.
- 10 толковых ребят, которых можно сразу садить за работу и они справятся с поставленными задачами.
Вот и выходит, что даже если вы сыграете в рулетку с последними 30 кандидатами, вы все равно получите правильный для себя результат, а про остальных просто забудете. В любом случае, вы никак на собеседовании не узнаете, как этот человек поведет себя через пол года и насколько эффективным будет его труд все эти пол года — от лени не застрахованы даже специалисты экстракласса. Так что какие бы вопросы вы не задавали, выбор все равно будет сделан на основании личных предпочтений/измышлений/предрассудков и в 99% случаев он будет правильным.
К тому же интервьюеры иногда бесят, задавая вопросы про регулярные грамматики и SOLID в мелкосошных конторах, которые никогда не занимались, не занимаются и не будут заниматься разработкой продвинутого софта. Встречаются и люди, которые слишком много о себе мнят и сами красуются вместо того, чтобы выяснять мой уровень знаний. Дико бесят.
Результат: работаю там, где «собеса» почти не было — так, посмотрели, спросили что-то. Я невнятно ответил. Дали задачу. И задачу я не решил! Но господа почему-то заинтересовались и взяли (о чудо!).
Но: в спокойной обстановке на вайтборде могу написать bubble sort и внятно рассказать о quicksort, когда расслаблюсь за кружечкой пива. В этом состоянии могу даже сказать связно более 2 предложений последовательно. Целых 3! Да, в 3 предложениях о quicksort! Pivot choosing, partitioning, recursion.
Проблема эта меня настолько взволновала, что я написал об этом в хабр: Нелегкая карьера программиста или чего хотят работодатели

Это мне напоминает «обман» визового центра с помощью бронирования апартаментов на букинге, а потом за день до поездки их отмену. Чтобы пройти в дамки, то есть попасть за границу.
Нечестная какая-то игра. Мы знаем ваши вопросы, а вы знаете правильные ответы. Ни то, ни то не используется в повседневной работе, но надо типа. Правила игры такие… SOLID, ACID, банда четырех…
Видимо, надо было дерябнуть до… и усугубить во время… :)
Даню не взяли в команду еще Павла Дурова, куда он действительно не подошел. Там нужен был определенный профиль людей, которые умели решать задачи поставленные в том числе на интервью. То что Даня под этот профиль не подошел не говорит, ни о чем. Ни о том, что процесс отбора в ВК был неправильный, ни о том что Даня плохой разработчик. Насколько мне известно, костяк команды Telegram все еще составляют люди, который могут и интерфейс запилить, и с хайлоадным бэкендом работат. И кажется, эти ребята прекрасно себя чувствуют.
Что касается, современной команды ВК, то Даня бы отлично к нам вписался. И мы, конечно, не задаем вопросы фронтам на собеседовании «как определить страну по IP». Так что мне кажется, что вся та дискуссия вырвана из контекста. Хотя я и не скажу, что наше собеседование просто пройти.
А если вы считаете, что конкретная команда кому-то что-то «должна», в плане выбора профиля/специализации людей, которых она ищет, то зря.
Нет, я вовсе не считаю, что конкретная команда чего-то должна.
Твит был приведён исключительно как утешающая иллюстрация: даже если человек не прошёл фильтр конкретной компании, на которую ставил все карты, очень вероятно, что успех ещё ждёт его впереди. (Просто не с этой конторой, а с другой.) Выбрал я этот твит, потому он яркий и потому что недавно попался мне в ленте. (Ну и ещё потому, что об Абрамове сейчас говорят даже гопники в подворотнях.)
Надеюсь, что теперь недоразумение улажено.
Правда я уже передумал уходить, так как работодатель меня на удаленку сплавил «когда хочешь». Но пойду, пособеседуюсь.
Личная статистика — 80% кандидатов на позицию сисадмина или сетевого инженера не могут ответить на вопрос что такое сетевая маска и зачем она нужна. Ни своими словами, ни чужими, ни примерами. С программистами еще хуже (я про Россию если что). Так что хватит ныть и вперед работать!
С программистами тоже беда. Утверждают, что пишут на каком-нибудь пайтоне, джаве и т. п. последние несколько лет, а fizzbuzz не осиливают
У меня несколько человек, говоривших о знании питона, на собеседовании не смогли даже for по списку написать. Как впрочем и самостоятельно сказать что же такое list в питоне. А это даже не fizzbuzz еще.
Написать fizzbuzz проще, чем нормально рассказать, что такое list в пайтоне и как он реализован. Если, конечно, не ограничиваться банальностью типа "динамический массив".
Меня вполне бы устроила банальность "динамический массив". Но по реакции человека было очевидно, что он не знает даже этого. Да меня даже ответ "массив" бы устроил, это был банальный фильтр как раз от таких людей.
Как обычный array list, см. https://hg.python.org/cpython/file/tip/Objects/listobject.c
А не разработчик CPython'а и не мейтейнер базовых python'овских пакетов в каком-либо дистрибутиве. Мне вполне простительно не знать, что они переехали) А в гугле у меня вообще по запросу cpython list первая ссылка на svn, но это в порнорежиме браузера xD В нормальном режиме уже на их repo на github'е.
Мы в Apache Tika, например, переехали на github как основной репозиторий с синхронизацией в git-wip-us.apache.org, но человеку не читающему dev@tika.a.o это знание не сказать, что сильно необходимо, патчи в jira спокойно принимаются ,)
Как-то предлагал вместо утомительных распросов о «поиске подмассива с заданной суммой элементов» и «разворота односвязного списка» отбирать людей по росту — брать только тех, кто выше 180см., так как корреляция такая же очевидная. Не прижилось.
«Как бы вы запроектировали X»
Я собеседовал немало людей, который отлично мне на high-level рассказали, как они красиво бы запроектировали и слова говорили правильные, а когда начинали писать код, то там была жуткая императивщина, забытые пограничные условия и весьма трудночитаемый код — 15-20 строк хватает, чтобы понять, что человек писать умеет плохо.
Да, в начале проекта будут бездумно копи-паститься решение со StackOveflow и будет казаться, что все хорошо, но потом полезут баги, а поддержка проекта будет очень сложной и дорогой.
Все это не противоречит тому, что многие интервью проводить не умеют. В whiteboard не вижу ничего плохого, и если кандидат не может вспомнить название функции — это вообще не проблема. А вот если у него код на 5 строк и там есть ошибка с выходом за пределы массива и он сам ее не находит даже после подсказки, то упс.
Ну и ещё вот моё личное мнение — я бы давал задачи на отладку. Потому что писать квиксорт по памяти — дело дурацкое, а вот искать, где в логике программы ошибка, из-за которой один раз в 10 дней всё падает к чертям — это задача гораздо более частая. Причём примеры можно прямо из кодбазы компании, из недавних факапов понабрать (если жалко показывать человеку без NDA продакшен-код — анонимизировать кусочки немного, свести до минимального примера). Даже джуниор должен хотя бы что-то знать о простейших техниках отладки и уметь читать чужой код хоть немного, а уж скажем лид — должен всегда быть готов прибежать спасать положение, когда на поиск ошибки джуниором уже два дня потрачено без видимых результатов.
А ещё важно умение задать Гуглу правильный вопрос, и среди тон хреновых ответов со StackOverflow найти нужный. Не знаю, как где, но в мобильной разработке из этого, кажется, 90% труда состоит — из выяснения, почему Андроид опять несёт чушь, хотя ты код чуть ли не из официальных туториалов брал. Причём по каждому вопросу на SO будет 50 ответов, и из них ровно 1 подходящий именно к твоей ситуации (это в хорошем случае). Чаще всего, это будет не первый ответ, а 4ый коммент к 5ому ответу в 3ей реинкарнации этого вопроса. Что удивительно, не каждый кандидат в программисты умеет искать и находить оные ответы! Вот это бы тоже неплохо проверять, правда, не особенно понятно как.
Причём по каждому вопросу на SO будет 50 ответов, и из них ровно 1 подходящий именно к твоей ситуации (это в хорошем случае).
И тот, что решает конкретно твою беду, будет иметь 0 голосов «за» :)
Это в контексте «вайтбординга» и алгоритмов.
Из рассмотрения выпали самые массовые группы разработчиков:
- Стажёры — нулевой опыт «промышленной» разработки; студенты технического вуза на профильном факультете.
- Джуниоры — «боевой» опыт до года или полутора лет; возможно, ещё студенты.
По опыту проведения собеседований, как раз на интервью с кандидатами из указанных групп на ура заходят задачи на алгоритмы и «вайтбординг». И польза от этого определённая есть, поскольку по ним можно оценить обучаемость и умение формулировать свои мысли.
Единственно, под «вайтбордингом» я больше понимаю псевдокод, схемы и рисунки, чем настоящий код.
Из наиболее востребованных качеств любого разраба добавил бы:
* умение находить общий язык с коллегами и общий уровень эмоционального интеллекта больше нулевого
* способность следовать принятым правилам вместо «я все равно знаю как лучше»
При достаточном уровне интеллекта и наличии мотивации, ответ на *любой* вопрос из упомянутых викторин гуглится/находится адекватным человеком за пару часов. Так что знание подобных ответов «на память» никак не показатель крутости кандидата. А незнание просто подтверждает факт, что память человека не безгранична.
И неужели «способность следовать корпоративным стандартам» важнее способности делать свою работу?
Сорри, наверное, пропустил какой-то список важных качеств, который выше где-то был…
Суперзвезду можно заменить только суперзвездой. Или восемью посредственностями.
При этом пока ты его заменишь — замучаешься восстанавливать то, что он «держал в голове со всеми нюансами», ведь как мы уже определились — «следовать корп.стандартам» он не умеет или не любит.
Я очень хочу себе суперзвезд которые сами работают так, чтобы их было легко заменить восемью посредственностями, но к сожалению я таких не смогу себе позволить оплачивать.
Времена когда эффективность была важнее поддерживаемости уже прошли.
Алгоритмы задают на интервью не потому что алгоритмы важны в работе. Их задают потому что из 100 кандидатов надо выбрать одного. В этом случае нужно использовать статистические методы. Вот есть у нас 100 человек, и 49 из них знают алгоритмы, а 51 нет. В первом множестве вероятность того, что случайно выбранный разраб будет хорошим выше, чем во втором множестве. Цена false negative невелика — ну отсеял ты хорошего разраба, ну и фиг с ним. Из сотни надо только одного.
Строго говоря, можно кроме алгоритмов взять другой критерий — ну например, отсеять людей без профильного образования. Или негров! Не потому что они плохие, а потому что среди них меньше вероятности найти хорошего разраба, а мы хотим искать в множествах с большими вероятностями.
Когда 100 человек на место — да, можно и так. Часто такие компании встречаются?
Но при этом именно гугл сказал что это неэффективно и нужно делать что-то еще.
В 2013 году. Вот статья. В обсуждаемой статье есть эта ссылка.
сравните с мучительными восьмичасовыми собеседованиями одной российской кампании
Знаю я эту компанию :)) и её многоэтапные бесконечные собеседования: особое удовольствие получил от написания кода в дурацкой вебморде без интерпретатора.
Важным является то, способен ли ты её понять и написать работающую реализацию.
Зачем? Зачем мне писать реализацию сортировки пузырьком, если я могу взять готовую сортировку из используемого фреймворка?
И даже если мне уж очень понадобится самописная сортировка, я скорее всего пойду искать оттестированую реализацию квиксорта (просто из-за того, что моя собственная оттестированной не будет)
Зачем мне писать реализацию сортировки пузырьком, если я могу взять готовую сортировку из используемого фреймворка?
То есть это:
слышал от нашего тим-лида, что есть люди, которые имеют привычку вместо написания кода гуглить подходящий код, а не найдя его могут глядя в глаза заявить, что "такое написать невозможно".
получается, что в точности про Вас!
Думаю в таком случае всё же лучше подойдёт модификация квиксорта: можно не сортировать предварительно отсортированные диапазоны, вышедшие за требуемый лимит.
И всё равно я попробую сначала найти готовую реализацию этой идеи перед тем, как писать свою.
https://habrahabr.ru/company/exante/blog/335096/#comment_10354038
Но это отличный пример, почему всегда нужно искать решение какой-то новой задачи: вы можете найти решение проще, чем придуманное вами.
Если проект большой и серьезный, то там и лямбды и полиморфизм и паттерны вылезают. Если в таком проекте поработать, то, рано или поздно, понимаешь и как эти лямбды страшные писать, и зачем семантика копирования нужна. Из stl еще повсеместно нужны set и map.
Сотни написанных программ (например, вот последняя: ссылка)
Вы уж извините, но такого уровня проекты дают начинающим PHP-шникам в качестве тестовых заданий) Ну ок, мидлам тоже дают. А когда они так пишут — с сырыми запросами и ассоциативными массивами (struct в C++) — то их на работу не берут.
Собственно, я о том, что раз вы пишете такие небольшие проекты, то понятно, что паттерны вам не нужны. Вы даже классами не пользуетесь, только структурами, хотя тут явно видны 3 бизнес-сущности. Есть 3 репозитория для них (*DatabaseEngine), где используется наследование, но оно как-то не особо помогает, все равно много копипасты. В больших проектах это не подходит, иначе потом никто не разберется. Поэтому и применяют разные средства организации кода и вспомогательные технические средства, и что-то даже попадает в стандарт.
Вы уж извините,
Не извиняйтесь. :) Мне крайне интересны советы и рекомендации.
Вы даже классами не пользуетесь, только структурами,
Честно говоря, я не понял, почему вы так решили? Там вся программа сплошь на классах. А структур там штуки три-четыре. Да и они ведь те же классы, только public.
все равно много копипасты
А вот что именно там копипаста?
Там вся программа сплошь на классах.Насколько я заметил, классы там либо заданные системой типа CDialog либо вспомогательные типа CSafeString, для бизнес-логики классов нет. Например, где-то должен быть метод типа assignTask(), обозначающий понятие бизнес-логики, либо в User, либо в каком-то TaskManager. Public или не public, кроме данных в структурах ничего нет, и у struct семантика все-таки другая, чем у class. Ну и в коде их побольше, чем 4.
Или почему в серверном коде используется CDocument_Main? Это же сервер, там нет пользовательского интерфейса.
Кстати, а вас SQL-инъекции в запросах не смущают?)
ReadSTaskInArray(ptr,offset,sClient.vector_Data.size(),sTask);
...
sql_request+=" WHERE (TaskGUID='"+sTask.TaskGUID+"')";
А вот что именно там копипаста?
void CUserDatabaseEngine_SQL::ResetBase(void)
{
CRAIICDatabase cRAIICDatabase(&cDatabase_UserList,UserListBaseInitString);
{
CString sql_request="";
sql_request+="DELETE * FROM ";
sql_request+=UserListTableName;
cDatabase_UserList.ExecuteSQL(sql_request);
}
}
void CProjectDatabaseEngine_SQL::ResetBase(void)
{
CRAIICDatabase cRAIICDatabase(&cDatabase_ProjectList,ProjectListBaseInitString);
{
CString sql_request="";
sql_request+="DELETE * FROM ";
sql_request+=ProjectListTableName;
cDatabase_ProjectList.ExecuteSQL(sql_request);
}
}
Например, где-то должен быть метод типа assignTask(), обозначающий понятие бизнес-логики, либо в User, либо в каком-то TaskManager.
Вот это я не понял, о чём речь. Что это значит?
Насколько я заметил, классы там либо заданные системой типа CDialog либо вспомогательные типа CSafeString, для бизнес-логики классов нет.
Там вот что сделано:
1) Сервер имеет пользовательский интерфейс. На сервере добавляются и редактируются данные пользователей — напрямую, оператором. Создан этот интерфейс с использованием технологии документ-представление. Вот откуда CDocument_Main. К нему обращаются и потоки и пользовательский интерфейс. Этот класс документа вызывает классы для работы с тремя базами данных (там есть реализация с SQL и реализация с прямым перебором базы данных).
2) Сервер создаёт потоки, которые и являются обработчиками клиентов. Это класс cthreadserver (общий поток ожидания подключения) и порождаемые им классы cthreadserverunit (обработчик отдельного клиента).
Кстати, а вас SQL-инъекции в запросах не смущают?)
Тут есть одна фишка — я SQL впервые задействовал. Я никогда с ним не работал. А в чём проблема с таким запросом? Я делал его по статье про запросы SQL.
Ну например вот
Но тут такая штука, что это разные классы. И именно поэтому им лучше не иметь общих элементов. Вдруг, я вообще какой-то из этих классов вместо базы данных на что-то другое переведу (например, на текстовый файл или ещё что — ну а вдруг?)? Поэтому тут ради гибкости классы сделаны полностью независимыми.
Вот это я не понял, о чём речь. Что это значит?
Это значит, что в проекте нет слоя бизнес-логики, она размазана по всей системе и теряется в технических деталях.
Возможно, я тут переусложнил, в случае простых CRUD действий assignTask() особо не нужен. Но должно быть место, где будут названия, используемые в предметной области и не будет деталей реализации типа SQL-кода или CRecordSet. И они должны быть в коде, а не в комментариях.
Например.
if (sTask.ForUserGUID.Compare(guid)==0
|| sTask.FromUserGUID.Compare(guid)==0
)
list_STask_Local.push_back(sTask);//это нам или наше задание
Вот то, что в if, надо вынести в метод isOurTask() или isUserTask() и куда-то этот метод поместить. Скорее всего в класс Task.
Вот откуда CDocument_Main. К нему обращаются и потоки и пользовательский интерфейс.
У вас должны быть общие компоненты, независимые от MFC или QT, к которым будут обращаться и потоки, и пользовательский интерфейс, и CDocument_Main, и который вы теоретически сможете подключать в другие проекты, например в службу какую-нибудь, где интерфейса нет.
А в чём проблема с таким запросом?
А что если в sTask.TaskGUID придет значение 123456' OR '1' = '1
?
Но тут такая штука, что это разные классы. И именно поэтому им лучше не иметь общих элементов. Вдруг, я вообще какой-то из этих классов вместо базы данных на что-то другое переведу
Но у вас все три класса работают с базой данных и наследуются от CIUserDatabaseEngine. Если DatabaseEngine вдруг начнет с файлами работать, это будет плохой код. Поэтому это не разные классы, это просто специфичные реализации. Если решите хранить в файлах, то все равно сделаете отдельный класс, где будет тот код.
И да, для этого как раз и применяются все эти интерфейсы и стратегии.
Факт в том, что в проекте много скопированного кода. Это говорит о проблемах в проектировании.
Это значит, что в проекте нет слоя бизнес-логики, она размазана по всей системе и теряется в технических деталях.
Почитал вот это (правда, кусочками). Вроде бы немного понял, что вы имеете в виду. Но смотрите, у меня есть класс документа CDocument_Main — он предоставляет методы для общей работы приложения — то есть, связывает графический интерфейс, потоки и базы данных между собой. Формально в нём и есть бизнес-логика. Дальше есть три класса, каждый отвечает за отдельные действия над пользователями, задачами и проектами. Каждый из этих классов уже работает с конкретной базой данных и инкапсулирует работу с ней. Вот в указанной статье предлагается со слоя этой самой бизнес-логики делать SQL-запросы. Не понимаю, зачем? Я наоборот скрыл базы от документа. Он понятия не имеет, с чем он работает. Потоки тоже не знают, что они делают. Они просто отрабатывают команды от клиентов, а документ сам знает, что нужно сделать, например, при переадресации задания. Структура программы получается прозрачная и состоит из законченных модулей со слабой связью между ними.
Но я в принципе понял, что вы советуете. Можно проверки из GUI поместить в документ.
Вот то, что в if, надо вынести в метод isOurTask() или isUserTask() и куда-то этот метод поместить. Скорее всего в класс Task.
Это возможно. Но вот насколько это будет лучше текущей реализации? Я не знаю, как сейчас, но десять лет назад всё-таки в книжках писали, не пытаться абсолютно всё представить классами. Сейчас, как я понимаю, советуют наоборот. :)
А что если в sTask.TaskGUID придет значение 123456' OR '1' = '1 ?
Такое возможно, если кто-то будет играть с протоколом обмена. Но как от этого защититься — я не знаю. Проверять, что TaskGUID действительно является числом?
Но у вас все три класса работают с базой данных и наследуются от CIUserDatabaseEngine.
Нет-нет-нет. У каждого из этих классов свой интерфейс. Они все наследуются от интерфейсов CITaskDatabaseEngine, CIProjectDatabaseEngine и CIUserDatabaseEngine, соответственно. Я так сделал, чтобы можно было менять реализации при желании. Эти классы уже конкретная реализация.
У вас должны быть общие компоненты, независимые от MFC или QT, к которым будут обращаться и потоки, и пользовательский интерфейс, и CDocument_Main,
Тут вот что плохо будет — CDocument интегрирован с GUI в MFC. У него есть возможность обновлять виды с помощью UpdateAllView. У стороннего отдельного класса этой возможности не будет — ему придётся знать о документе и вызывать его. А документу знать об этом классе и тоже вызывать его. Поэтому я оставил документ центральным элементом. Да, этим я привязался к MFC. Но весь GUI в любом случае здесь зависит от неё.
Но смотрите, у меня есть класс документа CDocument_Main… Формально в нём и есть бизнес-логика.
А если у вас будет служба, которая делает периодические действия с задачами? Вы туда копипастить будете?
Вот в указанной статье предлагается со слоя этой самой бизнес-логики делать SQL-запросы
Нет, там говорится что надо вынести бизнес-логику из хранимых процедур в приложение. Там не говорится, как ее в приложении организовать. Просто в результате работы всех низкоуровневых компонентов в базу пойдет тот SQL-запрос.
Я наоборот скрыл базы от документа.
Это правильно.
Можно проверки из GUI поместить в документ.
А это неправильно. Понятие "моя задача" связано только с задачей и пользователем, а не с интерфейсом и не с глобальным документом.
десять лет назад всё-таки в книжках писали, не пытаться абсолютно всё представить классами
Классами/объектами надо представлять то, что имеет состояние и связанное с ним поведение. Например, сущности предметной области. По техническим причинам можно сделать по-другому, но надо понимать зачем это надо, а не потому что в книжке написано.
Но как от этого защититься — я не знаю.
Экранировать строку или использовать именованные параметры. Ссылка про PHP, но они много где есть.
Честно говоря, это плохо, что на военной технике может быть такой код. Там ведь тоже связь есть.
Они все наследуются от интерфейсов CITaskDatabaseEngine, CIProjectDatabaseEngine и CIUserDatabaseEngine, соответственно.
Да, это я проглядел. Тогда это тем более неправильно. У вас есть механизм, но вы копируете код из-за того, что у вас вдруг реализация поменяется. Если вы будете хранить что-то в файлах, то вы реализуете CITaskDatabaseEngine в другом классе. Так зачем вам тогда копировать код?
У стороннего отдельного класса этой возможности не будет — ему придётся знать о документе и вызывать его.
Нет. Документ будет использовать сторонний класс.
GUI зависит от нее, но бизнес-логика не должна зависеть от GUI.
А если у вас будет служба, которая делает периодические действия с задачами? Вы туда копипастить будете?
Зачем? Она будет отдельным потоком и будет вызывать документ. Который этот поток, кстати, и запустит.
А это неправильно. Понятие «моя задача» связано только с задачей и пользователем, а не с интерфейсом и не с глобальным документом.
Задача — да. А пользователь — нет. Графический интерфейс у сервера обслуживает пользователя, а не задачу.
Классами/объектами надо представлять то, что имеет состояние и связанное с ним поведение.
Ни задача, ни пользователь, ни проект не имеют поведения — это просто элементы хранения данных. Поведение имеет тот, кто их использует. И он-таки класс.
Например, сущности предметной области.
Мне вот кажется, тут не более, чем вопрос вкуса. :)
Честно говоря, это плохо, что на военной технике может быть такой код. Там ведь тоже связь есть.
На военной технике (внутри) не применяют того, что не разрешено. А это МПИ (магистральный последовательный интерфейс) и CAN в основном. И никаких врезок в них не бывает и быть не может.
У вас есть механизм, но вы копируете код из-за того, что у вас вдруг реализация поменяется.
Нет, я копирую потому, что у этих классов разные интерфейсы. Возможно, множественное наследование (от интерфейса и класса работы с базой) поможет. Но вот тут я сразу не скажу, будет ли работать полиморфизм в случае такого множественного наследования — это вот как раз то, что я никогда не делал и понятия о нём не имею. Это надо смотреть отдельно.
Зачем? Она будет отдельным потоком и будет вызывать документ. Который этот поток, кстати, и запустит.
Я говорил про Windows Service, который работает постоянно, а не только когда оператор запустил программу.
Графический интерфейс у сервера обслуживает пользователя, а не задачу.
Он может обслуживать все сущности в системе, на то он и интерфейс. Факт в том, что в предметной области "управление задачами" есть понятие "моя задача", а понятия "CMainDocument" нет.
Ни задача, ни пользователь, ни проект не имеют поведения — это просто элементы хранения данных.
Это в вашей реализации они не имеют поведения. Есть понятия entity и value object. Грубо говоря, первый обычно передается по ссылке, второй можно передавать по значению.
Для хранения и передачи данных используются value object, из данных создается entity с поведением.
Можно использовать сущности без логики с публичными полями, тогда логика управления ими будет на уровень выше. TaskManager какой-нибудь или на худой конец один большой Engine. Но не класс для работы с UI.
В PHP в качестве value object часто используются ассоциативные массивы. Так часто пишут начинающие — с массивами и сырыми SQL-запросами, с "классами для работы с БД", почему я и сравнил. Такой код сложно понимать и поддерживать.
Мне вот кажется, тут не более, чем вопрос вкуса
Это вопрос правильного проектирования, понимания и дальнейшей поддержки, в том числе другими программистами.
И никаких врезок в них не бывает и быть не может.
А я не про врезку говорю. Может быть ошибка при формировании значения на клиенте. А логин например вообще вводится пользователем. Введет он специально построенный логин и перехватит управление удаленной техникой.
Нет, я копирую потому, что у этих классов разные интерфейсы. Возможно, множественное наследование поможет.
Это решается без множественного наследования, его вообще не рекомендуется использовать. Вы же сами эти интерфейсы делали, значит могли сделать один интерфейс, хотя бы для вещей типа ResetBase(). Еще наверно шаблоны здесь подойдут.
Вы ищете причины, чтобы не делать по-другому. Но причины здесь не важны. Есть много похожего кода, и от него можно избавиться. Как именно — дело десятое.
Я говорил про Windows Service, который работает постоянно, а не только когда оператор запустил программу.
А какая связь службы Windows и программы?
Он может обслуживать все сущности в системе, на то он и интерфейс.
Но список надо обновлять при изменении в базе пользователей (это в клиенте, скорее, чем в сервере — в сервере сам интерфейс задаёт изменение и знает, когда ему обновляться). Документ это умеет делать — он интегрирован с интерфейсом. А класс логики нет — он про документ ничего не знает. А потоки вызывать будут класс логики. И документ будет его вызывать. Сейчас документ и логика одно и то же.
Это вопрос правильного проектирования, понимания и дальнейшей поддержки, в том числе другими программистами.
Вот если почитать этот сайт, то тут на эту тему столько копий уже сломали! :)
А логин например вообще вводится пользователем.
Вот блин. Точно. Я и не подумал, что логин и пароль задаются ведь извне. Ну что ж, придётся сделать проверку на число в GUID. :)
Это решается без множественного наследования, его вообще не рекомендуется использовать.
Я поэтому его и не использую. :)
Вы же сами эти интерфейсы делали, значит могли сделать один интерфейс, хотя бы для вещей типа ResetBase().
Унаследовать интерфейсы от первичного с этим самым ResetBase? Хм, можно попробовать.
Вы ищете причины, чтобы не делать по-другому.
Не-а. Я как раз переделываю. :) Ну и попутно решаю, что стоит изменить, а что нет. Вот отдельный класс логики я пока решил не делать. А структуры заменить классами — заменил.
А какая связь службы Windows и программы?
Я же говорю, в таких приложениях служба может выполнять разные фоновые задачи — сложное удаление строк или файлов, рассылка писем, расчет статистики по ночам. То есть в службе как и в программе будут понятия Task, Project, User, но интерфейса и его документа не будет.
Но список надо обновлять при изменении в базе пользователей (это в клиенте, скорее, чем в сервере — в сервере сам интерфейс задаёт изменение и знает, когда ему обновляться).
А потоки вызывать будут класс логики.
Посмотрел повнимательнее. Так на клиенте обновление вызывается по таймеру раз в 100 миллисекунд.
OnTimer() - cDocument_Main_Ptr->Processing() - if (OnUpdateView) UpdateAllViews()
Потоки не вызывают обновление видов сами, они меняют переменную. Значит вам не нужен документ в потоках, вам нужно в документ и в поток передать одну ссылку на состояние документа. В состоянии списки сущностей и инстансы компонентов для работы с ними (TaskManager taskManager
). В поток пришло событие, поток поработал с сущностями, потом установил переменную.
Также надо учитывать, что на клиенте урезанная часть логики, только для удобства, вся работа делается на сервере. Например, на клиенте не будет поля user.password
.
Кроме того, не должно быть понятия "класс логики". Есть много компонентов, которые отвечают за взаимодействие сущностей, и это все слой бизнес-логики. В идеале каждый объект и процесс в ней соответствуют тем, что мы выделяем в реальности.
Унаследовать интерфейсы от первичного с этим самым ResetBase?
Еще унифицировать названия типа cDatabase_ProjectList
, вынести работу с CRAIICDatabase cRAIICDatabase
, cRAIICRecordset_ProjectList.GetMainObject().GetRecordCount()
и т.д. в родительский класс CDatabaseRepository, сделать 3 наследника в которых писать только специфичные SQL-запросы.
Еще можно по аналогии с названием таблицы сделать переменную с названием первичного ключа, а в User и остальные добавить методы getPrimaryKeyValue() и вызывать их в репозитории. Не уверен, насколько просто это сделать в C++, но тогда в репозиториях останется только конфигурация, ну и может пара переопределенных методов.
Я же говорю, в таких приложениях служба может выполнять разные фоновые задачи
Если я такое и буду делать, то это всё будет делать сам сервер — он всё равно работает постоянно. А у него с документом проблем не будет.
Так на клиенте обновление вызывается по таймеру раз в 100 миллисекунд
Верно. Но это костыль, от которого я бы хотел избавиться, но пока не знаю как. Причина простая — я не могу из потока вызывать UpdateAllView.
Есть много компонентов, которые отвечают за взаимодействие сущностей, и это все слой бизнес-логики. В идеале каждый объект и процесс в ней соответствуют тем, что мы выделяем в реальности.
Ну тогда в этой программе всё так и сделано. Базы сами не участвуют в логике — это делают документ (основа взаимодействия) и потоки.
Не уверен, насколько просто это сделать в C++,
Я ещё подумал и сообразил — наследование интерфейса бесполезно — нужно наследовать реализацию. В целом, тут можно всё это сделать вот как: интерфейс перестаёт быть чистым абстрактным классом и получает реализацию доступа к базе и виртуальные функции текущих интерфейсов. Но в этом случае выходит плохо — чистый абстрактный класс всё же предпочтительнее. В общем, тут надо хорошо подумать.
Честно говоря, это плохо, что на военной технике может быть такой код. Там ведь тоже связь есть.
Вот, кстати, любимое детище военных: ссылка Вот такая штука и работает внутри военной техники — соединяет блоки между собой, принимает и передаёт команды и данные. Все его возможности знают, наверное, только авторы. :) Этот интерфейс несколько подрывает веру в людей, если серьёзно — разобраться с его режимами и вопросами «зачем, зачем это сделано так?!» не так-то просто.
начинающим PHP-шникам
Но тут ведь не PHP. Тут Си++. Чистый. MFC+OBDC+Win32API+немного STL. На Delphi тоже ведь видеоплейер пишется просто — компонент ведь есть. А вот на Win32API написать видеоплейер (даже с DirectShow) уже совсем другое дело.
Но суть не в этом. Проект на 3 сущности, сделанный в одиночку, это не то место, где нужны лямбды и паттерны.
Я вам советую изучить веб-программирование. Просто узнаете другие подходы. Может будете применять в C++, может на другой язык перейдете, на котором такие проекты делать проще.
Кстати, а лямбды разве не способствуют этой самой копипасте? Вместо общей функции мы задаём локальную. И так везде, где она потребуется.
Я имел в виду современное программирование с базами данных. Зачем вам C++ для этой задачи? Основу такого проекта на PHP можно написать за пару часов, плюс пару дней-неделя на мелкие доработки. Просто это повысит эффективность вашей работы. В общем, если заинтересуетесь, фреймворк Yii 2 лучше всего подойдет.
Я не знаток C++, но подозреваю, что лямбды нужны как раз для тех функций, которые нужны один раз в конкретном месте, чтобы не засорять пространство имен. Еще они вроде бы локальные переменные родительского блока могут использовать.
но подозреваю, что лямбды нужны как раз для тех функций, которые нужны один раз в конкретном месте, чтобы не засорять пространство имен. Еще они вроде бы локальные переменные родительского блока могут использовать.
Проблема в этом случае в том, что такое «одно место» имеет тенденцию становиться не одним местом. :)
А если клиент отключится? Например, компьютер перезагрузился.
Нет особых проблем сделать это в браузере, есть push-уведомления и веб-сокеты, постоянное подключение для веб-страницы тоже необязательно. Разве что браузер можно просто закрыть. Ну не знаю, критично ли это, десятки таск-трекеров так работают.
А если клиент отключится? Например, компьютер перезагрузился.
Если клиент не успел передать данные серверу и компьютер просто перезагрузился, то, конечно, изменения потеряются.
Да, браузер закроют запросто. У нас Windchill стоит и её закрывают почти сразу, чтобы не мозолила глаза. :) У нас лет по 60-70 многим людям! :) Им этот браузер не нужен.
— У вас в коде возможна SQL инъекция. GUID, который читается из файла (settings.bin), т.е. может быть задан произвольно, напрямую подставляется в SQL запрос. Если бы вы использовали более высокоуровневый коннектор к базе, а не конструировали запрос вручную, ошибки можно было бы избежать.
— В коде присутствуют странные и непонятные вещи, например:
{
CEvent cEvent;
cEvent.ResetEvent();
WaitForSingleObject(cEvent.m_hObject,time_ms);
}
А вот здесь была попытка реализовать отправку данных с таймаутом по эвенту, хотя правильнее было бы просто задействовать WSAEventSelect.
{
on_exit=false;
long offset=0;
while(size>0)
{
if (WaitForSingleObject(cEvent_Exit.m_hObject,0)==WAIT_OBJECT_0)
{
on_exit=true;
return(true);
}
//узнаем как дела у наших сокетов
fd_set Writen;
FD_ZERO(&Writen);//обнуляем список
FD_SET(socket_server,&Writen);//добавляем сокет
fd_set Exeption;
FD_ZERO(&Exeption);//обнуляем список
FD_SET(socket_server,&Exeption);//добавляем сокет
timeval timeout;
timeout.tv_sec=0;
timeout.tv_usec=5000;
//спрашиваем, не готов ли сокет передавать данные
if (select(0,0,&Writen,&Exeption,&timeout)>0)
{
if (FD_ISSET(socket_server,&Exeption)) return(false);
if (FD_ISSET(socket_server,&Writen))
{
long ret=send(socket_server,package+offset,size,0);
if (ret==SOCKET_ERROR)
{
int error_code=WSAGetLastError();
if (error_code==WSAEWOULDBLOCK)//надо подождать
{
Pause(1);
continue;
}
return(false);
}
size-=ret;
offset+=ret;
}
}
else
{
return(true);
}
}
return(true);
}
— Низкоуровневость критиковать не хочу. Но лично я интерфейсы на MFC и голом WinAPI писать так и не смог и даже завидовал тем, кто умел это делать. Сначала я использовал Builder/Delphi, потом сразу перешёл на WinForms, хотя и поначалу плевался от .NET 1.1, предпочитая код писать на C++, а на .NET делать только интерфейсы.
> А вот на Win32API написать видеоплейер (даже с DirectShow) уже совсем другое дело.
А разве есть варианты написать полноценный плеер без использования DirectShow?
В коде присутствуют странные и непонятные вещи, например:
Разве это странная вещь? :) Обычное ожидание никогда не сработающего события. Точность невысокая и не больше кванта переключения потоков в Windows (62 герца вроде бы). Но больше и не нужно.
хотя правильнее было бы просто задействовать WSAEventSelect.
Сокетную часть не хотелось делать Windows-зависимой.
А разве есть варианты написать полноценный плеер без использования DirectShow?
Ну, смотря что называть полноценным. Так-то и для MS-DOS были видеоплейеры. А для Windows вроде бы winmm позволяет всё это сделать без DirectShow (у которого интерфейс та ещё головоломка) — но я этого не делал.
Так есть же функция Sleep.
> Сокетную часть не хотелось делать Windows-зависимой.
Зачем, если весь проект написан с использованием чисто виндовых технологий? А учитывая, что даже в функции отправки данных (SendData) используются виндовые функции и сущности WaitForSingleObject, WSAGetLastError, WSAEWOULDBLOCK, CEvent, ваше желание выглядит странноватым.
> Ну, смотря что называть полноценным.
Поддержку максимально возможного количества форматов и кодеков. Только с использованием DirectShow можно открыть всё, что угодно.
Так есть же функция Sleep.
Ну вот так вот было изначально давным-давно сделано. :)
Зачем, если весь проект написан с использованием чисто виндовых технологий?
Тут обратная фигня вышла: на самом деле, тут UNIX-код (точнее, из проекта для QNX) перенесён в Windows. :) И я подумывал собрать сервер под QNX, перенеся уже из Windows. Поэтому тут вышел некий компромисс.
Только с использованием DirectShow можно открыть всё, что угодно.
Ну так, конечно. :) Был бы кодек в системе. :)
Но программирование не стоит на месте и продолжает развиваться. Все новомодные языки программирования и технологии предназначены для повышения КПД программиста.
> Но вот что такое большой и серьёзный проект? Операционная система? Современная игра?
Сложно сказать. Наверное, проект, с большим количеством взаимозаменяемых разработчиков. Проект, где стоимость труда программистов является решающим фактором, и где повышение КПД программистов просто необходимо. Операционные системы и современные игры вполне сюда подходят.
> Я вот занимаюсь военной и космической техникой. Серьёзные ли это проекты?
В случае военной и космической техники вклад работы программиста в конечную стоимость продукта невелик, поэтому можно писать на чём угодно, лишь бы работало без ошибок. Да и плохо учёные программируют — они ж учёные, а не программисты.
> Да — если боеголовка улетит не туда, то последствия будут серьёзные. А вот большой ли — вряд ли.
Это просто цена ошибки, не более того.
Вы просто из другой эпохи. Вы нашли свою нишу, вас это устраивает, и вы попросту не готовы изучать новые технологии, потому что смотрите на них через призму своего опыта.
Эх, если бы меня это устраивало, я бы не хотел бы догнать уходящий поезд. :)
В случае военной и космической техники вклад работы программиста в конечную стоимость продукта невелик,
Да как сказать… На этапе НИР или НИОКР на самом деле, не меньше 10%. Но финальная работа изделия не получится без программы.
Да и плохо учёные программируют — они ж учёные, а не программисты.
Это делают не учёные, а обычные инженеры.
Даже не знаю, что посоветовать. Попробуйте C# или Java для десктопного программирования. Python не советую — после всей строгости C++ он будет вызывать сильнейшее отторжение.
Насчёт веба — не знаю. Но это совсем динамичная область, когда технологии успевают развиться, быть на пике популярности и потерять актуальность всего за пару-тройку лет.
> Да как сказать… На этапе НИР или НИОКР на самом деле, не меньше 10%. Но финальная работа изделия не получится без программы.
Ну вот о чём и говорю. Поделите суммарное время программирования в человеко-часах на общую трудоёмкость проекта — да даже меньше 10% будет. А когда доля программирования в проекте от 50% и выше, там без современных технологий никуда.
> Это делают не учёные, а обычные инженеры.
А что обычно делают инженеры? Если они программируют пару часов в неделю, их нельзя назвать программистами.
Даже не знаю, что посоветовать. Попробуйте C# или Java для десктопного программирования.
Не могу себя заставить. :) Я бы хотел, чтобы на выходе получался истинный x86 код. А так — ощущение, словно процессор теряет ресурсы напрасно. Вот я сегодня утром не смог комментарий написать. Я зашёл с ноутбука Celeron-1.7 768 МБ ОЗУ. Ужасно тормозит, Firefox 52 всё время твердит о застрявшем скрипте и предлагает его остановить, а кнопка «Отправить» не ожидает. Но в 2004-м этот ноутбук летал в инете. Я помню точно. А сейчас вот оно как.
А когда доля программирования в проекте от 50% и выше, там без современных технологий никуда.
Там именно трудоёмкость такая, а не сложность. Дело в том, что в военной автоматике (которая без человека часто) есть довольно сложные проблемы работы в условиях отказов. Вот тут можно застрелиться — работать должно как терминатор во второй части, когда ему ломом контакты перебило. И вот тут такая логика появляется, которую прозрачной сделать очень-очень непросто. И отладка может занять очень длительное время и быть весьма дорогой. Просто потому, что ситуации отказов аппаратуры нужно ещё предусмотреть и далеко не всегда это получается и с десятого раза. Отказ может быть вообще не полный — вроде работает, но как-то не так. :) Это такой ужас — не передать. :)
А что обычно делают инженеры? Если они программируют пару часов в неделю, их нельзя назвать программистами.
А они могут быть инженерами-программистами. :) Но попутно могут и схемотехникой заниматься. Одновременно.
аблсорт мне пригодился… НИ. КОГ. ДА
Пузырьковая сортировка — это просто простейший индикатор того учил ли человек алгоритмы вообще. И задав этот вопрос с вероятностью свыше 90% можно ответить изучал ли этот человек алгоритмы или нет.
И да, это вопрос на позицию джуниора :)
Когда приходит к тебе некто без опыта работы и показывает диплом, а ты пытаешься его проверить, что он вообще умеет и знает.
Задавать этот вопрос опытному разработчику, так же бессмысленно как спрашивать у математика таблицу умножения, которую он учил в первом классе.
PS бравировать незнанием этой сортировки — ещё глупее, чем задавать этот вопрос опытному разработчику.
Зачем оно мне? Я изучал все эти алгоритмы сортировки в конце девяностых.
Не помню я их.
Помню что есть варианты экономящие память, есть варианты экономящие время работы… Если меня спросить — напиши любой алгоритм сортировки, то я напишу пузырьковую, ибо как самая простая она первая в голову приходит. Но то что это именно пузырьковая я сейчас знаю только потому что прочитал это в данном топике, и через неделю опять забуду.
А еще я не помню синтаксис запросов CREATE/ALTER и даже UPDATE/INSERT.
Более-менее помню Select, и то UNION буду подглядывать.
Не потому что я тупой, просто если я оказываюсь в голом коде, без фреймворка, то первым делом я открываю документацию по нужной мне СУБД и пишу ORM. Ну а при ручном просмотре инструмент просмотра имеет мышередактор для базовых запросов, и мы их видим только постфактум, уже при выполнении.
Об архитектуре СУБД со мной можно пофилософствовать. Парсинг запроса, структура индекса, блокировки — худо-бедно, но сходу что-то расскажу. А запросы? Вот буду через год писать драйвера для тех СУБД которых нет в текущем моем ORM, тогда и прочитаю.
И забуду через неделю.
Нужна будет сортировка — забью в гугл «Алгоритм сортировки», перейду в википедию и узнаю все что мне нужно, включая то какое отношение имеет к обсуждаемой теме вот эта картинка:

А если заказчик захочет поэкзаменовать меня на знание сортировок, то специально для него, прямо в википедии возьму готовый алгоритм сортировки, и залью ему на продакшн.
int correct( int *arr, int size )
{
while (--size > 0)
if (arr[size - 1] > arr[size])
return 0;
return 1;
}
void shuffle( int *arr, int size )
{
int i;
for (i = 0; i < size; i++)
swap(arr + i, arr + (rand() % size));
}
void bogoSort( int *arr, int size )
{
while (!correct(arr, size))
shuffle(arr, size);
}
Я изучал все эти алгоритмы сортировки в конце девяностых.
Не помню я их.
А зачем Вам помнить их все?! O_O
А если заказчик захочет поэкзаменовать меня на знание сортировок
А Вы кто? Джуниор?
Вы кроме самого себя любимого читаете кто что пишет?
Я вот тут https://habrahabr.ru/company/exante/blog/335096/#comment_10354490 прямо в сообщении, на которое Вы, прямо тут, не читая ответили, написал:
это вопрос на позицию джуниора :)
Когда приходит к тебе некто без опыта работы и показывает диплом, а ты пытаешься его проверить, что он вообще умеет и знает.
Задавать этот вопрос опытному разработчику, так же бессмысленно как спрашивать у математика таблицу умножения, которую он учил в первом классе
PS если Вы и на это сообщение продолжите отвечать на то, что Я НЕ ПИСАЛ!
То извините, Вам с Вашей манией величия и голосами в голове с которыми Вы разговариваете — к доктору => https://geektimes.ru/post/288084/ & https://geektimes.ru/post/289069/
Таблицу умножения математик, да и просто грамотный человек вам в любом возрасте расскажет. Я половину таблицы не помню, но что не помню — мысленно добью сложением. А вот пузырьковую сортировку я не помню. Вернее помню что это словосочетание означает один из популярных алгоритмов, но какой именно — не помню.
Далее. По юниору.
Я буду сильно ругаться если у меня юниор будет из головы писать какую-то сортировку, даже если правильно. Или взять готовое из сети и подправить, или лучше не надо. Если интересно почему я против, то приведите мне блоксхему решения квадратного уравнения (гуглить можно), и тогда я отвечу.
- Вы мне мне приписали то, что я не утверждал.
- А затем "с успехом" опровергли то, что Вы мне приписали.
Я буду сильно ругаться если у меня юниор будет из головы писать какую-то сортировку, даже если правильно
=> то есть Вы тоже вот такой:
слышал от нашего тим-лида, что есть люди, которые имеют привычку вместо написания кода гуглить подходящий код, а не найдя его могут глядя в глаза заявить, что "такое написать невозможно".
После Ваших слов я твёрдо укрепился в мысли, что джуниоров нужно проверять на умение мыслить самостоятельно, а не надеяться как Вы на умение у кого-то списать, потому что может попасться ситуация когда списать не у кого.
И да, вопрос к джуниору не "напиши алгоритм сортировки пузырьком", а "отсортируй массив не обращаясь к стандартной библиотеке".
Просто "пузырёк" это самое простейшее из того, что может придти в голову.
1) вы не умеете внятно и однозначно высказывать свои мысли, что является плохим качеством для технаря
2) вы не способны провести элементарный дебаг собственных слов, даже после того как вас ткнули носом в вашу ошибку
3) вы истерически реагируете на замечания.
В принципе этого достаточно чтобы не продолжать разговор, но раз уж вы не поняли с первого раза то я разжую.
Любой математик ЗНАЕТ таблицу умножения или если даже что-то забыл то это не помешает ему ее назвать вслух мысленно заменив сложением. Это НЕ ЭКВИВАЛЕНТНО случаю когда опытный программист не помнит названия сортировок и тонкости классических алгоритмов в связи с тем что за те десятилетия что прошли с того времени как он их изучал.
На этом месте (а именно на различности этих примеров) крашится ваш концепт о том, что я опровергаю то чего вы не говорили.
Но дело даже не в этом. Главный посыл — юниору под страхом увольнения нельзя решать задачи требующие написания своего кода сортировки а не использования готовых методов языка. Это для вас первое что в голову приходит — пузырек. Мне первое что в голову приходит:
<?php
// Сортируем от большего к меньшему
class MySortZA extends AbstractMySort
{
protected function compareMethod($a, $b) {
return ($a > $b);
}
}
// сортируем от меньшего к большему
class MySortAZ extends AbstractMySort
{
protected function compareMethod($a, $b) {
return ($a < $b);
}
}
abstract class AbstractMySort
{
protected $in;
abstract protected function compareMethod($a, $b);
// Первый это тот кто самый [больший/меньший в зависимости от метода сравнения]
protected function getFirst() {
$max = NULL;
foreach($this->in as $curr) {
if(is_null($max)) $max = $curr;
if($this->compareMethod($curr, $max)) $max = $curr;
}
return $max;
}
// Следующее значение это то которое самое [большее/меньшее в зависимости от метода сравнения]
// из тех, кого еще не было, т.е. тех кто [меньше/больше предыдущего]
// если таковых нет, то вернем NULL
protected function getNext($last) {
$max = NULL;
foreach($this->in as $curr) {
if(is_null($max) AND $this->compareMethod($last, $curr)) $max = $curr;
if($this->compareMethod($curr, $max) AND $this->compareMethod($last, $curr)) $max = $curr;
}
return $max;
}
// Возьмем первого, потом в цикле выберем все остальные варианты
// Если уже ничего не возвращается, то закончим цикл и вернем результат
public function getSorted($in) {
$this->in = $in;
$out = [];
$curr = $this->getFirst();
do {
$out[] = $curr;
$curr = $this->getNext($curr);
} while(!is_null($curr));
return $out;
}
}
$in = [5,23,44,-22,2,-4,5667,3,-56,7,8];
$mySortAZ = new MySortAZ();
$outAZ = $mySortAZ->getSorted($in);
$mySortZA = new MySortZA();
$outZA = $mySortZA->getSorted($in);
echo 'in('.implode(', ', $in).')<br>';
echo 'outAZ('.implode(', ', $outAZ).')<br>';
echo 'outZA('.implode(', ', $outZA).')<br>';
?>
Ну да, у него квадратичное время и двойная память, но для небольших массивов вполне себе допустимо. Код в принципе читаемый, прилагаемый тест проходит. Просим оформить по-человечески и в продакшн? Или я на ревью должен потртатить примерно столько же времени сколько юниор писал такой код, чтобы его тщательно изучить? Нет, конечно я могу написать другие тесты и на других фикстурах оно может выглядеть иначе. Но не кажется ли вам, что лучше пусть тесты научатся писать чем велосипеды изобретать?
ПС: кстати вот еще одна задачка для собеса получилась — «сделать ревью для приведенного мною кода, после чего доработать этот код в соответствии с вашим ревью». ИМХО это прекрасный практический пример. Не сложный, и не слишком викторинный.
Я бы, получив такой вопрос на собеседовании, первым делом спросил бы, что делать в случае, если нет корней, если корни совпадают и если уравнение не квадратное, нужно ли проверять равенство коэффициентов нулю точно или с какой-то погрешностью (абсолютной или относительной?). А также в каком виде мы получаем входные данные и выдаем выходные — нужно ли их читать/писать в консоль, скажем.
Предположим, интервьювер дал ответы «выдать пустой массив», «выдать только один корень», «ну стандарт говорит, что в floating point типах не только числа есть», «проверяй точно», «пусть будет функция с тремя аргументами». Тогда я написал бы такой код:
std::vector<double> solveQuadraticEquation(double a, double b, double c) {
if (a == 0) {
if (b == 0) {
if (c == 0) {
// 0x = 0, Any number
return {std::numeric_limits<double>::quiet_NaN()};
} else if (c < 0) {
// 0x - 1 = 0, x = +inf
return {std::numeric_limits<double>::infinity()};
} else {
// 0x + 1 = 0, x = -inf
return {-std::numeric_limits<double>::infinity()};
}
} else {
// Linear equation
return {-c / b};
}
} else {
// Quadratic equation
double d = b * b - 4 * a * c;
if (d < 0) {
// No real roots
return{};
} else if (d == 0) {
// Equal roots
return {-b / (2 * a)};
} else {
// General case
double sqrtD = sqrt(d);
return {(-b - sqrtD) / (2 * a), (-b + sqrtD) / (2 * a)};
}
}
}
Сразу после написания я бы еще сказал, что в реальном коде, вероятно, я бы разбил функцию на несколько: отдельно решение общего случая линейного уравнения, отдельно квадратного, отдельно проверки (не факт, подумать надо), отдельно вырожденный случай, чтобы не нарушать S.
Выше вы писали, что можно неплохо придраться к любому решению. Мне очень любопытно, что в этом не так.
Нет, я конечно шучу, но не совсем.
В целом решение в данном случае закончилось бы на списке вопросов, дальше можно не идти. Однако придраться все равно есть к чему.
Вы сказали что блок-схему вы сюда не приводите потому что тут это не удобно (Чем неудобно я не знаю, ведь в гугле на первой странице в поиске картинок есть правильная блок-схема, пусть и не первая, ну ладно, ок, неудобно так неудобно).
Но вопросы вы задаете уже с учетом конкретной реализации в код, а не в контексте блок-схемы.
Но это так, придирка ради придирки, раз уж вы ловите меня на слове.
Печальный факт состоит в том, что из всего университетского курса в профессиональной деятельности мне пригодилась только оценка сложности алгоритмов. Иии… всё. В общем, чему-то не тому у нас учат.
> PS бравировать незнанием этой сортировки — ещё глупее, чем задавать этот вопрос опытному разработчику.
Поздно. Теперь я буду бравировать тем, что знание сортировки пузырьком мне пригодилось всего раз в жизни: в споре о необходимости знания сортировки пузырьком.
Зачем мне писать реализацию сортировки пузырьком, если я могу взять готовую сортировку из используемого фреймворка?
Потому что это собеседование. Цель — проверка умений. Типа экзамена. На экзамене тоже дают задания, решённые тыщу раз.
Здесь цель проверить как ты умеешь перевести ТЗ в алгоритм, а алгоритм в код. Легче всего это сделать на ранее решённой задаче и сверить твоё решение с прошлым.
Повторять обход с самого начала, пока таких перестановок не встретится.
Обойти массив чисел N раз, попарно сравнивая два рядом стоящих a[i] и a[i+1] и меняя их местами, если a[i+1] < a[i]
Зачем ставить лишнее условие «пока таких перестановок не встретится»? Массив гарантируется отсортируется за N — 1 проходов в худшем случае. Меньше условий — проще код.
Ну и ещё можно докопаться, что обходить массив нужно «треугольником», то есть так:
for (int i = 1; i < N; i++)
for (int j = 0; j < N - i; j++)
if (a[j] > a[j + 1]) swap(a[j], a[j + 1]);
Но по факту — плевать. На O-нотацию это не влияет, а ошибку допустить легко.
А в лучшем случае он отсортируется за один проход. В таком случае вы сделает N-2 холостых проходов. И O(N) превратится в O(N2)
Ну и что? В общем случае, вероятность лучшего случая близка к нулю (от задачи зависит, на самом деле). Нет смысл здесь делать оптимизацию.
> В таком случае вы сделает N-2 холостых проходов.
Да ну и хрен с ним.
> И O(N) превратится в O(N2)
O-нотация всегда рассматривает наихудшие случаи.
O-нотация всегда рассматривает наихудшие случаи.
Но это не значит, что надо писать заведомо под худший случай.
O-нотация всегда рассматривает наихудшие случаи.Вообще-то, нет. Выражение f(x) = O(g(x)) при x->x0 (в CS обычно к бесконечности) означает, что существует некоторая константа k, такая, что для всех x, достаточно близких к x0 (достаточно больших) f(x) <= k * g(x).
Вот только у нас время работы алгоритма зависит не только от размера входных данных, но и от самих данных, поэтому мы можем рассматривать разные случаи оцениваемой функции f(x):
- f(x) — среднее время работы на всех входах такого размера;
- f(x) — максимальное время работы на всех входах такого размера;
- f(x) — максимальное время работы на входах определенного класса такого размера (например, на уже отсортированном массиве для задачи сортировки);
- другие более экзотические случаи.
Все эти оценки являются О-нотацией, и все находят реальное применение на практике (первый попавшийся пример).
Именно поэтому нужно писать «сложность алгоритма в худшем случае O(f(n))» или «сложность алгоритма в среднем случае O(f(n))». Когда не указано, какой случай рассматривается, обычно предполагается, что это понятно из контекста. Вот мне, например, из комментария выше
А в лучшем случае он отсортируется за один проход.очевидно, что рассматривается случай уже отсортированного массива. Так что здесь действительно O(N) превращается в O(N^2). Если у пользователя достаточно много отсортированных (или почти отсортированных) массивов, это будет очень неэффективно.
А что в нём не так? Просто вопросы. Я понимаю, что "Написать нахождение 2х ближайших точек за NLogN" может быть уже черезчукр. Хотя его дают на 30 минут в DICE LA. Вообще все эти срачи похожи на нытьё неосиляторов. Люди, которые идут в программирование порой и не догадываются о том, как много нужно будет делать. Программист APi-колов, который не задумывается о сложности не напишет гугл. Вот и всё.
Раз уж это перевод или русская версия, то хотелось бы ссылку на оригинал. И ссылки на вики русифицировать можно для полноты и удобства. Спасибо за статью!
По поводу теоретических вопросов — большое О и так далее. У программиста должна быть теоретическая база, должно быть представление об алгоритмах, их сложности и т.п. Понятно, что в наше время все можно погуглить и найти — так вот, программист должен понимать, что именно гуглить. Я не считаю, что программист обязан уметь определять сложность алгоритма; но иметь представление о том, что это такое, понимать, что логарифмическая сложность лучше линейной, и чем чревата квадратичная он обязан.
Не вижу в этом ничего необычного
Необычно то, что речь о родственниках.
Это что, если у человека родственник живёт за границей с него тоже нужно справку о не судимости?!
Утрирую? Отнюдь. Когда нужно влезть в систему конкурента — ищут самые слабые места. Первым делом прощупывают работников. Есть уйма способов надавить на сидевшего человека. Поэтому такой родственник — слабое звено.
Не то чтобы в РФ это сильно неожиданно. Всем известный же факт, что в крупных конторах есть специальный отдел, который проверяет все что сможет найти про человека. С учетом легкости покупки слитой базы чего угодно в нашей стране тут даже какими-то специальными навыками обладать не нужно.
Так там работают бывшие сотрудники органов со связями. Им и базы слитые не нужны. Работал в подобной организации. Под видеокамерами как-то возле дома мой автомобиль кто-то царапнул и скрылся с места ДТП. Я раздобыл с видеозаписи номер и марку автомобиля, сходил к нашим безопасникам, и через полчаса знал ФИО, телефон и адрес виновника.
Все эти разговоры не об интервью на самом деле, а о любимом себе, который «вы нам не подходите» услышал как «ты кретин», как оскорбление, унижение.
И решение искать нужно именно здесь, в себе. А не «пусть весь мир перестроится под умного-достойного меня», «это не я дурак, а интервьюер».
Есть подозрение, что если оскорбленному вдруг когда-нибудь придется искать исполнителя, которому платить надо будет свои кровно заработанные, разговоры о правильных интервью кардинально изменятся. :)
2. Еще стоит акцентировать внимание на том, что собеседование, оно не в первую очередь, для того, чтобы выяснить «насколько крут» кандидат (хотя это тоже важно при сравнении). Оно в первую очередь для того, чтобы взять на работу человека, с которым будет комфортно работать *мне* (и любому другому члену моей команды). Т.е. он должен не отравлять неформальную корпоративную культуру, которая исторически сложилась в компании. И если в абстрактной конторе всем нравится рисовать сортировки маркером на доске, то они будут искать тех, кому тоже нравится рисовать сортировки маркером на доске.
От себя теперь, в связи с получением нового опыта, могу добавить следующее.
Самое страшное собеседование не там, где просят карандашиком написать алгоритм обхода бинарных деревьев. И не там, где спрашивают редко используемые методы каких-нибудь библиотек.
Самое плохое интервью там, где врут насчёт условий и характера будущей работы.
Пример: вы приходите к одному очень крупному (прям самому крупному в России) IT-работодателю, успешно проходите техническую часть интервью, далее будущий руководитель проекта буквально упрашивает вас выйти на работу, потому что в ваших услугах очень нуждаются.
Вы принимаете положительное решение, проходите бесконечные проверки (ведь это же самый крупный в России IT-работодатель!), даже сдаёте кровь и делаете флюорографию. Наконец, через месяц, вас готовы видеть в офисе. Вы выходите и прям с первого же дня понимаете, что вас тут не ждут. Вот прям буквально. Вы бэкенд, а тут нужен сильный фронт-енд. Или девопс. Или вообще наоборот. Но факт в том, что характер работы никак не соответствует вашей специализации и вашим ожиданиям. Вам либо надо очень быстро переучиться, либо искать то, что было нужно изначально.
Соответственно, впустую потраченные 2-3 месяца, впустую пережитый стресс от выхода на новое место, потери в зарплате и новый цикл поиска работы. А тот руководитель, который вас упрашивал выйти именно к ним в подразделение, в глаза вам говорит, что он вообще не понимает, кто вас нанял.
Вот это настоящая жесть.
Это все-таки не всегда правильное поведение. Просто из-за косяка собеседующего менять область работы на другую так себе идея. Особенно если область неинтересна. Я вот не горю желанием уходить во фронтенд например, даже на большую зарплату.
Перечитал и понял что получилось достаточно агрессивно, извините. Такой вариант вполне может быть и нормальной реакцией, зависит от ситуации конечно.
Как раз крупная компания работа на Энтерпрайз, большой поток кандидатов, подобные викторинные вопросы также присутствовали.
Статья понравилась, обращает внимание на проблему, без фанатичного склонения к какому-то другому методу.
Добавлю пару комментариев с другой стороны баррикад:
- Практически любые вопросы могут иметь смысл, если уметь правильно понимать ответы на них, под правильно подразумеваю учитывать контекст в котором возникла потребность в найме. Бывает полезны вопросы и «кем вы видите себя через 5 лет» и «зачем вы пришли к нам на собеседование» и как написать сортировку. К сожалению многие задают их, но не умеют интерпретировать ответы.
- В аутсорсинговых организациях программисты часто подвергаются собеседованию со стороны заказчика, где задаются те же самые викторинные вопросы и нужно понимать, как покажет себя на таком собеседовании потенциальный работник.
- Бывает, что сам не согласен со многим происходящим в компании, но профессионализм требует либо разделять подходы компании, либо менять, либо уходить. Менять что-либо чаще всего бывает сложно просто из-за политических противостояний.
P.S. Удивился, что не нашел упоминания про тест стаканом воды, мне он понравился, хоть я и не понял сразу, что это был тест.
«тест стаканом воды» — это попросить стакан воды на собеседовании, или какой-то иной?
«это попросить стакан воды на собеседовании» — тот самый.
А в чём смысл этой просьбы?
Есть чуть более хитрая вариация этого теста — со стаканом зелёном чая:
Хорошая «лакмусовая бумажка» ценят ли сотрудников в компании — попросить зеленый чай и проверить, принесут ли Гринфилд с мелиссой. Фактически это самый плохой и дешевый чай, который почему-то считается не стыдно принести в офис. Его вам предложат везде — на вокзале, в отделении банка для не-вип-клиентов, в офисе самой бедной турфирмы и т.д.
eax.me/job-interviews-tips/
Принесли чай с сахаром? — хреновая компания.
Принесли без сахара? — хреновая компания. Я хоть и люблю с сахаром, но сегодня я не в настроении.
Ну никак не коррелирует.
Кстати, вспомнил забавное: на моей практике был случай, когда мне на собеседовании не нашлось стула. (Директор и секретарша вместе долго искали, но тщетно.)
К слову: работал в одной, далеко не бедной, стране, где нет культуры чаепития. Чай в магазинах есть, но выбор беден. В стране просто все пьют кофе. Что же — не работать с людьми из-за чая?
По-моему это такой же абсурд со стороны соискателя, как и абсурд со стороны работодателя — спрашивать про количество пианистов в городе N.
Всегда можно вскипятить воду из-под крана в чайнике. Более того, во многих компаниях есть проточные фильтры для воды.
> Что же — не работать с людьми из-за чая?
Доля правды здесь есть. Например, когда все курят, а ты — нет, или наоборот, никто не хочет составить компанию покурить, работать будет не очень приятно.
Касательно чая: обычно нет никаких проблем пить чай, когда все остальные пьют кофе. Для заваривания чая достаточно источника горячей воды. А вот обратное (все пью чай, а хочется кофе) уже сложнее организовать.
Даже по кулеру, на худой конец. Может кулер утром сломался и до сих пор ждут мастера?
Простите, а работники в этом случае чего пьют? Если нет источника питьевой воды в офисе, насколько я помню по требованиям санипна, работа должна быть банально остановлена.
А не в каком-то обоссаном подвале, где крысы доедают бомжа?
Замутим стартап?
- Добро пожаловать в наш оупенспейс
- Но это же заброшенный подвал
- Это лофт
- Но там в углу крысы доедают наркомана
- Это перформанс
- А что за бомж в порванном костюме?
- Это наш коуч, Артемий
- А проститутка рядом с ним?
- Фешн-консультант Натали. Пройдемте на кухню. Берите фалафель.
- Но это же хлебный мякиш.
- Нут в этому году плохо уродил.
- А Что это за зек возле плиты?
- Это наш веган-шеф-повар Николай. Он недавно вышел по УДО. Желаете смузи?
- Похоже на чифир.
- У Николая свой секретный рецепт смузи.
- Все таки интересно узнать судьбу наркомана, который лежит в углу.
- Это наш сммщик. Отдал свою жизнь ради искусства. Получился неплохой перформанс, как считаете?
- Да, неплохой. Парень, который нюхает клей из пакета, местный вейпер?
- Как догадались?
- Да так, чисто интуитивно.
- А, что за сумасшедшая женщина с котами?
- наш HR
- А вас как зовут?
- Валера, я CEO. Знаю наизусть все цитаты великих людей, которые помогли мне стать успешным. Сигареткой не угостите?
Когда я начинал карьеру, мне сразу предлагали кофе, и спрашивали со сливками или без… а сейчас, я уже давно такого не встречал.
На пальцах:
- конечный заказчик требует софт, выполняющий такие-то задачи, удовлетворяющий таким-то стандартам качества, с документацией и ясным путём поддержки
- Контора, «представляющая мистического заказчика»: «сейчас наши экстрасенсы определят, совпадает ли ваш энергетический уровень с нашим, и как там ваши чакры?»
Накипело.
Я лишь заявил, что практически для любого вопроса может быть место на собеседовании.
По вопросам ведущего собеседование можно понять, что он пытается выяснить, какие слабые места он видит в вас и насколько вообще понимает, что делает.
На вопросы «кем вы видите себя через 5 лет» и «зачем вы пришли к нам на собеседование» у меня ответов нет. По-крайней мере не вижу смысла рассказывать о своих планах человеку, которого впервые вижу. Я считаю это дурацкими вопросами.
Пожалуй единственными правильными ответами будут зеркальные вопросы: кем вы видите меня через 5 лет и зачем я пришёл к вам на собеседование?
Именно про будущие планы разработчикам вопросы редко задают, в целом они предсказуемы в своих намерениях.
Однако в некоторых случаях важно понять, коррелирует ли личный план кандидата с планами компании на кандидата (собеседование — это же процесс переговоров о сотрудничестве).
Например кандидат часто меняет сферу деятельности, или много времени посвятил изучению другой специальности, или демонстрирует какие-то специфичные навыки.
Для разработчика вообще хороший ответ — «наверняка буду разработчиком», джуниору вообще смело можно говорить, что понятия не имеет. Правильных ответов нет, есть неправильные — например агрессия в любом проявлении, так как в хороших компаниях лучше рискнут потерять квалифицированного кандидата, чем внести разлад в команду пригласив неадеквата.
Правильного ответа на «зачем сюда пришли» также нет, есть неправильные. Если хотите продемонстрировать потенциальную лояльность — найдите факторы привлекающие вас, хотите показать независимость — скажите, что рассматриваете компанию наряду со многими другими.
Опытный собеседователь будет наблюдать как соотносятся ваши рассуждения со всеми другими фактами и составит о вас какую-то в карину в целом (если, к примеру, показания не будут сходиться, то это может быть свидетельством вашей непоследовательности, или того хуже — намеренного введения в заблуждение), и эта картина будет иметь значение, а не ответы на отдельные вопросы и средний балл по ним в результате.
В своей практике я стараюсь задавать гораздо более провакационные вопросы специалистам, чья деятельность связана с общением с внешним миром — поддержка, аналитики, руководящий состав особенно, чтобы увидеть, как они будут представлять компанию. Конечно, подвергать разработчиков или тестировщиков стрессу чаще всего излишне, но всякие обстоятельства бывают, наперед не знаешь какие именно вопросы задать, все зависит от кандидата и контекста.
Могу и ошибаться. Работаю на западе, не в России, реалии могут быть совсем иными. В моей практике случаи, когда кандидаты просто вставали и уходили после вопроса «зачем вы сюда пришли?». Поэтому считаю этот вопрос дурацким.
Друзья из более «материальных» видов бизнеса (судостроение, нефтяные платформы), нанимающие сварщиков, инженеров, водолазов, инспекторов — не позволяют себе задавать такие дурацкие вопросы.
Эти токсичные, токсичные собеседования