LINUX.ORG.RU
ФорумTalks

Фрустрация от собеседования в «Яндекс»

 , ,


1

9

Здравствуйте. Некоторое время назад я собеседовался в «Яндекс». Хочу поделиться здесь моими впечатлениями от собеседования и историей неуспеха.

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

Итак, был дан код класса на C++: это контейнер, как std::vector, который должен уметь возвращать случайный объект согласно весам, которые передаются как float.

Код был написан с использованием функции rand() и содержал одну очевидную ошибку, которую я нашёл, и ещё одну неочевидную, связанную с возможной проблемой при округлении с арифметикой над float, которую я тоже нашёл. Я сказал, что rand() непотокобезопасна; её реализация, как правило, низкого качества; RAND_MAX зависит от платформы; получить честный рандом при заранее неизвестном RAND_MAX сложно; и т.д. Сказал, что в C++11 есть <random>. Интервьювер сказал, что <random> слишком громоздко для собеседования, давайте уж использовать rand().

Что-то там написали, пришло время писать тесты. Написали какой-то тест, который 1000 раз генерирует случайные объекты №1 и №2 с весами 1 и 2 и проверяет, что объектов №2 получилось больше. Далее по ролям: я (Я), интервьювер (И).

И: — Да, только тест недетерминированный, как его сделать детерминированным?

Я: — Можно зафиксировать seed. Если бы мы использовали <random>, там у engine есть метод seed(), а тут…

И: — Есть специальная функция srand()!

Я: — Да, только она зависит от платформы, как и rand().

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

<примечание>

То есть речь идёт о том, чтобы превратить метод

    T getRandomElement() const { … }
в
    T getRandomElement(int (*custom_rand)()) const { … }
И передавать туда либо настоящий rand, либо свою детерминированнуюю реализацию. Даже без void *userdata, насколько я понял — то есть то ли состояние должно храниться в глобальной переменной, либо оно должно возвращать константу. Да, это C++, не в Си. Указатель на функцию, не лямбду.

</примечание>

Я: — Ну можно, но это какой-то мегакостыль, да и зачем уродовать интерфейс для этого…

И: — Ну хорошо, у нас осталось не так много времени, давайте не будем это писать.

---

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

Я, конечно, знал, что крупные компании очень привиредливые, но это вообще что такое? Какой извращенец пройдёт это интервью?

Эту тему я создаю в том числе для того, чтобы давать на неё ссылку HR из яндекса, если таковые ко мне ещё когда-либо постучатся.



Последнее исправление: shdown (всего исправлений: 5)

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

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

Но вообще, я бы не стал мучить кодом, а выяснил бы понимание именно словами. Тем более это проблема уровня «проверил, увидел что не повторяется входная последовательность, добился чтобы повторялась» и делов то

I-Love-Microsoft ★★★★★
()

Побуду, так сказать, адвокатом дьявола

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

Я: — Ну можно, но это какой-то мегакостыль, да и зачем уродовать интерфейс для этого

Я правильно понял, что

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

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

а потом удивились, почему вам сначала назначили грейд middle-, и позже, скорее всего после ваших возмущений, вообще влепили вам во внутреннее досье no hire?

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

Самое забавное, что потом вы прибежали на ЛОР создавать тему чтобы «давать на неё ссылку HR из яндекса» или, если по русский: «я три дня гналась за вами, чтобы сказать, как вы мне безразличны», полностью подтверждая причину, почему не связываться с вами с точки зрения компании/крупного коллектива было правильной идеей.

summon
()
Ответ на: комментарий от summon

вы так и не предоставили ни решения

А «зафиксировать seed» — не решение? Из «Если бы мы использовали <random>, там у engine есть метод seed()» можно вывести, что я бы предложил использовать шаблонный аргумент.

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

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

стандартный пример реализации зависимости компонент системы через DI

Да-да, указатель на функцию в C++ (ещё и без void *userdata) — это стандартный пример. Который передаётся в метод, а не в конструктор класса.

мегакостылем, уродующим интерфейс

Это и есть мегакостыль, уродующий интерфейс. Это не очевидно? Почему использующий должен писать x.getRandomElement(::rand) вместо x.getRandomElement()? Ещё и импортировать rand из <cstdlib>…

