• Какие есть книги по расчёту оборудования под инфраструктуру сайта?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Во первых, в связи с быстроменяющимися технологиями такие книги устаревали бы к моменту выхода, так как верстка и написание их занимала бы больше времени чем время между анонсами нового серверного железа.

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

    В третьих - профиль нагрузки у очень похожих приложений может сильно отличаться, в силу специфики приложения.

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

    Как с этим жить?
    Нагрузочное тестирование на спектре нагрузок, аппроксимация роста нагрузки с ростом операций, расчет от текущего железа вверх согласно предсказанному росту нагрузки. Пока ничего умнее не придумали.
    Ответ написан
    Комментировать
  • В какую дружественную страну переехать из России чтобы продолжить работать на Upwork?

    @medlas
    Эритрея, там тепло!
    Ответ написан
    Комментировать
  • Правильно ли я понял принцип инверсии зависимостей?

    @Akela_wolf
    Extreme Programmer
    Главная идея принципа инверсии зависимостей "детали зависят от абстракций, но не абстракции от деталей".
    В приведенном вами примере класс Main зависит от всего: от интерфейса INumberOperation и от обоих классов NumberOperation1, NumberOperation2. То есть тут принцип инверсии зависимостей вообще не работает. Никак.

    Проявляется же он в следующем примере. Пусть у меня есть некая абстрактная логика "прочитай число, выполни над ним операцию, запиши результат". Эта абстрактная логика (потому она и абстрактная) ничего не должна знать ни откуда она читает число, ни какую операцию над ним выполняет, ни куда и как записывает результат. Таким образом, у нас есть модуль, состоящий из
    interface NumberInput {
      int read();
    }
    interface NumberProcessor {
      int process(int a);
    }
    interface NumberOutput {
      void write(int a);
    }
    class Processor {
      private final NumberInput input;  
      private final NumberProcessor processor;
      private final NumberOutput output;
    
      public Processor(NumberInput input, NumberProcessor processor, NumberOutput output) {
        this.input = input;
        this.processor = processor;
        this.output = output;
      }
    
      void process() {
        output.write(processor.process(input.read()));
      }
    }

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

    И наконец функция main, которая будет собирать все это в единое целое. Она самое конкретное что есть в нашей программе, так как она имеет дело с конкретными классами, экземпляры которых она создает. Поэтому она зависит от всех модулей - от модуля абстрактной логики и от модулей с реализациями интерфейсов. И тут принцип инверсии зависимостей тоже соблюдается - деталь (в какой именно конфигурации запускается программа) зависит от абстракции (абстрактная логики и конкретные реализации интерфейсов из которых выбирается именно та, которая будет использована)

    Этот принцип очень хорошо объяснен в книге Р.Мартина "Чистая архитектура", по крайней мере у меня все встало на свои места именно после прочтения этой книги.
    Ответ написан
    1 комментарий
  • Оптимальные конфиги для связки: DigitalOcean(5$) + VestaCP + Wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Веста хоть и самая легкая из CP, но все же жрет ресурсы, а на дроплете за $5 их и так очень мало. Ну а для одного сайта зачем вообще контрольная панель?! Удалите к чертям. Ну или попробуйте объяснить, зачем вам эта панель вообще нужна. Уверен, смысла в ней нет.

    2. На минимальном дроплете надо все делать максимально продуманным и эффективным. Обязательно нужен swap 512Мб или даже 1Гб. Nginx, желательно последний mainline. PHP5-FPM с Opcache, для Opcache необходимо выделить 32Мб. Если сайтов больше чем 1 - возможно придется увеличить до 64Мб. Вместо MySQL ставим MariaDB. Обязательно ставим Memcached, php5-memcached (c буквой "d" в конце), ему даем 64-128Мб памяти. В WordPress устанавливаем плагин Memcached Redux (только внимательно читаем как его устанавливать - вместо активации плагина надо скопировать файл в wp-content). Это включит persistent object cache на уровне WordPress, большинство запросов вообще перестанет доходить до БД, а это самое узкое место на минимальном дроплете. Кроме того, если уж делать все серьезно, ставим плагин FFPC (Fast Full Page Cache), он позволит кешировать страницы целиком, а чуть поковырявшись с конфигами, можно кешировать страницы в Memcached (то есть в память), и отдавать их оттуда непосредственно Nginx'ом, даже не поднимая PHP-процесс, и уж тем более не касаясь базы данных. Объем памяти для Memcached, возможно, придется увеличивать - все зависит от объема сайта. Но при таком подходе вы получите очень высокую скорость отклика от своего маленького сервера, и он сможет выдерживать очень большие нагрузки. С полностью кешированным в память сайтом и отдачей Nginx'ом непосредственно из Memcached, а также с оптимизированным кодом и файлами (минификация и конкатенация скриптов и стилей, gzip, оптимизированные картинки и т.д., минимизация количества запросов и т.п.) данный дроплет за $5 сможет обслуживать и 50 000 просмотров в сутки. А это уже 1 500 000 в месяц. Даже пиковые 1-2-3 тысячи запросов (что будет крайне редко, если будет вообще) за короткий промежуток времени ("хабраэффект") пройдут еле-еле заметно - даже если начнет использоваться swap, на SSD-дисках он быстр. В итоге часть клиентов будут испытывать небольшие задержки, не более. Но это речь об одновременной тысяче посетителей на сайте, не меньше. К тому времени, как аудитория сайта дорастет до этого уровня, уверен вы уже перейдете хотя бы на дроплет за $10. А там ресурсов больше, при аналогичном подходе этот дроплет выдержит намного больше.
    Ответ написан
    5 комментариев
  • Как тестировать NestJS?

    meowto16
    @meowto16
    Делаю штуки
    Если говорить о юнит тестах:

    Контроллеры - тестим, что отдаются верные статус-коды и дергаются нужные сервисы. Можно проверять ответ, можно проверять валидацию параметров

    Сервисы - удобнее тестить когда используется паттерн с репозиторием, а в сервисе зашивается лишь бизнес-логика без обращения к БД.
    Просто тестируем бизнес-логику зашитую в сервисе, имплементация репозитория/ORM мокается.

    Если говорить о e2e тестах:

    Можно использовать supertest. Как и в остальных языках/фреймворках - создается тестовая база, забивается различными необходимыми для теста данными (с помощью фабрик, фикстур). В тестах идет прямое обращение к эндпоинтам и сравнивается результат, будто бы мы тестили это вручную в swagger'е
    Ответ написан
    Комментировать
  • Единый микросервис для сбора/хранения всех логов, правильно ли это?

    saboteur_kiev
    @saboteur_kiev
    software engineer
    1 вариант: Все логи отправляются в один микросервис.

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

    А вот как это делать - уже разные варианты есть.

    Ваше приложение может писать в stdout, и если вы пользуетесь чем-то вроде kubernetes/openshift, то это удобно ловить централизировано сразу на кластере, тегировать по имени приложения/пода и отправлять дальше.

    Ваше приложение может напрямую писать логи в какой-нибудь logstash, который все собирает парсит и отправляет дальше

    Ваше приложение может писать логи в брокер сообщений, из которого уже логи попадают в аггрегатор. Полезно если бывают очень большие пики логов и есть вероятность, что аггрегатор может в какой-то момент не справитьcя и часть потеряется - тогда какой-нить kafka/rabbitmq как раз будет промежуточным буффером, который гарантировано примет все логи, сколько бы их ни было и передаст их дальше со скоростью, которая комфортна для вашего лог аггрегатора (масштабировать брокер проще, чем аггрегатор)

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

    Ваше приложение может писать просто в лог файлы, а потом эти лог файлы собираются, парсятся, отправляются в лог аггрегатор.

    В общем на любой вкус и цвет. Определитесь с объемом логов, с пиковыми моментами, с тем что вы хотите делать и сделайте общий стандарт для всех ваших компонентов.

    2 вариант: Каждый микросервис пишет собственные логи в своем хранилище.

    Ну можно и так.
    Ответ написан
    2 комментария
  • Стоит ли покупать mac mini?

    RAFAILgaley
    @RAFAILgaley
    MacMini 16gb/512gb m1 - супер конфиг
    бери не сомневайся

    и не забывай - писи и виндос это страдание
    выбор писи может быть оправдан только если у тебя нет денег на мак про, но нужна такая же конская производительность с дорогущими видеокартами

    для твоих задач миника хватит точно
    https://browser.geekbench.com/macs/mac-mini-late-2020
    и легко продать сможешь чрез пять-десять лет
    Ответ написан
    3 комментария
  • Что означает "!!~"?

    E1ON
    @E1ON Куратор тега JavaScript
    Programming, Gamedev, VR
    https://developer.mozilla.org/en-US/docs/Web/JavaS...

    ~ Заменяет каждый бит операнда на противоположный.
    !! (Логическое НЕ) Возвращает false, если операнд может быть преобразован в true; в противном случае возвращает true.
    Ответ написан
    2 комментария
  • Что означает "!!~"?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сокращалка, удобная для indexOf(), который возвращает -1 если не найдено, или индекс от 0 и больше.

    Для логики приложения часто бывает нужно узнать только, найдено или нет: т.е. -1 или иное значение. Можно просто сравнивать if (a.indexOf(b) > -1) { /* найдено! */ } но иногда хочется короче.

    Битовый оператор НЕ ~ хорош тем, что выделяет -1: только -1 с этим оператором даст 0. Прочие числа дадут какое-то ненулевое значение.

    ~(-1) === 0

    Остаётся привести значение из численного в булево. Для этого два воскл. знака — два логических НЕ.
    • для варианта «найдено» из числа от 0 и больше получилось тоже ненулевое число, и !! даст true
    • для варианта «не найдено» из -1 получится уникальный 0, и !!0 вернёт false
    Ответ написан
    4 комментария
  • Приоритет в асинхронном коде, как это работает?

    Alexandroppolus
    @Alexandroppolus
    кодир
    1) Просто вызов: оба хендлера последовательно запускаются в одном и том же синхронном коде (в текущем таске), ставят в очередь 2 микротаска.

    2) Через клик: на каждый хендлер создается отдельный таск в event-loop, таски отрабатывают по очереди, каждый из тасков создает по одному микротаску, последний выполняется до перехода управления к след. таску.
    Ответ написан
    Комментировать
  • В чем суть такой записи в reset.css?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Это разные по сути объявления.
    content: ""; - задаёт содержимое псевдоэлемента (пустую строку)
    content: none; - говорит, что псевдоэлемент вообще не генерируется
    Ответ написан
    2 комментария
  • В чем суть такой записи в reset.css?

    nowm
    @nowm
    Это специфичное для blockquote определение, которое Eric Meyer (автор reset.css) позаимствовал у Paul Chaplin. Первая строка content: "" делает так, чтобы у blockquote исчезли кавычки — на случай, если вторая строка content: none не поддерживается браузером, потому что первая строка — это CSS 2, а вторая — это CSS 2.1. В одну строку их записать нельзя, потому что по стандарту для свойства «content» нельзя комбинировать ключевые слова «normal» и «none» с другими значениями.

    Вообще, когда встречается перечисление одного и того же свойства с разными значениями, это делается для того, чтобы обеспечить совместимость с разными браузерами. То есть, если, например, браузер не поддерживает «content: none», он применит «content: ""», а другую запись проигнорирует.

    Обычно дублирующие записи располагаются в определённом порядке. Первой записью идёт самый плохой вариант, который должен сработать везде. Затем идёт вариант, который более полно описывает вашу цель. Пример:

    .some-class {
        background: #e66465;
        background: linear-gradient(#e66465, #9198e5);
    }


    В этом коде, если браузер поддерживает градиентный фон, он сначала прочитает, что нужно использовать цвет «#e66465», а потом это перезапишется записью «linear-gradient», и итоговое значение будет «linear-gradient(#e66465, #9198e5);». Если же браузер не поддерживает градиент, он сначала прочитает, что нужно использовать «#e66465», а потом увидит неподдерживаемое определение «linear-gradient», проигнорирует его, и итоговое значение будет «#e66465».
    Ответ написан
    Комментировать
  • Какие есть CMS, аналогичные Wordpress, с возможностью писать фронт на vue?

    bootd
    @bootd
    Гугли и ты откроешь врата знаний!
    Зачем искать, если wp и так умеет rest api
    Ответ написан
    4 комментария
  • Действительно ли закончилось свободное место?

    SagePtr
    @SagePtr
    Еда - это святое
    А inode случаем не закончились? df -i что говорит?
    Ответ написан
    2 комментария
  • Рефакторинг кода. Как оптимизировать количество if?

    @rPman
    Вместо if в таких случаях используют switch case.

    Альтернатива - определи map с ключом твои сравниваемые значения и значением делегат Func или экземпляр класса с виртуальным методом. Но что бы ты не делал, синтаксически это не добавит тебе простоты, а просто переместит в другое место определение кода и сравниваемое значение.

    Есть еще препроцессор #if или даже собственный кодогенератор, иногда оно оправдано.

    Городить что то сложнее switch нужно, когда логика, стоящая внутри кода около каждого из вариантов значения, может быть свернута в общий единый код или наоборот, он весь сводится к коротким инструкциям,красиво смотрящимся в виде анонимных функций, которые неплохо смотрятся в виде констант иннициализатора map
    Ответ написан
    Комментировать
  • Стоит ли идти в NoCode разработку?

    saboteur_kiev
    @saboteur_kiev Куратор тега Карьера в IT
    software engineer
    NoCode это инструменты для тех, кто не умеет кодить, но готов потратить немного времени чтобы сделать какую-то штуку сам для себя.
    Специалисты по NoCode не нужны вообще.
    Если кто-то сделал свой "бизнес" и решил сделать себе сайт-визитку, то благодаря NoCode, не особо криворуким рукам и невысоким требованиям к конечному результату, он сможет сам ее себе сделать в одном из тысяч конструкторов.
    Но такому бизнесмену ты вообще не нужен.

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

    inoise
    @inoise Куратор тега Карьера в IT
    Solution Architect, AWS Certified, Serverless
    No code это не разработка
    Ответ написан
    Комментировать
  • Стоит ли идти в NoCode разработку?

    BorLaze
    @BorLaze
    Java developer
    Как бы вайти в айти, но так, чтобы не учить ничего по айти?
    Ответ написан
    Комментировать
  • Как правильно получить промис?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    А кто будет ждать асинхронное действие?
    @Controller()
    @Get('/dashboard')
    @Render ('dashboard')
        async getDashboard () {
            const sites = await this.usersSitesService.selectSitesByUserId(1);
    
            return { sites };
        }


    selectSitesByUserId =  async (id: number): Promise<any>
    Какой смысл в тайпскрипте, если писать any?

    Репо с докой router-controller https://github-com.translate.goog/typestack/routin...
    Ссылка на машинный перевод? Вы это серьезно?
    Ответ написан
    2 комментария