Это вопрос, который мне задали на собеседовании, и я не могу найти ответ, который они искали, поэтому я надеюсь, что у кого-то здесь могут быть какие-то идеи. Цель состоит в том, чтобы написать функцию, которая никогда не будет возвращать одно и то же значение дважды. Предположим, что эта функция будет доступна нескольким машинам одновременно.
Моя идея состояла в том, чтобы назначить каждой машине уникальный идентификатор и передать это значение в функцию генератора уникальных значений:
var i = 0;
function uniq(process_id, machine_id) {
return (i += 1).toString() + machine_id + "-" + process_id;
}
Это позволит избежать последствий от условий гонки, поскольку даже если два или более процессов считывают одно и то же значение i
, каждое возвращаемое значение помечается уникальной комбинацией идентификатора процесса и идентификатора компьютера. Однако моему интервьюеру не понравился этот ответ, потому что подключение другой машины к сети подразумевает присвоение ей идентификатора.
Так кто-нибудь может придумать другой способ решить эту проблему, который не включает в себя настройку каждой машины, чтобы иметь уникальный идентификатор? Я хотел бы получить ответ, если этот вопрос возникнет снова. Спасибо.
источник
Ответы:
Не думайте, просто бросьте простой (потокобезопасный) счетчик за какой-то конечной точкой связи (WCF, веб-сервис, что угодно):
Да, это в конечном итоге переполнится. Да, он не обрабатывает перезагрузки. Да, это не случайно. Да, кто-то может запустить это на нескольких серверах.
Это самая простая вещь, которая удовлетворяет практическим требованиям. Затем пусть они будут теми, кто следит за этими проблемами (чтобы убедиться, что они понимают ограничения, действительно ли они думают, что вам нужно больше 2 ^ 64 идентификаторов), чтобы вы могли тогда спросить о том, какие компромиссы в порядке. Нужно ли пережить перезагрузки? Как насчет сбоя жесткого диска? А как насчет ядерной войны? Это должно быть случайным? Как случайно?
источник
x
. И я думаю, что без объяснения того, какой механизм блокировки вы имеете в виду, этот ответ довольно расплывчатый.System.Threading.Interlocked
класс, который обеспечивает атомарные приращения. Но вы также можете прочитать это как некий псевдокод.Если бы мне задали этот вопрос, и они дали понять, что он должен быть уникальным при перезагрузке и на разных машинах, я бы дал им функцию, которая вызывает стандартный механизм для создания нового GUID, независимо от того, что происходит в используемый язык.
источник
Интервьюер сказал, что метод будет вызываться одновременно, а не параллельно; просто верните дату / время на столько знаков после запятой, сколько сможете.
Почему все думают над этим? Вы будете мертвы долгое время, прежде чем любая конечность будет израсходована, и у вас нет шансов на столкновение.
Если вы беспокоитесь о возврате в одно и то же время, добавьте задержку для наименьшего количества измеримого времени.
Если вас беспокоит перевод часов на летнее время (1 раз в два раза), добавьте константу ко времени во второй раз.
источник
Во-первых, вы захотите задать интервьюеру два вопроса.
Вопрос 1.
ожидает ли интервьюер одной или нескольких «центральных машин», которые будут использоваться для присвоения некоторых уникальных номеров или блоков уникальных номеров.
Вопрос 2.
Если интервьюер ожидает механизм обнаружения столкновений, или вместо того, чтобы принять вычисленную риск крошечного шанса столкновения без явных их обнаружения.
Существует также подход глубокоэшелонированной защиты, при котором в случайность включается некоторая часть идентификатора пользователя (таким образом, не полностью случайная). Поэтому вероятность того, что один и тот же пользователь столкнется с конфликтом внутри контента, созданного этим же пользователем, уменьшается.
Есть неявный вопрос 3, ...
Но это тот, который вы должны оценить сами, не спрашивая, потому что очень невежливо спрашивать вашего интервьюера.
Предполагает ли интервьюер знание вероятности, риска и некоторых простых методов, используемых в криптографических системах и системах защиты информации.
Первый тип знаний гарантирует, что вы не пытаетесь убедить не научного человека принять научную концепцию, которую он не примет.
Второй вид знаний гарантирует, что вы решаете проблемы, которые являются дополнением к простой вероятности. Другими словами, как защититься от «злоумышленников», которые хотят преднамеренно нарушить вашу схему рандомизации, манипулируя машинами или их виртуальными хостами, чтобы заставить две машины генерировать одинаковое значение.
Зачем спрашивать.
Причина в том, что, если интервьюер ожидает, что так или иначе, попытка ответить с противоположным подходом никогда не сделает интервьюера счастливым.
Более глубокая причина заключается в том, что некоторым людям не нравится идея сказать,
1.0e-20
шанс потерпеть неудачу. (Я постараюсь не вызывать здесь философских или религиозных аргументов.)Прежде всего «пространство имен» случайных чисел превращается в иерархию, в которой определенное количество битов выделено одному источнику рандомизации, а другое число битов выделено некоторым другим путям и т. Д.
Централизованный подход опирается на некоторые центральные полномочия для уникального назначения первого уровня битов. Затем другие машины могут заполнить оставшиеся биты.
Есть несколько децентрализованных подходов:
источник
Итак, учитывая, что это вопрос интервью, а не реальный сценарий из реальной жизни, я считаю, что правильный подход (и, вероятно, то, что ищет интервьюер) состоит в том, чтобы задать уточняющий вопрос или написать «Это не может быть сделано "и двигаться дальше. Вот почему
Что спрашивает интервьюер:
Что нужно интервьюеру:
Никогда не принимай.
Когда инженеру вручают требование (через SOW или Спецификацию или какой-либо другой документ с требованиями), некоторые из них самоочевидны, а другие совершенно неясны. Это прекрасный пример последнего. Как показали предыдущие ответы, невозможно ответить на это требование, не сделав несколько основных предположений либо (а) относительно характера вопроса, либо (б) относительно характера системы, поскольку требование не может быть выполнено как написано (это невозможно).
Большинство ответов делают одну или другую попытку решить проблему с помощью ряда предположений. В частности, рекомендуется просто сделать это быстро и позволить клиенту беспокоиться об этом, если это не так.
Это действительно плохой подход. Как клиент, если я задаю неясное требование, а инженер уходит и создает мне решение, которое не работает, я буду расстроен, что они пошли на работу и потратили мои деньги, не потрудившись спросить меня в первую очередь. Такой тип кавалерийского принятия решений демонстрирует отсутствие командной работы, неспособность критически мыслить и плохое суждение. Это может привести к любым негативным последствиям, включая гибель людей в критической системе безопасности.
Зачем задавать вопрос?
Дело в том, что это упражнение является дорогостоящим и трудоемким, чтобы построить с неоднозначными требованиями. В случае с ОП вам дали невыполнимую задачу. Ваше первое действие должно заключаться в том, чтобы попросить разъяснений - что требуется? Какая степень уникальности нужна? Что происходит, если значение не является уникальным? Ответом на эти вопросы может быть разница между несколькими неделями и несколькими минутами. В реальном мире одним из главных факторов, определяющих стоимость сложных систем (включая многие программные системы), являются неясные и плохо понятые требования. Это приводит к дорогостоящим и трудоемким ошибкам, перепроектированию, разочарованию клиентов и команды, а также затрудняет освещение в СМИ, если проект достаточно большой.
Что происходит, когда вы предполагаете?
Учитывая мой опыт работы в аэрокосмической отрасли, а также из-за очень заметного характера неудач в аэрокосмической отрасли, я хотел бы привести примеры из этой области, чтобы проиллюстрировать важные моменты. Давайте рассмотрим пару неудачных миссий на Марс - орбитальный аппарат на Марс и Полярный Марс. Обе миссии провалились из-за проблем с программным обеспечением - потому что инженеры сделали неверные предположения, отчасти из-за неясных и плохо сообщенных требований.
Mars Climate Orbiter - этот случай обычно упоминается как случай, когда НАСА пытается преобразовать английский в метрические единицы. Однако это слишком упрощенное и плохое представление о том, что действительно произошло. Правда, была проблема преобразования, но это было связано с плохо сообщенными требованиями на этапе проектирования и неправильной схемой верификации / валидации. Кроме того, когда два разных инженера заметили проблему, потому что это было очевидно из данных траектории полета, они не подняли проблему до надлежащего уровня, потому что они предположили, что это была ошибка передачи. Если бы оперативная группа миссии была проинформирована об этой проблеме, было бы достаточно времени, чтобы исправить ее и сохранить миссию. В этом случае существовало невозможное логическое условие, которое не было признано таким, каким оно было, что приводило к дорогостоящему провалу миссии.
Марс Полярный Ландер- этот случай немного менее известен, но, возможно, более смущает из-за его временной близости к отказу Марс-климатического орбитального аппарата. В этой миссии программное обеспечение контролировало спуск ракеты с помощью двигателя на поверхность Марса. В точке 40 метров над поверхностью ноги посадочного аппарата развернуты в процессе подготовки к приземлению. Был также датчик на ногах, который обнаружил движение (чтобы сигнализировать, когда они пострадали), чтобы сказать программное обеспечение, чтобы выключить двигатель. Наилучшим предположением НАСА относительно того, что произошло (поскольку существует множество возможных отказов и неполных данных), является то, что случайные вибрации в опорах из-за их одновременного развертывания и неправильного запуска механизма отключения на 40 м над поверхностью приводят к аварии и разрушению 110 долл. США. М космический корабль. Эта возможность была поднята в разработке, но никогда не был адресован. В конечном счете, команда разработчиков сделала неверные предположения о том, как должен выполняться этот код (одно из таких предположений состоит в том, что ложный сигнал будет слишком коротким, чтобы его можно было принять, несмотря на тесты, показывающие обратное), и эти предположения никогда не подвергались сомнению до тех пор, пока факт.
Дополнительные соображения
Интервью и оценка людей - сложное дело. Есть несколько аспектов кандидата, которые интервьюер может захотеть изучить, но одним из наиболее важных является способность человека мыслить критически. По ряду причин, не в последнюю очередь из-за того, что критическое мышление плохо определено, нам очень трудно оценивать навыки критического мышления.
Как инженер-инструктор, один из моих любимых способов оценить способность студента мыслить критически - это задать несколько двусмысленный вопрос. Более проницательные ученики могли понять ошибочную предпосылку вопроса, отметить это и либо ответить, исходя из предпосылки, либо отказаться от ответа вообще. Как правило, я бы задал вопрос, подобный следующему:
(Кстати, вы были бы шокированы тем, как часто на рабочем месте появляются такие плохие спецификации.)
Я ожидаю, что студенты поймут, что невозможно создать идеальную функцию, и что они заявят об этом в своем ответе. Я обычно получаю бонусное очко, если они говорят, что вернутся к дизайнеру и попросят разъяснений, прежде чем делать деталь. Если студент продолжит рассказывать мне, как он собирается достичь планетарности 0,001 или какой-то другой выдуманной ценности, я начисляю ноль баллов. Это помогает мне подчеркнуть, что мои студенты должны думать о более широкой картине.
Нижняя граница
Если я беру интервью у инженера (или схожей профессии), я ищу человека, который может критически мыслить и задавать вопросы о том, что было перед ним. Я хочу кого-то, кто задает вопрос "Имеет ли это смысл?" ,
Нет смысла просить идеально ровную деталь, потому что идеальной вещи не существует. Нет смысла просить функцию, которая никогда не возвращает дублирующее значение, потому что невозможно дать такую гарантию. В программировании мы часто слышим фразу «мусор входит, мусор выходит». Если вам вручают мусор для требований, ваша этическая ответственность - остановиться и задать любой вопрос, который поможет вам выявить истинное намерение. Если я беру интервью у кандидата и задаю ему неясное требование, я буду ожидать уточняющих вопросов.
источник
Гарантировать уникальность сложно, потому что у компьютеров нет бесконечно больших переменных. Никакая реальная машина Тьюринга не может.
На мой взгляд, здесь есть две проблемы, и у обеих есть устоявшиеся решения.
Вот мое решение на Java:
BigInteger - целочисленный тип произвольного размера. Он может расти, чтобы содержать значения, которые являются довольно большими, даже если не бесконечными. Блокировка обеспечивает параллелизм, поэтому одно и то же значение не может быть возвращено дважды двумя одновременными запросами, обслуживаемыми отдельными потоками.
источник
Я бы выставил функцию через порт на сервере; для вызова функции запрашивающая машина запрашивает соединение и получает его, в то же время выделяя идентификационный код (для простоты порядковый номер). Всякий раз, когда на порт отправляется сообщение с запросом уникального значения, это значение генерируется путем объединения хэша MD5 текущей даты и времени с хешем MD5 идентифицирующего кода.
Если им нужно более пуленепробиваемое решение, они должны будут указать свои реальные требования, а не быть расплывчатыми.
источник
Вышеописанным способом мы можем убедиться, что возвращаемое значение отличается, даже если есть перезапуск или даже если вызов вызван одновременно с разных машин.
источник