Вы, как и no-such-file, считаете, что в программировании не нужно душнить и вдаваться в частности? И что вы лучше меня знаете, что было на собеседовании и после него («скорее всего после ваших возмущений»)?

Надеюсь, вы не так бездарно сольётесь, как он.

shdown
() автор топика
Последнее исправление: shdown (всего исправлений: 2)
Ответ на: комментарий от shdown

А «зафиксировать seed» — не решение?

Вы же сами на собеседовании сказали «она зависит от платформы, как и rand()», а значит, как вы сами сказали, не решение.

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

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

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

Да-да, указатель на функцию в C++ (ещё и без void *userdata) — это стандартный пример. Который передаётся в метод, а не в конструктор класса.

Это не зависит от языка - передача функции в функцию для разделения на независимые компоненты - это базовый прием существующий со времен машинного кода / ассемблера, активно используемый везде, и в C, и в высокоуровневых ЯП, в том числе и в С++, в том числе и в публичных API - попадая как частный простейший случай в паттерн под обобщенным названием: Dependency Injection.

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

«мегакостыль, уродующий интерфейс» - это очень субъективная оценка - не находите?

А разработка ПО - достаточно объективная область.

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

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

или, хотя бы, предложить совместить два варианта в одном API:

T getRandomElement() { return getWeightedElement(::rand); }

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

Вдаваться «в частности» можно и нужно, вопрос лишь в том, что такое эти «частности» и насколько они важны с точки зрения бизнеса. Тот факт что вы указали на то, что rand и srand не детерминированы между платформами - это объективная и, возможно, важная частность.

А вот, что такой интерфейс - это костыль, до тех пор пока нет объективных причин - не частность, а просто личное предпочтение.

===

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

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

  • Решение вопроса (которое объективно решало проблему), предложенное интервьером было вами, судя по написанному, в достаточно неконструктивной форме отвергнуто по исключительно субъективным соображениям.

что привело к тому, что

  • Вопрос не был решен

А если бы не ваше чувство прекрасного, то

  • Вопрос был бы решен

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

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

вы лучше меня знаете, что было на собеседовании

Я лишь могу оперировать тем, что вы написали и подметить, что по выше-описанному у вас был пробел, граничащий с no-hire в подходе к решению задач, что демонстрируется объективным результатом: есть кандидаты, которые решает проблему из вопроса, есть кандидаты, которые не решают, а есть которые не решают и за одно скажут вам, что и вы «не так» решили. Вы, видимо, попали в третью категорию.

summon
()
Ответ на: комментарий от summon

А «зафиксировать seed» — не решение?

Вы же сами на собеседовании сказали «она зависит от платформы, как и rand()», а значит, как вы сами сказали, не решение.

Вы то ли не понимаете, о чём идёт речь, то ли сознательно игнорируете то, что я пишу. А скорее всего, вы просто не знаете, что есть в <random> и как оно устроено.

Я сказал: «Если бы мы использовали <random>, там у engine есть метод seed()». Это означает, что я предложил использовать шаблонный аргумент.

Это не зависит от языка - передача функции в функцию для разделения на независимые компоненты - это базовый прием существующий со времен машинного кода / ассемблера, активно используемый везде, и в C, и в высокоуровневых ЯП, в том числе и в С++, в том числе и в публичных API - попадая как частный простейший случай в паттерн под обобщенным названием: Dependency Injection.

С вашим знанием языка всё понятно. Это в Python идиоматично передавать функцию, а в C++ это делается с помощью policy-based design на шаблонах. Смотрите, коли уж не знаете: http://en.wikipedia.org/wiki/Modern_C++_Design#Simple_example

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

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

<например просто передать невзвешеный индекс, вместо функции>

Я не могу полностью понять, что вы имеете в виду. Можете ли объяснить или привести пример кода? Или вы как no-such-file — нагадил и убежал, попутно вопя «лол, ты ничего не знаешь, неуч»?

---

Что вы там ещё резонёрствуете, я не понимаю и ответить по существу на шизофазию вашу не могу.

shdown
() автор топика
Последнее исправление: shdown (всего исправлений: 4)
Ответ на: комментарий от shdown

