Skip to main content

Разработка ПО

Вначале программистами были учёные. Они сами писали программы и сами их использовали. Сами программы писались на перфокартах. Подробнее об этом этапе можно прочитать здесь.

Базы данных

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

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

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

Об исполняемых файлах

Исполняемым файлом называют файл с программой, которая состоит из машинных команд. В операционной системе Windows исполняемые файлы имеют расширение .exe от слова execution, оно переводится, как "исполнение". Исполняемые файлы ещё называют бинарниками, потому что команды хранятся уже в двоичном коде, а не в текстовом представлении, например.

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

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

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

Т.к. раз разом программисты решали одни и те же задачи, то в какой-то момент появилось готовое решение, которое снимало с программистов часть рутинных задач. Этим решением стал стандарт SLQ (structured query language - язык структурированных запросов).

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

Сейчас самое популярное SQL решение - это PostgreSQL. Инструкция по установке на Windows можно найти здесь.

Для изучения рекомендую книгу "Postgres: первое знакомство". Скачать её можно здесь.

Общая идея табличных, иными словами, реляционных(SQL) баз данных заключается в том, что все связи между таблицами указываются при помощи дополнительных колонок и идентификационных номеров id.

Подход с id пришёл из бумажных формуляров. Там каждой записи присваивался порядковый номер.

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

Пусть мы хотим хранить информацию об учениках и об их школах, где они учатся.

При этом о каждой школе мы хотим хранить информацию о её названии и районе:

Школы
idНазвание школыРайон
0ФМЛ №239Центральный
1ФМЛ №30Василеостровский
2Лицей ФТШВыборгский

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

Ученики
idФамилияid школыКласс
0Иванов110
1Сидоров19
2Петров09
3Смирнов211
3Агапов09

Такой подход очень хорош, когда нам надо работать с данными в конкретной таблице, а не переходить по связанным объектам. Если связи меняются чаще, чем добавляются или просто изменяются записи в таблицах, тогда лучше использовать NoSQL решения.

Такие базы данных ещё называют нереляционными. Реляция - это донесение. в названии подразумевается, что необязательно работать с базой данных, как с таблицей.

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

Тестирование

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

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

Работая над своим модулем, разработчики начали писать тесты для проверки до объединения. Хотя на написание тестов тратится дополнительное время, оно с лихвой окупается при объединении. Объединение модулей или программ в программировании называется интеграцией. Тестирование на уровне модулей или компонент называется Unit тестированием. Подробнее о нём можно прочитать здесь.

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

Сейчас написание юнит-тестов - это уже отдельная профессия QA Engineer, QA расшифровывается как Quality Assurance, т.е. "обеспечение качества".

полезное средство

Для тестирования веб-сайтов создан специальный фреймворк Selenium. Он запускает свой браузер и эмулирует действия пользователя, при помощи команд python или java, как если бы это делал настоящий человек. При этом браузер может быть запущен в фоновом режиме. Подробнее о selenium можно прочитать на хабре.

Автоматическая сборка

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

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

В java библиотеки автоматически устанавливаются при помощи maven или gradle. В python при помощи pip.

Помимо сборки на локальном компьютере, сейчас принято поднимать сервер сборки. Самый известный сервер - это Jenkinks.

jenkins

Он автоматически обрабатывает все новые изменения в репозитрии git (о нём будет рассказано в следующем параграфе), потом скачивает код и согласно инструкциям выполняет сборку проекта. В этих инструкциях можно указать и просто команды linux. Обычно на jenkins выполняют сборку проекта, тестирование и публикацию программы на рабочем сервере.

Agile

Вместе с развитием средств разработки развивалась и сама методология. Методология - это набор приёмов для решения тех или иных задач. Подробная история развития методологий описана здесь.

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

Самая продвинутая методология на данный момент - это Agile. Она пришла из стартапов, где замотивированные толковые люди объединялись для совместной работы над сложной задачей. Для рутинной поддержки или полностью предсказуемого программного обеспечения лучше использовать RAD Model.

Agile манифест

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

ex

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

По сути agile сейчас - это просто набор приёмов, которые укладываются в определённую манифестом концепцию.

Подробнее о выгодах Agile написано в этой статье.

ex

XP

Самая известная реализация Agile - это экстримальное программирование(XP).

XP - это набор конкретных методик, которые в 2004 году собрал воедино эксперт по менеджменту Дуг Де Карло. Расшифровывается это название как eXtreme Progrmamming.

ex

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

