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


Оглавление (нажмите, чтобы открыть):

Дневник программиста

среда, 1 августа 2012 г.

Как я провалил собеседование по теме C/C++/Linux

Подробности того, как я провалил простое собеседование

    Содержание
  • Предисловие
  • Практические вопросы
  • Теоретические вопросы
  • Комментарии к практическим вопросам

Предисловие

Не так давно, на мою электронную почту пришло сообщение от рекрутёров, представляющих одну очень известную и очень крупную компанию, работающую на мировом рынке электронных устройств. По разного рода этическим соображениям я не буду уточнять название компании. Тема сообщения, как вы догадались, была приглашением на собеседование. Следуя принципу «от меня не убудет», а также подогреваемый любопытством и амбициями, я, после двадцатиминутного телефонного разговора с позвонившим мне агентом из этого рекрутского агентства, согласился.

Сегодня состоялось собеседование по скайпу с сотрудниками компании. Собеседование я, с большой долей вероятности, провалил. Прежде всего из-за элементарного недостатка знаний по некоторым деталям. Хотя, пару-тройку вопросов я элементарно не додумал. Так часто бывает в обстановке экзамена 🙂

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

Также, хочу добавить, что я крайне отрицательно отношусь к собеседованиям вообще. Во-первых, мало кто в состоянии вести себя на собеседованиях адекватно. Как не крути, а наличествует некоторый стресс. Даже в случае, если ты пришел на собеседование просто так, для «пощекотать нервы» (Думаю, что многие согласятся с тем, что надо всегда находится в поиске и не отказываться априори от того, что может сулить какие-то перспективы. Пусть и несбыточные.) Во-вторых, умение писать код и разбираться в вопросах на собеседовании не проверить. Для этого надо обязательно проводить тестовое задание.

Как бы там не было, думаю, что многим интересны будут вопросы, которые могут задать по профилю C/C++/Linux. Именно этим профилем занимаюсь я, и именно по этому профилю было проведено собеседование, отчёт о котором я хочу здесь представить.

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

Практические вопросы

Системный вызов fork(), стандартные потоки ввода/вывода

  1. Что вы можете сказать о следующем фрагменте кода? Есть ли в нем ошибки? Дайте максимальные комментарии о работе этого кода.
  2. Откомпилируется ли представленный фрагмент кода? Если откомпилируется, то что будет при запуске?
  3. Нужно ли изменить программу в строке с вызовом fprintf(), чтобы надпись «Hello» печаталась два раза? Если нужно, то как?
  4. Нужно ли изменить программу в строке с вызовом fprintf(), чтобы надпись «Hello» печаталась один раз? Если нужно, то как?

Знаковые и беззнаковые типы разной ёмкости

Что будет лежать в A после исполнения следующего фрагмента кода?

Виртуальный деструктор

Что будет напечатано при исполнении следующего фрагмента кода? Максимально прокомментируйте этот код. Есть ли в нем принципиальные ошибки и, если есть, то как их исправить?

Игры с указателями

Что будет содержаться в массиве a после исполнения представленного ниже кода?

Односвязный список

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

Теоретические вопросы

Теоретические вопросы я оставлю практически без комментариев. Они достаточно чёткие в своей постановке и если кто-то чего-то не знает, то может найти это в литературе или в сети Интернет без особых проблем.

  1. Что такое виртуальная память? Что в процессоре ответственно за реализацию виртуальной памяти?
  2. Что вы можете рассказать об архитектурах CISC и RISC? Основные особенности и различия.
  3. Как работают системные вызовы? Как переносятся параметры системного вызова?
  4. Расскажите о системном вызове fork(). Что передается в копию процесса?
  5. Что такое виртуальный конструктор?
  6. Сколько таблиц виртуальных методов может быть в объекте класса? От чего это зависит? Что можно сказать о размещении указателей на них?
  7. Можно ли в конструкторе вызывать виртуальные методы?
  8. Что вы можете рассказать о различиях между std::vector и std::list в плане их внутренней реализации?
  9. Как должен быть оформлен класс, чтобы его объекты могли храниться в std::vector?
  10. Чем отличается процесс от потока?
  11. Разделяют ли потоки стек?
  12. Что такое мьютекс? Что такое семафор? Можно ли семафор использовать для синхронизации процессов?
  13. Какие вы знаете средства взаимодействия процессов? Могут ли процессы иметь общую память?

Хочу дать единственный комментарий к вопросу о количестве таблиц виртуальных методов. Прежде чем отвечать наверняка вспомните и подумайте о множественном наследовании. Здесь вас могут легко запутать.

Комментарии к практическим вопросам

Системный вызов fork(), стандартные потоки ввода/вывода

Конечно же в представленном коде есть ошибки. Прежде всего, нулевой указатель на поток не приведет ни к чему хорошему, учитывая, что здесь, очевидно, хотят сделать вывод строки в поток. Такой код откомпилируется, так как синтаксически он корректен, но приведет к segmentation fault.

Если в качестве потока вывода указать поток stdout, т.е. написать fprintf(stdout, «Hello»), то надпись будет выведена два раза, так как поток stdout буферизируется и при создании копии процесса, также будет сделана копия буферов stdout. Поэтому, при завершении обоих процессов, буферы каждого будут сброшены и на терминале появятся две надписи «Hello».

Если в качестве потока вывода указать поток stderr, т.е. написать fprintf(stderr, «Hello»), то надпись будет выведена только один раз, так как поток stderr не буферизован и поступившие в него данные сразу будут выброшены на устройство вывода связанное с данным потоком. Функция fork() будет выполнена только после этого.

Знаковые и беззнаковые типы разной ёмкости


Что будет лежать в A после исполнения следующего фрагмента кода?

Тип char представляет собой знаковый однобайтовый тип, поэтому число 128, которое будет в него записано будет интерпретироваться как отрицательное число в дополнительном коде. Следовательно, при обратном присвоении мы получим число (-128).

Виртуальный деструктор

Код представляет собой проблему из-за того, что не имеет виртуального деструктора. В результате, объект, созданный как Son, но хранящийся как Father не будет иметь в своей таблице виртуальных методов указание на деструктор подкласса и будет уничтожен как объект класса Father. Вообще, говоря, данный объект вообще не будет иметь таблицы виртуальных методов, так как он не имеет ни одного виртуального метода.

Ситуация представленная в этом примере является более чем «классикой жанра» и может быть найдена в любом пособии при разговоре о виртуальных деструкторах.

Игры с указателями

Имя массива в C/C++ является адресом его начального элемента. Приведя этот адрес к указателю на целое число мы получаем указатель на следующие четыре байта целого (для вычислительных систем, где int занимает четыре байта). Инкремент этого указателя сдвигает адрес указателя на четыре байта (столько занимает начальный элемент массива из элементов типа int). Следовательно разыменуемый адрес указывает на четыре байта памяти, сдвинутые относительно исходного адреса на четыре байта. После обнуления этих четырех байт мы получим, что в массиве a будет лежать «1111\000\000\000\0001111». В этой записи, согласно стандарту Си, литерал ‘\000’ представляет собой восьмиричную запись однобайтового значения.

Односвязный список

Вот по поводу этого вопроса я ничего сказать не могу. Априори был уверен, что сделать это нельзя. На собеседовании меня уверили, что можно. Буду думать. Если придумаю, то может найду время написать об этом.

Некоторые из тех, кому я уже рассказал об этой задачке предполагают, что речь идёт о кольцевом односвязном списке. Однако слово «кольцевой» в вопросе, насколько я помню, не звучало. Как умолчание я бы посчитал это нелепицей. Да и если речь идёт о кольцевом односвязном списке, то это было бы слишком просто. Хотя, судя по тому, что все вопросы были достаточно простые, то, может быть, так оно и есть.