И, самое интересное: если я не знаю, что указатели на функции можно использовать для абстракции, как же я 10 лет назад написал luastatus?

P.S.

а в C++ это делается с помощью policy-based design на шаблонах

Ну или по крайней мере с помощью std::function, но это медленнее.

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

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

shdown
() автор топика
Последнее исправление: shdown (всего исправлений: 2)
Ответ на: комментарий от shdown

Отвечу кратко:

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

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

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

Или, говоря одним предложением: интервьюер вам про Фому, а вы ему про Ерему в грубой форме.

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

summon
()
Ответ на: комментарий от summon

Интервьюер […] вас спрашивал

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

а именно «указатель на функцию» именно в C++ это не тоже самое, что, скажем, std::function

Уважаемый, я вообще добавить шаблонный параметр к классу предложил, а не std::function. Вы вообще читали код по моей ссылке на википедию выше?

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

Передавать шаблонным параметром Г(П)СЧ в класс; потом, для тестов, использовать ГПСЧ из <random>; и предварительно зафиксировать его seed — для вас не ответ и не решение исходной задачи? Или вы вообще не понимаете половину слов в предыдущем предложении?

демагогический конфликт

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

обсуждении терминологии

Ничего себе! Может быть, для вас шаблонный параметр vs передача в конструктор функции — это тоже вопрос терминологии?

Можно было сказать: «монада массив абстрактный метод TDD Флойд-Уоршелл ABI кубернетес регуляризация большие данные бинарный поиск» — и потом утверждать, что я всё правильно решил, ну может чуть-чуть неправильно сказал, но это только вопрос терминологии, если не душнить, то можно понять, о чём я?

shdown
() автор топика
Ответ на: комментарий от shdown

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

Лишь то, что вы сами сообщили

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

В моем предложении явно указано следующее «, скажем, std::function» поскольку это не важно какой именно способ реализации DI вы будете использовать. Вопрос задан о том, как сделать реализацию для того, что писать нормально тесты. Но забавы ради вот ваша цитата из поста «Указатель на функцию, не лямбду.» - что подтверждает насколько же буквально вы восприняли и стригерились на совершенно не важное определение того, что вам сказали. Так что мой пример вполне построен на том, что вы сами написали.

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

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

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

предварительно зафиксировать его seed — для вас не ответ и не решение исходной задачи

Не решение, поскольку даже если предположить, что это гарантирует детерминированность “на бумаге”, это не гарантирует детерминированность на человеческом уровне. Например, если у вас есть массив [4,5,6] и веса [1,2,3], какой будет ожидаемый результат вызова вашей функции с сидом генератора = 42?

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

говнокод калякать, а не думать, как вообще этот код может работать в продакшене

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

для вас шаблонный параметр vs передача в конструктор функции

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

Можно было сказать: «монада массив абстрактный метод TDD Флойд-Уоршелл ABI кубернетес регуляризация большие данные бинарный поиск»

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

summon
()
Ответ на: комментарий от summon

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

Вот здесь произошёл вброс ложной дихотомии.

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

CrX ★★★★★
()
Ответ на: комментарий от CrX

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

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

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

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

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

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

При этом, факт есть факт. Если человек что-то сказал и, например, 95% людей его поняли как надо, а 5% поняли не так, то проще рашать проблему 5ти процентов, чем 95 процентов.

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

summon
()
Последнее исправление: summon (всего исправлений: 1)
Ответ на: комментарий от summon

хочу лишь заметить, что такой иллюзии ни у кого нет.

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

При этом, факт есть факт. Если человек что-то сказал и, например, 95% людей его поняли как надо, а 5% поняли не так, то проще рашать проблему 5ти процентов, чем 95 процентов.

Это работает не совсем так. Проблема в том, что «так» и «не так» плохо определены. Если под «так» подразумевать «восприняли мысль абсолютно так же, как её думал автор», то там никаких 95% не будет, не будет и 50%, будут единицы. Но в подавляющем большинстве случаев (пусть будет в пресловутых 95% случаев) люди понимают «с точностью, достаточной для коммуникации».

