• Какие библиотеки грамотно составлены, с чего брать пример?

    Nipheris
    @Nipheris Куратор тега C++
    header-only: nlohmann_json
    компилируемая: fmt, zeromq, libuv

    Стоит предупредить, что даже в приличных библиотеках в CMake-скриптах и в целом в инфраструктуре сборки может встречаться жуткая дичь (где-то - из-за необходимости поддержки старых версий CMake, где-то - из-за того что никому нет дела, пока оно работает), поэтому если собираетесь использовать эту сборочную систему, сразу читаем сюда: https://cliutils.gitlab.io/modern-cmake/ . Вот есть неплохой пример структуры проекта.
    Ответ написан
    1 комментарий
  • А существует ли что-то типа Git для БД (MySQL) - мне нужно понять как скрипт меняет содержимое БД не копаясь в самом скрипте?

    Инструмент для вашей задачи - системное версионирование, введённое в SQL:2011, ищите "system-period temporal tables" или "system-versioned tables".

    К сожалению ещё не все СУБД его поддерживают, насчёт MySQL не уверен. А вот MariaDB вроде умела.
    Ответ написан
    1 комментарий
  • Почему при использовании конструкции TryEnter() не запускается второй поток?

    Nipheris
    @Nipheris Куратор тега C#
    Ну видимо потому что второму потоку не удалось захватить блокировку, он пошёл в ветку else и, после вывода сообщения, завершил свою работу, т.к. в теле функции Run больше нет инструкций.

    Странно, что вы это спрашиваете, если писали этот код.
    Ответ написан
    Комментировать
  • А как выглядит настоящее, большое, корпоративное "Энтерпрайз" веб-приложение?


    Это я вам дал примеры БОЛЬШИХ веб-приложений. "Энтерпрайзные" в пример привести сложно, потому что обычно это значит "внутренние" или "ориентированные на конкретный тип бизнеса". Впрочем, какая разница, если речь идёт об оценке сложности.
    Ответ написан
    1 комментарий
  • Почему большой/объемный pull request это плохо (или хорошо)?

    было много ПР в промежуточную ветку, их ревьюила команда, к которой принадлежит разраб который сделал ПР;
    далее эти все коммиты/изменения были объединены в один ПР и он стал похож на страницу с содержанием книги с десятками коммитов, в то же время к ревью подключились разрабы из других комманд и ревью затягивается еще на несколько дней;

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

    Почему вы повторно ревьюите этот же код, ещё и теперь объединённый в один большой ПР? Какой смысл? У вас что-то не так с организацией ответственности.
    Ответ написан
    4 комментария
  • Почему при глобальной установке пакета работает только npm?

    Какая ОС? Результат вызова yarn global bin в PATH добавлен? Если нет, читайте инструкцию по ссылке.
    Ответ написан
    Комментировать
  • Как защититься от двойного списания в многопоточном приложении?

    если проверка прошла, то обе выполнятся

    Кто сказал что СУБД позволит выполнить обе транзакции с одними и теми же исходными данными?
    Если обе транзакции начали исполняться параллельно, прочитали одни и те же данные, и пытаются их перезаписать, как СУБД будет себя вести? Позволит ли она вообще отработать обеим транзакциям? Или одна их них подождёт, пока не закончит работу другая? Вопрос гораздо интереснее, чем кажется. И, что самое главное, неглупые люди уже подумали над ним. Очень хорошо подумали.

    В доках постгреса написано ещё лучше.

    Или лучше каждый раз пересчитыапть из истории?

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

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

    Nipheris
    @Nipheris Куратор тега C#
    Что вы понимаете под "создавать переменные"? Если вы имеете в виду объявление переменных, то это не просто нормальное явление, а рекомендация - если переменная нужна вам только в цикле (а за пределами цикла её видно не будет, т.к. у цикла будет свой scope), то намного лучше, если вы в цикле её и объявите.

    Правило очень простое - держите объявление переменных поближе к месту их использования, а если точнее - то держите переменные в самом вложенном скоупе, насколько это возможно согласно местам их использования.
    Ответ написан
    3 комментария
  • Разница CompareTo() в IComparable и Equals() в IEquatable?

    Nipheris
    @Nipheris Куратор тега C#
    IComparable предназначен для установления отношения порядка между объектами, реализующими этот интерфейс, ну или грубо говоря, для сортировки. Т.е. когда для двух данных объектов А и Б вы можете утверждать, что А < Б ИЛИ А == Б ИЛИ А > Б.

    IEquatable предназначен для установления отношения равенства. Когда для двух данных объектов А и Б вы можете утверждать, что А == Б или А != Б.

    Далеко не для всех типов данных вы хотите и можете устанавливать отношение порядка, в то время как для большинства типов с value-семантикой вы захотите иметь отношение равенства/неравенства. Это настолько частая и необходимая вещь, что записи в C# автоматически реализуют для вас IEquatable.
    Ответ написан
    1 комментарий
  • Писать типы вначале или рассчитывать на вывод типов компилятором?

    Никакой религии в этом вопросе нет и быть не может. Есть вполне конкретные правила, когда писать типы весьма полезно.

    Если вы НЕ указываете тип, и рассчитываете на автовывод, то значит вам нужен не какой-то конкретный тип, а ТАКОЙ ЖЕ, КАК И... где-то ещё. Например, такой-же-как тип константы или такой-же-как тип возвращаемого значения функции. Иными словами, если я пишу:
    const id = findIdByName("abc");
    то мне не так важно, какой конкретно тип будет иметь id, мне важно чтобы это был тип возвращаемого значения функции "findIdByName". Для меня это приоритетно. Более того, если в какой-то момент тип возвращаемого значения у этой функции поменяется, то этот код продолжить компилироваться и, вероятно, даже РАБОТАТЬ (это зависит уже от того, что мы потом собираемся делать с id).

    Совершенно противоположная ситуация - интерфейсы. В широком смысле. Интерфейсы функций, интерфейсы классов, интерфейсы в смысле типов данных, создаваемых с помощью "interface". Особенно если эту функцию/класс/интерфейс использует много кто ещё. Тогда наоборот, вам НЕЛЬЗЯ допустить, чтобы типы параметров или тип возвращаемого значения просто так поменялись. Это вдвойне важно, если вы пишите библиотеку и речь идёт о её публичном интерфейсе - любое изменение интерфейса тогда должно подкрепляться версионированием (например, семантическим). Вы не можете просто так, тем более по недосмотру, вместо числа начать возвращать из функции строку - вы сломаете ваших клиентов, причём даже не знаете как и где.
    Ответ написан
    Комментировать
  • Что значит typename?

    Nipheris
    @Nipheris Куратор тега C++
    1. typename в данном случае нужен компилятору только как подсказка от разработчика, что последующий идентификатор (т.е. std::stack<T>::container_type::iterator) - это действительно имя типа. Подсказка нужна потому, что этот typedef вероятно находится также в шаблоне, и мы ещё не знаем, во что конкретно инстанциируется шаблон std::stack (в этом случае говорят, что container_type "is dependent on a template-parameter" - пока не инстанциируем std::stack, не узнаем).

    2. Member-тип container_type эквивалентен типу нижележащего контейнера (т.к. std::stack - это адаптер под интерфейс стека, а не реальный контейнер, реальный контейнер для хранения вы выбираете вторым параметром шаблона, по-умолчанию это std::deque).

    3. Вот у std::deque<T> итератор действительно есть.
    Ответ написан
    Комментировать
  • Как из вне получить доступ к файлам AWS S3?

    Помимо того, что предложил Андрей Гаврилов , вам ещё нужно при заливке или после заливки объектов выставлять им ACL так, чтобы у группы Everyone (public access) были права Read. Скорее всего, при дефолтных настройках у вас не выставляется это право доступа.
    Ответ написан
    Комментировать
  • Собрать пример CURL-приложения C++11 в MVS2019?

    Nipheris
    @Nipheris Куратор тега C++
    У вас проблемы с линковкой, не настроены или неверно выбраны import-библиотеки или статические библиотеки (зависит от того, как вы планируете линковать libcurl к своему проекту-примеру).
    Также возможно неверно настроены определения комплиятора - некоторые библиотеки требуют задания констант препроцессора при динамической, или наоборот, статической линковке. Например, libcurl требует настройки CURL_STATICLIB при статической линковке.

    Все пакеты установлены из пакетного менеджера VS

    Закопайте эти библиотеки, проект CoApp, который был посвящён идее использовать NuGet для нативных (С/С++) библиотек, умер почти сразу после своего рождения, на границе 2014/2015 годов. Это очень старые версии, к тому же. Практика показала, что NuGet в большинстве случаев не годится для нативных библиотек (не буду расписывать, почему).

    Используйте для C/C++ проектов нормальные пакетные менеджеры вроде Conan или, на худой конец, Vcpkg. Там это всё уже предусмотрено. Впрочем, это не отменяет необходимости понимания простейших ошибок компилятора/линковщика и его основных опций.
    Ответ написан
    1 комментарий
  • Почему сервер не принимает проект?

    Git-сервер не принимает ваш бранч. Там выше не написано, почему это происходит? Может быть Heroku пытается выполнить деплой, но у него не удаётся это сделать, и он отфутболивает бранч?

    Поищите логи какие-то деплойские чтоли, а лучше это всё текстом, а не фотографией.
    Ответ написан
    1 комментарий
  • Create products with color variants?

    Всё дело в понимании предметной области.

    Выходит, что "продукт" в вашем случае - это не один товар, а множество товаров с подобными характеристиками. Вы можете называть "продуктом" то, что выводите на основной странице, а "товаром" - конкретную разновидность продукта, и именно с "товаром" вести ценнобразование, учёт остатков и прочее.

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

    Разумеется, это только один из вариантов решения. И только один из аспектов, т.к. встанет вопрос - как хранить различные поля в описании, немного разные в разных продуктах? Ну и прочее.
    Ответ написан
  • Как ускорить отрисовку изображения на picturebox.image и прочих элементов?

    А вы, показывая одно изображение, сразу грузите следующее (может даже парочку). Не важно - из сети, или с диска, идея одна и та же.

    Попробуйте полистать в виндовом средстве просмотра БЫСТРО - возможно заметите задержку.
    А вообще, раз речь идёт о сети, то у вас отличная возможность ознакомиться с кэшированием.
    Ответ написан
    Комментировать
  • Баг тайпчекинга параметров функции?

    Отличный вопрос.

    Strict function types:
    The stricter checking applies to all function types, except those originating in method or constructor declarations. Methods are excluded specifically to ensure generic classes and interfaces (such as Array) continue to mostly relate covariantly.

    При замене методов на обычные функции сразу появляется ошибка:
    type AFnc = (p: A) => void
    
    function foo(p: A): void { }
    function bar(p: AB): void { }
    
    const f: AFnc = foo;
    const b: AFnc = bar; // не компилируется с сообщением о том, что AB требует ещё и свойство b
    Ответ написан
    3 комментария
  • Как обработать такое исключение с помощью TS?

    const arr1 : [Item, ...Item[]] = [{ title: 'a' }] // OK
    const arr2 : [Item, ...Item[]] = [] // Не скомпилируется

    Playground

    Используя такой tuple-тип вместо обычного массива, вы можете ПОТРЕБОВАТЬ наличия некоторого количества элементов в начале массива.
    Ответ написан
  • Почему конструктор Class ( Class other) { } не может принимать объект своего типа по значению?

    Nipheris
    @Nipheris Куратор тега C++
    Потому что чтобы передать какой-либо агрумент по значению, его нужно скопировать. Чтобы скопировать аргумент, который является объектом класса, нужно вызвать конструктор копирования (неважно, сгенерирован ли он автоматически или вручную написан).

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

    Вроде должно быть понятно.
    Ответ написан
    2 комментария