• БД для хранения сообщений чата, какую выбрать?

    @InoMono
    Вполне себе любая развитая современная РСУБД годится для этой задачи.
    MySQL, PostgreSQL...

    А по мере роста нагрузки - тут не выбором СУБД нужно заморачиваться, а MQ-сервер ставить. Он гораздо легче сравиться с бешенными нагрузками.

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

    Из самого критично подозрительного - полнотекстовый поиск.
    Впрочем, полагаю, что полнотекстового поиска средствами MySQL или PostgreSQL вплоне хватит.

    Если уж делать прям таки серьезный чат типа Slack, то для полнотекстового поиска я бы вообще отдельную специализированную БД держал бы. Например, SphinxSearch.

    Но, для начала, возможностей PostgreSQL или MySQL будет вполне достаточно.

    Что до Mongo... Если вам не нужна репликация без консистентности. Зато быстрая...
    Так вот если вам не нужна такая репликация, то Монга вам не нужна.

    РСУБД будут существенно быстрее.

    Вот ежели вы планируете заводить ваш чат в кластер, когда одного сервера вам не хватит, то тут да, тут РСУБД не лучший выбор. Тут бы я рекомендовал как раз Монгу.
    Но опять таки кластер серверов для чата вы без MQ не сделайте.

    Вывод:

    Начните с обычной РСУБД.
    Как начнутся затыки - рассмотрите MQ
    Как начнется рост до масштаба планеты - рассматрите Монгу.

    Вся система работает с бд MySQL - InnoDB, сообщения пишутся в бд при каждой отправке (INSERT), пока сервис еще не запущен, сообщений мало (только мои тестовые) все работает шустро, но вот когда запущу и количество сообщений перевалит за несколько миллионов, что будет тогда с моей бд? Начнутся жесткие тормоза при select и insert?


    Вам никто не мешает это проверить.
    Сгенерируйте миллион случайных сообщений.

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

    Брат, пока не поздно, делитай Джумлу и ставь Wordpress. Я начинал с верстки шаблонов для Джумлы, очень круто реализовано меню и модули, мне нравилось, но были проблемки с доступом к ядру и не стакающиеся скрипты. Потом перешел на ВП, и после завершения работ по первому же сайту сказал: Е*ать, как тут все просто!
    Тебе понадобятся ACF и шорткоды к ним, сделаешь второй контакт, тру стори xD
    Минимум php, все найдешь в нете, основа - это HTML + CSS естессно, не забудь инициализировать кастомные скрипты в footer.php, в общем удачи тебе и новых открытий.
    Ответ написан
    1 комментарий
  • Какой сайт/сервис или на что вы обращаете внимание когда беретесь за очередной проект для заработка?

    iiiBird
    @iiiBird
    Пока ты спишь - твой конкурент совершенствуется
    Стартапы делятся на 3 типа: (это мое ИМХО и мои 3 типа)
    1) Купить нишу (деньги) - значит выбрать абсолютно любую нишу и купить место в ней. Т.е. сумма денег прямо пропорциональна популярности ниши.
    2) Добиться ниши (время) - Потратить уйму времени, чтобы занять место в нише. (К примеру человек создал статейный сайт и просто годами его наполнял. Вот прям годами. Десятилетиями. И в конечном итоге смог выйти в прибыль.)
    3) Оказаться в нужном месте в нужное время (случайность) - Просто по случайному стечению обстоятельств должно повезти так, что ты займешь нишу, в которой будет хорошая прибыль.

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

    Раз ты тут написал что не 1 и не 2. То для тебя вариант 3
    Ответ написан
    Комментировать
  • Какой сайт/сервис или на что вы обращаете внимание когда беретесь за очередной проект для заработка?

    dimonchik2013
    @dimonchik2013
    non progredi est regredi
    ну кто ж тему спалит

    все проекты делаются двумя путями:
    1) дублированием новых западных на местный рынок/рунет/Европу ( в Европе тоже есть кому заняться)
    2) отжимом доли на локальных либо основном рынке у давно ( или недавно) работающих успешных

    отсюда ясно на что смотреть: ищещь рынки, прикидываешь место, строишь
    Ответ написан
    Комментировать
  • Как грамотно замаскировать поле _id при передаче на UI?

    @kliss
    > мог узнать и получить доступ к документам из этого диапазона _id (авторизация не учитывается)

    Вот где проблема, а не в айдишниках. Security by obscurity не работает. Настрой проверку прав и хоть интегерами айдишники передавай.
    Ответ написан
    9 комментариев
  • Как грамотно замаскировать поле _id при передаче на UI?

    yarkov
    @yarkov
    Помог ответ? Отметь решением.
    У Монго есть виртуальные поля. Заюзайте их и будет счастье ))
    // ПСЕВДОКОДИЩЕ!!!
    var ArticleSchema = new Schema({
      title: {
          type: String
      }
    });
    
    ArticleSchema
      .virtual('id') // вместо _id
      .get(function() {
        let hash = md5(this.title);
        return encrypt(this._id, hash);
      })
      .set(function (setFullNameTo) {
        // some setter code
      });
    Ответ написан
    4 комментария
  • Как грамотно замаскировать поле _id при передаче на UI?

    Wolfnsex
    @Wolfnsex
    Если не хочешь быть первым - не вставай в очередь!
    Допустим, организация ссылок на моем сайте, это вызов документа через явное указание _id (в строке адреса), но мне не хотелось бы что бы человек, всего лишь посмотрев на запрос, мог узнать и получить доступ к документам из этого диапазона _id (авторизация не учитывается).

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

    Первое что приходит на ум это назначить свой _id рендомом.

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

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

    Я бы всё-таки оставил ID в покое и не пытался бы сделать "из палки пистолет". Добавьте новое поле в качестве URL'а документа и записывайте туда хэшированный ID, не думаю, что увеличение объёма документа на 20-40 байт данных, может привести к тотальному краху системы (это как минимум, было бы странно). Ну или, если очень хочется и... и того и другого, используйте механизм "обратимого шифрования", т.е. хэширование - это по сути своей "односторонее шифрование" (если выражаться по простому), хэш нельзя превратить обратно в данные. Используйте обратимое шифрование, например такое. Идею с обратимым шифрованием можно развить и придумать какие-то дополнительные ключи или соль, если хочется прям "совсем страшно зашифроваться"...

    P.S. Библиотека для шифрования в примере, - первая что попалась в поиске. Судя по тегам, Вы используете Node.JS, уверен для нее подобных библиотек и алгоритмов должно быть в избытке.
    Ответ написан
    1 комментарий
  • Задачка по обработке CSV файла. Как подсчитать среднее значение?

    @pcdesign
    Если на коленке и без использования всяких модулей, то можно вот так:

    use strict;
    use warnings;
    use utf8;
    
    my $csv = <<'EOF';
    ClassA1,mark,chemistry,5
    ClassA2,mark,philosofyr,5
    ClassA2,julia,physic,5
    ClassA1,julia,math,3
    ClassA1,mark,philosophy,5
    ClassA1,julia,chemistry,4
    ClassA2,mark,chemistry,4
    ClassA2,julia,literature,2
    EOF
    
    my @csv = split "\n", $csv;
    
    my (%sum, %count);
    for my $row (@csv) {
        my ( $class, $name, undef, $num ) = split ",", $row;
        my $key = $class . '-' . $name;
        $sum{$key} += $num;
        $count{$key} += 1;
    }
    
    for my $name_class ( keys %sum ) {
        print $name_class, $sum{$name_class}/$count{$name_class}, "\n";
    }


    Результат:
    ClassA1-julia3.5
    ClassA2-julia3.5
    ClassA2-mark4.5
    ClassA1-mark5


    Хотя можно все это покрасивее и короче написать.
    Ответ написан
    Комментировать
  • Как найти строку совпадение в файле и распечатать все строки, которые находятся после нее?

    vaut
    @vaut
    perl -ne '$print=1 if /pattern/; print if $print'

    Мне тут подсказали что есть более изящное решение:
    perl -ne 'print if /pattern/ .. eof'
    Ответ написан
    Комментировать
  • Что значит оборачивание функции в скобки (function() { ... })?

    copist
    @copist
    Empower people to give
    Короткий ответ
    (function() { ... })()
    Это определение анонимной функции без параметров и непосредственный вызов её, так же, без параметров

    Длинный ответ
    Зачем оборачивать значение в круглые скобки?

    Оборачивание функции в скобки, так же как и оборачивание константы в скобки - это просто способ показать интерпретатору, что это значение внутри скобок может быть использовано как возвращаемое значение.
    var var_a = 5
    (var_a) /* или */ (5) // не является ошибкой, возвращает значение переменной или выражения
    function func_b() { }
    (func_b) /* или */ (function func_b() { }) // не является ошибкой, возвращает ссылку на функцию
    var var_c = { key: "val" }
    (var_c) /* или */ ({ key: "val" }) // не является ошибкой, возвращает объект
    var var_d = [ "one", "two" ]
    (var_d) /* или */ ([ "one", "two" ]) // не является ошибкой, возвращает массив


    Ну а раз (func_b) - это ссылка на функцию func_b, то значит её можно сразу же вызвать.
    A если (var_c) - это объект, то значит можно сразу же использовать его
    Аналогично (var_d) - это массив, то значит можно сразу же использовать его

    (func_b)() или (function func_b() { })() вызвать функцию
    (var_c).key или ({ "key": "val" }).key использовать объект
    (var_d)[0] или ([ "one", "two" ])[0] использовать массив

    Синтаксической ошибкой было бы использование функции, массива, объекта без скобок ( )
    function func_b() { }() ошибка "Unexpected token )"

    Хотя нет ошибки, по крайней мере в Google Chrome
    { key: "val" }["key"]
    ["one", "two"][0]

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

    Сравни
    var a = "test"
    alert(a)

    по завершении этого блока переменная a болтается в глобальной области видимости

    и
    (function(){
        var a = "test"
    })()
    
    alert(a) // недоступно, потому что она была локальной переменной внутри анонимной функции


    Почему скобки ( ) пустые?
    В данном случае у функции function() { ... }нет формальных параметров, значит и вызывать можно без параметров.

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

    (function (w, d, $) {
       // некоторым нравится сокращать код путём использования коротких имён переменных
       w['fizz'] = "buzz" // вот так можно принудительно зарегистрировать
                           // глобальную переменную fizz
       $('body').css({background: 'red'}) // вот так можно работать с jQuery через привычную $
                           // даже если библиотека была загружена в режиме noСonflict
    }(window, document, jQuery))


    Некоторым не нравится длинный вариант проверки на undefined и они специально предусматривают лишний параметр, который не инициализируют

    (function (message1, message2, empty) {
        // это и есть проверка на undefined
        if (message1 === empty)
            alert('message1 is undefined')
        else
            alert('message1 = ' + message1)
    
        if (message2 === empty)
            alert('message2 is undefined')
        else
            alert('message2 = ' + message2)
    })("test") // вызвана только с одним параметром, значит второй по имени message2
    //  будет пустой, а третий empty специально ввели в качестве образца
    //  данных с типом "undefined", для служебного использования

    Зачем функция анонимная?
    Аналогично - чтобы не регистрировать её имя в глобальной области видимости, если она нужна один раз.
    Ответ написан
    7 комментариев
  • Как высчитать сколько понадобится времени что бы создать дочерний процесс?

    Olej
    @Olej
    инженер, программист, преподаватель
    Как высчитать сколько понадобится времени что бы создать дочерний процесс в системе UNIX?

    Бессмысленный вопрос :-(.
    Правильный ответ: нисколько ;-) ... в смысле исчезающе мало, чтобы об этом беспокоиться.

    В POSIX, когда говорят "создать дочерний процесс" - имеют в виду, в первую очередь, fork() (хотя в других системах или при других обстоятельствах могут иметься в виду exec*(), spawn*() и так далее... popen() ;-) ).
    В современных POSIX системах выполнение fork() не зависит от всех ваших килобайт ... или мегабайт...
    Потому что при выполнении fork(), за счёт механизма COW (Copy On Write) не создаётся никакого такого адресного пространства. А всё время выполнения затрачивается только на выполнение системного вызова в ядре по созданию новой записи task и помещения её в циклическую очередь процессов.

    P.S. И ещё для вас будет большим сюрпризом, думаю, (но относящимся к делу) что время выполнения fork() будет примерно то же, что и время создания нового потока pthread_create() внутри одного процесса.

    P.S. А если вам позарез нужно узнать время fork() (в наносекундном диапазоне), то используйте для этого счётчик тактов процессора RDTSC и соответствующую команду ассемблера rdtsc.
    Ответ написан
    Комментировать
  • Как на javascript и jquery реализовать поблочный скролл?

    Написала свой плагин на чистом js
    Там есть поддержка сенсорной мыши (чего нет у onepage scroll) и куча других настроек по отслеживанию прогресса, также есть callback функции и возможность сделать блок со скроллом внутри одного слайда (странички)

    https://github.com/librisius/OliwPageSlider - дока на русском
    Ответ написан
    1 комментарий
  • Кириллица в vim'e

    @vireulgr
    Понимаю, что "Вопрос задан более 3х лет назад", но может кому интересно будет ))
    Перед запуском vim в консоли делаю
    chcp 1251
    и потом, если возникают проблемы, обратно
    chcp 866
    В .vimrc такие настройки:
    if has( "gui_running" )
    ...
    else
        if has( 'win32' )
            set encoding=cp1251
            set termencoding=cp866
            set keymap=russian-jcukenwin
        endif
    endif

    Переключение языков производится сочетанием Ctrl-6. Подробнее см. справку в Vim
    :help keymap
    :help enc
    :help tenc

    UPD:
    Поюзал консольный Vim под виндой, и обнаружил ещё кое-что
    • Если в свойствах консоли выбрать какой-нибудь TrueType шрифт, то нужно делатьset termencoding=cp1251
    • Чтобы не запариваться с переключением chcp 1251 ... chcp 866, можно сделать алиас для cmd.exe: DOSKEY vim=chcp 1251 $T vim $* $T chcp 866, поместить этот алиас в скрипт и настроить автоматическое выполнение скрипта при старте cmd.exe (будет что-то вроде .bashrc для bash). Про алиас и скрипт подробнее здесь: stackoverflow.com/a/21040825/3047301.


    ОС Win 7 x64, Vim 7.4.
    Ответ написан
    Комментировать
  • Название переменных?

    aen
    @aen
    Keep calm and 'use strict';
    Если мы говорим о JS, то:
    • имена переменных должны быть существительными (id, name, count);
    • имена функций должны начинаться с глаголов (getId, parseName, setCount);
    • имя константы должно быть записано прописными буквами, а слова должны быть разделены нижним подчеркиванием (MAX_COUNT);
    • имя объекта, обернутого jQuery, должно начинаться с $ ($el, $this);
    • имена функции-конструкторов должны начинаться с заглавной буквы (Plugin, Number, String);
    • избегайте слишком абстрактных названий, например, temp, foo, bar.
    Ответ написан
    1 комментарий
  • Как повесить событие на подгружаемые ajax'ом элементы?

    @eandr_67
    web-программист (*AMP, Go, JavaScript, вёрстка).
    Не надо заворачивать on в on.

    Чтобы повесить обработчики на все элементы ".ad-append a", которые появятся на странице, достаточно:
    $(function(){
      $(document).on("click", ".ad-append a", function(e) {
        e.preventDefault();
        console.log("okay");
      });
    });
    Ответ написан
    3 комментария