Как стать автором
Обновить

Комментарии 29

В описании вакансий часто можно встретить 2 отдельных требования — знание C++ и знакомство с STL.

Смею предположить, что когда STL фигурирует в вакансии, ожидается не только знакомство, но и знание внутреннего устройства базовых реализаций контейнеров/алгоритмов и скорости работы. Однажды проходил собеседование без должной подготовки и не смог рассказать ничего внятного про std::map (спойлер: не прошёл).


За подборку большое спасибо.

По моей статистике, вопросы про назначение и преимущества\недостатки контейнеров std::map и std::deque ставят в затруднительное положение даже разработчиков с многолетним стажем в C++.

Еще есть вероятность, что человек занимается разработкой под встраиваемые системы и там часто no std

Про SBO возможно стоит упомянуть трюк из С, но для этого придётся переставить порядок элементов — последним должен идти массив символов (по-моему flexible array member можно даже нулевого размера). Можно выделить через alloca нужный размер (больше чем сам struct), после чего обращаться к символам вне диапазона задекларированного массива.
Удобно при работе c POD
TMP — Шаблонное метапрограммирование
CV — const volatile (qualifiers)
ABI — упомянута но не раскрыта
LTO — оптимизация линковки
PCH — pre compiled header
PGO — оптимизация по результатам профайлинга
SEH\VEH — обработчики исключений (win)
VLA — фича из C но употрбляется и в С++ контексте
Про ABI будет во второй части. Остальное добавлю кратким списком, спасибо.
В тему UB вспомнилась аббревиатура NDR no diagnostic required.
После C++ переходить на Java это такое облегчение)
Не хотелось бы начинать бесполезный спор, но не соглашусь :) Отсутствие в Java таких банальных вещей, как беззнаковые целые и значения аргументов по умолчанию обескураживает.

Значение аргументов по умолчанию — зло :) Поубивал бы людей, которые их придумали) Столько дебильных багов из-за них словлено и отыскать их в коде оч трудно глазами.


Особенно они хороши в таких замечательных вещах, как виртуальные функции :) Например что выведет этот код:


struct A {
    virtual void foo(int a = 5) 
    {
        std::cout << a << std::endl;
    } 
};

struct B : A
{
      void foo(int a = 7) override
      {
         std::cout << a*2 << std::endl;
      }
};

A a;
B b;

auto pa = dynamic_cast<A*>(&b);

pa->foo();

В целом, никакого глубокого познания в С++ не требуется, чтобы понять что этот код должен вывести, но в первый раз я впал в ступор потому что даже после пяти лет на плюсах я был НЕ УВЕРЕН в ответе, хоть и дал его правильный, когда спрашивали :)

А об этом, кстати, отдельно написано в книжке Майеса, довольно старой уже :)
В общем, подводных камней везде хватает, просто к C++ я уже привык.

Были б безболезненные типы может и багов было чуточку меньше.

Если кому-то интересно почему: значения аргументов по-умолчанию связываются статически (при компиляции). Поэтому они определяются статическим типом указателя. В данном случае pa имеет тип A*. Соответственно вызывается виртуальная B::foo() с аргументом a = 5.

Ну, тогда стоит отметить, что помимо аргументов по умолчанию, статически привязана и сигнатура функции. Несмотря на то, что вызывается B::foo(), мы об этом узнаем только в рантайме, поэтому не будет работать следующий код:


struct A {
    // Нет аргумента по умолчанию!
    virtual void foo(int a) {  
        std::cout << a << std::endl;
    } 
};

struct B : A {
      void foo(int a = 7) override {
         std::cout << a*2 << std::endl;
      }
};

A a;
B b;

auto pa = dynamic_cast<A*>(&b);

pa->foo(); //Ошибка в сигнатуре A::foo(), нет default аргумента.
Для меня основное разочарование в Java/c# это отсутствие приватного наследования, невозможность иметь невиртуальные функции/конструторы в интерфейсе (иными словами отличие интерфейса от класса). Отсутствие нормальной const логики (именно как в плюсах).

В недостатках CRTP


И вообще, у потомков есть публичные методы, которые нигде, кроме базового класса, использоваться не должны. Это нехорошо, но исправляется через дополнительный уровень абстракции (см. FTSE во второй части).

А что мешает писать так?


class Derived : Base<Derived>
{
private:
  friend Base<Derived>;
  void actionImpl() const { ... }
};
Ничего не мешает, но это все равно усложняет код и взаимоотношения классов.
Раз уж зашёл разговор о вопросах на собеседованиях. В Нидерландах как обстоят дела на собеседовании с такими вот вопросами по аббревиатурам и тому же STL? Есть отличия в том, что понимают под STL когда пишут у нас и у них?
Из того, что я сам испытал в Нидерландах, могу сказать, что на технических скиллах тут не зацикливаются. Если решил задачаки на Hackerrank/Leetcode/где-то еще — молодец, давай обсудим твой опыт.
Сколько их там нарешать нужно?
Немного, штуки 3-5.
Тривиальные вещи тоже можно не пропускать – это было бы полезно и начинающим прогерам, и любопытствующим из совсем других стеков технологий вроде меня (:
По моему у автора ошибка в RVO и NRVO примере.
Где именно?
Слона-то я и не заметил. Спасибо.
Только я заметил, что в статье нет описания аббревиатур из вводной части «DRY, KISS, YAGNI, NIH»? Вам так и не удалось найти их описания? :)

Ой! Оказывается они во второй части описаны.

Еще не хватает Ro5 - Rule of 5.

Перед каждым собеседование перечитываю. Спасибо за ясное изложение)

Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории