LINUX.ORG.RU

Какой должен быть тест на базовые знания C++?

 ,


0

3

Недавно видел тест, «Базовый C++», который предлагают нашим инженерам-программистам. Видимо, хотят понять, вдупляем ли мы вообще C++ или требуется обучение.

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

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

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

Последняя часть меня просто убила. Там были задания, как будто вот с этих ваших писькомерных сайтов с задачками на C++ или олимпиады, вообще никакого отношения к теме «базовый C++».

И вот я подумал, от чего так? Почему люди концентрируют внимание на какой-то укуренной белиберде - которую у джунов надо наоборот вытравливать на ранних стадиях, чтобы писали надежный, читаемый и поддерживаемый код - а не на том, что кодеру нужно будет в реальной работе? Ведь дофига есть актуальных тем, например, современные фичи C++, как писать безопасный код, параллельные вычисления, стандартная библиотека. Складывается такое ощущение, что такие тесты пишут какие-то сычи, которые специализируются на олимпиадах и говнокоде, на каких-то нахрен никому не нужных редких правилах C++.

★★★★★

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

XMs ★★★★★
()
Последнее исправление: XMs (всего исправлений: 1)

Пока нет технических каментов, напишу гуманитарный.

И вот я подумал, от чего так?

Оттого, что тщеславная обезьяна, составляющая тест, чесала собственное ЧСВ, а не решала поставленную задачу.

thesis ★★★★★
()
Ответ на: комментарий от XMs

Ты тест куда-нибудь выложи

нет, это внутренний документ, да и нет его в просматриваемом виде

да опиши, чем разрабы занимаются

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

«базовыми» могут быть и адресная арифметика

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

и шаблоны,

а вот это, как киллер-фича C++ (особенно вкупе с вариадиками), вообще не была освещена, хотя это одна из причин, по которой до сих пор хочется использовать C++.

и мультитред

ничего не было про мультитред

seiken ★★★★★
() автор топика
Последнее исправление: seiken (всего исправлений: 1)

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

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

rumgot ★★★★★
()

Если у тебя тест будет состоять только из простых конструкций, применяемых всеми, то почти у всех, кто его проходит будет 100%. Т.е. это явно плохой тест. Тест должен быть таким, чтобы ЦА могла его пройти правильно процентов на 80, а остальное должно быть сложным и неочевидным.

Это, разумеется, не оправдывает кривых и безалаберных вопросов. Это про то, зачем там rtti и адок на указателях.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Если у тебя тест будет состоять только из простых конструкций, применяемых всеми, то почти у всех, кто его проходит будет 100%

Нет. Не обязательно. Примениямые конструкции не обязательно должны быть простыми.

Т.е. это явно плохой тест. Тест должен быть таким, чтобы ЦА могла его пройти правильно процентов на 80, а остальное должно быть сложным и неочевидным.

Смысл собеседования - выявить подходящего кандидата на конкретную должность. Если пришло 10 человек на одно место и все подходят - просто берем того, кто пришел первым. Если давать им задания, которые не имеют никакого отношения к должности, и все таки отсеять 9 из 10, то это имеет для должности околонулевую полезность. С таким успехом можно ввести задание кто больше отожмется.

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

Нет. Не обязательно. Примениямые конструкции не обязательно должны быть простыми.

Ну вот на наличие сложной адресной арифметики ТС и пожаловался. Тут либо что-то сложное, либо применяется всеми, либо ты слишком хорошего мнения о человечестве.

все подходят - просто берем того, кто пришел первым.

Зачем, если можно взять лучшего (или хотя бы повысить шансы взять лучшего)?

Если давать им задания, которые не имеют никакого отношения к должности

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

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

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Зачем, если можно взять лучшего (или хотя бы повысить шансы взять лучшего)?

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

что программисту на С++ задают вопросы о языке С++

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

rumgot ★★★★★
()
Ответ на: комментарий от Ivan_qrt

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

А с чего бы такие вопросы? Задачи плохо закрываются? Или начальство это от безделья?

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

А с чего бы такие вопросы?

Откуда я-то знаю? Я не являюсь начальником ТСа и никакого отношения к их фирме не имею.

Я лишь сказал, на что это похоже судя по описанию.

Ivan_qrt ★★★★★
()

это как анекдот - а карузо-то оказывается петь не умеет вообще! хрипит, сипит, нот не знает, пускает петуха! - а ви слушали карузо? - да не, это мне рабинович напел.

где сами тесты-то?

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от rumgot

Знания о том, что делает говнокод и что выводит - это не поможет выявить лучшего.

Если программист на С++ не знает ЯП, на котором он пишет, то весьма маловероятно, что он сможет писать хороший поддерживаемый код. Я уж молчу о том, что главный навык программиста - это читать код и понимать, что в нём происходит. Есть, конечно, люди, которые без отладчика совсем не способны понять код, но это определённо не те, кого стоит нанимать. И программисту надо быть способным читать и понимать любой код на С++, а не только то, что ему на курсах С++ за 21 день рассказали.

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

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