И вот стоят ли те 5%, где недостаточно, того, чтобы всё переделывать — вопрос открытый. Потому что даже если из этих 5% всего 1% будет критическим непониманием в критически важном вопросе, все эти 95% могут оказаться неважны. Вопрос соотношения рисков — не только в вероятности, но и в критичности ошибки. Одно дело иметь 5% шанс покрасить стены не в тот оттенок цвета, который ожидался, совсем другое, когда во время операции человеку с вероятностью 5% удалили чуть больше или чуть меньше, чем надо, и совсем-совсем другое, если в итоге с вероятностью 5% начнётся война двух сверхдержав.

Например, если вам говорят «разрежь торт на 4 части» вы скорее всего разрежете примерно на 4 равные части, хотя человек и не сказал вам, что он хотел именно равные части.

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

Более того, просьбы вида «разрежь торт на 4 части» практически не встречаются в реальной жизни. В реальной ситуации скорее скажут «нарежь на четверых». А это уже немного другой смысл, подразумевающий не просто формальные математические 4 части, а именно что это на четверых человек, что в свою очередь заставляет человека выполнять задание не формально, а именно додумывать недосказанное, или переспросить, если не очевидно. Да, по умолчанию человек поймёт «на четверых» как на четверых равных по правам и статусу людей, потому что люди однозначно подразумеваются в задании (а не математически абстрактные 4 части), а равноправие участников по умолчанию заложено в нашу (по крайней мере европейскую, а не уверен на 100%, что азиат или индеец порежет поровну) культуру.


P.S. Хуже всего даже не то, когда люди не так понимают, или из-за лени не так формулируют, а когда люди в принципе не способны сформулировать свои мысли, даже когда их настойчиво просят, и с десятой попытки. К сожалению, это встречается всё чаще. И с пресуппозицией «пойму ка я это как что-то нечёткое, и будь, что будет» в таких случаях будет тяжко: один не может сказать, другой понять. Результат будет скорее всего не «хз», а катастрофой рано или поздно.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 2)
Ответ на: комментарий от summon

Лишь то, что вы сами сообщили

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

Не решение, поскольку даже если предположить, что это гарантирует детерминированность “на бумаге”, это не гарантирует детерминированность на человеческом уровне. Например, если у вас есть массив [4,5,6] и веса [1,2,3], какой будет ожидаемый результат вызова вашей функции с сидом генератора = 42?

Уважаемый, я же говорю, вы даже не понимаете того, что такое «шаблон». И вообще в C++ — ни в зуб ногой.

#include <vector>
#include <iostream>
#include <cstdint>

template<class T, class G>
class MyContainer
{
    std::vector<T> values_;
    G g_;

public:
    MyContainer(G g = G())
        : g_{std::move(g)}
    {}

    void add(T x)
    {
        values_.push_back(x);
    }

    T get_random_element()
    {
        return values_[g_() % values_.size()];
    }
};

class MockRNG
{
    std::vector<int> seq_;
    std::uint64_t i_;

public:
    MockRNG(std::vector<int> seq)
        : seq_{std::move(seq)}
        , i_{0}
    {}

    int operator ()()
    {
        return seq_[i_++ % seq_.size()];
    }
};

int main()
{
    MockRNG g{{3, 4, 7, 8}};
    MyContainer<double, MockRNG> c(g);
    c.add(1.5);
    c.add(2.5);
    c.add(3.5);
    // [3, 4, 7, 8] % 3 = [0, 1, 1, 2]
    // Result cycles between: [1.5, 2.5, 2.5, 3.5]
    for (int i = 0; i < 10; ++i) {
        std::cout << c.get_random_element() << std::endl;
    }
}

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

Ага, но только если этот продакшен не использует многопоточность :)

И дело нпроисходит не в обработчике сигнала.

shdown
() автор топика
Ответ на: комментарий от shdown

Передавать шаблонным параметром Г(П)СЧ в класс; потом, для тестов, использовать ГПСЧ из ; и предварительно зафиксировать его seed — для вас не ответ и не решение исходной задачи?

Не решение, поскольку даже если предположить, что это гарантирует детерминированность “на бумаге”, это не гарантирует детерминированность на человеческом уровне. Например, если у вас есть массив [4,5,6] и веса [1,2,3], какой будет ожидаемый результат вызова вашей функции с сидом генератора = 42?

Уважаемый, я же говорю, вы даже не понимаете того, что такое «шаблон». И вообще в C++ — ни в зуб ногой.