И еще один момент. Я специально спрашивал насчёт указателя на начало списка. Указатель не дали. И ещё раз уточнили. Дан односвязный список и указатель только на тот внутренний элемент списка, которые требуется корректно удалить. В общем, выглядит задачка как полный бред. Как заметил один мой коллега, Дубровин Алексей, за эту задачу компании должна быть назначена премия Тьюринга по теме «Как утечку памяти превратить в связанный список» :).

Спустя неделю. Прошла неделя с момента публикации этого сообщения и я подумал, что имеет смысл опубликовать размышление моих коллег по этой задаче. Сначала коллеги из «Мирантис», потом Михаил Сёмичев из «ЕПАМ» (все это наши местные отделения распределенных аутсортинговых компаний) и, наконец, Владимир Легкий из компании «Волга-софт» предположили, что возможно речь идет о следующем решении. Если не заниматься движениями указателей, а выполнить смещение данных относительно удаляемого элемента, то решение получается простое, но имеет одно ограничение. Оно не работает для случая, если указатель задачи указывает на последний элемент.

Поясню решение. Оно может быть в нескольких вариантах, но в одной сути.

Один из вариантов предпологает, что мы выполним циклический сдвиг данных по элементам списка относительно указываемого элемента. Тогда данные из указываемого элемента пропадут (чем не удаление элемента), а два последних элемента списка будут иметь одинаковые продублированные данные. Последний элемент, в этом случае, мы можем без проблем удалить.

В другом, более хитром и более эффективном применении идеи о перемещении данных, мы можем сделать полную копию следующего элемента в указываемый по задаче. Т.е. буквально сделать memcpy(). Перед этим надо сохранить указатель на следующий элемент с тем, чтобы после выполнения «сырой» копии удалить следующий элемент.

прикладная математика

Примеры вопросов для программистов С++ на собеседованиях

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

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

Зачем все это?
Хочется собрать реальные вопросы и ответы на них в одном посте. Т.к. меня не устраивают те, что я вижу в интернете, они порой слишком размазанные (например, 75 страниц на геймдеве), или рассматривающие всего несколько примеров, или с ошибками, которые уже никто не исправит, или с ссылками на уже мертвые топики, или какие-то надуманные,… список можно продолжать.

В общем хочется иметь список с самыми популярными вопросами по данной теме, и если, вдруг, понадобится освежить знания, чтобы не приходилось лезть в какие-то записки, запускать IDE или гуглить, а можно было открыть одно место и там все прочитать.

Наиболее интересной данная тема должна показаться тем, кто еще только начинает свои шаги в этом безграничном море под названием C++.

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

Какая будет структура этих вопросов?
Линейный список. Вопросы будут добавляться по мере поступления, я постараюсь не забрасывать данный раздел и обновлять его. В конце я буду ставить дату последнего обновления, чтобы было понятно когда список меняли последний раз.

Сейчас я планирую написать первые 20 вопросов, а если эта тема будет востребована, то буду постепенно добавлять новые.

У вас ошибка в коде, как вы ее проглядели?
Людям свойственно ошибаться и я не считаю себя гуру способному писать безошибочно. И это C++, здесь вероятность ошибиться еще больше.

Если вы видите ошибку, напишите о ней, и я обязательно ее исправлю.

1. Зачем нужен виртуальный деструктор?
Ответ: Чтобы избежать возможной утечки ресурсов или другого неконтролируемого поведения объекта, в логику работы которого включен вызов деструктора.
Пример:

Без ключевого слова virtual у родительского класса Base деструктор порожденного класса не был бы вызван. Т.е. вызвался бы только

Наглядный пример возможной утечки в следующем вопросе.

2. Что стоит помнить при использовании исключений в конструкторе объекта?
Ответ: Если исключение не обработано, то c логической точки зрения разрушается объект, который еще не создан, а с технической, так как он еще не создан, то и деструктор этого объекта не будет вызван.
Пример:

Я немного модифицировал предыдущий пример, чтобы проблема была наглядней. Здесь объект m_hFile (если был открыт) утечет т.к. до CloseHandle() выполнение не дойдет. Т.е. имеем такие же проблемы как в первом примере: возможная утечка ресурсов или другие проблемы из-за нарушения логики работы класса.

Мастер Йода рекомендует:  Model в MVC на PHP

Здесь могут спросить: «Как бы вы поступили при подобной ситуации». Правильный ответ: «Воспользовался бы умными указателями». Простой пример умного указателя:

Теперь и без вызова деструктора Base хэндл будет закрыт, т.к. при уничтожении класса Base будет уничтожен объект m_hFile класса CHandle, в деструкторе которого и будет закрыт хэндл.

Изобретать велосипед, конечно, не надо, все уже написано до нас, это пример который можно написать на бумажке при соответствующем вопросе. А так есть boost, Loki, ATL и т.п., где это уже реализовано.

3. Для каких целей применяется ключевое слово const?
Ответ:
Позволяет задать константность объекта
Позволяет задать константность указателя
Позволяет указать, что данный метод не модифицирует члены класса, т.е. сохраняет состояние объекта
Пример 1. Не можем изменить значение объекта:

Пример 2. Не можем изменить указатель на объект:

Пример 3. Не можем изменить члены класса:

Дополнение: константный метод может изменять члены класса, если они объявлены как mutable.

4. Можете ли вы написать пример какого-нибудь алгоритма сортировки?
Ответ: Пузырьковая сортировка, для контейнеров, без временных переменных:

5. Можете ли вы написать код для переворота строки?
Ответ: Код переворота строки для контейнеров, без временных переменных, не осуществляющий прохода по всей строке:

6. Как защитить объект от копирования?
Ответ: Сделать private конструктор копирования и оператор =.
Пример:

7. В чем разница между struct и class?
Ответ: Практически ни в чем. В struct модификаторы доступа по умолчанию public, в class private. Также отличается и наследование по умолчанию, у structpublic, у classprivate.
Пример:

8. Каким свойством должен обладать объект, чтобы его можно было добавить в ассоциативные контейнеры в качестве ключа?
Ответ: Т.к. значения в ассоциативных контейнерах хранятся отсортированными, то объект должен реализовывать оператор сравнения


Тесты на синтаксис с++, собеседование на джуниора

22.09.2014, 11:01

Портфолио джуниора
Всем привет. Посоветуйте, пожалуйста, какое портфолио создать джуниору на C#. Какие программы.

тесты(систем продуктов программ.)тесты.
тесты,плиз кто умеет. токо овтет кратко,например 2-а,и т.д. заранее благодарю и спс.

Наставник для джуниора
Здравствуйте. Обращаюсь к более-менее опытным пользователям Джава. Я студент и есть крошечный опыт.

Тестовое задание для джуниора на C#
Всем привет. Много раз читал и слышал что работодатели любят проверять знания джуниоров тестовыми.

Приоритетные знания для джуниора
Добрый день. Устроился недавно на свою первую работу в качестве веб программиста. Работается.

22.09.2014, 11:05 2 22.09.2014, 11:09 3

Добавлено через 3 минуты

22.09.2014, 12:17 4

Мб всё-таки не взяли за то, что плюнул

Тест, как правило, позволяет отсеять львиную долю некомпетентных спецов + сократить время собеседования. Но истинная проверка начинается лишь при общении с человеком. В нормальных конторах могут и задачи на логику позадавать (на quizful также смотрите вопросы собеседования).

22.09.2014, 12:17
22.09.2014, 12:35 5
22.09.2014, 12:50 6
22.09.2014, 13:49

Меню пользователя Tulosba
22.09.2014, 14:50 8
19.01.2020, 23:56 9
20.01.2020, 01:40 10

В современных реалиях предпочтительно разделять тесты по C++ по стандартам.