Ivan_qrt ★★★★★
()

И, кстати, покажите каких тестов на базовое знание, если кто знает.
И про упомянутую «семантику фич» чегонить краткого и емкого.
А то я как тот лось из анекдота - все хеловорлдю, хеловорлдю, а мне все хуже и хуже.

thesis ★★★★★
()
Ответ на: комментарий от Ivan_qrt

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

именно так. Я, кстати, был когда-то на курсе повышения квалификации под названием «продвинутый C++», возможно вот как раз по итогам подобного теста. Пришли мы на этот курс, и по мере того, как участники себя проявляли, выяснилось, что два чела из группы знали только C (программировали DSP), и не только не знали базовых фич C++ (самых примитивных, типа объектов, методов), но один еще прилагал неимоверные титанические усилия, чтобы понять объяснения, и, видимо, так до конца и не понял. В итоге большую часть времени потратили на элементарщину а ля «C++ за 21 день».

seiken ★★★★★
() автор топика
Ответ на: комментарий от Ivan_qrt

Если программист на С++ не знает ЯП, на котором он пишет

Количество не знающих C++ программистов, программирующих на C++, полагаю, приближается где-то к 95% от общего их числа.

И еще где-то 4.5% настолько не умны, что всерьез думают, что знают C++.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

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

Ivan_qrt ★★★★★
()
Ответ на: комментарий от no-such-file

Это не означает, что он обязан всё знать наизусть.

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

Ivan_qrt ★★★★★
()
Ответ на: комментарий от eao197

WTF «знает С++»? Туда слишком много всего напихали. Вот у меня по диплому квалификация физик, я считаю себя физиком и занимаюсь физикой 30 лет, но я её знаю очень избирательно. При этом «мой книжный шкаф знает больше чем я, но физик все таки я а не он»(с) А.Азимов

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от Ivan_qrt

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

Это только одна сторона медали. Другая сторона же в том, что C++ большой. Настолько большой, что какие-то его куски могут быть вообще незнакомы программисту. Например, программист может не иметь представления о том, как можно приспособить собственные структуры данных к использованию в structured binding. Или не иметь представления о назначении std::launder. Просто потому, что подобное никогда человеку не требовалось.

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

Мне лично всегда тяжело разбираться в коде с метапрограммированием. Назвать такое «подъемной задачей» можно лишь с большой натяжкой, имхо.

Или, например, если человек не в курсе такой штуки, как operator, (оператор запятая), то какие-то вещи он вообще не поймет. Пока кто-то ему не объяснит.

eao197 ★★★★★
()
Ответ на: комментарий от AntonI

Любой С++ код?

А что, в исходной цитате есть какие-то ограничения? ;)

Собственно, как только начинаются разговоры о «знании C++» без вменяемых ограничений контекста, так сразу можно подозревать, что говорящий не очень представляет себе глубину кроличьей норы :)))

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Я со всем этим согласен. Но тут опять же стоит учитывать контекст. При прочих равных, ты бы взял к себе человека, который знает про std::launder (и понимает, зачем он нужен), или первого, кто пришёл на собеседование?

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

Я, так-то тоже, в большом метапрограммировании буду разбираться очень долго, а в каком-то вообще не разберусь. А запятую, && и || вообще перегружать недопустимо, т.к. они при этом меняют своё поведение, и такой код, даже зная об этих операторах, становится очень сложно понимать.

Но это же не значит, что про это всё не имеет смысла спрашивать и что не важно, что кандидат знает, а что нет?

Вопросы всегда должны быть немного выше уровня ЦА.

Ivan_qrt ★★★★★
()

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

filosofia
()
Ответ на: комментарий от Ivan_qrt

При прочих равных, ты бы взял к себе человека, который знает про std::launder (и понимает, зачем он нужен), или первого, кто пришёл на собеседование?

Про взять «первого, что пришел» не я говорил. Для меня такой дилеммы нет.

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

Только вот это ортогонально «писать хороший поддерживаемый код».

А запятую, && и || вообще перегружать недопустимо

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

template <class T>
class reference_wrapper {
public:
  // types
  using type = T;
 
