All streams
Search
Write a publication
Pull to refresh
151
0
Евгений @Izaron

Программист C++

Send message

Может я старпер, но меня такое модернизированное определение понятия "владеть чем-то" не очень устраивает.

Как я понял, у нелохов 2022 edition принято ничего своего не иметь, и чем меньше у тебя имущества, тем больше ты нелох.

"Зачем своя машина, каршеринг круче"

"Зачем свой офис, коворкинг круче"

"Зачем свой дом, коливинг и хостелы круче"

"Зачем жена, гетеры круче"
и теперь "Зачем вообще владеть чем-то, вот тебе NFT, а само имущество побудет у других дядей"

Вы не ответили на прямой вопрос, наверное стоит повторить его еще раз

Что сейчас мешает opensea поменять как они хотят картинки на своем сервере?

Скорее на рынке огромный перекос в деньгах.

Когда MS купил Blizzard, кто-то откомментировался что капитализация Blizzard (4 700 сотрудников, производит компьютерные игрушки) больше капитализации Газпрома (500 000 сотрудников, крупнейшая в мире газотранспортная система, геологоразведка, добыча, нефть и т.д. и т.п.)

Это, конечно, довольно сложно объяснить. Но показывает, почему граждане "правильных" стран, не пуганные МММ, могут вкладывать миллионы долларов в фантики.

Опять же возникает вопрос, что более вероятно - что все картины отдадут в макулатуру и на месте Эрмитажа сделают картофельное поле, или что сайт отключат за "неуплату" и держатели бирок пойдут лесом?

Да, картины-подделки бывают, но обратите внимание - вы говорите про единичные случаи, тогда как в случае с NFT под сомнение ставится само понятие как таковое.

А чем современная банковская система не устраивает? Тем, что в ней намайнить бабла немножко сложнее, чем накупить асики и подключить к программке?

Таким образом - делаем в cron ежеминутную задачу - отслеживать конкретный лог-файл на предмет ключевого слова/фразы/цифры и т.д.

Мне кажется, это одно из худших проявлений Hyrum's law. Мне было бы неприятно, если после релиза с изменением логов стали стучаться в личку и требовать вернуть их назад, а то не считается статистика за день. Настолько "разумную жизнь" на основе логов надо убирать как можно быстрее.

Про "стиль C++" в списке, а именно про это

pub struct Item<T> {
    data: T,
    next: *const Item<T>,
}

pub struct List<T> {
    head: *const Item<T>,
}

Это скорее реализация std::forward_list (односвязный список), чем std::list (двусвязный).

В C++ можно передать кастомный аллокатор, если нет желания использовать дефолтный.

Эта строка:

data: T,

Что насчет placement new? В вашем примере объект создается и только потом мувается в это место, но он мог бы сразу создаваться. Это "стиль C++" с С++11. Вместо этой строки должен быть растовый аналог std::aligned_storage<T>, а в методе push - perfect forwarding аргументов.

Я имел в виду названия полей, то есть из записи

repeated string Pepper = 13;

В сериализованном виде слово "Pepper" пропадет, но к сожалению я не так прочитал абзац (неправильно понял), посчитал что "Pepper" и есть "ключ" (по аналогии с JSON).

последовательность бит из ключей и значений

На самом деле в сериализованном представлении ключи выкинуты (остались значения), так как считается, что контрагент знает про тот же .proto файл и может с его помощью расшифровать бинарный поток. Без .proto файла бинарный поток понять человеку/программе невозможно, читабельны только string-поля.

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

Для удобства можно считать, что нас вершин 1024 штуки (степень двойки специально), нумерация от 0 до 1023 включительно.

Можно завести `std::array<int, 1024> keys` (ключи отсортированы) и `std::array <int, 1024> values`.

Поиск по ключу займет не более чем 10 сравнений, по одному биту каждый раз. Индексы ключей у нас от `0000000000` до `1111111111`, поэтому надо смотреть ключ посередине - по индексу `1000000000`. Если он больше, то единицу отнимаем. И потом смотрим следующий бит.

    int some_key = XXX;
    int index = 0;
    for (int i = BYTES - 1; i >= 0; --i) {
        if (some_key >= keys[index + (1 << i)]) {
            index += (1 << i);
        }
    }
    return value[index];

Да уж, это насколько же программисту надо плохо думать о разработчиках компиляторов, чтобы полагать, что x /= 2 не заменится на x >>= 1 сам)

Да, язык хорошо живет без рефлексии много лет, но новый функционал это новые возможности.

Можно подсмотреть, что крутого есть в других языках. Фреймворк Spring в Java в этом плане очень мощно развит.

Так выглядит обработчик http-запросов:

в Java
@RestController
class EmployeeController {

  private final EmployeeRepository repository;

  EmployeeController(EmployeeRepository repository) {
    this.repository = repository;
  }

  @GetMapping("/employees")
  List<Employee> all() {
    return repository.findAll();
  }

  @PostMapping("/employees")
  Employee newEmployee(@RequestBody Employee newEmployee) {
    return repository.save(newEmployee);
  }

  @GetMapping("/employees/{id}")
  Employee one(@PathVariable Long id) {
    return repository.findById(id)
      .orElseThrow(() -> new EmployeeNotFoundException(id));
  }

