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

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

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


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

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 раз "силой" (в юности пытался заниматься спортом, в итоге из-за травмы завязал), 20 раз без разминки-подготовки для меня было абсолютно безопасным... Сильно от бэкграунда зависит...

Не поверите, но когда перестал готовиться к собеседованиям лет 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'
НЛО прилетело и опубликовало эту надпись здесь

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


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

Что-то не смог найти ни одной отсылки старше 2007 года...

В контексте разговора — нет, далеко не 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, детка :) Прошу прощения за фамильярность, но это передаёт суть

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


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

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

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

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

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

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

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

Нет, Шелл неустойчив, в отличие от.

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

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

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

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


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

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

single linked list reverse algorithm
НЛО прилетело и опубликовало эту надпись здесь

I see what you did here! :)

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

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

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

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

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

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

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

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

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

После Питона и Джавы возможности Go в этой области меня очень расстроили.

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

НЛО прилетело и опубликовало эту надпись здесь
Это игра, в которую могут играть двое.

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

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

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

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

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

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

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

Лучший комментарий :)

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

Ну это проблема 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). С ситуацией когда оптимизатор может вернуть аргумент в качестве результата.

НЛО прилетело и опубликовало эту надпись здесь
А считать первый ответ «хэш-таблица» неправильным на вопрос «Как устроен тип 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..., или напишем лямбда функцию возвращающую списочек ...

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


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

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

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


А еще это название структуры данных.

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



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

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


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

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


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

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
«Что должен делать специалист за зарплату 15000 рублей? Ничего, и даже немного вредить.»

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

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

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

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

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

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


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

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

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


Задача нормального менеджера убедить и джуна, и коллег, что джун, получая ответы на свои вопросы от них, ни у кого время не ворует, что менеджер заложил "минус 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 необходимость в линтерах меньше. Просто потому что сам компилятор проверяет суровее.

НЛО прилетело и опубликовало эту надпись здесь
Все пункты спорны, но вот про 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».


Угу. Есть такая тенденция.
Сравните хотя бы диагностику GCC и Clang
НЛО прилетело и опубликовало эту надпись здесь
gcc и clang — новые языки? Или они по умолчанию компилируют с -Werror?


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


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

То, что вам надо — есть в других языках.
Выбор языка под задачу — совершенно нормально.
НЛО прилетело и опубликовало эту надпись здесь
Вот и я не могу понять, зачем [мне] Go. Для каких задач он мне пригодится?

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


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

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

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

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

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


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

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

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

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

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


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

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

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


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


_, _ = 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 одни авторы )


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

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

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

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

То, что указывает на потенциальные ошибки — плюс.


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

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


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

Как показала моя практика компиляции библиотек, написанных на С, С++ — разработчики изначально проигнорировали миллион warning, что в результате привело к невозможности использования этих библиотек.

К сожалению, человека нужно иногда заставлять.

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

На практике все же 80% разработчиков именно что идиоты/ленивы.

И если разрешить выбирать оставшимся 20% умных/ответственных самостоятельно определять уровень warning — оставшиеся 80% просто первым делом будут отключать warning навсегда. Что значительно снизит общее качество ПО.

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

А для этого есть комментарий-прагма:


//nolint:имена,линтеров // причина отключения
На практике все же 80% разработчиков именно что идиоты/ленивы.

Очень жаль, что у вас все так печально. Только вот как я уже сказал, вы лечите проблему головной боли гильотиной. Кто мешает на CI проверять отсутствие варнингов? В итоге имеем лучшее двух миров: разработчик их видит но может временно игнорировать, а CI обеспечивает именно временность и то, что в гите не хранятся все эти "Рыбу заворачивал".


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

Очень жаль, что у вас все так печально. Только вот как я уже сказал, вы лечите проблему головной боли гильотиной. Кто мешает на CI проверять отсутствие варнингов?


Это как раз подразумевает культуру работы с кодом.

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


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

Для той же цели разрабатывался как и усложненный Java, так и упрощенный Go.

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

Вы реально знаете джависта, который шарит во всех тонкостях GC?!!! Рили?

НЛО прилетело и опубликовало эту надпись здесь

Там просто шутка в том, что у них 6 штук что ли GC )))

Да откуда вы все берете, что Go делали для идиотов? Ритчи, Томпсон, Керниган, Кокс и Пайк не идиоты. Зачем они для себя делали что-то как для идиотов? Или идиоты?

НЛО прилетело и опубликовало эту надпись здесь

Загуглите, пожалуйста. Хуже не будет. Просто чтобы это прозвучало из уст хотя бы одного из разрабов. Вообще Гугль большой — ему можно, а система зависимостей в «старом» go просто ужасна. Сейчас стало получше, но все равно завязка на публичные репозитории — этапять.

НЛО прилетело и опубликовало эту надпись здесь

Правда в том, что когда они начали его разрабатывать, Гугла даже в проекте не было, а Брин наверное ещё в Lego играл. И слова такого не было "микросервисы". Они не могли это делать для выпускников вузов, которых надо было сажать чтото там писать. Несомненно, они одними из первых подошли к снаряду микросервисов, но развить его не смогли тогда. Но теперь у нас есть UTF-8, /procfs и Golang


Дедфуд, это ты что ли? Ну камон, ты же знаешь эту историю. Я лет 10 назад в жуйке всех достал вроде

НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь

Наверное потому что авторы Go одни из первопроходцев микросервисов. Когда это ещё не было модным. Это не везение, это целенаправленное движение

НЛО прилетело и опубликовало эту надпись здесь

Я и не настаивал. Я настаивал на том, что история создания Go вообще к гуглю имеет опосредованное отношение. И это точно не было "для студентов за 50р". Это была внутренняя игрушка вполне определенного отдела BellLabs. И если cfront, utf-8 и /procfs "взлетели" тогда, то прародитель Go шёл долгим путем любимой игрушки бывших сотрудников Bell Labs

НЛО прилетело и опубликовало эту надпись здесь
игрушка получилась так себе

Путь так скажем был тернист. Но проблема там была не в синтаксисе и конструкциях. Хотя… Хотя дженерики вот они выпилили


и выстрелила только в условиях гугла

Несомненно

выстрелила только в условиях гугла и охапок студентов

Да ладно.
Полным полно широкораспространенного ПО, созданного с использованием Go.
Да хоть Docker.

Но только потому что Гугл прокачал

Но только потому что Гугл прокачал

Ну да, а Яву прокачал почивший в бозе Sun
ЯваСкрипт был прокачан Netscape Communications Corporation
Python опять Гугль прокачал.
C# — проделки MS.
А вот неплохой вроде D не взлетел — ибо за ним никого влиятельного не стояло.

P.S.:
Хотя если взглянуть внимательнее:

Docker
Проект начат как внутренняя собственническая разработка компании dotCloud, основанной Соломоном Хайксом (Solomon Hykes) в 2008 году с целью построения публичной PaaS-платформы с поддержкой различных языков программирования


Разработка Go началась в сентябре 2007 года, его непосредственным проектированием занимались Роберт Гризмер, Роб Пайк и Кен Томпсон[5], занимавшиеся до этого проектом разработки операционной системы Inferno. Официально язык был представлен в ноябре 2009 года.


Всё из Википедии.

Чтобы докер взял Go должно было что-то случиться. Про игрушку создателей UNIX/C конечно же знало какое-то количество людей. Я даже нашёл В РОССИИ несколько человек, реально что-то делавших на одной из тупиковой веток предшественников Go. Кстати это интересно, Docker это про микросервисы. Это прямо то, с чего начался путь Go. "make mainframe great again" — это Пайк/Ритчи/Керниган конца 80-ых. Несмотря на то, что когда я увидел docker, я чуть кофе не подавился, я не считал docker идеологическим наследником Go-way. Но сейчас задумался. Надо покопаться и найти, кто у них был фаном команды Bell labs и их изделий

одной из тупиковой веток предшественников Go

Если это намёк на Limbo, то я бы не сказал, что это тупик. Вложили бы в него столько ресурсов, сколько в Go — результат был бы намного круче.

Если это намёк на Limbo, то я бы не сказал, что это тупик. Вложили бы в него столько ресурсов, сколько в Go — результат был бы намного круче.


У истории нет сослагательного наклонения.

Назови 10 отличий Limbo от Go.

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


Но главное в том, что 10 отличий и не нужно — потому что на практике значение имеет ровно одно: Go писался под POSIX (и позднее дорабатывался под винду), что позволило использовать его в привычных условиях, освоив буквально пару необычных концепций (горутины и интерфейсы). Порог входа в Limbo на пару порядков выше.

Ну да, синтаксически за основу взят предшественник Limbo. Выкинуто лишнее, типа дженериков, и добавлен рантайм, обкатанный на dis-машине в Limbo. И некоторые синтаксические конструкции типа перевернутого определения переменных и сигнатур функций. Про 10 отличий я спросил потому что Go довольно мало взял в себя чего-то супернового. Точнее, в нем есть новые концепты, но основа у него уже была


Год назад, мы кстати уже говорили про Limbo :) Это я был )) Я спрашивал про дженерики в функциях

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


Ну авторы Go и не скрывают, что там еще идеи Хоара. А они — 197x-е годов.

В этом Go не одинок:
habr.com/ru/company/oleg-bunin/blog/516218
У разных гуру, как обычно, разные мнения. Разработчики объектных языков говорят о принципиальных новшествах, для реализации которых они сделали свои языки. Это Бьерн Страуструп, разрабатывавший в 1979-1986 первый вариант языка C++. Практически параллельно с ним работал Бред Кокс, автор Objective-C (1982), Бертран Майер, разработавший Eiffel (1985) с концепцией design by contract, и другие.

Однако, рассказывая историю языков, статьи вики всячески подчеркивают, что это были не оригинальные идеи, они уже были в ранее разработанных языках, и авторы концептов не просто были с ними знакомы, а использовали эти языки. Этого же мнения придерживаются некоторые гуру, разрабатывавшие структурное программирование. Например, Николаус Вирт, работавший над Алголом, а позднее разработавший Паскаль. Он полагает, что в Алголе объекты «почти были», а С++ и другие объектные языки ничего принципиально нового они не принесли.


Мы привыкли, что каждые пару лет — по новой версии Andoroid да по новому iPhone.

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

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

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

Там не совсем просто "идеи". Там совершенно конкретная история развития совершенно конкретного языка совершенно конкретной команды с совершенно определенными вехами. Одна идея. Одна команда. Один вождь. В 2009 мы узнали это как Go.

Я люблю рассказывать — я видел живой cfront. Реально. На одном дистрибутивном диске с прародителем Go

Да, я это понял ещё с твоих первых комментов тут. Я резко заинтересовался, кто это тут знает такие исторические подробности, полез в профиль — ба, да это Фил! :) Кстати, я смотрел твой доклад по теме нашей беседы и в полном восторге, спасибо!

Я в докладе кстати упустил, что Acme таки есть на Go :)

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

Про изоляцию неймспейсы. Он конечно про пакетизацию и управление запуском. И про эксплуатацию. И именно он разогрел тему микросервисов. Ну так кажется. Потому что в том же 2010 теми же cgroups было ещё невозможно пользоваться

были солярки и фрибсд ) с зонами и тюрьмами (jails). Да и параллельно с докером очень подтянулся системди

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

были солярки и фрибсд ) с зонами и тюрьмами (jails). Да и параллельно с докером очень подтянулся системди


Про Солярку не скажу. А на FreeBSDшную тюрьму Докер переплюнул довольно быстро. За пару лет.
НЛО прилетело и опубликовало эту надпись здесь

"было бы"? Да оно и было все 15 до. На том самом уровне. О нём кто-то знал, но и всё

«было бы»? Да оно и было все 15 до. На том самом уровне. О нём кто-то знал, но и всё


Вы про себя? Ну дык не значит что так было у всех.
У нас, к примеру, активная разработка, ведущаяся прежде всего на Go, уже лет 7. До этого присматривались и экспериментировали года три.

А про "до этого". 15 лет до точки "11 лет назад"

топикстартер может нанять кого угодно.

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

А в расте с борроучекером не будет таких же лавинных эффектов (правда, по другой причине)?
А в пайтоне и js с async / sync вызовами?


А в с++ с модификатором const?

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

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

slice = append(slice, item) и map[key] = value выполняют в какой-то степени одну и ту же операцию: добавляет элемент в коллекцию. Только почему-то в первом случае это можно сделать с nil-коллекцией, а во втором — нет. И, кстати, append не совсем некорректно называть функцией, вы сами такую написать не сможете.

НЛО прилетело и опубликовало эту надпись здесь
Может, стоит попробовать Rust?
Вот не уверен, что на Rust можно написать обращение односвязного списка за 5 минут. И даже за 10.
это правда. я уже потратил на Rust tour больше времени, чем на Go tour, и я пока не очень понимаю, как написать на Rust односвязный список и его обращение :)
Можно воспользоваться учебником Learning Rust With Entirely Too Many Linked Lists. Но это не отменяет того факта, что со связными списками на Rust не так-то просто работать.
спасибо!
Самое смешное, что в указанном выше туториале так и не объясняется, как правильно реализовать LinkedList в Rust.

Держите. Заняло минут 30, но связные списки в Rust – это упражнение со звездочкой. :)
Ёлки-палки, зачем вам там сырые указатели потребовались? Я уж молчу о том, что у вас там память течёт.
Ёлки-палки, зачем вам там сырые указатели потребовались?
Готовы продемонстрировать эффективную реализацию reverse для списка без сырых указателей?
Я уж молчу о том, что у вас там память течёт.
А еще нельзя узнать ни одного значения из списка. Задача была реализовать reverse, а не весь linked list. Как реализовать Drop я думаю и так понятно.
Готовы продемонстрировать эффективную реализацию reverse для списка без сырых указателей?

Уже выложил тут

Кул! Мне не пришло в голову, что можно делать mem::swap/replace для &mut Box<T>.
Но с двухсвязными так уже не сработает.

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


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

НЛО прилетело и опубликовало эту надпись здесь

Связнаые списки в Rust это задача примерно уровня "создать объект с гарантированным методом удаления из памяти в любом ЯП с GC". Есть вещи, которые просто не делатся легко в некоторых языках.


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

К слову, прямо сейчас реализую свою кривую-косую версию двухсвязных списков на Rust. Так как нужен доступ по индексу, вырезание слайса и объединение слайсов за O(1).

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

Для любой реальной ситуации есть библиотека. Например, понадобилось нам как-то держать мапу с локфри доступом и возможностью обновления. Ну я напутил прототип на arc_swap с обычной мапой. Когда нужно обновить данные — готовим мапу с новыми данными, атомарно заменяем, профит. Но оказалось, что с таким подходом мы дублируем количество используемой памяти (старая копия + новая в какой-то момент существуют параллельно), при том, что обновления обычно происходят над 1-2% структуры. Коллега пару дней попробовал руками что-то намутить, но конечно же борровчекер надавал по рукам, потому что нормально гарантировать что мы мутируем мапу на которую уже нет ссылок нет — ведь в любой момент может прийти HTTP зарпос или старый ещё только отдает данные и ему нужна копия данных.


В итоге просто взяли evmap, почитали немного документации и всё заработало. Под капотом там наверняка всякий ансейф и прочее, но нам это не очень интересно, бенчи показывают успех, бизнес доволен. Так же и для связных списков, и для деревьев, и для всего остального, есть крейты со стабильными реализациями этих структур, а т.к. больше 1 раза их реализовывать не надо, то и сложность их написания не очень важна… Если только нет цели показать, что структуры данных которые элементарно делаются в одних языках сложно выразить в других. Может и так, но их выразили, и их можно подключить одной строчкой и пользоваться, как и везде. А сколько там страдали авторы прежде чем его родили — любопытно, но не более того.

В моем случае есть IndexList, который позволяет индексироваться по спискам, но не позволяет сливать и разрезать их за O(1). Чтобы это было возможным, необходимо чтобы группа листов шарила общий аллокатор (Vec).

Но стоп, кому то приходится эти структуры писать. Хорошо что не нам конечно =)

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

НЛО прилетело и опубликовало эту надпись здесь
А если хочется без ре/аллокаций? Хаскель справится?
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Нет заимствований – приходится терпеть сборку мусора.
НЛО прилетело и опубликовало эту надпись здесь

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

Ну если не надо, не делай, не понимаю вопроса) Линейные типы в хачкеле ничем не "менее линейные" чем в расте.

Можно врубить unsafe, и написать как на сях. Только тогда приходит осознание, что на сях простая реализация не такая уж и правильная, а правильная везде сложная.

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

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

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

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

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


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

p.s. могу ошибаться, но я бы не был столь категоричен относительно lock-free структур в Go. Вы уверен, что они там всегда есть?
> относительно lock-free структур в Go. Вы уверен, что они там всегда есть?

чтение из sync.Map — lock free, по большей части: golang.org/src/sync/map.go?s=1149:2596#L104

правда, чтобы было так, надо, чтобы записей в мапу оказалось достаточное количество: golang.org/src/sync/map.go?s=1149:2596#53

Ну не, так низя говорить. По большей части тогда и спинлоки можно считать lock-free при низком контеншне :)
Ваще с темой lock free я был бы очень осторожен. Может оказаться, что ответ "нет" не совсем неверный. В отрыве от архитектуры, в общем случае, в go нет lock free структур. Пакет atomic гарантирует атомарность, но нигде не гарантирует её без блокировок. Вроде на arm он использует локи.

ну вот это ответ на 7-8. отличается существенно от категоричного «нет», не правда ли?
какой же ответ на 10?
шкала 0-9. и 9 — это знать, что там у sync.Map внутри.
НЛО прилетело и опубликовало эту надпись здесь
Есть ещё категория, я бы назвал её «синьоры поневоле». Два с половиной года назад я устроился в компанию мидл фронтенд разработчиком. Спустя полтора месяца ушел лид нашей команды, меня вызвали к руководству и радостно объявили, мол «поздравляем, ты теперь тимлид; вот твои два джуна, вперед». И внезапно ты остаешься тем самым человеком, который должен решать самые нерешаемые проблемы. Спросить помощи не у кого, причем не только по технологиям, но и по проекту. А проект сильно мудреный (частично из-за мудреных бизнес-процессов, частично из-за ужасного кода). И с одной стороны у тебя код, с другой джуны, которым нужно дать задание и отревьюить их код, с третьей бизнес, которому постоянно нужны фичи. И в такой момент, единственное, о чем думаешь — это то ЧТО надо сделать, а не то, ПОЧЕМУ надо делать именно так. И у тебя растет опыт. Опыт практического решения практических задач. И ты начинаешь думать, что ты крут. Вот прям КРУТ. И задачи, которые до тебя два года никто не решался сделать ты сделал, и джуны твои уверенно растут, и бизнес доволен и счастлив. И очень трудно убедить себя в обратном. Мне помогло внезапное расширение команды пол-года назад. Получилось оставить себе только менеджерские функции, а фичи для прода вообще не писать. И появилось время на осознание тщетности бытия своего настоящего уровня. И я понял, что фундаментально я не сильно ушел от того уровня, который был два года назад, когда я только стал «тимлидом». И все мои крутые решения это «прочитай 10 статей, где люди решают частично похожие проблемы и на основании прочитанного напиши нужное тебе решение». А вот дай мне сложную задачку и лист бумаги с карандашом — и я вряд ли смогу написать что-то вменяемое.
ну я так в CTO угодил однажды :)
Ну так подавляющее большинство сеньеров такие.
Или вы думаете, что каджый сеньер — магистр компьютерных наук идеально знающий свой язык? Да таких на весь мир единицы в каждой области. И их имена на слуху. Разговариваете с сеньером, имени которого никогда не слышали? Ну так он обычный специалист, просто не идиот и с большим опытом.
Ну прочитают эту статью потенциальные кандидаты, вызубрят ответы на вопросы и расскажут их вам, что изменится-то? Или вам надо чисто формально, чтобы «сдал экзамен», а дальше уже не ваша забота?

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

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

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

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

Я про, например, PHP могут на день вопросов подготовить, минимум. Но на собеседованиях на позиции где PHP на первом месте в технологиях меня лично о PHP практически не спрашивают. Самый распространённый, пожалуй, "что больше всего запомнилось, понравилось в изменениях самого PHP?" и после ответа "появилось ООП в 4 (1999 для справки) и к 5.3 (2009) стало юзабельным", разве что "а в 7.*(2015-2020)?" ещё уточняющий и больше по языку вопросов нет.

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

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

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

> С чем работать — это одно. Что будут спрашивать — совсем другое.

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

Некоторые связи довольно очевидны без вопросов. Например, если на позицию PHP-разраба спрашивают по HTML и JS в некоторых компаниях/проектах без упоминания их в вакансии. Зато спрашивают про OpenAPI, который тоже не упоминался. Объединение множеств "очевидных" смежных технологий я могу на сотню пунктов набросать навскидку. Угадать конкретное подмножество практически нереально.

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

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

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

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

А мог бы просто оставить комментарий // this is obviously correct и пойти дальше, как принято в "настоящей разработке". Хотя в мейнстриме для такого даже комментарий не принято писать.

НЛО прилетело и опубликовало эту надпись здесь

Да, неприятно. С другой стороны для меня агда это что-то вроде J, только с привкусом TeX, так что меня это не особо затрагивает, прикосаться к нему желания нет. А вот на идрисе я бы чего интересного пописал, жаль экосистема отсутствует. А самому её делать — ну не знаю даж… В последние несколько месяцев мотивация подупала.

НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь
Вот как назвать переменную Γ⊢[x↦ε]τ чистой латиницей?

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

НЛО прилетело и опубликовало эту надпись здесь

О, судя по коду, Агда умеет в затенение переменных?

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

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

это прекрасный ответ, но на другой вопрос. soft skills, конечно, overrated, но заполучить в команду человека, да не линейным программистом, а лидом, который так будет реагировать на задачи в трекере — мало кто хочет.

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

Потому что задача не сформулированная нормально. Термин "разворачивание" неоднозначный.

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

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

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

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

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

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

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

Несомненно

Я к тому, что обычный бизнес обычно не может уверенно сформулировать требования к разработчику на уровне задачи для HR/ОК, пока не найдёт человека, который ожидания бизнеса от ИТ-подразделения (пускай из одного человека) не сможет конвертировать в типовую вакансию и методологию проверки кандидата на соотвествие.

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

Спрашиваете про прометеус? А может быть, он знает TICK стек. Или работал со спланком. Или у него на предыдущем проекте было хитрое ТЗ, но он виртуозно кладет метрики по UDP? Ничего из этого вы не узнаете. Вы ткнете своим очень узким вопросом и скажете «ок, хорошо». Или «нус, как такого можно не знать сеньору, давайте дальше». Максимум, что вы проверите — умеет ли человек в: «фак, я не знаю, но ладно, порассуждаем». Большинство же кандидатов такой вопрос переведет в состояние: «блин, интервью провалено, интересно, долго ли еще мучиться». Проиграете здесь вы.

Что делать?

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

Очень не советую «тащить список вопросов себе», если вы хотите нанимать. Уверен, это просто быстрый способ ЧСВшнуть и оскорбиться «ужасным состоянием рынка».
сколько глубоких технических интервью открытыми и уточняющими вопросами, совместно работая над задачей, похожей на ту, что кандидат умеет решать, а еще лучше — на знакомой кодбазе вы способны провести в месяц, коллега?
спервадобейся? пять баллов!
Около 70. Это 2-3 в день по 45 минут. А Вы?

Можно, я приду к вам на собеседование? С целью обмена опытом

На собеседование с кандидатом, к сожалению, нельзя. Мы собеседуем 1-1, чтобы не пугать и не нервировать. Но созвониться, конечно, можем — расскажу и покажу наш флоу, matvey@amixr.io
я как раз на место кандидата хотел. напишу в почту, спасибо!
Готовьтесь к вопросам по Python, я подготовлюсь к ответам на Go :)

Трансляция будет?

В итоге оба не пройдут с оценкой примерно 3/10 и комментарием «не тянет даже на мидла».

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

Это если считать "не тянет" как "не может ответить точно".

Не понимаю, как можно не знать "конкретику". Ну какие-то совсем детали типа "как реализуются разные уровни транзакцийй в СУБД" ещё могу понять, то вот историю пару лет назад что чувак собесился на сениор сишарп вакансию и не смог ответить зачем нужен кейворд virtual… По-моему это как езда на велосипеде. Когда на собеседовании на программиста неиронично спрашивают физзбазз мне даже интересно, кто эти люди с опытом работы программистом в резюме которые его не могут написать...

Попробовал как-то проехать на велосипеде после 20 лет перерыва. Минут 5 ушло на то, чтобы первые 50 метров проехать с торможением и поворотом. Да и потом навык явно не полноценно восстановился.

10 лет не катался на велосипеде, со школы. Когда появилась работа в паре км от дома, решил что пешком ходить далеко, а на ОТ ездить — близко. Купил велосипед, сел, поехал. Никаких проблем :shrug:. Первые буквально пару метров немного неловко ехал, потом нормально. Конеш старых трюков типа "захеать на высокий бордюр" сходу делать будет опасно, но ездить проблем никаких.

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


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


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

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

for — это не конкретика. Хотя синтаксис этого самого for я вполне себе позволяю не помнить, особенно если приходится одновременно писать на 3-4 языках. Я знаю, что он бывает в стиле while по условию, бывает в стиле C с инициализацией и постусловием, и бывает в стиле range/итератора. Сколько из этих стилей поддерживает текущий язык и через какую пунктуацию они в нём записываются — я могу и не помнить, и это норм. А вот если такое не помнит миддл, который обычно пишет на одном языке — это сразу заставляет заподозрить, что он этого языка вообще не знает (либо, что более вероятно, он дико волнуется на собесе и надо переключить разговор на отвлечённые темы чтобы он успокоился, а потом вернуться к вопросу про for).

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

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

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

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


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

(исключая ситуации когда порядок реально очевиден — вроде x,y или login,pass — и нет нормального способа этого избежать)

У вас логин и пароль имеют одинаковый тип?


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

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

НЛО прилетело и опубликовало эту надпись здесь

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

Кто сказал Lombok?

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

штук 40
мы уже списались с коллегой Matvey-Kuk, и у него не все так просто :)

он, фактически, выдает тестовое типа «почитать код», и просит покодить в реальном времени.

а у вас как устроено?

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

Ну а чем это лучше чем выбросить сразу половину резюме «нам неудачники не нужны»? И чем тут настолько гордиться что аж статью писать
Еще этот список — быстрый способ найти работу, только не работнику, а очередному гуру по их найму.
Пару вопросов из списка, в паре с реальными короткими задачкой — имхо намного более эффективно, чем просто пройтись по зачастую ненужной теории (хеш-меп как уже было сказано) и edge-caseам структур. Которые опять таки, зачастую можешь из-за дня в день делать правильно, при этом уже и позабыва поведение при «неправильно»
Ну как в примере с чтением из закрытого канала
Оно вроде бы как и важно, но по сути столкнувшись с этим первый раз — второй уже будешь работать через v, ok на автомате, если вообще стоит вопрос о закрытых каналах. А что именно там происходит в v < — closed из памяти вполне и выпасть может…

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

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

Конкретно про go, из простых, полезных вопросов что задаю — напишите прорамку, которая принимает из stdin int, по одному на строчку, запускает некую обработку, для примера — рандомальный sleep, не больше 128 паралельных исполнений.
Чаще всего очень быстро приходится дополнить — без дополнительных библиотек, только stdlib, без гугла, без документации.

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

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

ЗЫ, к слову о rust vs go
Есть проект, который мне достался в наследство, на который тоже ищу кандидатов, он написан на rust. Я его называю SSAS, Stupid simple api service. Утрирую, но ничего заоблоачного там нет и на мой взгляд rust не оправдан.
Искал месяца 2 на позицую на rust. С кандидами в целом было плохо, тех кто утверждали что знают раст вообще единицы. Задачку выше на расте никто не решил и за половину времени.
А даже те кто вообщем то действительно как-то раст знали, запутались в трейтах, что можно, что нельзя, почему некая стороняя библиотека(на раст разрешал делать что угодно, хоть с stackoveflow скопипастить) не работает с аргументами комманды(там я просил аргументы, а не stdin) и много чего еще. В общем это была боль.

В конечном счете я решил просто переписать на go и искать соответствующе. Стало проще. Ибо не готов я повторять эти поиски кандидатов на rust, в отличии от go, такой ряд теоретических вопросов становится намного важней, а найти и так сложно.
Пару вопросов из списка, в паре с реальными короткими задачками — имхо намного более эффективно, чем просто пройтись по зачастую ненужной теории (хеш-меп как уже было сказано) и edge-caseам структур. Которые опять таки, зачастую можешь из-за дня в день делать правильно, при этом уже и позабыва поведение при «неправильно»
Ну как в примере с чтением из закрытого канала
Оно вроде бы как и важно, но по сути столкнувшись с этим первый раз — второй уже будешь работать через v, ok на автомате, если вообще стоит вопрос о закрытых каналах, либо что еще более вероятно — range. А что именно там происходит в v < — closed из памяти вполне и выпасть может…

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

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

Конкретно про go, из простых, полезных вопросов что задаю — напишите прорамку, которая принимает из stdin int, по одному на строчку, запускает некую обработку, для примера — рандомальный sleep, не больше 128 паралельных исполнений.
Чаще всего очень быстро приходится дополнить — без дополнительных библиотек, только stdlib, без гугла, без документации.

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

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

ЗЫ, к слову о rust vs go
Есть проект, который мне достался в наследство, на который тоже ищу кандидатов, он написан на rust. Я его называю SSAS, Stupid simple api service. Утрирую, но ничего заоблоачного там нет и на мой взгляд rust не оправдан.
Искал месяца 2 на позицую на rust. С кандидами в целом было плохо, тех кто утверждали что знают раст вообще единицы. Задачку выше на расте никто не решил.
А даже те кто вообщем то действительно как-то раст знали, запутались в трейтах, что можно, что нельзя, почему некая стороняя библиотека(на раст разрешал делать что угодно, хоть с stackoveflow скопипастить) не работает с аргументами комманды(там я просил аргументы, а не stdin) и много чего еще. В общем это была боль.

В конечном счете я решил просто переписать на go и искать соответствующе. Стало проще. Ибо не готов я повторять эти поиски кандидатов на rust, в отличии от go, такой ряд теоретических вопросов становится намного важней, а найти и так сложно.

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

А на Сях принимается? :)

А на Сях принимается? :)

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

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

Добавил в закладки. Если ещё раз придётся писать что-то на Go, то пройдусь по списку.

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

P.S. Или ему скажут, что здесь и здесь используется это и он должен, при необходимости, справиться с поддержкой этого кода вне зависимости владеет ли он GO при этом?
(понимаю, что это маркетинго-рекламная статья и дальше интервьюреюмый будет заселён на необитаемый остров для кодинга без всяkих Github и.т.д ресурсов в условиях IT посакколапсиса :)
Всё равно, кого бы не было принято решение на наём в контору оно не будет «идеальным».

Ну, имхо базовые структуры данных знать надо. Потому что на ревью у нас регулярно бывает, что человек создает массивчик из 10 констант и потом делает if (MyConsts.Contains(thisValue)) { ... }. Регулярно прошу сделать вместо массива хэшмап. Объясняю, что одно вычисления хэша (no-op для энума который обычно просто int) и доступ по индексу куда быстрее итерирования по многим элементам коллекции. Не столько потому, что я люблю микрооптимизации, а сколько для прививания привычки "Contains можно делать только на множествах". Помогает потом не делать Contains на каком-нибудь вычисляемом поле в БД.

сеньер на этом месте еще и напишет микробенчмарк, который выявит, действительно ли map быстрее.
НЛО прилетело и опубликовало эту надпись здесь
  1. я практически уверен, что шарповый джит это не съест. Собсна да
  2. подобная привычка может и не дает особого выигрыша на маленьких массивах, но там на самом деле не так важно, 100нс или 200нс занял поиск. Зато минимизирует риск сделать Contains на массиве из миллиона элементов (не раз такое наблюдал).
НЛО прилетело и опубликовало эту надпись здесь
Вообще говоря, Vec выгоднее HashSet вплоть до ~220 байт (u8) либо ~40 u64, конкретно на моей машине, конкретно для Rust. Причем, вплоть до ~100 байт выиграшь более чем в два раза. Так что можно смело пользоваться такого рода оптимизацией даже на ощутимого размера списках.

А сколько это в наносекундах? Потому что это правило не про то, как оптимизировать список из 40 элементов, а как не искать за линию в множестве из миллиона.

Это примерно ~10ns на элемент, с возможностью оптимизации до ~3-5ns.

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

К тому же, часто бывает так что элементы изначально заданы в виде чего-то типа вектора. В таком случае, если мы точно знаем что их всегда маленькое количество и нет corner cases, то преобразовывать вектор в хешмапу ради поиска это overkill.

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

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

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


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

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

НЛО прилетело и опубликовало эту надпись здесь
Ура! :D

А что в значениях хэшмапы? Что с памятью?

На мой взгляд, сеньор, всё же, должен представлять ассимптотики алгоритмов и стандартной библиотеки (а также такие особенности сортировок как stable/unstable), иначе он рискует попасть в ситуацию, когда код тормозит, а почему – хз. А ответ – простой, из разряда того, что он случайно написал квадратичную сложность вместо линейной.
А по логам просто нельзя посмотреть где тормозит?

Нет. Как минимум потому что любые логи — сами по себе «тормозят». А включение логов может изначальную картинку вообще перевернуть с ног на голову (как в квантовой механике — измерение влияет на объект измерения)

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

У нас никакого HFT, но при этом логгирование в консоль просаживало RPS сервиса авторизации в 10 раз. Не нужно недооценивать роль инструментации в оверхеде на производительность.

Вы синхронно в логи что ли пишите? Или пишете туда целые эпопеи?

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

Ну так, логи надо в отдельный тред через wait-free буфер сбрасывать, чтобы не влияло на перфоманс.

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

А потом буфер переполняется и логи теряются… Типичный кейс из жизни. Да, это проблема. Но решаемая

НЛО прилетело и опубликовало эту надпись здесь

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

а можно просто экспортировать метрики.

А запись метрик, разумеется, никакие локи не берёт и информацию ни в какие буферы не складывает.

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

прометеевский экспортер — на атомиках

Атомики всё ещё медленнее обычных load/store

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

НЛО прилетело и опубликовало эту надпись здесь

А по логам зачастую "тормозит везде" и логи ничем не помогают. Помогает понимание где какие лишние действия происходят.

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

У вас очень наивное представление о профилировании. Если программа писалась не левой пяткой, а с хоть с каким-то пониманием перфоманса, то там не будет никаких "бутылочных горлышек", которые вносят 80% тормозов.

А по логам просто нельзя посмотреть где тормозит?

В лоб — нет, не увидите.
Читать логи (а также в них грамотно писать) тоже нужно уметь.

Или, к примеру, это множество быстрых событий, но тормозит из-за того что их множество — тем более не просто. Суммарное торможение видно только если просуммировать время этого множества быстрых событий. Вам часто приходилось суммировать записи в логах (да еще и по определенному фильтру), вы и инструменты сходу назовете, которыми это будет сделать удобно?
Вероятно, так бывает, но почти всегда тормоза в реальных системах — это какой-то один грубый косяк, который по логам видно невооруженным взглядом.
Доказательств этому конечно же не будет?
Ну и удачи покрыть логами набор операций, длящихся микросекунды, и как то выводы о узких местах потом по таким логам строить.
Мир IT не ограничивается интернет магазинами по продаже обоев, представьте себе.
НЛО прилетело и опубликовало эту надпись здесь
Что мешает взять файл поменьше и прогнать на тестовой среде?
НЛО прилетело и опубликовало эту надпись здесь
onokonem
Ответ на все 28 вопросов давно дал Александр Чистяков, alexclear, я думаю вам знакомо это имя.

Цитирую:

Ну а смысл быть сеньором за пять кусков, когда можно быть джуниором за три?
Меня это всегда удивляло.
Сеньор — 5, джуниор — 3, это что, один сеньор приносит конторе меньше пользы, чем два джуниора?
***но это тогда, а не контора.
Или сеньор ***но.
Или Москва.


(источник alexclear.livejournal.com/489205.html )
не хочу регаться в ЖЖ, поэтому спрошу у вас. Вы не знаете где автор откопал джунов, получающих по 3K? Я б пошел туда.

Это был 2013 год.

хорошо, где в 2013-м джунам платили по 3K? Или это в рублях?
Android/IOS разработчикам в Москве. За 70-80к рублей на позицию джуниора точно брали.
В 2013 сплошь и рядом было в Москве. Толковых джунов днем с огнем искали и сметали с рынка.

Не знаю кто там джуном сметал, я в 2013 на 15к полставки устраивался и считал, что мне повезло, мог с универом совмещать. К 2016 я вырос до 100к.


ИМХО зарплаты не особо поменялись за последнее время в долларах. Сениоры как получали порядка 4к долларов, так и сейчас получают. А то на одной чаше весов я вижу комментарии лдей у которых 5к не деньги, и у которорых джуны по 3к получают, а с другой статистика моего круга где медианная ЗП разработчиков в РФ — 108к.


Уж не ложная ли это память?


В 2013 г. средняя зарплата российских специалистов по разработке ПО, включая менеджеров, составила $2645 или около 80 тыс. руб., говорится в предварительных итогах уходящего года отраслевой ассоциации «Руссофт».

По данным этого некоммерческого партнерства рост зарплат в 2013 г. составил в среднем 15%. «В 2012 г. этот показатель проседал до 7-8%, а по итогам 2011 г. рост был сопоставим с показателями 2013 года — 18%», — говорится в отчете ассоциации. Данные для аналитики подавали ее участники: около 70 компаний, в штате которых состоит порядка 17 тыс. сотрудников.
По статистике того же круга — в Мск средняя зп 160к. Для всего айти вместе с 1С и тестерами ручниками. Не надо тут!
В 2013м 160К в Москве было прям очень хорошо (5+K$) и не то, чтобы прямо везде валялось.

Это просто рубль улетел в жопу, сейчас джуны должны получать соответственно 300к, а сеньёры - 500-1000к.

не хочу регаться в ЖЖ

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

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

но, когда мы на прошлой неделе разговаривали — он все еще был сеньером :)
так он сперва добился!
Самый популярный неправильный ответ: «Это хеш-таблица». Да, это хеш-таблица.

Самый популярный неправильный ответ: «Вернется ошибка». Да, вернется.

Самый популярный неправильный ответ: «Я не пользуюсь стандартным логгером». И никто не пользуется, сюрприз! Но почему?

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

Самый популярный неправильный ответ: «Gorm, вроде, неплох». Конкурирует с ответом «Я всё пишу руками». Я даже согласен с обоими ответами


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

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


Go — императивный или декларативный? А в чем разница?

Императивный. Разница в том, что декларативные языки обычно никто не понимает :).


Что такое type switch?

switch variable.(type), позволяет обработать разные типы одной переменной удобным способом.


Как сообщить компилятору, что наш тип реализует интерфейс?

var _ interfaceName = &typeName{} // если typeName это структура


Вот только делать этого обычно не нужно.


Как работает append?

Просто вставляет в конец слайса, пока есть место (capacity), и увеличивает его в N раз (вроде 1.5, но могу ошибаться), когда место кончается.


Какое у slice zero value? Какие операции над ним возможны?

Полностью эквивалентен слайсу нулевой длины и емкости за исключением того, что при сравнении на nil будет true, а не false.


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

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


Каков порядок перебора map?

Случайный.


Что будет, если читать из закрытого канала?

Хз. Знаю, что можно делать range по каналу, и итерация остановится, когда канал закроют. Видимо, вернется nil value, но я в реальном коде такого не видел.


Что будет, если писать в закрытый канал?

Паника.


Как вы отсортируете массив структур по алфавиту по полю Name?

sort.Slice(arr, func(i, j int) bool { return arr[i].Name < arr[j].Name })


Что такое сериализация? Зачем она нужна?

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


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

Одну, потому что я скопирую этот код из Stack Overflow. Ну и давайте серьезно, никто в Go односвязные списки всё равно не использует.


Где следует поместить описание интерфейса: в пакете с реализацией или в пакете, где этот интерфейс используется? Почему?

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


Предположим, ваша функция должна возвращать детализированные Recoverable и Fatal ошибки. Как это реализовано в пакете net? Как это надо делать в современном Go?

Да кто ж его знает, как она в пакете net реализована :)? Можете использовать errors.Wrap(), errors.Is() и прочее, но так вроде мало кто делает пока что.


Главный недостаток стандартного логгера?

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


Есть ли для Go хороший orm? Ответ обоснуйте.