  // construct/copy/destroy
  template <class U, class = decltype(
    detail::FUN<T>(std::declval<U>()),
    std::enable_if_t<!std::is_same_v<reference_wrapper, std::remove_cvref_t<U>>>()
  )>
  constexpr reference_wrapper(U&& u) noexcept(noexcept(detail::FUN<T>(std::forward<U>(u))))
    : _ptr(std::addressof(detail::FUN<T>(std::forward<U>(u)))) {}

это, если интересно, кусочек возможной реализации стандартного класса std::reference_wrapper, взятый в свое время с сайта cppreference.com (может он там до сих пор в таком же виде висит).

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Только вот это ортогонально «писать хороший поддерживаемый код».

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

но вам может потребоваться разобраться в том, что и как происходит в коде.

Ну я это и имел ввиду. Не стоит всё возводить в абсолют, я думал вполне очевидно, что можно написать кода на плюсах, в котором человек в принципе не способен разобраться. Причём без всяких языковых нюансов, просто берёте функцию на 10 kloc с переменными a1, a2, a3, … и ни один вменяемый человек в таком не разберётся за разумное время. Но есть всё-таки разница между чем-то, что непонятно из-за запутанности кода и между тем, что человеку не знакомы языковые конструкции или он не умеет ими оперировать. Обсуждение велось про последнее.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Не стоит всё возводить в абсолют, я думал вполне очевидно, что можно написать кода на плюсах, в котором человек в принципе не способен разобраться. Причём без всяких языковых нюансов, просто берёте функцию на 10 kloc с переменными a1, a2, a3, … и ни один вменяемый человек в таком не разберётся за разумное время.

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

Речь идет о том, что в C++ может быть нормально (даже больше скажу: отлично) написанный код, в котором человек, не имеющий глубоких познаний в языке, не разберется ну никак. Именно потому, что этих самых познаний нет. Причем, что самое плохое, написать по другому может и не получится (либо вообще, либо это приведет к тому самому говнокоду, который можно написать на любом языке).

А этих самых глубоких познаний может не быть просто потому, что надобности никогда и не было.

При этом писать нормальный и поддерживаемый код в рамках своей текущей предметной области C++ программист вполне себе может.

eao197 ★★★★★
()
Ответ на: комментарий от Ivan_qrt

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

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

AntonI ★★★★★
()
Ответ на: комментарий от eao197

Плохой код можно написать на любом языке

Но все де на плюсах говнокодить гораздо проще чем на фортране/С.

Другое дело, что наилучший из возможных кодов в некоторых задачах можно написать тока на плюсах - у других ЯП не хватит средств и выразительности.

AntonI ★★★★★
()
Ответ на: комментарий от Ivan_qrt

ты бы взял к себе человека, который знает про std::launder (и понимает, зачем он нужен)

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

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 2)
Ответ на: комментарий от eao197

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

Может. Но с

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

это уже совсем не вяжется.

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

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

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

Обо всем другом сложно судить не зная конкретики. Но, скажем, про RTTI можно предположить, что человек, который годами работал в embedded (где ни RTTI, ни исключений), может не ответить сходу чем dynamic_cast отличается от static_cast.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Это медицинский факт. Скажем в числодробилках есть расхожее мнение, что плюсы медленнее с/фортрана. Конечно они будут медленнее если на каждом чихе толстые объекты передавать/возвращать по значению…

У плюсов очень много всяких возможностей, и заюзать че нить из них криво гораздо проще, чем в ЯП где возможностей меньше.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

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

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

Я так предполагаю, что большинство программистов рассчитывают на то, что операторы запятая, && и || не перегружаются никогда. Сам я на это рассчитываю.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от eao197

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

Допускаю что такое возможно, но мне это представить очень сложно.

bugfixer ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Запятая перегружается для левого операнда специального типа и возвращает результат такого же типа, а-ля <<. Если этот тип служебный и создантся тлько в специальных случаях в обертке, то что это может сломать? Ну если кто то захотел залезть руками в потроха этой либы, то он сам себе злобный буратино. Можно придумать защиту от дурака, но только от неизобретательного:-)

AntonI ★★★★★
()
Ответ на: комментарий от bugfixer

Допускаю что такое возможно, но мне это представить очень сложно.

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

eao197 ★★★★★
()
Ответ на: комментарий от eao197

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

Но, скажем, про RTTI можно предположить, что человек, который годами работал в embedded (где ни RTTI, ни исключений), может не ответить сходу чем dynamic_cast отличается от static_cast.

Может. Но в этом случае ему нужно будет с этим разбираться. Это более-менее базовые вещи языка. В особенности указатели, про rtti ещё можно сказать, что это уже более продвинутые вещи.

Микроконтроллерщикам действительно было бы странно спрашивать про rtti. Но если в кодовой базе есть, например, виртуальное наследование, то спросить про rtti как минимум стоит.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от eao197

А каким боком rtti к виртуальному наследованию?

Насколько я помню, upcast’ы при виртуальном множественном наследовании можно делать только dynamic_cast’ом. При этом компилятор во многих случая не будет там расчехлять rtti, но может, если не сможет рассчитать смещения баз.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Насколько я помню, upcast’ы при виртуальном множественном наследовании можно делать только dynamic_cast’ом.

upcast вы здесь употребляете как «приведение к указателю на базовый класс» или как «приведение к указателю на производный класс»?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Ну да. Судя по всему при апкасте компилятору всегда известны все смещения базовых классов и static_cast всегда хватает (по-крайней мере у меня не получилось придумать, в какой ситуации у него может этой инфы не быть).

Ну тогда dynamic_cast нужны только для даункастов, но для них-то точно может понадобится при множественном виртуальном наследовании.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Например библиотека линейной алгебры Eigen как раз перегружает запятую для инициализации матриц и векторов в таком духе:

Matrix2d A;
A<<1, 2,
   3, 4;

Сам я на это рассчитываю.

Зря :)

Waterlaz ★★★★★
()