• Какие есть it-профессии, где не нужно писать код?

    @xfg
    Тестировщик, архитектор програмнного обеспечения, администратор баз данных, менеджер проектов, контент-менеджер, специалист тех. поддержки.
    Ответ написан
  • Как обезопасить свой бекенд от разработчиков?

    @xfg
    Удалить может и пользователь используя уязвимость. Вообще в этом мире существуют бекапы, а так неплохо бы код ревью делать. Никакие изменения не мержатся пока их не подтвердят два других разработчика. Не для того чтобы обезопаситься, а чтобы спагетти-код не проходил. Это в интересах разработчиков. Им же возможно в будущем придется разбираться в этой лапше. Поэтому проще сразу отклонить.

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

    Если у вас всё делает один человек, а вы только создаете видимость работы, то конечно он вас кинет если будет прибыль. Сколько уже видел таких ламерских проектов. Пациент нашел раба. Сам ничего не может. Жмет кнопки в админке. Считает, что работает за семерых. Раб везет телегу до поры до времени. Упс, а у пациента даже бекапов нет. Ибо идиот. Прикольно за этим наблюдать.
    Ответ написан
  • Как работает на низком уровне Node.js и Angular?

    @xfg
    У вас на сервере должен быть запущен постоянно работающий процесс, чтобы обрабатывать входящие запросы от клиентов. На PHP как правило пишут скрипты, которые не висят постоянно в памяти, а выполняются и умирают раз за разом. В таких условиях нужен посредник в виде постоянно работающего процесса. Поэтому вы используете apache, nginx, etc или пользуетесь встроенным php -S localhost:8080 mysite/index.php

    В node.js можно несколько иначе. Скрипты висят в памяти. Чтобы с ними как-то взаимодействовать по сети, вы должны позаботиться об этом самостоятельно и реализовать некий протокол взаимодействия с вашей программой поверх tcp. Это может быть популярный и всем известный http протокол или что-то менее известное или даже придуманное вами.

    Поскольку http протокол довольно популярен, то в node.js предоставили готовую реализацию в виде http модуля, который позволяет написать http сервер в несколько строк.

    Строго говоря, вы это всё можете делать на любом языке, который умеет работать с сетью и PHP здесь не является исключением. Например вот одна из реализаций http сервера на PHP https://github.com/reactphp/http
    Ответ написан
    4 комментария
  • Правильное тестирование Javascript?

    @xfg
    В случае если объект внутри себя инстанциирует другой объект, тогда такой объект должен рассматриваться как единый юнит.

    import LineItem from './LineItem';
    
    class Order {
      constructor(lineItems = []) {
        this.lineItems = lineItems;
      }
      addLineItem(name, cost, quantity) {
        this.lineItems.push(new LineItem(name, cost, quantity));
      }
    }


    В этом случае писать юнит-тест необходимо на класс Order. Необходимости в тестировании класса LineItem нет, так как он является составной частью класса Order. Такие классы носят название - Агрегат. Когда автосалон вас приглашает на тест-драйв автомобиля, то это предполагает тестирование Агрегата в целом, то есть Автомобиля. Тестировать отдельно составные его части такие как колеса/двигатель мы не будем.

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

    class Route {...}
    class Ship {
      addRoute(route) {
       if (!(route instanceof Route)) {
         throw new Error('route must be instance of Route');
       }
        this.route = route;
      }
      ...
    }


    В этом случае необходимо писать отдельные юнит-тесты на Route и на Ship. Чтобы написать юнит-тест на класс Ship его необходимо изолировать от класса Route с помощью мок-объекта.

    Интеграционный тест подразумевает, что вы не будете подменять Route на мок-объект, чтобы протестировать класс Ship. Вместо это необходимо передать настоящую реализацию класса Route. В таком случае мы протестируем взаимодействие между двумя юнитами Ship и Route.
    Ответ написан
  • Для чего идеальна MongoDb? Примеры приложений, где монга будет лучше mysql?

    @xfg
    Высокопроизводительные распределенные интернет-приложения. Конкретные примеры: amazon.com, netflix.com, ebay.com. NoSQL движение возникло как ответ на проблемы масштабируемости. Реляционные базы ориентируются на требования ACID и как следствие имеют проблемы с горизонтальным масштабированием. Для таких баз необходимо реализовывать шардинг на уровне приложения. Но тогда будет необходимо отказаться от ACID, объединения таблиц и контроля целостности. В таком случае реляционная база теряет все козыри перед NoSQL. Но оставляет на плечах разработчика заботу о шардинге.

    Интернет забит вопросами о том как жить без транзакций в NoSQL. Но бизнес-процессы в реальной жизни не являются транзакционными. Вы не можете человека, который покушал в вашем ресторане, а теперь отказывается платить по счетам заставить сделать роллбек вашей еды. Фактически посетитель вам бросил эксепшен. И даже если вам удастся извлечь еду из вашего посетителя, то маловероятно, что она будет готова к последующему употреблению. Но можно взыскать с него все затраты через суд и придти таким образом в согласованное состояние. Любому бизнесмену это очевидно. Но программисту нет. Он хочет транзакционно. Но пишет систему для автоматизации бизнес-процессов. Парадокс.
    Ответ написан
    7 комментариев
  • Структурирование исключений. Что вы указываете в качестве exeption code?

    @xfg
    Понял, вас интересует для чего нужно свойство code в исключениях. К сожалению, я так и не смог нагуглить точного описания для чего в php это свойство добавили к исключению и для каких целей php предлагает его использовать сегодня.

    Но я думаю, что так сложилось исторически. В PHP 3 появились самые первые средства для работы с ООП. Не такие мощные и функциональные, какими вы их видите сегодня в PHP 5/7. Тогда механизм исключений в php не позволял добавлять множественные catch блоки. Это не имело смысла, так как в php не существовало возможности типизировать аргументы функций. Соответственно единственная возможность отличить одно исключение от другого внутри блока catch это использовать свойство code. Время прошло, добавили типизацию, множественные catch блоки, а свойство code осталось, как и многое другое в php. Использовать свойство code в настоящее время вряд ли имеет какой-либо смысл.
    Ответ написан
    Комментировать
  • Можно ли сделать интернет-стартап не будучи ИТ-специалистом?

    @xfg
    Конечно можно. На аутсорсинг отдаете эти функции заключив длительный договор с подрядчиком от 1 года. Они делают свою работу, вы свою. Все так и живут.
    Ответ написан
    Комментировать
  • Как Вы задаете правила для пользователей?

    @xfg
    Раньше RBAC был. Модуль искал в файлах с контроллерами все экшены и отображал в виде списка. Чекбоксами отмечали для каких экшенов сгенерировать права. Дальше права назначались на роль. Роли на пользователей. В коде прежде чем запустить любой экшен был хук, который проверял есть ли у роли право с названием "модуль:контроллер:экшен". Есть - выполняем. Нет - 403 Forbidden.

    Была куча проблем. И вообще позже заметили, что назначаем права один раз и больше никто ничего не меняет. Потому что все эти права это бизнес-логика нашего приложения. Мы же не cms делаем и не нужно пытаться выносить эти правила из кода в веб-интерфейс. Меняются бизнес-правила - меняется код. Теперь всё проще. Мы пишем мидлвары например аутентифицирован/заблокирован и т.д. Мидлвары просто вешаются на нужный экшен и передают управление друг другу по цепочке до самого экшена и каждый из мидлваров может зарубить запрос. Это оказалось гибче, проще и удобнее, чем тыкать сотни чекбоксов в веб интерфейсе ведь в мидлваре можно написать абсолютно любой код. Потому что не бывает так, что вам надо сегодня заблокированным запретить комментировать фото, завтра разрешить, а послезавтра снова запретить. Даже если надо, то мы напишем соответствующий мидлвар, повесим на экшен и выкатим в продакшен, а не будем тыкать каждый день чекбоксы в малопонятном веб-интерфейсе прав доступа. Тем более заказчик всё равно не понимал, что это за чушь NewsModule:NewsController:addAction сколько бы ему не объясняли, что это название разрешения на добавление новостей, а нотация указывает для какого модуля, контроллера и экшена, а названия разрешений такие убогие, потому что генерируются автоматически из исходного кода. У него взрывалась голова и он говорил, ладно ребята, надо будет поменять, я вам наберу :)
    Ответ написан
    Комментировать
  • Что почитать и на чем потренироваться, не могу перейти от процедурного к ооп?

    @xfg
    Ну это очень просто. Объект - это сущность, которая имеет некое состояние и поведение, через которое это состояние можно изменить. Объект может содержать в себе другие объекты, тогда это принято называть агрегатом.

    Скажем вы пишите софт для компании по грузоперевозкам. У компании наверняка как минимум есть автомобиль и есть груз. Груз можно поместить в автомобиль. Поместить объем груза больше объема вместительности автомобиля невозможно.

    Можно смоделировать этот пример допустим на php (синтаксис может быть некорректен!) таким образом
    (свойства объектов желательно делать приватными с доступом через геттеры, чтобы состояние объекта было невозможно изменить вне его. Опущено, ради упрощения).
    class Car {
      public $id;
      public $capacity;
      public $payload;
    
      public function __construct(int $id, int $capacity, array $payload) {
        $this->id = $id;
        $this->capacity = $capacity;
        $this->payload = $payload;
      }
      public function assignCargo(Cargo $cargo) {
        if ($cargo->volume + $this->calculateOccupiedCapacity() > $this->capacity) {
          throw new DomainException('The capacity has been exceeded.');
        }
        $this->payload[] = $cargo;
      }
      private function calculateOccupiedCapacity() {
        return array_reduce($this->payload, function($accumulator, $cargo) {
          return $accumulator += $cargo->volume
        });
      }
    }
    
    class Cargo {
      public $volume;
      
      public function __construct($volume) {
        $this->volume = $volume;
      }
    }

    Должно быть понято что примерно происходит даже человеку из бизнеса. Берем автомобиль и пытаемся его загрузить. Если автомобиль заполнен до предела, система сообщает об этом. Примерно так и создается модель реального бизнеса с помощью объектно-ориентированного проектирования.

    Гораздо сложнее с инфраструктурой. Автомобиль хотелось бы сохранять в хранилище, извлекать его оттуда и до загружать его. Здесь начинаются проблемы вроде impedance mismatch. Затем наверняка изменение одного объекта, будет влиять на состояние другого и нужно будет выстраивать систему для работы с доменными событиями. И много всего такого. Но это уже про инфраструктуру. Саму бизнес-модель спроектировать как объектно-ориентированную не является уж совсем чем-то запредельно сложным. Достаточно помнить, что это должны быть по возможности plain php object, которые не зависят от стороннего кода фреймворков и библиотек. В этом случае бизнес-модель можно будет запустить на любом фреймворке/окружении.

    Почитать можно что-нибудь про многоуровневую архитектуру. В контексте Java много пишут об этом. В книге Implementing domain-driven design автор хорошо рассказывает про все уровни приложения и о том, как они взаимодействуют друг с другом.
    Ответ написан
    Комментировать
  • Что есть исключения?

    @xfg
    Исключение - это отклонение от нормы. Оно всегда будет. Всего не предусмотреть. Вы можете сделать исключения для Unprocessable, Forbidden, NotFound.
    Написать обработчик, который ловит все необработанные исключения и конвертирует Unprocessable в HTTP 422, Forbidden в HTTP 403, Not Found в HTTP 404, а все остальное в HTTP 500.

    О проблемах с сетью клиента уведомлять не надо. Таких технических проблем могут быть сотни и тысячи. Когда они возникнут, ваше приложение итак по очевидным причинам не сможет обработать запрос и упадет с исключением/ошибкой. Вам лишь надо, чтобы исключение/ошибка провалилась в обработчик и превратилась в 500 Internal Server Error. О большем клиенту знать не зачем.
    Ответ написан
    Комментировать
  • Поясните как реализовать личные сообщения по вебсокету?

    @xfg
    1. Пользователь устанавливает вебсокет соединение с сервером.
    2. Пользователь пробует добавить сообщение в чат. Отправляет запрос:
    {id: 1, action: 'chat:add', params: {chat_id: 1}}
    3. Сервер присылает ответ
    {id: 1, error: 'Not authenticated'}
    4. Пользователь отправляет
    {id: 2, action: 'user:login', params: {email: 'test@me', password: 'qwerty'}}

    5. Сервер отвечает
    {id: 2, data: {token: '123456'}}
    6. Пользователь повторяет пункт 2. Сервер отправляет пользователю успешный ответ, а его собеседника уведомляет новым личным сообщением.

    Это грубо. В целом, ты работаешь почти также как и с HTTP. В формате запрос -> ответ. Отличие только в том, что вместе с ответом на запрос, иногда нужно будет уведомлять других пользователей о произошедшем событии.

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

    @xfg
    Екатеринбург, УрГУПС, электротехнический факультет, специальность информационные технологии (ИТ). Сам там учился, пока не выгнали за прогулы и плохую успеваемость. Программирование преподавали. Базы данных. Но мало. Больше было всякой разной математики.
    Ответ написан
  • Тупиковое и медленное развитие, лекарство?

    @xfg
    Полутора миллионник в России. Найти человека, который бы знал что-то о многоуровневой архитектуре или ddd среди тех, кто идет на вакансию PHP/Python/Ruby программист, крайне трудная задача. Из 100 придут 99 сеньоров по 20-25 лет каждому с умением отгружать спагетти на очередном крутом фреймворке. Найти хорошего фуллстек разработчика вообще за гранью фантастики.

    Видел я таких, которые через месяц выкатывают в продакшн. Всё работает на честном слове, без тестов, без solid, без grasp, без паттернов, без архитектуры в конце концов.

    - Как нам убедиться, что ваш код работает как ожидается?
    - Бля буду работает!

    - Как работает Event loop в Javascript ?
    - Что это?
    Ответ написан
    Комментировать
  • Кому принадлежат симкарты?

    @xfg
    Симкарты оформляются на юридическое лицо. Компания получает тысячи симкарт. Затем продает их не обременяя покупателя переоформлением. Барыги покупают у таких компаний симкарты оптом примерно по 15руб/шт. Но если хочешь войти в подобный бизнес, то не забудь взять с собой аргумент ввиде ак-47, когда пойдешь на вокзал. Правил нет. Чеков тоже. Не успеешь ничего продать, как проломят голову или подойдут полицейские, которые всегда там прикормленные где-нибудь за углом и будет статья 14.1 КоАП осуществление предпринимательской деятельности без государственной регистрации.
    Ответ написан
  • Идеальная база данных для хранения большого числа уникальных строк?

    @xfg
    Можете посмотреть еще https://ru.wikipedia.org/wiki/HBase
    Ответ написан
    Комментировать
  • Создание прототипа серверной игры?

    @xfg
    Необходимо, чтобы сервер учитывал время сетевой задержки (latency). Для этого на стороне сервера необходимо создать timestamp и вычесть latency, чтобы получить реальное время нажатия кнопки клиентом. Далее остается сравнить таймштампы двух игроков и выявить победителя. Без учета latency тот у кого короче маршрут следования пакета, тот и в приоритете. Можете почитать о проблемах сетевых реалтайм игр, там обо этом есть.
    Ответ написан
    Комментировать
  • Как правильно настраивать дев-окружение для веб-разработки?

    @xfg
    Не думайте о доменах. Вы смешали администрирование и программирование. Не нужно никакого dev сервера. Делайте работу на локальной dev машине, отправляйте изменения в удаленный репозиторий и всё. Можете вообще не устанавливать nginx/apache и т.д. на локальную dev машину, чтобы не забивать голову всякими доменами, а проект запускать под встроенным PHP сервером например из корня проекта и тогда будете обращаться к вашим сервисам по адресу localhost:port/service1/index.php, localhost:port/service2/index.php и т.д.

    Домены будете создавать уже на продакшене. В простейшем случае склонируете на продакшн машину удаленный репозиторий проекта и в конфигах nginx нужно будет написать что-то типа такого

    server {
      server_name company.com;
      root /home/www/company/frontend;
     ...
    }
    server {
      server_name admin.company.com;
      root /home/www/company/backend;
     ...
    }
    server {
      server_name service1.company.com;
      root /home/www/company/service1;
     ...
    }
    server {
      server_name service2.company.com;
      root /home/www/company/service2;
     ...
    }


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

    Так и делают. Разработчикам не нужен никакой dev сервер. Они клонируют репозиторий, делают что-то локально у себя и отправляют изменения в удаленный репозиторий. Для тестеров и всяких менеджеров просто поднимают так называемый stage-сервер где они и тестируют приложение, но это тоже самое что и продакшн сервер, просто доступ к нему только внутри компании. Можно настроить continuous integration чтобы все изменения из репозитория в master ветке автоматически бы приводили к деплою приложения на stage и продакшн сервера. Примерно так в общих словах устроена веб разработка.
    Ответ написан
    22 комментария
  • Как реализовать проект от а до я, с созданием сайта, серверной части, мобильных приложений под ios,android и windows phone?

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

    @xfg
    Yii использует алгоритм хеширования blowfish. Чтобы в php получить хеш по этому алгоритму, нужно просто взять функцию crypt и вторым аргументом передать соль в формате$2a$13$6abRKtrd12bvkltrfsorbd

    где
    $2a$ (также может быть $2x$ или $2y$) - указывает на алгоритм блоуфиш.
    13 - сложность алгоритма, может быть от 04 до 31. Чем больше число, тем дольше будет вычисляться хеш.
    6abRKtrd12bvkltrfsorbd - 22 символа для соли.

    Проверить хеш против пароля можно функцией password_verify. Берете хеши, которые вам нагенерил Yii и передаете в функцию password_verify и всё у вас заработает, без проблем. Я с Yii на node.js уезжал с этими хешами, никаких проблем :)

    Все что ниже можно не читать. Там для тех, кому интересно откуда взялось 3 разных префикса ($2a$, $2x$, $2y$).

    Префиксы $2y$ и $2x$ существуют только в PHP, так как они налажали в алгоритме блоуфиш в версиях до 5.3.7. Префикс $2x$ был добавлен для обратной совместимости, т.е. если вы генерили хеши $2a$ в версии PHP до 5.3.7 и теперь обновились до или выше этой версии и хотите, чтобы ваши уже существующие уязвимые хеши продолжали правильно работать, то нужно было заменить у таких хешей префикс с $2a$ на $2x$. Префикс $2y$ это уже исправленный алгоритм хеширования и ничем не отличается от $2a$ в версиях PHP 5.3.7 и выше. Подробнее обо всем этом можно прочитать php.net/security/crypt_blowfish.php

    Yii использует префикс $2y$. Но в спецификации из всех этих префиксов есть только $2a$ и его и нужно использовать, если у вас версия выше или эквивалентна PHP 5.3.7. Так что, если вы избавились от Yii, то можете поменять и префикс у ваших хешей. Потому что, когда я мигрировал на node.js библиотека для блоуфиш хеширования естественно не поддерживала никаких $2y$ и $2x$ и не собиралась этого делать в дальнейшем, так как это не их баги, а PHP, вот пусть PHP с этими префиксами и живет :)
    Ответ написан
    1 комментарий
  • Как монетизируются языки программирования и бесплатные фреймворки?

    @xfg
    Колесят по конференциям и собирают барыши. Книгами барыжат. Много всего.
    Ответ написан
    3 комментария