Задать вопрос
  • Как правильнее хранить друзей и контакты в бд?

    @Everything_is_bad
    Первое что пришло в голову - таблица contacts
    норм

    1. 10.000 пользователей импортируют свои 100-200 контактов - в бд уже будет >1 млн записей
    это мало

    Если строк будет очень много, то будет ли тормозить обычный select? на userId и phoneNumber будут индексы
    с большой вероятностью не будет, но обычно если возникает вопрос, собирают тестовый стенд и проверяют самостоятельно.
    Ответ написан
    Комментировать
  • Каких вещей следует избегать в Rust?

    vabka
    @vabka Куратор тега Rust
    Сложно сказать, чего стоит избегать, но точно не стоит избегать чтения растбука
    Ответ написан
    2 комментария
  • Каких вещей следует избегать в Rust?

    bingo347
    @bingo347
    Crazy on performance...
    Я знаю, что следует избегать всяких "продвинутых" штук из ряда связных списков, самореферентных структур и т.п.
    Односвязные списки никаких проблем не доставляют (ну кроме того, что они плохо ложатся на процессорный кэш). Для двусвязных списков и самореферентных структур придётся использовать сырые указатели и unsafe.

    Ещё я обнаружил, что создание больших структур, с методами, с кучей полей, обычно приводит к проблемам с borrow checker.
    Borrow checker абсолютно плевать на размер структур. Это никак не связано.

    А если в структуре будет ссылка или иное заимствование, то это гарантированные проблемы.
    Нет ни каких проблем.

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

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

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

    И очень часто в Rust программах, мне приходится идти на более уродливую архитектуру, дабы избежать проблем с (почти ненужным в однопоточном коде) borrow checker.
    Что-то делаете не так. Скорее всего просто не понимаете borrow checker и пытаетесь писать на новом языке так, как привыкли в каком-то другом.

    И в вопросе о borrow checker, разве не является тот факт, что большинство библиотек избегает &mut self в изменяющих что-то методах, звоночком к наличию большим проблем в языке?
    О каком большинстве речь? Библиотеки используют мутабельные ссылки там где это нужно. Если метод действительно что-то меняет, то будет мутабельная ссылка ну и иногда будет использоваться interior mutability там где это необходимо. В языке нет проблем с мутабельными ссылками.

    В общем, посоветуйте что-то что-бы помогало меньше бороться с borrow checker, потому что сейчас я очень много времени трачу именно на это.
    Для начала понять его. Понять какую проблему он решает. Почитайте, что такое undefined behavior. Почитайте, что такое алиасинг.

    Возможно где-то альтернативой мутабельным ссылкам будут Cell/RefCell в однопоточном коде и Mutex/RwLock в многопоточном.
    Возможно если покажете примеры кода, где у Вас проблемы, то можно будет подсказать что-то более конкретное.
    Ответ написан
    3 комментария
  • Почему в Go вакансиях требование знания PHP?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Или это просто такое количество кодовой базы на PHP накопилось, которую все дружно решили переписывать на Go

    Скорее всего.

    если да, то почему именно на Go?

    Если компания решилась вложиться в переписывание продукта на другом языке, то у неё на это точно очень веские причины, вероятнее всего - проблемы производительности. В этом случае Go - очевидный выбор. Python, Ruby и JS не дадут никакого выигрыша относительно PHP. Хоть на языках из мира jvm и .net можно писать высокопроизводительный софт, но они скорее решают проблемы сложности огромных кодовых баз. С++ и Rust очень сложны и для прикладного софта применяются только в крайнем случае. Всякая экзотика, типа Erlang, Elixir и Haskell - это вообще редкий случай в энтерпрайзе. Go же одновременно очень прост и ориентирован на высокую производительности.
    Ответ написан
    7 комментариев
  • Как в библиотеке пометить макрос, как unstable?

    vabka
    @vabka Куратор тега Rust
    Мне кажется, прямо в названии отражать, что он unstable не обязательно, ибо стабилизация существует только в рамках стандартной библиотеки - просто дай ему другое название и закрой за feature, которую можно включить только на nightly.

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

    @alexalexes
    MS Excel.
    Создаете таблицу с названиями колонок:
    Клиент, Цвет волос, Длина волос.
    Добавляете фильтры на заголовки таблицы и можете фильтровать по любой комбинации критериев.

    MS Access.
    Создаете аналогичную таблицу в СУБД.
    Добавляете формы и отчеты (уже не помню, что там в школьной программе делали).
    Ответ написан
    7 комментариев
  • Выбор программы или ЯП для создания приложения по обработке данных?

    Делать это всё на чистом экселе - умрёшь.

    Это очень пахнет отраслевым решением - такие редко делают бесплатные.
    Скорее всего какое-то специализированное решение для ресторанов уже имеет функции для работы с технологическими картами и складом (r_keeper и подобное, например)
    В ту же сторону - 1С, тем более что в этом соцучреждении уже наверняка 1С где-то используется.
    Ответ написан
    Комментировать
  • Как правильно добавлять столбцы в БД - в конец таблицы или логически группировать?

    @Everything_is_bad
    Просто в выборках явно указывай поля, а не тупо *. Либо извлекай в ассоциативный массив.
    Ответ написан
    Комментировать
  • Что выбрать: sqlite или redis?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Можно попробовать вот эту фичу (Redis Queue)
    https://redis.io/glossary/redis-queue/

    Не должно быть "слишком долго". Как раз как хочет автор. :)
    Ответ написан
    Комментировать
  • Как пояснить работу с типом &str?

    vabka
    @vabka Куратор тега Rust
    Для конкатенации строк нужно одно из двух:
    1. Одна из строк должна быть String, а не &str и тогда ты просто добавляешь к ней вторую
    2. Ты должнен в процессе конкатенации создавать новый String.

    А второй вариант у тебя не работает из-за того что ты дропаешь String, который был создан при конкатенации.

    Первый вариант имхо не очень читабельный получился. Лучше попробуй вот так:

    fn main() {
        let a = "x";
        println!("1. {:?}", a);   // "x"
    
        let b = format!("{}y", a);
        println!("2. {:?}", b);    // "xy"
    }


    Либо:
    fn main() {
        let mut s = "x".to_string();
        println!("1. {}", s);   // "x"
        s += "y";
        println!("2. {}", s);   // "xy"
    }
    Ответ написан
    6 комментариев
  • Какую базу данных использовать для хранения метаданных?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Основной use-case при работе с любыми данными это "запрос".

    Ты должен задать себе вопрос как я буду эти данные искать? По каким атрибутам?
    Например базы данных семейства key-value почти всегда всем подходят и всем нравятся
    за высокую скорость и дешевизну. Но это - только при условии что вы делаете поиск по ключевым атрибутам.
    Но вы не сможете к ним сделать агрегации (group by).

    Ничего плохого не могу сказать про Mongo. Но загрузи сначала туда хотя-бы сотню тысяч
    ситетических документов и смоделируй нагрузку. Вдруг Монга уже на этом этапе захлебнется
    и не потянет. Получается что твой выбор был неправильный.

    Из личного опыта. Часто выбирают какую-то БД из того что человек (команда) уже раньше
    с ней поработали и уже имеет опыт. И такое реально было и с Ораклом и с MS-SQL. Люди их
    выбирали не потому что они хороши а чаще всего потому что "так привыкли". И десяток
    лицензий были уже давно куплены. Почему-бы не использовать. Заказчик оплатил.
    Так жить проще. Так и живут. И так строят архитектуры.
    Ответ написан
    4 комментария
  • Элегантный способ парсинга и обработки ошибок?

    @0x0f80
    Например метод map_err. Статейка
    pub fn build_server_config(&self) -> Result<Config, ConfigError> {
        let socket_addr_v4 = self.socket_addr.parse::<SocketAddrV4>()
            .map_err(ConfigError::WrongSocketAddr)?;
        Ok(Config {
            // инициализация полей Config
        })
    }
    Ответ написан
    1 комментарий
  • Стоит ли начинать учить программирование с Golang?

    Maksim_64
    @Maksim_64
    Data Analyst
    1. Начинать с go не нужно. Это довольно нишевый язык, по которому будет крайне тяжело найти первую работу. Обычно go специалисты, это программисты с опытом которые в определенный момент добавляют его в свое портфолио.

    2. Платные курсы тоже не нужно, стоят они не дешево и это плохая инвестиция денег, учись бесплатно, а денежки пусть будут.

    В остальном определись не с языком, а что ты именно хочешь делать, в создании какого продукта принимать участие и под это дело подбирай язык, и не пытайся быть особенным, тебе нужен большой рынок и скромненькое местечко на этом рынке.
    Ответ написан
    5 комментариев
  • Знаю только Python и SQL. Нужно ли наращивать стек знаний перед попыткой смены работы?

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

    или мне в настоящее время стоит относить себя к т. н. «Разработчикам приложений» (по классификации «Хабр Карьеры»)

    То что ты описываешь - похоже на бэкендера.

    Нужны ли на рынке труда специалисты с таким стеком за такую зарплату

    Вопрос не имеет смысла, ибо он не отвечает на главный вопрос - найдёт ли конкретный соискатель себе рабочее место.
    надо заняться самообразованием, изучая, скажем связку FastAPI + Kafka + Kubernetes?

    Самообразование никогда лишним не будет.
    Ответ написан
    Комментировать
  • Где умные указатели размещают полученные данные?

    vabka
    @vabka Куратор тега Rust
    Cell<T> has the same memory layout and caveats as UnsafeCell<T>. In particular, this means that Cell<T>has the same in-memory representation as its inner type T.


    У остальных нет никаких обязательств о memory representation, но они тоже ничего в куче не выделяют.

    Ну и всегда можно посмотреть на исходники)
    https://doc.rust-lang.org/src/core/cell.rs.html#293
    https://doc.rust-lang.org/src/core/cell.rs.html#2034
    https://doc.rust-lang.org/src/core/cell.rs.html#700
    https://doc.rust-lang.org/src/core/cell/once.rs.html#33
    Ответ написан
    Комментировать
  • Выражение без эффекта перемещает переменную?

    @deliro
    Если bb; убрать, то всё работает, почему так? Никакого перемещения там не происходит, но компилятор думает иначе.

    Перемещение происходит. Семантически это выражение эквивалентно `{ bb }`

    Это точно системный язык на котором можно писать серьёзные вещи?

    Нет, язык херня. Беги писать на жс

    Или тут и правда происходит некое перемещение в параллельную вселенную?

    Хорошая привычка — агриться на вещи, которые ты не понимаешь. Далеко пойдёшь.
    Ответ написан
    3 комментария
  • Как работает этот код?

    bingo347
    @bingo347
    Crazy on performance...
    Очень упрощенно HashMap можно представить следующим образом:
    pub struct HashMap<K, V> {
        table: Table<(K, V)>,
    }
    
    struct Table<T> {
        // битовая маска занятых ячеек в items
        mask: u64,
        items: Box<[std::mem::MaybeUninit<Item<T>>; 64]>,
        len: usize,
    }
    
    struct Item<T> {
        data: T,
        next: Option<std::ptr::NonNull<Item<T>>>,
    }


    А Entry так:
    pub enum Entry<'a, K, V> {
        Vacant(VacantEntry<'a, K, V>),
        Occupied(OccupiedEntry<'a, K, V>),
    }
    
    pub struct VacantEntry<'a, K, V> {
        hash: u64,
        key: K,
        table: &'a mut Table<(K, V)>,
    }
    
    pub struct OccupiedEntry<'a, K, V> {
        elem: Bucket<(K, V)>,
        table: &'a mut Table<(K, V)>,
    }
    
    // указатель на Item.data
    struct Bucket<T> {
        ptr: std::ptr::NonNull<T>,
    }


    Как можно заметить у Entry есть лайфтайм, который связывает его с HashMap от которой он создан. А внутри есть мутабельная ссылка с этим лайфтаймом на таблицу с данными HashMap.
    Метод entry упрощенно выглядит примерно так:
    impl<K, V> HashMap<K, V> {
        pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V>
        where
            K: Eq + std::hash::Hash,
        {
            use std::hash::Hasher as _;
            let mut hasher = self.get_hasher();
            key.hash(&mut hasher);
            let hash = hasher.finish();
    
            if let Some(elem) = self.table.find(hash, |(k, _)| key == *k) {
                Entry::Occupied(OccupiedEntry {
                    elem,
                    table: &mut self.table,
                })
            } else {
                Entry::Vacant(VacantEntry {
                    hash,
                    key,
                    table: &mut self.table,
                })
            }
        }
    
        fn get_hasher(&self) -> impl std::hash::Hasher {
            todo!()
        }
    }
    
    impl<T> Table<T> {
        fn find(&self, hash: u64, is_match: impl FnMut(&T) -> bool) -> Option<Bucket<T>> {
            todo!()
        }
    }

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

    saboteur_kiev
    @saboteur_kiev Куратор тега Компьютерные сети
    software engineer
    Приложение может слушать сколько угодно портов.
    Можно даже один порт слушать двумя приложениями, есть даже такой вариант, но он редко используется.

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

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Разницы нет. Просто теперь потомки каждого узла лучше представлять в виде массива, по которому нужно итерироваться - без left и right

    void Visit(Node node) {
         for (auto child: node.children()) {
               stack.append(child);
         // Не так
         // if (node.left != nullptr) {
         //    stack.append(node.left);
         //  }
         // if (node.right != nullptr) {
         //    stack.append(node.right);
         //  }
       
    }
    Ответ написан
    1 комментарий
  • Как избежать дубликации кода реализуя Trait'ы в Rust?

    bingo347
    @bingo347
    Crazy on performance...
    Написать derive макрос. Правда стоит соизмерить трудозатраты.
    Или написать обычный декларативный макрос (не так гибко как derive, но написать проще).

    А вообще, Rust не Java/C#, trait - не интерфейс.
    Если приведете не абстрактные примеры, вполне возможно, что задача решается проще.
    Ответ написан
    Комментировать