LINUX.ORG.RU

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

 ,


0

3

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

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

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

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

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

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

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

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

Поскольку любое приведение к указателю на наследника безопасно делать только через dynamic_cast, то наличие/отсутствие виртуального наследования здесь абсолютно фиолетово.

Ну и если у соискателя решили спросить про виртуальное наследование, то dynamic_cast здесь должен обсуждаться уж точно не в первую (и не во вторую, и не в третью) очередь.

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

Поскольку любое приведение к указателю на наследника безопасно делать только через dynamic_cast

Дык, неправда же - информация о настоящем типе может быть доступна из сторонних каналов, да и virtuals может не оказаться…

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

Дык, неправда же - информация о настоящем типе может быть доступна из сторонних каналов

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

да и virtuals может не оказаться…

Тогда и dynamic_cast, емнип, откажется работать.

eao197 ★★★★★
()

По описанию похоже на тест по C++ в универе. Там не столько умение программировать проверялось, сколько знание стандартна на уровне разработчика компилятора. Собственно составляла его кафедра, которая немного занимается компиляторами, поэтому не удивительно.

Вообще тест по ЯП – заранее провальная идея, которая к чему-то подобному и приводит.

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

Поскольку любое приведение к указателю на наследника безопасно делать только через dynamic_cast, то наличие/отсутствие виртуального наследования здесь абсолютно фиолетово.

Смотря что подразумевать под «безопасно». Да, в случае ошибок программиста static_cast исключение не бросит, но если с типами ошибок нет и они контролируются как-то ещё, то без виртуального наследования можно спокойно делать static_cast, а с виртуальным нельзя и нужен dynamic_cast.

то dynamic_cast здесь должен обсуждаться уж точно не в первую (и не во вторую, и не в третью) очередь.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ну и опять таки, в ВУЗе учат с запасом, и это правильно. Тем же матанализом во всем объеме я не знаю кто на работе пользуется…

AntonI ★★★★★
()

Видимо, хотят понять

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

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

«учиться учиться и еще раз учиться!» всем курсы, конференции и мастер классы, руководству кривую обучения персонала, стремящуюся к зияющим вершинам.

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

конец истории.

olelookoe ★★★
()
Ответ на: комментарий от ya-betmen

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

Т.е., сложность в понимании кода должна в первую очередь быть прямым следствием сложности предметной области, и в последнюю - особенности ЯП.

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

именно. Есть 3 стадии проявления ошибки:

  1. на этапе компиляции/верификации;
  2. на этапе исполнения, контролируемо (перехватываемые исключения);
  3. на этапе исполнения, неконтролируемо.

Чем более безопасен ЯП, тем больше ошибок обнаруживаются на как можно более ранних стадиях, в идеале весь код верифицируется статически.

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

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

Или фишка нашей кафедры

Мы(я) что-то пропускаем. Раскройте subject plz?

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

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

Ну для условного eigen может быть полезно, да. Но полезность самой high-level библиотеки алгебры на C++ уже сомнительна. Я давно таким не занимался, но кажется сейчас проще построить оптимальный граф вычислений (и символьные преобразования) где-нибудь на python, откуда дёргать плюсовый код максимально тупых числодробилок как в том же numpy. С шаблонной абстракцией, опять же, сложнее контролировать сработала ли автовекторизация циклов.

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

Или не иметь представления о назначении std::launder.

Почитал. Трындец костыль. После такого хочется писать на чистой сишке. Единственное не понял – это в C++17 новый UB и его решение завезли, или это решение для старого UB, который нашли юристы языка? Страшно представить, сколько пул аллокаторов наступили на него.

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

Основная проблема, которую я наблюдаю - пишут на С, а компилируют С++ компилятором.

Нужно дать простую задачу (чтобы это не был тест на алгоритмы) и посмотреть, везде ли используют С++.

