Часто работодатели пытаются ввести нас в заблуждение сложными вопросами и логическими задачами. Это своего рода мозговой штурм, чтобы проверить кандидата не только на умение правильно решать сложные задачи, но и на время, за которое он приходит к правильным ответам.
Чтобы не ударить лицом в грязь, просмотрите нашу подборку из 15 нелегких вопросов с IT-собеседований по C++: она вам обязательно пригодится.
1. Что мы получим на выходе, исходя из условия?
Ответ: 8.
Думаю, объяснения излишни, но на всякий случай: «чтение» кода в плюсах происходит строго сверху вниз. Так что как в Java, где можно ниже мейна объявлять сколь угодно методов, а они все равно будут воспроизводиться в указанном порядке, сделать не получится.
2. Что будет выведено и почему?
Ответ не -25, не надейтесь.
Ответ (который удивит многих): 4294967271, предполагая 32-битные целые числа.
Почему так происходит?
Существует иерархия: long double, double, float, unsigned long int, long int, unsigned int, int. И когда два операнда определены как 25u (unsigned int) и 50 (int), 50 также будет интерпретироваться как беззнаковое целое число, то есть 50u.
Кроме того, результат операции также будет иметь тип операндов. Следовательно, результат 25u — 50u и сам является беззнаковым целым числом. Таким образом, результат -25 преобразуется в 4294967271.
3. Когда используется виртуальное наследование?
Распространенный вопрос с IT-собеседований. Когда есть класс (класс A), который наследуется от 2 родителей (B и C), оба из которых разделяют родителя (класс D):
Если вы не используете виртуальное наследование, то получите две копии D в классе A: один из B и один из C. Чтобы исправить это, вам нужно изменить объявления классов C и B следующим образом:
4. Что вообще означает модификатор virtual?
В C++ виртуальные функции позволяют поддерживать полиморфизм – одну из ключевых составляющих ООП. С его помощью в классах-потомках можно переопределять функции класса-родителя. Без виртуальной функции мы получаем «раннее связывание», а с ней – «позднюю привязку». То есть, какая реализация метода используется, определяется непосредственно во время выполнения и основывается на типе объекта с указателем на объект, из которого он построен.
5. Приведите пример использования виртуальной функции.
У нас есть 2 класса:
В основной функции:
Теперь сделаем так, что eat() будет вызываться посредством какой-нибудь промежуточной функции:
В основной функции:
Как это исправить, если мы захотим добавить больше животных? Просто делаем eat() виртуальной функцией:
Теперь в основной функции:
6. Есть ли разница между классом и структурой?
Единственное различие между классом и структурой – это модификаторы доступа. Элементы структуры являются общедоступными по умолчанию, а класса – private. Рекомендуется использовать классы, когда вам нужен объект с методами, а в случае с простым объектом – структуры.
7. В чем проблема следующего фрагмента?
Из спецификации (C++11 §5.3.5/3):
Если статический тип подлежащего удалению объекта отличается от его динамического типа, статический тип должен быть базовым классом динамического типа подлежащего удалению объекта и иметь виртуальный деструктор или поведение undefined.
8. Что такое класс хранения?
Класс, который определяет срок существования, компоновку и расположение переменных/функций в памяти.
В C ++ поддерживаются такие классы хранения: auto, static, register, extern и mutable.
Обратите внимание, что register устарел для C++11. Для C++17 он был удален и зарезервирован для будущего использования.
9. Как вызвать функцию C в программе на C++?
Еще один популярный вопрос с IT-собеседований, рассчитанный на новичков, совершенно не представляющих, как такое возможно. На самом же деле возможно, если использовать extern «C»:
10. Что делает ключевое слово const?
Ответ: задает константность объекта, указателя, а также указывает, что данный метод сохраняет состояние объекта (не модифицирует члены класса).
Пример с неизменяемыми членами класса:
11. Виртуальный деструктор: что он собой представляет?
Во-первых, он объявляется как virtual (об этом модификаторе мы писали выше). Он нужен, чтобы с удалением указателя на какой-нибудь объект был вызван деструктор данного объекта. Например, у нас есть 2 класса:
В итоге выполнится деструктор базового класса, а не производного. Это может поспособствовать утечке памяти. Если же до объявления деструкторов установить модификатор virtual, выполнится деструктор производного класса.
12. Виртуальный конструктор: что он собой представляет?
Каверзный вопрос с IT-собеседований, который чаще всего задают именно после виртуальных деструкторов, дабы сбить кандидата с толку. Конструктор не может быть виртуальным, поскольку в нем нет никакого смысла: при создании объектов нет такой неоднозначности, как при их удалении.
13. Сколько раз будет выполняться этот цикл?
Еще один вопрос с подвохом с IT-собеседований. Если бы вы сказали 300, а i был объявлен как int, вы были бы правы. Но поскольку i объявлен как unsigned char, правильный ответ – зацикливание (бесконечный цикл).
Объясняем. Выражение 2 * half_limit будет повышаться до int (на основе правил преобразования C++) и заимеет значение 300. Но так как i – это unsigned char, он пересматривается по 8-битному значению, которое после достижения 255 будет переполняться, поэтому вернется к 0, и цикл будет продолжаться вечно.
14. Каков результат следующего кода?
Ответ:
Здесь важно отметить порядок уничтожения классов и то, как метод класса Base возвращается к своей реализации после удаления А.
15. Что мы получим на выходе?
Ответ: 8.
- (1 + 3)[a] – то же, что и a[1 + 3]==5
- a[0]==1
- (a + 1)[2] – то же, что и a[3]==4
Суть вопроса заключается в проверке арифметических знаний и понимании всей магии, которая происходит за квадратными скобками.