• Как использовать строку в качестве названия функции в GoLang?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Добро пожаловать в мир компилируемых языков программирования и статической типизации, здесь такое не нужно, считается очень плохой практикой и достижимо только через чёрные ходы, вроде рефлексии, что снижает производительность и безопасность кода, а также усложняет его сопровождение.
    Ответ написан
    Комментировать
  • Как генерировать палитру всех 24бит цветов в изображении размером 4096х4096 чтобы был плавный переход цвета?

    GavriKos
    @GavriKos
    Использовать другие цветовые представления и не последовательную запись. Например, не RGB а HSL, где по X двигать H и S, а по y - L
    Ответ написан
    Комментировать
  • Почему сайт на GitHub Pages выглядит иначе?

    alsolovyev
    @alsolovyev
    ¯\_(ツ)_/¯ Enjoy life, Eat well & Laugh often
    GitHub Pages - это хостинг для статических файлов. Использовать php нельзя. У Вас 3 варианта:
    1. Арендовать свой сервер и использовать на нем PHP
    2. Написать сайт на чистом HTML, CSS, JS и постить на GitHub Pages
    3. Изучить какой статический генератор сайтов (например, Jekyll, Hugo и т.д.). Это похоже на второй вариант, но с автоматизацией рутинных задач (генерация однотипных страниц, заполнение метаданных, использование шаблонов и тд)
    Ответ написан
    Комментировать
  • В чем смысл использования Golang как веб сервер?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    А теперь возьмите не синтетический тест, а реальную задачу сложнее перекладки json'ов, например, с шифрованием, дайте серьëзную длительную нагрузку и посмотрите латентность по процентилям.
    Ответ написан
    Комментировать
  • Как уменьшить вес gif с помощью php?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    GIF использует lzw-сжатие без потерь. Уменьшить размер файла можно только убрав часть информации, то есть уменьшив разрешение изображения или количество цветов.
    Ответ написан
    1 комментарий
  • Какие параматры устройства отслеживает сайт для идентификации пользователя?

    @Refguser
    Решения для бизнеса: от создания ИМ до...
    Какие параматры устройства отслеживает сайт для идентификации пользователя?

    Изучаем фингерпринт

    Это вообще осуществимо, например на линуксе?

    Теоретически можно, но -запаришься- в реальности не нужно. Достаточно поменять или эмулировать другое устройство. А если ещё и с другими UA и IP, то 100%.
    А в конкретном случае может быть достаточно сменить браузер.
    Ответ написан
    Комментировать
  • Как должен выглядеть идеальный контроллер?

    Если хотите идеал, то он должен соответствовать следующим пунктам:

    1. Сериализация/десериализация - это дорогостоящее мероприятие, поэтому оно должно делаться только в двух местах: прямо на входе и прямо на выходе. Вход - это ваш контроллер, Выход - это другой сервис, куда вы передаёте данные, или база данных (тут тоже происходит сериализация, либо явно, либо в ORM). Во всех остальных слоях инфообмен должен совершаться уже при помощи объектов PHP либо нативных типов. Это экономит ресурсы. При передаче между слоями приложения объектов вместо значений либо ассоциативных массивов вы сразу будете видеть очепятки, IDE вам прекрасно поможет при помощи автодополнения, объекты могут иметь какие-то полезные методы.

    2. Очень желательно в каждом из слоёв иметь собственный класс, отвечающий за данные. Например, нам в слой API приходит JSON-чик с новым пользователем.
    - Сериализуем JSON в DTO UserInAPI, сразу валидируем всё то, что мы можем валидировать без слоя бизнес-логики, и либо отдаём клиенту ошибку, либо передаём сам объект UserInAPI в следующий слой: слой бизнес-логики
    - В слое бизнес логики, получаем DTO UserInAPI на входе, преобразуем его в свой бизнес-объект UserInBusiness, валидируем его уже с точки зрения бизнеса, и либо возвращаем ошибку в слой API, либо совершаем над ним действия, и передаём объект класса UserInBusiness в слой работы с базой
    - В слое работы с базой данных получаем на входе объект UserInBusiness, преобразуем его уже в сущность базы данных UserInDB, валидируем всё на предмет корректности данных для базы, и либо возвращаем ошибку в бизнес, либо сохраняем сущность класса UserInDB в базу.

    Зачем такие сложности, вы спросите? А просто обратите внимание на то, что скорость изменения кода в разных слоях разная.
    - API вообще должен меняться раз в сто лет, чтобы не злить клиентов. Поэтому DTO класс UserInAPI будет стабильным и редко будет меняться.
    - Бизнес-логика меняется очень часто. У класса UserInBusiness постоянно будут добавляться поля и методы, тут жизнь будет кипеть.
    - Слой базы данных будет меняться реже, чем слой бизнеса, но чаще, чем слой API, потому что нам нужны будут новые поля в базе, новые таблицы и связанные таблицы.
    - И если мы один тип сущности протащим во все слои, то эта сущность обрастёт таким количеством различной хрени, что нам плохо станет, когда будем на неё смотреть. Либо она обрастёт кучей декораторов в каждом из слоёв. Поэтому лучше всё разделить.

    3. Теперь внимание, казалось бы, что мы слишком сильно связываем наши слои, и нижестоящие слои знают что-то о вышестоящих, а это неправильно. Ведь мы передаём объект UserInAPI в слой бизнеса, т.е. слой бизнеса должен уметь работать с этим объектом. И так же слой базы должен уметь работать с объектом бизнеса UserInBusiness. Как же быть? А очень просто. На входе слоёв использовать интерфейсы. Т.е. в слое бизнеса мы будем принимать не сам класс UserInAPI, а объект, имплементирующий интерфейс UserIncoming, который объявим в бизнес слое, и заставим слой API сделать так, чтобы его класс UserInAPI имплементировал этот интерфейс. Таким образом слой бизнеса ничего не будет знать о слое API, а будет ждать на входе данные по контракту, описанному в интерфейсе. Бизнесу плевать на конкретную реализацию, ему нужны только методы getUsername, getEmail из интерфейса. А какой класс ему их предоставит - пофигу. Таким образом мы практически полностью разделяем слои и в два счёта сможем поменять слой API, где у нас HTTP контроллеры, на слой RabbitMQ, SOAP, Grpc и т.д.
    Ответ написан
    6 комментариев
  • Вычитаю одно округленное число из другого, в ответе выдается число с кучей знаков после запятой, как это исправить?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Добро пожаловать в реальный мир вычислений чисел с плавающей запятой с погрешностью! Если вам нужны точные вычисления - используйте тип decimal или аналогичный для вашего ЯП.
    https://habr.com/ru/articles/266023/
    https://learn.microsoft.com/ru-ru/office/troublesh...
    https://0.30000000000000004.com/
    Ответ написан
    2 комментария
  • Как задать запрос в базу mysql с массивом данных?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега MySQL
    Понятия не имею как с этим работать.
    Поскольку это даже не JSON, а сериализация средствами PHP, то единственный адекватный способ - получать все записи из БД, десериализовывать и в коде считать что нужно.
    Ответ написан
    2 комментария
  • Есть ли в PHP готовый инструмент для получения элемента массива вложенность которого хранится в другом массиве?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Есть. Называется цикл.
    Ответ написан
    Комментировать
  • Как из контроллера дернуть команду?

    vhood
    @vhood
    Не забывайте отмечать решения
    в ней происходит просто обращение курлом по ссылке и получение картинки
    Вынесите этот функционал в отдельный сервис и используйте его и в команде, и в контроллере.
    Ответ написан
    Комментировать
  • Как установить лимит на использование оперативной памяти для ElasticSearch в Docker?

    ky0
    @ky0
    Миллиардер, филантроп, патологический лгун
    Так же, как для любого другого контейнера - через resources:
    https://docs.docker.com/compose/compose-file/deplo...
    Ответ написан
    3 комментария
  • В чем ошибка SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    1) $params собственно нужен для биндинга, чтобы не вставлять данные прямо в запрос, так как это чревато инъекциями. По этому дебильный совет "просто поменяй на $stmt->execute();" желательно проигнорировать.

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

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

    4) WHERE $email что? Вы вообще понимаете что и для чего пишете? Просто переведя на русский "где емэйл" не кажется вам слегка странной конструкцией? Просто загляните в документацию SQL где описывается WHERE.
    Ответ написан
    Комментировать
  • Как писать микросервисную архитектуру?

    @Everything_is_bad
    Забей на микросервисы, джуны не способны их нормально сделать, тут тупо нужен опыт, так что для начала пиши монолит. Красивое раскидывание кода по папкам, вообще не имеет отношение к микросервисам.

    Условно мы отправляем сообщение в чат, в котором состоит пользователь. Нам нужно получить и заблокировать список пользователей, добавить сообщение, и разблокировать.
    зачем вообще тут блокировать пользователей?
    Ответ написан
  • Как реализовать идеальный метод indexOf?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Вы неверно понимаете суть О-нотации. Почитайте книги Дональда Кнута про это.
    O(3) - это то же самое, что O(1). Нет разницы. O(N), O(N+1000), O(10*N) - это тоже одно и то же.
    В таких случаях речь всегда идёт не про конкретный кейс, а про обобщенный. Вы не знаете в каком порядке элементы вашего массива, где находится искомый, сколько всего элементов будет в конкретных кейсах, поэтому определяется ряд случаев: средний (по вероятности, если входные данные рандомные), худший (чтобы понимать границы и сколько может "висеть" алгоритм теоретически). Лучшие варианты обычно никого не интересуют, потому что и вероятность их мала, и смысла никакого нет в столь малых величинах.

    У вас типичный случай компромисса в реализации структуры данных. Вы всегда балансируете между памятью и скоростью. Больших семь шапок из овцы не выкроить никак.
    То есть, вы можете сделать такую структуру данных, которая "под капотом" будет держать древовидный индекс с данными или отсортированную по ключу карту значений для бинарного поиска. Хотя эти варианты - суть одно и то же.
    Если не рассматривается вариант размена производительности на память, то в этой задаче у вас будет только O(N) без вариантов.
    Если усложнить структуру данных, то можно добиться и O(logN) при поиске, и даже O(1). Почитайте как устроен словарь в питоне.

    Да, помимо сложности поиска у вас будет сложность вставки в структуру новых элементов. И тут опять трейд-офф. Ну а что вы хотели?
    Ответ написан
    3 комментария
  • Почему отказались от оператора GoTo в высокоуровневых языках?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Поскольку goto позволяет писать очень запутанный и непонятный код. Слишком легко написать плохой код.
    Ну не могут люди в голове удерживать спагетти из кучи возможных путей исполнения. if/else, да циклы - это людям понятно. Появилась инструкция goto изначально, потому что в машинных кодах, а значит и в асемблере эта инструкция есть. Оттуда она перекочевала в языки более высокого уровня. Процессоры, наоборот, if/else вообще не умеют. Вместо это там всякие условные goto.
    В новых языках программирования goto вообще нет, а в старых его обычно запрещают использовать в правилах кодовой базы. Если кто злоупотребляет - ему дают по рукам.
    Ответ написан
  • Почему отказались от оператора GoTo в высокоуровневых языках?

    saboteur_kiev
    @saboteur_kiev
    software engineer
    Никакие комьютеры не отказались от goto.
    Кроме того, это не функция, а оператор.

    Но если писать длинный код активно используя goto, в нем будет крайне сложно разобраться.
    Поэтому в некоторых языках программирования его может и не быть. Но на архитектурном уровне и низкоуровневом ассемблере, он естественно есть.
    Ответ написан
    Комментировать
  • В чем проблема плагинов "раскрашивания" скобок для IDE?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Слишком много разноцветных побрекушек только отвлекают.
    А если тебе нужно раскрашивать скобочки, чтобы понимать где ты находишься, то их раскрашивание это только маскирование симптомов - проблема уже в архитектуре кода
    Ответ написан
    4 комментария
  • Как отменять коммит слияния, чтобы потом без проблем выполнить повторное слияние?

    sergey-kuznetsov
    @sergey-kuznetsov Куратор тега Git
    Автоматизатор
    Линус Торвальдс уже подробно комментировал подобную ситуацию.

    И вы совершенно правильно всё поняли. Реверс коммита слияния восстанавливает код, который был изменён этим коммитом, но ничего не делает с эффектами, которые это слияние оказало на историю. Слияние всё ещё будет существовать, и оно всё ещё будет восприниматься как объединение двух веток, и будущие слияния будут воспринимать это слияние как последнее общее состояние — и реверт никак на это не повлияет.

    Таким образом, «revert» отменяет изменения кода, но это совсем не «undo» в том смысле, что он не отменяет влияния коммита слияния на историю репозитория.

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

    Но есть ещё один способ — можно по-настоящему отменить слияние, пересобрав тематическую ветку заново. Тогда не придется делать повторный revert.

    Давайте вернемся к вашей ситуации:
     P---o---o---M---x---x---W---x
      \         /
       A---B---C----------------D---E   <-- доработанная ветка задачи

    Где M — это слияние, которое вносит эти преждевременные изменения в основную ветку, x — это изменения не связанные с тем, что сделала тематическая ветка и уже внесённые в основную, а W - это «реверт M» (разве W не выглядит как перевернутое M?)

    Мы можем пересобрать тематическую ветку заново

    $ git rebase --no-ff P

    Получим:
       A'---B'---C'------------D'---E'  <-- пересозданная тематическая ветка
      /
     P---o---o---M---x---x---W---x
      \         /
       A---B---C----------------D---E

    Теперь можно слить пересозданную ветку с основной, не откатывая коммит W, и история основной ветки будет выглядеть так:
       A'---B'---C'------------D'---E'
      /                              \
     P---o---o---M---x---x---W---x---M2
      \         /
       A---B---C

    Правда такой трюк не сработает, если вы успели до слияния пообновлять тематическую ветку из основной. Эти коммиты слияния намертво свяжут две цепочки коммитов и не дадут сделать rebase.

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