• Какое место БД в Чистой Архитектуре?

    Где-то на одном из внутренних слоёв находится интерфейс для доступа к данным (репозиторий)
    А какой-нибудь из внешних слоёв этот интерфейс реализует.
    Ответ написан
    5 комментариев
  • Вопрос по конструктору класса?

    Vindicar
    @Vindicar
    RTFM!
    К сожалению, functools.singledispatchmethod тут не поможет, так как он не справляется с аргументами-экземплярами того же класса.
    Ты можешь проверять переданные аргументы вручную...

    import typing as tp
    
    
    class Test:
        @tp.overload
        def __init__(self, x: int, y: str):
            ...  # тут не должно быть тела!
    
        @tp.overload
        def __init__(self, other: 'Test'):
            ...  # typehint в виде строки, так как класс Test еще не создан. Тела нет!
    
        def __init__(self, *args, **kwargs):  # настоящий конструктор
            # определяем, как нас вызвали
            if 'other' in kwargs:
                first_arg = kwargs['other']
                x, y = first_arg.x, first_arg.y
            elif 'x' in kwargs:
                x, y = kwargs.get('x'), kwargs.get('y')
            elif isinstance(args[0], Test):
                x, y = args[0].x, args[0].y
            else:
                x, y = args[0:2]
            self.x: int = x
            self.y: str = y
    
        def __repr__(self) -> str:
            return f'Test(x={self.x!r}, y={self.y!r})'
    
    # порядковая передача аргументов сработает
    t1 = Test(1, 'foo')
    t2 = Test(t1)
    print(t1, t2)
    # именованная передача аргументов сработает
    t3 = Test(x=2, y='bar')
    t4 = Test(other=t3)
    print(t3, t4)
    
    Test(3, y='baz')  # а вот это сломается...

    Но у тебя будет куча проблем с аргументами имеющими значение по умолчанию.
    Метод copy() будет куда практичнее и понятнее.
    Ответ написан
    Комментировать
  • Как в rust конвертировать place expression в value expressions?

    vabka
    @vabka Куратор тега Rust
    Попробуй так
    fn main() {
        let funcs = {
            // Можно использовать не FnOnce, а что-то другое. Например Fn или FnMut. Но в любом случае придётся использовать dyn, тк наша лямбда берёт что-то из окружающего контекста.
    
            let mut funcs: Vec<Box<dyn FnOnce() -> usize>> = Vec::with_capacity(3);
    
            for i in 0..3 {
                let i_copy = i.clone(); // вообще clone() тут не нужен, тк usize реализует трейт Copy. Оставлено для примера
                funcs.push(Box::new(move || i_copy));
            }
            funcs
        };
        
        for func in funcs {
            let result = func();
            println!("{result}");
        }
    }

    https://play.rust-lang.org/?version=stable&mode=de...

    Другой вариант - делать не массив лямбд, а сделать структуру с методом и сделать массив структур.
    В твоём случае это будет эффективнее:
    #[derive(Copy, Clone, Debug)]
    struct Something(usize);
    impl Something {
      fn value(&self) -> usize {
        self.0
      }
    }
    
    fn main() {
        let items = {
            let mut items = Vec::with_capacity(3);
    
            for i in 0..3 {
                items.push(Something(i));
            }
            items
        };
        
        for item in items {
            let result = item.value();
            println!("{result}");
        }
    }

    https://play.rust-lang.org/?version=stable&mode=de...
    Ответ написан
    Комментировать
  • Как заставить работать одновременно фронтенд и бэкенд на одном порте?

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

    Ты можешь поднять nginx (ну или caddy, раз уже определился) на 80-м порту и настроить его на раздачу статики и проксирование запросов.
    MongoDB останется как есть.
    Ответ написан
    2 комментария
  • Стоит ли покупать мини-пк для подъема сервера для небольшого веб-сервиса или арендовать хостинг?

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

    Больше различий с VPS нет.
    Все минусы можно перекрыть, если ты ещё колокейшн купишь.

    PS: если тебе "даже несчастный raspberry pi" может сойти, то зачем такой дорогой сервер арендуешь? За такую цену вроде арендуется что-то типа 4 vcpu 100% + 8gb ram + nvme
    Ответ написан
    Комментировать
  • Разделение ответственности или производительность?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Мне кажется, что все прочитали только заголовок, а на текст поста никто не обратил внимания. Как обычно
    А там-то и лоснится самый ЖЫР:

    Но в этом случае мне придется выполнить 2 запроса к базе данных

    То есть вся "проблема" тут из-за каши в голове клиента, который откуда-то взял, что во втором варианте у него будет не два запроса, а один. Ну то есть понятно откуда - очередной разрабончик баз данных, который SQL видел только в кино, а база данных для него - это вот это вот prisma create.

    И только из-за этих нелепых страхов он ломает всю логику и сервис юзеров у него начинает лазить в БД постов. Что и является здесь проблемой. А не какие-то, опять же, дурацкие страхи про дублирование вызова нотификации.
    Ответ написан
    6 комментариев
  • Какие linux дистрибутивы можно установить на пк с 8 гигами озу?

    ValdikSS
    @ValdikSS
    1. Установите ядро 6.1, в более старых отсутствует поддержка MGLRU. В Debian 12 оно установлено по умолчанию, в Debian 11 необходимо установить из backports: https://packages.debian.org/bullseye-backports/lin...
    2. Установите пакет zram-tools, он настроит сжатие оперативной памяти — это гораздо быстрее, чем сброс данных на диск. В настройках /etc/default/zramswap настройте использование 80% RAM
    3. Настройте MGLRU — улучшенный менеджер виртуальной памяти и файлового кеша, который куда лучше понимает, какие данные вытеснять не следует (это основная причина тормозов при недостатке памяти):
    sudo tee /etc/tmpfiles.d/mglru.conf <<EOF
    w-      /sys/kernel/mm/lru_gen/enabled          -       -       -       -       y
    w-      /sys/kernel/mm/lru_gen/min_ttl_ms       -       -       -       -       1000
    EOF

    И перезагрузитесь.
    Ответ написан
    1 комментарий
  • Нормально ли так делать на Vue?

    @alexalexes
    Можно, но у вас нет оценки, насколько потом вы эти компоненты будете переиспользовать.
    Если не знаете, как будут переиспользоваться отдельные элементы управления формы или интерфейса, реализуйте сначала всю форму как один компонент, а после того, как она будет в рабочем состоянии, подумайте, нужно ли что-то выносить в доп. компоненты. Основной критерий принятия такого решения - возможность дальнейшей поддержки новой конфигурации компонентов, чтобы можно было легко вносить новые изменения, и это не было больно.
    Ответ написан
    Комментировать
  • Как сделать, чтобы сайт закрывался или становилась белая страница при открытии консоли?

    @alexalexes
    Никак. Любая составляющая сайта, переданная на сторону клиента, может использоваться и изучаться клиентом как угодно и какими угодно инструментами (кто сказал, что на другой стороне будет браузер?), как в полезном ключе, так и в зловредном.
    Краеугольным вопросом безопасности вашего ресурса является не противодействие анализу той части, которая получает клиент, а сделать так, чтобы серверная часть не реагировала на запросы, которые не соответствуют бизнес-логике клиентской части (или считала ошибкой, выводя соответствующее сообщение).
    На стороне сервера нужно проверять валидность данных, получаемых от клиента, как по правам доступа (имеет ли право клиент совершать определенное действие), так и по содержанию (данные, приводящие к изменениям, не будут ли приводить к противоречивому состоянию базы?).
    Ответ написан
    1 комментарий
  • Собственное поле для ввода на чистом JavaScript?

    @rPman
    Первый же запрос в гугл выдал
    Очевидно свой input потребует закодировать огромное количество ситуаций, выделение в т.ч. по дабл- и трипл-клику, вставка через буфер, работу с правосторонними шрифтами и вообще мультиязычная поддержка это ад (невидимые символы, меняющие поведение)
    Ответ написан
    Комментировать
  • Могут ли отказать в работе из-за административки 6-летней давности?

    @Drno
    Соц сети не указывай, кроме например 1 мессенджера. Остальное - твое личное дело, шли нафиг
    Если будут вопросы - рабочей соцсети нет (типо гитхаб к примеру), а личные я указывать не буду, т.к. это мое личное дело
    Административная - нет, всем плевать
    Ответ написан
    1 комментарий
  • Какие виды функций есть в C++, и как их различать?

    @code_panik
    В c++ есть бинарный оператор <<, который для целых чисел является оператором сдвига битов числа влево на заданное количество позиций (то же, что и повторное умножение на два). Например, программа напечатает 2 << 1 == 4,
    #include <iostream>
    using namespace std;
    
    int main() {
        cout << "2 << 1 == " << (0b010 << 1); // 0b100
        return 0;
    }

    Одна из основных возможностей языка - перегрузка функций, в частности встроенных операторов (не всех). То есть мы можем определить свой тип данных со своей реализацией оператора <<.
    #include <iostream>
    using namespace std;
    
    struct Foo {
        Foo& operator<<(int x) {
            cout << "Integer: " << x << '\n';
            return *this;
        }
    
        Foo& operator<<(const char* str) {
            cout << "String: " << str << '\n';
            return *this;
        }
    };
    
    int main() {
        Foo foo;
        foo << 3; // Integer: 3
        foo.operator<<("Hello world"); // String: Hello world
        return 0;
    }

    Для компилятора запись foo << 3; значит именно вызов функции foo.operator<<(3). Аналогично в случае cout, объекта типа std::ostream, который представляет поток вывода (character output).
    https://en.cppreference.com/w/cpp/io/basic_ostream...
    Ответ написан
    Комментировать
  • Как виртуальные машины исполняют код и как правильно это реализовать?

    WNeZRoS
    @WNeZRoS
    Если вопрос при виртуальные машины по типу тех что используется для исполнения Java или C# кода, то инструкции в них гораздо проще. В CIL например, у большинства инструкций нет параметров, они просто берут нужные данные с конца стека. А когда параметры есть - он один: значение или токен переменной/функции.

    Можно посмотреть как C# преобразуется в инструкции виртуальной машины на sharplab.io, сопоставить и понять как оно выполняется.

    Например
    IL_0000: ldarg 1 // кладёт в стек первый аргумент
    IL_0001: ldarg 2 // кладёт в стек второй аргумент
    IL_0002: sub     // достаёт из стека два последних значения и отнимает последний от пред последнего (т.е. будет arg.2 - arg.1), результат складывается в стек
    IL_0003: brtrue.s IL_0011 // достаёт из стека значение, если оно не 0, переходит к инструкции IL_0011, если 0 исполнения идёт дальше на I_0005
    
    IL_0005: ldstr "zero" // загружает в стек строку "zero"
    IL_000a: call void System.Console::WriteLine(string) // вызывает вывод в консоль, из стека достаются N нужных значений для параметров (в данном случае 1), void функция ничего в стек не добавляет
    IL_000f: br.s IL_001b // переход (jump) к IL_001b
    
    IL_0011: ldstr "not zero" // загружает в стек строку "not zero"
    IL_0016: call void System.Console::WriteLine(string) // вызывает вывод в консоль, из стека достаётся 1 значения для параметра 
    
    IL_001b: ldstr "done" // загружает в стек строку ...
    IL_0020: call void System.Console::WriteLine(string) // ...


    Пример реализации простой виртуальной машины на основе примера выше

    (Код написан так чтобы работал, правильнее писать более безопасно и читабельнее)

    #include <stdio.h>
    
    enum Opcode {
        OP_LOAD_ARGUMENT,
        OP_LOAD_STRING,
        OP_SUBTRACT,
        OP_GOTO,
        OP_GOTO_IF_TRUE,
        OP_CALL,
        OP_RETURN
    };
    
    union Argument {
        int value;
        const void* pointer;
    };
    
    struct Instruction { 
        Opcode opcode; 
        Argument arg; 
    };
    
    void run_vm(const Instruction* instructions, const Argument* args) {
        Argument stack[16];
        
        Argument* stack_pointer = &stack[0];
        int address = 0;
    
        while(true) {
            const Instruction instruction = instructions[address];
            address++;
    
            switch(instruction.opcode) {
                case OP_RETURN:
                    return;
                
                case OP_LOAD_ARGUMENT:
                    *stack_pointer = args[instruction.arg.value];
                    stack_pointer++;
                    break;
    
                case OP_LOAD_STRING:
                    *stack_pointer = instruction.arg;
                    stack_pointer++;
                    break;
    
                case OP_SUBTRACT:
                {
                    stack_pointer--;
                    int b = stack_pointer->value;
                    
                    stack_pointer--;
                    int a = stack_pointer->value;
    
                    stack_pointer->value = a - b;
                    stack_pointer++;
                    break;
                }
    
                case OP_GOTO:
                    address = instruction.arg.value;
                    break;
    
                case OP_GOTO_IF_TRUE:
                    stack_pointer--;
                    if(stack_pointer->value != 0)
                        address = instruction.arg.value;
                    break;
    
                case OP_CALL:
                    void (* fn)(const void*) = (void (*)(const void*))instruction.arg.pointer;
                    stack_pointer--;
                    fn(stack_pointer->pointer);
                    break;
            }
        }
    }
    
    void print(const char* text) { printf("%s\n", text); }
    
    int main(int argc, char** argv) {
        const Instruction instructions[] = {
            /* 0 */ { OP_LOAD_ARGUMENT, { 0 } },
            /* 1 */ { OP_LOAD_ARGUMENT, { 1 } },
            /* 2 */ { OP_SUBTRACT, {} },
            /* 3 */ { OP_GOTO_IF_TRUE, { 0x7 } },
            /* 4 */ { OP_LOAD_STRING, { .pointer = "zero" } },
            /* 5 */ { OP_CALL, { .pointer = (void*)&print } }, // функции надо где-то регистрировать, чтобы знать сколько у них параметров и какого они типа
            /* 6 */ { OP_GOTO, { 0x9 } },
            /* 7 */ { OP_LOAD_STRING, { .pointer = "not zero" } },
            /* 8 */ { OP_CALL, { .pointer = (void*)&print } },
            /* 9 */ { OP_LOAD_STRING, { .pointer = "done" } },
            /* A */ { OP_CALL, { .pointer = (void*)&print } },
            /* B */ { OP_RETURN, {} }
        };
    
        const Argument args[] = { 
            { 100500 },
            { 777 }
         };
    
        run_vm(instructions, args);
        return 0;
    }



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

    @deliro
    use std::env::current_exe;
    
    fn main() {
        let x = current_exe();
        println!("{x:?}")
    }
    Ответ написан
    1 комментарий
  • Почему ругается Vscode на типы?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну потому что это union - он строгий, он позволяет получать свойство напрямую только в том случае, если оно есть у всех членов union'а. В ином случае надо руками делать проверку, которая сузит тип до нужного. if ('counter' in ...) и т.п.
    Ответ написан
    Комментировать
  • Есть ли название у подобного подхода?

    What is an early return?
    An early return, or “return early” is an approach to keep readability in functions and methods.

    It is always considered a wise choice to return early if simple conditions apply that can be checked at the beginning of a method.
    https://dev.to/jpswade/return-early-12o5
    Ответ написан
    1 комментарий
  • Как вернуть пункт меню фаил visual studio code в контекстное меню?

    yarkov
    @yarkov
    Помог ответ? Отметь решением.
    На любом значке правую кнопку мыши нажми и верни проводник
    6496b61f93760495472006.png
    Ответ написан
    Комментировать
  • Что такое Docker простыми словами?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Что такое Docker простыми словами

    простыми словами

    Если совсем прям простыми, то - это некая легковесная оболочка, которая способна изолировать приложение внутри себя от внешнего мира. Очень похож (по логике) на системы виртуализации VMware, VirtualBox, Parallels итп, но сам не является им.

    Возможности:

    - Контейнеризация: Docker позволяет паковать приложения вместе со всеми их зависимостями в контейнеры, обеспечивая тем самым их независимость от конкретной инфраструктуры.
    - Переносимость: Контейнеры Docker могут быть запущены на любом компьютере, который поддерживает Docker, независимо от операционной системы. Это делает распространение и развертывание приложений намного проще.
    - Изоляция ресурсов: Каждый контейнер Docker работает в изолированной среде и не влияет на другие контейнеры или хостовую систему.
    - Слоистая файловая система: Docker использует слоистую файловую систему для хранения данных, что позволяет существенно экономить дисковое пространство и упрощает обновление и распространение контейнеров.
    - Сетевые возможности: Docker позволяет настраивать сетевые параметры каждого контейнера, что позволяет создавать сложные многокомпонентные приложения.
    - Docker Hub: Docker Hub – это репозиторий, где можно хранить и делиться контейнерами. Это облегчает развертывание и распространение приложений.
    - Docker Compose: Это инструмент для определения и запуска многоконтейнерных - Docker-приложений. С помощью Compose вы можете использовать файл YAML для конфигурации служб вашего приложения, а затем с помощью одной команды создать и запустить все службы.
    - Docker Swarm: Docker Swarm предоставляет нативные возможности Docker для оркестрации и масштабирования кластера Docker.
    Ответ написан
    Комментировать
  • Есть ли в РФ учебные заведения, которые выпускают сеньоров или мидлов?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Ни в РФ нет, ни где-либо ещё. Это на столько же невозможно, как стать чемпионом мира по боксу, посмотрев бой по телевизору.
    Ответ написан
    Комментировать
  • Как работает finally и then в Promise?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Никто ничего ждать не будет. Исполнение кода пойдёт дальше до самого конца функции.
    Когда промис, который вернул fetch, перейдёт в состояние resolved, в очередь микротасков будет добавлен вызов каллбэк-функции из первого then. Если промис вернёт rejected, то вызова не будет, вернётся новый промис в rejected.
    Когда промис из первого then перейдёт в состояние resolved, в очередь микротасков будет добавлен вызов каллбэк-функции из второго then. Если промис вернёт rejected, то вызова не будет, вернётся новый промис в rejected.
    Когда промис из второго then перейдёт в состояние resolved или rejected, в очередь микротасков будет добавлен вызов каллбэк-функции из finally.
    Ответ написан
    Комментировать