C++ 1MIT осень 1 2019 — различия между версиями

Материал из CSC Wiki
Перейти к:навигация, поиск
(Практика 1: Соколов)
(Практика 2: Свиридкин)
Строка 247: Строка 247:
  
 
[https://github.com/Nekrolm/cmake_vscode_example Репозиторий] с минимальным примером cmake-проекта с настроенным vscode
 
[https://github.com/Nekrolm/cmake_vscode_example Репозиторий] с минимальным примером cmake-проекта с настроенным vscode
 +
 +
 +
 +
'''Особенности оценивания сдаваемых работ:'''
 +
 +
 +
1. Корректное решение поставленной в лабораторной задачи весит 75% от максимального числа баллов.
 +
 +
2. Segmentation fault и иное любое проявление Undefined Behavior на каком-либо '''корректном''' наборе входных данных приводят к оценке в 0-25% баллов. Используйте valgrind и(или) санитайзеры. Тестируйте свои программы более чем на одном первом пришедшем в голову тесте.
 +
 +
3. Оставшиеся 25% баллов приходятся на стиль кода, удачные (к месту) реализации тех или иных моментов и почее.
 +
 +
4. Утечки памяти приводят к уменьшению числа начисленных баллов на 5-20% (в зависимости от тяжести, явности или неявности).
 +
 +
5. На сдачу дается 3 попытки. Их использовать можно как угодно, с соблюдением двух условий:
 +
  -- Одна попытка должна быть обязательно сделана до промежуточного дедлайна (или иное требование, указанное в условиях задач)
 +
  -- В день финального дедлайна после 18:00 сгорают все попытки, кроме одной.
  
 
== Практика 3: Лапшин ==
 
== Практика 3: Лапшин ==

Версия 21:30, 10 октября 2019

Лекции

Лекторы:

  • I поток: Линский Евгений Михайлович (evgeny.linsky@gmail.com)
  • II поток: Суворов Егор Федорович (egor_suvorov@mail.ru)

Ссылки:

Презентации первого семестра:

Планы лекций Егора: github.com/yeputons/hse-2019-cpp

Презентации ликбеза по С:

Книги

  • С нуля
    • С. Дэвис, C++ для чайников
    • Г. Шилдт, С++ базовый курс
  • Язык С
    • Б. Керниган, Д. Ритчи, Язык программирования C
    • Б. Керниган, Р. Пайк, Практика программирования
  • Язык C++
    • Б. Страуструп, Язык программирования С++
    • Б. Эккель, Философия C++
  • Дополнительно
    • Б. Страуструп, Дизайн и эволюция языка C++
    • С. Майерс, Эффективное использование С++/Эффективное использование STL
    • Г. Сеттер, Решение сложных задач на C++/Новые сложные задачи на C++
    • Р. Седжвик, Алгоритмы на C++
  • На английском

Оценка за курс

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

  1. В течение семестра (помимо одного экзамена в конце семестра, в конце второго модуля) проводятся:
    1. Письменные тесты по материалу лекций, каждый оценивается примерно в 10 баллов. Ожидается примерно три.
    2. Лабораторные работы, каждая оценивается примерно в 5-15 баллов. Ожидается примерно восемь.
    3. Большие домашние задания, каждое оценивается примерно в 30 баллов. Ожидается примерно два.
    4. Также на усмотрение преподавателя практики можно получить до 10 дополнительных баллов за особо хороший код.
    5. Всего можно получить порядка 160-200 баллов.
  2. Обозначим долю полученных баллов за всю работу в течение семестра за P. P может быть больше 1, если сделано всё и ещё получены дополнительные баллы.
  3. На экзамене ставится одна из четырёх оценок: 0, 1/3, 2/3, 1, обозначим её E.
  4. Итоговая оценка за предмет: 6 * P + 4 * E, округляется до ближайшего целого, а при .5 — вверх. Если получилось меньше 1, то 1. Если получилось больше 10, то 10.
  5. Блок: если хотя бы одно из больших домашних заданий не сдано (<=> не сделана попытка или баллы за корректность равны нулю), то курс не зачтён.
  6. Блок: если P < 0.4, то курс не зачтён.
  7. Блок: если E=0, то курс не зачтён.

Примеры

  1. Вы получили 3/4 баллов по домашкам (P=0.75) и сдали экзамен на E=2/3. Тогда итоговая оценка: 7,17 → 7 (хорошо).
  2. Вы получили 3/4 баллов по домашкам (P=0.75) и сдали экзамен на E=1. Тогда итоговая оценка: 8,5 → 9 (отлично).
  3. Вы получили чуть больше половины баллов по домашкам (P=0.54) и сдали экзамен на E=1. Тогда итоговая оценка: 7,24 → 7 (хорошо).
  4. Вы получили чуть больше половины баллов по домашкам (P=0.54) и сдали экзамен на E=2/3. Тогда итоговая оценка: 5,91 → 6 (хорошо).
  5. Вы получили чуть больше половины баллов по домашкам (P=0.54) и сдали экзамен на E=1/3. Тогда итоговая оценка: 4,57 → 5 (удовлетворительно).
  6. Вы прошли ровно-ровно по блокам (P=0.4, E=1/3), тогда итоговая оценка: 3,73 → 4 (удовлетворительно).
  7. Вы полностью сдали домашки (P=1), но завалили экзамен (E=0). Тогда P делится пополам и итоговая оценка: 6 * P / 2 + 4 * (E-2)/3 = 3 по десятибалльной шкале (неудовлетворительно).
  8. Вы завалили домашки (P < 0.4). Тогда итоговая оценка независимо от экзамена не превосходит 2.4 → 2 (неудовлетворительно).

Лабораторные и домашние

  • GitHub — гит-репозиторий с описаниями лабораторных (обновляется каждую неделю).
  • Trac — trac для лабораторных.
  • http://trac.compscicenter.ru/hse-svn/cpp19/lastname.firstname — svn для лабораторных (замените lastname.firstname на ваш логин - имя-фамилия транслитом).

Сдача и оценивание

Подробная инструкция по сдаче расположена на главной странице Trac.

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

Практика 1: Соколов

Преподаватель: Вячеслав Соколов (vi.soksok@gmail.com, +7 921 780 11 12)

Trac: sokolov

deadline первой попытки первой лабораторной: среда 09.11 21:00

Письма просьба идентифицировать префиксом в теме [HSE][CPP]

Linux

  • Минимальный набор для работы из консоли (для Ubuntu):
    • man manual
    • ls list
    • pwd print working directory
    • mkdir make (create) directory
    • cd change directory
    • cp copy
    • rm remove
    • touch "потрогать" объект на файловой системе
    • mv move
    • gcc gnu C compiler
    • make make
    • svn subversion
    • apt aptitude
  • Исследование бинарных артефактов
    • nm list symbols from object files
    • readelf displays information about ELF files
    • c++filt demangle symbols

Для тех, кому хочется поэкспериментировать с консолью

  • Эмуляторы терминала
    • terminator
    • tilix
    • а также много других, легко ищутся
  • Shell
    • bash по умолчанию, но есть кое-что поудобнее, например
    • fish - interactive shell, создан, чтобы быть удобным
    • zsh - для любителей писать скрипты

Системы сборки

Для наших нужд достаточно Make

Если проект становится большим, нужно что-то посложнее, например (альтернативы):

Полезные сайты

  • cppreference - консультация со стандартом языка Си
  • godbolt - compiler explorer (удобно делиться примерами)
  • ideone - возможность делиться кодом, поддержка разных ЯП, исполнение кода online
  • stackoverflow - огромное количество ответов на разные вопросы. Прежде чем самому задавать вопрос, будет полезно ознакомиться с текстом https://habr.com/ru/post/339038/
  • cdecl - поможет ответить на вопрос, что есть int (*(*foo)(void ))[3]

Статьи

Практика

Требования корректности, предъявляемые к работам

1. Проверка контрактов функций.

На мой взгляд, чуть ли не единственной обязательной к использованию парадигмой и доступной во всех языках программирования, выше ассемблера, является [1]. Ключевые понятия: предусловия, постусловия и инварианты. В языках C/C++ соблюдение контрактов контролируется с помощью assert, возведения сигналов, бросания исключений.

Данный подход является обязательным, потому что гарантирует максимально раннее обнаружение проблемы. Игнорирование подхода приводит к проблемам в самых неожиданных местах. Программа может вести себя как корректная, хотя содержит в себе большое количество ошибок, пока очередная проблема не приведет к лавине. Примеры неожиданно всплывших проблем: https://software-testing.ru/library/testing/general-testing/2082-horrible-bugs

Требуется производить проверку контрактов:

  • предусловий: с помощью assert в начале функции. Пример: Указатель: может быть нулевым? Нет? assert.
  • инвариантов: по ходу выполнения функции. Пример: по ходу алгоритма нужно произвести удаление элемента из контейнера. Можно проверить, что этот элемент вообще присутствует в контейнере.
  • постусловий: В конце функции и с помощью тестов. Пример: в результате удаления вершины из списка она не должна быть достижима из головы списка. Это можно провалидировать с помощью assert.

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

Q: но ведь проверка контракта может быть медленной, теряем производительность

A: используйте assert для медленных проверок, если нужна производительность - используется release режим сборки, туда эти проверки не попадут

Q: а что делать с malloc, который вернет NULL, это же и в release может случиться

A: сейчас у нас в арсенале нет способа просто решить эту проблему. Можно, но сложно. Поэтому ставим assert, чтобы развивать привычку. В заданиях незачем аллоцировать Очень Много Памяти, поэтому проблема не слишком актуальная. "В жизни" будет использоваться не assert, а какой-то другой механизм.

2. Стиль кода совпадает во всем проекте.

Либо везде табуляции для отступов, либо везде пробелы. Именование переменных либо везде snake_case, либо везде camelCase. Желательно отделять разные сущности друг от друга написанием. Например, можно выделять:

  • МАКРОСЫ()
  • КОНСТАНТЫ
  • функцииКоторыеЧтоТоДелают()
  • переменныеКоторыеЗачемТоПонадобились
  • ИменаКлассовИСтруктур

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

3. Каждая строчка кода что-то делает.

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

4. В языке Си использовать void(void), а не void().

5. Отсутствие утечек памяти, Undefined Behaviour и других проблем Ваша программа должна компилироваться и корректно завершаться, а соответствующая утилита не должна находить какие-либо проблемы:

  • в debug и release (-DNDEBUG) режимах сборки
  • будучи запущенной из-под gdb
  • будучи запущенной из-под valgrind
  • после компиляции с -fsanitize=address
  • после компиляции с -fsanitize=undefined
  • после компиляции с -fsanitize=leak
  • на разных версиях разных компиляторов (gcc, clang, msvc, ...)

включая комбинации этих опций, кроме случаев ошибок в самих утилитах и несоответствия компилятора Стандарту. (Да, и то, и то бывает.)

6. Именование должно быть понятным кому угодно, не только лишь Автору, но и всем. Имя функции должно отражать особенности ее поведения. Имя переменной должно быть говорящим. Лучше всего, если вне контекста можно понять, за что отвечает / что делает та или иная функция, структура, переменная. Стандарт языка в этом смысле не является примером для подражания.

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

7. Если была допущена какая-то проблема в реализации функции, должен быть написан тест, детектирующий эту проблему.

8. Использование сторонних функций только из стандартной библиотеки языка, если противное явно не оговорено в задании.

В частности, написание C/C++ кода без привязки к платформе Linux; отсутствие POSIX-специфичных функций и структур. Не смотря на то, что целевая платформа - Linux, привычка писать платформенно-специфичный или компиляторо-специфичный код может однажды сыграть злую шутку. Комитет по стандартизации стремится к тому, чтобы не было необходимости писать такой код, включая новые и новые платформенно-независимые вещи в стандарт языка. Если "совсем никак", то лучше обернуть специфичную функцию: сделать size_t mygetline(char **lineptr, size_t *n, FILE *stream) {return getline(lineptr, n, stream);}

To be continued.

Практика 2: Свиридкин

Преподаватель: Дмитрий Свиридкин (dmisvrl1@gmail.com) Префикс [C++Practice]

Договоренности со студентами:

1. Бинарники складывать в каталог bin, объектники -- в каталог obj

2. Разобравшиеся с make, при желании, могут использовать cmake


Полезные ссылки:

Кратко про make: habr

Дополнительно про mangling

Минимальный набор команд для работы с консолью (bash)

Примеры UB c cppreference

UB c вызовом невызываемой функции [2]

Репозиторий с минимальным примером cmake-проекта с настроенным vscode


Особенности оценивания сдаваемых работ:


1. Корректное решение поставленной в лабораторной задачи весит 75% от максимального числа баллов.

2. Segmentation fault и иное любое проявление Undefined Behavior на каком-либо корректном наборе входных данных приводят к оценке в 0-25% баллов. Используйте valgrind и(или) санитайзеры. Тестируйте свои программы более чем на одном первом пришедшем в голову тесте.

3. Оставшиеся 25% баллов приходятся на стиль кода, удачные (к месту) реализации тех или иных моментов и почее.

4. Утечки памяти приводят к уменьшению числа начисленных баллов на 5-20% (в зависимости от тяжести, явности или неявности).

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

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

Практика 3: Лапшин

Преподаватель: Дмитрий Лапшин, по вопросам курса писать сюда: au-cpp@ldvsoft.net.

Ссылочки выше и ниже тоже полезны!

Практика 4: Суворов

Преподаватель: Егор Суворов (egor_suvorov@mail.ru, t.me/yeputons).

Префикс в теме электронного письма: [C++TA]

В личку писать по системе neprivet.ru: сразу пишете вопрос, а не спрашиваете, можно ли задать вопрос.

Есть беседа в Telegram, куда надо вступить: там будут оповещения про занятия и промежуточные дедлайны. Ещё там можно задавать вопросы.

Планы практик: github.com/yeputons/hse-2019-cpp (папки, заканчивающиеся на p)

Попытки сдачи лабораторных

  • Я проверяю лабораторные несколько раз в неделю в определённое время (анонсируется в беседе): сажусь и занимаюсь проверкой с времени T1 до времени T2.
    • Если что-то пришло до момент T2 — проверяю, пока не наступит время T2 (после этого проверка прекращается, что не успел — то не успел).
    • В приоритете более старые лабораторные (по которым раньше дедлайн).
    • На одну посылку у меня уходит 5-15 минут. Вы можете посмотреть на текущие тикеты в Trac и примерно оценить свою позицию в очереди.
  • Исправления после последнего срока сдачи лабораторной оцениваются в ноль баллов. Но можно допроверить "для себя".
  • Для баллов и проверки абсолютно неважно, когда вы сдаёте лабораторную.
    • Но если сдали лабораторную раньше, она раньше в очереди и раньше будет проверена => больше шансов исправить
    • Я почти никогда не видел, чтобы сдавали с первой попытки. Можете попробовать сдать за три минуты до дедлайна — если всё корректно, то честно получите полный балл.
  • Неважно количество попыток сдачи (но если пытаетесь меня заспамить вместо тестирования, то я вежливо пишу "не надо так").
  • Можно пропускать попытки сдачи без последствий (кроме "у вас меньше шансов на исправления").
  • Если вы успеваете исправить замечания до того, как у меня закончился слот T1-T2, я проверю ещё раз (если успею).
  • Если вы прислали некорректно оформленное задание (например, не все поля в Trac заполнены), то я об этом сообщю, а попытка может быть либо проигнорирована до исправлений, либо перемещена в конец очереди.

Особенности проверки

  • Если ваше решение не проходит ваши собственные тесты — автоматически ноль за попытку и дальше не проверяю. Если вы уверены, что у вас всё проходит — напишите в личку, разберёмся. Скорее всего, я потребую, чтобы вы сначала проверили:
    • Отсутствие изменений, которые не попали в репозиторий (svn status ничего не выводит)
    • Ваш код корректно работает с Address Sanitizer
    • Ваш код корректно работает под Valgrind
  • В первых попытках сдачи стиль я либо вообще не проверяю (если корректность слишком мала), либо проверяю поверхностно, потому что при исправлении корректности всё равно всё поменяется.
  • При исправлении стиля вы можете добавить новых стилистических замечаний (особенно если исправление большое), поэтому исправление стиля может занимать несколько итераций. А ещё это повод мне не проверять детально каждую строчку, если я понимаю, что она всё равно поменяется.
  • Если вам кажется, что я засыпаю вас всё новыми и новыми замечаниями по стилю и получается нечестно — требуйте объяснений/справедливости в личке.
  • Если прошёл дедлайн, а я так и не проверил/не выставил баллы за корректность или стиль — переоткройте тикет с комментарием "хочу подробные баллы".

Критерии оценки

  • Лабораторная №3 (WW_intrusive_list), корректность:
    • Корректный Makefile и структура папок +1
    • Работают print, add, exit (возможно, с утечками или крупными нарушениями формата) +1
    • Работают print, add, exit (возможно, с утечками или небольшими нарушениями формата) +1
    • print не выводит лишних пробелов и выводит перевод строки +0.5
    • Корректно обозначен размер буфера при считывании команды +0.5
    • Работает ещё и len +1
    • Работает ещё и rm +1
    • Работает ещё и rma +1
    • Нет утечек памяти +1

Полезная информация

  • Ключ GCC для включения отладочной информации при компиляции (номера строк, имена исходных файлов): -g
  • Ключ GCC для включения address sanitizer (попытка поймать обращения не к той памяти, в том числе выходы за границу массивов: -fsanitize=address (надо добавлять и на этапе компиляции, и на этапе линковки)
    • Также можно пробовать -fsanitize=undefined (пробует ловить UB)
    • Address sanitizer несовместим с Valgrind.
    • Запускать приложение как обычно: ./lab_01
  • Для запуска Valgrind надо отключить sanitizer, всё перекомпилировать и запускать как valgrind ./lab_01
  • Ключи на все случаи жизни для предупреждений: -Wall -Wextra -Werror
  • Видео с демо отладчика GDB на английском на 15 минут (интерфейс, путешествия во времени): https://www.youtube.com/watch?v=PorfLSr3DDI

Практика 5: Гулецкий

Преподаватель: Артур Гулецкий (hatless.fox@gmail.com)

Префикс в теме письма: [C++TA]

Еще один вариант книги с нуля: C++ Primer, 5th

Makefile

Почитать (opt):

GDB

  • GDB intro + мини-ликбез по ассемблеру/C Hacking tAoE, 2nd, sect. 0x250-0x270
  • (opt) DWARF - формат для хранения отладочной информации

C-string utils

Почитать:

Intrusive lists

C I/O

Практика 6: Алфёров

Преподаватель: Василий Алфёров (vasily.v.alferov@gmail.com)

Telegram: @vasiliyalferov

Дедлайн по исправлениям лабораторных работ, если они разрешены: неделя после проверки.


Обещанные ссылки: