Задать вопрос
  • Как поднять контейнер mysql через wsl?

    opium
    @opium
    Просто люблю качественно работать
    rm -rf /var/lib/mysql/* внутри контейнера тут не поможет, потому что /var/lib/mysql у тебя примонтирован с хоста и для --initialize каталог должен быть полностью пустым. Если данные не нужны, удали именно хостовую папку:
    rm -rf ./data/docker-files/mysql-db && mkdir ./data/docker-files/mysql-db
    и пересоздай контейнер. На будущее для MySQL под WSL проще использовать именованный volume вместо bind mount — с ними таких проблем нет.
    Ответ написан
    4 комментария
  • Как в Go происходит неявное удовлетворение интерфейсу?

    Интерфейс в Го, это структура с двумя полями.
    1. Указатель на данные (в вашем случае на структуру User с age и name)
    2. Указатель на таблицу виртуальных методов.
    В таблице виртуальных методов как раз перечислены методы, которые реализованы на структуре и на рантайме через нее Го понимает, что можно вызывать, а что нельзя.

    В статье https://habr.com/ru/articles/856272/ можете почитать подробнее, там описано как работает itab (таблица виртуальных методов).


    Можно ли даже при созданном вручную String() использовать метод String() из стандартной библиотеки?


    String в стандартной библиотеке это не метод на структуре. Это код, который через рефлексию смотрит что ему пришло и вызывает соответствующий форматтер. Одно из условий, которые он проверяет, это как раз, имплементит ли объект интерфейс Stringer, поэтому в вашем коде вызывается этот метод.
    Использовать стандартный форматтер структуры получится разве что костылями, дергая вручную более "тупые" методы стандартной библиотеки или через пакет reflect вытащить данные из структуры.

    Как это вообще может помочь в целом в работе и какие есть юзкейсы для этого?


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

    @igreklpofrss Автор вопроса
    Как оказалось не учел соглашение о вызовах.
    __cdecl: очищает стек после каждого вызова (add esp, X)
    __stdcall: очищает стек внутри функции(retn X)

    После добавления __stdcall в функцию crsGetString, компилятор теперь знает, что она самостоятельно очищает стек, поэтому функции GetMapDescriptions не надо заниматься его очисткой.
    typedef int (__stdcall *crsGetStringType)(void *, int, char *Destination, int Count);

    На Ассемблере проще писать, чем на С++ с учетом кучи тонкостей..
    Ответ написан
    1 комментарий
  • Влияет ли, передаёшь ты в функцию аргументы по ссылке или по значению, на производительность и память?

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

    Ссылка тоже занимает место, так что в случае int и других маленьких объектов (которые по размерам как указатель или меньше) дешевле передавать значение (как по памяти, так и по времени).

    Да и выделение/освобождение памяти в куче дороже, чем выделение/освобождение памяти на стеке. (зато меньше риск получить висячий указатель или stack overflow)

    Хороший вопрос содержит половину ответа :)
    Ответ написан
    Комментировать
  • Влияет ли, передаёшь ты в функцию аргументы по ссылке или по значению, на производительность и память?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    По ссылке дешевле во многих случаях. Ибо передача по значению создает копию. Поэтому передача большого вектора по значению будет очень дорогой.

    В целом, в С++ хорошее правило - передавать большие переменные как const &.

    Но для мелких типов, вроде int, передавать по ссылке может быть даже дороже, ибо и ссылка и значение тупо помещаются в регистр. Но ссылку надо будет еще разыменовывать, чтобы прочитать значение из памяти, а значение из регистра компилятор может даже не сохранять в память.

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

    Сразу говорить про все языки программиования нельзя. В некоторых языках вообще все передается по ссылке, в других вообще нет разницы для мелких типов.
    Ответ написан
    Комментировать
  • Почему я могу изменять состояние объекта хранящийся в const std::unique_ptr и const std::shared_ptr?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно сделать указатель на const. Вот этот ваш const, он относится к самому указателю, его нельзя менять (в смысле, на другой адрес). Но после разыменовывания получается не константная ссылка. Вот оно в документации:
    typename std::add_lvalue_reference<T>::type operator*() const


    Там нет никакого const в типе возвращаемого значения, несмотря на то, что оператор можно вызывать у константных экземпляров класса. Зачем конкретно так сделано, я не знаю. Наверно, тут копируется поведение обычных указателей: там тоже можно иметь неизменный указатель на изменяемую область памяти.

    Так что если вы хотите запретить менять объект, то можно сделать так:
    void foo(const std::unique_ptr<const int>& ptr) {
        if (ptr) {
            *ptr += 5; // Ошибка компиляции.
            std::cout << *ptr;
        }
    }
    
    int main() {
        std::unique_ptr<const int> ptr = std::make_unique<const int>(5);
        foo(ptr);
    }


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

    Но вообще, обычно нет смысла передавать unique_ptr по ссылке. Можно передать по ссылке сам объект, все равно владение в функцию не передается же. И уже там можно навешивать const, если надо. Или, если передавать просто unique_ptr, без ссылки, то даже лишнего кода не надо для обработки const:
    void foo(const std::unique_ptr<const int> ptr) {
    }
    
    int main() {
        std::unique_ptr<int> ptr = std::make_unique<int>(5);
        foo(std::move(ptr));
    }
    Ответ написан
    3 комментария
  • Какое есть бесплатное решение для организации файлообменника?

    @rPman
    Syncthing, в любую сторону, любая платформа
    Ответ написан
    Комментировать
  • Reverse engineering black box ML-модели?

    @rPman
    Вам бы с ИИ пообщаться, в отличии от гугла, оно ищет информацию заметно лучше, 'понимая' задачу

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

    Первая же ссылка на статью, она не даст ответ о методиках но там есть ссылка на пример взлома чего то типа персептрона.

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

    p.p.s. вот если бы структура модели была известна (точно) то можно даже некоторые веса извлекать (читал что первые слои GPT-шки извлекали)

    Ну и есть такое понятие - distilation, если структура модели примерно известна, можно вполне себе не дорого обучить, собственно deepseek так сделали
    Ответ написан
    Комментировать
  • Reverse engineering black box ML-модели?

    Maksim_64
    @Maksim_64
    ML Engineer
    1. Нет нельзя.
    2. Тоже нельзя.

    Без параметров, и детальной архитектуры ML - модели, ловить нечего.

    Для первого случая вообще нет исключений, даже если твой black-box это простая линейна регрессия, такой же выхлоп, может давать куда более сложная модель.

    Для второго, в качестве исключения на примитивных взаимоотношениях да.
    Ответ написан
    Комментировать
  • Существуют ли российские Mobile Device Management (MDM) системы?

    NeiroNx
    @NeiroNx
    Программист
    Ответ написан
    Комментировать
  • Почему i? Почему переменную, используемую в циклах, обычно называют именно i?

    @alexalexes
    index. А вообще, индексы элементов массива пришли из математики - i, j, k для первых трех измерений.
    Просто, первыми компухтеры оседлали математики, отсюда и традиция в циклах использовать эти буквы.
    Ответ написан
    2 комментария
  • Macbook air или pro для продуктового дизайнера и работы в figma?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Если вам важна компактность - берите Air, но обязательно добавьте до максимального объема оперативной памяти. Аир легко переваривает докер на десяток-полтора контейнеров и целом отличнейшая рабочая машинка. Производительности вполне хватает на всё. Брать прошку старого поколения нет особого смысла. Лучше сейчас сразу доплатить и получить дополнительную оперативную память, чем менять на новый лет через пять или когда упрётесь в лимит. В целом же для большинства современных задач 16 гигов вполне достаточно, хоть это и минимум. Но лучше всё же иметь запас на будущее.
    Ответ написан
    Комментировать
  • Почему именно такой порядок вывода в консоль?

    @NikitaLikosov
    Представим eventloop step by step
    1. Мы синхронно выполнили код и получили 2 микротаска с вызовом 1 и вызовом 3
    2. Микротаски вызвались и создали еще 2 микротаска с вызовом 4 и вот этим вот промисом return new Promise((resolve) => resolve());(функция в then его просто вернула, а в следующий then он должен попасть выполненным, так что, js его отдельно сначала должен выполнять )
    3. После вызова прошлых микротасок мы получили микротаск с вызовом 5 и 2
    4. Осталось вызвать микротаск с 6 и все
    Ответ написан
    3 комментария
  • Как писать микросервисную архитектуру?

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

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

    Сделайте лучше хороший проект-монолит, отработайте навыки языка, БД, развертывания, гита, итд... на одном проекте. Будет гораздо полезнее.
    Ответ написан
    2 комментария
  • Как вытащить поля из запроса в pgx?

    Eugene-Usachev
    @Eugene-Usachev
    struct User {
        id int
        name string
        level int
        currentExp int
        maxExp int
    }
    
    var user User
    
    row := ... // Ваш запрос
    if err := row.Scan(&user.id, &user.name, &user.level, &user.currentExp, &user.maxExp); err != nil {
        // обработайте ошибку
    }
    
    // тут поля у user заполнены


    Вы не приложили структуру, поэтому мне пришлось её выдумать. Используйте метод Scan у row. Он принимает ссылки на переменные для вставки значений. Значения вставляет в том порядке, в котором они возвращаются, за этим нужно следить.

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

    https://pkg.go.dev/github.com/jackc/pgx
    Самый первый пример из верха документации
    var name string
    var weight int64
    err := conn.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }


    Только поля замените на свои

    В пятой версии добавились еще другие способы https://pkg.go.dev/github.com/jackc/pgx/v5#hdr-Que...
    Ответ написан
    Комментировать
  • Если в glang перемнная передана в func, то она там живёт сомостоятельно или в пямяти 1 адрес?

    В Го по-умолчанию переменные передаются по значению (то есть, копируются на стеке), но есть нюансы.

    1. Мапы и каналы всегда передаются по указателю.
    2. У слайса на стеке только дескриптор, так что он копируется, но данные, на которые слайс указывал, остаются там же в памяти, где и были.
    3. Если вы явно передаете указатель, то тут все очевидно.
    4. У интерфейсов копируется дескриптор, но т.к. в дескрипторе указатель, то тут все как со слайсами.
    Ответ написан
    Комментировать
  • Как компилировать общие файлы двух бинарников один раз?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Из компилируешь a.cpp и b.cpp, а затем просто используешь их объектные файлы

    пример на Makefile

    a.o: a.cpp
         gcc -c a.cpp -o a.o
    
    b.o: b.cpp
         gcc -c b.cpp -o b.o
    
    tests.exe: a.o b.o
         gcc a.o b.o test_main.cpp -o tests.exe
    
    app.exe: a.o b.o
         gcc a.o b.o app_main.cpp -o app_main.exe


    как-то так

    UPD: если про CMake, то используй OBJECT библиотеку

    add_library(common OBJECT a.cpp b.cpp)
    add_executable(tests PRIVATE tests_main.cpp $<TARGET_OBJECTS:common>)
    add_executable(app PRIVATE app_main.cpp $<TARGET_OBJECTS:common>)
    Ответ написан
    Комментировать
  • Сколько вообще целых и дробных чисел с неповторяющимися цифрами существует?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Давайте прикинем.
    Для дробных чисел, имеющих хоть один значащий разряд перед запятой и один после мы должны выбрать первую цифру из девяти (ноль исключаем), последнюю из восьми (исключаем уже выбранную и ноль), третью из восьми оставшихся, четвёртую из семи и т.д. Кроме того, точка может стоять в одной из n-1 позиций, где n - количество цифр.
    Получаем:
    Чисел из 10 цифр: 9 * 8 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 * 9 = 26'127'360
    Чисел из 9 цифр: 9 * 8 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 8 = 23'224'320
    Чисел из 8 цифр: 9 * 8 * 8 * 7 * 6 * 5 * 4 * 3 * 7 = 10'160'640
    ...
    Чисел из 2 цифр: 9 * 8 * 1 = 72
    Просуммировав, получим 63'130'248
    Добавим сюда числа вида 0.xxx. Поскольку ноль фиксирован, первую цифру после него мы можем выбрать из девяти, вторую из восьми оставшихся и так далее.
    Чисел из 10 цифр: 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 362'880
    Чисел из 9 цифр: 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 = 362'880
    Чисел из 8 цифр: 9 * 8 * 7 * 6 * 5 * 4 * 3 = 181'440
    ...
    Чисел из 2 цифр: 9
    Сумма 986'409
    Теперь возьмём целые числа. В первой позиции не может быть нуля, поэтому первую цифру выбираем из девяти. Вторую из девяти оставшихся, третью из восьми и т.д.
    Чисел из 10 цифр: 9 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 3'265'920
    Чисел из 9 цифр: 9 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 = 3'265'920
    Чисел из 8 цифр: 9 * 9 * 8 * 7 * 6 * 5 * 4 * 3 = 1'632'960
    ...
    Чисел из 2 цифр: 9 * 9 = 81
    Чисел из 1 цифры: 9
    Сумма 8'877'690
    Сложим всё, добавив ноль, получим 72'994'348.
    Ответ написан
    5 комментариев