• В чем разница между многопоточностью, многозадачностью и многопроцессовостью?

    @xfg
    sugadu: так не бывает, если кто-то уже работает с участком памяти, остальные будут ждать, пока с этого участка памяти не будет снят лок (блокировка), который обязательно ставится прежде чем начать работу с этим участком памяти.
  • Что выбрать для углубления знаний (backend)?

    @xfg
    В третьих WASM уже есть как пару лет

    Где он есть? Его стандарт еще проектируется webassembly.github.io/. Он есть только в эксперементальных сборках браузеров.
    JS же семимильными шагами поёт.

    es3 - 1999 год
    es5 - 2009 год
    es6 - 2015 год
    Ну да. Развивается прям со скоростью света.
  • Что выбрать для углубления знаний (backend)?

    @xfg
    Иван: так идея в том, что писать можно будет на любом языке и у JS больше не будет монополии на фронтенд, как сейчас. Но в первую очередь это делают для производительности, чтобы приблизить веб к десктопу, потому что сейчас многое, что делают на десктопе является затруднительным в вебе. И wasm призван исправить это и дать наконец разработчикам делать в вебе всё что только можно себе вообразить.

    Я бы не сказал, что JS простой, скорее наоборот. На нем очень легко писать спаггети-код. Я не видел ни одного фреймворка в JS который позволял бы писать независимую от этого самого фреймворка бизнес-логику. Везде пишут простыни кода, где всё что угодно может вызывать всё что угодно. Сам пишу на JS/node.js, но пришел в него из других языков где культура кода повыше.
  • Что выбрать для углубления знаний (backend)?

    @xfg
    sugadu: если с чем-то не согласен то пиши развернуто.
  • Что выбрать для углубления знаний (backend)?

    @xfg
    Вам стоит обязательно ознакомиться с
    https://en.wikipedia.org/wiki/Asm.js
    https://en.wikipedia.org/wiki/WebAssembly

    для того чтобы понять, что js врядли что-то захватит. Сейчас уже можно компилить C/C++ код в asm.js и запускать в браузере. Так что смотри как бы php не захватил client side :)
  • PHP Websocket оповещение о новой записи в базе данных mysql, как реализовать?

    @xfg
    BoShurik: чтобы понять, что никакой true асинхронности не существует в компьютер сайнс, достаточно почитать как работает процессор компьютера :)
  • PHP Websocket оповещение о новой записи в базе данных mysql, как реализовать?

    @xfg
    BoShurik: не обязательно, reactphp это просто асинхронная платформа. Этот тренд появился с момента появления nodejs. Но есть и другие варианты. Например в сетевых десктоп приложениях (игры например) очень развит подход с воркерами (дочерние процессы или треды), как в веб сервере apache, т.е. только master процесс является асинхронным и отвечает за коннект клиентов и прием запросов от этих клиентов, а далее отдает воркеру, который работает в обычном синхронном режиме. Если все воркеры сейчас заняты, то ставит запрос в очередь на обработку.

    По большему счету все эти асинхронные платформы работают также, просто это скрыто от пользователя. Ибо магии не бывает, и на каком-то уровне все равно нужно создать дочерний процесс/тред для обработки запроса. Так что внутри какого-нибудь event loop те же дочерние процессы https://developer.gnome.org/glib/stable/glib-The-M...
    Вот и всё. Но все относятся к nodejs, reactphp и т.д. как к какой-то магии :(
  • PHP Websocket оповещение о новой записи в базе данных mysql, как реализовать?

    @xfg
    Mr_Romanov: да ws устраняет проблему request-response на уровне браузера и приложения, но эта же проблема всё еще остается на уровне приложения и базы данных. Фактически переходит перекладывание poll-решений с уровня "браузер - приложение", на уровень "приложение - база данных". Заявленный как realtime фреймворк Meteor по сути так и работает, на поллинге базы и прослушивании лога репликации.

    Но realtime db уже появляются, яркий представитель rethinkdb. Там сейчас конечно много еще чего нет, например транзакций или realtime join запросов, но разработчики обещают со временем всё добавить.

    Еще как альтернатива поллингу, теоретически при insert/update/delete можно было бы руками посылать нужные данные по ws своим клиентам. На практике , если проект сложный то это становится трудно поддерживать, так как быстро выясняется, что от одного update запроса может зависеть куча различных событий и все эти события нужно послать клиенту.

    В общем идеальных решений для realtime web пока нет.
  • Где найти готовые шаблоны баз данных?

    @xfg
    FireGM: но нормализация же не всегда подходит. Она отлично подходит для актуальных данных, но с ней начинается беда, как только появляется требование хранить историю чего-либо. Например хранить все сообщения пользователя, который уже давным давно был удален из базы данных.
  • Как работать в git + mysql?

    @xfg
    beginer123: ведется история миграций, те миграции, которые уже были применены к базе повторно накатываться не будут, только новые. Если с вашего последнего вызова git pull появилось 2 новые миграции, то когда вы в следующий раз сделаете git pull и затем запустите консольную утилиту, которая накатывает миграции, то только эти 2 миграции будут применены к базе.

    Поэтому не стоит изменять миграции, которые уже были опубликованы в основной репозиторий, так как это может сломать проект у других разработчиков. Лучше создать новую.
  • Почему на node.js до сих пор нету фреймворка уровня symfony или zend?

    @xfg
    отработал - умер.

    Что будете делать, когда вам понадобятся долгоживущие соединения? Например websocket? Тогда вам в любом случае придется писать демон, хоть на php, хоть на node.js или еще на чем. И в таком случае на php можно будет точно также наплодить утечек памяти, как и на ноде. Никакой разницы.
  • GIT как правильно пользоваться?

    @xfg
    Да, на vps репозиторий создавать не нужно.
    Можно как угодно закидывать, но вообще да git clone на тестовый сервер, но для этого не нужно создавать никаких доп репозиториев, просто git clone, затем сборка проекта, затем тесты. На следующей итерации опять git clone, сборка, тесты и т.д.

    Лучше почитать об инструментах непрерывной интеграции, тогда понятнее будет, каким образом код перемещается из VCS на тестовый сервер. Всё же это уже немного другая тема.
  • GIT как правильно пользоваться?

    @xfg
    По миграциям - верно.

    По шагам не совсем верно.

    1. Кто-то один создает у себя первоначальную директорию с проектом.
    2. Переходит в коносле в директорию проекта и инициализирует новый репозиторий командой git init.

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

    3. Заходим на гитхаб и создаем новый репозиторий.
    4. Подключаем только что созданный удаленный репозиторий к нашему локальному репозиторию командой git remote add origin git@github.com:user/repo.git (user и репо repo заменить на свои разумеется)
    5. Если в локальном репозитории уже есть коммиты, то можно отправить все изменения в удаленный репозиторий командой git push -u origin master
    6. Сокомандники форкают репозиторий через сайт гитхаба и клонируют форк себе на машину командой git clone git@github.com:user/repo.git
    7. Сокомандники создают фичу-ветку и пишут в ней код фичи.
    8. Сокомандники пушат изменения в удаленный репозиторий (форк).
    9. Сокомандники через сайт гитхаба делают пулл риквест в основной репозиторий.
    10. Вы и ваши сокомандники обсуждаете пулл риквест
    11. Вы через сайт гитхаба мержите пулл риквест в основной репозиторий или отменяете пулл риквест если посчитали что он не достоин быть в основном репозитории.
    12. Если вы смержили пулл риквест на 11 шаге, то теперь у вас в основном репозитории будет фича ветка и master ветка. Вы мержите фичу ветку с веткой master, а затем удаляете фичу ветку, так как она больше не нужна.
    13. Пьете пиво и ждете новых пулл риквестов от ваших сокомандников.

    Это и есть Github Flow.

    По поводу веток нет, не n+1, где n - количество разработчиков, а n+1, где n - это количество фич, которые сейчас разрабатываются. Сколько фич сейчас, столько и веток. Сделали фичу - удалили ветку. Не сделали фичу (надоело/потеряло актуальность и т.д.) - удалили ветку.


    Т.е у нас должно быть 4 репозитория?
    1. Локальный
    2.Гитхаб
    3.Тестовый
    4.Главный сайт

    Нет. У вас будет только локальный репозиторий и удаленный (гитхтаб/битбакет/свой сервер и т.д.).

    3 и 4 это не репозитории. Это ваши сайты (билды). Сайты(билды) собирают из репозиториев. Это можно делать как руками, так и автоматизировать этот процесс.

    Если вы используете Continuous integration, то тогда примерно это выглядит так.

    1. Ваш тестовый CI сервер получает исходный код из репозитория
    2. Собирает проект (ваш сайт) из репозитория.
    3. Запускает тесты.
    4. Если все тесты успешно прошли, то разворачивает проект на продакшн сервера (то что вы называете "готовый сайт"). Если нет, то не разворачивает.
    5. Отправляет отчет о тестировании.

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

    @xfg
    As of 2011, personal computers typically have 24-bit (TrueColor) and the use of "web-safe" colors has fallen into practical disuse.

    Так что можно забыть про безопасные цвета, сейчас все современные девайсы передают 16 млн. цветов, а глаз юзера может воспринимать только 10 млн. цветов. А допотопные девайсы сгладят цвета, чтобы попасть в палитру.
  • Проблемы с Роскомнадзором, нужен IT-юрист?

    @xfg
    О том, что камеры, которые используются гос. структурами сертифицируются и регистрируются, в то время как видеорегистратор это бытовой прибор. Запись с такого устройства точно не будет рассмотрено как доказательство по уголовному делу, максимум по административному и то далеко не во всех случаях, к такой записи будет много вопросов, совпадает ли дата съемки с датой произошедшего события, действительно ли запись велась из этого автомобиля, является ли запись подлиной и прочее. Более того, даже если запись с видеорегистратора рассмотрят, то это будет не более чем косвенное доказательство. Любой опытный юрист сделает так, что такую запись не рассмотрят даже как косвенное доказательство.

    Поэтому не нужно сравнивать запись с бытового прибора и с сертифицированного устройства. Разные вещи.
  • Проблемы с Роскомнадзором, нужен IT-юрист?

    @xfg
    Ну да, как обычно, сначала в СМИ трубят о терроризме, педофилии, мятежах, а затем принимают законы ограничивающие свободы людей под предлогом защиты населения. Достаточно в начале убедить большинство, что им это необходимо, а дальше делай что хочешь, блокируй что хочешь.
  • Проблемы с Роскомнадзором, нужен IT-юрист?

    @xfg
    Запись с камер более весомый аргумент в суде, чем запись с ютуба, которую могут вообще не принять к рассмотрению и любой юрист сразу же поставит такую запись под сомнение. Поэтому скрывать смысл есть.
  • Как правильно масштабировать nodejs-приложение с помощью cluster?

    @xfg
    https://nodejs.org/dist/latest-v6.x/docs/api/clust... там где server.listen просто пишите cluster.worker.id получите id текущего воркера
  • Как правильно масштабировать nodejs-приложение с помощью cluster?

    @xfg
    Alexander K.: вроде в доках речь не о pid, а о id https://nodejs.org/dist/latest-v6.x/docs/api/clust... он вроде высчитывается по формуле N+1 для каждого воркера. То есть для твоих 8 воркеров должны быть id 1, 2, 3 ... 8. Даже если я ошибаюсь и id вычисляется иначе, то упорядочить воркеры можно и самому, затем взять за базу например число 6000 и прибавлять к нему id, в итоге получится номер порта. Ну это так, решение за 10 секунд, можно еще подумать.

    На будущее может имеет смысл подумать о таких решениях, как передача базового числа как аргумента при запуске приложения из консоли, чтобы избежать конфликта когда приложение будет запускаться на 2+ серверах.
    node server.js -p 6000
    Сейчас только ради теста это делать конечно бессмысленно, но вообще стоит задумываться всегда, что может случиться в будущем и примерно хоть понимать как буду решать.
  • Как правильно масштабировать nodejs-приложение с помощью cluster?

    @xfg
    Alexander K.: а лучше попробуй для начала оставить всё как было, но попробуй для дебага вот это вот всё вынести на top level
    var app = require('config/application');    //express
    app.set('port', _G.cfg.port);
    var server = http.createServer(app);
    var io = require('socket')(server);   //socket
    io.adapter(redis({host: _G.cfg.rdb.host, port: _G.cfg.rdb.port}));

    То есть чтобы было вот так
    const log = require("core/lib/log")(module);
    require('globals');
    const cluster = require('cluster');
    const numCPUs = require('os').cpus().length;
    var http = require('http');
    var redis = require('socket.io-redis');
    
    var app = require('config/application');    //express
    app.set('port', _G.cfg.port);
    var server = http.createServer(app);
    var io = require('socket')(server);   //socket
    io.adapter(redis({host: _G.cfg.rdb.host, port: _G.cfg.rdb.port}));
    
    if (cluster.isMaster) {
        var workers = [];
        var spawn = function(i) {
            workers[i] = cluster.fork();
            workers[i].on('exit', function(worker, code, signal) {
                log.info(`respawning worker [${worker.process.pid}]`);
                spawn(i);
            });
        };
    
        for (var i = 0; i < numCPUs; i++) {
            spawn(i);
        }
    }else {
        server.listen(_G.cfg.port,()=>{
            app.set('io', io);
            log.info(`Server listen port: "${server.address().port}"`);
        });
    
        server.on('error', (error) =>{
            if (error.syscall !== 'listen') throw error;
            switch (error.code) {
                case 'EACCES':
                    console.error(`${_G.cfg.port} requires elevated privileges`);
                    process.exit(1);
                    break;
                case 'EADDRINUSE':
                    console.error(`${_G.cfg.port} is already in use`);
                    process.exit(1);
                    break;
                default:
                    throw error;
            }
        });
    }