Смотрите, никто нигде не утверждал, что нельзя сделать изоляцию компонент через шаблон на С++ и поле класса, я лично утверждал выше, что можно сделать как угодно и все будет работать. Например, Можно даже это сделать не через поле, а через аргумент и шаблон. Можно сделать через указатель на функцию и аргумент, можно сделать чрез std::function и аргумент, можно сделать через указатель на функцию и поле класса, можно сделать через std function и поле класса, можно сделать через аргумент и интерфейс, можно сделать через поле класса и интерфейс, можно сделать через функтор и поле класса, можно сделать через функтор и аргумент и я могу продолжать - это все без разницы. А можно вообще индекс просить как аргумент и сказать, чтобы пользователь апи сам генерировал случайное число.

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

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

Ага, но только если этот продакшен не использует многопоточность :)

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

summon
()
Ответ на: комментарий от summon

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

Ну продемонстрируйте, как можно сделать с помощью указателя на функцию.

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

А до этого вы писали «у вас был пробел». Как это понимать?

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

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

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

shdown
() автор топика
Ответ на: комментарий от shdown

А до этого вы писали «у вас был пробел». Как это понимать?

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

морочить своей шизофазией.

Единственный, бессвязный набор слов я видел только от вас: « монада массив абстрактный метод TDD Флойд-Уоршелл ABI кубернетес регуляризация большие данные бинарный поиск»

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

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

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

Ну продемонстрируйте, как можно сделать с помощью указателя на функцию.

Это - это что? Замокать данные для теста?

summon
()
Ответ на: комментарий от summon

Но интересно, как вы доказывали про то, что фиксирование сида - это полное решение

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

Как вообще можно зафиксировать seed у чего-либо из <random> без шаблонного параметра? Это же не srand(), который сразу глобальное состояние меняет и все последующие вызовы rand() будут выдавать что-то другое. Там нельзя для всех следующих экземпляров что-то поменять, только для одного конкретного.

Вы явно не разбираетесь в теме.

Не это ли пример расстройства личности?

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

Жду от вас лекции

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

У «объектов, их методов и шаблонов» таких проблем нет.

Сойдёт за лекцию?

было ли ваше исходное решение (даже до попытки абстрагировать генератор от реализации) потокобезопасным?

Если мы под «потокобезопасностью» имеем в виду «разные экземпляры класса можно использовать в разных потоках» (определение №1), то да, было. Если под этим мы понимаем «один и тот же экземпляр класса можно использовать в разных потоках» (определение №2) — нет, не было. Ну то есть std::vector соответствует определению №1, но не определению №2.

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

Это - это что? Замокать данные для теста?

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

shdown
() автор топика
Последнее исправление: shdown (всего исправлений: 3)
Ответ на: комментарий от shdown

фиксирование сида — это лишь одна деталь решения.

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

Все потому, что фиксировать сид - это определяющее ваше решение спецификация, а

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

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

фатальная ошибка

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

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

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

У «объектов, их методов и шаблонов» таких проблем нет.

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

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

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

Зачем вам мой код - что это изменит в вашем понимании? Позволит опять менять тему и переключать разговор с вас и вашей незрелости на меня? :)

summon
()
Последнее исправление: summon (всего исправлений: 1)
Ответ на: комментарий от summon

Все потому, что фиксировать сид - это определяющее ваше решение спецификация

Хорошо, допустим. Процитирую мой вопрос к вам в предыдущем сообщении: как вообще можно зафиксировать seed у чего-либо из <random> без шаблонного параметра? Это же не srand(), который сразу глобальное состояние меняет и все последующие вызовы rand() будут выдавать что-то другое. Там нельзя для всех следующих экземпляров что-то поменять, только для одного конкретного.

Если моё решение — не шаблонный параметр и не srand(), то в чём оно может заключаться и как работать, вообще, в теории?

Фатальной ошибкой было написать рандомный тест

Да-да, фатальной ошибкой было написать именно такой тест, который попросил написать интервьювер.

который неясно что проверяет

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

вместо написания нормальных тестов

А «нормальные» тесты в чём должны заключаться, по-вашему? И почему интервьювер попросил написать такой тест, а не нормальный?

