Курсовая работа

Курсовая по программированию в МГТУ им. Баумана: как превратить код в инженерный проект с тестами и измеримым результатом

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

Содержание +

Запрос «курсовая по программированию в Бауманке» обычно относится не к отдельному направлению подготовки, а к конкретной дисциплине или проекту внутри IT-программы. Это важно, потому что требования курса могут быть заметно жёстче обычной учебной разработки.

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

Официальные страницы:
https://iu7.bmstu.ru/study-plans/
https://iu7.bmstu.ru/

Начните с алгоритмической задачи

Плохо:

«Создание программы на C++».

Сильнее:

«Разработка алгоритма маршрутизации на графе с анализом времени для графов различной плотности».

Язык является средством.

Результат - алгоритм и его поведение.

Техническое задание

Опишите:

  • вход;
  • выход;
  • ограничения;
  • ошибки;
  • размер данных.

Например:

N до 100000.

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

Примеры входа

Подготовьте:

  • обычный;
  • минимальный;
  • максимальный;
  • ошибочный.

Не тестируйте только один красивый пример.

Структура данных

Выбор:

  • array;
  • list;
  • hash map;
  • tree;
  • heap;
  • graph

должен следовать из операций.

Не используйте map там, где достаточно массива, только потому что он знаком.

Сложность операций

Составьте таблицу:

| Операция | Структура A | Структура B |
|---|---:|---:|
| поиск | ... | ... |
| вставка | ... | ... |

После этого выбор становится обоснованным.

Алгоритм

До кода запишите идею.

Например:

1. прочитать граф;
2. инициализировать очередь;
3. извлечь вершину;
4. обновить расстояния;
5. повторить.

Так легче найти логическую ошибку.

Инвариант

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

Это помогает объяснить корректность.

Например:

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

Граничные случаи

Проверяйте:

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

Большинство учебных ошибок прячется на границах.

Ошибка ввода

Программа должна корректно реагировать на неверный формат.

Не допускайте crash без сообщения, если ТЗ предусматривает пользовательский ввод.

Декомпозиция

Функция на 500 строк трудно тестируется.

Разделите:

  • parsing;
  • computation;
  • output.

Это облегчает unit tests.

Чистая функция

Где возможно, отделите логику от I/O.

Функция:

input -> output

тестируется намного проще, чем функция, которая сама читает файл и печатает.

Имена

Переменная `a1` допустима для короткой формулы, но не для сложной бизнес-логики.

Имя должно помогать читать алгоритм.

Не компенсируйте плохие имена длинными комментариями.

Комментарии

Комментируйте:

  • почему;
  • ограничение;
  • необычный алгоритм.

Не пишите:

`i++ // увеличить i`.

Код и так это показывает.

Ошибки памяти

Для C/C++ особенно следите за:

  • lifetime;
  • dangling pointer;
  • buffer;
  • double free.

Используйте sanitizers, если курс позволяет.

RAII

Управление ресурсом через объект уменьшает утечки.

Покажите, где ресурс создаётся и освобождается.

Не делайте ручной `new/delete` без необходимости.

Исключения

Определите, какие ошибки:

  • возвращаются;
  • обрабатываются;
  • приводят к завершению.

Не ловите `...` и не игнорируйте проблему.

Рекурсия

Проверьте:

  • базовый случай;
  • глубину;
  • стек.

Красивое рекурсивное решение может падать на большом N.

Итеративный вариант

Если глубина велика, сравните с итеративным.

Покажите память и время.

Не выбирайте стиль только по компактности кода.

Сортировка

Если используете готовый sort, объясните:

  • зачем;
  • сложность;
  • comparator.

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

Хеширование

Учитывайте:

  • collisions;
  • load factor;
  • worst case.

Не считайте hash lookup строго O(1) в любой ситуации.

Граф

Для задачи на графе определите:

  • directed;
  • weighted;
  • connected.

Выбор adjacency list или matrix зависит от плотности.

Dynamic programming

Запишите:

  • state;
  • transition;
  • base;
  • order.

Не начинайте с массива `dp`, пока не определено состояние.

Greedy

Жадный алгоритм требует доказательства свойства выбора.

Один набор тестов не доказывает общую корректность.

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

Unit tests

Каждый тест должен проверять конкретное поведение.

Плохое название:

test1.

Сильнее:

returns_empty_for_empty_input.

Тест должен быть читаемым.

Property-based testing

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

Например:

после сортировки элементы не убывают и сохраняется мультимножество.

Это сильнее нескольких ручных случаев.

Regression test

Нашли bug - сначала зафиксируйте тест, который падает.

Потом исправьте.

Так ошибка не возвращается.

Coverage

Процент строк полезен, но не является целью.

100% coverage может не проверять ни одного правильного результата.

Оценивайте смысл тестов.

Benchmark

Для performance-задачи генерируйте входы размеров:

10³, 10⁴, 10⁵.

Покажите:

  • время;
  • память;
  • медиану повторов.

Не делайте вывод по одному запуску.

Генератор данных

Фиксируйте seed.

Для графов укажите плотность.

Для строк - длину и алфавит.

Иначе сравнение методов может быть нечестным.

Профилирование

Если программа медленная, сначала измерьте.

Profiler покажет реальный hotspot.

Не оптимизируйте функцию, которая занимает 1% времени.

Оптимизация

Сравните до и после на одинаковом input.

Если ускорение только 2% и код стал в три раза сложнее, обсудите, стоит ли оно того.

Memory profiling

Иногда время нормальное, но программа использует слишком много RAM.

Покажите peak memory.

Это особенно важно для больших структур.

Файл данных

Если вход хранится в файле, отделите parsing от алгоритма.

Иначе скорость чтения может скрыть разницу вычислений.

Параллельность

Добавляйте только если задача действительно параллелится.

Измерьте speedup и overhead.

Не считайте количество потоков равным ускорению.

Репозиторий

Сохраните:

  • source;
  • build instructions;
  • tests;
  • examples.

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

Сборка

Для C/C++ используйте понятный build process:

  • CMake;
  • Make;
  • другой инструмент курса.

Не требуйте ручного запуска десяти команд без документации.

Практическая глава

Хорошая структура:

1. ТЗ;
2. алгоритм;
3. структуры;
4. реализация;
5. тесты;
6. benchmark;
7. анализ сложности;
8. ограничения.

Бауманский контекст

На ИУ7 и других IT-кафедрах программирование является фундаментальной практикой, но конкретные требования зависят от языка и дисциплины.

Курсовой проект по алгоритмам, ООП и системному программированию должен иметь разную структуру.

Защита

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

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

Степан Сергеев

Автор – Степан Сергеев

Кандидат физико-математических наук (PhD). Четыре диплома о высшем образовании. Помогаю разобраться в учебных и исследовательских задачах.

Ещё по теме