Pull to refresh

Comments 1091

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


Делает по решениям, подставляя код, а не разбираясь в принципах. Вот в памяти
и не остается.

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

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

А как узнать знаю или не знаю, пока не видел вопроса?

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

Учить, повторять, использовать знания на практике. 10-летний опыт при белых пятнах,
видимо, в теории? Меня бы не впечатлило
1. Вероятность полного совпадения опыта случайно взятого специалиста и интервьюера (или составителя чек-листа) довольно низка. Если взять список из 28 вопросов, не дать к ним подготовиться и предположить, что шанс знания любого из них составляет 95%, то шанс безошибочного ответа по всему чек-листу составляет 23%. При этом специалист с опытом умудрялся как-то находить работу и приносить ощущение пользы, раз его оттуда не выгоняли.
2. Теоретические знания помогут на практике только чтобы осадить ретивых коллег в комментах к пулл-реквесту или надуть щёки на собеседовании, чтобы лягушка показалась больше, опаснее и увесистее. Ну, наверное эти слои брони хороши для кандидата, раз он их на себя навешивает. Только вы нанимаете писателя кода руками или говорителя ртом университетских лекций?

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

вы переоцениваете и работодателей и соискателей и ситуацию на рынке, чтобы так считать
при собеседовании сеньора ни один работодатель не будет
готов услышать «не знаю»

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

я вот, например, пересеньор Java, но нюансы Core Java — такие как JMM, ассортимент GC, и подход к реализации compare-and-set навскидку не помню, потому что давно не сталкивался с performance issues. И я спокойно отвечаю на подобные вопросы — «не помню». Но столкнувшись с проблемой и легонько погуглив — вспомню. В том числе, и что я делал, и как решал. Просто некоторый опыт лежит в cold storage и без нужного количества ассоциаций из глубин памяти не поднимается.

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

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

Че вы прям на собеседование без подготовки идете

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

даже описаниемвакансии не прочитав?

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

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

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

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

Зависит. Но не вижу связи с моей предыдущей репликой. Детализируйте?
Че вы прям на собеседование без подготовки идете


Это не школа и не ВУЗ. Где можно выучить перед экзаменом за день-два, а потом благополучно забыть навечно.

Вас нанимают как профессионала в какой-то сфере.

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

Что-то можно освежить в голове. Но не более.

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

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

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


Сравнивать умственную деятельность, которой вы занимаетесь как профессионал ежедневно полный день?
С физической деятельностью, которой вы занимаетесь через день в течение пары часов?
И после этого ерунду говорю я?

> Сравнивать умственную деятельность, которой вы занимаетесь как профессионал ежедневно полный день?

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


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

Значит и подготовиться к ней надо обстоятельно и серьезно

Рвете 20 раз без разминки и подготовки?

Да, 20 раз без разминки сделаю и не замечу. А вот условно уже 40 вряд-ли, но подготовив мыщцы(около недели-двух) смогу сделать без проблем. Именно подготовив конкретные мыщцы(ака конкретный навык). Для этого необходим бэкграунд.
> Да, 20 раз без разминки сделаю и не замечу.
травма вам обеспечена. я вас честно говорю. как потерпевший
травма вам обеспечена. я вас честно говорю

Кмк на турнике(просто подтягиваясь) сложно травму получить. А вот со штангой запросто.
Абсолютно верно. При работе со своим весом и обычных нагрузках все будет нормально. За 8 лет регулярных занятий я думаю мог уже получить необходимых знания. То что вы повредились и сделали неправильные выводы экстраполировав их на всех, конечно, печально. Да, разогреваться нужно, если идешь на свой рекорд. А для рутины не стоит тратить время.

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

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

А че так со штпнгой? Подошел и 100 раз раанул. Без разминки и подготовки. Ну как на собеседовании.

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

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

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

Да я тоже когда перестал готовиться к соревнованиям по маоафону стал выигрывать только первые места. Не поверите?

Он не говорил, что он не работал над собой вообще.
И я спокойно отвечаю на подобные вопросы — «не помню»

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

1.


шанс знания любого из них составляет 95%, то шанс безошибочного ответа по всему чек-листу составляет 23%

во-первых, нет такой величины как "шанс знания", если ты работаешь с этим инструментом, то объём знаний зависит не от шанса, а от опыта работы. Да, ты можешь не использовать какую-то часть языка, но как раз именно объём (и глубина) знаний и отличает например сеньора от джуна. Если бы у сеньора был такой же "шанс знаний", как и у джуна, наверно, никому не требовались бы сеньоры.
Во-вторых, знать — это не обязательно в 100%-ном объёме помнить все детали. Знать — значит понимать и быть способным аргументировать (подразумевается, верно). Если человек может и не "знать", почему (к примеру) поиск в линейном массиве менее эффективен, чем в хэшированном дереве, то один может это вывести на ходу, а для другого разницы никакой нет — и это тоже один из факторов, которые проверяются на собеседовании.


Не нужно знать ответы на 100% вопросов, но уровень знания и понимания технологии коррелирует с уровнем ответов. Поэтому и спрашивают.


2.


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

Это либо наивность, либо провокация. Если бы было так, наверно сеньорам платили бы 23% от джунов (типа сеньор больше знает и поэтому будет злоупотреблять знаниями?)


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


А умение отыскивать и применять, если за этим не стоит фундаментального знания и понимания технологии, приводит к такому:
https://habr.com/ru/post/521104/

Если у вас нет знания за этим, то ваше решение — буллшит.

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

А если эти решения принимаются уже над подсознательном уровне? Например, много лет назад были все эти знания, ...

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


Скажем, из последних примеров, пришёл программист на РНР в питон и пишет:


if "x" in the_dict.keys(): ...

Да, он пишет на подсознательном уровне потому, что isset() в питоне нет. Если я ему в ревью напишу, что в питоне есть оператор "x" in the_dict, это кому-то повредит? Ущемит эго похаписта? Может он как-то аргументировать в свою пользу или нет?


Или вариант 2: в Python 3.7 добавили функцию datetime.fromisoformat(). Да, раньше приходилось либо писать в каждом проекте это заново, т.е. просто копипастить ("на подсознательном уровне"), либо использовать какую-то библиотеку. Если я в ревью напишу автору кода, что "в 3.7 это уже встроено", это кому-то как-то повредит? Ущемит эго?


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


Но знания устаревают, и если ты считаешь себя пригодным для работы в современных условиях, твои знания должны быть современны. А если ты считаешь обновления знаний "бессмысленной потерей времени", ну будешь через 10 лет как те, кто сейчас на дельфи ваяют монохромные ГУИ под виндовс 98 для кассовых компов в Нигерии. Хотя возможно, это и было нормой 20 лет назад.


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

Знания были и я не про миграцию с языка на язык или даже с версии на версию. Сходу аргументировать не получится, время на повторный рисерч нужно будет. Результаты которого, да, могут быть сюрпризом, если версия сменилась. Вот, например, для многих пэхепэшников сюрприз, что true и false с некоторых пор занимают столько же места как null. По факту нисколько, типы с одним значение и значение не хранит, а bool = true|false под капотом, и теперь чаще всего лучше писать ['val1' => true, 'val2' => true] вместо ['val1' => null, 'val2' => null]: затраты памяти те же, а работать удобнее чаще всего.

Знания были

ну я собственно говорил


Если у вас нет знания за этим, то ваше решение — буллшит.

так что видимо это не тот случай. :)

"Были и утрачены" для меня равносильно "нет"

datetime.fromisoformat()

Пишу на питоне раз в 100 лет, обрадовался как-то что наконец затащаили в стд работу с датами… А потом оказалось, что нет, не затащили


from datetime import datetime
print(datetime.fromisoformat("2020-10-03T11:39:26.084730Z"))
# ValueError: Invalid isoformat string: '2020-10-03T11:39:26.084730Z'
UFO landed and left these words here

Все правильно, таймзон. Мне и нужно таймзон. Например так работает:


from datetime import datetime
print(datetime.fromisoformat("2020-10-03T11:39:26.084730+00:00"))

А если заменить +00:00 на эквивлентный Z то уже нет.

безотносительно проблемы: +00:00 и Z не совсем эквивалентны. Вернее в случае с Z они эквивалентны, но +00:00 — это смещение, а буква — это указание на таймзону, которое в разное время может иметь разное смещение: переход на летнее/зимнее время или политика может на это влиять.

Учитывая, что все смещения отсчитываются от зоны Z, то 00:00 ему эквивалентно.

вместо Z — +00:00


хотя согласен, Z это практически стандарт. Сам немного напрягался по этому поводу.

Спасибо :) как раз к вопросу о пользе знаний.


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


Caution This does not support parsing arbitrary ISO 8601 strings — it is only intended as the inverse operation of datetime.isoformat(). A more full-featured ISO 8601 parser, dateutil.parser.isoparse is available in the third-party package dateutil.

https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat


что, конечно, немного удивительно.

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

Сложность с датами обычно начинается в районе "сложить-вычесть". Но хотя бы распарсить по ISO-то можно наверное… Функцией fromisoformat :)

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


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

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

Согласно этой трактовке, «сеньорность» как признак сводится к совпадению модных фетишей у двух охотников из техно-варварских племён, один из которых оценивает, а другой — оценивается; при этом набор паролей и ответов постоянно меняется. Что ж… Раз это даёт какие-то результаты, которые можно зримо оценить, это иногда работает. Но меня смущает в этом механизме то, что если сотрудник умеет очень хорошо проходить собеседования (то есть обладает большим количеством паролей от них), значит он часто по ним ходит, а следовательно не занят производительной деятельностью и/или может обладать другими качественными недостатками, которые не может вскрыть система чеклистов.

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

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

Поэтому любое собеседование в сущности сводится к двум вещам:
1. к тестированию, насколько велик запас терпения миссионера тимлида к вводимому в лоно истинной веры кающемуся язычнику нанимаемому сотруднику после чтения им местного извода Кахетезиса модных цитат про паттерны программирования, KISS, SOLID, модели OSI, количество бакетов на острие хэш-таблицы, местонахождение мяуколки у кошки, дефолтный способ вычисления хэша для объектов в данном ЯП и прочие вещи, которые было бы слишком оскорбительно использовать для решения приземленных задач вроде катания круглых апи и таскания квадратных крудов.
2. и насколько хорошо тимлид умеет обучать новоприобретённого серва прыгать на минах своего собственного ОКР (потому что вполне возможно, что нанимаемый гребец может не подавать сигналы желания пройти очередной этап дрессуры, а следовательно бесполезен для дрессировщика).

А умение отыскивать и применять, если за этим не стоит фундаментального знания и понимания технологии, приводит к такому:

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

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

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

Хотя я немного иначе смотрю на этот процесс, но ваше мнение прям вот, что называется, «по земле ходит».
Иначе — потому, что я уверен, что хорошему разработчику нужно уделять время не только обучению, но и, в идеале, преподаванию. Немного, но надо.
Ой, ну я считаю себя неплохим специалистом по написанию низкоуровневой графики.
Вчера проходил собеседование на другую должность в своей же фирме.
Поплыл на двух простейших вопросах:
1. Поплыл на порядке вызовов виртуальных деструкторов в С++. Как работают конструкторы и деструкторы в нормальной ситуации я прекрасно помню. Как ведет себя всё это если делать не правильно — я с трудом осознавал в процессе собеса. Потому что в жизни я когда-то прочитал про то, как работают виртуальные деструкторы, какие могут быть проблемы. И просто пишу правильно всегда. Вспомнить порядок вызовов(вернее даже не вспомнить, а попытаться воспроизвести на основе знаний о внутренностях С++, вот что я пытался сделать). Хотя вопрос просто стыдный, даже для моей текущей должности.

2. Поплыл на левосторонних и правосторонних системах координат. Хотя казалось бы, куда проще вопрос то для программиста графики?

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

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

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

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

Это вопросы его показывают, верно. Которые помогают кандидату
почувствовать себя уверенно, а не интервьюеру тешить свои знания
в узких областях до запятой
Поплыл на порядке вызовов виртуальных деструкторов в С++
Заинтриговали. И что же хотел услышать интервьюер?
Просто предлагал написать что будет если в одном месте virtual поставить, что будет если в другом месте virtual поставить.
Неужели не стыдно отвечать «не знаю» на собеседовании

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

Почему? Ему стыдно.

И на мой взгляд это неправильно — нет ничего постыдного, если ты чего-то не знаешь. Стыдно, если не хочешь узнать.
мне вот совершенно не стыдно отвечать «не знаю»

даже не знать мне не стыдно — все знать все равно не получится

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

6. Как устроен тип map?

Самый популярный неправильный ответ: «то хеш-таблица». Да, это хеш-таблица. Как устроена хеш-таблица?
Наводящие вопросы: какая hash-функция используется в map в Go? Что такое bucket?


-_\ это вы серьезно сейчас? Ну т.е. какая *реальная* польза от того, что чел будет знать, какая там хэш-функция используется? Если хотите спросить про хэш-таблицы — ну так и спросите без применения к языку «Какие хэш-таблицы вы знаете?». А считать первый ответ «хэш-таблица» неправильным на вопрос «Как устроен тип map» — ну, такое.

12. Сколько времени в минутах займет у вас написание процедуры обращения односвязного списка?

Самый популярный неправильный ответ: «А что такое односвязанный список?». Это такая структура данных...

Благодаря усилиям хэдхантеров Evrone Екатерины Тхоржевской и Анны Кудряшовой — спасибо им! — до меня добираются только резюме интересных кандидатов


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

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

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

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

про список — я сам сначала не поверил, стал на собесах задавать вопрос на собесах.
А поясните для не-сварщиков на go: так и какая же функция хеширования используется? А где это специфицировано? А что менялось с версии 1.10 до 1.13+ в этой части?
это вопрос с подвохом. там под разные типы разные функции. для int, например, он сам :)
Я не стану повторять вопрос, но вы на него не ответили в полном объеме, а он (ответ) потянет на весьма немаленькое исследование и копания в сорцах, а если наложить ещё и версии...

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

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

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

если у вас есть идеи, что спрашивать на этом месте — предлагайте!
Надо спрашивать о свойствах map/хеш-таблицы. Какое (асимптотическое) время операций, какие накладные расходы, какие требования к ключам. Чем эта структура хуже и лучше сбалансированных деревьев. Защищает ли стандартная реализация от DoS атак и что это такое. Если защищает – что это означает с точки зрения воспроизводимости поведения структуры, если нет – в каких случаях ее нельзя использовать. Что с потокобезопасностью?

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

Гораздо важнее, чтобы разработчик понимал свойства и гарантии используемых инструментов, а не внутренюю реализацию. Я вот знаю как устроен HashMap в Rust, но лучше бы не знал – там столько SIMD и черной магии, что можно засмущать любого интервьювера на собеседовании.

Аналогичный вопрос: как работет динамический массив? Вы вот точно знаете все ньюнсы его реализации? Сколько будет по факту выделено памяти в каждом случае инициализации и релокации?
и ее неизменность гарантируется от версии к версии

Не гарантируется. Надо следить. Это тоже один из факторов опыта. Тоже самое с массивом. Go кстати редкий удивительный язык, который интересен внутри. В доках 30 летней давности они даже так и писали: "Ну вы там в реализацию такой-то либы взгляните"

В доках 30 летней давности они даже так и писали
Ему 11

Ему 11 только в последнем издании. А так — больше 30

В контексте разговора — нет, далеко не 11

Только программистов могут так собеседовать. Представляю себе собеседование на должность строителя, которого сначала расспрашивают какой фирмы обмотка в дрели Макита, технические характеристики цемента, виды кирпичей, диаметры патрубков. Или просят построить «тестовый» дом. Или приводят к кривой и косой избе и просят рассказать что в ней не так, и как это пофиксить.
Причем ладно бы это имело какой смысл и было бы что предложить кандидату, но 95% российских компаний ничего не могут предложить разработчику, кроме ежедневной рутины за копейки. Но собеседования с таким выпендрёжем смеху подобно. Вместо того, чтобы брать с запада зарплаты и условия труда, берут подобные фильтры отсева. Но раз это хавают, то что поделаешь.
технические характеристики цемента, виды кирпичей, диаметры патрубков

а вот это прораб должен знать, хотя бы в общих чертах

У меня все-таки вопрос — зачем вам нужен прораб? И как вы жили без него до сего момента? Смайлик.

ну вот эта должность была — прорабская
У меня все-таки вопрос — зачем вам нужен прораб? И как вы жили без него до сего момента? Смайлик.


У меня всё таки вопрос:
Зачем вы инженерную специальность (software engeneer) сравниваете с рабочим?
Но отказываетесь принять тот факт, что она по уровню, всё же, ближе к должности прораба.
Тот факт, что в ИТ нет такого количества простых рабочих, а все разработчики, по сути, инженеры — ну вот так это в ИТ. Полной аналогии со строительством нет.

P.S.:
Когда я получал разряд простого слесаря в прошлом веке — на экзамене меня гоняли по видам резьб и особенностям обработки металла. И это нормально.
P.S.:
Когда я получал разряд простого слесаря в прошлом веке — на экзамене меня гоняли по видам резьб и особенностям обработки металла. И это нормально.

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


Да, были несколько вопросов по форме резцов токарного станка.

а какая зависимость от того 220 или 380 у него напряжение питания

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


1) Я писал о слесаре. Не токаре.
2) Про высокий разряд ни словом ни обмолвился. Там ни о каком сеньоре-слесаре и речи ни шло.
3) Вы серьезно считает что опросник из статьи предназначен для тестирования сеньоров?

1) Я писал о слесаре. Не токаре.

Пфф… я вам могу придумать кучу вопросов по кувалде (состав стали? влияние веса и состава на максимальную температуру детали по которой вы бъете, ухудшаются и насколько характеристики металла при ударе и почему)

3) Вы серьезно считает что опросник из статьи предназначен для тестирования сеньоров?

Я серьезно? так там в статье написано что автор считает что по данному опроснику сеньор должен набирать +8 баллов, а джун 3+
и мой опыт собеседований на сеньора (не golang) подсказывает что такие опросники действительно поляризуются популярностью
гоняли, конечно. я тоже в прошлом веке получал разряд токаря :)
Интервьюер: Итак, вы считаете себя плотником?
Плотник: Всё верно. Это именно то, чем я занимаюсь.

Интервьюер: Как долго вы занимаетесь этим?
Плотник: Десять лет.

Интервьюер: Очень хорошо. А теперь я бы хотел задать вам несколько технических вопросов, чтобы оценить, насколько вы впишетесь в нашу команду. Договорились?
Плотник: Конечно, было бы неплохо.

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

Интервьюер: Да, я понимаю, но не могли бы вы подсказать мне, сколько у вас опыта именно с коричневыми? Ну, плюс-минус.
Плотник: Я действительно понятия не имею. С того момента, как дом построен, меня не волнует, в какой цвет его покрасят. Может, шесть месяцев?

Интервьюер: Шесть месяцев? Вообще-то мы ищем кого-нибудь с гораздо большим опытом коричневого, но позвольте мне задать вам ещё несколько вопросов.
Плотник: Ладно. Но, знаете, покраска — это покраска.

Интервьюер: Да-да, хорошо. Что насчёт Ореха?
Плотник: А что с ним?

Интервьюер: Много ли вы работали с ореховым деревом?
Плотник: Конечно. Ореховое дерево, сосна, дуб, красное дерево — всё, что угодно.

Интервьюер: Но сколько лет вы работали с Орехом?
Плотник: Да не знаю я, чёрт возьми. Я что, должен считать каждую доску?

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

Интервьюер: Но вы не ореховый гуру?
Плотник: Ну, я же плотник — я работаю с любыми типами дерева, которые, конечно, имеют некоторые отличия, но я считаю, что если ты хороший плотник…

Интервьюер: Да, да, но мы используем ореховое дерево. Это нормально?
Плотник: Ореховое дерево — это прекрасно! Всё, чего пожелаете — я же плотник.

Интервьюер: Что насчёт чёрного Ореха?
Плотник: А с ним что?

Интервьюер: У нас было несколько ореховых плотников, но потом случайно выяснилось, что они не были плотниками по чёрному Ореху. Имеется ли у вас опыт с ним?
Плотник: Конечно, немного. Полагаю, было бы хорошо иметь больше опыта для моего резюме.

Интервьюер: Ладно. Позвольте мне свериться со списком вопросов.
Плотник: Да пожалуйста.

Интервьюер: Итак, последний вопрос на сегодня. Мы используем Камень 5.1 для забивания гвоздей. Использовали ли вы Камень 5.1?
Плотник: [становясь белым...] Ну, я знаю, что множество плотников начали использовать камни, чтобы забивать гвозди, когда Craftsman купил каменоломню, но, вы знаете, честно говоря, у меня это получается гораздо лучше с моим гвоздомётом. Или молотком, если хотите. Мне кажется, что, когда я использую камень, то слишком часто ударяю себя по пальцам, и моя рука сильно болит, потому что камень очень большой.

Интервьюер: Но другие компании используют камни. Вы хотите сказать, что камни не работают?
Плотник: Нет, я вообще-то не говорю, что камни не работают. Я лишь считаю, что гвоздомёты работают лучше.

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

Интервьюер: Ок. У нас есть ещё несколько кандидатов; мы свяжемся с вами, когда примем решение.
Плотник: Что ж, спасибо за ваше время. Было приятно поговорить.

СЛЕДУЮЩИЙ ДЕНЬ

Звонок…

Интервьюер: Алло?
Плотник: Здравствуйте! Помните меня? Я тот плотник, которого вы собеседовали для работы с чёрным ореховым деревом. Хотел лишь узнать, приняли ли вы решение.

Интервьюер: Вообще-то приняли. В целом, нам нравится ваш опыт, но мы решили взять кого-то, кто больше работал с коричневыми.
Плотник: Правда? И это всё? Меня не взяли на работу, потому что у меня недостаточно коричневых?

Интервьюер: Ну, это только частично правда, но частично, мы взяли другого парня, потому что он намного дешевле.
Плотник: Серьёзно? И сколько же у него опыта?

Интервьюер: Ладно, он не совсем плотник, он продавец машин. Однако он продал много коричневых машин и работал с отделкой из орехового дерева.
Плотник: [короткие гудки]
Не по теме, но ситуация с камнями мне напоминает ситуацию с redux во фронтенде) Есть гвоздомёты, молотки для забивания гвоздей, но стандарт — камень.

Там не просто разные функции, там разные реализации(map_fast32.go, map_fast64.go, map_faststr)?

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


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

И да, забыл еще это упомнянуть:
10. Как вы отсортируете массив структур по алфавиту по полю Name?

Самый популярный неправильный ответ: «Методом пузырька». Пузырек — прекрасный алгоритм, но есть сегодня и поэффективнее. Например — quicksort. Не можете с ходу имплементировать quicksort? Так ведь и не надо!


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

Собственно, поставьте этот и вопрос про список двумя первыми и сэкономьте свое время.
Мне кажется, если программисту надо имплементировать (в очередной раз) метод сортировки и при этом он не разработчик ядерных библиотек языка, то в используемом им стэке что-то очень сильно не так.
так в том и point, что не надо, надо знать стандартную библиотеку.
А что, в Go реализован ванильный quicksort? Сильно в этом сомневаюсь.

Я вот не могу сходу правильно реализовать quicksort, потому что не помню как эфективно выбирать медиану, чтобы побороть деградацию производительности к O(n^2). Я плохой разработчик? А вы помните?

Если вам правда нужно реализовать свою сортировку – использование quicksort скорее всего плохая идея. Большинство стандартных библиотек полагаются на mergesort, как основной алгоритм, реализуя поверх него гибридные схемы (timsort и другие). Гораздо важнее знать эту информацию, чем помнить наизусть школьный алгоритм.
В Go есть пакет sort, который содержит в себе набор функций для сортировки. В этом и вопрос: вы будете quicksort писать сами или воспользуетесь стандартной библиотекой? В которой реализовано всё минимально необходимое как для сортировки слайсов int, float, string, так и для сортировки структур. Там даже два разных алгоритма есть (в коде один называется stable, другой quickSort). Для каждого указано даже O(...log(n)...) вызовов и для одного указано, что-то типа «not guaranteed to be stable» — интересно для которого? =) Было бы интересно поговорить не только про библиотеку, но и про сам алгоритма quicksort. Прям открыть код и поговорить — почему оно реализовано так и какие проблемы они пытаются решить.

Или вопросы ставить нормально. Вы же не даёте синьорам-помидорам задачи не на сортировку массивов.
Если это список пользователей, почему, к примеру, order by в SQL запрос не добавить?


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

Потому что надо быть достаточно упоротым

Это Go, детка :) Прошу прощения за фамильярность, но это передаёт суть

А потом на практике окажется что метод пузырьком будет быстрее на малом объеме данных, потому-что кеш.
А потом на практике окажется что метод пузырьком будет быстрее на малом объеме данных, потому-что кеш.


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

Вы уверены, что на нынешнем железе стоит тратить на это время?

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

Задержки по сети, задержки на диске, ожидание ввода пользователя.

Не распространяйте свой опыт на всех остальных, не все пишут круды.

Вы уверены, что на нынешнем железе стоит тратить на это время?

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


Да, задержки по сети у нас были, но если мы отвечаем на событие за 500 наносекунд, а кто-то — за 450, то мы проиграли.

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

Метод пузырьком нахрен не нужен, потому что Шелл лучше всегда

… а потом окажется, что 99% времени приложение проводит в IO, на ожидании сетевых/дисковых ресурсов. и эти микрооптимизации никому не впились, потому что один умник решил в цикле запрашивать базу/rest-сервис на каждый элемент.
зато про сортировку знал!

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

"Разрабатывать БД" обычно входит в "писать круды", редко бывает выделеный DBA или типа того.

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


В наше время работа с СУБД встречается на каждом шагу.
Не нужно быть выделенным DBA чтобы тебя это коснулось.
Может и к лучшему, что молодежь не знает про списки. Для небольшого набора данных лучше использовать массив, для большого — хеш-таблицы или деревья. Почти никогда за тридцатилетнюю практику не использовал списки.

Да фиг с ним с самим списком. Что такое его обращение? Что такое его разворачивание или развёртывание? Операция обратная свёртке? Как это будет по-английски?

Ещё можно поиграться и попросить сформулировать определение разворота списка — каким условиям должен удовлетворять reverse(xs).

обычно и интервьер и интервьюируемый дорошат своим временем, и в такого рода игры не играют.

А зря (настолько же зря, насколько «зря» неумение перевернуть список), потому что перед тем, как что-то делать, стоит понимать, что именно нужно сделать. Да и разговор это интересный, о формулировке ТЗ и контрпримерах, ИМХО куда интереснее, чем ещё один цикл или рекурсивную функцию написать.

А какие тут могут быть разные формулировки?

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

Даже если высасывать из пальца, то это была бы "развёртка в список", а не "разворачивание списка".

Вопрос все равно не праздный. Люди которые проверяют разворот чуть надежнее чем тестом rev [1,2,3] == [3,2,1] требуют понимания, когда мы считаем что разворот успешно завершен. Формальный критерий.

Формальные критерии — это точно не про мейнстримные языки. Тут максимум — тесты. Впрочем, их писать тоже мало кто умеет. Вон, автор статьи даже не задаёт вопросов на эту тему.

просто не знаю, как об этом спрашивать без написания собственно тестов.

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

Как вы протестировали бы Х (например метод для деления целых чисел). Какие граничные случаи тут есть. Моки чем от стабов отличаются. Какие библиотеки для тестирования, для геренерации тестовых данных использовали. Ну вот в общем.

