• Какой специалист мне нужен?

    Deita
    @Deita
    Бизнес-аналитик
    Ответ написан
    Комментировать
  • Какой специалист мне нужен?

    newross
    @newross
    Product owner
    Бизнес-аналитик либо продакт.
    Желательно знакомого с вашей предметной областью и аудиторией.
    Чего точно не стоит делать, так это делегировать принятие решений разработчикам. А то получите красивый код, оторванный от бизнеса
    Ответ написан
    Комментировать
  • Как запретить скачивание/запуск исполняемых файлов и все сайты с онлайн играми?

    CityCat4
    @CityCat4 Куратор тега Информационная безопасность
    Внимание! Изменился адрес почты!
    Как обычно.

    Файрволлом баним все запросы наружу.
    Прокси делаем доступ к тому, куда надо и баним туда, куда не надо. Поскольку сейчас все сайты по https - потребуется бампинг.
    Ответ написан
  • Как запретить скачивание/запуск исполняемых файлов и все сайты с онлайн играми?

    @Drno
    Можете установить прокси и на нем запретить всё, кроме нужных сайтов.
    Например squid или 3proxy
    Ответ написан
  • Как по ВПН соединить две сети с одинаковым поддиапазоном 192.168.0.1/24?

    ValdikSS
    @ValdikSS
    С OpenVPN это сделать сравнительно легко — у него имеется встроенное средство переназначения сетей.

    --client-nat args
            This pushable client option sets up a stateless one-to-one NAT rule on packet addresses (not ports), and is useful in cases where routes or ifconfig settings pushed to the  client  would
            create an IP numbering conflict.
    
            Examples:
    
                client-nat snat 192.168.0.0/255.255.0.0
                client-nat dnat 10.64.0.0/255.255.0.0
    
            network/netmask  (for  example  192.168.0.0/255.255.0.0) defines the local view of a resource from the client perspective, while alias/netmask (for example 10.64.0.0/255.255.0.0) defines
            the remote view from the server perspective.
    
            Use snat (source NAT) for resources owned by the client and dnat (destination NAT) for remote resources.
    
            Set --verb 6 for debugging info showing the transformation of src/dest addresses in packets.


    А с другими типами — использовать ядерное переназначение через iptables/nftables: DNAT/SNAT, NETMAP.
    Ответ написан
    Комментировать
  • Почему FireFox может скачать некий файл по https, а моя программа не может?

    @devian3000
    Ну можно сказать что доступ закрыт)
    Если все заголовки скопированы включая Authorization то можно предположить что при генерации страницы для скачивания файла генерится ключ авторизации, скорее всего уникальный на каждую сессию. это легко проверить посмотрев на ссылки, если там меняется какой-то набор символов значит ключ находиться в самом url.

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

    GavriKos
    @GavriKos
    Никак
    Ответ написан
    Комментировать
  • Как организовать систему балансировки нагрузки во время работы доменных пользователей Active Directory?

    hint000
    @hint000
    у админа три руки
    1. Вы пишите, что у вас только один контроллер домена. Второй сервер вы только собираетесь сделать контроллером домена? Делается в два шага: (а) ввести сервер в существующий домен, (б) добавить на нём роль AD DC и объявить его новым контроллером.

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

    3. О какой-то нагрузке на контроллер домена можно начинать рассуждать, когда в домене 1000+ пользователей; в этом случае у вас уже будет развитая сетевая инфраструктура, и вы можете два контроллера разместить в двух сайтах (в терминах AD), каждому сайту назначить подсеть, пользователи из определённой подсети будут обслуживаться своим контроллером;
    Но если у вас пользователи распределены территориально и работают в разных подсетях, то даже при малом количестве пользователей есть смысл распределить контроллеры по тому же принципу - не для распределения нагрузки, а для надёжности.
    Ответ написан
    3 комментария
  • Баг Telegram, взлом, слежка?

    ValdikSS
    @ValdikSS
    У вас могли украсть директорию данных Telegram, в этом случае дополнительная сессия не будет отображаться, вы и злоумышленник будете использовать одну сессию.
    Завершите ВСЕ сессии и аутентифицируйтесь с гарантированно чистого устройства заново, с нуля. Если дело действительно в компрометации директории, вам необходимо просканировать компьютеры на вирусы, а лучше переустановить ОС без сохранения данных.
    Ответ написан
    8 комментариев
  • Как изменить права доступа к общей папке?

    morihaos
    @morihaos
    На 99% вопросов уже есть ответы в инетке...
    Привет,
    Дело не в NTFS. Дело в том, что при старте гостевой системы Ubuntu Server общая папка монтируется на уровне ядра по информации из файла /etc/mtab с доступом для root:vвoxsf и разрешениеями rwxrwx---, то есть с ней могут работать root и все юзеры, которые входят в группу vboxsf. Если вы, конечно, поставили гостевые дополнения прилагаемые к виртуалбоксу в консоли Ubuntu Server примонтровав их по /dev/cdrom, а не через apt из репозитория Ubuntu.
    Добавьте себя в эту группу командой:
    sudo usermod -aG vboxsf username
    где username - ваш логин входа на консоль, перелогинтесь в консоли и без проблем сможете писать в свою общую папку.
    Если же ставили как-то нестандартно гостевые дополнения, то смотрите файл /etc/mtab и ищите вашу общую папку в примерно такой строке:
    имя_вашей_шары /media/sf_имя_вашей_шары vboxsf rw,nodev,relatime 0 0
    вот этот vboxsf и есть группа, в которую вам надо себя добавить.
    Еще вариант - проверить, кому принадлежит смонтированная папка и ее разрешения командой:
    ls -al /media
    или, куда у вас она смонтирована автоматом или монтируется руками и посмотреть, кто ее владелец и какая группа юзеров к ней подключена и уже по этой информации добавить себя в эту группу.
    Ответ написан
    Комментировать
  • Как правильно заменить диск в Software RAID??

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    То, что вы подчеркнули красным, это точка монтирования. Два тома в одну точку монтировать нельзя.
    Вам надо отформатировать раздел на новом диске и скопировать на него содержимое папки /boot/efi
    Примерно так:
    sudo mkfs -t vfat /dev/nvme1n1p2
    sudo mount /dev/nvme1n1p2 /mnt
    sudo cp -r /boot/efi /mnt
    sudo umount /mnt
    Ответ написан
    9 комментариев
  • Как ускорить поиск элементов из статичного string[] по подстроке?

    @Degot Автор вопроса
    Я сравнил несколько вариантов: Contains, SqliteFTS, Words. И выбрал реализацию Words.
    Псевдо-C#:
    var strings = new string[]; //25 млн записей
    
    var words = new Dictionary<string,HashSet<int>>();
    //формирование "справочника"
    var str = string.Empty;
    for(var stringId = strings.Length - 1; stringId >= 0; stringId--)
    {
        str = strings[stringId];
        var stringWords = NormalizeString(str).Split(' ');
        foreach(var stringWord in stringWords )
        {
            words[stringWord].Add(stringId);
        }
    }
    
    //поиск
    var searchTermWords= NormilizeString(searchTerm).Split(' ')
    var foundIds = new HashSet<int>();
    foreach(var searchTermWord in searchTermWords)
    {
       foreach(var matchWord in words.Keys.Where(x => x.Contains(searcgTermWord)))
       {
      if (words.TryGetValue(matchWord, out var stringIds))
      {
        if (foundIds  == null)
        {
            foundIds = stringIds;
        }
        else
        {
            foundIds = stringIds.Where(x => foundIds .Contains(x)).ToHashSet();
        }
     }
     else
     {
         foundIds  = null;
     }
    }
    }
    
    Console.WriteLine($"Найдено строк: {foundIds.Count} ");


    Тесты разных вариантов для списка объектов с 4мя строковыми полями:
    Поиск: 100 циклов поиска 1-3 символьной подстроки по одному полю
    
    records: ~5 000 000
    
    TestContains (ms):
      -> Max: 434, Avg: 295.56, Median: 281
    
    TestSqliteFTS (ms):
      CREATE -> 111
      INSERT DATA -> 34697 //INSERT INTO temp_table(object_id, поле0, поле1, поле2,  поле3)
      INSERT INDEX -> 161683 // INSERT INTO fts_index(object_id, поле0, поле1, поле2,  поле3 ) SELECT * FROM temp_table
      DROP DATA -> 1191
      VACUUM -> 15849
    
      -> sqlite.db (FTS5: 1.6GB, tokenize = 'trigram', content='',columnsize=0, detail='column')
      -> Max: 10, Avg: 1.16, Median: 0
      
    TestWords (ms):
      CREATE -> 89
      INSERT DATA -> 98851 //INSERT INTO temp_table(word_id, object_id)
      AGGREGATE DATA -> 28504 //SELET object_id FROM temp_table WHERE @word_id  -> FastPFor -> INSERT word_id, object_ids_as_bytes
      DROP DATA -> 1360
      CREATE INDICES-> 9
      VACUUM -> 262
    
      -> sqlite.db (CUSTOM: 9.5MB, (tbl: fields -> id, value), (tbl: words -> id, field_id, value), (tbl: data -> word_id INTEGER, integersQty INTEGER, bytes BLOB))
      -> Max: 128, Avg: 18.78, Median: 1
      
      Статы:
        field_id    wordsQty   maxRefsQty  avgRefsQty  maxRefsBytes    avgRefsBytes
        0           24075	    6461929	    271         910000          52
        1	        5339	    23858735	4515	    3336816         667
        2       	3602	    6766040     1913        952808          295
        3	        11825	    7595099     744         1069508         123
    
    
    records: ~25 000 000
    
    TestContains (ms):
      -> Max: 2568, Avg: 1524.47, Median: 1437.5
    
    TestSqliteFTS (ms):
      CREATE -> 135
      INSERT DATA -> 255882 //INSERT INTO temp_table(object_id, поле0, поле1, поле2,  поле3)
      INSERT INDEX -> 1022499 // INSERT INTO fts_index(object_id, поле0, поле1, поле2,  поле3 ) SELECT * FROM temp_table
      DROP DATA -> 370118
      VACUUM -> 1230845
      
      -> sqlite.db (FTS5: 8.1GB, tokenize = 'trigram', content='',columnsize=0, detail='column')
      -> Max: 587, Avg: 11.53, Median: 0
    
    TestWords (ms):
      CREATE -> 107
      INSERT DATA -> 581050 //INSERT INTO temp_table(word_id, object_id)
      AGGREGATE DATA -> 132700 //SELET object_id FROM temp_table WHERE @word_id  -> FastPFor -> INSERT word_id, object_ids_as_bytes
      DROP DATA -> 6855
      CREATE INDICES-> 32
      VACUUM -> 1161
    
      -> sqlite.db (CUSTOM: 35MB, (tbl: fields -> id, value), (tbl: words -> id, field_id, value), (tbl: data -> word_id INTEGER, integersQty INTEGER, bytes BLOB))
      -> Max: 492, Avg: 64,87, Median: 1
      
      Статы:
        field_id    wordsQty   maxRefsQty  avgRefsQty  maxRefsBytes    avgRefsBytes    
        0       	24075	    32570729	1355        4586324         205
        1	        5339	    120257135	22577       16818780        3192
        2	        3602	    34103240	9566        4802092         1372
        3	        11825	    38282299	3723        5390372         542


    P.S. После тестирования FastPFor, WAH, RoamingBitmap и LZO для хранения индексов (слово -> индекс строки[]) остановился на Delta + LZO. Итоговый размер индекса: 17MB. Максимальное время поиска 600ms, среднее 7ms.
    Ответ написан
  • Монитор fullHD 17-19 дюймов, существуют ли?

    @alexalexes
    Действительно, сегмент малых мониторов с FullHD сейчас занимают только сенсорники.
    В качестве исключения можно найти отдельных китайцев, но это исключение из правил, например:
    https://market.yandex.ru/product--monitor-carcam-l...
    Ответ написан
    Комментировать
  • Как сгенерировать шахматный бакграунд в ImageMagick.Net?

    @U235U235
    Зачем рисовать квадратики в цикле? Вообще-то шахматный паттерн уже есть в IM.
    convert -size 8x8 pattern:gray50 -scale 5000%  chessboard.png
    Ответ написан
    6 комментариев
  • Как заблокировать доступ к ресурсу для конкретного региона?

    @Everything_is_bad
    Недавно проверял состояние сервера и заметил в логах много неудачных попыток входа на сервер (В основном через ssh)
    ну как первый раз в интернет вышел, уже сто лет такое, ssh вообще постоянно долбят, ставишь fail2ban, а еще лучше меняешь дефолтный порт и ставишь логин только по ключу. А регион блокировать, так себе идея.
    Ответ написан
    9 комментариев
  • Как заблокировать доступ к ресурсу для конкретного региона?

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

    С веб-сервером сложнее - тут без подключения посторонних сервисов выбор невелик - модуль geoip или ручное перечисление диапазонов релевантных стран.
    Ответ написан
    1 комментарий
  • Как заблокировать доступ к ресурсу для конкретного региона?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    GeoIP ngx_http_geoip_module

    1. Nginx должен включать модуль ngx_http_geoip_module.
    2. Качаем БД GeoLite2 Country.
    3. Пример конфига (nginx.conf), с отправкой всех из Индии в 403 лес:
    http {
        geoip_country /path/to/GeoLite2-Country.mmdb;
        map $geoip_country_code $allowed_country {
            default yes;
            IN no; # banned india
        }
    }
    
    server {
        if ($allowed_country = no) {
            return 403;
        }
    }
    Ответ написан
    5 комментариев
  • Как ускорить поиск элементов из статичного string[] по подстроке?

    VoidVolker
    @VoidVolker Куратор тега C#
    Dark side eye. А у нас печеньки! А у вас?
    Раз нет ограничений по памяти и надо максимально быстро, то можно разложить весь массив в дерево таблиц переходов с шагом в один символ на таблицу. Самый быстрый и самый затратный по памяти. Таблица на каждый символ - 256 байт. Скорость поиска зависит только от размера строки и не зависит от объема данных: один символ - один переход в таблице к следующей таблице или конец поиска, если ноль. Я так уже делал: использовать имеет смысл на объемах примерно от 4 гигабайт данных (чем больше объем - тем меньше затраты на каждый символ). Но, если память позволяет и цель именно в скорости - то вполне нормальная плата памятью за скорость. Можно сократить расход памяти, если перекодировать строки в кодировку по числу используемых символов. Тогда таблица переходов будет в несколько раз меньше. Более экономный и более медленный вариант - дерево массивов/списков с шагом в 2/4/8 символов, при этом в поиске сравнение не по символам делать, а сразу по 2/4/8 байт: т.е., работаем со строкой как с массивом байтов и получаем оттуда uint16/uint32/uint64 и их и сравниваем, ибо процессору все равно какую инструкцию выполнять - один байт сравнить или 8. Возможно, конечно, оптимизатор в поиске по строке это все и оптимизирует. Я давно уже не смотрю на результаты его работы - так что тут только опытным путем. Ну и щас еще других вариантов накидают с деревьями тоже.

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

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

    UPD2:
    Таки нашел немного времени и откопал исходники для шарпа и провел несколько тестов по расходу памяти.

    Число строк / общий размер данных / итоговый размер дерева

    5 символов:
    1000000 / 55.9MB / 13.2GB
    2000000 / 111.6MB / 25.2GB

    10 символов:
    100000 / 8.1MB / 4.1GB
    200000 / 16.1MB / 8GB
    300000 / 24.2MB / 11.9GB
    400000 / 32.2MB / 15.7GB
    500000 / 40.3MB / 19.5GB

    15 символов:
    100000 / 10.5MB / 6.6GB
    200000 / 21MB / 13.1GB
    300000 / 31.5MB / 19.5GB
    400000 / 42MB / 25.8GB

    20 символов:
    100000 / 13MB / 9.1GB
    200000 / 25.9MB / 18.1GB
    300000 / 38.9MB / 27GB


    Максимальный размер дерева для глубины в 5 символов на платформе х64:
    • Для диапазона 0-255 - до 8Тб и до 4 311 810 305 узлов
    • Для диапазона 0-70 - до 13.5Гб и до 24 357 971 узлов

    Максимальный размер дерева для глубины в 4 символа для диапазона 0-255: ~17Гб и ~33Гб для х86 и для х64 соответственно и лимит в 16 843 009 узлов. Ну и в коде есть функция для вычисления максимального числа узлов и размера дерева.

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

    И соответственно код: https://github.com/VoidVolker/search-tree/tree/master (предупреждаю сразу: код старый, по сути экспериментальный, не вылизанный и вероятно приведет кого-то в ужас). Но, главное, что работает.
    код

    Тестовый код:
    static Random rnd = new Random();
    static string[] GenStrings(int cnt, int strLen)
    {
        string[] arr = new string[cnt];
        var i = 0;
        while (i < cnt)
        {
            var sb = new StringBuilder();
            for (var j = 0; j < strLen; j++)
            {
                sb.Append(rnd.Next(0, 256));
                //sb.Append(TAbc[rnd.Next(0, TAbc.Length)]);
            }
            arr[i++] = sb.ToString();
        }
        return arr;
    }
    
    var arraySize = 300000;
    var stringSize = 20;
    
    var GCStartArr = GC.GetTotalMemory(true);
    
    var strings = GenStrings(arraySize, stringSize);
    
    var GCEndArr = GC.GetTotalMemory(true);
    var GCStart = GC.GetTotalMemory(true);
    
    var tree = new ArrayTree<string>();
    foreach (string s in strings)
    {
        tree.Add(Encoding.UTF8.GetBytes(s), s);
    }
    
    var GCEnd = GC.GetTotalMemory(true);
    
    Console.WriteLine("Array x string size / Array memory used / Tree memory used");
    Console.WriteLine($"{arraySize} х {stringSize} / {BytesToString(GCEndArr - GCStartArr)} / {BytesToString(GCEnd - GCStart)}");
    Ответ написан
  • Как ускорить поиск элементов из статичного string[] по подстроке?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Сначала объедините все ваши строки в одну через какой-то раздилитель, которого не может быть в искомой строке (можно и без него, но с ним код чуть проще будет). В конце поставьте этот же разделитель 2 раза. Вроде "строка1$строка2$строка3$...$строкаN$$".

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

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

    Другой вариант - через преобразование Барроуза — Уилера. Вот есть лекция. Этот алгоритм часто упоминается в курсах по биоинформатике. Реализацию может даже найдете где-то. Потом можно найти номера исходных строк из индексов вхождений через тот же бинпоиск по сортированному массиву индексов начал всех строк в тексте.

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

    Учтите, что построение структуры данных тут будет в несколько раз медленнее простого for+Contains. Выигрыш вы получите, если у вас текст действительно статичный и вы в нем много раз что-то ищите.
    Ответ написан
    7 комментариев
  • Позволяет ли какой-либо ИИ генератор изображений менять не одежду заданного человека на фото, а человека по заданной одежде?

    soundie
    @soundie Автор вопроса
    Посмотрел внимательнее сервисы, которые генерируют одежду по фото человека - оказывается у одного из них (на приведённой мной даже странице внизу ) есть и обратное:
    5z8bploodu1npq8i9j1pxyxb53u.jpeg

    Тем не менее, если кто знает ещё сервисы - прошу подсказать.
    Ответ написан
    4 комментария