vak: (Default)
[personal profile] vak
Нас всех учили понемногу, чему-нибудь и как-нибудь. В моё время, в середине 80-х обучение программированию сводилось к изложению синтаксиса языка и написанию коротких изолированных задачек. На первом курсе нам давали Алгол и Бейсик, на втором Фортран и Паскаль, на третьем ассемблер (тогда он назывался автокод) и снова Фортран, на четвёртом почему-то опять Фортран, с самого начала.

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

С тех пор много воды утекло, и сейчас есть несколько книжек, учащих реальным приёмам программирования. Вот одна из них: "Modern C++ Programming with Test-Driven Development".



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



Кроме TDD есть и другие подходы: BDD, TSD и прочие. Но все большие проекты из моего опыта используют методику "непрерывного" тестирования. Без этого разработка больших продуктов вообще невозможна, ведь внося любое изменение программист нарушает поведение системы. Без набора тестов с хорошим покрытием невозможно определить, насколько допустимо это нарушение.

Для поддержки разработки через тестирование существует несколько пакетов похожей функциональности: Googletest, CppUnit, Catch и другие. Некоторые из них описаны в вышеприведённой книжке. Я по работе использую Googletest, а для самоделок Catch.

В качестве заготовки я приготовил два репозитория (на Гитхабе и на Битбакете) с одним и тем же примером на Си++: вычислением чисел Фибоначчи.
Тестируемая функция - вычисление чисел Фибоначчи методом конечной рекурсии: demo.cpp

Набор тестов к ней: test_demo.cpp

Запуск тестов выглядит так:



После каждого коммита заходим на вкладку Actions (на Гитхабе) или Pipelines (на Битбакете) и смотрим результаты автоматического тестирования.

Date: 2020-08-04 09:44 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Не знаю, почему вас не учили. Я писал диплом по методике Джексона.

Date: 2020-08-04 18:06 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Объектно-ориентированное тогда было только в бредовом изложении Буча. Книга Шлейер-Меллора, где принципы описывались по-человечески, появилась только в девяносто третьем, а использовать его начал уже на второй работе.

Date: 2020-08-04 10:41 (UTC)
gonchar: (Default)
From: [personal profile] gonchar
Любопытство - тот тезис, который я ниже напишу, он - банальность, чепуха, что-то иное?

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

Однако есть принципиальная сложность - она появляется тогда и только тогда, когда программистов нужно более одного. И почти всё, что делалось в теории программирования, по сути делалось ради решение этой задачи. Как сделать так, чтобы группа программистов, работающих параллельно или последовательно, получала эффективный результат, а не тонула в бездне проблем взаимодействия друг с другом.
И именно ради этой задачи и пишутся новые языки, строятся системы, придумываются технологии - и пр., и пр.
Edited Date: 2020-08-04 10:44 (UTC)

Date: 2020-08-04 12:29 (UTC)
sobriquet9: (Default)
From: [personal profile] sobriquet9
Тезис неверный. Не всех можно научить программировать, особенно за несколько месяцев. Я до сих пор проваливаю вопросы на собеседовании.

TDD позволяет обнаружить внесённую ошибку сразу. Тогда её легче найти и проще исправить. Это полезно даже при работе в одиночку.

Date: 2020-08-04 14:13 (UTC)
gonchar: (Default)
From: [personal profile] gonchar
1.Я не очень точно, конечно, сказал. Я говорил о ЗНАНИЯХ и НАВЫКАХ, а прозвучало, словно любой человек, формально окончивший... Нет, конечно, мозги определённого уровня и желание учиться и работать нужно.

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

То есть, мой вопрос остаётся с учётом п.1.
Грубо, Борланд С - помните такой? - уже достаточен для чего угодно, если человек работает один. Проблемы начинаются тогда, когда задача - написать что-то, на что производительности одного попросту не хватит, когда придётся либо использовать чужой код, либо писать вместе с кем-то.

Date: 2020-08-04 15:36 (UTC)
sobriquet9: (Default)
From: [personal profile] sobriquet9
Борланд С недостаточен для чего угодно. Точнее он достаточен для чего угодно в том же смысле, в котором машина Тьюринга достаточна для чего угодно - они оба Turing complete и любая программа может быть тривиально преобразована туда-сюда. Только тривиальность эта чисто математическая. На практике написать современное приложение с серверами в облаках и отдельными клиентами для iPhone/Android/браузеров ни на том, ни на другом не получится.

Вместе с кем-то приходится писать потому что много писать, и потому что надо много знать разного. Тяжело одному человеку оставаться на переднем крае всего сразу, неизбежна специализация. Хотя сейчас модно это отрицать и даже слово специальное есть, dev ops.

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

Date: 2020-08-04 16:33 (UTC)
sab123: (Default)
From: [personal profile] sab123
Идея о писании тестов до кода неправильная. До реализации есть смысл писать примеры использования. Но это совсем-совсем не то что тесты. Примеры должны быть маленькими, а тесты - наоборот, детальными и залазящими в каждый закоулок. Если писать тесты до реализации, то это большое количество выбрасываемой на ветер работы (потому что их та кили иначе придется исправлять по релузьтатам реализации). Поэтому я подозреваю, что у таких авторов очень неправильнео понимание, что такое тесты.

Date: 2020-08-04 18:12 (UTC)
sab123: (Default)
From: [personal profile] sab123
Смысл тестов - именно проверка правильности кода во всех граничных случаях. Выходит, что автор путает тесты и примеры, и видимо в итоге не тестирует получившийся код.

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

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

Date: 2020-08-04 20:03 (UTC)
sab123: (Default)
From: [personal profile] sab123
Книжки у меня нету. Из википедии следует именно то, что я рассказал.

В книжке есть раздел "Test-driven vs testing" но Амазон не дает его открыть. Даже если они в итоге пишут настоящие тесты, то тогда все равно название неправильное, и подвигающее людей на неправильные вещи.