Вряд ли. ORM вообще не бывают хорошими.


Какой у вас любимый линтер?

go vet


Можно ли использовать один и тот же буфер []byte в нескольких горутинах?

Если только для чтения — можно. Для чтения и записи — нельзя.


Какие типы мьютексов предоставляет stdlib?

Что за дурацкие вопросы? Вроде есть Mutex и RWMutex. Что дает это знание :)? Есть ещё ведь как минимум атомики и каналы, но это не мьютексы.


Что такое lock-free структуры данных, и есть ли в Go такие?

Структуры, не опирающиеся на мьютексы (наверное?). В Go таких нет. В Go даже sync.Map использует мьютексы для записи.


Способы поиска проблем производительности на проде?

Обычный линуксовый perf прекрасно работает, начиная с 1.5 вроде. Ну и pprof, конечно же.


Стандартный набор метрик prometheus в Go -программе?

Вот вообще без понятия. Не все используют prometheus, и не очень понятно, почему должны :).


Как встроить стандартный профайлер в свое приложение?

import _ "net/pprof" или как-то так.


Overhead от стандартного профайлера?

Зависит от приложения. Обычно не очень большой, от силы должен быть 10-20%, но я видел и в несколько раз замедление как-то.


Почему встраивание — не наследование?

Потому что это разные концепции, очевидно :). Не знаю, что ещё тут сказать.


Какие средства обобщенного программирования есть в Go?

До Go2 таких средств нет. Кодогенерация не в счёт. Интерфейсы тем более.


Какие технологические преимущества языка Go вы можете назвать?

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


Какие технологические недостатки языка Go вы можете назвать?

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

навскидку — 6+, скорее больше, но надо ополнительные вопросы задавать.

элементарщина же? элементарщина!
Как работает append?

Просто вставляет в конец слайса, пока есть место (capacity), и увеличивает его в N раз (вроде 1.5, но могу ошибаться), когда место кончается.


Вы ещё забыли упомянуть восхитительный подводный камень append: она меняет переданный слайс in-place, если это возможно, а если нет — выделяет новый, в который копирует содержимое старого. В обоих случаях возвращается тот слайс, в котором лежит добавленный элемент(ы), из-за чего банальный vec.push(item)/vec.push_back(item) в других языках программирования превращается в
slice = append(slice, item)

, вынуждая повторять путь до слайса дважды.

Какие технологические преимущества языка Go вы можете назвать?

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


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

я вот недавно выяснил, как реализовано это в виде библиотеки на rust (tokio). и оказалось, что, если ты хочешь, чтобы оно нормально работало, весь IO тебе надо делать на tokio, и всю синхронизацию на tokio, и все таймеры на tokio.

в этом свете решение внести эту функциональность прямо в runtime уже не выглядит таким уж кривым.

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

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

Сложностей нет ровно до тех пор, пока вы контролируете 100% кода, который исполняется. То есть, как правильно заметил Даниил, весь код должен быть асинхронным и написанным с помощью этой библиотеки, иначе можно случайно, грубо говоря, вызвать какой-нибудь библиотечный метод, который начнет писать в файл или делать какие-нибудь синхронные сетевые вызовы (условно, в DNS сходить или что-нибудь такое), и отследить это бывает очень сложно. В Go же можно на эту тему особо не переживать и весь библиотечный код будет гарантированно асинхронным. Он может содержать другие сюрпризы, например паники в горутинах, которые Вы не контролируете, но это уже другой разговор.

НЛО прилетело и опубликовало эту надпись здесь

(на правах сарказма)


haha unsafePerformIO goes brrrr

НЛО прилетело и опубликовало эту надпись здесь

haha {-# LANGUAGE Trustworthy #-} goes brrrrr

НЛО прилетело и опубликовало эту надпись здесь

Сдаюсь, у меня brrrrrr закончился.

Сложностей нет ровно до тех пор, пока вы контролируете 100% кода, который исполняется. То есть, как правильно заметил Даниил, весь код должен быть асинхронным и написанным с помощью этой библиотеки, иначе можно случайно, грубо говоря, вызвать какой-нибудь библиотечный метод, который начнет писать в файл или делать какие-нибудь синхронные сетевые вызовы (условно, в DNS сходить или что-нибудь такое), и отследить это бывает очень сложно.

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


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


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

писать это мы все умеем.

читать эту лапшу — вт что трудно
Это может потому что у одного сладенького пирожочка кривые руки? :)

Ну так покажите, как надо, маэстро.

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

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


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

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

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


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

Это в целом больше не является правдой с введением асинхронного вытеснения горутин в одной из последних версий (1.14 вроде): https://medium.com/a-journey-with-go/go-asynchronous-preemption-b5194227371c

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

Я немного о другом: если мне нужна операция "дождаться результата горутины", то мне туда надо пихать какой-то код помимо бизнес-логики, а я бы хотел саму запускаемую функцию не менять. Собственно, в том же tokio функция для запуска асинхронных задач возвращает ручку к этой задаче, на которой я могу вызвать .await, чтобы получить то, что функция вернула, причём я могу это сделать не сразу, а положить в какую-нибудь коллекцию, а достать и дождаться исполнения уже позже, или вообще положить в FuturesUnordered, чтобы дождаться нескольких задач сразу.

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

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

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

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

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

Тупо по времени непрерывной работы. И никак не настраивается, ага. Смешно.

Неправда. Точно помню, что я использовал токийный таймер на actix-rt, например. Да и в целом, асинхронные примитивы в расте построенны больше вокруг общей инфраструктуры std::future::Future, а дальше есть tokio/romio/async-std/… хз какие там ещё придумали, мне в целом токио хватает. Но я вижу ценность в том, что это библиотека, а не стд. Токио 0.1 и 0.3 отличаются разительно, 0.2 вообще проскочили потому что там прототипировали просто адски. В итоге 0.3 это сплав из 0.1 и 0.2, в парой любопытных идей.


Если бы это было в СТД, то мы бы никогда не увидели нормального интерфейса, костыли 0.1 тащили бы до скончания веков. Так что подход "библиотеки, а не язык" я считаю более чем правильным. Вот пошли на поводу и асинк-авейт сделали на уровне языка — ну всё, теперь там пин/анпин и прочая хрень, которую невозможно запомнить. Я пару раз пробовал, и бросил — гиблое дело. Просто не пользуюсь пинами вообще, зато регулярно читаю плач людей которым оно позарез надо.


Так что функциональность в рантайме — та ещё проблема.

что именно «неправда»?

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

использовать токийный таймер на actix-rt ничто не мешает, но не появится ли у нас от этого два event loop в программе? я не в курсе, но, насколько я понял — это конкурирующие реализации экзекутора.

в go же доступ к шедулеру ограничен оператором
go
. внутри можно перепахивать все очень серьезно — например, в 1.14 появилась вытесняющая многозадачность — и на коде это не отразится никак.
использовать токийный таймер на actix-rt ничто не мешает, но не появится ли у нас от этого два event loop в программе? я не в курсе, но, насколько я понял — это конкурирующие реализации экзекутора.

Не появится, экзекутор ровно один, и причем конфигурируется.


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

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

не будет ли проблем, если лодним корутинам подсунуть один шедулер, а другим — другой?

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

Вот, кстати, ещё один вопрос для собеседования, если у вас его нет. «В чём разница кооперативной и вытесняющей многозадачности? Какая стратегия используется в go?». И если кандидат ответит, то можно дополнительно спросить: «Как в go реализуется вытесняющая многозадачность?».
в старом опроснике был. тоже меня ругали за излишнюю теоретичность :)
в этом свете решение внести эту функциональность прямо в runtime уже не выглядит таким уж кривым.

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


А ещё явное наличие рантайма означает, что мы можем его настроить, причём до создания. Какие там ручки у рантайма есть в Go? GOMAXPROCS, GOGC и… Всё?

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

а зачем это может быть нужно?

Какие там ручки у рантайма есть в Go? GOMAXPROCS, GOGC и… Всё?

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

я и эти-то ручки не кручу со времен 1.5
а зачем это может быть нужно?

Вы нарочно проигнорировали следующее предложение?


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

Ну, например, интервал времени между безусловными сканами сборщика мусора. Из-за невозможности настроить это в принципе Discord в итоге свой read states переписал с Go на Rust.

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

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

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

Оверхеда на синхронизацию чего с чем?

Внутренних структур рантайма между потоками.

но там нет ничего, что требовало бы синхронизации!

onokonem выше немного заминусовали за "навскидку — 6+", но ошибки ведь действительно есть, и их не одна или две:


Разница в том, что декларативные языки обычно никто не понимает :).

Это не ошибка, конечно, но шутка не самая удачная, учитывая что очень многие всё ещё много и часто работают с SQL, не испытывая особых проблем с его пониманием.


var _ interfaceName = &typeName{} // если typeName это структура

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


Просто вставляет в конец слайса, пока есть место (capacity), и увеличивает его в N раз (вроде 1.5, но могу ошибаться), когда место кончается.

Опять не ошибка. Но здесь важнее упомянуть что именно стоит за словом "увеличивает" и как это может внезапно сказываться на производительности и приводить к out of memory.


Видимо, вернется nil value, но я в реальном коде такого не видел.

Да, вернётся zero value, но суть вопроса-то не в этом, а в том как отличить чтение zero value записанное в канал от zero value считанное в связи с закрытием канала.


sort.Slice(arr, func(i, j int) bool { return arr[i].Name < arr[j].Name })

Снова ситуация, когда ответ выдаётся недослушав вопрос: вопрос был про массив, а не срез.


Одну, потому что я скопирую этот код из Stack Overflow. Ну и давайте серьезно, никто в Go односвязные списки всё равно не использует.

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


Интерфейсы позволяют таким образом разрешать циклические зависимости, например.

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


Да кто ж его знает, как она в пакете net реализована :)? Можете использовать errors.Wrap(), errors.Is() и прочее, но так вроде мало кто делает пока что.

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


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

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


go vet

Хорошо, что Вы про него знаете и используете. Не очень хорошо, что это не golangci-lint с конфигом включающим абсолютное большинство встроенных линтеров. (Или хотя бы gometalinter, если Вы немного отстали от прогресса.)


Что дает это знание :)? Есть ещё ведь как минимум атомики и каналы, но это не мьютексы.

Знание даёт, как обычно, силу. :) А конкретнее, когда нужно выбрать механизм синхронизации для конкретной задачи, хорошо бы знать, что помимо sync.Mutex и sync.RWMutex есть и другие варианты. И они существуют именно потому, что вышеупомянутые мьютексы хороши далеко не во всех ситуациях. (И, кстати, каналы — это тоже мьютексы, в том смысле, что реализованы с использованием мьютекса.)


В Go даже sync.Map использует мьютексы для записи.

Не всегда, в этом и смысл его существования. При правильном использовании sync.Map будет работать практически lock-free.


Зависит от приложения. Обычно не очень большой, от силы должен быть 10-20%, но я видел и в несколько раз замедление как-то.

Вопрос был с подвохом — просто добавление профайлера (тот самый import, который Вы не совсем верно написали, но это как раз не важно) никак не влияет на производительность.


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

У вас один момент упущен, как в видео, так и в тексте.


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


Окей, видите проблему?


Есть мнение, что вы подогнали опросник под те заветные 8+ баллов для сеньора, экспертиза по которым уже есть в компании и релевантна только для узкого круга опрошенных.
То есть, с помощью интервью вы хотите нанаять сотрудника, чтобы улучшить экспертизу (bar raiser) в компании за счет тех доменов, в которых и так уже все хорошо. При этом те домены, которые являются сильными сторонами интервьюируемого вы сознательно (?) выкинули из процесса.


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


Но таки давайте быть немного честнее и начинать не c 3.3 для людей из вне, а с 4.5 для людей внутри? ;)

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

так что — да, опросник подогнан под имеющуюся экспертизу.

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


Почти все вопросы — это либо какой-то бред из методички (вроде append, map, мьютексов из stdlib), либо какие-то частности вроде prometheus, линтеров и прочая вкусовщина.


Никто не размышляет "а как же работает append" или "какие мьютексы есть в stdlib". Именно это знать не обязательно. Потому что абсолютно не важно.
А что важно — это какие мьютексы применять, когда у вас соотношение R/W — 50/50 или 99/1.
Или что будет со слайсом снаружи, если он передаётся в функцию, а внутри вызывается append.


Как отражает готовность работать зубрёжка метрик прометеуса, которые можно в официальной доке за минуту глянуть? А если ты пользовался не прометеусом, то всё, пока? Исходя из предположения, что окружение для сбора метрик в проекте настроено и работает, въехать в сбор метрик — это совсем не проблема. А если вообще никакого окружения нет — то и разницы никакой.

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

Если я правильно понял наводку, то range по map не честно случайный.
Во всяком случае не был таковым пару лет назад.
Он специально слегка «размешивается» чтобы пользователи языка не полагались на порядок, но до честного нормального распределения очень далеко при мапе большого размера.

это ответ на 9

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

А сид этого «размешивания» можно проставлять?

Насколько мне известно нет. Его же специально добавили, чтобы никто не полагался на порядок. И даже тест на это есть.
github.com/golang/go/blob/f979d072d339a24e4938d46588c153587d61af19/src/runtime/map_test.go#L507

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

Не могу отвечать за создателей go, но скорее они решили себе «постелить соломки».
Если указать что порядок специфицирован, то в новых версиях языка сложнее изменить внутренюю организацию map.
А так ребята явно говорят: порядок не гарантирован, хотите гарантированный — пожалуйста, заведите себе slice с ключами рядышком. (https://blog.golang.org/maps Iteration Order)
Еще и специально сбивают порядок, чтобы кто-то случайно не завязался. Забота. :-)
Если указать что порядок специфицирован, то в новых версиях языка сложнее изменить внутренюю организацию map.

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

а что такое «не меняют» в мире параллельного программирования?

Ах да, в гошке же всё может быть расшарено. Каюсь, забыл.

Означает что её "не меняют"

Однопоточное мышление detected.


Менять мапу может, например, GC.


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


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

Это баг, и его фиксят.

Это ваше мнение. Как по мне — совсем не баг


Менять мапу может, например, GC.

А при чем тут многопоточность?

И да, я не понимаю причин для рандомизации. Ну вот от чего эта фича защищает?
От denial of service via collision attack. Если злоумышленник контролирует значения добавляемых ключей, он может легко выродить хеш таблицу в вектор, нагнув вашу систему.
НЛО прилетело и опубликовало эту надпись здесь
Как я понял, там для одного и того же объекта, без каких-либо модификаций между итерациями, порядок итерирования не совпадает.
НЛО прилетело и опубликовало эту надпись здесь
(опять же, выдумываю на ходу) Если посмотреть исходники, то размер хеша зависит от платформы (32 или 64 бита), а размер сида всегда 32 бита.

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

Реализовано это за счет случайного сдвига начального индекса для каждого бакета и каждой итерации.

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

В мапе код который рандомно выбирает первый бакет с которого начинается итерация, а дальше как кольцевой буфер обходится: https://github.com/golang/go/blob/f89d05eb7ba1885474d03bb62f0a36a2d3cf56ea/src/runtime/map.go#L832

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

Вы случаем не знаете какой размер хеша используется в Go?
Ну вот от чего эта фича защищает?

Опять же, я не разрабатываю Go, спросите Роба Пайка. :-)
Могу только предположить, что от того, что кто-то завяжется на это в коде, а потом начнет создавать issue и жаловаться, что ему сломали back compatibility в новой версии.

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

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

Да, можно говорить про "отношения … как к глупым сусликам". Но суровая правда в том, что все суслики делают ошибки, и умные, и глупые. И техники, которые позволяют эти ошибки дешевле обнаруживать — это очень нужные и полезные штуки. Лично я не раз видел, как "внезапно" проваливающийся тест на CI (который дома прошёл один раз перед отправкой PR) помогал найти проблему… чаще всего в тесте, но и в коде — тоже случалось. Очень дёшево найти, обращаю внимание, что ценно.

допустим я сделаю мапу из объектов [1,2,3,4,5,0]. Теперь я делаю


int count = 0;
for i in map {
   print(10/i);
   if (count++ == 3) { break; }
}

И теперь этот код будет то работать, то не работать. Понимаете, я не собираюсь завязываться на порядок перебора элементов, но мне нужно чтобы результат выполнения одного и того же кода был детерминирован. Спасибо конеш за такую "Заботу", теперь баг с прода может не воспроизводиться ни при каких условиях. Один раз на миллион рандом выдаст такую последовательность обхода мапы, что всё поломается, и потом никогда не найдете, в чем была причина. До следующего падения через месяц. Удобно, ничего не скзаать. А ещё если учесть, что в тесте мапа из 4 элементов, то судя по реализации в 25% случаев тест должен падать. Весьма удобно.

Видите ли. Когда возникает конфликт между "мне нужно A" и "язык делает B" — нужно или язык менять, или свои нужды подстраивать под используемый язык.


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


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

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

PsyHaSTe утверждает вообще-то строго обратное. Вместо ДЕТЕРМИНИРОВАННОЙ ошибки — он получает рандом, который может стрельнуть, а может не стрельнуть.

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

play.golang.org/p/jJveuIrmJY8

Или он может только мне палки в колеса совать, когда мне это нафиг не надо, вроде «unused import»?

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

на самом деле в долгосроке это возможно правильное решение, т.к. позволяет избежать т.н. side channel attack. Но это должно быть явно задекларированным свойством алгоритма. Т.е. даете рандомизированный перебор — давайте и нормальный, детерминированный перебор. И возможность выбора.

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


То есть тут кмк скорее не забота о пользователях, а скорее гццшное "а давайте на УБ запускать арканоид, ведь согласно спецификации мы имеем на это право". То есть такой "ах, вы попробовали завязаться на деталь реализации? Нате вам неприятный сюрприз. Получили? То-то, будете в будущем читать документацию внимательно!"


Звучит по-детски и глупо.

Я кстати знал и забыл

А можно и вообще простенькое задать, типа как развернуть по диагонали вот эту матрицу:
10011110
00110111
01111001
10111001
01111111
01001010
01111100
00010110
в вот эту:
10010000
00101110
01111010
11111011
10111110
11001011
11001101
01111000
И сделать это за одну операцию.
Так вы легко поймете — начинал ли испытуемый читать Кнута. Только какой в этом толк в подавляющем большинстве случаев… За всю жизнь мне это только один раз пригодилось.

Сорян, за две операции

Это биты? То есть матрица задана как 8 байт? Хммм, а из какого множества операций можно выбирать?

Гугл мне в помощь. Спасибо, что вы пример прям скопировали. Вобщем, это действительно биты и эти 64 бита составляют октабайт в терминологии Кнута. Вобщем, решение предлагается искать среди команд MMIX — придуманного самим же Кунтом (так и не реализован в железе). Для решения нужны команды перемножения матриц октабайтов. Интересно, есть ли такие операции в современных процессорах…

НЛО прилетело и опубликовало эту надпись здесь
Я бы развернул её за ноль операций, просто изменив функцию индексации элементов (типа stride в numpy). И провалил бы собеседование. Хорошо, что ни на одном собеседовании (кроме совсем упоротых) мне не задавали технических вопросов и не давали тестов, задачек и т.п. :) Обычно мы просто общались о прошлых и планируемых проектах.
Одни считают что хороший программист должен быстро и, по возможности, качественно решать задачи бизнеса. Другие ожидают от него знания асимптотики красно-чёрного дерева и пересказа спецификации %фичанейм% из %языкнейм%. Со временем первых становится всё больше в процентном соотношении, как-никак программирование пришло в массы и стало обычным ремеслом. Это не хорошо и не плохо, ведь от сварщика никогда не требуют знания химии плавления, а от учёного варки ровных швов. Со временем авторам этой и подобных ей статей придётся смириться и перестать искать для работы на стройке людей «с вышкой».

эта вакансия была для прораба. прораб должен уметь держать в руках нивелир.
6. Как устроен тип map?
  • Что я хочу оценить: насколько интересно кандидату, как именно ложатся в память наши байтики. Map, возможно, самая важная из стандартных структур данных, и весьма замысловато устроенная. Она сложная, она эффективная, она обладает встроенным race condition детектором… Неужели не любопытно?!
  • Самый популярный неправильный ответ: «Это хеш-таблица». Да, это хеш-таблица. Как устроена хеш-таблица?

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