Ну можно property test'ы написать, например. Это уже чуть ближе к требованию формальных критериев.

Я про свои ассоциации при чтении холиваров о "правильных" собесах и тестовых, где задача "развернуть/обратить/… список" регулярно упоминается. Звучит как задача из предметной области высшей математики, на уровне "эффективно отсортировать массив"

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

Это игра, в которую могут играть двое.

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

> Ну т.е. какая *реальная* польза от того, что чел будет знать, какая там хэш-функция используется?

Я однажды заморочился и откопал типовой комплект ответов на вопросы по Java, залил себе в мозг эту мусорную инфу по хэш-таблицам и потом пугал ею интервьюеров на собеседованиях, которые спрашивали что такое hash index в MySQL. Думаю, они ожидали менее развёрнутый ответ, который и приличествовал программисту LAMP-стэка. Такие знания — это сила. Это мощь паровоза, который несётся по болотам, распугивая квакающих лягушек. Это булава интеллектуальной битвы, это боевой клич берсерка из драккара компьютерных наук, обожравшегося пшеницы со спорыньей и прочих некачественных продуктов.
Практически неприменимо в быту, но вы же не станете требовать, чтобы руны образовывали вокруг голого торса огненный щит? Один покарает вас за такое желание облегчить свою участь инфоберсерка.
можно прогнуть по зарплате — это хорошая шутка, смешная.
Ну т.е. какая *реальная* польза от того, что чел будет знать, какая там хэш-функция используется?

Менее 10%. А вот чистый код намного важнее. Но эти споры будут вечными. Интервьеверы хотят нанять богов программирования.
Такие знания — это сила. Это мощь паровоза, который несётся по болотам, распугивая квакающих лягушек.

Юмор отличный )))

Интервьюверы часто просто не знают, что спрашивать. Вот и составляют "чеклисты", а потом делают оффер, тому кто, больше всех ответил, например 15 из 100, когда остальные 6-12

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

У разных людей/компаний разные подходы. Видел изнутри как именно так набирали. Да, одна из оценок, но чёткий выход в баллах от интервьювера плюс комментарий устный

У разных людей/компаний разные подходы. Видел изнутри как именно набирали. Никаких чеклистов и списка из 100 ответил 67.

Хоть и согласен с комментарием, всё равно поспорю с аргументом про необходимость знать функцию хэширования по умолчанию конкретно в Java (в java.lang.Object) Это нужно знать, иначе рискуешь встретить коллегу, который вставит ключ в HashMap или элемент в HashSet, не переопределив hashCode(), и потом не может найти его снова. У меня такие коллеги были, как и те, кто пытался массив сделать ключом в HashMap.

Ну это проблема Java и C#, которые почему-то решили что любой объект должен уметь хэшироваться, преобразовываться в строку (даже если это бесполезный неймспейс.класснейм) и т.п. Не думаю, что тут стоит сильно винить разработчиков.
Ну это проблема Java и C#

Чисто теоретически если порасуждать то убрать это из языка уже крайне тяжело.

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

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

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

upd. Проясню. Против самой задачи я ничего против не имею. В целом такие простые задачи неплохой способ отсеять совсем слабых программистов. Но требовать, чтобы их знали, держали в пальцах, да ещё допытывать время выполнения. Возможно я в чем-то не прав (я все-таки не лид и сам собеседования не проводил ещё), но мне это кажется сильно странным.
Идея была в том, что для данной задачи вообще ничего знать не нужно, кроме, собственно, определения списка (если с этим проблемы, то это *уже* значит, что задача достаточно показательна и полезна). Алгоритм соображается на пальцах за пару минут и быстренько пишется на том языке, на котором вы собеседуетесь. Естественно, при уточнениях возможны усложнения — тут проверку, там проверку, а тут вообще в хитром случае упасть может, но я считаю, что на обычном собесе это не суть критично, вы не Яндекс, где вам дают задачу, вы молча 10 минут кодите, потом так же молча собеседующий вам ответит «неверно» и сиди думай, что не так.

И, в отличие от возможных способов построения хэш-таблиц, само знание о том, что есть такая структура — список и чем она отличается от массива и хэш-таблицы — это, на мой взгляд, обязательно знать каждому девелоперу. Не обязательно знать детали, можно загуглить. Но банальный факт, что операция «remove» в массиве будет занимать дольше, чем в хэш-таблице или что поиск элемента в списке будет долгим — это же из разряда знаний на подкорке, как можно писать что угодно сложнее хелловорлда без этого знания? Я так в коде нашего сеньора как-то увидел очевидно квадратичную конструкцию, где на каждой итерации довольно длинного цикла вызывался поиск по списку вместо того, чтобы сделать некий препроцессинг в хэш-таблицу сначала. Так и тут — если человек не понимает, какие вообще основные структуры есть (для реальной жизни достаточно знать три: массив, список, хэш-таблица) — к такому чуваку могут быть вопросы. У Гугла будут вопросы, если чувак не может хотя бы три вида самобалансирующихся деревьев назвать, но вы не гугл, достаточно базы. А базу стыдно не знать имхо.

Это не задача на графы, не задача на хитрые алгоритмы, не задача на что-то, что нельзя сообразить на пальцах. Это как fizzbuzz, я не знаю. Вы же не будете говорить, что на физзбазз вам нужно больше 5 минут?

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

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

Не факт, всё это зависит от реализации и контекста использования.

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

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


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

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


rev :: [a] -> [a]
rev [] = []
rev (x : xs) = rev xs ++ [x]

затем можно заметить что он неоптимален (аллоцирует много) и заменить на аккумулятор который работает по принципу стека, на которорый уже пара минут нужна (проверить правильность рекурсии):


rev :: [a] -> [a]
rev = revInner [] where
  revInner acc [] = acc
  revInner acc (x : xs) = revInner (x : acc) xs 

Как мне кажется, достсаточно простой вопрос, чуть сложнее fizzbuzz. С другой стороны, ни разу не писал функции разворота списка на практике. Самое близкое — stateful fmap.

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

С чего бы это? Вот определение списка:


data List a = [] | (a :: List a)

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


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

Не буду спорить, все-таки в хаскеле я не силен =)

Ну, тут всё просто. data обозначает АДТ, то есть тип-сумму, то есть энум на который можно дополнительные данные прицепить. Соответственно список либо является [] (он же Nil, он же пустой список), либо (::) (он же Cons) состоящий из элемента типа a и хвоста. Варианты удобно перечисляются через |.


Сначала немного непривычно, что конструктор это не слово а какой-нибудь оператор (например :: вместо Cons), но потом начинаешь ценить подобное удобство. Если не ударяться в крайности, то читаемость ощутимо выигрывает.

С чего бы это? Вот определение списка:

Ну вся соль задачи что аллокаций памяти в куче не производится,
и используется O(1) доп. памяти. Такое возможно реализовать на хаскелле?

Ну если вы старой версией не пользуетесь то компилято вполне вероятно соптимизирует это в мутабельную игру указателями. Но если пользуетесь, то без доп. памяти офк никак. Реверс в данном случае это List Reverse(List) а не void Reverse(List). С ситуацией когда оптимизатор может вернуть аргумент в качестве результата.

Такое возможно реализовать на хаскелле?

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

А считать первый ответ «хэш-таблица» неправильным на вопрос «Как устроен тип map» — ну, такое.

Ну вообще вопрос понятен и такой ответ говорит о том, что человек не знает, что там под капотом. Почему это важно? Наводящий вопрос: map[int]TStruct или map[int]*TStruct? Почему? В если их миллион? Почему? Правильного ответа нет. Но выбрать без понимания — ударить себя лопатой (я самоударенный, я туповат и учусь прыгая с разбегу на грабли)

Для питон разработчиков я обычно задавал вопрос "допустим мы храним телефоны как строки (а если это плохо, то как раз можно объяснить, почему), причем храним только телефоны 8-800 и 8-499. Лучше использовать хэшмап или массив, и почему тот или иной вариант".

Опечатался, имел в виду "телефоны как числа" наоборот, в противовес обычному "как строки".

Для хранения лучше массив — меньше памяти займёт. А других задач не обозначено :)

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

В смысле? Как-то непонятна задача. для меня хранить телефоны в массиве значит:


[
88001234567,
88007654321,
84991234567,
84997654321,
]

какие нуллы в каком диапазоне?

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


phones = [...., "VolCh", "PsyHaSTe", ....]
volchPhone = phones[88001234567]
psyPhone = phones[88001234568]

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

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

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

чисто любопытства ради.


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

Суть задачи — как лучше хранить привязку номер телефона — имя пользователя. Или Map<Int, String> или просто String[]


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

Ну если вы не знаете что такое хэшмап то наверное действительно стоит развернуться и уйти. Если вопрос "хэшмапа… В смысле дикт?" То можно просто получить утвердительный ответ и пойти дальше. Знакомые программисты вообще в одном предложении могут использовать оба термина, все же понимают, что речь об одном и том же. "Какие-то дельфи" — да нет, ваще-то почти во всех языках принято так называть. Кругозор "знаю больше 1 языка" тоже приветствуется и является бонусом.

"Какие-то дельфи" — да нет, ваще-то почти во всех языках принято так называть

