• Как проверять оплату в эквайринг Тинькофф?

    @belkinark Автор вопроса
    Разобрался с проблемой.
    tokentr = token[1]["Password"] + x["PaymentId"] + token[0]["TerminalKey"]
    Ответ написан
  • Как вы ведете документацию кода?

    vabka
    @vabka
    Токсичный шарпист
    Многие говорят, что код должен быть самодокументируемым.

    Так говорят только про случаи типа:
    // Время до перегрева реактора в секундах
    var a = 42;

    return id % 3; // 3 - это количество наших серверов. Тут мы находим id нужного сервера, на котором хранятся данные

    В вышеназванных случаях комментарий не нужен и может быть заменён нормальным неймингом.
    В некоторых случаях комментарии можно заменить на нормальные типы.
    // ПЛОХО!
    /// <param name="time">Дата и в формате rfc2822</param>
    public void DoSomething(string time) {}
    
    // Хорошо!
    public void DoSomething(DateTime time) {}

    Писать комментарии в коде нужно там, где что-то не очевидно (описание какого-то алгоритма или протокола, например, ссылки на задачи, в рамках которых был добавлен какой-то неочевидный, но важный "костыль" и так далее)
    + Следует пользоваться встроенными средствами для документирования.

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

    Если вашей команде документация действительно важна, то её нужно вносить в основной цикл разработки.
    Что-то типа
    Specification -> Design review -> Development -> Review -> Testing -> Documentation -> Release
    Тоесть нет документации - нет релиза. Нужно вносить роль технического писателя, который будет писать тексты и следить за актуальностью.

    которые автоматически показывали бы покрытие кода документацией.

    Код документацией покрывать не надо (по крайней мере так, как это обычно тестами происходит).
    А вот для покрытия методов и публичного api и так есть инструменты для проверки. Например в C# даже warning есть соответствующий.

    что-то похожее на TDD - когда ты пишешь документацию а потом код

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

    PS: Попробуй отталкиваться от того, кто будет эту документацию читать.
    1. Новые разработчики в твоей команде во время онбординга? Тогда проще C4 Diagram нарисовать
    2. Другие разработчики, которые хотят с твоим сервисом интегрироваться? Тогда и описывай протокол взаимодействия, примеры приложений, и имеющиеся публичные методы
    3. Техподдержка? Тогда лучше посмотреть в сторону базы знаний
    4. Пользователи системы? Тогда лучше отталкиваться от вариантов использования - инструкции, как сделать то или иное действие, обзоры разных модулей.
    5. Аналитик при продумывании новых фич? Тогда тут нужно что-то среднее между п1, п2, и п3.
    6. Никто? Тогда и не мучай бумагу.
    Ответ написан
    Комментировать
  • Зачем нужны "ссылочные" методы и почему они не удовлетворяют интерфейсам?

    func (h *Human) Speak() {
    
    }

    Если глянуть на внутренности языка, то метод это по сути обычная функция, у которой первым параметром является ресивер (тот объект, у которого вызывается метод). То есть, компилятор этот код превратит в
    func Speak(h *Human) {
    
    }

    Соответственно, при вызове метода в случае *Human будет передача структуры по указателю, а в случае Human, по значению, со всеми вытекающими.

    Что касается ошибки про несоответствие интерфейсу, то тут надо учесть, что если у структуры определены методы через указатель, то и соответствовать интерфейсу будет указатель на эту структуру: https://go.dev/play/p/o7EsGmeYSRS
    Если же без указателя, то соответствовать интерфейсу будет сама структура: https://go.dev/play/p/oTsXP4DXaMJ
    Но оба одновременно определить не получится.
    Ответ написан
    Комментировать
  • Как оптимизировать одновременную подгрузку 2000 картинок низкого качества?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Однозначно спрайты.
    Во первых - поэксперементировать с форматом, если лого у вас в основном малоцветные - больше подойдет пнг, нежели вебп или жпег. Фотошоп позволяет достаточно эффективно оптимизировать картинку.
    Во вторых - сумма байт от всех картинок скорее всего будет в разы больше одной большой, в силу алгоритмов сжатия, так как они работают эффективнее на большой картинке.
    В третьих - "резать" на фронте ничего не надо, просто вставляете бэкграундом со смещением.
    Как вариант для избегания пустых мест в этом блоке - скрыть его до загрузки спрайта. По загрузке сделать видимым.
    Ответ написан
    Комментировать
  • Как разрешить вызов api контроллера, только одному серверу по ip (который отправляет вебхук)?

    EvgenyMamonov
    @EvgenyMamonov Куратор тега Go
    Senior software developer, system architect
    Чаще всего, в таких случаях, используют секретный ключ, который передают или в параметрах запроса (так лучше не делать, т.к. секретный ключ будет виден в логах промежуточных прокси и сервера) или в HTTP заголовке (этот вариант безопаснее, чем передача в параметрах запроса).

    Реже используют вариант с цифровой подписью запроса. Этот вариант ощутимо безопаснее, чем передавать секретный ключ в открытом виде. При таком варианте вы не только знаете о том, что запрос отправил нужный вам сервер, но и о том, что запрос не был изменён никем (например прокси сервером).

    Но оба эти варианта требуют доработки со стороны отправляющего запрос сервера.
    Как я понимаю для вас этот вариант не доступен.

    В принципе вариант защиты по IP адресу вполне нормальный.
    Самый простой способ - настроить firewall, т.е. закрыть доступ всем к вашему сервису и открыть только для IP сервера, который делает запросы.

    Если вариант с firewall не подходит - можно обеспечивать защиту на стороне Go.
    IP можно получать из запроса HTTP https://pkg.go.dev/net/http#Request

    Вот готовый пример
    package main
    
    import (
        "fmt"
        "log"
        "net/http"
    )
    
    func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Your IP is %s", r.RemoteAddr)
    }
    
    func main() {
        http.HandleFunc("/", handler)
        log.Fatal(http.ListenAndServe(":8080", nil))
    }

    Иногда (зависит от настроек веб сервера) реальный IP может приходить в HTTP заголовках запроса
    ip := r.Header.Get("X-Forwarded-For")
    // или
    ip := r.Header.Get("X-Real-IP")
    Ответ написан
    3 комментария
  • Как сделать динамической секцию отзывов?

    @its2easyy
    post type нормально, но если отзывов будет мало и не нужна будет дополнительная функциональность типа запросов по ним или таксономий, то проще использовать complex field из carbon fields или repeater из acf. Тогда можно будет добавить отзывы как опции страницы если они на одной странице используются, или вынести на страницу общих настроек если отзывы ко всему сайту относятся.
    Ответ написан
    1 комментарий