Например, ввести с клавиатуры пару строка-число и отсортировать сначала по строке, а потом по числу. Если человек использует scanf(), printf(), char *, массивы/веторы не из STL, и вручную пишет сортировку - сразу указывать на дверь. Потому что такие потом наплодят memory leak’ов и будут говорить что С++ виноват.

Как по мне вот этого достаточно:

Если человек демонстрирует указанное выше, я бы уже его брал. Всё остальное наживное (а часто и вредное: практика показывает, что чем замудрённее конструкции используются, тем сложнее другому человеку будет читать код).

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

Хотябы основы exception safe programming, как минимум гарантирует что в деструкторе не будет исключений.

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

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

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

Нужно дать простую задачу (чтобы это не был тест на алгоритмы) и посмотреть, везде ли используют С++.

А я бы вот смотрел на знание алгоритмов и data structures гораздо более внимательней чем на C++ специфичные вещи.

И кстати - плюсовые стримы по сравнению с C-шным IO - медленные.

ПыСы. Я не о printf() / scanf(), а об read() / write() (ну или хотя бы fread() / fwrite())…

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

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

И 3-ёх утра по Москве не было - что вы здесь делаете?

генерация исключения говорит о том, что аффтар не представляет как ему локально разрулить неожиданную ситуацию

Иии??

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

После такого хочется писать на чистой сишке.

А вам кто-то не дает это делать?

это решение для старого UB, который нашли юристы языка?

Решение для старого UB, которое до C++17 компиляторостроители не могли эксплуатировать. Сейчас могут.

Страшно представить, сколько пул аллокаторов наступили на него.

Если нормально используют placement new, то нисколько.

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

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

Ваша категоричность заставляет поинтересоваться сколько человек в команде, в которой вы работаете?

eao197 ★★★★★
()

а разве у крестовиков нету сертификации по типу многоуровневых cisco/microsoft/rh/kuber/lpic/etc?
или условно Страуструпа прочитал - достоин?

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

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

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

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

все хорошо в меру, короче.

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

Меня интересует не логика Хоара, а ваш опыт в качестве разработчика ПО. Категоричность ваших суждений (не только в этой ветке) вселяет серьезные опасения о том, а есть ли таковой вообще.

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

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

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

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

Это все лишь одна из возможных политик обработки ошибок

Позволю себе доколупаться до формулировок: одна из возможных политик информирования об ошибках.

Обработка это уже несколько другое. Ее может и не быть.

Извините за буквоедство.

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

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

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

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

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

афторы Эйген вообще большие затейники, к тому же шаблонов там наверчено жуткое количество

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

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

а меня ваш опыт в качестве разработчика по не интересует.

Прекрасно. Но меня ваш интересует дабы вывести коэффициенты «поправки на ветер» для ваших высказываний.

у вас есть аргументы в пользу втыкивания везде исключений?

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

Во-вторых, да, в пользу исключений есть очень веский довод: их нельзя просто так проигнорировать, при этом happy path не замусоривается лишними проверками.

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

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

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

Основная проблема, которую я наблюдаю…

Если человек использует scanf(), printf(), char *, массивы/веторы не из STL, и вручную пишет сортировку - сразу указывать на дверь.

Бггг, с таким подходом я бы сам рванул к двери роняя тапки.

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

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

STL по дефолту работает с памятью очень неэффективно. Где то это прокатывает, где то нет.

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

Я глубоко эйген не копал, коллеги его юзали в каком то проекте а мне пришлось его в питон биндить через SWIG. Как погромист я его оценивать не возьмусь, но как конечный пользователь… мне например категорически НЕ НРАВИТСЯ, что тип результата будет зависеть о того перемножаю я строку на столбец или наоборот. Да, в линейной алгебре это важно. Но я физик, и числодробилки наши идут от физики, а там вектор это вектор, скалярное произведение векторов это число, и у меня дел других нет - тока думать о том кто там столбец а кто строка и кого надо транспонировать.

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

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

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

eao197 ★★★★★
()