20.01.2020, 02:17 11
20.01.2020, 02:21 12

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

Добавлено через 2 минуты
C++ средний уровень не смог пройти т.к. не вышло зарегаться (а это обязательное условие)
На почту пришло

20.01.2020, 02:25 13
20.01.2020, 02:57 14
20.01.2020, 03:30 15

Мне и по второй не понятно. Почему в тесте вариант int $; помечен как корректный для создания переменной.
В С++ разрешено называть переменные если:
1. Они состоят из символов латиницы верхнего/нижнего регистра, цифр и символа подчёркивания.
2. Они не должны начинаться с цифры.
3. Они не должны совпадать с каким-либо ключевым словом, зарезервированным для конструкций языка.

Переменные с символом $ разрешены в некоторых языках, но С++ к ним не относится.

Добавлено через 3 минуты
Гугление показало, что некоторые компиляторы разрешают создание переменных с $, это расширение языка и в стандарт не входит. А тест должен быть по стандарту, а не расширениям.
https://stackoverflow.com/questions/7926394/in-variable-name

Добавлено через 6 минут
Standart:

identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
identifier-nondigit:
nondigit
universal-character-name
other implementation-defined characters

An identifier is an arbitrarily long sequence of letters and digits. Each universal-character-name in an
identifier shall designate a character whose encoding in ISO 10646 falls into one of the ranges specified
in E.1. The initial element shall not be a universal-character-name designating a character whose encoding
falls into one of the ranges specified in E.2. Upper- and lower-case letters are different. All characters are
significant.

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

Из своего опыта знаю что программистом С++ устроиться на хорошее место очень сложно. К программистам на этом языке предъявляют очень высокие требования и очень обширного набора знаний. Второй интересный аспект данного вопроса, почему к программистам на C++ предъявляют обязательное требование знать Qt и даже при наличии хороших знаний по C++/STL и смежных направлений без знания данной библиотеки кандидатов даже не рассматривают. Третий аспект, это что на C++ без огромного опыта работы по трудовой берут только молодых специалистов. Если устраиваться программистом C#/JS/SQL на даже большие деньги при тестировании вопросы в разы проще, типа напишите пару SQL запросов и как в коде работают замыкания плюс на ошибки смотрят сквозь пальцы.
Приведу несколько примеров:
1) На собеседовании помимо С/С++ были задания на знание Win32 API и в частности Threads, хотя это не подразумевалось.
2) На собеседовании по C/C++ не было ни одного вопроса по данному языку, а только тесты по алгебре и геометрии, например — разделить прямоугольник с выбитой окружностью на две равные по площади фигуры с помощью прямой или другое задание — сколько не пересекающихся плоскостей можно провести через 4 точки не лежащие в одной плоскости и помимо решений привести доказательства. Хотя анонсировано было только тестирование C/C++ и векторная алгебра.
3) В задании было написано что принимаются работы на OpenGL и DirectX, но в итоге кандидатов с решениями на DirectX не рассматривают.
4) Выполнив задание для очень крупной компании на DirectX 12 (предложили разобраться) и убив очень много времени что бы выучить данную библиотеку даже не отвечают на письма. И как оказалось DX12 промышленно почти ни кто не использует.
5) Поставленные задачи необходимо решать только на определенных алгоритмах, например для задач со строками необходимо обязательно пользоваться логикой указателей, а все другие решения считаются неправильными.
6) Если вы где то ошиблись то вам в конце обязательно заявляют что в данной компании необходим человек который сразу может решать задачи компании и что вы не являетесь таким человеком или что вы в принципе не умеете решать задачи по математике или геометрии или чему то еще.

oioki.ru

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

1. Функция gets()

Вопрос: В приведенной программе есть проблема. Можете её найти?

Ответ: Скрытая проблема в этом коде – это использование функции gets(). Эта функция принимает строку со стандартного ввода без проверки размера буфера, в который будет помещена эта строка. Это запросто может привести к переполнению буфера. В данном случае лучше использовать другую стандартную функцию – fgets().

2. Функция strcpy()

Вопрос: Приведенный код реализует простейшую защиту по паролю. Можно ли вы взломать эту защиту, не зная пароля?


Ответ: Да. Логику кода аутентификации, приведенного выше, можно обойти при помощи уязвимости в функции strcpy(). Эта функция копирует пароль, предоставленный пользователем, в буфер ‘passwd’, не проверяя, достаточно ли в этом буфере места. Предположим, что пользователь введет случайный пароль, имеющий длину достаточную для того, чтобы заполнить как буфер ‘passwd’, так и перезаписать область памяти, содержащую изначальное значение ‘0’ переменной ‘flag’. В этом случае, даже если сравнение введенной строки и пароля не пройдет, то все равно проверка флага, который изначально имел нулевое значение, станет ненулевым, и таким образом, защита будет “взломана”.

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

Для защиты от подобных случаев следует пользоваться функцией strncpy().

Замечание от автора: В наши дни компиляторы стали довольно умными – они автоматически отлавливают подобные случаи и располагают переменные на стеке таким образом, чтобы значительно усложнить взлом стека. В моем случае, компилятор gcc включил эту опцию по умолчанию, и поэтому мне пришлось воспользоваться обратной опцией ‘-fno-stack-protector’, чтобы воспроизвести традиционное поведение компилятора.

3. Тип возвращаемого значения функции main()

Вопрос: Скомпилируется ли следующий код? Если да, то какие проблемы могут возникнуть?

Ответ: Этот код скомпилируется без ошибок, но с варнингом (на большинстве компиляторов) о том, что значение, возвращаемое функцией main(), должно иметь тип ‘int’, а не ‘void’. Тип ‘int’ позволяет программам возвращать код статуса, что очень важно, когда программа выполняется как часть скрипта, и внутри скрипта есть условия, которые зависят от результата выполнения программы.

4. Утечка памяти

Вопрос: Приведет ли следующий код к утечкам памяти?

Ответ: Конечно, этот код не освобождает память после ее выделения, но это не приведет к утечке памяти, ведь программа завершается почти сразу же. Операционная система автоматически очищает всю задействованную программой память, при ее завершении. Однако, если вышеприведенный код будет находиться в цикле вроде while, это приведет к серьезным утечкам памяти.

Замечание: Если хотите узнать больше об утечках памяти и о том, как их отлавливать, прочтите нашу статью о Valgrind.

5. Функция free()

Вопрос: Следующая программа вылетает с ошибкой сегментации, если ввести ‘freeze’. Однако если ввести ‘zebra’, то все будет хорошо. Почему?

Ответ: Здесь проблема заключается в том, что код изменяет адрес указателя ‘ptr’ (путем инкремента переменной ‘ptr’) внутри цикла while. Когда пользователь вводит ‘zebra’, цикл while завершается без единой итерации, поэтому адрес, переданный функции free(), будет точно такой же, какой был присвоен функцией malloc(). Однако в случае с ‘freeze’, значение переменной ptr изменяется внутри цикла while, что приводит к передаче неправильного адреса в функцию free() и ошибке сегментации.

6. Функции atexit и _exit

Вопрос: В следующем коде функция func() не вызывается. Почему?

Ответ: Из-за функции _exit(). Эта функция не вызывает функции очистки вроде atexit(). Если нужно, чтобы функции atexit() все-таки вызывались, нужно воспользоваться exit() или ключевым словом return.

7. void* и структуры C

Вопрос: Напишите функцию, которая принимает аргумент любого типа, а возвращает int. И еще, можно ли будет передать ей более чем один аргумент?

Ответ: Функция, которая принимает аргумент любого типа, выглядит так:

Если нужно передать более одного аргумента, тогда этой функции нужно передавать в качестве аргумента — указатель на структуру, а в полях структуры — аргументы, которые нужно передать.