Скажем так, во многих языках они так называются, если называются явно, хотя могут быть нюансы. Вон вы же пишите Map<Int, String>, а не HashMap<Int, String> :)

Суть задачи — как лучше хранить привязку номер телефона — имя пользователя. Или Map<Int, String> или просто String[]

очевидно зависит от того — какие операции потом будут производиться? Например, поиск имени по номеру телефона (строим какой-нибудь АОН) или наоборот — по ФИО ищем телефон (как в какой-нибудь адресной базе)

Суть задачи — как лучше хранить привязку номер телефона — имя пользователя. Или Map<Int, String> или просто String[]

тогда не очень понятно, в чём заключается доп.условие что номера только 8-800 и 8-499. Если мы храним номер как 10-значный int, то это одно. Если мы храним его как 7-значный инт плюс префикс 800/499 (может быть и бред, но мало ли кому что в голову взбредёт) то одним интом не отделаешься.


если вы не знаете что такое хэшмап

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


if "x" in the_dict.keys()

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


Map<Int, String> или просто String[]

вот о чём я и говорил, к питону это не имеет никакого отношения.


"Какие-то дельфи" — да нет, ваще-то почти во всех языках принято так называть.

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


Так вот, в питоне нет типа данных "хэшмап". И если вы имеете в виду дикт, то я развернусь и уйду. Если же это какой-то самописный class HashMap, то возможно ещё подумаю, хотя необходимость такого в питоне сомнительна.


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

Я знаю довольно много языков, как ЯП, так и человеческих. И именно поэтому, для меня важна точность терминологии. Называть хэшмапом дикт в питоне, это то же самое, что называть машину в английском "machine". Да, формально "car" и "auto" это тоже machine, но люди так не говорят. Просто сразу видно, что вы не местный. Ничего личного, но если вы при этом работаете в фирме переводов, то досвидос. Так же и со словарями и списками в питоне. Ничего личного, я уважаю Жаву как язык. Но работаю на питоне.

тогда не очень понятно, в чём заключается доп.условие что номера только 8-800 и 8-499. Если мы храним номер как 10-значный int, то это одно. Если мы храним его как 7-значный инт плюс префикс 800/499 (может быть и бред, но мало ли кому что в голову взбредёт) то одним интом не отделаешься.

Храним как 10-значный инт


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

Не понимаю, почему это должно кого-то смущать. Если знаете > 1 языка то точно проблем никаких не будет. Если не знаете — не беда, переформулирую.


Если вы используете in для проверки наличия ключа в питоновском дикте так:

if "x" in the_dict.keys()ё

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

Я никакой x in dict.keys() нигде даже близко не писал. Вы точно на тот комментарий отвечаете?


вот о чём я и говорил, к питону это не имеет никакого отношения.

Конкретно к питону офк не имеет, но обычно срашиваю на япе который собеседуемый знает.


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

Логика уровня /b/. Впрочем, склонен согласиться, что не по пути))


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

Конечно говорю. Трейт, тайпкласс, имплементировать, инвестигейт, багтрекер,… Как и большинство коллег, с которыми общаюсь.


Я знаю довольно много языков, как ЯП, так и человеческих. И именно поэтому, для меня важна точность терминологии. Называть хэшмапом дикт в питоне, это то же самое, что называть машину в английском "machine". Да, формально "car" и "auto" это тоже machine, но люди так не говорят. Просто сразу видно, что вы не местный. Ничего личного, но если вы при этом работаете в фирме переводов, то досвидос. Так же и со словарями и списками в питоне. Ничего личного, я уважаю Жаву как язык. Но работаю на питоне.

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

Я никакой x in dict.keys() нигде даже близко не писал

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


Логика уровня /b/.

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


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

пардон вы ошиблись — во-первых, здесь нет перевода. Трейт — это англоязычный термин, который не переведён, а взят как есть, перевод был бы "особенность", "черта". Во-вторых, это общепринятая практика, например слово "танк" это тоже заимствование из английского, без перевода (перевод — "бочка"). Впрочем, кому я объясняю, вы это и сам прекрасно знаете. И либо вы понимаете ошибку в вашей логике и намеренно её делаете, либо не понимаете, тогда увы о чём разговор про логику уровня /b/.


Ну значит вы "питон разработчик".

Да, когда работаешь на питоне, наиболее эффективно работать используя подходы, принятые в питоне. Пиша на Жаве — подходы, принятые в Жаве. Если вы считаете, что на всех языках одинаковые идиомы одинаково эффективны, вы не "просто разработчик", а просто не разработчик. (Не имея в виду лично вас.)


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

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

И откуда эта идиома?


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

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


пардон вы ошиблись — во-первых, здесь нет перевода. Трейт — это англоязычный термин, который не переведён, а взят как есть, перевод был бы "особенность", "черта". Во-вторых, это общепринятая практика, например слово "танк" это тоже заимствование из английского, без перевода (перевод — "бочка"). Впрочем, кому я объясняю, вы это и сам прекрасно знаете. И либо вы понимаете ошибку в вашей логике и намеренно её делаете, либо не понимаете, тогда увы о чём разговор про логику уровня /b/.

А "хэшмап" — это перевод какого слова?


Да, когда работаешь на питоне, наиболее эффективно работать используя подходы, принятые в питоне. Пиша на Жаве — подходы, принятые в Жаве. Если вы считаете, что на всех языках одинаковые идиомы одинаково эффективны, вы не "просто разработчик", а просто не разработчик. (Не имея в виду лично вас.)

Но есть общие вещи. Например "хэшмап" реализован +- одинаково и в питоне, и в жабе, и в расте, и где угодно ещё. От того что где-то его называют "словарём" (как в моем основном сишарпе, к примеру) ничего не меняет. А если вы так прикипели к конкретной терминологии, это как раз скорее для меня сигнал про неготовность к развитию. Для человека по-хорошему должно быть неважно даже на каком языке писать, не то, что какими синонимами описывать происходящее в ней.

И откуда эта идиома?

да, подумав, пожалуй не в тему =)


Если я использую распространенную терминологию

я не соглашусь, что она распространённая. Конкретно HashMap, Array — типы данных из Жавы. Честно, за 11 лет работы ни разу не слышал слова "хэшмап" в контексте питона. Map, Mapping может быть ещё более-менее, хотя в первом случае путается с функцией map(), а во втором — с collections.abc.Mapping. Конечно, я пойму, о чём идёт речь, если кто вдруг выскажется, но всё-таки предпочитаю называть лопату лопатой (call a spade a spade) :)


С другой стороны YMMV — я не работал везде, и сказать что никто не использует слова "хэшмап" вместо дикта/словаря и "массив" (прям-таки Pascal :)) вместо листа/списка, тоже не могу.


В чужой монастырь, как говорится.

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


А "хэшмап" — это перевод какого слова?

HashMap как тип в Жаве соответствует dict как типу в питоне. Т.е. перевод HashMap на язык питона — dict. :) В примере с языками я всего лишь хотел подчеркнуть, что если речь идёт о питоне, то пользоваться стоит питоновскими терминами.


От того что где-то его называют "словарём" (как в моем основном сишарпе, к примеру) ничего не меняет

Окей, обратный пример. Я прихожу на собеседование Java Senior Dev и говорю, если ключик в словаре ("in") is None..., или напишем лямбда функцию возвращающую списочек ...


Есть ли вероятность, что я бы прошёл собеседование дальше этих фраз? Даже если я бы мог написать код на жаве правильно, это всё равно выдаёт человека, которому Жава не настолько близка, чтобы он выражался принятой в ней терминологией. Ибо поработав с языком -дцать лет, ты уже не думаешь, что в теории дикт и хэшмап это одно и то же, а говоришь то, что видишь чаще всего. С другой стороны, мне вряд ли вообще пришло бы в голову назвать java.util.HashMap диктом — просто потому, что он называется HashMap, а дикт, это вроде вполне конкретный тип в питоне...


Хотя возможно я и переоцениваю влияние языка (ЯП) на язык (которым выражаешься) и обратно.

я не соглашусь, что она распространённая. Конкретно HashMap, Array — типы данных из Жавы.

А ещё из хаскеля. И из С++. И из раста. И из котлина. И из дарта. И из ...


Почему сразу считаете, что это "тип из джавы"?


Окей, обратный пример. Я прихожу на собеседование Java Senior Dev и говорю, если ключик в словаре ("in") is None..., или напишем лямбда функцию возвращающую списочек ...

Ну и нормально, говорите :)


Хотя возможно я и переоцениваю влияние языка (ЯП) на язык (которым выражаешься) и обратно.

Вот. Именно это я и хотел донести.

Я не уверен, о чём тут дискуссия, но при прочих равных я бы предпочёл термины «хешмапа» и «tree map» — у них разные характеристики сложности, разные требования к данным и разные юзкейсы. А дикт… Ну словарь можно и поверх обычного массива сделать (и так иногда даже делают в некоторых приложениях).

. хранится список номеров телефонов или номер телефона это ключ к записи? в чём вообще суть задачи?



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

Было похожее собеседование недавно на senior php.


  • паттерны проектирования знаем? — нет
  • explain в sql для чего нужен? — не знаю
  • какие виды архитектуры знаем? — не силен в теории
  • как работает DI? — человек плавает, говорит какую-то чушь про service provider
  • как с docker? — никак использую vagrant
  • с *nix как? — только основы

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