P.S. Возможно я не понял для какой цели ищется кандидат, бизнес действительно подразумевал найм:
человека, который сможет задать и поддерживать высокий уровень профессионализма в применении языка Go
Эдакого гуру задача которого не кодить а рассуждать о качестве кода и духе Go. Если так то вопросы сразу отпадают.
тут и близко нет про количество линз. тут все вопросы типа «как лазерный нивелир автоматически находит горизонталь» (лазер там в кардане подвешен, если что. и из этого следует, что рычажок фиксации надо передвигать в правильное положение при любой транспортировке, хоть на пару метров)
Прораб не знающий всего вышеперечисленного, но при этом являющийся уверенным пользователем всегда передвигающим «рычажок» в правильное положение (например в молодые годы его очень сильно ругали за забывчивость) будет плохим работником? Для него это просто чёрный ящик и он обучен(и неоднократно закрепляет на практике) использованию предоставленного ему интерфейса, разве этого ему не хватит на любом не rocket science проекте?
прораб, который тупо делает, как научили, и не задумывается над смыслом — скорее всего будет плохим прорабом.

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

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

Как вы отсортируете массив структур

Да никак. За меня это сделает import «sort». И никаких велосипедов изобретать не надо в 99% случаев. Может у вас, как раз, регулярно возникает оставшийся 1%? Ок, тогда у меня три встречных вопроса: почему они возникают, почему этих велосипедов нет в проектных библиотеках и почему эти ситуации не вынесены на собеседование?

А если хотите порассуждать о пузырке и прочих мерже/квик сортах — спросите прямо. В чем проблема?
Да никак. За меня это сделает import «sort».


ответ на 9, едем дальше

Тогда вы просто ищете токсиков, которые могут в ответ "нахамить". Потому что когда вопрос поставлен таким образом, то подразумевается, что реализовывать надо, и что варианты "взять из библиотеки"/… уже отметены по каким-то причинам. Возможно, этим причины соискатель может уточнить, но это необязательно и принимается на веру.


А что что вы на 9 оцениваете соискателей за ответы "никак не буду делать, импортирую"/"так никто не делает"/..., но при этом на единичку тех, кто говорит "не знаю, импортирую"/"не знаю, так никто не делает" весьма иронично.

НЛО прилетело и опубликовало эту надпись здесь

Это мне напоминает стресс-тест "плеснуть стаканом воды кандидату в лицо". Помнится, сколько-то лет назад это было весьма популярно.

А что что вы на 9 оцениваете соискателей за ответы «никак не буду делать, импортирую»/«так никто не делает»/..., но при этом на единичку тех, кто говорит «не знаю, импортирую»/«не знаю, так никто не делает» весьма иронично.


смысл этого пассажа ускользает от меня :(

Имелось в виду — не Ваш «ответ на 9ый вопрос», а «оценка кандидата на 9 баллов из, скажем, 10»
Возвращайтесь в реальный мир )
Обоим ( с PsyHaSTe ) — навык однозначно доносить свои мысли — тоже очень важный

9 — это максимум, шкала 0-9

вообще — я ровно «воспользуюсь стандартной библиотекой» и хочу услышать.

если кандидат говорит «погуглю» — я предлагаю погуглить прямо сейчас. только мало кто говорит «погуглю» :(
А вы уверены, что мидлов и сеньеров можно заподозрить в незнании стандартных библиотек? О_о

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

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

Вы думаете, что мне надо "засыпать" кандидата? А что навело вас на эту мысль?

Печально, что статьи подобные этой, скорее отталкивают от изучения Go нежели мотивируют. Д'Артаньянство конечно тешит ЧСВ но для бизнеса это чистый убыток. Для меня, понимание границ своей компетенции кандидатом — это огромный плюс. «Я не знаю» это не проблема (без фанатизма пожалуйста), это пространство для роста. К примеру пересечение моей экспертизы с вопросами интервьюеров в последних собеседованиях не превышало 5%, а это на минутку 5 раундов технических собеседований по часу каждый. В своих собеседованиях я стараюсь найти как минимум несколько плюсов у каждого кандидата. Подход описанный в статье — это не отбор разработчиков, это отбор Working Unit #372. Один сгорел — заменить на другого и никто не заметит.
подход, описанный в статье, или подход, описанный в докладе?

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

Так вам не го разработчик нужен, а go евангелист?
Хм, может ввести должность «инженер по качеству кода»? Интересная идея, однако

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

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

Вот серьёзно, список — это ужасная структура данных, которая не нужна ни в каких задачах, кроме «разверни-ка этот список» или «объедини-ка эти два списка» (опять же, речь про императивные языки в духе го).

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

Каким образом тут функциональные языки появились?

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

Например, операция вставки элемента в список — очень дешёвая

А вы не подскажете, насколько долго искать место вставки?

Если вам не встречалось таких задач, это не значит, что их нет.

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

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

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

С двусвязными, конечно, но:


  • простейший LRU-кэш обычно реализуется через хэш-мапу и список
  • цепочки буферов обычно строятся на основе списков
  • очередь тоже часто на основе списка
  • Простейший LRU реализуется как import LRU from something
  • Цепочки буферов на практике видел только внутри какого-нибудь malloc, а не юзер коде
  • Очереди уже везде реализованы, второй раз делать этого не надо

Вы сейчас точно в том треде отвечаете? Этот тред про то, что список — негодная структура данных:


Вот серьёзно, список — это ужасная структура данных, которая не нужна ни в каких задачах, кроме «разверни-ка этот список» или «объедини-ка эти два списка»

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

простейший LRU-кэш обычно реализуется через хэш-мапу и список

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

цепочки буферов обычно строятся на основе списков

Не уверен, что понимаю о чем речь. Сколько обычно буферов?

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

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

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


Не уверен, что понимаю о чем речь. Сколько обычно буферов?

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


Но часто и нет. В С++ вот на основе массива. С большой вероятностью это более эффективно.

В libstdc+++ через деку, а не через массив: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_queue.h#L75
Потому что нужна эффективная операция снятия элемента с начала цепочки элементов, а в массиве такого не сделать. Вот если бы очередь была фиксированной длины, да элементы одинакового размера, тогда можно было бы говорить о кольцевом буфере на непрерывном куске памяти.


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

НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь
Вы определитесь — вам нужен инженер или обезьянка-зубрилка? Если второе то ладно, может такие собеседования и работают.

Автору поста: напишите книгу с ответами на эти вопросы и разбором best practices. Я серьезно. Может получиться очень хорошо.

я пишу, туго идет :(
Я могу подробно описать как работает HashMap, например, но на вопросе про односвязный список, который я легко писал на любом языке еще 20 лет назад — я бы подзавис. Во-первых, я тупо не сразу бы выудил из головы, что это такое, во-вторых, я бы стал вспоминать, почему он односвязный, и в-третьих, что значит развернуть? Потому что развернуть для меня это равносильно — раскрыть, но никак отсортировать в обратном порядке. И спустя 5-10 минут, осознав, что от меня хотят — я бы набросал все это на листке, но… зачем?
писать программы на листке бумаги — унизительно, поэтому я и не прошу это делать.

не понимать, что интервьюер имеет в виду под «развернуть» — нормально, и задать уточняющий вопрос тоже.

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

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

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

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

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

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

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

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

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

и вот вы такой «общаетесь об опыте, о задачах, проектах».

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

я, оказавшись пару раз в такой ситуации, решил свой опыт обобщить и формализовать.

а вы — обобщили и формализовали, или полагаетесь на интуицию?

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

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

это для меня лично было бы очень выгодно — интервью крутятся, бабосы мутятся, и мы никого не нанимаем, work place secured.

но репутация же, она как рейтинг на хабре, все время понижается, если ничего не предпринимать
Экспертное мнение никто и никогда не описывает через boolean
Составляется карта с ранжированием от 1 до 10 (например) и по каждому пункту проставляются варианты. Оценка принятия 5-6 (средняя по всем показателям)
Нельзя сделать шкалу где джун-3, миддли-6, сеньор-9
У вас должно быть 3 шкалы с уровнем принятия 5-6.
Все другие подходы не являются «экспертными», веет отсебятиной без знания матчасти.
ну, я пришел к тому, что имею два опросника, фактически, на мидла и на сеньера.

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

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

а где глянуть ваш, правильно составленный?

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

По поводу оценок, я не препод и не имею энциклопедических знаний
Описание находится в теории принятия решения, экспертное мнение, экспертная система. И в материалах по теории систем.

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


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


Что я хочу оценить: насколько интересно кандидату, как именно ложатся в память наши байтики. Map, возможно, самая важная из стандартных структур данных, и весьма замысловато устроенная. Она сложная, она эффективная, она обладает встроенным race condition детектором… Неужели не любопытно?!

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




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

Неужели каждое обращение к каждой мапе триггерит некоторый детектор?


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

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

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

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


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

Это не так, и об этом много говорилось и в статье и в комментариях.


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

Эмм. А что ещё делать, если наше субъективное впечатление имеет тенденцию ярко запоминать одно и при этом напрочь забывать другое? Удачный ответ на один вопрос может заставить забыть пару крайне неудачных ответов на другие… как и наоборот. Баллы позволяют принять более справедливое решение, учтя все ответы наравне. Нужна ли эта справедливость в данном конкретном случае — другой вопрос, но в самом подходе ничего плохого нет, на нём вся современная наука держится.

Тогда надо не собес проводить, а требовать «сертификацию программистов». Для админов испокон веков существовали всякие CCNA… вот и пора вводить сертификацию «Golang senior programmer v1.13». Этим может заняться какой-то отдельный комитет. Представьте себе какая экономия времени — если у человека есть такая бумажка и подтверждённый опыт — можно сразу скраивать время на техсобес и спрашивать более интересные вещи, чем про стандартную библиотеку или односвязные списки


onokonem Ваши 200 вопросов — первая заявка на такое. Проблема только в том, что ответы должны быть однозначные )))

НЛО прилетело и опубликовало эту надпись здесь
Интересно почему в сис админстве эти вещи присуствуют, а в dev нету. Может не выгодно?


Очередная версия языка — использовать её или нет это выбор самого программиста.

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

С админством не так. Если вам нужна новая фича — нельзя оставаться в старой версии ПО. Нужно обновлять. А что потянет за собой обновление? За код-то админ, в отличие от разработчика не отвечает, он и починить не может и даже посмотреть не всегда может что там. Поэтому привязка сертификации к версии ПО важна.

Ну и вторая причина, которая, имхо, важнее:

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

Вообще существует какая-то серьезная сертификация под язык программирования, кроме языка Ada и т.п.?

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Так это с++, а вот что-то отличное от бекендов, сетевых сервисов и утилит на голанг пишут ?

В стиле автора:


  1. Усилия автора по поиску go сеньоров

  • Что я хочу оценить: Насколько автор вообще настроен именно найти человека, а не просто потешить ЧСВ


  • Самый популярный неправильный ответ: «Я им даю вот этот задачник. А потом бомблю с ответов». Очень жаль, что ты простой quiz, %USERNAME%. Если бы ты хотел искать сеньоров, а большинство кандидатов не знали бы ответа на первый вопрос, ты бы разобрался как они ищутся, а не просто сидел как бот и спрашивал тех, кого дают.


  • Наводящие вопросы: Откуда уверенность что тебе подают именно сеньоров? Усилия хэдхантеров как-то оцениваются? Хоть раз-то проверял, какие резюме попадают к тебе, а какие — в мусорку?



  1. Вопросы

  • Что я хочу оценить: Умение автора задать вопрос


  • Самый популярный неправильный вопрос: «Что такое Х?». На ответ "Х это Y" начинается вонь и глумление. Оказывается надо было понять, что автор хочет узнать не что такое Х, а как работают Z и как устроен W из которых состоит Y. При этом заботливо стоит пункт "что я хочу услышать", но он отделен от вопроса. Зачем спрашивать то что ты хочешь услышать, если есть тупой и некорректный вопрос? Молодец, автор! Так держать!


  • Наводящие вопросы: Почему не говорить кандидатам сразу пункт "что я хочу услышать"


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

А устроившись на работу и получив непонятную задачу этот человек задаст наводящие вопросы? Или он сразу бросится воевать с ветряными мельницами?

На работе этот человек научился задавать вопросы, когда нужно, а на собесе еще нет.
Тут больше экзамен и психологически воспринимается по другому. Часто студенты спрашивают, что хочет услышать в ответ экзаменатор? Я ни разу не видел, чтобы кто-то спросил.
> На работе этот человек научился задавать вопросы, когда нужно, а на собесе еще нет.

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

И без постановки технической задачи вообще.

И еще когда бизнес не знает чего хочет

Не, это уже граница за которой начинаются продакты.

Да, не стоит вскрывать эту тему :)
  1. При том что я знаю, что поменялось в 1.13 в месте с ошибками (и знал), я не понял вопроса. Т.е. из вопроса я узнал, что есть теперь стандартная практика
  2. Я бы вставил "моржика". Он зараза хитрый
  3. Я понимаю, что вшивый о бане. Но вопросы паттернов ООП прямо вот странные. Да, я понимаю, что зная паттерны довольно легко выяснить понимание встраивания. Просто стравив его с наследованием. Но есть много людей, которые с ООП столкнулись лет 20 назад и потом нет. Я про наследование года три назад специально повторял, потому что вопросы задолбали. Есть масса людей, которые вообще не сталкивались с ООП. А из тех, кто думает, что прямо весь в ООП — многие глубоко заблуждаются. Но паттерны конечно отщелкает. Я бы скорее что-нибудь про замыкания спрашивал. Почему нет? Чем они провинились перед полиморфизмом? )
  4. Или вот sync.Map. Единственный смысл спросить об этом — это узнать, помнит ли человек о таком. Я сейчас третий раз прочитал и вероятно третий раз забуду. А вот тема тредов и процессов пропущена. Вот где открытий нас много ждет
вот не начинай, а?

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

Ну да, это спор о том, что попало в призовую игру. Ну ок. Предположим я не знаю, что такое линтер (ну очень интуитивно только), но довольно недурно отличаю процессы, треды и сопрограммы. Посыплюсь только на вопросе асинхронности дискового i/o. Без гугла я думаю, что там имитация асинхронности путем вынесения в отдельный тред. Это хорошо или плохо? Я считаю управление программой более базовым, а линтер — премиальным знанием. Или вот аллокации. Я плаваю в этой теме и это плохо. Вокруг этого бы всё обойти: https://golang.org/ref/mem

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

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

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

рекорд — 8.3 за 20 минут.

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

Да опросник супер. Я фанат твоих опросников )))
Я нифига ещё с прошлого раза не понял SOLID. Но вот то, что есть целые теории вокруг tight coupling меня заинтересовало. Это прямо вот то, во что я сейчас нырнул

Ну, хотя бы вопросов по битовым операциям нету.

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

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

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

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

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


Реальная история. 1995 год. Игра Wizardry 7. У меня компа не было. Я пришёл поиграть в гости, а то завидно, пока все на кухне пили. Прихожу как-то посреди ночи на кухню к друзьям и рассказываю, что меня вынесли крысы, а самое мощное заклинание, которое у меня было — "KNOCK-KNOCK" — не эффективно.


Эта история про фокусировании на бизнесе

Сейчас сходу вообще не смогу пройти ни одно собеседование. Смогу только если буду пару месяцев часов по 5-8 в день готовиться к этому. Я реально базовые примитивные вещи забываю, так как обычно в работе их не использую. Иногда гуглю заново какую-то простейшую ерунду, которую уже гуглил месяцев 6 назад, что видно по цвету ссылки в браузере (он как бы укоряет меня таким образом). Просто эти 6 месяцев я делал что-то другое, зачастую очень сложное, и про ту простую штуку уже забыл. Спрашивать про декларативность и императивность меня можно с тем же успехом, что спрашивать про отличия ямба от хорея — без гугла не смогу. Хотя в школе-то знал про это… Ну, где-то с неделю после того как это рассказали, дольше мой мозг просто не даёт хранить ничего без повторения и использования.
НЛО прилетело и опубликовало эту надпись здесь
На сколько понимаю, то основная цель — это найти человека, который сможет поддерживать высокий уровень профессионализма в применении языка Go, задать стандарты. Думаю, что многие со мной не согласятся, но это факт, что без хорошей теоретической базы в структурах данных и алгоритмах сложно поддерживать высокий уровень кода в компании или даже в команде. Поэтому HR-ы должны на подлете срезать тех, кто не знает про связные списки, не знает как их обратить, не может ничего сказать про %желаемая_структура_или_алгоритм% и т.п.

Не все вопросы я бы взял, что-то бы переформулировал, но расширил бы ваш список вопросами это точно:

а) контекст — человек должен прекрасно понимать что это и зачем.
б) как выделяется память в Go программе
в) как работает сборщик мусора
г) дебагер — как делаете отладку локально. Почему это важно? Потому что очень много людей выводят дампы в консоль через println или spew.Dump. Скажем так это не совсем то что нужно, если мы за культуру разработки :)
д) вопросы про принципы построение библиотек, про design patterns применительно именно к Go. У вас есть вопрос про интерфейсы, и при желании из него можно выйти, но мне кажется, что этого не достаточно, для оценки специалиста, на котором будет ответственность за качество Go кода.
изначально список был на 200 с лишним вопросов. и я его урезал со слезами, чтобы интервью хотя бы в час укладывалось

Возможно ли взглянуть этот полный список? Чисто себя поверить.

а, не, прошу прощения, это уже редуцированный.

полный оформлен так, что только мне и полезен, так что — нет :(

можно на mindmap глянуть, то самое "дерево знаний"

г) дебагер — как делаете отладку локально. Почему это важно? Потому что очень много людей выводят дампы в консоль через println или spew.Dump. Скажем так это не совсем то что нужно, если мы за культуру разработки :)

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

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

Но это довод так себе. Мне вот быстрее и удобнее дебаг логи поставить. Т.е. это очень субъективно и явно не повод ставить минус на интрервью и вообще спрашивать про это, как считате?
Много моих коллег, кто пишет на го, пришли из php. И они очень хорошо пишут, качественно. Но у них привычка писать строки в консоль и смотреть хоть как-то в дебаггер они не приучены. Если вопрос про культуру и про ее поддержание, то человек, который будет этим заниматься должен иметь опыт и привычку пользоваться дебаггером. Всегда ли нужно лезть в дебаггер или на все ли случаи подходит вывод в консоль? Нет, в этом и суть вопроса — вы как локально отлаживаете и почему? Можно ли отлаживать исключительно выводя всё в консоль — можно. Но возникает вопрос в скорости отладки, в наглядности информации предоставляемой обоими способами. Как у меня коллега отлаживает проблему, которая возникает где-то в цикле: в цикле пишет кучу переменных в консоль, форматирует вывод, выводит разделители и т.п. Запускает, смотрит вывод. Добавляет / убирает переменные из вывода. Зачем делать работу, которая делается дебаггером из коробки?
PHP, Go? Какая разница если мы говорим об отладке? Я например 15 лет назад на С++ писал и использовал отладчик. Сейчас только ассерты и трейсы использую, в JS, Go, Python, whatever. Так мне быстрее и удобнее, особенно в мультипоточной или асинхронной среде, не зависимо от АЯП. И я буду держаться подальше от компании, в которой вышестоящие люди будут навязывать свой субъективный опыт в том, какими инструментами мне лучше и быстрее решать проблему, если мне не приведут какие-то объективные преимущества, а пока я их не вижу.
Для себя вопрос давно закрыл — логирование удобнее, потому что А — автоматизация: глазам не надо страдать отслеживая баг вручную прыгая по окошкам отладчика — просто один грамотно оформленный вывод в лог на одну гипотезу.
Ваш пример с циклом не очень удачный. Даже когда использовал отладчик, мне приходилось добавлять условие средствами отладчика, чтобы он остановился только на брейкпойнте только при определенном условии, чтобы не скакать в цикле по брейкпойнтам и не дергать лишний раз глаза. Так зачем спрашивается так мучиться, если проще автоматизировать через лог?
for ... {
  if(val != expectedVal) {
   print oops/trace/stack/whatever
   break
  }
}