8. Операторы * и ++

Вопрос: Что напечатает данная программа и почему?

Ответ: Программа выведет следующее:

Так как приоритет операторов ‘++’ и ‘*’ одинаков, то обработка ‘*ptr++’ будет осуществляться справа налево. Следуя этой логике, сначала вычисляется ptr++, а затем *ptr. Таким образом, получаем ‘L’. Так как к ptr был применен постфиксный оператор ‘++’, второй printf() напечатает ‘i’.

9. Редактирование в сегменте кода

Вопрос: Следующий код завершается с ошибкой сегментации. Объясните, почему?

Ответ: Потому что операция *ptr = ‘T’ пытается изменить первый байт строки ‘Linux’, которая хранится в памяти в сегменте кода (а этот сегмент только для чтения). Эта операция некорректна, и приводит к падению программы с ошибкой сегментации.

10. Процесс, изменяющий свое имя

Вопрос: Напишите программу, которая изменяет свое имя во время выполнения.

Ответ: Например, такая:

11. Вернуть адрес локальной переменной

Вопрос: Есть ли проблемы с данным кодом? Если да, то как от них можно избавиться?

Ответ: Хотя эта программа может отрабатывать нормально, однако у нее есть серьезная ошибка в функции inc(). Эта функция возвращает адрес локальной переменной. Время жизни этой локальной переменной — это время, пока выполняется функция inc(). После того, как функция inc() отработала, использование адреса локальной переменной может приводить к непредсказуемым результатам. Эту программу можно исправить, если передавать в функцию inc() не значение переменной ‘a’, а ее адрес. Таким образом, мы будем вносить изменения только по этому адресу, и не будем задействовать локальные адреса переменных.

12. Аргументы printf()

Вопрос: Что выведет следующий код?

Ответ: Программа выведет следующее:

Несмотря на то, что аргументы функции printf отображаются слева направо, но обрабатываются справа налево.

7 thoughts on “Собеседование на знание языка C – 12 вопросов и ответов”

В последнем вопросе в строке:
printf(“\n %d..%d..%d \n”, a+b+c, (b = b*2), (c = c*2));
имеем undefined behavior
так как реализация функции может быть с обработкой параметров в другом порядке