В php в этом вообще печаль-беда — куча web мастеров с портфолио на 50+ проектов на готовых движках, но задашь что-нибудь не стандартное и все человек выпучил глаза и тупит. Я лучше еще одного junior возьму и буду обучать...

Вот я всё это знаю, а толку, код писать не помогает…
Давайте только без сказок, как вы возьмете джуна и будете всему этому обучать ))) В реальности и на позицию джуна вы озвучите те же вопросы, ну может за исключением парочки из них и не услышав внятного ответа, пошлете и джуна лесом. Реалии рынка таковы, что джунов сейчас хотят по зарплате, а по требованиям это далеко не так. Часто читаю вакансии и возникает вопрос — ребята, а речь точно о джуне? Ведь по мнению сегодняшних работодателей джун должен уже все знать и уметь, но просто стоить куда дешевле человека с опытом. Я бы сам рад куда-нибудь джуном пойти. Размер зарплаты при этом не важен, пусть он будет минимальным, чтобы с голода не помереть ))) Но нет, никому такие джуны не нужны. Никому не интересно никого учить. Надо, чтобы человек пришел и просто начал работать.
Не так давно отправил запрос на вакансию с зарплатой 15 или 17 тысяч, не помню уже. Ну просто предполагая, что за такие деньги можно вообще ничего не знать, но начать получать какой-то опыт. Но нет, даже похоже там нужен готовый специалист ))) Вот только интересно, где они найдут такого на такую ЗП.
«Что должен делать специалист за зарплату 15000 рублей? Ничего, и даже немного вредить.»

Слишком демпниговать тоже не стоит, можно получить эффект "как-то он слишком мало хочет. Наверное какой-то стрёмный. Ну нафиг".

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

Да вот никому это сейчас не надо, даже если готов работать за еду, только бы опыт приобрести.
Ну это от организации зависит. В текущей например мы действительно джунов даже не рассматриваем, потому что 1 джун это обычно не плюс 1 разработчик, а минус 0,5.

Но если посмотреть на компании типа Ланита, которые продают джунов по цене сениоров, то там уже шансы выше. Я сам как раз на 15к туда устраивался в 2013м, по схожим соображениям. В 2012 пробовал в каспера, но не захотели они меня даже на собес звать.

А так: опенсорс, разработка, все дела. У меня щас в тематическом канале в телеге сидит школьник-10классник, который уже и идрис выучил, и на расте бодренько шпарит (один из коллабораторов библиотеки teloxide), и запилил свой язык на макросах поверх С, с АДТ, тайплевелом и прочими вкусностями. Хотя казалось бы — 18 лет нет человеку… Такого я б даже может взял, несмотря на наши правила)
Хотя казалось бы — 18 лет нет человеку… Такого я б даже может взял, несмотря на наши правила
Выгореть может парниша, так что на работу ему еще рано.
да мозг такая штука. Тяжело иногда ему угодить.
Ну это от организации зависит. В текущей например мы действительно джунов даже не рассматриваем, потому что 1 джун это обычно не плюс 1 разработчик, а минус 0,5.

Но если посмотреть на компании типа Ланита, которые продают джунов по цене сениоров, то там уже шансы выше. Я сам как раз на 15к туда устраивался в 2013м, по схожим соображениям. В 2012 пробовал в каспера, но не захотели они меня даже на собес звать.


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

P.s. Ужасно иногда хабр тормозит на мобильных устройствах. И это ресурс для айтишников )))

Перешел на файрфокс, хабр тормозить перестал. Чего и вам желаю.

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


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

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

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


За пол года дорос до крепкого мидла, после этого отработал год и гордо ушел в закат.


После чего на одной конфе встретился со знакомым и узнал что этот дядя освоил ruby on rails и сидит себе сапортит legacy монолит в крупной компании и счастлив.

Говорите за себя. У нас сейчас 5 джунов, 3 уже делают успехи. Еще один дорос до мидла и платим ему норм зп, еще одна уже ушла в спорт и получает зп оператора.


С джунов просим 2 вещи — стремление развиваться и умение писать код (на уровне fizzbuzz). Первые месяцы джуны сидят в офисе и проходят онлайн курсы, если есть вопросы — то спрашивают мидлов. После чего включаем в работу постепенно допуская все к более сложным задачам. Вот неделю назад буквально одному из них доверил собирать dev-сборки

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

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

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

Вы хотите найти людей, которым нравится Go. И которым нравится писать на Go.


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


И почему это никому не нравится инвестировать энтузиазм в Go?


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

Кто не любит го? Кому не нравится инвестировать энтузиазм в Go? Кто любит разбираться в расте потому что любит раст, но не любит го?
/me робко поднимает лапку
Скажем, потому что мне не хочется учитывать уйму подводных камней Go.


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

Смотрите что там написано:

Пункт 1) Достоинство выдаваемое за недостаток. В других языка заводят специальные большие документы по code style и пишут дополнительные утилиты, чтобы избежать проблемы, которой в Go нет из коробки. И уж чем, чем, а именно подводным камнем не является, так как вам не удастся сделать это незаметно, компилятор вам не даст.

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

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

Пункт 4) Вкусовщина. Подводным камнем не является, так как вам не удастся сделать это незаметно, компилятор вам не даст.

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

Пункт 6) Вкусовщина. Подводным камнем не является, так как вам не удастся сделать это незаметно, компилятор вам не даст.

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

Пункт 8) Автор статьи требует нарушить принципы языка Go — делать вещи по возможности явными.

Пункт 9) Ну так то речь вообще о разных вещах. Автор ожидает что и у функции и у простого присваивания будет одинаковое поведение. Что? Проблема в голове автора.

Пункт 10) Это второй однозначно подводный камень. Он идет 10-ым в списке претензий. Что показывает притянутость за уши большей части претензий.

Пункт 11) Совершенно логично сделано в языке.

Ну и так далее в том же духе.

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

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

Вы напрасно ссылаетесь на тот список, как на какой-то авторитет.

Все пункты спорны, но вот про 2 и 3 откомментирую: когда я игрался с кодом на Go то любое экспериментирование в стиле "давайте закомментируем использование этой переменной и попробуем всесто неё использовать константу" приводило к лавинообразному "неиспользуется там/неиспользуется здесь". В итоге я по 5 минут занимался тем, чтобы комментировать разные куски кода, или тем паче его редактировать, а потом после игрищ нужно было как-то помержить результат исследования с изначальным видом кода.


В других языках отформатированный код лежит в репозитории, а на машине разработчика он может делать что угодно. Потому что не нужно поддерживать "0 ворнингов" ПОСТОЯННО, достаточно чтобы на момент коммита было так. А это легко решается вызовом форматтера на стороне гит сервера, который проверит, что код корректно написан. Вы правда думаете, что дописать одну проверку сложно?

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


Я правда думаю, что этого никто делать не будет. Если не принуждать.

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

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

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

Чем это плохо? Глазу нужно время чтобы настроится.

А код на Go читается гораздо легче и быстрее всегда, там глаз всегда настроен на одно и то же, потому что авторы языка Go продавили определенный стандарт на code style немножко насильно.

К слову: автор утилиты go fmt даже сам не был согласен с конкретными правилами code style, принятыми для Go. Но при этом он понимал, что всё равно эти правила должны быть едиными для всех, независимо от его личного вкуса.

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

ничего выбивающегося я из десятков реп что открывал не припомню


Если вы про rustfmt, то у Go это тоже такое же добровольное как и go fmt.

Выдаете желаемое за действительное.

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

Даже живя в соседних государствах — Канада и США, в одном маленьком государстве совсем рядом — Англия и Шотландия — мы имеем разный английский.

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

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

Получается, заставлять под дулом пистолета все же нен адо?


Служители Rust — элита, осознающие что нужно придерживаться code style?
А пишущие на Java, JavaScript, Python, PHP, С++ и пр. форматируют кто в лес, кто по дрова, ибо они все сплошь быдлокодеры?

Просто языки разного поколения. Можно видеть, что чем дальше в прошлое, тем ниже культура оформления кода в среднем. У сишников лучше чем у алголовцев, а у го/раста лучше чем у сишников. Выдавать это за илитарность или нет решайте сами :shrug:

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

А для Rust специальных «чистых» программистов родили просто?

Глобально это одни и те же люди.

Причина, имхо, всего лишь в наличии легкодоступного (не нужно что-то искать и что-то ставить дополнительно) встроенного rustfmt. То есть в наличие стандарта, «навязанного» разработчиками Rust.

Нет, просто множество программистов на сишарпе и расте меньше, чем просто на сишарпе. Поэтому даже если программисты, получив опыт раста (или го) запилили у себя в попенсор сишарп проекте форматтер или линтер, то это не окажет большого влияния на процент проектов на гитхабе с настроенным форматированием. У меня вот на всех проектах оно стоит, а у моих коллег которые с растом/го не знакомы и не пользовались консольным форматтером (а только тем, что предоставляет ИДЕ) — нет.

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

Вот есть у нас условно 5% разработчиков сишарпа, которые познакомились с линтерами в других япах. И теперь на 5% нового кода с линтерами будет приходиться 95% НОВОГО кода но без линтеров. Про старый я вообще молчу, там триллионы строк кода написанного по-старому.