Все хуже — отладчик можно запустить только на локальной машине. Когда у тебя 100500 микросервисов — удачной отладки в тесте и на проде. Только логи и метрики спасают ((((

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

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


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

Этож кто в здравом уме, прод запускает с активной отладкой то?

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

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

Как-то сложно. Лог проще :)

Если заранее нет понимания какие гипотезы требуется проверить — то вам для сбора логов потребуется 5-10 раз передеплоить весь прод. Ну или сделать всё то же самое, что было предложено делать для подключения отладчика...

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


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


Ну вот как есть TDD, так видимо есть и LDD




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

Если бы всё было так просто… Вот в примере выше отладочная печать стоит в ситуации когда val != expectedVal. Но если expectedVal известна — зачем вообще вычислять val? Вполне возможно, что проверяет эта проверка лишь частный тестовый случай, и включать её в общем случае — полностью бесполезно.

затем если val это признак чего-либо, а не полноценное значение само по себе. например if responseStatus != ResponseStatus.Ok — можно ли выкинуть такую проверку? не стоит ли заллогировать ответ если условие истинно?

Но я не вижу каким образом при проверке if responseStatus != ResponseStatus.Ok пригодится трассировка стека. При таких проверках, как правило, и без того понятно где она произошла...


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

Ну вот например я недавно функционал писал, вот эти логи в итоге помогли найти проблему.


img


Я просто проверил, что начиная с какого-то момента в логах писалось не то, что я ожидал и поправил. Дебажить такое трудно, потому что тут завязаны очереди, другие компоненты и т.п. Отключать всё это даже на тестовом стенде и заводить на разработческую машину долго. Кроме того, эти логи пригодястя в будущем, если меня собъет машина и система будет странно себя вести, по этим логам любой человек сможет понять "хмм, а почему тут эти два поля равны, Хотя по тесткейсу не должны и должны были обновиться?.."

Господи что за говнокод. Вы так в прод пишите? Хотя кто бы говорил. У нас и похуже код есть. Да что уж там, у нас в проде вообще логи уровня Information и ниже не пишутся. Это если что не мое решение.

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

Тыж мой маленький, пузатенький, сладенький пирожочек. Просто ты меня игнорил вот и хотел привлечь внимание. XD
Не видя полностью код и не зная полностью контекста и задачи сложно. Вообще у PickapTimeSlot есть свой тип добавить в этот тип PickapTimeSlotOfset сравнение по полям From и To. Дальше уже в условии проверять через вызов этого метода. Не делать выставление через вложенный if а просто сделать метод и возвращать нужный pickupTimeOffset. Сделать проверку в начале и в начале запись в лог и прерывание метода. Тогда не будет вложенных if и сразу понятно что с этого место дальше просто уже ничего не выполняется. Добавить в PickapTimeSlotOfset доп конструтор который принимает другой объект и вот эти timeZone, LocaleFrom. В общем мелочи такие всякие. Ну это так, возможные улучшения на первый взгляд.
Вообще у PickapTimeSlot есть свой тип добавить в этот тип PickapTimeSlotOfset сравнение по полям From и To.

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


Не делать выставление через вложенный if а просто сделать метод и возвращать нужный pickupTimeOffset. Сделать проверку в начале и в начале запись в лог и прерывание метода.

Не понимаю, давай код.


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

Только дальше как раз всё выполняется, тут 3 ветки при которых выставляется picupTimeSlotOffset в определенное значение.


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

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

Тут надо целиком смотреть. Если бы я знал все варианты и всю задачу то возможно сделал бы все на типах без огромных ифов и вставлением в процедурном значении в трех местах этого офсета. Я так понимаю помимо этого куска кода который можно было бы в функцию завернуть он там еще в двух местах выставляется? Про код конструктора — ну метод Copy тогда. Ты так и так эти параметры в этот конструктор передаешь. Может ты меня не понял. Я имел в виду для удобства добавить доп метод в конструктор который вызывает конструтор этого же класса через: this( просто с доп параметрами. И таки да — обязанность конструтора создавать объекты из набора каких-то данных. Тут все в порядке. Он этим и продолжает заниматься просто новый набор входных параметров приобретает.
А вот это с моей тз не улучшение, а ухудшение. Констуктор принимает минимум информации который ему нужен, про вот эти LocaleFrom он не знает и знать не должен, это вообще не его зона ответственности.
Хм, тогда почему у конструктора уже есть параметр localeFrom?
Не понимаю, давай код.
Так просто превратить весь этот кусок кода в функцию которая возвращает это офсет как свой результат. Вместо того чтобы в этом куске кода в нескольких места его устанавливать. Я так понял это не сработает потому что ниже и выше он и опять высталяется или что-то в этом роде. Не видя всего кода сложно сказать.

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

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

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


Ты чего такой токсичный? Если там этот кусок кода для тебя был как родной и тебя эта моя фигня сильно задела то прости. Забей вообще на мой комментарий. Люблю тебя.

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

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

Так тестами можно было этот флоу описать. Что если вот так то должно делаться вот так. Если есть входные и выходные данные из логов то можно было реально с ними продебажить в специально созданном тесте — просто в моки и стабы данные нужные выставить и дебажить. Ну как тест — это уже просто экспериментальный запуск. Хотя там такое, я всего кода не вижу. Может там дофига внешнего взаимодействия и написать моки/стабы был бы дикий гемморой.

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

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

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

Я мокаю X чтобы протестировать Y. Надо свой код протестировать на то как он себя ведет с различными входными данными. Если ты не умеешь писать чистый код и у тебя Ввод Вывод ака IO перемешан с твоей логикой то ты ССЗБ.
Надо свой код протестировать на то как он себя ведет с различными входными данными

А потом оказывается, что замоканный объект ведет себя не совсем так, как замокали. И ваш код превращается в тыкву.

Вообще фишка маленьких чистых методов и функций (вроде того же метода на сравнение по From и To) что для них можно такие же маленькие и Проперти базед тесты писать.
Вообще с тестами это на практике приходит. Я лично вижу и как сделать чтобы покрыть тестами и какие граничные варианты. Начиная писать код с желанием максимально покрыть его тестами и сделать поведение предсказуемым я потихоньку научился код писать тестируемым и расширяемым. Тесты они меняют твой стиль кода и начинаешь в принцыпе писать код так чтобы он был тестируемым и с маленькими понятными Юнит Тестами.
Все фигня кроме ёжиков потому что ёжики не фигня. Ты Балдурс Гейт 3 видел? Я смотрел стримы и по моему годнота. Хочу поиграть ток ранний доступ и забагованно все к чертям. Да и только первый акт открыть. Я теперь жи буду это — в нетерпении ждать пока не выйдет полная версия. В принцыпе пока что можно в Дивинити 2 поиграть. БД 3 таки очень на Дивинити похожей вышла. Один фиг, растравили мне душу теперь руки чешутся по скорее поигать.
Да забей, про фу говнокод это была шутка. Обычный такой середнячек. Я тебе более ООП вариант предложил. Тут более процедурный. Можно вообще весь этот метод в пределах класс PikapTimeSlotOfset поместить а логи оставить только снаружи на входные данные и получившийся результат.
В этом куске кода вообще все что происходит это взаимодействие одного офсета с другим + откуда-то timeZone прилетает + логи лишние.
Ты чего такой токсичный? Если там этот кусок кода для тебя был как родной и тебя эта моя фигня сильно задела то прости. Забей вообще на мой комментарий. Люблю тебя.
Ты чего такой токсичный? Если там этот кусок кода для тебя был как родной и тебя эта моя фигня сильно задела то прости. Забей вообще на мой комментарий. Люблю тебя.

Кажется, тут вовсе не ваш оппонент токсичен...

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

А что вам мешает автоматизировать всё что нужно в отладчике?

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

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


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

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

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


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

С логами та же ерунда выходит...

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

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

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

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

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

с чего бы?

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

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


А ещё иногда логи могут тормозить...

Возможно и то и другое. Но опять же, если мы пишем отладочную инфу в stdout только из одного потока, вероятность воспроизводимости разная. На практике меня логирование выручало. Статистику не вёл, но в 100% случаев. Как у вас?

Ну а вот моя статистика: при отладке через логи, по ощущениям, нужно в среднем пять итераций гипотез. Т.е. программу надо перекомпилировать и перезапустить 5 раз, в то время как при использовании отладчика достаточно 1 раз попасть в нужную точку останова. Так что именно в сравнении с отладчиком мне логи не помогли ни разу.


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

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

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

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

Логов тоже можно наставить слишком много и потом потеряться в них.

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

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

Там в комментарии выше под "автоматизацией логов" понимается if(val != expectedVal). Но тот же уровень автоматизации доступен и в отладчике, к точке останова тоже можно добавить условие.

Я такую привычку поставил бы скорее в плюс нежели минус. Надо только приучить


  1. вместо печати в консоль писать в лог
  2. НЕ УДАЛЯТЬ эту отладочную печать перед тем как коммитить в прод

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

А мы говорим про одно и то же? Я пишу про случаи, когда коллегам нужно посмотреть правильность выполнения условий, присвоения значений и т.п.
for i := range slice{
 ...
 ... {  spew.Dump(i, slice[i]) }
 ...
}


Такое можно с учетом вашего пункта 1 писать в лог отформатировано и красиво. Но в какой-то момент у нас туда вообще всё будет писаться. Считаю, что в логи писать всё что тебе пришлось отлаживать не имеет смысла.
Человек приходит и говорит — у меня nil pointer exception. Он идет и расставляет по коду spew.Dump ( или вывод в лог) что бы понять где и в каком месте у него значение не присвоилось. Имеет ли смысл такое оставлять и писать в логи? Нет.
Такое можно с учетом вашего пункта 1 писать в лог отформатировано и красиво. Но в какой-то момент у нас туда вообще всё будет писаться. Считаю, что в логи писать всё что тебе пришлось отлаживать не имеет смысла.

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


Ну вот простой пример. у вас ВДРУГ в этом месте прод начал ломаться. В одном случае у вас уже есть логи, вам достаточно просто написать в конфиге "мне все подробные логи которые пишет этот компонент пожалуйста" и посмотреть что происходит. А если логи после дебага поудаляли — то куда смотреть? Новые писать? Так это ещё надо разобраться, куда и что писать.


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

Согласен с вами, что важные моменты нужно логгировать, в том числе и промежуточные результаты операций, работу со внешними ресурсами. Тогда мы сможем восстановить ход событий и воспроизвести ошибку. Но есть много в процессе отладки, что является по факту мусором. И выше я говорил, что у меня коллеги «дампят» массивы, «дампят» сущности в консоль, потому что какие-то поля у них пустые, компоненты не проинициализированы, описались/перепутали знаки в условиях и т.п. Они это выводят и фиксят: задают полям значения, инициализируют компоненты, правят с if… на if!.. и т.п. Не понимаю пользы такого логгирования. Тогда у нас через строчку будут логи в какой-то момент) Из сегодняшнего вечернего: коллега перепутал в if > и <. Глаз замылился к вечеру и не замечает. Отлаживает. Выводит значения переменных используемых в условии, выводит метку «выполняется ли код в этом блоке». Я говорю про отладку таких ошибок — есть ли смысл в том, что бы это всё оставлять? Думаю, что — нет.

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

А мне понравились вопросы. Не знаю, насколько они полезны при найме, но для себя нашел много вопросов на покопаться и изучить предмет глубже. Спасибо.
спасибо!
Как устроен тип map?
Что я хочу оценить: насколько интересно кандидату, как именно ложатся в память наши байтики. Map, возможно, самая важная из стандартных структур данных, и весьма замысловато устроенная. Она сложная, она эффективная, она обладает встроенным race condition детектором… Неужели не любопытно?!
Самый популярный неправильный ответ: «Это хеш-таблица». Да, это хеш-таблица. Как устроена хеш-таблица?


Я не понял, так это правильный ответ или неправильный? Сначала пишите, что неправильный, потом, что «да, это хэш-таблица», т.е. правильный. Прямо шиза какая-то в одном предложении, или если выражаться политкорректно, противоречие.
это такой художественный прием
  • Господи! Народ — говно!
  • Но другого у меня нет для тебя Моисей. Проповедуй в этом.

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


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


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


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


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

Насчёт Гугла — совершенно согласен.

Чем дальше я по возрасту от института, тем меньше я помню ответы на эти вопросы.

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

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

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

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

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

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

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

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

Поэтому, когда индустрия варится в ситуации, когда нужно Быстро и Дешево, страдает качество. А следом и уровень понимания фундаментальных основ технологий.
но надо же что-то делать :)
Я не изучал Гоу, поэтому уверенно ответить смог только на 12-й вопрос :)
Но читать было интересно, теперь, если когда-либо буду в него погружаться, обязательно вернусь к этому тексту!
На самом деле, с теми или иными оговорками, список вопросов проецируется практически на любой язык, только вот ответы в зависимости от этого будут разные.
да, языки не так сильно различаются между собой, особенно принадлежащие к одной парадигме

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

да с чего бы? вопросы-то тривиальные

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

В результате лучшие кадры приучаются делать только то, что им поручено, ничего, кроме того, что им поручено, и необходимый минимум того, что им поручено. И этот подход, я предполагаю, незаметно и неосознанно эти кадры распространяют и на свое обучение. Разработчик изучает только то, что ему нужно по текущей задаче: ничего, кроме этого, и ограничивается минимально возможным набором знаний. Моё скромное мнение — так нельзя! Образование — это игра в долгую, и подходить к нему надо с другими критериями, нежели к очередному «Проверим идейку MVP».

И я тоже согласен, что это плохо.


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


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


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


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


P.S. "не знаю" можно также заменить на "не помню". Когда я искал работу полтора года назад, я это всё как орешки щёлкал. А сейчас банально часть вещей забыл, ибо у мозга (по крайней мере, моего), очень эффективный garbage collector. XD

>И я тоже согласен, что это плохо.

А мне кажется это закономерным.
Мы, когда изучаем любую новую технологию — начинаем с минимального числа абстракций для прикладного применения. Т.е. условно «вставляешь это сюда, а это сюда и оно работает», но при этом все, что под капотом — это «магия».
Уже позже, когда в голове эти знания перешли в долговременную память — мы можем углубиться и разобрать, как оно внутри работает. Это, несомненно, открывает больше вариантов использования. Но абсолютно невозможно на первом этапе.
Объем знаний в ИТ расширяется невероятными темпами — вполне закономерно, что у нас не хватает времени на глубокое понимание везде и мы переходим к поверхностному.
И этот процесс будет и дальше продолжаться. Единственное, что ему можно противопоставить — это деление на более узкие специализации, но у него куча своих проблем.

Поэтому все менее полезными становятся глубокие фундаментальные знания алгоритмов — они итак чаще всего уже лежат в каких-то библиотеках и для их использования достаточно помнить их ограничения и применимость, а вовсе не реализацию.
NB: я бесконечно далёк от Go, если что.
На каком-то бесконечно далёком собеседовании на должность программиста меня начали гонять по порядку аргументов в редких процедурах-функциях, вплоть до winapi. Были очень удивлены моей реакцией, которая была не «не знаю» или «не помню», а «да мне в общем-то пох какой там порядок».
Это я к чему — с таким вашим подходом лично я завалю любого кандидата на собеседовании по любому мало-мальски известному мне языку. Ну может кроме сеньора из сеньоров, но его и без этого видно практически сразу.
И да, я честно опросник дочитал примерно до середины — реально годный вопрос номер 12 и с оговорками 8-9 (если это реально используется в ваших проектах).

Экзамен в вузе.


Входит преподаватель:
— Вопрос на 5 — как меня зовут?
Молчание.
— Вопрос на 4 — что сдаем?
Молчание.
— Вопрос на 3 — какого цвета учебник?
Голос с заднего ряда:
— Во валит!

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

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

Но почему даже после отсева к вам попадают люди с средним баллом 3,3, а не с 8+ как вы хотите?
Почему вы со своим предложением не интересны людям с 8+?
Почему ваши ожидания, что Senior должен знать на 8+, так расходятся с реальностью?

Отличные вопросы, между прочим!

Почему ваши ожидания, что Senior должен знать на 8+, так расходятся с реальностью?

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

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

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


Но вот что меня удивляет: 28 тривиальных вопросов стали вдруг мучением для программиста. Как это произошло? Когда?

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

или в чем поинт?
поинт в том, что мало входных данных. Нет понимания обучения, будет ли гап в месяц-два на вхождение в должность и принятия тех ресурсов. Зачастую люди набираются под проект и имеющиеся ресурсы. Если есть второй миддл/серьор, который знает хеши в Го, то он и расскажет о них в первую неделю при правильной постановке задачи, а ваша задача как итервьюера оценить возможность принятия новой информации и технический бекграунд.
У вас хороший список вопросов, но очень неправильно преподнесен подход и ожидаемы ответы. Человек должен рассуждать, выдавать свои знания, а не совпадения своих знаний с вашими. Т.е. про хеш и порядок можно уточнять
что за функция, почему дерево, почему не дерево, почему не двоичное, почему двоичное, что такое дерево, какие типы деревьев знаете, почему тут хешь это набор связанных списков, а не деревьев, нужно ли его балансировать или с этой задачей и так поплывем, а если у нас хеш на 10 элементов, а если на 100млн, есть разница?
Вот в чем поинт, а не просто ждать «ну потому что в Go придумали так».
наводящие вопросы построены именно по такому принципу, да
судя по посту, мне кажется вы путаете причину и следствие.
На собеседовании наводящие вопросы приводят к знаниям, а не отсутствие знания к вопросам.
Если окружающая вас реальность не соответствует вашим ожиданиям, то нужно менять свои ожидания, а не огорчаться на реальность.

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

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Вот реально — 28 тривиальных вопросов теперь у нас считаются завышенными ожиданиями?

НЛО прилетело и опубликовало эту надпись здесь
ну вот как будет готов ваш курс «Интервью для программистов!» — так и поговорим :)

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

если у вас конкурс прыжков в мешках — я вас не критикую.

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

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

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

или обмазываться годогенерацией.

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

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

Мне за последние 7 лет в Go встречалась одна-единственная библиотека, что предполагает кодогенерацию. Но не для генериков, а кодогенерацию объектов соответствующих конкретной схеме базы данных.

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

Map, возможно, самая важная из стандартных структур данных, и весьма замысловато устроенная.

Для тех, кто не знает ответа, есть вариант сделать "ход конем". Спросить интервьюера, мол, а Вы в курсе, что из-за неэффективности хранения большого количества пар ключ-значение Discord переписал одно из приложений на Rust? А те, кто имеет дело с реальным highload препочитает "использование slices вместо maps для хранения key->value значений".


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


  1. Какие технологические недостатки языка Go вы можете назвать?

Непригодность встроенного типа map для highload :)

Там не собственно в map было дело, а в его взаимодействии с GC.


И это починили, даже раньше, чем Дискорд переписался...

Возможно, я что-то пропустил. Разве интенсивная работа с map не вызывает больше фрагментации памяти? Разве циклом сборки мусора теперь можно пренебречь?


Ради интереса запустил https://www.komu.engineer/blogs/go-gc-maps


go version go1.14.6 windows/amd64
With a map of strings, GC took: 1.3960798s
With map of strings(that are hashed to ints), GC took:: 11.0006ms

Программа создает словарь размером 30E6 а затем запускает runtime.GC()

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

Интересно. По какому критерию Вы определили, что цикл GC при наличии в памяти обновляемого словаря размером в 30E6 элементов влияет на производительность в допустимых пределах?

бенчмарк написал, со случайным чтением/записью, графики нарисовал

циклы GC на них видно, но и близко нет той пилы, которую дискорд нам показывал. на 1.9 — есть.
А те, кто имеет дело с реальным highload препочитает «использование slices вместо maps для хранения key->value значений».


Особенно если им нужен частый поиск по ключу.
Ну да, конечно.

Можно тут поподробнее раскрыть? Вы считаете, что Александр Валялкин (автор цитаты "использование slices вместо maps для хранения key->value значений") использует для больших кэшей структуры типа map а не что-то на основе slice?

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

про конкретные значения есть в начале статьи

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

Забавно. Почти на всё есть ответ в книге "Язык программирования Go". Неужели не все go-разработчики её читают?

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

Ну и в добавку, вот мой любимый вопрос, который отсеивает джунов, да и вообще, людей, которые не понимают, что не все задачи решаются технически.
Как сохранить 10ГБ на диск объемом в 1ГБ?
Почему-то, люди начинают и в правду решать эту задачу. Самый лучший ответ, который я слышал, это сохранять в /dev/null :))
Как сохранить 10ГБ на диск объемом в 1ГБ?

Ответ "если в заархивированном виде не влезает, то никак" принимается?

Нет, можно с потерями сохранить :)

Ну в моем контексте термин "сохранить" это операция обратная "загрузить", причёт сохранить . загрузить = id. Что накладывает определенные ограничения на работу этих функций.

В условии задачи было только сохранить...

Да, сохранитЬ, только термин "сохранить" означает конкретную вещь. А не просто "записать что-то куда-то". Если мне сказали записать файл а я записал нолик на диск — это я сохранил или ещё нет? Как вы это определили?

НЛО прилетело и опубликовало эту надпись здесь
Тогда тут впору развести полемику «что означает сохранить» :)

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

Вопросы интересные, но откуда вообще уверенность, что сильный программист, которому интересно разбираться во внутренностях языка на уровне знания конкретных хеш-функций в мапах, вообще будет смотреть в сторону Go и неизвестной галеры типа Evrone?

Ну и еще наброшу из реальных собесов по гошечке: medium.com/@gotzmann/so-you-think-you-know-go-c5164b0d0511
сильный программист, которому интересно разбираться во внутренностях языка на уровне знания конкретных хеш-функций в мапах


Это отнюдь не показатель «сильного программиста».
Сильного олимпиадника, возможно.

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

действительно! Не чета какому-нибудь https://andersenlab.com/ или EPAM/Luxoft!

Про епам/люксофт я например слышал, а про Evrone первый раз

Ну и еще наброшу из реальных собесов по гошечке

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

Что, даже четвёртый?

Присмотрелся повнимательнее — да, в последнем какая-то дичь. Причем если заменить a = append(a, 5) на a = a то поведение программы совершенно меняется. Судя по всему что-то с реаллокацией происходит, но на сторонний взгляд выглядит как баг.

это документированное поведение.

a = append(a, 5) расширяет слайс не на один элемент, а с запасом.

в результате второй append, который 6 элемент добавляет, не приводит к переаллокации.

Я понимаю как работают списки на массивах, вопрос немного в другом. Поведение программы


package main

import "fmt"

func surprise(a []int) {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}

// Quiz #4

func main() {
    a := []int{1, 2}
    a = append(a, 0)
    surprise(a)
    fmt.Println(a)
}

и


package main

import "fmt"

func surprise(a []int) {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}

// Quiz #4

func main() {
    a := []int{1}
    a = append(a, 0)
    surprise(a)
    fmt.Println(a)
}

Совершенно различается! Получается, у вас весь флоу программы без единого условного оператора зависит от реального значения, которое написано в a! Это же жесть.

привильный flow вот такой:
package main

import "fmt"

func surprise(a []int) []int {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)

    return a
}

// Quiz #4

func main() {
    a := []int{1, 2}
    a = append(a, 0)
    a = surprise(a)
    fmt.Println(a)
}


он вполне однозначный. и об этом много где написано

ну или еще вот так можно, тоже все однозначно
package main

import "fmt"

func surprise(a []int) {
    a = append(a, 5)
    for i := range(a) {
        a[i] = 5
    }
    fmt.Println(a)
}

// Quiz #4

func main() {
    a := []int{1, 2}
    a = append(a, 0)
    surprise(append(([]int)(nil), a...))
    fmt.Println(a)
}

Что значит "правильный флоу"? Это корректный код на Go? Если нет то вопрос, почему нет ворнингов. Если да, то мне непонятно, почему изменение контента влияет на поведение. Потому что получается, что у вас например с консоли массив читается, а дальше в зависимости от того что ввел пользователь семантика совершенно различается. Либо это УБ, тогда вопросов нет (разве что откуда в современном языке с ГЦ взялось УБ)

surprise(append(([]int)(nil), a...))

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

это документированное поведение.

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

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

Это ведь прямо место для линтера, да?

да, но я не могу его придумать :)

надо смотреть на аргументы (https://habr.com/ru/company/oleg-bunin/blog/521582/?reply_to=22140014#comment_22140048, вариант 2)

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

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

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

А при чем тут они? Они си делали, и для других целей совсем.

В смысле причём тут они? Вы не знали, что в разработке Cи и Go (и кстати, частично C++) участвовали одни и те же люди? Вы же не думаете, что Go 11 лет?

Go 11 лет. А то так можно приплести что тайпскрипт это такой Паскаль, ведь Хейслберг пилил. И ему 50 лет

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

Никогда в живой природе cfront не видели, кстати? А я видел. На одном диске с позапрошлой версией Go. А знаете что объединяет Go и UTF-8? Они созданы друг для друга. Это не философское утверждение

А знаете что объединяет Go и UTF-8? Они созданы друг для друга.

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

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

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

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

Это не строка, извините, а bytearray или что там у вас является аналогом в языке

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

Это не строка, это набор байт.

Это не строка, извините, а bytearray или что там у вас является аналогом в языке


Э… нет, господа.
Это именно строка, но пришедшая из внешнего источника. Он нас не зависящая.
Например, строка из файла-шаблона для формирования HTML.

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

От внешнего источника не может прийти UTF-8 строка, может прийти только набор байт. А в строку её надо парсить. Причем парсинг может очевидно завершиться неудачно.

А в строку её надо парсить.

Имеет смысл парзить, если вам нужно её парзить.
Ну а если не нужно?

Если нужно просто сделать что то типа «внешняя строка»+«мои данные»+«другая внешняя строка» = записать в файл?
И что там было во «внешней строке» нас не интересует.

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


Мы то работаем с ней как со строкой — см. выше.

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

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

Тогда это не строка :shrug:


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

Так вы уж определитесь — "современные языки заставляют проверять кейсы" и "ну мы-то люди, не проверяем нихрена".


А то с моей колокольни это все больше напоминает карго-культ, где с одной стороны в компиляторе встроена проверка не ниспользуемые переменные и форматирование, а с другой херак-херак, непроверяемые строки (но надеемся что там всё ок), interface{} через interface{} и прочее. В итоге бамбуковый аэропорт совсем как настоящий, но почему-то не работает.

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


Вы путаете ветки разговора.
Если нужно просто сделать что то типа «внешняя строка»+«мои данные»+«другая внешняя строка» = записать в файл?
И что там было во «внешней строке» нас не интересует.

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

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


Мы же о Go?


byteA:= []byte("aaa")
byteB:= []byte("bbb")

byteC:= byteA + byteB // а так нельзя
byteC:= append(byteA, byteB...) // можно так

strA:= string(byteA)
strB:= string(byteB)

strC:= strA + strB // а так мне нравится больше


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

Вы молодец, а потом у Вас на входе UTF-16 и все идет по одному месту, ога-ога. И приходится делать все равно так. Ну, что ж. Удачи.

Потому что это не те строки. Но с UTF-8 с некоторым допущениями исторический факт. Спецуево за два дня

опросник лежит в открытом доступе 3 месяца уже.

а предыдущий — пару лет.

пока никто не хакнул ни тот, ни другой.

думаю, это потому, что хакать его нет никакого смысла

Для позиции


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

Совершенно адекватное интервью. Я бы сказал, что позиция, скорее, на tech lead, поскольку нужно "задать" высокий уровень, чем senior. Но я не совсем понял


средний балл по опроснику — 3.3 по шкале 0-9. 3.3, Карл! 3.3 — это, с моей точки зрения, уровень junior. Middle должен набирать, я считаю, 5+. Senior — 8+.

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


Возможно, и проблема с деньгами — люди, кто могут показать 8+ просто не особо шли. Впрочем, их и очевидно просто мало.


Считать среднее вообще не имеет смысла. Это нормальная статистика, что, чтобы нанять одного разработчика нужно провести около 10 собеседований. И это при хорошем фильтре резюме, как для mid, так и senior. Соответственно, да: 9 из 10 мидов попадают под <5, 9 из 10 сеньоров под <8.

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

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

более того, по беседе об опыте и текущей позиции тоже вполне.

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

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

— А кто ищет Сеньора Go? Собственник бизнеса или руководитель отдела, просто не ясно, где Сеньор Экономики в этом вопросе. Экономика говорит о том, что выигрывает тот, у кого средство производства при прочих равных дешевле. Просто с этой колокольни это выглядит так: «мы ищем пахаря за еду и ценнейшие опыт, который мы ему дадим в нашем колхозе». В этом смысле, эффективнее, и это тоже звучит в комментариях, у Пахаря интересоваться общим состоянием здоровья, целостностью зубов и общим развитием мускулатуры. Готовностью в конце концов пахать до ночи в сезон урожая. А инструкцию к плугу он прямо во время первой смены освоит или ему подскажут старшие товарищи.

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

Вот из моего опыта: код на go, но sql запросы совершенно не дружат с постоянными подключениями, не используются prepared (убивать за это пора уже), параметры подставляются конкатенацией с сомнительным экранированием (sql инъекции в 2020 году, уау). То есть по сути — весь код в помойку, потому что под нормальное использование подготовленных запросов его не так то просто будет переписать.
Как вы со своим опросником помогаете отсеять людей делающих такие вещи я даже не представляю.

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

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

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

ЗЫ про вред не слышал

Что же экономится-то, если в каждой следующей транзакции необходимо повторять prepare этого же запроса? А вред в том, что prepare+execute это 2 запроса вместо одного. Почитайте исходники, там звёзды должны сойтись чтобы в транзакции не пришлось повторять prepare: ранее подготовленный stmt не должен в этот момент использоваться в другой транзакции, должен уже быть ранее подготовлен именно на этом соединении с БД… Я пару раз когда-то делал бенчмарки на коленке — без prepare внутри транзакции бегало заметно быстрее, а при отсутствии транзакций — наоборот (впрочем, охотно допускаю, что проблема была в самом бенчмарке, я не очень сильно на него заморачивался).


Наверное, если заранее подготовить пул stmt в которых подготовлен одинаковый запрос и ручками распределять их между текущими транзакциями, плюс уделить внимание вопросу сколько у нас живут соединения с БД и постараться продлить их жизнь — очень может быть что и получится получить выигрыш в производительности… только я вот такого в полном объёме ни в одном проекте не видел пока. И, сказать честно, обычно тормоза реляционной БД решаются вовсе не благодаря prepare — если конечно у нас не тот самый очевидный кейс, когда один запрос многократно выполняется с разными параметрами подряд кучу раз в рамках обработки одного ответа юзеру.

О какой, простите, транзакции вы говорите, если обычно самые тяжелые запросы — чтение фильтрованных списков?

Все остальные ваши утверждения как то не сходятся с документацией.

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

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

Выполняем:
Planning Time: 5.939 ms
Execution Time: 3.437 ms
Planning Time: 4.540 ms
Execution Time: 3.030 ms
итд

Теперь Prepare, execute:
Planning Time: 0.189 ms
Execution Time: 2.818 ms
Planning Time: 0.050 ms
Execution Time: 3.809 ms

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

Не поймите неправильно. Я охотно допускаю, что не прав — собственно, я с этого данную ветку и начал (давно не сталкивался с высокими нагрузками на реляционную БД, стараюсь проектировать системы так, чтобы такая ситуация не возникала в принципе). Тем не менее, я не вижу в указанной Вами доке конфликтов с тем, что говорю я. Плюс, как бы не работал постгрес, но между нашим кодом и постгресом находится database/sql (мы здесь ведь Go обсуждаем), а он работает именно так, как я описал — сходите по ссылке выше и убедитесь. А поведение определяемое постгресом наступает уже потом.


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

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

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

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

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

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

В результате лучшие кадры приучаются делать только то, что им поручено, ничего, кроме того, что им поручено, и необходимый минимум того, что им поручено. И этот подход, я предполагаю, незаметно и неосознанно эти кадры распространяют и на свое обучение. Разработчик изучает только то, что ему нужно по текущей задаче: ничего, кроме этого, и ограничивается минимально возможным набором знаний.
По большей части согласен. Что с этим можно сделать? Да ничего. Чтобы хорошо справляться со своей работой, обычно глубоких познаний в теории не нужно. Много кому нужен начитанный разработчик, от которого профит будет больше на 0-20%, но зарплата которого в 2-3 раза больше? Бизнесу это обычно не нужно и это нужно принять. Если было бы очень нужно, тогда из 8 часов выделяли бы несколько не на работу, а на обучение.

Почему так? Почему опытные, квалифицированные разработчики набирают такой низкий балл?
Помимо вашего предположения, есть еще и другие причины:
  • в их обязанности на работе не входит сдача экзаменов) Они не заучивают и не перечитывают прочитанное в прошлом, если им это не нужно.
    Отсутствие глубокого познания теории, которые не используешь или используешь редко — это одна проблема. Вторая проблема — что большую часть рабочего времени пишешь код, а не рассказываешь, объясняешь что-либо, и эти навыки у многих деградируют, не развиваются.
  • позиция — бэкендера, а кандидат фуллстэк. Кандидат широкопрофильный специалист, а собеседуют, как узкопрофильного. Он знает больше технологий, но в лучшем случае на среднем уровне.
  • собеседования обычно проходят так, как будто интервьюер собеседует сам себя. То есть спрашивает то, в чем он хорошо разобрался. Без учета, что у других разработчиков свои знания, свой опыт, обычно сильно отличающиеся от знаний и опыта интервьюера. Программисты обычно заносчивы и уперты. Большинство считают, что все обязаны знать именно то, что знают они.
    Даже если ограничиться одним стеком, возможных технологий и знаний будет слишком много, чтобы их все знал один человек. Плюс технологии быстро меняются. Также разработчик может сменить стек.
  • они не перечитывают годами одни и те же книжки по языку и структурам данных, а изучают что-то новое, что может пригодиться в работе. На самообучение этому в течении 10 лет итак у большинства уходят тысячи часов личного времени.
  • со временем набираются опыта, меняются ценности в жизни. Приходит понимание, что технические знания особо не улучшат качество их жизни, и если развивать что-то, то эффективней точно не их. Вырастают из этих игр в крутого разработчика и вместо траты свободного времени на обучение по работе, тратят больше времени на себя и своих близких. Стать счастливым или стать крутым специалистом? Я думаю, выбор очевиден)
  • может зарплата маленькая, вот и пришли кандидаты, у кого зарплата меньше. А спецы в теории уже получше работу нашли.


6. Как устроен тип map?
Что я хочу оценить: насколько интересно кандидату, как именно ложатся в память наши байтики. … Неужели не любопытно?!
Ну, мне например такое уже не интересно. Все эти постоянные дедлайны, ограничения по времени на задачу, попадание в проекты с плохим кодом, привело к тому, что мне интереснее то, что может помочь сделать проект быстрее и код читабельней, гибче.
Ну а вообще, кому-то интересно строить, кому-то разбирать. Нет же профессии археолог-строитель?) Так и здесь. Программисты тоже разные бывают. Кому-то интересно в «кишках» копаться, кому-то интересно изучать, как сделать код более масштабируемым, третьему нравится c 3rd party решениями разбираться.

26. Какие средства обобщенного программирования есть в Go?
Что я хочу оценить: знакомство с основными парадигмами современного программирования и границами их применимости в Go.
Если вы хотите оценить знакомство с основными парадигмами, то и вопрос должен звучать: «какие парадигмы вам известны ...?»
А этим вопросом вы только про одну спрашиваете. Хорошо, если вы скажете, что именно вы хотите оценить. В таком случае вы можете получить ответ не «я не знаю», а «именно эту я не знаю, но могу рассказать про другие».
вопрос должен звучать: «какие парадигмы вам известны ...?»

прямые вопросы не работают :(

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

на любой вопрос можно зайти минимум с двух сторон, и даже со стороны «да это все не важно»

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

"они не перечитывают годами одни и те же книжки по языку и структурам данных, а изучают что-то новое,"


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

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

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

это, конечно, так и есть — никто не знает, что такое «хороший программист»

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

ценной информацией пока поделился только Matvey-Kuk. Оказалось — он отправляет кандидатов изучать некий код еще до собеса.

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

Я этого не говорил. Более того — выразился максимально абстрактно о всей Вашей отрасли в целом. Просто увидев Ваш список аж 28 вопросов я мягко говоря выпал в осадок.
ценной информацией пока поделился только

А какая ценная информация Вас интересует? Чем я руководствуюсь?
Я просто смотрю на то, что человек делал по резюме, а если этой информации нет — прошу рассказать о самых сложных устройствах которые он проектировал. И задаю вопросы, позволяющие мне оценить их сложность с моей точки зрения и прояснить с какими областями знаний он при этом имел дело. Ну например — «а к чему у Вас там была подключена память, а какая? а код контроллера памяти Вы сами писали? а как отлаживались? были ли проблемы? какие? как решали?»
У меня раньше был опросник с кучей умных вопросов с двойным дном. Я заменил их несколькими, которые не имеют правильного ответа а скорее провоцируют кандидата порассуждать на техническую тему. Пример такого вопроса «если бы Вам досталась чужая плата на проверку — что бы Вы там проверяли и на что обращали внимание».
Я уверен что в Вашей отрасли тоже можно собеседование из экзамена превратить в рассказ кандидата о себе, просто напрявляя его повествование в интересное для себя русло и прося раскрыть какие-то детали. Люди любят рассказывать о себе и любят детально рассказывать о том что знают — сами. Стресса меньше, меньше людей будут считать Вас плохим человеком и картинка получится вероятно более объективной.
У меня даже был случай, когда одна женщина (ранее работала в NVidia, сейчас в Intel — моделирует чипы ихние на Signal/Power Integrity) просто пошатнула мою картину мира. Сначала мне показалось что она говорит какую-то дичь, а через пару уточняющих вопросов (в духе — «это почему это вдруг?») я понял, что она на голову выше меня по квалификации просто. Если не вдаваться в детали, я с ней беседовал об интерфейсах до 10G, а она со мной — от 40G — просто контекст не почувствовала. Я употребил термин «высокочастотные интерфейсы», а в ее мире планка «высокочастотности» сильно выше оказалась. Получил массу новой информации в голову.
Ну все же уже глумятся над Вашими (не персонально Вашими, а в целом в отрасли) экзекуциями при найме.
я пытаюсь технологизировать процесс интервью (не зря дал ссылку на доклад)

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

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

я довольно часто слышу «спасибо, было интересно» после интервью. так что, все же, не экзекуции.
«Спасибо, было интересно» я сказал руководителю RnD компании Т-Платформы в 2012 году, собирая с пола остатки своего самолюбия после 3х часового экзамена, включающего основы фундаментальной физики, высшей математики, принципа триангуляции сигнала, Signal/Power Integrity, задачки и ребусы. В общей сложности я ответил на 8 из 10 вопросов (с подвопросами) и получил отказ.
После этого месяц страдал от собственной ничтожности, а еще через 3 месяца мне оттуда позвонили и сделали оффер, так как этот человек (в целом кстати очень хороший и я рад знакомству с ним — просто вот так он проводит собеседования) за 4 месяца не смог никого нанять.

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

у нас страдать некогда, у нас ажиотажный спрос на спецов.

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

кто сказал — не закрываем?

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

вы же понимаете, что это вопросы не ко мне, а к указзанным в статье хантерам?

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

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

у меня есть ответ, но он никому не понравится

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

Спасибо за ссылку, было весело!

Куда идти? Кого бить? А вообще, тут я узнал что я внезапно Гном-Воин. Хотя вроде как работаю магом и люди меня считают тролем. Да фигня это все ваши психологические тесты в интернетах, ИМХО.

Ну вот, например, я как-то думал дать HR чёткую инструкцию какие резюме отсеивать, а какие нет, имея перед глазами несколько десятков откликов от кандидатов, половину из которых я собеседовал потом и отсеял бОльшую часть как "какой сеньор?! ему год минимум в нашей команде работать под чуткой опёкой, чтобы миддлом стать"


Сдулся после, когда "инструкция" на 10-й лист полезла, а имеющиеся резюме стали попадать в не те классификации.

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

никто не знает, что такое «хороший программист»

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

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

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

ценной информацией пока поделился только

Желаете ценной информации? Пройдитесь по опыту соискателя. Знаний можно почерпнуть сколько угодно.

Примеры:
Человек отвечает что написал много крутых клиентских библиотек для REST API: можно спросить о недостатках, даже подсказать про уровень транспорта и приложения, да даже прямо намекнуть про коды ошибок, если не упомянет про 401,403,404,500, то я склонен сомневаться в его опыте.

Знает vue.js? Да самое простое, отличие computed/functions, data/props. Хуки жизненного цикла (те что помнит). Если не ответит значит не работал с vue, если ответит то по сути всe, особо спрашивать там больше нечего.

Любит ORM? Да еще доктрину? Спросим про мэппинг кастомных запросов.

Обожает фреймворки? Ок, пройдемся по компонентам фреймворка и зачем они вообще то нужны.

Пишет запросы: select, join, group by, having, with (cte), partition over(window functions) и смотрим где сознается или замнется и уже понятен уровень.

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

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

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

а заказчику интервью я что скажу? «я поговорил, норм чел»?

а в ответ на «ты с тремя поговорил, какого берем»?

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

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

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

или вам кажется, что и не надо все это знать, можно так, без знаний кодить? так ведь нет, нельзя.

«я поговорил, норм чел»

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

«ты с тремя поговорил, какого берем»

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

и еще у меня будет измеримая метрика.

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

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

вам все кажется, что я прекрасных кандидатов сливаю

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

так ведь нет, знать-то они больше не начнут

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

или вам кажется, что и не надо все это знать, можно так, без знаний кодить? так ведь нет, нельзя

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

ЗЫ я вот прочел вакансию которую вы линканули, читаем «Знания и опыт использования баз данных не только через ORM (у нас есть PostgreSQL, Tarantool и Redis)». Значит разработчики сами пишут запросы, значит умение их писать весьма важно (прямо в основном блоке), у вас по этому делу — ни одного вопроса. Но уверен если бы были вы наверняка бы спрашивали устройство b-tree, gist индексов, wal, буферизацию и это вот все и это как раз то что интересно в последнюю очередь.

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

Вот эта мысль, что я что-то нетривиальное спрашиваю — она откуда? :(

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

То есть — я спрашиваю тривиальное, Но кандидаты не могут ответить?

Средний балл 3.3 уже говорит сам за себя. В остальном вам уже подробно расписали в чем дело, в том числе и я. Если желаете возразить — делайте это пожалуйста аргументированно.

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

По-моему Вы немного забыли постановку задачи. Если бы это был собес на сениора — один разговор. Сениор должен уметь ровно то, что уже много раз упомянули в комментариях, а не то, о чём статья (но отличный сениор не будет этим себя ограничивать, и сможет справиться с большинством вопросов не напрягаясь). Но в статье чётко сказано: «найти человека, который сможет задать и поддерживать высокий уровень профессионализма в применении языка Go». Вы где-то здесь между строк прочитали слово "сениор"? Перечитайте, его там нет.


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


P.S. Лично меня тоже огорчает тот факт, что сейчас вполне нормально работать сениором и даже хорошо справляться со своей работой, и при этом не знать ответы на такие вопросы. От найма таких сениоров меня это не остановит (как не останавливает и onokonem — если нанять нужно именно сениора), потому что доучить их при необходимости не сложно, но… всё-равно это огорчает. Возможно дело в том, что когда я начинал более 30 лет назад — мне было интересно само программирование, а не "таски пилить" или "крутая зарплата". И до сих пор мне интересно само программирование — поэтому я им занимаюсь вне зависимости от того, платят ли мне в данный момент, или нет. И поэтому я плохо представляю себе как можно называть себя сениором и при этом не знать элементарных вещей, описанных в статье. Ну т.е. мне — было бы стыдно. Для выполнения типичной работы сениора — да, можно многого из этого не знать. Но самому искренне считать себя "старшим разработчиком", учить других, и при этом не быть в состоянии ответить… я этого просто не понимаю, честно.

По-моему Вы немного забыли постановку задачи

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

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

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

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

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

ЗЫ поймите меня правильно, я сам в ужасе от того какие прикольные люди просят с порога по 200 тысяч, но поймите так же и тот факт, что действительно крутые ребяты уж точно не будут рады допросам с пристрастием, я сам через это проходил и больше у меня нет никакого желания (делаем еще скидку на тон и формат с которым это делается). В том числе потому что я оглядываюсь вокруг и вижу кто как работает и я так же знаю как трудно найти хорошего специалиста. У меня даже есть личный подбор примеров веселых проектов вроде интернет магазина за 40 месяцев или баз данных которые еле ползают. И среди авторов этой дичи очень много людей которые легко проходят такие собеседования, а у меня от их кода facepalm непрерывно случается. Посему когда я нанимаюсь разработчиком, выбирать буду я и выбирать придирчиво, начиная с избегания вот таких допросов и очень многие разработчики которых я бы хотел нанять сделают ровно также.

ЗЫЗЫ Ну и средний 3.3 смущает дальше некуда. Знаете как говорят: «если на вопрос ответили все, это легкий вопрос, если никто — тупой». Если _средний_ показатель настолько низок то вы ищете либо не так (что тут уже попытались объяснить), либо не там (уровень зарплаты я бы не назвал мечтой).
Нет не забыл, я сходил по ссылочке из коментария, прочел вакансию, нашел компанию на hh и хабр карьере, посмотрел ставку и сделал выводы.

+1

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


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

Возможно, а еще вы совершенно точно никогда не увидите тех кто знает себе цену.

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

Сейчас икать не в столицах на позиции middle+ долго дорого и сложно. А уж какое веселье искать тимлида/cto ууух… Будет еще хуже. Потому что даже у самых упертых патриотов или особо привязанных к месту/родне/окружению начинают сдавать нервы.
Ну, что там за задача — на самом деле не понятно.
В статье одно, а в вакансии — сеньор. Чем заниматься будет разработчик — не понятно. Может компания галера и разработчик будет пилить небольшие стартапы, а может поддерживать и развивать продукты с многомилионной аудиторией.
«Найти человека, который сможет задать и поддерживать высокий уровень профессионализма в применении языка Go». Мы не знаем, уточнял ли автор статьи, что под этим подразумевается, каким видит подходящего кандидата заказчик. Может автор понял по своему.

Дана задача — «найти такого-то разработчика». Деньги и время тратятся, но человек с задачей не справляется. Ладно, почему? Где анализ возможных причин? Что можно сделать, чтобы ее выполнить? Может предлагаемая зарплата низкая, может текст вакансии надо исправить?
Если же вместо анализа проблемы и предложений решения, получаем ответ вроде «причина не во мне, а в том, что все кандидаты плохие», то лично мне это говорит о том, что задачу доверили не тому человеку.
Деньги и время тратятся, но человек с задачей не справляется.

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

кодить — можно, эффективно кодить — вряд ли, разрабатывать — невозможно

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

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


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

никто не знает, что такое «хороший программист»


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


Это разница между джуном и миддлом.
Не про сеньора.
Автор, я читаю, яркий пример: с заданием не справляется, в анализе причин блока «я делаю что-то не так» нету, возможно, о проблемах заказчик тоже не осведомлен. Сеньор бы действовал иначе.

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


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

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

конечно

Понятно, что в таком случае «уверенные самозванцы» тоже пройдут

Нет, если задать несколько вопросов вглубь.
Могу простой пример привести. Кандидат рассказывает что переводили весь проект на graphQL, ярко так, убедительно. Прошу рассказать нюансы, что доставило боль, что гереоически решили — тон уже менее уверенный. Через 10 минут спрашиваю в лоб почему не выкинули бек и не запустили graphQL прямо на Postgresql: в следующие 5 минут приходим к тому что за последний год их отдел занимался ничем. Это говорит о том, что человек делал мелкие задания без понимания зачем и почему.
и не запустили graphQL прямо на Postgresql

А что, так можно было? Вот в голову бы просто не пришло при рисече гуглить "можно ли запустить graphQL на РСУБД".

Вы бы гуглили «postgresql graphql» и сразу бы получили ссылку на postgraphile. На самом деле она ставится на ноду но весь ACL поверх механизмов бд на основе RLS

по сути это и есть отдельный бекенд......

Смотря как посмотреть. В любом случае приходим к тому что «все уже сделано до нас», а далее та ветка что ниже обсуждается.
Через 10 минут спрашиваю в лоб почему не выкинули бек и не запустили graphQL прямо на Postgresql: в следующие 5 минут приходим к тому что за последний год их отдел занимался ничем


Могут быть доводы и против.

Например, нельзя напрямую отдавать наружу GraphQL из соображений безопасности — чтобы нехорошие люди не положили по сути прямыми запросами в СУБД через API GraphQL всю производительность СУБД в 0.

Другое дело, что не на уровне того человека было принимать такие решения…
Другое дело, что не на уровне того человека было принимать такие решения…

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

Как раз ACL уровня бд меня лично и смущает, у еще чуток сама нода раздражает. Кроме того у меня обычно очень быстро появляются очень сложные запросы которые в graphQL посинеть можно описывать. К тому же когда схему разворачивает на 180 градусов 4 раза в месяц, и если проект простой то graphQL ускоряет разработку, если сложный — замедляет. Но я пишу запросы на SQL намного быстрее чем с использованием любого инструмента, для большинства все иначе.

Собственно ваш аргумент или свой я и ожидал услышать. Выше хороший коммент с которым я согласен.
Тут вся индустрия со времён Windows XP занимается ничем, а вам какой-то один отдел жалко.
когда из его «рассказа о себе» вообще ничего толком не понятно.

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

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

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

Ну то есть Вы считаете, что нанимая специалиста априоре с другим контекстом, наилучший способ это проверить насколько качественно он читал учебники, утрирую?
ИМХО — это дает Вам абсолютный 0 информации.
Я бы в такой ситуации оценивал человека по следующему принципу:
— посмотрел бы что за компания в которой он работал, что за продукты она выпускает, насколько они качественны и успешны (я всегда гуглю последнее место работы кандидата и смотрю что делает эта компания как минимум);
— спросил бы о его роли в разработке — что конкретно он делал. Вы же вполне способны оценить качественно — сложно это и круто, или полная ерунда и перед Вами просто юнец который рад, что смог зажечь зеленую лампочку;
— в конце концов просто пообщался бы на отвлеченные темы, чтобы понять — а как вообще, я смогу этого человека каждый день видеть на работе-то?
Попробуйте выключить учебник и использовать джедайскую силу в общем. У Вас же большой поток кандидатов вероятно — можно и поэкспериментировать.

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

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

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

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

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

Во, пример из моей жизни. Я хочу обсудить разбор XML на Go и map[int]TStruct vs map[int]*Struct в применении к списку Роскомнадзора. И поговорить сразу станет не с кем. А вот топикастер не сможет поговорить со мной про линтер, я хз что это. Ну и так далее

НЛО прилетело и опубликовало эту надпись здесь
150Mb и я хотел таки ловить его и раз в три минуты на VDS до 20$. Это оказалось не так просто. А да. Я держу его в памяти и раздаю своему боту по protobuf. Основная проблема была в 2млн IP (сейчас их нет)
НЛО прилетело и опубликовало эту надпись здесь

Проверять на принадлежность. Выдавать метаданные согласно принадлежности. Метаданных около 200k записей. Никаких диапазонов. Разреженный массив

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Это ты на чем парсишь xml этот 4 секунды? Я в смысле оборудования и диска.

НЛО прилетело и опубликовало эту надпись здесь

Да DO закинь

НЛО прилетело и опубликовало эту надпись здесь

Это было год назад. Около 40 секунд первое всасывание. Примерно 20 апдейты. Жрет под 800Mb в пике. Но это с индексами по доменам, URL, IP. Но да, я для отдачи сохраняю данные в сыров виде и дополнительно в разобранном

А да. 150Mb — это XML. Я хочу и быстро апдейтить. Апдейты небольшие, но мне прилетает просто новая версия в 150Mb

НЛО прилетело и опубликовало эту надпись здесь

Мммм… И дольше, и жрет. Но легче делать. Это был первый вариант архитектуры. Я сделал иначе — там просто куча строк с уникальными Id. Я сравниваю контрольные суммы старых и новых, и делаю списки тех id, что изменились. Те id, что не появились в новом — удаляю. Те, что не нашлось в старом — распарсиваю. Те, что изменились — распарсиваю заново и заменяю на новую версию

НЛО прилетело и опубликовало эту надпись здесь

20$/mth vs 40$/mth на общественную деятельность — это очень ощутимое оправдание

контрольные суммы старых и новых,

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

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

Мне это напомнило тестирование на сайте учебного центра «Специалист» на владение виндой. Выглядело примерно так: «какие 10 способов переноса файла с дискеты в папку вы знаете?»
Почему так? Почему опытные, квалифицированные разработчики набирают такой низкий балл?

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

есть ли у вас на примете хороший?

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

https://roadmap.sh/ — неплохой ресурс оказался, кстати. Примеряю на себя и действительно — идея хорошая — определить на каком этапе такого роадмапа "к экспертности" находится кандидат.

Смотрю там на фронтенд — сплошные глупости.

Ну, поправьте — там есть гитхаб и можно сделать коррективы )

Между "предложить пулреквест" и "сделать коррективы" — пропасть.

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

Ага, создай свой сайт, потом сам пропиарь как следует и всё это ради… чего, собственно?

ну сделайте это просто так. just for fun. оставьте так сказать на древе знаний свою зарубку. от вас же не убудет

Я лучше что-нибудь полезное сделаю для зарубки.

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

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

Можно поправить ) Но все равно, повторяю, что это хорошая стартовая точка

там есть раздел Contribute — дерзайте
там есть раздел Contribute — дерзайте

Для потенциального сеньора это не полезный ресурс.
Готовый к выходу на этот уровень уже сам представляет, без подобных сайтов. Иначе он еще не готов стать сеньором.
P.S.:
Сейчас не рассматриваю ситуацию, когда лычку сеньора тебе дают через 3 года с начала программирования просто потому чтобы твоё тщеславие побаловать, а зарплату не добавлять.
> Для сеньора это не полезный ресурс.
сделайте его полезным для тех, что в будущем станет сеньором

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

Ради чего? Если я не согласен со всей концепцией этого сайта для сеньора.

ну тогда создайте сайт с правильной концепуией для сеньора
ну тогда создайте сайт с правильной концепуией для сеньора


Вот ведь какой вы любитель халявы…
Зачем мне на это тратить ресурсы?
Ради вас?
Незачем.
если вы так дорожите своими ресурсами, то почему вы их в пустую тратите на комменты?
если вы так дорожите своими ресурсами, то почему вы их в пустую тратите на комменты?


Это несравнимо:

1) Я потратил на коммент 10 секунд.

Вы же теперь утверждаете: «ты потратил 10 секунд, то потрать и 5 дней на разработку роадмапов — это же одно и то же».

Вы серьезно?

2) Может быть вы и работаете бесплатно. А я не практикую такое.

В комментах идет оплата эмоциями: я получаю удовольствие от прямого общения.

А чем вы мне оплатите за роадмапы?

P.S.:
Как и любой человек халяву я тоже люблю как и вы.

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

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

А требовать, чтобы кто-то для вас что-то сделал бесплатно — это совсем другое.
>> Вы же теперь утверждаете: «ты потратил 10 секунд, то потрать и 5 дней на разработку роадмапов — это же одно и то же».

вам не надо 5 дней на разработку роадмапов
>> Вы же теперь утверждаете: «ты потратил 10 секунд, то потрать и 5 дней на разработку роадмапов — это же одно и то же».

вам не надо 5 дней на разработку роадмапов

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

> Ну так если вы это знаете — то вы и составьте. Не?

а не занимаюсь ни фронтендом ни бэкэндом
а не занимаюсь ни фронтендом ни бэкэндом

Но надо полагать по своей области вы уже составили роадмап для желающих? Где его можно посмотреть?
ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B5%D1%82%D1%8C%D1%8F_%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0_%D0%9A%D0%9F%D0%A1%D0%A1


Вот так удобнее см. ту ссылку, что вы привели: Третья Программа КПСС, 1961 г.

Тег «a href» здесь комментах можно использовать.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Позавчера мне было интересно (в этом же треде) наваять парсер РКНовских блэклистов на хаскеле, чтобы посмотреть на производительность и объём кода и сравнить это с Go — я это и сделал.

с нетерпением ждем очередной статьи со сравнением haskell vs go!

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
вот и у меня нету :(

но я работаю над этим!
Образование — это игра в долгую, и подходить к нему надо с другими критериями, нежели к очередному «Проверим идейку MVP».
Казалось бы, при чём здесь образование…

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

статья не о проблемах найма, которых нет, а о проблемах квалификации, которые есть.

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

завышенное ЧСВ — этим можно что угодно аргументировать :)

но я лично не думаю, что у кандидатов что-то завышенное и/или неадекватное.

со своей работой они справляются ведь? справляются!

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

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

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

да. ответственность самого разработчика. lifetime learning. но не все разработчики знают об этой отвественности. а те что знают, не знают как учиться. а те что знают как учиться, не учат других тому, как учиться. вот и давайте те, кто знает, будут делться знаниями с теми кто не знает
детектировали мы вместе с кандидатом на собесе.

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

А представляете себе подобный автоматический онлайн-детектор? Чтобы в вакансии бросить сыслку на него и дописать "если не можете пройти на 80 из 100, то не тратье своё и наше время?"

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

именно эту автоматизировать, скорее всего, не удастся (и я говорю об этом в докладе)
А вот было бы неплохо, если бы компании выкладывали перечень вопросов или тесты, показывающие, что у них примерно спрашивают на собеседованиях. Конечно, вопросы у интервьюера и вопросы в открытом доступе должны быть разные.
У компании уменьшилось бы количество неподходящих кандидатов. А кандидаты смогли бы сэкономить время, оценив адекватные ли вопросы у компании или там спрашивают всякую чушь, которая или никогда не пригодится или которую помнить нереально.
ИМХО Cracking the coding Interview и есть пример такого подхода. Но опять же FANG это FANG, а какой-нибудь мелкий стартап или безымянная энтерпрайз галера скорее просто получат резко уменьшившийся поток кандидатов.

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

> А есть какой-то стандарт, что должен знать сеньор?
а сеньор в какой области?

Да в любой ит-шной.

вот прям в любой?

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

Супер! Наверное как раз оттуда были все вопросы в данной статье:) и каждый на собесе это спрашивает, «стандарт» же!

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

Профессиональные стандарты, разве что.

А есть какой-то стандарт, что должен знать сеньор?

это тема отдельной большой статьи.

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

но формализованного описания я пока не видел. возможно — про это будет следующая статья :)

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

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

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

прощаю вас коллега, список приведен в качестве стеба. знание — сила

А потом ещё и performance review раз в квартал, а то вдруг забыл чего. И ещё каких-нибудь проверок знаний и чтоб не менее одного выступления на конференции. С процессами всегда все хорошо, это с квалификацией всегда проблемы:)

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


Я себя не позициюнирую как Go разработчика, не работаю Go разработчиком, хотя считаю, что на уровень Middle претендовать вполне могу (несколько pet проектов именно на go, в том числе и с задачами на производительность).


Так вот, на 2/3 вопросов в режиме "здесь и сейчас" я ответить не смогу. На подкорке мгновенно мозг ответил только про каналы, sync.map, профайлер, да про логгер.
А что самое интересное — почти по всем вопросам я в своё время детально разбирался (разве что во внутренности структур не лез руками, но читал про них), очень многие вещи есть в моём коде, который я осознанно писал.
Ну то есть я готов дать осознанный ответ, но если мне дадут на каждый вопрос несколько минут покопаться в собственном коде и повспоминать ;))
Вот даже про подключение профайлера — не помню я, как его подключать, хотя подключал и использовал.


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


p.s. Даже вопрос про доступ из нескольких горутин к []byte тоже спорный — да, лучше, к примеру, каналами, но если представить, что это общий вопрос, то на месте []byte может оказаться мапа, к которой нередко нужен доступ из множества горутин (и не всегда тут синкмапа подойдёт). И тогда кандидаты будут отвечать не на вопрос "нафига вообще лезть к []byte", а на вопрос "как обеспечить одновременный доступ к разным объектам, если считаем, что такой доступ точно нужен".

вопрос про доступ из нескольких горутин к []byte очень спорный — я просто не придумал ничего лучше.

Роб Пайк недоволен опом, ведь он разрабатывал язык для макак, которые не задаются вопросами типа "Есть ли для Go хороший orm" или "Какой у вас любимый линтер". там 100 страниц спецификации и 50 бест практис, это все что нужно знать.

100 страниц спецификации и 50 бест практис вполне достаточно, чтобы набрать на этом опроснике 8+
время «бородатых» программистов прошло, сейчас люди изучают достаточный минимум для решения практических задач и шаг влево/вправо проваливаются… нет знаний, толи дело было в 98 году ядро freebsd пересобирать, к примеру, постоянно с новыми опциями и смотреть что будет… просто так) или ставить (на сегодняшний взгляд) нелепые задачи и решать их еще более нелепыми способами, но получая бесценный опыт и знания, вместо instagramm/tinder etc…
> время «бородатых» программистов прошло, сейчас люди изучают достаточный минимум

— Да, были люди в наше время,
Не то, что нынешнее племя:
Богатыри — не вы!

Но будет помнить вся Россия про Как пропатчить KDE2 под FreeBSD