Восьмой ответ не корректен.
Приоритет у постфикс оператора ‘++’ выше, чем у ‘*’ (https://en.cppreference.com/w/c/language/operator_precedence). Но это ещё не все новости ��
Порядок выполнения регулируется не приоритетами операций, а другими правилами (https://en.cppreference.com/w/c/language/eval_order).

В одиннадцатом нужно использовать статическую переменную и все проблемы решены.
А передавать адрес это уже не исправление ошибки, а целый рефакторинг.
int* inc(int val)
<
static int a = val;
a++;
return &a;
>

2 Михаил
статическая переменная для таких вещей – полнейший ахтунг:
int* a = inc(10);
int* b = inc(100);
cout


по второй задаче. Бред. Функция strcpy().

как распределиться память в ОЗУ:
допустим flag по адресу 0х8000’0000, массив passwd по адресу 0x8000’0004, passwd занимает 10 байт, т.е. 0x8000’0004 по 0x8000’000D. если вылезти за пасворд, то поменяешь данные по адресам 0x8000’000E, 0x8000’000F, 0x8000’0010, 0x8000’0011 и т.д. А данные по адресам 0x8000’0000-0x8000’0004 не изменяться

Возможно, если этот пример запустить с MMU (например под Linux), то так и будет. ОС грубо говоря, выделит под задачу 14 байт ( с адресами 0x0000’0000 по 0x0000’000D). при переполнении стека в strcpy указатель укажет на начало памяти. strcpy по кругу перезатерёт адреса 0x0000’0000 – 0x0000’0003, т.е. переменную flag. И это сработает.

Но если эту программу запустить на процессоре без MMU (ARM Cortex-M, AVR, MSP430), даже на линуксе (например на uLinux), то ни какого взлома пароля не будет. В худшем случае перетрётся какая-нибудь память и программа или устройство зависнет/перезапустится.

в задаче нет оговорок на MMU, это задача на знание Си. В Си нет ни какого зацикливания указателей памяти и перепишется память которая ЗА passwd, но не перед.

11 задача. полный ахтунг. ошибка на лицо. но предлагают её решение не понятно какое? передавать указатель в inc()? И? у вас будет меняться переменная а, объявленная в main(). А это требуется?

Вообще, какая задача? не понятно. “Вернуть адрес локальной переменной”? А зачем? И как можно вернуть адрес локальной переменной, если она “умирает” при выходе? Постановка задачи не правильная. Вернуть адрес статической локальной переменной – это другое дело. делаем статик. Создать динамически перемеренную и вернуть адрес – это третье. Ошибку видно в коде. Но как исправить? Ни как! Что нужно сделать? Что должна делать функция inc()?

ну если на то пошло, то в 3-м задании будет warning и по поводу того, что вы не подключили библиотеку для функции malloc

Вопросы на собеседовании программисту С++

Посоветуйте интересные вопросы программисту С++, что бы оценить его знания?

Вот несколько вопросов, которые задаю я на интервью:

1. Виртуальные функции — что это и зачем?
2. Виртуальный деструктор — что это и зачем?
3. Что предпочтительней, наследование или инкапсуляция? в каких случаях и почему?
4. Есть такие волшебные слова: мьютекс и волотайл, о чем речь?
5. Чем отличается процесс от потока?

  • Вопрос задан более трёх лет назад
  • 21706 просмотров

Моно добавить пару вопросов про шаблоны. К примеру, такой.
Есть объявление
templatevoid f( T arg )
<
printf( «general call» );
.
>

template<>
void f( long arg )
<
printf( «explicit call» );
.
>

и вызов
int i = 0;
f( i );

Что будет вызвано?

Вместо int и long можно использовать указатели на класс и его предок; константный и неконстантный указатели.

template
void f( T arg )
<
printf( «general call» );
.
>

template<>
void f( long arg )
<
printf( «explicit call» );
.
>

Прошу прощения, одна из скобок сломала сообщение…

Что предпочтительней, наследование или инкапсуляция? в каких случаях и почему?

Какой-то странный вопрос. Может имелось ввиду наследование и делегирование?

Я завалил несколько человек тупым вопросом — чем отличаются virtual функции от pure virtual.
Ещё про mutable можно спросить — про эту штуку мало кто знает.
Ну, ещё по stl погонять, основы знать надо! Типа, что быстрее справится с такой-то задачей: vector или map? Области применимости и т.п.

«5. Чем отличается процесс от потока?» — это скорее вопрос на общую компьютерную грамотность, типа «Чем отличается процессор от системного блока?», который нам на информатике в школе задавали.

Вот такой вопрос куда отнести:

Что в С++ кроме классов может быть полиморфно?

Презентация на тему: 15 популярных вопросов с IT -собеседований по языку С++

Первый слайд презентации: 15 популярных вопросов с IT -собеседований по языку С++

Источник: https ://proglib.io/p/tricky-challenges-cpp/

Слайд 2: 1 Что получим на выходе?

#include using namespace std ; int f(); int x = 9; int main() < f(); cout

Слайд 3: 2 Что на выходе и почему ?

int main( int argc, char ** argv ) < std :: cout 4

Слайд 4: 3 Разберем код:

Слайд 5: 3 Когда используется виртуальное наследование?

Слайд 6: 4 Что означает модификатор virtual ?

В C++ виртуальные функции позволяют поддерживать полиморфизм – одну из ключевых составляющих ООП. С его помощью в классах-потомках можно переопределять функции класса-родителя. Без виртуальной функции мы получаем «раннее связывание», а с ней – « позднее связывание». То есть, какая реализация метода используется, определяется непосредственно во время выполнения программы и основывается на типе объекта с указателем на объект, из которого он построен.

Слайд 7: 5 Пример использования виртуальной функции

>eat (); cat- >eat (); > // Outputs: «I’m eating generic food.» // Outputs: «I’m eating a rat.

Слайд 8: 5 Пример использования виртуальной функции

Добавим функцию: void func (Animal *xyz) < xyz->eat (); >


Слайд 9: 5 Пример использования виртуальной функции

Исправим: void func (Animal *xyz) < xyz->eat(); >

Слайд 10: 6 Существует ли различие между классом и структурой ?

Единственное различие между классом и структурой – это модификаторы доступа. Элементы структуры являются общедоступными по умолчанию – public, а элементы класса – private. Рекомендуется использовать классы, когда вам нужен объект с методами, а иначе (простой объект) – структуры.

Слайд 11: 7 Что не так с кодом ?

Слайд 12: 7 Что не так с кодом ?

Удаление объекта порожденного класса через указатель на базовый класс без виртуального деструктора ( virtual

) является неопределенным поведением ( undefined behavior ) согласно стандарту C ++11 § 5.3.5/3. Вызов деструктора порожденного класса может работать, а может и нет, и нет никаких гарантий -> избегать такого.

Слайд 13: 8 Что такое класс хранения ?

Класс, который определяет срок существования, компоновку и расположение переменных/функций в памяти. В C ++ поддерживаются такие классы хранения: auto, static, register, extern, mutable. Обратите внимание, что register устарел для C++11. Для C++17 он был удален и зарезервирован для будущего использования.

Слайд 14: 9 Как вызвать функцию C в программе на C++ ?

//C code void func ( int i) < // code >void print( int i) < // code >Соглашение о вызове: в С и С++ параметры передаются по разному (используя регистры и стек, но каждый по-своему). //C++ code extern «C» < void func ( int i); void print( int i); >void myfunc ( int i)

Слайд 15: 10 Что делает ключевое слово const ?

Задает константность объекта, указателя, а также указывает, что данный метод сохраняет состояние объекта (не модифицирует члены класса). Пример с неизменяемыми членами класса : cannot be modified because it is being // accessed through a const object

Слайд 16: 11 Виртуальный деструктор: что он собой представляет ?

Во-первых, он объявляется как virtual. Он нужен, чтобы с удалением указателя на какой-нибудь объект был вызван деструктор данного объекта. Например, у нас есть 2 класса: >

Слайд 17: 11 Виртуальный деструктор: что он собой представляет ?

Без виртуального деструктора будет выполняться только вызов деструктора базового класса, а вызов производного деструктора — не будет. Получаем «утечку памяти». Поэтому необходимо деструктор базового класса сделать виртуальным (добавить virtual ), тогда освобождение памяти будет корректным.

Слайд 18: 12 Виртуальный конструктор: что он собой представляет ?

Каверзный вопрос с IT-собеседований, который чаще всего задают именно после виртуальных деструкторов, дабы сбить кандидата с толку. Конструктор не может быть виртуальным, поскольку в нем нет никакого смысла: при создании объектов нет такой неоднозначности, как при их удалении.

Слайд 19: 13. Сколько раз будет выполняться этот цикл ?

unsigned char half_limit = 150; for (unsigned char i = 0; i 20

Слайд 20: 14. Каков результат следующего кода ?

#include > baseMethod (); delete base; return 0; > from А from А from Base Здесь важно отметить порядок уничтожения классов и то, как метод класса Base возвращается к своей реализации после удаления А.

Последний слайд презентации: 15 популярных вопросов с IT -собеседований по языку С++: 15. Что мы получим на выходе ?

#include int main () < int a[] = <1, 2, 3, 4, 5, 6>; std :: cout

Типичные вопросы на собеседовании по C++

Зачем нужен виртуальный деструктор?

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

Output:

Без ключевого слова virtual у родительского класса My деструктор порожденного класса не был бы вызван. Т.е. вызвался бы только

Что стоит помнить при использовании исключений в конструкторе объекта?

Если исключение не обработано, то c логической точки зрения разрушается объект, который еще не создан, а с технической, так как он еще не создан, то и деструктор этого объекта не будет вызван.

Например:

Output:

Здесь могут спросить: «Как бы вы решили эту проблему при подобной ситуации». Правильный ответ: «Воспользовался бы умными указателями».

Пример умного указателя:

Теперь и без вызова деструктора Base хэндл будет закрыт, т.к. при уничтожении класса Base будет уничтожен объект m_hFile класса CHandle, в деструкторе которого и будет закрыт хэндл.

Изобретать велосипед, конечно, не надо, все уже написано до нас, например в boost, Loki, ATL и т.п.

Для каких целей применяется ключевое слово const?

  1. Позволяет задать константность объекта
  2. Позволяет задать константность указателя
  3. Позволяет указать, что данный метод не модифицирует члены класса, т.е. сохраняет состояние объекта

Учтите что константный метод может изменять члены класса, если они объявлены как mutable

Можете ли вы написать пример какого-нибудь алгоритма сортировки?

Первое что приходит всем на ум это сортировка пузырьком.

Рассмотрим пузырковую сортировку без временных переменных

Напишите код для реверса строки?

Как защитить объект от копирования?

Сделать private конструктор копирования и оператор =.

В чем разница между struct и class?

Практически ни в чем. В struct модификаторы доступа по умолчанию public, в class private. Также отличается и наследование по умолчанию, у structpublic, у classprivate.

Сколько в памяти занимает произвольная структура?

sizeof всех членов + остаток для выравнивания (по умолчанию выравнивание 4 байта) + sizeof указателя на vtable (если есть виртуальные функции) + указатели на классы предков, от которых было сделано виртуальное наследование (размер указателя * количество классов)

Как сгенерировать pure virtual function call исключение?

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

В чем отличие vector от deque?

Здесь вспоминают о наличии у deque методов push_front и pop_front. Но основное отличие в организации памяти, у vector она как у обычного Си-массива, т.е. последовательный и непрерывный набор байт, а у deque это фрагменты с разрывами. За счет этого отличия vector всегда можно привести к обычному массиву или скопировать целиком участок памяти, но зато у deque операции вставки/удаления в начало быстрее (O(1) против O(n)), ввиду того, что не нужно перемещать

В чем отличие malloc от new?

malloc — выделение блока памяти в стиле Си, опасное с точки зрения приведения типов (non-typesafe), т.к. возвращает void * и требует обязательного приведения. new — выделение блока памяти и последующий вызов конструктора, безопасное с точки зрения приведения типов (typesafe), т.к. тип возвращаемого значения определен заранее.

В чем различия между dynamic_cast и reinterpret_cast?

Динамическое приведение — это безопасное приведение по иерархии наследования, в том числе и для виртуального наследования. Проводит преобразование типа, предварительно убедившись (с помощью RTTI), что объект expression_from в действительности является объектом типа type_to. Если нет: для указателей возвращает NULL.

При reinterpret_cast результат не гарантирован, проверки не осуществляются. Ограничения на expression_from: порядковый тип (логический, символьный, целый, перечисляемый), указатель, ссылка. Ограничения на type_to: для порядкового типа или указателя — порядковый тип или указатель. Для ссылки — ссылка.

Для чего нужен аллокатор и как создать свой собственный аллокатор?

Аллокатор это шаблонный класс, который отвечает за выделение памяти и создание объектов. По умолчанию все контейнера используют std::allocator .
В языке c++ имеется так же возможность написать свой аллокатор. У своего алокатора должно быть такое объявление:

В чём суть множественного наследования? Какие проблемы могут возникнуть при его использовании? Как их преодолеть?

Множественное наследование – мощный способ связи классов в с++. С помощью множественного наследования класс может иметь сразу несколько базовых классов, объединяя в себе их свойства. Однако данный метод порождает определенные неудобства, из-за которых множественно наследование отсутствует в таком языке, как Java, к примеру, уберегая программиста от возможных проблем, и вынуждая его строить механизм множественного наследования без порождения выше упомянутых проблем.
Проблемы, собственно говоря, возникают, когда имеет место такая ситуация:
Пусть класс A – базовый, далее классы B и С наследуют A, к классу D применено множественное наследование — для него базовыми являются одновременно B и C. Программа видит эту структуры таким образом:
A(1) A(2)
| |
B C
\ /
D
Теперь, вызывая из D метод, расположенный в A программа сталкивается с неоднозначностью: а из «какого» A вызывать? A(1) или A(2)?
Избежать данной проблемы поможет использование ключевого слова virtual, которое превращает класс A в виртуальный класс, так сказать «класс – шаблон». Теперь никакой неоднозначности нет, и ситуация выглядит вот так:
A
/ \
B C
\ /
D

Какая разница между указателями:

Ответ:

возвращает ненулевой указатель, а

возвращает нулевой указатель.

выделит память в GlobalHeap, а

выделит в LocalHeap.

Отсюда в оператора new преимущества в памяти.

В чем основное различие между деструктором и оператором delete?

Оператор delete освобождает область памяти зарезервированную ранее с помощью оператора new. При этом для объектов автоматически будет вызван деструктор. Деструктор содержит код, который необходимо выполнить до освобождения памяти, например, освобождение системных ресурсов и т.д. Вызов деструктора вручную не приводит к освобождению памяти, занимаемой объектом.

Чем отличается vector от deque?

Отличие в организации памяти, у vector она как у обычного Си-массива — последовательный и непрерывный набор байт, а у deque это фрагменты с разрывами. За счет этого отличия vector всегда можно привести к обычному массиву или скопировать целиком участок памяти, но зато у deque операции вставки/удаления в начало быстрее (O(1) против O(n)), ввиду того, что не нужно перемещать остальные значения. А также наличие у deque методов push_front и pop_front.

Что можно сказать о delete this?

Это выражение считается выражением плохого тона и нужно стараться избегать его использования, так как оно ведет к ошибкам.
Данная конструкция имеет две ловушки.
Во-первых, если оно выполняется в методе extern, static или automatic объекта, программа скорее всего завершится досрочно вскоре после выполнения оператора delete. Не существует переносимого способа сообщить, что объект создан на куче, таким образом класс не может проверить корректно ли объект создался.
Во-вторых, при таком самоуничтожении, программа может и не узнать об этом. Для нее объект по-прежнему продолжает существовать, несмотря на то, что это не так. Любое обращение к this или к любым данным объекта приведет к катастрофическим последствиям. При этом методы, которые не содержат обращения к полям-данным объекта, выполняются нормально.

В чем разница между массивом и списком?

Массив – это набор однородных элементов, а список – разнородных.
Распределение памяти массива всегда статическое и непрерывное, а в списке все это динамическое и рандомное.

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

Как проводить собеседование с IT-специалистами. Рекрутеры советуют, программисты комментируют

Статья в источнике:hr-journal.ru/articles/pp/pp_1291.html

Подбор IT-специалистов — одно из самых сложных направлений рекрутинга. Есть мнение, что эйчарам и айтишникам вообще трудно понять друг друга: HR-менеджеры vs. IT-специалисты. Взаимопонимание отсутствует? Именно поэтому мы решили, что полезно услышать мнение не только рекрутеров, но и представителей со стороны самих IT-специалистов. И попросили программистов прокомментировать отдельные положения статьи. Что же они думают про рекрутинговые технологии?


Мелкишева Оксана, менеджер по развитию агентства рекрутинга «Люди Дела». В прошлом занималась подбором персонала. Сейчас ведёт работу с клиентами, отвечает за продвижение компании, пишет статьи о современном рекрутинге, проводит исследования рынка труда и готовит аналитическую информацию.

Ни для кого не секрет, что профессия накладывает сильный отпечаток на характер и поведение индивида, во многом определяет и то, как он общается с другими представителями рода человеческого. Подобрать и мотивировать хорошего специалиста — большой труд для любого менеджера по персоналу, а подобрать и мотивировать IT-специалиста — огромнейший.

И тем не менее найти общий язык с «властелинами машин и кода» можно. В этой небольшой заметке нам хотелось бы обратить внимание на ряд основных сложностей, что могут возникнуть у HR’а, который совсем недавно решил окунуться в рекрутинг компьютерных специалистов, и дать ему несколько советов. Сразу стоит заметить, что под «айтишниками» сейчас мы не будем подразумевать специалистов всего пласта IT-структуры, а лишь самых ярких его представителей — программистов и системных администраторов.

Одним из основных препятствий на интервью с айтишником является немногословность последнего. Во-первых, большинство программистов и сисадминов имеют математическое образование, а оно заведомо подразумевает некую лаконичность в общении. Во-вторых, это обусловлено постоянным взаимодействием таких специалистов с компьютером. Ведь если обратиться к тем профессиям, где превалирует общение с людьми, то становится заметным, что их представители легче идут на контакт. Обладатели «общительных» специальностей, как правило, с лёгкостью проходят вопросы, требующие развёрнутого ответа, выясняют важные для себя моменты и подробно рассказывают о себе и своём опыте. С представителями же IT-сферы выигрышным будет полуформализованное интервью, где вопросы цепляются один за другой и задаются с максимальной конкретикой. Привыкший к чёткой логической цепочке при работе с кодом, айтишник также конкретно отвечает на поставленный вопрос и часто недоумевает, если после этого следует поток уточняющих «вопросиков». Поэтому спрашивать рекомендуется максимально точно, открыто и прозрачно, чтобы избежать недопонимания. Также недоумение возникает если, например, сначала спросить о проектах, а после тут же задать вопрос о семейном положении. Некоторые рекрутеры сходятся во мнении, что у айтишников отсутствует навык самопрезентации, поэтому неформализованное интервью будет являться наихудшим из вариантов, так же как и обилие вопросов, требующих от интервьюируемого развёрнутых длительных ответов.

Комментирует Сергей Лаур, программист, руководитель группы разработчиков:

— На самом деле не столь важно, конкретные задаются вопросы или более общие. Интеллектуально неполноценных среди состоявшихся программистов мало, поэтому мы в состоянии отвечать на любые вопросы. А математическое мышление как раз предполагает высокую степень абстракции. Гораздо важнее, чтобы вопросы учитывали психологические особенности IT-специалистов, их мировоззренческие установки. Возможно, рекрутеры сильно бы удивились, если бы увидели, насколько разговорчивым бывает кандидат, который у них проявил себя молчуном. Главная проблема именно в этом: у нас различное видение мира. И некоторые вопросы, которые рекрутеры считают себя вправе задавать (про семейное положение и личную жизнь, занятия в свободное время), воспринимаются как вторжение в личное пространство. Не возьмусь говорить за всех IT-специалистов, но я просто не вижу, какое это имеет отношение к моей работе и обязанностям, да и вообще к вакансии.

Комментирует Андрей Кирьянов, программист:

— Любой высококвалифицированный разработчик рано или поздно приходит к осознанию того, что ему необходимо уметь контактировать и работать с людьми. Нередко приходится общаться напрямую с заказчиком, чтобы понять его требования к разрабатываемому продукту. Замкнутость же и неумение грамотно строить речь могут наложить свой отпечаток на карьерное продвижение сотрудника, а то и на развитие бизнеса в целом. Поэтому считаю, что если рекрутер находится в поисках IT-кандидата именно на ответственную или руководящую позицию, то кандидат не должен иметь малейших коммуникационных сложностей при общении с ним.

Советуем узнать об уже реализованных проектах, попросить прислать ссылки на них. Да, возможно, вы сами не сможете правильно оценить подобный материал, но HR — лишь промежуточное звено в оценке, этот инструмент позволит вам передать более полную информацию об опыте и проектах руководителю «домашнего» IT-подразделения.

Комментирует Сергей Лаур, программист, руководитель группы разработчиков:

— Да, ссылки на проекты — правильный ход. Но не всегда это возможно. Это зависит от того, чем именно занимается специалист. Проще всего, если речь идёт о веб-разработке, но и тут есть нюансы. И ещё. Лучше всего, чтобы информация шла в письменном виде, иначе эйчар превращается в испорченный телефон, не всегда способный адекватно передать данные. Это так ввиду того, что IT-отрасль очень специфична.

Комментирует Михаил Горшков, программист:

— Главное, чтобы оценка предыдущих проектов не превращалась в разглядывание их «фасадов», за которыми теряется то, к чему непосредственно приложил руку программист. Поэтому подобные материалы оценивать всё же не рекрутеру. К тому же не стоит забывать, что авторство кода и разработки в целом — установить на практике очень трудно. А некоторые исходники и вовсе являются исключительной собственностью прежних работодателей.

Помимо немногословности, к сложностям можно отнести специфичность терминологии, которую вы встретите в резюме и в ходе беседы с кандидатом. Нередко в диалоге возникает «языковой барьер» из-за обилия в речи интервьюируемого англицизмов, профессионального сленга и терминов. HR’у не нужно быть матёрым специалистом во всех языках программирования и на зубок знать содержание системного блока, но подготовку к интервью по незнакомой ранее вакансии никто не отменял. Поэтому нелишне будет заранее проштудировать базовые определения и термины в новой для себя области. Однако не исключено, что некоторые смысловые конструкции всё же могут остаться «в вакууме», так как напрямую программированием рекрутеры всё же не занимаются. Если такая ситуация и возникает, например, в ходе самого собеседования, то крайне не рекомендуется делать вид, что суть той или иной фразы предельно ясна, ведь грамотный IT-специалист раскусит подобные экивоки за секунду. Если знаний в какой-либо области, поднятой айтишником в ходе собеседования, всё же оказалось недостаточно, то не стоит делать вид, что они есть, судорожно перебирая в памяти значения однокоренных неизвестному слов. Можно легко попасть впросак, например, нечаянно перепутав frontend и backend, что, конечно, будет являться обидной ошибкой, из-за которой интересного кандидата могут прибрать к рукам более компетентные рекрутеры-конкуренты. Поэтому лучше всего максимально подробно изучить данную специальность, чтобы минимизировать число подобных оплошностей (мы же не задумываемся над тем, что такое тюнинг и двигатель у автомобиля, хотя и не являемся автомеханиками).

Комментирует Сергей Лаур, программист, руководитель группы разработчиков:

— Вот эта рекомендация — «максимально подробно изучить данную специальность» — позабавила. Добро пожаловать в вуз на несколько лет. И что значит «на зубок знать содержание системного блока»?! Это заблуждение, что рекрутер, не имеющий отношения к отрасли, сможет тем не менее разговаривать с айтишником на одном языке. Именно такие попытки производят очень плохое впечатление. Нахватанность терминов не имеет ничего общего с пониманием. Если человек говорит, что его компетенции — отбор по психологическим качествам, а общение на профессиональные темы будет идти с будущим руководителем — это оптимально. Попытка же рекрутера «оценить профессионализм» айтишника в устной беседе — по моему мнению, профанация и гордыня. Когда моему отделу нужны сотрудники, я именно так и стараюсь договориться с нашими эйчарами: всю психологию и прочую корпоративность можете смотреть вы, а подходящих кандидатов разговаривать о работе приводите ко мне.

Комментирует Андрей Кирьянов, программист:

— Очень важно, чтобы HR-специалист, работающий с IT-вакансиями, всё же был в курсе дел и современных тенденций в отрасли. Когда возникает лишнее, «глухонемое» звено в собеседовании между мной и, например, руководителем группы разработки, мне будет очень неприятно заново рассказывать последнему о моих знаниях и достижениях. Обычно HR с умным видом выслушивает меня, а потом мне приходится всё повторять. Цените, пожалуйста, время кандидатов на трудоустройство.

Комментирует Михаил Горшков, программист:

— Лучшей для рекрутера подготовкой к интервью по подобным вакансиям, полагаю, будет беседа со специалистом «домашнего» IT-подразделения, обсуждение с ним вида анкет, где кандидаты указывали бы уровень владения интересными работодателю инструментами и технологиями, на основании которых можно было бы готовить более конкретные вопросы для второй беседы. Или даже составление списка узкоспециальных вопросов на первую, ответы на которые после собеседований направлялись бы для оценки специалисту «домашнего» IT-подразделения. А если есть возможность, то лучше и первое интервью проводить непосредственно в его присутствии.

Не стесняйтесь попросить специалиста уточнить, что он имел в виду: как правило, наиболее подробно айтишники готовы объяснять премудрости своей работы «простым смертным». Позвольте специалисту поговорить на любимую тему, и будете вознаграждены. К тому же без специфического опыта в вёрстке сайта или внедрения какого-либо ПО гораздо проще оценить кандидата по его собственным рассказам о том или ином случае, произошедшем «на производстве», проблеме и способе её решения.

Ведь айтишники — народ творческий, поэтому задавая простые лаконичные вопросы, можно попробовать облечь их в творческую форму. Например, вместо вопроса: «Что такое обфускация?» можно спросить: «Объясните ребёнку, что такое обфускация кода: простыми словами, чтобы даже он понял» — это позволяет оценить, знает ли собеседник теорию, может ли простым языком рассказать о своей работе, объяснить сложную терминологию. На IT-рынке есть огромное множество гуру кода, которые на собеседовании не могут раскрыться в силу личностных особенностей, часто обусловленных профессиональной деформацией. Очень часто действительно гениальные кодеры «срезаются» на этапе интервью, так как являются весьма закрытыми людьми. Поэтому вопросы в креативной обёртке помогают сформировать интерес у кандидата, расположить его к себе нетипичным подходом к интервью.

Комментирует Артём Андреев, программист:

— Кстати, «творческость» айтишников — ещё один миф. Творческие — дизайнеры, иллюстраторы, писатели. У нас же просто другой подход. То, что воспринимается как креатив людьми со стороны, внутри IT-отрасли — просто норма.

Комментирует Сергей Лаур, программист, руководитель группы разработчиков:

— «Гениальные кодеры» — уже показывает, что понимание темы, скажем так, неайтишное. А вот вопросы в «креативной обёртке» напрягают. Чаще всего это значит, что сейчас рекрутер начнёт в сотый раз задавать вопрос из арсенала Microsoft: почему люки круглые, сколько теннисных мячиков поместится в боинг и прочее. Это уже давно не креатив, а его противоположность. Но может быть, автор что-то другое имела в виду, все рекрутеры разные, как и айтишники, вообще-то.

Комментирует Михаил Горшков, программист:

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

А что касается «гениальных кодеров», то программиста всё же определяет не богатый опыт написания кода, а умение думать так, что любой код получается оптимальным, «правильным». Поэтому программисту просто необходимо иметь хорошее абстрактное мышление — его наличие и нужно проверять, даже без привязки к низкому уровню, к коду (эйчар вполне способен к этому подготовиться). Ведь не умея мыслить системно: минуя частности, находить отправные точки для решения самых нестандартных задач, — программист остаётся лишь обычным кодером — вузовским полуфабрикатом, компилятором блоков чужих универсальных решений и «золотых» алгоритмов. Потому и «мелкософт», и другие крупные компании такое место и отводят на интервью нестандартным вопросам, что хотят на ранних этапах отбора выявить незашоренных логиков и просто мыслящих нешаблонно, пусть и делается это средствами высосанных из пальца задач, безразборное, безответное, без обратной связи решение которых эту зашоренность у большинства кандидатов и создаёт… Тут при трудоустройстве предыдущий опыт не всегда всё решает. А подходящего, но не совсем готового кандидата компании (вроде Microsoft) могут себе позволить подтянуть основательно, доучить чему нужно, потратиться на него. Они-то уж точно знают, что трудно представимы в качестве стартовой площадки.

А вот сочетание амбиций кандидата, недостаточных технических умений, но высокого «потенциала программиста» должно для компании не первого эшелона быть сигналом того, что она может потерять будущего работника, так и не успев воспользоваться реальными плодами вложений в него, в его дообучение. Поэтому и мода в любой и каждой (sic!) айтишной конторке задавать вопросы и давать задачки, подобные майкрософтовским, удивляет.

По нашему опыту, в оценке мотивации кандидата из этой сферы наиболее удачными являются вопросы о том, какие проекты для него интересны, какие рабочие условия будут комфортны, каковы зарплатные ожидания — то есть о том, что действительно важно айтишнику. Ни в коем случае не спрашивайте: «Кем Вы видите себя через 10 лет? Почему Вы выбрали нашу компанию? С чем связано Ваше решение? Почему мы должны взять Вас на работу?»

Комментирует Артём Андреев, программист:

— Да, верно, согласен на все сто. И немного дополню. Спрос на программистов сейчас очень высок, таково состояние рынка труда. Поэтому актуальны не только вопросы, но и ответы кандидату. Например, мне интересно услышать, почему я должен выбрать именно вашу компанию. Это становится реальной проблемой, когда у тебя 3–4 серьёзных предложения от работодателей.

Комментирует Михаил Горшков, программист:

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

Итак, если обобщить вышесказанное, то мы получим несколько простых правил, которых нелишне придерживаться при интервьюировании айтишника:

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

2. Избегайте абстрактных вопросов: как при оценке мотивации, так и навыков. Уменьшите количество вопросов, которые требуют от кандидата длительных ответов-рассказов.

3. Фантазируйте, придумывайте необычную подачу обычным вопросам (конечно, не теряя при этом присутствия логики и структуры).

4. Изучайте терминологию. Важно углубится в новую для вас сферу, несмотря на кажущуюся сложность формулировок и терминов.

5. Не старайтесь придумывать на ходу объяснения терминам, использованным IT специалистом. Лучше переспросить, чем упустить ценный кадр.

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

Комментирует Сергей Лаур, программист, руководитель группы разработчиков:

— По этим 5 пунктам я не буду высказываться, основное уже сказал выше. Желаю эйчарам удачного рекрутинга, а всем айтишникам — найти суперского работодателя. И пусть рекрутеры и IT-специалисты научатся лучше понимать друг друга 😉

Мелкишева Оксана, менеджер по развитию агентства рекрутинга «Люди Дела»
Источник: Журнал «Работа с персоналом»

Что нужно знать для практического использования С++? [закрыт]

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

Как писать драйвера? (в какую сторону смотреть, есть ли книги или документация). Что вообще следует писать на с++ и «как, чем»? Какой API лучше использовать для написания оконных приложений и стоит ли это делать на с++?

Вот я и не могу понять, как это происходит, ведь в книгах с++ этого нет. Надеюсь вы поняли ход моих мыслей и сможете прояснить. Спасибо.

Закрыт по причине того, что необходимо переформулировать вопрос так, чтобы можно было дать объективно верный ответ участниками Kromster says support Monica, A K ♦ , entithat, pavel, iksuy 12 ноя ’18 в 12:39 .

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

4 ответа 4

На мой взгляд одна из самых актуальных проблем современной литературы — много фундаментального и мало более профессионального. Я постараюсь объяснить это так, как вижу сам. Хотя знаний у меня не так уж много, но по крайней мере я попытаюсь. Надеюсь знающие люди подправят, если ошибся.

Итак, работа электроники происходит посредственном передачи данных по шинам от одного управляющего устройства другому(процессоры, микропроцессоры, микроконтроллеры и т.д.). В зависимости от того, какие данные переданы, электроника выполняет определенные задачи. Фактически это уровень архитектуры компьютера и ассемблера, которую очень хорошо бы знать на базовом уровне(Тоненбаум — «Архитектура компьютера»). Команды эти обычно объединяются в своего рода блоки, аналогично функциям, которые делают какую-то определенную цель. Иногда создаются целые кучи функций, которые объединяются в библиотеки функций(те самые math, iostream и т.д.).

Низкий уровень, драйвера:

Для написания драйвером надо посылать эти самые команды управляющим устройствам. Язык С++ не очень подходит под эти задачи, проще пользоваться чистым Си. В самом простом случае подключается какая-то библиотека, которая позволяет посылать значения устройствам и читать их. К примеру, простейший способ обращения к динамику ПК может выглядеть так(учтите, windows не разрешает напрямую обращаться к портам!):

Правда добрые люди обычно делают сторонние библиотеки более высокого уровня, которые уже содержат список готовых функций, классов, структур для обращения к устройствам. Например, код выше прекрасно работает из библиотеки функций windows.h, вызывая функцию beep(). Если вы хотите писать драйвера, то вам придется читать о том, как обращаться к устройству из документации разработчиков с оффициальных сайтов, какие команды устройство может выполнять, какие данные надо для этого посылать, есть ли для этого специальные библиотеки от разработчиков и многое другое.

Высокий уровень.

Люди, которые используют С++, работают обычно с готовыми наборами библиотек или создают свои под те или иные задачи. Например, есть такая вещь как WinAPI для создания графического интерфейса Windows окон. Это опять же готовые функции, вы подключаете библиотеку и работаете с ними. В ответ они делают какую-то работу и выдают результат. Если вы посмотрите на минимальное окно, то в коде вы увидите заполнение знакомых элементов: структуры, вызов функций, использование циклов и т.д. Другое дело, что эти функции и структуры сделали разработчики и они выполняют определенную работу, Вам остается только их вызывать. Для ознакомления с ними есть документация.

Все выше и выше.

Обычно библиотеки делаются универсальными и их можно использовать повторно. Например, на основе одной можно создать другую которая будет выполнять еще более специализированные функции. Например, можно создать библиотеку с функцией рисования линий. Из нее библиотеку с функцией рисования геометрических фигур. Из нее библиотеку с рисование деталей и т.д. так наращивается функциональность. Есть например программное рисование графики на мониторе, в windows его надстройка winAPI(линии, окошки, цвета уже готовы), но и у него есть более высокоуровневая оболочка MFC или Windows Forms, которые являются более усовершенствованными, но основаными на все том же WinAPI.

Как итог: фактически работа программиста заключается в том, что бы выяснить какая библиотека может помочь справиться с нужными задачи и изучить ее. А изучив применить к своим нуждам. Хотите использовать Windows GUI приложения — есть WPF и Windows Form, или на более низком уровне взять WinApi. Хотите использовать видеокарту для 3D приложений — изучайте DirectX. Хотите работать с музыкой, опять же всякие библиотеки типа OpenAL есть в распоряжение. Охота писать драйвера, ищите информацию о том, как можно обращаться к устройствам и посредством какой библиотеки. Хотите узнать почему используются готовые библиотеки, изучите архитектуру компьютера и самые основы ассемблера. В любом случае вы будете пользоваться основными изученными элементами языка С++: структуры, функции, классы, указатели, простые типы данных и т.д.

Мастер Йода рекомендует:  Webpack основы настройки проекта на JavaScript и Sass
Добавить комментарий