И это если эти 5% стали использовать линтеры во всём своём коде. Хотя, если часть из них сможет продвинуть линтеры на свои проекты, на свои команды, то конечный результат непредсказуем :)

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


Острейшая необходимость в линтере есть как раз в древнем от рождения С++.

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

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

По моим очень скромным наблюдениям с очень скромными выборками, люди, которые в гробу видали линтеры и форматтеры, также в гробу видали хаскель, раст, C++20/17/14/11 и так далее, и пишут на том же, на чём писали и 5-10-20 лет назад. И обратно, люди, которые прикручивают к репе какие-нибудь форматтеры, анализаторы, CI и прочее, почему-то интересуются, что там ещё в индустрии происходит, и приходят в понедельник на работу с историей «о, я тут, кстати, с растом игрался на выходных…»

Все пункты спорны, но вот про 2 и 3 откомментирую: когда я игрался с кодом на Go то любое экспериментирование в стиле «давайте закомментируем использование этой переменной и попробуем всесто неё использовать константу» приводило к лавинообразному «неиспользуется там/неиспользуется здесь». В итоге я по 5 минут занимался тем, чтобы комментировать разные куски кода, или тем паче его редактировать, а потом после игрищ нужно было как-то помержить результат исследования с изначальным видом кода.


Совершенно согласен, что это раздражает.

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

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

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

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

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

Эти доп. проверки основываются на "разработчик дурак, мы за него решим как лучше". Этакий эппл от мира разработки. Я считаю, что это вредно. Мало того, что разработчик не понимает, ПОЧЕМУ так сделано, это ещё и ставит палки в колёса тем, кто понимает. Проверок на уровне создания коммита или даже PR более чем достаточно для поддержания чистой кодовой базы.

Эти доп. проверки основываются на «разработчик дурак, мы за него решим как лучше». Этакий эппл от мира разработки. Я считаю, что это вредно. Мало того, что разработчик не понимает, ПОЧЕМУ так сделано, это ещё и ставит палки в колёса тем, кто понимает.


Вы серьезно?

То, что компилятор указывает вам на потенциальные ошибки вы считаете минусом? Предлагаете откатиться во времена С?

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

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

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

То, что компилятор указывает вам на потенциальные ошибки вы считаете минусом? Предлагаете откатиться во времена С?

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


если я написал print("Hello world") а потом закомментировал его я НЕ ХОЧУ получать ошибку что у меня неиспользуемый fmt — я ЗНАЮ, я закомментировал его на одну секунду проверить одну идею. После того как скомпилируется я его раскоммнетирую. Я не хочу иметь из-за этого ошибку. Варнинг — ещё ладно, но ошибку точно нет. Перед коммитом в репозиторий я конечно почищу все варнинги, но сейчас-то я не хочу тратить время на это.


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

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

Ну так не запускайте линтер при записи файла. gofmt/goimports/gofumports — другое дело, но они на такое не ругаются. Поддерживать одинаковое форматирование кода всегда, включая процесс активного редактирования кода — это одно, и это действительно очень полезно, потому что глаз привыкает и проще читать код. Гонять жёсткие линтеры каждые несколько минут и поддерживать требуемую ими чистоту кода во время активного редактирования — это уже какой-то мазохизм. Линтер надо запускать в идеале перед коммитом, очень желательно перед отправкой PR, и обязательно на CI, которая этот PR проверяет.

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

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

Для этого есть более эффективные средства, вроде комментариев FIXME/DEBUG — на которые обучен ругаться линтер, благодаря чему отпадает субъективный фактор "режет глаз", который может сработать далеко не всегда (особенно если задачу пилит больше одного человека, или просто если отвлекся и не просмотрел внимательно git diff перед коммитом).

По какой метрике считаем эффективность? )


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

Околонулевые. Более того — линтер всё-равно надо подключить и настроить, без вариантов, на любом проекте, включая личные мелкие пет-проекты. Так что даже если бы затраты были более значительными чем скопировать .golangci.yml из предыдущего проекта и добавить вызов линтера в конфиг CI — их всё-равно пришлось бы делать.

Ну вот я сейчас оцениваю затраты на подключение линтера как часов 60 моего времени. Из них часов 30 на настройку самого линтера и часов 30 на автоматизацию CI на базе ранее не встречавшегося мне и непонятного Teamcity. Речь не про Go если что, банальный PHP.

В 60 — не верю, простите. Я настраивал немало разных линтеров для разных языков и CI, столько на это не нужно. На линтер максимум часа 2-3, это если это монстр мета-линтер содержащий десятки других линтеров и его надо заточить под особенности текущего проекта. Изучение нового сервиса CI может занять много времени, но линтер тут не виноват. А подключить линтер к уже настроенному CI — дело пяти минут, максимум получаса.


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

Особенности текущего проекта:


  • линтеров не было никогда
  • навскидку используется три код-стайла в нашем основном коде, причём не строго в даже рамках одного файла.
  • куча стороннего кода, причём после трёх месяцев на проекте я ещё не знаю точно где наш, а где сторонний — только по истории коммитов смотреть надо, добавлялся он одним куском или постепенно писался. Там тоже с код-стайлом не очень
  • код на фреймворке с кучей магии, позволяющей использовать необъявленные переменные. надо как-то прикрутить проверку обязательности хотя бы аннотаций в комментариях. Выглядит как написание своего модуля для линтера. В идеале с проверкой наличия столбцов в базе для магии слоя доступа к ней.
  • тестов нет, чтоб с чистой совестью прогнать автоисправление
  • в исходниках код на пяти языках не считая SQL в строках, плюс файлы сочетающие код на нескольких языках (.ini подобные разделители секций)

Ну и сама CI с GUI невнятным. В теории можно писать пайплайны на Kotlin, но пока для меня эта возможность заблокирована.

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


Из хороших новостей: некоторые линтеры поддерживают режим "проверять только новый код", т.е. проверяться будут только те строчки, которые изменились/добавились в текущем PR. Это позволяет намного быстрее начать пользоваться линтером. Но даже если такой стиль не поддерживается, то всё-равно можно, например, за день-два отрефакторить проект так, чтобы весь, условно, старый код жил в каталоге old/ и линтер туда не совался, а все новые фичи писались в другом каталоге, который линтер проверяет максимально тщательно. Ну и дальше в том же духе можно покрутить, как сделать так, чтобы по старому коду линтер проверял самый минимум или вообще ничего, а по новому работал в полную силу. И дальше уже постепенно, по одной, активировать фичи линтера для старого кода, одновременно подчищая этот код — да, этот процесс растянется на месяцы, но зато он не будет блокировать текущую разработку бизнес-фич а код будет постепенно становиться чище.

если я написал print(«Hello world») а потом закомментировал его я НЕ ХОЧУ получать ошибку что у меня неиспользуемый fmt — я ЗНАЮ, я закомментировал его на одну секунду проверить одну идею.


Просто используйте
_ = НенужнаяФункция()
вместо
НужнаяПеременная = НужнаяФункция()
если вам так надо.

В реальности, как показывает куча подключенных ненужных зависимостей в ПО годами уже работающего в production, программисты, конечно, всё знают и всё помнят. Но забывают.

Буквально вчера исправил подобную багу из-за неиспользуемого кода, что жил на сервере года 4-5.

Подобные косяки встречаются чаще, чем вам кажется.

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


Ну это и есть дело линтера «немножко параноить». Не запускайте его просто. Или настройте до нужно вам уровня паранойи.

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

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


_ = НенужнаяФункция()
вместо
НужнаяПеременная = НужнаяФункция()
если вам так надо.

А на это я получаю ошибку no new variables on left side of :=. Видимо подчеркивание считается какой-то магической переменной, которую присваиваем а не инициализируем. Тем более, нужно тогда все := заменять на _ для такого. ИМХО неудобно совершенно.

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

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

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


Современные языки используются всё больше с IDE…
Это формально конечно «внешний тулз». Но он всегда с нами.

В современных языках это ворнинг. Который можно проигнорировать.


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

В современных языках это ворнинг. Который можно проигнорировать.

Вы говорите о нормах конца прошлого начала нынешнего века.

В старых языках — да.
В новых языках — идет обратная тенденция.

Уж очень люди ленивы, уж очень часто программисты забивают на warning.

Rust — старый язык? Idris — старый язык?


Покажите любой язык кроме Go где unused это ошибка компиляции.


Уж очень люди ленивы, уж очень часто программисты забивают на warning.

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


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

Покажите любой язык


Почему в одном языке должны быть те же принципы, что и в другом? Зачем тогда вообще разные языки?

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

тип название_переменной;
название_переменной: тип;
название_переменной тип

Разница-то в языках не только в этом.

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


Да ладно вам демонизировать.
Есть же и Python выросший тоже под крылом Google. И он другой.

Просто языки — они разные.
В этом и смысл.

Один язык не обязан следовать принципам принятым в другом языке. Иначе и смысла придумывать разные языки не было бы никакого.
Почему в одном языке должны быть те же принципы, что и в другом?

Вы же сами написали, что «в новых языках», а не «в одном конкретном Go».


Разница-то в языках не только в этом.

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

Вы же сами написали, что «в новых языках», а не «в одном конкретном Go».


Угу. Есть такая тенденция.
Сравните хотя бы диагностику GCC и Clang

gcc и clang — новые языки? Или они по умолчанию компилируют с -Werror?

