15 популярных вопросов с IT-собеседований по языку C++

6
38238
Добавить в избранное

Мы собрали 15 самых каверзных вопросов с IT-собеседований по C++, на которые не просто желательно, а необходимо знать ответы.

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

Чтобы не ударить лицом в грязь, просмотрите нашу подборку из 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

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

Вас также могут заинтересовать другие статьи по теме:

Интересуетесь программированием на C++?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Комментариев: 6

  1. По вопросу №2 можно ссылку на документацию или стандарт про иерархию?

  2. Вопрос №1 — ответ: ничего такой код не выведет:

    4:4: error: expected constructor, destructor, or type conversion before ‘;’ token
    6:11: error: ‘::main’ must return ‘int’ In function ‘int main()’:
    8:7: error: ‘f’ was not declared in this scope At global scope:
    12:3: error: ISO C++ forbids declaration of ‘f’ with no type [-fpermissive] In function ‘int f()’:
    15:1: warning: no return statement in function returning non-void [-Wreturn-type]

  3. В 6 вопросе дополните, что различие еще в методе наследования по-умолчанию. У классов по-умолчанию наследование private, а у структур public

  4. В 13 вопросе не гарантированно будет бесконечный цикл. Размер типа char (и соответственно его signed и unsigned вариантов) является implementation defined. Соответственно на каких-то целевых платформах значение 300 вполне может в него влезать. Кроме того, размер типа int тоже implementation defined (от 16 бит и выше). Соответственно, может возникнуть ситуация, когда размеры типов char и int равны. Тогда цикл будет конечным при любых значениях half_limit.

  5. что за синтаксис ::x = 8; что означают эти двоеточия, не встречал такого ранее….

    1. Обращение к переменной уровнем выше

Добавить комментарий