А в отдельном абзаце спросил про расстройство личности

Ну хорошо. «Пример расстройства личности» — это, например, ПРЛ или НРЛ. А вы хотели сказать «симптом расстройства личности». Какого расстройства личности это, по-вашему, симптом? Как этот симптом правильно называется?

Не вижу причин на фундаментальном уровне запрещающих использовать в методах глобальный стейт

Там для этого нет необходимости, а в указателях на функцию — есть.

shdown
() автор топика
Последнее исправление: shdown (всего исправлений: 1)
Ответ на: комментарий от shdown

как вообще можно зафиксировать seed у чего-либо из без шаблонного параметра?

Да кто же вас знает? И интервьюер не знает. Может быть вы добавите seed как параметр в метод get random element и там каждый раз рандом выбранного вами движка инициализировать? :) Может вы создадите конкретный движок в конструкторе, а в конструктор передадите seed. Вариантов много, а самое главное, вас же явно попросили без судя по тому, что вы написали. :) Да и какая разница как это сделать, если ваше решение предполагало фиксировать Сид через библиотеку как решение проблемы, которую интервьюер попросил не использовать. :)

Да-да, фатальной ошибкой было написать именно такой тест, который попросил написать интервьювер.

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

А «нормальные» тесты в чём должны заключаться, по-вашему? И почему интервьювер попросил написать такой тест, а не нормальный?

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

Как этот симптом правильно называется?

Синдром школьника. :)

summon
()
Ответ на: комментарий от summon

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

Вы написали, что моя ошибка — в том, чтобы «написать рандомный тест, который неясно что проверяет […] вместо написания нормальных тестов».

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

Синдром школьника. :)

Показывайте описание симптома с таким названием в серьёзной литературе по психиатрии.

shdown
() автор топика
Последнее исправление: shdown (всего исправлений: 4)
Ответ на: комментарий от shdown

Всё-таки хочется понять их логику. Почему они требуют такие решения? Что? Зачем? Как?

Кто «они»? Нет никаких «они». В компаниях с толпами людей манагеры вдруг решают, что пора расширяться. Технарям из отдела спускают разнарядку, собеседовать поток. Чуваки выбирают того, кто особо ничем не занят и у кого есть желание этимм заниматься. Или кто сам вызывается. В любом случае, в подавляющем большинестве случаев, собеседующим оказывается чувак, который в техническом плане ниже среднего (иначе бы код пилил, ни на что не отвлекаясь), но с большим желанием поразвлечься на бедных дрожащих собеседуемых. Вот с одним из таких ты и спорил. Он заведомо в выигрышной позиции, так как его слово там закон, твое ничего не значит. Это, кстати, большой прокол все этой системы отбора, основанной на собеседованиях: самих собеседующих отбирают по принципу «кто согласится», а не по принципу «кто грамотен в проверке квалификации», ибо последнее-это отдельный особый навык, который нужно доверять людям с педагогическим образованием, а не рандомным прыщам из техотдела. ЗЫ отличием малых компаний от крупных: собеседующим чаще оказывается тимлид, который и просил HR-ов найти подмогу, поэтому заинтересованнный найти помощника, а не оторваться и поразвлекаться на собеседованиях.

slew
()
Ответ на: комментарий от slew

про крупные несколько «сложнее»:

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

скорее это(«неадекватность») собеседующего показатель степени серьёзности(речь не про зп для соискателя) найма - ибо очевидно что чем маржинальней индустрия по не зависящим от хардов причинам тем астрологичней будут практики

qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 2)
Ответ на: комментарий от slew

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

Чушь. Никогда такого не видел (в том числе и в Яндексе). Поскольку главному в команде хочется работать только с сильными и адекватными кадрами, то собеседование самому слабому никогда не доверяют. Всё с точностью до наоборот.

urxvt ★★★★★
()
Ответ на: комментарий от no-such-file

Это называется ананкастное расстройство личности.

А противоположность называется «гуманитарий, не могущий в формальные системы и точные науки». Как ты, например: спрашивали про упоминание конкретного симптома/синдрома в литературе, а ты какой-то диагноз называешь.

shdown
() автор топика
Последнее исправление: shdown (всего исправлений: 1)
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)