gcc и clang — новые языки? Или они по умолчанию компилируют с -Werror?


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

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

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


Зачем нам совершенно одинаковые по функционалу языки? Зачем повторять другие?

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

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


Ключевая особенность и философия Go — ошибка, а не ворнинг на неиспользуемую переменную, что ли?


Зачем нам совершенно одинаковые по функционалу языки? Зачем повторять другие?

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

Вот и я не могу понять, зачем [мне] Go. Для каких задач он мне пригодится?

Вот и я не могу понять, зачем [мне] Go. Для каких задач он мне пригодится?

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


Я лично перешёл на Go потому, что он хорошо подходит именно для тех проектов, которые я обычно пишу (микросервисы и утилиты), потому, что он очень простой сам по себе, и потому, что код на нём легче читать и поддерживать. Моя жизнь после перехода на Go стала заметно легче — мне нужно прикладывать меньше усилий, чтобы написать качественный и вполне производительный микросервис, и потом его поддерживать.

Зависит от того, какого типа у Вас проекты

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


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

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

Диагностика на неиспользуемые переменные была по-моему ещё в паскале. Какие это «новые тенденции»?
Диагностика на неиспользуемые переменные была по-моему ещё в паскале. Какие это «новые тенденции»?

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

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

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


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

«Мы же умные, мы же сами решим когда их обрабатывать, а когда не обрабатывать».

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

И обмазали Яву с ног до головы необходимостью всё декларировать.

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

Я с явой не работал, не знаю, на что именно ругались люди в checked exceptions, но в хаскеле я Either и прочие MonadError очень сильно люблю (а они по смыслу довольно близки к checked exceptions), а исключения (которые по смыслу — unchecked exceptions) не люблю. И это стандартный взгляд в хаскель-коммьюнити.


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

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


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

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

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


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


_, _ = varA, varB

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

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

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

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

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


Напомните, в каком это произошло году?
А в каком году появилась Ява?

Если сравнить первую Яву и нынешнюю — там очень много изменений. Вплоть до невозможности просто перекомпилировать без исправлений сколько-нибудь сложный проект так чтобы в итоге ничего не сломалось.

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

Как IDE помогает удалять неиспользуемые импорты?
Ну, понятно всякие фичи рефакторинга — но это опять ВРЕМЯ

Подсвечивает, как минимум.


Плюс Code > Optimize imports у JetBrains

Как IDE помогает удалять неиспользуемые импорты?

Погуглите функционал goimports

В Intellij можно поставить галочку "оптимизировать импорты" во время выполнения форматирования кода. Не знаю, как все, а я часто прожимаю этот шорткат на автомате (прямо как Ctrl+S некоторые).

В Intellij можно поставить галочку «оптимизировать импорты» во время выполнения форматирования кода. Не знаю, как все, а я часто прожимаю этот шорткат на автомате (прямо как Ctrl+S некоторые).


Разве по default не включена?

У меня в Vim при записи запускается автоматически и добавление/удаление импортов, и переформатирование, и проверка на ошибки. Всё это выполняется практически моментально. Вручную импорты мне приходится добавлять где-то раз в пару недель, когда тулза ошибается. Удалять импорты вручную не приходится вообще никогда. Иными словами — Вы не правы, никому ничего не мешает.

Вот у вас есть использование форматирования в WriteLine. Вы закомментили этот код. Вам IDE автоматически импорт удалит? ПОтому что если нет то в го у вас теперь код не компилируется, ведь есть неиспользуемый импорт!

Как сам удалит, так сам и вернёт, когда я раскомментирую строку. Он сам с собой в это добавление/удаление импортов играет, по сути, я туда обычно даже не смотрю (за исключением редких ситуаций, когда есть высокая вероятность, что он автоматически подсунет импорт не той библиотеке, вроде math/rand вместо crypt/rand, или первую версию вместо /v2, etc. — но это бывает редко).

Спрашивается, и зачем тогда эти импорты в файле, если программист их не вводит и даже не смотрит на них..

Действительно, получается requirements или package.json достаточно....

Он есть — go.mod. И да, я тоже думаю, что тулзе было бы неплохо обращать на него больше внимания при поиске подходящих импортов. Но есть нюансы: иногда добавляется новая зависимость, и это делается прямо в коде, не отвлекаясь на добавление её сначала в go.mod (ибо она туда добавится автоматом сама чуть позже), иногда это стандартная библиотека, как в примере с math/rand vs crypt/rand, которую в go.mod не добавляют, иногда (редко) в go.mod подключены две мажорные версии одного пакета, соответственно какая из них нужна конкретно в этом месте кода тулза сама может не разобраться. В общем, тут явно есть, что улучшать, но вот прям сходу вообще выкинуть импорты из кода "в связи с их очевидностью" пока не получится.

Спрашивается, и зачем тогда эти импорты в файле, если программист их не вводит и даже не смотрит на них..


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

Например, в случае одноименных пакетов. В частности IDE Jetbrains подключает импорты молча, если они однозначные. И задает вопрос, если есть сходные имена (как выше с примером rand)
в случае одноименных пакетов

мне кажется, что их проще банить на уровне принятия в репо пакетовв. Или на уровне конвенций об именах делать их униками (ну, как, в джаве — com.gitlab.component.my — многословно, но этот код автогенерируется IDE)

в случае одноименных пакетов


мне кажется, что их проще банить на уровне принятия в репо пакетовв. Или на уровне конвенций об именах делать их униками (ну, как, в джаве — com.gitlab.component.my — многословно, но этот код автогенерируется IDE)


Полное имя пакета — да, уникальное.
И в импорте указывается именно оно.

Но в основной части кода при обращении к объекту из этого пакета указывается только последняя часть.

В вашем примере это будет:

my.A()
my.B
my.C{}

И если есть пакет
com.gitlab.other_component.my

то в нем могут быть ровное все те же:

my.A()
my.B
my.C{}

А как оно будет работать если функция в двух подключенных пакетах есть? Пример из жизни, у меня есть микросервис, который опрашивает 5 других микросервисов. Каждый из которых выставляет типа ServiceA.Error, ServiceB.Error,… Как эта штука будет определять, какой именно Error я имел в виду в закомментированной строке?

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

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


Кстати, а неиспользуемые переменные оно тоже так подставляет? Потому что импорты-импортами, но это общее правило. Закомментил переменную А. Перестали использоваться B, C. закомментил и их. Перетали быть нужы D, E, F. Закоментил их — теперь функция не использует входные параметры. Закомментил их — теперь нужно поправить все места, которые эту функцию вызывают… Хотя наверное я зря на это ругаюсь, и через _ это решается (и замену := на =), но все же.

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


Это чисто архитектурное решение.

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

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

В реальной развитой IDE все эти вещи глубоко под капотом.

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


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

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

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

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

А отказываться компилировать программу в которой нет ошибок это свинство


Так отказывают вам в компиляции не потому что всё в программе идеально, так же?
А как оно будет работать если функция в двух подключенных пакетах есть? Пример из жизни, у меня есть микросервис, который опрашивает 5 других микросервисов. Каждый из которых выставляет типа ServiceA.Error, ServiceB.Error,… Как эта штука будет определять, какой именно Error я имел в виду в закомментированной строке?


Поскольку Go это язык со статической типизацией — у IDE довольно-много информации, чтобы решить самой.
Ибо кроме имени функции есть еще её сигнатура.

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

Тут 2 варианта что делать при наличие дублей:

1) Или каждый раз спрашивать у человека.
2) Или запоминать последнее используемое.

А при чем тут сигнатура? Вот я пишу


Error Foo() { }

Где Error — красным подсвечен. Сейчас в том же сишарпе тул предложит импортировать Error и на выбор выдаст все пакеты, откуда он может быть получен. Автоматически это решить просто невозможно.


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

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


В Go — аналогично.
Если не однозначно, то IDE вас спросит.
Если однозначно — сама подставит.

И кстати, да, в Go у вас было бы не так как в вашем примере, а так:

module1.Error Foo() { }

Ибо внешние объекты в Go указываются вместе с именем пакета.

А это уже упрощает получение подсказок/автоимпорта от IDE.

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

Интересные аллюзии :) В смысле иронии :) В том смысле, что у С и Go одни авторы )

В том смысле, что у С и Go одни авторы

это интересный тезис и я бы переформулировал его, чтобы он был более точный. "Часть разработчиков языка С является разработчиками языка Go"


Ну, и в связи с этим не могу упомянуть:

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

Ну, опять же апелляция к авторитету — это плохой пример.
Тот же Фоменко со своей "Новой Хронологией" крышей поехал (или нет? и просто рубит капусту?) — "прошлые" заслуги — НИЧТО. Важно то, что ты делаешь сейчас.

Нуууу… Сейчас Ритчи отдыхает ))) Трудно что-то ему предъявить )

Не уверен насчёт верхней цитаты в колонке 2013, но нижняя совершенно точно относится к временам задолго до гугла — она является одним из принципов заложенных в OS Inferno.

Кстати о картинке. Гугл не является родиной Go :)
P.S. В контексте философий, а не формальностей, конечно

Интересные аллюзии :) В смысле иронии :) В том смысле, что у С и Go одни авторы )


Между языками сколько десятилетий?

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

Мммм… Около двух десятилетий. Да, несомненно все менялись. Причем довольно сильно. Вместе со своими языками