Первый контур охватывает непосредственную работу программиста:

  • Разработка через тестирование - одна из самых трудных практик методологии. В XP тесты пишутся самими программистами, причем до написания кода, который нужно протестировать. При таком подходе каждый модуль или функция будут покрыты тестами на 100%.
  • Рефакторинг - это переписывание кода с целью усовершенствования. XP подразумевает, что однажды написанный код в процессе работы над проектом почти наверняка будет неоднократно переделан. У этого приёма есть границы адекватности. Как пишет Джошуа Блох в книге "Java. Эффективное программирование", нужно писать качественный и хороший код, но при этом не нужно гнаться за максимальной эффективность. С определённого момента повышение эффективности и надёжности кода требует неоправданно больших усилий разработчиков. Зачастую дешевле купить ещё одну "голову" в вашу вычислительную сеть. Головой называется физический сервер внутри вычислительной сети.
  • Простой дизайн - XP исходит из того, что в процессе работы условия задачи могут неоднократно измениться, а значит, разрабатываемый продукт не следует проектировать заблаговременно целиком и полностью. Проектирование должно выполняться небольшими этапами, с учётом постоянно изменяющихся требований. В каждый момент времени следует пытаться использовать наиболее простой дизайн, который подходит для решения текущей задачи, и менять его по мере того, как условия задачи меняются. Из этого подхода в последствии выросла самостоятельная методология MVP(Minimum Viable Product - минимальный жизнеспособный продукт). Согласно ей, первые версии продукта нужно делать как можно менее объёмными по функционалу, чтобы как можно быстрее предоставить пользователю возможность использовать приложение. Последующие направления развития определяются активностью пользователей.
  • Парное программирование предполагает, что весь код создается парами программистов, работающих за одним компьютером. Один из них работает непосредственно с текстом программы, второй наблюдает за работой первого и следит за общей картиной происходящего.

Второй контур охватывает непосредственную работу программиста в малой группе.

  • Метафора системы - это представление о компонентах системы и их взаимосвязях между собой. Разработчикам необходимо проводить анализ архитектуры программного обеспечения для того, чтобы понять, в каком месте системы находятся самые узкие места, что нужно доработать в первую очередь и как.
  • Непрерывная интеграция - в XP интеграция кода всей системы выполняется несколько раз в день, после того, как разработчики убедились в том, что все тесты модулей корректно срабатывают.
  • Коллективное владение кодом - означает, что каждый член команды несёт ответственность за весь исходный код. Таким образом, каждый вправе вносить изменения в любой участок программы. Парное программирование поддерживает эту практику: работая в разных парах, все программисты знакомятся со всеми частями кода системы. Важное преимущество коллективного владения кодом в том, что оно ускоряет процесс разработки, поскольку при появлении ошибки её может устранить любой программист.
  • Стандарт кодирования - в рамках XP необходимо добиться того, чтобы было сложно понять, кто является автором того или иного участка кода, - вся команда работает как один человек. Команда должна сформировать набор правил, а затем каждый член команды должен следовать этим правилам в процессе кодирования. Перечень правил не должен быть исчерпывающим или слишком объёмным. Задача состоит в том, чтобы сформулировать общие указания, благодаря которым код станет понятным для каждого из членов команды. Самая полезная практика в этом приёме - это создание документации к коду сразу же после того, как он одобрен остальными разработчиками.
  • Устойчивый темп обеспечивается социальными гарантиями и отсутствием переработок

Третий контур - это контур планирования

  • Вся команда - XP утверждает, что заказчик должен быть всё время на связи и доступен для вопросов
  • Игра в планирование - позволяет быстро составить приблизительный план работы и постоянно обновлять его по мере того, как условия задачи становятся всё более чёткими. Очень хорошо с этим справляется Scrum-подход. Подробнее о нём можно прочитать здесь.
  • Частые небольшие релизы - версии (releases) продукта должны поступать в эксплуатацию как можно чаще. Работа над каждой версией должна занимать как можно меньше времени. При этом каждая версия должна быть достаточно осмысленной с точки зрения полезности для бизнеса.
  • Пользовательское тестирование - это тоже одно из основания MVP, идея в том, чтобы как можно раньше дать конечному пользователю протестировать ваш продукт.

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

Общий вид цикла гибкой разработки:

xp

CI/CD

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

Общая идея в том, чтобы писать маленькие программы, выполняющие небольшие задачи, которые общаются друг с другом через единую мастер-программу. Эту программу называют Black Board, на русский переводится чёрная доска. Здесь подразумевается меловая доска, к которой можно прикрепить разные бумажки, фотографии, соединить их связями, что-то нарисовать. Каждую задачу могут решать параллельно несколько экземпляров программы.

Чтобы работать с такими программами была разработана специальная технология контейнеризации. Самое распространённое средство контейнеризации - это Docker. Каждый контейнер строится на основе того или иного образа. Работа с контейнерами уже выделилась в отдельную специальность DevOps. Почитать о ней можно здесь.

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

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

Работая с kubernetes, мы можем в автоматическом режиме добавлять, удалять и заменять контейнеры того или иного образа. Это бывает очень полезно в непрерывной поставке, Continuous Deploy(CD). С помощью кубернетса можно легко заменить часть старых контейнеров, выполняющих определённую задачу, на новые. После этого можно сравнить, как работают обе версии и решить, переходить на новую или нет.

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

Подробнее о CI/CD можно почитать здесь.