Самое главное что хедхантеры не расстраивают!
7. Каков порядок перебора map?
Самый популярный неправильный ответ: «В порядке вставки». Хеш-таблица, которая сортирует элементы в порядке вставки, ага. А как в ней происходит выборка по ключу в таком случае?

Если взять для примера Java с его JVM, то одна версия отдает обход по дереву, а другая отдает по вставке, вне зависимости от формирования дерева. Один и тот же обход map на мобилке и десктопе будет работать по разному.
Возможно в Go есть подобные штуки.
Так что это вопрос из серии «угол заточки стамески».

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

а смысл, если ответы на вопросы выше гуглятся за 5 минут при нормальной техбазе. У вас вопросы по Go, а не по тех базе специлаиста.

Стандартный набор метрик prometheus в Go -программе?

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

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

дашборд — это вообще не про это (и это часть вопроса)
7. Каков порядок перебора map?
Самый популярный неправильный ответ: «В порядке вставки». Хеш-таблица, которая сортирует элементы в порядке вставки, ага. А как в ней происходит выборка по ключу в таком случае?


Если взять для примера Java с его JVM, то одна версия отдает обход по дереву, а другая отдает по вставке, вне зависимости от формирования дерева. Один и тот же обход map на мобилке и десктопе будет работать по разному.
Возможно в Go есть подобные штуки.
Так что это вопрос из серии «угол заточки стамески».


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

Проверил.
Оказалось, что при обращении к одному и тому же мапу порядок перебора может меняться.
Деталей не помню, то ли после перезапуска программы то ли еще какая погода на Луне влияет.
Но в спецификации языка порядок вам не гарантирован. И так оно и есть.
Гарантировано только что вы можете обойти весь мап.

Так что это вопрос из серии «угол заточки стамески».

Вы вот напрасно так пренебрежительно.
Угол заточки принципиально важен.
Из того, с чем вы можете лично столкнуться: посмотрите форму свёрел по металлу, по дереву и по бетону. Они сильно разные. Одно сверло вообще не способно решить вашу проблему в другой ситуации.
С поиском далеко не всегда всё так плохо. Чаще опирается только в оценки О(). То есть вы можете использовать и другой алгоритм. Просто он будет медленным.
Другое сверло вы использовать не сможете, вообще никак.

угол заточки стамески зависит от задачи и материала.
Если ставить вопрос про угол, то ответ «разный»
Так и с перебором
какой порядок перебора, ответ «разный»
Хм ну опросник по стеку из одного языка это конечно здорово. И я наверное смог бы ответить на половину, если бы работал с одним языком достаточно длительное время. Вот только я в аутсорсе 8 лет (вру был пару лет в продуктах в Берлине, но там такая же ситуация). Так вот за это время я писал на php 5-7, react, angular, nodejs и вот сейчас пишу амазоновские лямбды на питоне. Просто потому, что сегодня у вас один проект, а через месяц другой с другими потбностями и стеком. Я правда должен вызубрить всю теорию по всему стеку? А можно спросить зачем? Чтобы интервьюверу было приятно? Ну так себе причина. Ну и вообще умению проходить интервью (читай — продавать себя) и плодотворно работать — это 2 разных и не особо связанных с собой скила. И для второго совсем необязательно обладать первым. В целом при походе по собесам есть 2 основных типа интервьюверов. Первые, как автор, проверяют как вы зубрите теорию и насколько хороша ваша память. Вторые проверяют умеете ли вы думать над задачей и находить решение. Я врядли пройду собес у первых (да собственно не очень и хотелось), но вполне успешно прохожу и с удовольствием работаю со вторыми. В конце концов на рынке труда IT — работник выбирает работодателя, а с переходом многих контор на ремоут все стало еще проще. И на один отказ от любителей теории я получу 3 офера от других работодателей. На самом деле статистика даже не 1 к 3, последний раз когда искал работу из 12 собесов получил 10 оферов. Так что будьте проще — и люди к вам потянутся.
коллега, а какой из 28 вопросов показался вам самым теоретическим, и какой — самым сложным?

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

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

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

Не считаю, что вопрос про реализацию map это классический (кажется, именно на нём чаще заостряли внимание). Если человек знаком с этой реализацией, это вполне себе показатель того, что он интересуется инструментом и изучает его. Для примера — в js, в отличие от других языков, которые я знаю, обход map должен сохранять порядок вставки элементов. Интересно же, как это реализовано. Очевидно, что senior должен знать это отличие. И можно ожидать, что обсуждение деталей реализации этого отличия может быть частью желаемой вами дискуссии

Знать не должен. Но должен быть способен такую структуру данных спроектировать.

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

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


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

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

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

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

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

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

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

можно получить за ответ «0,47 секунды — за столько гугл выдает мне невелосипедное решение»?
1. это разные пункты, вы заметили?
2. можно попробовать. за сколько вы реально это нагуглите? и что вы нагуглите? хронометрируйте, показывайте, будем смотреть
Заметил. Разные пункты должны быть самосогласованны, разве нет? Или подразумевается, что тут будет задушевная история в духе: «Для начала расскажите мне контекст задачи, почему было решено использовать односвязный список и почему возникла необходимость его обращать?» с дальнейшим предложением более элегантной структуры данных?

Я это реально загуглил за 0,47 секунды. Не верите джентльменам на слово?

Очень жаль, вот пруф
image


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

Это я специально ограничения соблюдал с нагуглить. Для велосипедов у меня отдельная закладка есть (считаем время за 0?). Можете и ее прокомментировать, очень любопытно.
набирали запрос и анализировали результаты вы, видимо, 0.05 секунды. это нереально круто!

вариант хороший

а закладка вообще шикарная.

и то, и другое потянет на 9
Большое спасибо за ответ. Возможно, я не вполне корректно сформулировал, конечно, общий процесс занял больше полсекунды, но в целом даже с набиранием запроса и пониманием того, что вот уже четвертая ссылка дает адекватный и работоспособный вариант, ушло очень мало времени, не засекал, но по субъективным ощущениям, в минуту всяко уложился. Я просто хотел сказать, что на мой взгляд, нет ничего постыдного в том, чтобы не помнить детали реализации совсем типовых задач, если точно знаешь, что их хорошие решения уже есть и ищутся за разумное время. Главное, чтобы при этом не атрофировался навык решения тех задач, которые не удается нагуглить — вот тут это уже обсудили.

p.s. Рад, что закладка понравилась. Всегда делюсь ей с удовольствием!
  1. Где следует поместить описание интерфейса: в пакете с реализацией или в пакете, где этот интерфейс используется? Почему?

Оба варианта плохи, если нет какой-то специфики у Go, красиво решающую ситуацию "много пакетов с реализацией интерфейса, ещё больше пакетов использующих этот интерфейс с реализаций, которую клиент или бутстрап предоставит.


P.S. Прочитал вакансию. Выглядит так, что, с учётом этого поста, можно подготовиться за пару месяцев по вечерам и віходным на такого сеньора, если немного покривить душой и сказать, что опыт на Go есть. Или убедить начальство попробовать Go для сервиса-другого и сильно переинженерив их. Главное туториал хороший найти по "ентерпрайз" разработке на Go. Я в своё время не смог. Вообще, кажется неудачное время выбрал для входа в Go, как раз выход модульной системы новой, как я понимаю.

go не про энтерпрайз разработку. go — про смузи-хипстеров и 20-летних синьоров

Забрал нишу Руби? )

Ну, у Go такая специфика как раз есть, в виде отсутствия явной директивы реализации интерфейса. Поэтому, если интерфейс используется всего в одном пакете — ему самое место именно там и быть объявленным.


Третий пакет понадобится только в том случае, когда у интерфейса несколько потребителей, либо если вы собираетесь в пакет с реализацией добавить тест на соответствие реализации интерфейсу. Но последний вариант противоречит идеологии языка Go, и если появилось желание так сделать — пора задуматься от переходе на какой-нибудь Rust или хотя бы C# :-)

Но последний вариант противоречит идеологии языка Go,

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

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

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


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

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


Нет совершенно никакого смысла в проверке соответствия неэкспортируемому интерфейсу! Эта проверка имеет смысл ровно в одном случае — когда есть гарантия, что "проверочный" интерфейс совпадает с требуемым.

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


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


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


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

Вот есть снаружи интерфейс:


type Foo interface {
    bar(name string)
}

Я в библиотеке пишу его реализацию:


type Baz struct { }

func (*Baz) bar(id int) { }

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


type Foo interface {
    bar(id int)
}

...

var _ Foo = new(Baz)

Ну и внимание вопрос: нафига была эта проверка, если ошибку она не отловила?

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


А у Вас откуда-то взялось второе объявление интерфейса Foo, которое соответствует не требуемому, а неправильной реализации. Откуда и зачем оно вылезло?

А у Вас откуда-то взялось второе объявление интерфейса Foo

Вы мне посоветовали. Я-то как раз с самого начала писал, что надо не копировать его, а импортировать актуальное.

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

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


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

А если как в других языках, общие интерфейсы, у которых заведомо много реализаций будет (DBAL например), выносить в отдельные пакеты? Совсем не go-way?

Go-way здесь заключается в том, что:


  1. Интерфейс не привязан к реализации, вообще никак. Это важно и круто. Язык даёт нам это из коробки, и go-way тут в том, чтобы не пытаться прибивать их обратно гвоздями друг к другу ручками, по привычке из других языков.
  2. Пользователям рекомендуется принимать внешние зависимости в виде минимального интерфейса, описывающего только то, что реально использует данный конкретный пользователь (что зачастую понимают как "пользователь должен сам объявить нужный ему интерфейс", но это не так — если где-то уже объявлен подходящий, то его использование ничем не противоречит go-way).

Конкретные примеры из стандартной библиотеки:


  • минимальные интерфейсы (буквально из одного метода) вроде io.Reader уже объявлены и рекомендованы к использованию (хотя объявить свой такой же никто не мешает, и он ничем не будет отличаться в использовании от стандартного, но это просто лишняя бессмысленная работа и так обычно никто не делает);
  • а вот например библиотка log никакого интерфейса не объявляет, хотя очевидно же, что всем нужен логгер, причём полезно иметь возможность его подменять или мокать, а для этого очень бы пригодился интерфейс — потому что большинству её пользователей обычно нужны не все её методы, и даже не большинство, а один-два (и, соответственно, альтернативному логгеру обычно достаточно реализовать для совместимости со стандартным логгером только часть методов — да, это не сделает его 100% совместимым, но для большинства пользователей логгера — которые, в соответствии с go-way, принимают параметром минималистичный интерфейс логгера содержащий только нужные им методы — такой сторонний логгер окажется вполне совместимым со стандартным).

Понятнее стало, спасибо.

общие интерфейсы, у которых заведомо много реализаций будет (DBAL например), выносить в отдельные пакеты?

Прошу прощения, отвечая на последний вопрос я упустил из виду предыдущий.


Выносить в отдельный пакет такие интерфейсы можно. Но так обычно не делают, не потому, что "не go-way", а потому, что просто не нужно:


  • Одна из основных причин вынести такие интерфейсы в отдельный пакет в том, чтобы можно было импортировать пакет с интерфейсами, не создавая при этом зависимости от пакета с реализацией. Но в Go, в большинстве случаев, пакет это часть модуля, а модуль это одно репо, и импортируя пакет мы получаем зависимость от всего модуля/репо. Соответственно, чтобы в этом подходе был реальный смысл, нам нужно целый отдельный репо завести под такой "общий интерфейс".
  • Чтобы имело смысл так заморачиваться, нужно чтобы импортировать этот пакет ради интерфейса было заметно проще, чем набрать этот интерфейс ручками по месту использования. А это подразумевает, что интерфейс этот — большой и сложный. Что таки уже начинает противоречить go-way, если пользователь реально использует только подмножество этого интерфейса, как чаще всего и бывает.
Самый популярный неправильный ответ: «Встроенный в Goland». Come on!, там нет линтера, там — тривиальный syntax checker!

Вот сейчас обидно было...

возможно, я слегка приуменьшил :)

то, что находит goland, полезно и важно.

но и половину не перекрывает того, что находит правильно настроенный golangci-lint

в первую очередь потому, что goland должен быть быстрым

И да, и нет. Большинство проверок в линтерах достаточно просты, и при правильной реализации на производительность не влияют. В то же время, мы никогда не ставили своей целью перетащить к себе все. Обычно мы стараемся добавлять наиболее полезные инспекции, к которым можно сделать квикфиксы. И мы всегда рады фидбеку, чего именно не хватает ;) В любом случае, наличие control flow, data flow и nilness анализаторов позволяется мне не согласится с утверждением про "тривиальный syntax checker".

мне, кстати, не хватает моего github.com/Djarvur/go-err113

а про «тривиальный чекер» — это я в полемическом запале, да :)

хотите — дам где-нибудь опровержение?

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

Улучшить работу с ошибками есть у нас в планах (GO-8317). Обязательно сделаем, непонятно только, когда.

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

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

НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь

Лакмусовая бумажка, позволяющая убедиться, что это две несвязанные структуры: если мы выкидываем саму хеш-таблицу (массив корзин), то все наши элементы по-прежнему доступны, можно их добавлять/удалять/итерировать через те самые "две ссылки"; если мы выкидываем эти "две ссылки", то мы имеем ту же картину, все элементы доступны, можно их добавлять/удалять/итерировать (только уже в неопределённом порядке).

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
пока есть острый дефицит кадров в нашем регионе эти кадры будут загибать пальцы со словами «а зачем мне это надо, я и так синьёр», а в сша у них кроме этого списка ещё и алгоритмы спросят, как результат “Синьёр Вася” становится куда более простым в общении и ещё любознательным, те 4-6 месяцев пока он будет закрывать пробелы в знаниях, получая везде отказы.
Вообще наш человек так воспитывается со школы: включай смекалку, учись списывать, не забивай лишним голову. В школе ещё полностью учатся профильные предметы, т.к. по ним будет конкуренция при поступление в вуз, но в вузе можно уже на всё забить кроме программухи, ведь оценки у нас никто не смотрит нигде. На западе ситуация иная, там не понимают когда человек списывает, учит только то, что ему сейчас нравится и диплом в котором 90% троек на руки не дают. В итоге имеем то, что имеем, самых смекалистых синьёр стекоферфлоу девелоперов, которые с удовольствием поучатся азам за счёт заказчика при необходимости, необходимость эта конечно может растянутся на многие месяцы переделок. Мне бы на месте заказчика такое конечно не очень то и нравилось.

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

Есть вопрос по поводу пункту 14, а именно Fatal ошибки. Под fatal подразумевается deadlock, out of memory , out of index и тд или просто серьезные ошибки, после которых надо закончить функцию/горутину?

Так как если это именно fatal ошибка (например deadlock), то как вообще можно делать какой-то дополнительный детализированный вывод помимо стандартного?

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

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

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

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

По сути собеседование я уже давно воспринимаю как экзамен. И да - я сама с ходу не пройду собес. Обычно 1-3 собеса идут как тестовые, чтобы понять что сейчас в тренде по вопросам.

НЛО прилетело и опубликовало эту надпись здесь

Конструкция switch во всех языках примерно одинаково выглядит.

Но собеседование это не экзамен!

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

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

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


А когда в языке есть одновременно switch expression и switch statement с разными синтаксисами — то и вовсе забыть одно из них совершенно нормально.

А если человек привык пользоваться if/else if/else, а не switch?

Я и такое встречала. 5 или 6 if/else подряд. Согласитесь это слишком.

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

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

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

Не согласимся, 5 или 6 if/else подряд проще понятнее и безопаснее.

if s == "test1" {
  //.....
}
if s == "test2" {
  //.....
}
...
if s == "test10" {
  //.....
}

Не думаю, что такая конструкция выглядит более читаемой, чем switch

замените if s == на case и что-то сильно поменяется в читаемости кода?

Ещё и работать не будет без break после каждого case.

В Go, break не нужно

Офигенный вопрос кстати. Прямо к опроснику выше. И ведь на него есть ответ. Ответите?

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

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

в этом смысле этот опросник не очень хорош (я в нем разочаровался за эти годы :) )

но никаких подходов лучше я пока не придумал

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

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

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

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

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

НЛО прилетело и опубликовало эту надпись здесь

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

В этом месяце у меня было наверное одно из лучших технических интервью - на позицию Senior/Техлид примерно.

Сколько было технических вопросов? - 0.

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

рад за вас

Раз уж этот пост внезапно всплыл через несколько лет, то

Каков порядок перебора map? Самый популярный неправильный ответ: «В порядке вставки». Хеш-таблица, которая сортирует элементы в порядке вставки, ага.

Ага, а вот в JavaScript именно так: есть map, который

  • как минимум в одной из реализаций (V8), когда я последний раз туда смотрел, реализован на hash-таблице,

  • и перебирается в порядке вставки т.к. спецификация явно этого требует: https://262.ecma-international.org/6.0/#sec-map.prototype.foreach "Map.prototype.forEach ... Repeat for each Record ... in original key insertion order"

Описание алгоритма реализации такого hashmap: https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables

как мы понимаем - это не map, а более сложная структура данных, которая включает в себя собственно map и linked list

"Собственно map" уже включает в себя какое-то количество (по числу бакетов) linked list или вообще деревьев, как в https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/HashMap.java

Конечно, сложность - субъективная оценка, и формально добавление одного linked list - это усложнение структуры, но IMHO в конкретно этом контексте нет смысла писать "это более сложная структура данных, там ведь ещё и linked list".

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

вот что лишь для джунов - это правда

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

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

Обычно это значит что интервьюер мудак.

конечно, кто же еще...

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

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

Звучит (в купе с содержимым и размером опросника), как поиск человека не на конкретные проекты, а в так называемый "Офис языка GO" по аналогии с "Проектным офисом", который не реализует конкретные проекты, а следит за корректностью и (возможно?) эффективностью применения практик управления проектами.

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

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

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

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

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

серьёзно? вы думаете, что для ответов на элементарные вопросы нужна эйдетическая память? просто понять, как и что устроено в go - не для вас?

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

Программировать на нём всерьёз сложно, потому что ну как можно сделать недо-С с сборщиком мусора и продвигать это как современное решение всех проблем?

О да, Пайк, Керниган и Ритчи известны своим подходом "абы как" к продуктам. И языкам в частности :) Ну хоть немного за речью-то следите :)

Аппеляция к авторитетам, которые к тому же неособо причастны к созданию этого языка. Которым всем по 90 лет и всё что они делали это что-то связанное с unix на С и собственно сам язык С, как же у них мог выйти полу-С с сборщиком мусора...

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

средний балл по опроснику — 3.3 по шкале 0-9

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

Есть ещё один момент. Я некоторое время наблюдаю оду анскилу (раз, два, дальше лень, но такого навалом). Статьи об этой тенденции я ещё не видел

Короче, дальше лучше не будет. Может, пора писать статьи "Как выйти из айти"?

софскилы нам тоже нужны

Тенденция идёт к замещению хард скилов так называемыми "софт скилами" -- а рынок за это активно топит

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

Можно своё мнение прибавить, как взгляд с соседней колокольни? По ходу работы постоянно сталкиваюсь с разработчиками и с результатами их труда. Это основная часть моей работы. Сам себя разработчиком не считаю, хотя постоянно пишу тот или иной код (HCL, CI/CD, скрипты автоматизации), изучаю техническую литературу, которая иногда заходит в область разработки. Каюсь, периодически пишу на Go. Этим всего лишь хочу сказать, что совсем не далёк от темы разработки и подробностями, связанными с этим.

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

Go — императивный или декларативный?

Не поверите, многие уверены что функциональный

Что будет, если читать из закрытого канала?

Что будет, если писать в закрытый канал?

У нас проект пока в стадии разработки, поэтому пока не до каналов и что с этим связано. Если надо, будем потом необходимое внедрять (с)

Главный недостаток стандартного логгера?

Стандартный логгер для некоторых был открытием

Есть ли для Go хороший orm?

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

Какой у вас любимый линтер?

С большим трудом своей командой протолкнули линтер в CI. Но жить ему там похоже не долго

Способы поиска проблем производительности на проде?

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

Стандартный набор метрик prometheus в Go -программе?

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

Какие технологические преимущества языка Go вы можете назвать?
Наводящие вопросы: чем отличается goroutine от OS thread?

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

Какие технологические недостатки языка Go вы можете назвать?

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

ну вот да :(

и такое - прям сплошняком

АААААААААААААААААААААААААААААААААААА

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