  @DeleteMapping("/employees/{id}")
  void deleteEmployee(@PathVariable Long id) {
    repository.deleteById(id);
  }
}

Примерно так можно бы сделать в C++, когда доработают поддержку пользовательских атрибутов:

в C++
class [[rest_controller]] employee_controller {
public:
    void set_component(std::shared_ptr<employee_repository> repository) {
        _repository = std::move(repository);
    }

    [[get_mapping("/employees")]]
    std::vector<employee> all() {
        return _repository.find_all();
    }

    [[post_mapping("/employees")]]
    employee new_employee([[request_body]] employee new_employee) {
        return _repository.save(std::move(new_employee));
    }

    [[get_mapping("/employees/{id}")]]
    employee all([[path_variable]] size_t id) {
        std::optional<employee> e = _repository.find_by_id(id);
        if (e.has_value()) {
            return std::move(*e);
        }
        throw employee_not_found_exception(id);
    }

    [[delete_mapping("/employees/{id}")]]
    void delete_employee([[path_variable]] size_t id) {
        _repository.delete_by_id(id);
    }

private:
    std::shared_ptr<employee_repository> _repository;
};

В C++ типы всех значений вычисляются в процессе компиляции и жестко фиксированы. "Тип" auto это просто синтаксический сахар, все равно это будет какой-то реальный фиксированный тип.

Все переменные/объекты занимают какое-то количество байт на стеке, и это количество нужно знать заранее, иначе, например, непонятно как вычислить размер stack frame у функции (ассемблеру нужно это знать).

Вот такого в C++ не будет скорее всего никогда:

auto list = create_list();
// ^^^ тип list вычислится в РАНТАЙМЕ,
// будет std::vector<int>/std::vector<std::string>/другой

Аналог того, что происходит в C#/Java, на C++ выглядит скорее как использование std::any, который аллоцирует нужное количество байт для объекта в куче (в отличие от стека, там необязательно знать объем выделяемой памяти в compile-time). Можно иметь один из типов в рантайме:

std::any create_list(int n) {
    if (n == 0) {
        return std::vector<int>();
    } else if (n == 1) {
        return std::vector<std::string>();
    } else {
        return std::vector<char>();
    }
}

int main() {
    int n;
    std::cin >> n;

    auto list = create_list(n);

    if (list.type() == typeid(std::vector<int>)) {
        std::cout << "got vector of int" << std::endl;
    } else if (list.type() == typeid(std::vector<std::string>)) {
        std::cout << "got vector of string" << std::endl;
    } else if (list.type() == typeid(std::vector<char>)) {
        std::cout << "got vector of char" << std::endl;
    }
}

Ради справедливости, высокочастотный трейдинг это не совсем "типичная" C++ программа.

Если, например, писать реалтаймовую программу по обработке аудио-сигналов (где тоже своя атмосфера), то мы связываем себе руки в направлении:

  • не блокировать поток (не пытаться завладеть мьютексом, память аллоцировать строго на стеке, не делать I/O - в общем, не делать системных вызовов)

  • не пользоваться алгоритмами сложности >O(1) / амортизированной сложности

  • по возможности использовать статический полиморфизм вместо динамического

Поэтому не стоит сравнивать какие-то гиперболизированные свойства.

То, что сортировка станет вдвое быстрее для 99.9% остальных программ - это же круто? В больших корпорациях ускорение на 2-3% это огромные деньги.

  • Пиши в хидерах код а-ля using namespace std; - коллеги скажут спасибо, за то что им не придется это писать в каждом .cpp!

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

  • Функция должна вернуть больше чем одно значение? Есть крутой лайфхак - записывай результаты в указатель! Для трёх значений это int process(int arg, int* res2, int* res3).

У меня возник похожий вопрос - а сами студенты перед поступлением в распоряжение к топикстартеру в курсе о гарантированном no hire в Huawei/Intel/Nvidia/etc.?

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

Откуда такой миф, что заниматься "наукой" это нереально здорово, почти как быть сверхчеловеком?

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

Вы теперь миллиардер? Нет, все сливки снимет братва с фармкомпаний и академическая мафия, а ты как ехал на маршрутке, так и будешь ехать дальше, ведь у тебя !ПРИЗВАНИЕ! работать за 14-20к.

Про студентов: а кто постановил, что они обязаны работать в науке, особенно под вами? От школьников в 10-11 классах ведь не ждут, что они будут вести уроки за учителей. Так и студенты - они идут в вуз ввиду отсутствия альтернатив (у 95% элементарно откосить от армии), а там у какой-то деловой колбасы на них "виды" в своих корыстных целях. Учитесь работать в рыночной экономике.

С уважением, ваш Фрай

У нас некоторые преподы сходили с ума и присылали какой-то бред

Правила сдачи одного из экзаменов

Скрипт хороший. Жаль только, что многие преподаватели (в основном еще видевшие живого Ленина) ОЧЕНЬ волнуются, если кто-то не слушает именно их пересказ учебника в 8:45, поэтому любят просить включать камеры, задавать рандомные вопросы рандомным людям в рандомное время, и так далее.

Information

Rating
Does not participate
Registered
Activity