1. C# / Говнокод #20016

    0

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    foreach (var r in rezList)
    {
        int newId = rnd.Next();
        rez.Add(new FileItem()
        {
            Id = newId,
            /* ..... */
         });
    }

    Новый способ генерирования ID...

    Запостил: kontora, 16 Мая 2016

    Комментарии (69) RSS

    • Не поверишь, но это вполне может быть оправдано. Правда, чаще так гуиды генерят, т.к. у них вероятность коллизий сильно меньше, но с интами тоже можно, если сиквенсы маленькие, в пределах которых нужна уникальность и коллизии не приводят ни к чему страшному.
      Ответить
      • где оправдано?
        на c#?
        там где сгенерить ууид = написать 1 строку?
        Ответить
      • > нужна уникальность ... коллизии не приводят ни к чему страшному

        парадокс
        Ответить
        • Гм. Знаменитый GetHash сишарпика выдаёт инт. Вроде и уникальность нужна, а к критическим последствиям коллизии не приводят. Парадокс?
          Ответить
          • уникальность не нужна
            нужен достаточно хороший разброс

            даже если GetHash будет всегда возвращать 1, то ничего не упадет
            просто будет тормозить
            Ответить
            • > уникальность не нужна
              Уникальность нужна. Вся идеология хэшей построена на том, что большая часть из них уникальна.

              > нужен достаточно хороший разброс
              Разброс не нужен. В большинстве алгоритмов поиск ведётся по бинарному дереву, но с прохождением по всем ветвям в обязательном порядке, и сбалансированность этого дерева ну почти никак не влияет на быстродействие. Грубо считается, что сложность HashSet = O(1). Другое дело, что в хэшсете хранятся списком значения с одинаковым хэшем. И там их надо выбирать полноценным сравнением.

              > даже если GetHash будет всегда возвращать 1, то ничего не упадет
              > просто будет тормозить
              Да ладно! Не может быть такого!
              Ответить
              • >>Уникальность нужна. Вся идеология хэшей построена на том, что большая часть из них уникальна.

                Чем больше уникальности -- тем лучше. Но гарантировать полную уникальность нельзя уже потому, что int не бесконечен.

                >>Разброс не нужен.
                Нужен.

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

                щито?) Зачем нужно дерево с обязательным прохождением по всем ветвям?))
                Почитай как в той же жабе HashMap работает, например.
                Ответить
                • > Зачем нужно дерево с обязательным прохождением по всем ветвям
                  Чтобы поебаться с его обходом же.
                  Ответить
                  • причем поебаться так, что бы было O(1)

                    потому что при полном обходе бывает что-то с числом N, не так-ли? Например O(N)
                    Ответить
                    • > O(1)
                      Ну оно почти всегда из одного элемента, уникальность же хорошая :3
                      Ответить
                      • а как этот элемент находят?

                        А, я понял. У пользователя просто p+(2^32) байт оперативки под это дерево, и хеш это просто адрес.

                        вот, я придумал алгоритм с доступом O(1): govno = (govno *)(p + hash)
                        Ответить
                • > Но гарантировать полную уникальность нельзя уже потому, что int не бесконечен.
                  Копетан, залогинься.

                  >>Разброс не нужен.
                  >Нужен.
                  Не нужен.
                  Не, ну а чо, аргументы приводить на заявление без аргументов? Я что, больной?

                  > щито?) Зачем нужно дерево с обязательным прохождением по всем ветвям?))
                  Для О(1), например. Это было довольно грубое сравнение, в хэше не совсем дерево. Там мапка с эрекцией, которая увеличивается по мере увеличения энтропии хэшей. И да, читал, только не про жабу, а про шарпик. И не только Рихтера.
                  Ответить
                  • >>>Разброс не нужен.
                    >>Нужен.
                    >Не нужен
                    Конечно нужен. Если 49% хешей будет 42, а другие 49% будут -1, то это говно а не хеш

                    >>Для О(1), например.
                    Что за структура данных при ПОЛНОМ ее обходе дает O(1)?
                    Мне такие не известны.

                    >>Там мапка с эрекцией, которая увеличивается по мере увеличения энтропии хэшей.

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

                    Итого там получается логарифм, а в случае константного хеша всё вырождается в лист и получается O(N)
                    Ответить
                    • > > >Для О(1), например.
                      > Что за структура данных при ПОЛНОМ ее обходе дает O(1)?
                      > Мне такие не известны.

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

                    при хорошем разбросе в бакете будет мало (а то и вовсе один) объект
                    http://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs,d3599058f8d79be0

                    private void Insert(TKey key, TValue value, bool add) {
                            
                                if( key == null ) {
                                    ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
                                }
                     
                                if (buckets == null) Initialize(0);
                                int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
                                int targetBucket = hashCode % buckets.Length;
                     
                    #if FEATURE_RANDOMIZED_STRING_HASHING
                                int collisionCount = 0;
                    #endif
                     
                                for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) {
                                    if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
                                        if (add) { 
                                            ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
                                        }
                                        entries[i].value = value;
                                        version++;
                                        return;
                                    }
                    Ответить
              • > большая часть из них уникальна.

                Короче, define("уникальность") и define("разброс")

                Я утверждаю, что если "большая часть объектов уникальна", формально из 2N объектов N + 1 встречаются ровно один раз, а остальные N - 1 имеют одинаковых хэш, то это говно, т.к. среднее время доступа будет
                (N+1 + (N-1)(N-1)/2) / 2N ~= N/4, т.е. O(N).

                Я также утверждаю, что если "разброс хороший", т.е. Pr [ hash(x) = hash(y) ] ~= 1/2N, то хэш опупенен, даже если в коллекции нет ни одного объекта с уникальным хэшем (по два в бакет накидались). Ибо ожидаемое время доступа O(1).

                Учите математику, господа.
                Ответить
                • В первом случае будет 2 уникальных хэша, во втором N/2 уникальных. Явно, что при N>2 второй хэш будет лучше.
                  Ответить
                  • > В первом случае будет 2 уникальных хэша
                    В каком первом? с "большей частью"? Если объектов N, то в "первом" случае будет N / 2 + 1 уникальных хэшей, а "во втором" N / 2. Туговато у вас с арифметикой что-то.
                    Ответить
          • Так тут смысл не в уникальности же, а в распределении. Оно должно быть однообразным-нормальным. Тут даже не обязательно рандом использовать, вполне можно функцию с маленьким периодом, главное, чтобы значения ключей получались более-менее равномерно распределенными. Т.е. например, если дано, что входные параметры - слова на английском, можно взять статистику английских текстов, посмотреть как часто встречаются какие буквы и на основании этого генерировать ключи.

            Скажем так: нам нужно сгенерировать регулярное выражение с минимальным детерминированым автоматом с количеством состояний таким же как количество битов в ключе. (Михил-Нирод теорема гарантирует то, что таким образом мы поделим весь язык на нужное количество классов). Ну и дальше имея статистику можно просчитать сколько слов определенной длины попадет в каждый из классов. Дальше, построить Витебри автомат, оптимизировать его, в том смысле чтобы все классы были более менее одинаковыми - и вот вам хеш-функция.
            Ответить
            • Вот как выглядит overqualification.
              Ответить
            • Я по секрету скажу, что нормальное распределение нихуя не равномерное.
              Охуенная, конечно, хэш-функция получилась для входного слова. Жрущая память, сложная и непонятная. Не проще ли слова поксорить? Распределение будет явно равномернее.
              Ответить
              • Как там на мостике, дельфины-русалки?
                Ответить
                • Эка ты его заковыристо капитаном назвал...
                  Ответить
      • А что мешает использовать API для GUUID? AFAIK они уникальны во времени и пространстве, на этом построено в винде буквально все, начиная с COM

        По теории вероятности скорее тебя загрызет стая диких волков, чем твои гуиды совпадут
        Ответить
        • Речь о том, что не всегда гуид нужен. Гуид - 128 бит, инт - всего 32. Если надо по ид найти файл в маленькой выборке, сначала ищем по ид, если попалось два штуки, сравниваем по имени. Намного быстрее и коллизии пофиг. И хранить надо меньше, чем в случае с гуидом.
          Ответить
          • а, я понял
            у тебя сто миллиардов файлов, и потому лишние 96 байт -- непозволительная роскошь
            да?
            Ответить
            • Лишние 12 байт. Тут в продакшен базах юзают guid'ы как ключи во всех таблицах и не ссут... А он для "маленькой выборки" боится...
              Ответить
              • у меня коллега юзала

                знаешь, какой был аргумент? А чтобы не угадать ID было.

                Ну вот есть например урл /govno/1 и ты сразу понимаешь что есть /govno/2
                а если там /govno/{00020800-0000-0000-C000-000000000046}
                то фигу что ты угадаешь
                Ответить
                • Секретный url для защиты - хуевая идея в общем случае. Есть 100500 вариантов, когда он может утечь.
                  Ответить
                  • а это и не единственная защита
                    это так, от дурака
                    Ответить
                  • Ну если надо анонимный но не публичный доступ - вариантов особо и нет.
                    Ответить
                    • Есть как минимум передача постом
                      Ответить
                      • Как ты ссылку другому чуваку post'ом передашь?
                        Ответить
                        • Сделать на сайте поле «код для вставки» (типа как в Ютубе), которое показывает код:
                          <form method="post" action="http://some.site/">
                          <input type="hidden" name="token" value="314159265" />
                          <input type="submit" name="Читать суперсекретную статью" />
                          </form>

                          Попросить юзера сохранить код в файл с расширением .html, открыть в браузере и нажать кнопку.
                          Ответить
                        • Даешь ссылку, где надо ввести код.
                          Ответить
                • > чтобы не угадать ID было
                  Ну тогда надо выхлоп криптостойкого ГСЧ, а не GUID...
                  Ответить
                • Олсо, люди на сайтах ЧПУ пилят, чтобы пользователей айдишками не пугать... А тут такой пиздец в урле.
                  Ответить
                  • >Олсо, люди на сайтах ЧПУ пилят
                    Шта?
                    Ответить
                    • http://some.site/o-nashem-yobanom-saite
                      Ответить
                      • особенно охуенно выглядят ЧПУ на русском
                        Ответить
                        • Особенно если домен тоже русский...
                          Ответить
                          • При этом одни браузеры показывают URL кириллицей, другие — в закодированном виде. Теоретически возможно 2³ вариантов:
                            1. Домен в Punycode — домен кириллицей.
                            2. Части пути urlencoded — части пути кириллицей.
                            3. get-параметры urlencoded — get-параметры кириллицей.

                            А небраузеры вместо части URL, идущей после домена, подставляют title, а URL показывают только после наведения указателя.
                            Ответить
                            • > показывают
                              Копируют то один хер пуникодом?
                              Ответить
                              • Проверим:
                                1. Opera/Presto: домен показывает кириллицей, копирует кириллицей.
                                2. Фуррифокс (современные версии, а не 3.x): аналогично.
                                3. IE9: аналогично.
                                4. Хром: хуй пойми что. Показывает без схемы (http://) и кириллицей, а копирует в Punycode.
                                5. Сафари: внезапно и показывает, и копирует кириллицей, как в браузерах, несмотря на то, основан на Вебките.

                                Вывод: Хром не нужен.
                                Ответить
                                • Это если весь домен кириллицей? Если намешано с латиницей - вроде в пуникоде кажет.
                                  Ответить
                              • Продолжаем тестирование.

                                Путь:

                                1. Показывают и копируют кириллицей: Opera/Presto, IE, Сафари.

                                2. Показывают кириллицей, копируют в urlencode: Хром, Фуррифокс.

                                GET-параметры:
                                1. Opera/Presto: показывает в urlencode (причём не в UTF-8, а в cp1251), копирует как показывает.
                                2. ΙΕ: показывает абракадабру в cp1252/iso8859-1, копирует как показывает.
                                3. Фуррифокс: показывает кириллицу, копирует в urlencode (UTF-8).
                                4. Хром: показывает кириллицу, копирует в urlencode (UTF-8), как Фуррифокс.
                                5. Сафари: показывает кириллицу, копирует кириллицу.
                                Ответить
                                • > копирует в urlencode (UTF-8).
                                  Раньше вроде был такой прикол, что у яндекса страница была в 1251 и текст в запросах им же кодировался.
                                  Ответить
                                  • Плюсовавшим - сейчас это как?

                                    Кстати, вот я не скажу в каком браузере это было, может быть и в очке. Сейчас яндекс на utf8 перешел.
                                    Ответить
                                    • <meta charset="utf-8"/>
                                      Ответить
                                    • >> это было, может быть и в очке
                                      Сём, а программирование-то тут причем?
                                      Ответить
                      • google: ЧПУ
                        Ответить
                        • Вторая ссылка: https://ru.wikipedia.org/wiki/ЧПУ_(Интернет)

                          Не я же эту хуйню выдумал. Мне самому при слове ЧПУ станки вспоминаются.
                          Ответить
                          • >ЧПУ (от жаргонного «человеко-понятный урл»)
                            Первый раз слышу. Какой-то форс?
                            Ответить
                            • Х.з. На русскоязычных ресурсах по вебдеву часто проскакивало.
                              Ответить
                              • Что за ресурсы?
                                Ответить
                                • Да та же швабра.

                                  З.Ы. Я вебом почти не занимался, так что хороших ресурсов насоветовать не смогу.
                                  Ответить
                                • пол инета этим засрано

                                  human readable url
                                  Ответить
                                  • Напомню, тут речь идет про аббревиатуру ЧПУ
                                    Ответить
            • Во-первых, не у меня. Не я этот код писал. И не я его постил на ГК.

              Во-вторых. Меня уже бесят те, кто сразу знает, что так делать нельзя, видя только пару строчек. Программирование - это вообще не впихивание цилиндрических объектов в круглые отверстия. Тут немножечко всё сложнее и на каждую задачу существует бесконечное множество решений, начиная от забить до уговирить заказчика так не делать. Написать код - это где-то посередине, а способов написать этот код тоже почему-то бесконечность. Это включая выбор языка, платформы, БД, ОРМ, стиля и инструментов. Что, сука, характерно, что влияющих на выбор факторов тоже, почему-то, бесконечность. И при этих бесконечностях, население ГК почему-то считает, что использование инта вместо гуида по тому же принципу однозначно неправильно. Даже не думая о том, что могут быть объективные обстоятельства, а решение могло быть вполне обдуманным, взвешенным и здравым.

              В третьих. На сто миллиардов файлов (которые в файловой системе, ага, со скоростью доступа на несколько порядков меньшей, чем оператива) будет оверхед не 96 байт. Тут легко считается 96 бит разницы умножить на сто миллиардов. Получается 1,2 триллиона байт оверхеда.
              Ответить
              • > сто миллиардов файлов
                И это типа "маленькая выборка", о которой ты упоминал?
                Ответить
                • Нет. Сто миллиардов - это предположение @guesto. Но для маленькой выборки тоже может быть профит, если этих выборок стопицотмиллиардов.
                  Ответить
              • > Меня уже бесят те, кто сразу знает, что так делать нельзя, видя только пару строчек.

                тогда что ты делаешь на ГК?
                Ответить

    Добавить комментарий