itmo_conspects

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

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

На этом курсе будут детально разбираться ключевые инструменты и практики, которые являются стандартом де-факто в индустрии:

Интегрированная среда разработки и дебаггер

Интегрированная среда разработки

Интегрированная среда разработки (IDE, Integrated Development Environment) - это инструмент, который объединяет в едином интерфейсе все инструменты, необходимые для разработки ПО

На ранних этапах развития компьютерных технологий почти весь код писался на перфокартах, которые считывались компьютером. Далее после создания ОС Unix в 1970-ых появились базовые текстовые редакторы, такие как vi и emacs, а сборка происходила в командной строке

Далее в 80-ых догадались, что к текстовому редактору можно прикрутить кнопку сборки, чтобы все делалось в одном окошке - так появилась среда разработки для Turbo Pascal

Сейчас же современные IDE и редакторы кода, такие как Visual Studio Code, Neovim и среды от JetBrains обладают широким функционалом написания и редактирования кода:

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

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


Сейчас популярными решениями являются:

Выбор среды разработки в первую очередь должен исходить из личного удобства

Дебаггер

Отладчик или дебаггер (от debug, устранять баги) - инструмент, предназначенный для анализа выполнения разрабатываемой программы и поиска ошибок в ней

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

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

Для разных языков существуют разные дебаггеры, например, для проектов на C и C++, скомпилированных с помощью GCC, существует gdb (GNU DeBugger). Предварительно сборка проектов осуществляется в дебаг-режиме, что отключает оптимизации компилятора и добавляет отладочную информацию в готовый исполняемый файл. В release-режиме код оптимизируется, что затрудняет отладку

Рассмотрим встроенный дебаггер pdb для языка Python на таком примере:

import pdb

def complicated_function(a, b):
    c = a + b

    d = c**a

    pdb.set_trace()
    return d

print(complicated_function(4.5, 2))

Здесь pdb.set_trace() - точка останова. Среды разработки предлагают визуально отметить точку останова красной точкой рядом с номером строки

При запуске python -m pdb code.py появляется командная строка дебаггера:


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

Система версионного контроля

В процессе разработки любого проекта часто возникает необходимость фиксировать изменения, экспериментировать с новыми идеями, параллельно работать над разными задачами и объединять результаты труда нескольких специалистов. Системы контроля версий (VCS, Version Control System) решают эти задачи, предоставляя структурированный и автоматизированный подход к управлению изменениями

При работе с проектом одному VCS может не пригодиться, но при работе в команде система позволяет откатить какие-либо изменения какого-либо разработчика. Сейчас самой распространенной является Git, разработанная Линусом Торвальдсом в 2005 году для разработки Linux

До этого существовала локальная система Subversion, и она работала так:

1) Система загружает файл в базу данных 2) При изменениях файла в базу данных заносятся конкретные его изменения (так называемая дельта или дифф)

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

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

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

Сейчас существуют 3 популярные хостинга, поддерживающие Git:

Git можно скачать с официального сайта https://git-scm.com/

У Git есть командный интерфейс. Перед тем, как начать работать с Git, нужно создать git-репозиторий в рабочей директории командой:

git init

После этого можно совершать коммиты. Коммит (от commit - совершать, фиксировать) – информация о фиксации репозитория

Коммит содержит информацию об авторе коммита, дате, измененных файлах и т. д. Перед созданием коммита нужно добавить измененные файлы в локальный индекс Git командой:

git add script.py

Также можно добавить файлы, которые совпадают с паттерном: git add *.py. Или добавить все текущие файлы: git add -A или git add .. Таким образом, файлы в системе могут иметь три состояния:

Командой git status можно посмотреть измененные и добавленные в Git файлы

После этого можно сделать коммит командой git commit -m "added hello.py"

Параметр -m “added hello.py” обозначает сообщение коммита. Сообщение должно быть у каждого коммита для того, чтобы другие разработчики понимали вкратце, какие изменения внесены этим коммитом

При первой встрече Git может пожаловаться на то, что у вас нет учетной записи – система не позволяет делать анонимные коммиты, поэтому надо внести данные о себе:

git config --global user.email "почта@example.com"
git config --global user.name "Имя"

Также параметр --add в команде git commit --add позволяет автоматически закоммитить подготовленные файлы, которые были добавлены ранее с помощью git add

Все данные в Git хранятся в виде 4 объектов:

Коммит в git

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

git checkout хеш_коммита

Особый тег HEAD указывает на текущий, выбранный командой checkout, коммит. Команда git log позволяет посмотреть всю историю коммитов, а git log хеш_коммита1..хеш_коммита2 - ее отрезок в указанных пределах. С помощью git show хеш_коммита можно посмотреть информацию о коммите

Помимо тегов существуют и другие указатели на коммиты - ветви. Ветви (branch) позволяют создавать параллельные изменения в проекте. По умолчанию все коммиты происходят в ветви main (или master). В отличии от тегов ветви - двигающиеся указатели

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

Создать ветку можно с помощью команды git branch dev. Чтобы перейти на эту ветку, можно воспользоваться командой git checkout dev. В этой ветке мы можем делать коммиты, которые не затронут основную ветвь main. Чтобы удалить ветку, можно воспользоваться командой git branch -d dev

Ветви в git

Самое интересное, что можно делать слияние веток (или мердж, от merge). Когда все изменения зафиксированы в экспериментальной ветке, ее коммиты можно слить в главную или любую другую:

git checkout main
git merge dev

Если найдутся файлы, у которые на одинаковых строчках разное содержимое, Git предложит вручную решить конфликт. Для решения конфликтов слияния, Git помещает в файлы метки такого типа:

<<<<<<< HEAD
Текст из текущей ветки
=======
Текст из сливаемой ветки
>>>>>>> branch-name

Удаление этих меток и сохранению нужного содержания даст понять системе Git, какую версию оставить в финальном коммите. Помимо ручного изменения можно принять изменения конкретной ветки для всего файла:

# Принять версию текущей ветки (то есть HEAD)
git checkout --ours file.txt

# Принять версию сливаемой ветки
git checkout --theirs file.txt

или использовать специальные утилиты для слияния, такие как vimdiff или прямо в среде разработке. Потом измененные файлы нужно добавить с помощью git add и закоммитить с помощью git commit. Слияние тоже представляет из себя коммит

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

Всего различают 2 вида слияния:

Также, если нужно актуализировать стороннюю ветку неконфликтующими изменениями из другой, применяют команду git rebase название_ветки в сторонней, которая копирует коммиты из другой в стороннюю

Перемещение коммитов

Если нужно копировать отдельный коммит из одной ветки в другую (то есть совершить черри-пикинг), можно применить git cherry-pick хеш_коммита1 хеш_коммита2, которая копирует изменения из указанного коммита и создаёт новый коммит в текущей ветке

Черри-пикинг


Если репозиторий находится на удаленном сервере (например, на GitHub), то его можно склонировать на локальный компьютер:

git clone https://github.com/pelmesh619/itmo_conspects.git

После этого совершенные коммиты можно отправить на сервер при помощи команды git push или git push origin, если к репозиторию есть доступ на платформе. Здесь origin - это адрес удаленного сервера, origin обозначает адрес, из которого репозиторий был склонирован

Внутри Git создаются отдельные ветви с префиксом origin/ (например, origin/main или origin/dev), которые показывают, где находятся ветви на сервере при последнем обновлении

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

Хостинги обычно предусматривают возможно сделать форк репозитория (от fork - вилка). Контрибутор может сделать форк репозитория другого пользователя, внести нужные изменения, а затем сделать пулл реквест (pull request в GitHub или merge request в GitLab - запрос на слияние). Далее владелец репозитория рассматривает изменения (делает ревью кода) и выносит вердикт - сливать ветвь или нет. Таким образом, происходит вклад других пользователей в open-source проекты

Методология разработки

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

Каскадная модель

Каскадная модель, также известная как модель “Водопад” (Waterfall model), была описана в статье Уинстона Уокера Ройса в 1970 году. Она представляла собой прямой “поток” из следующих этапов:

  1. Определение требований

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

  2. Проектирование

    На основе требований архитекторы и разработчики создают технический дизайн системы: выбираются технологии, проектируется архитектура, схемы баз данных и интерфейсы. Результат - набор проектных документов.

  3. Конструирование

    Непосредственно написание кода программистами строго в соответствии с документацией, созданной на этапе проектирования

  4. Тестирование и отладка

    Готовый продукт передается тестировщикам, которые проверяют его на соответствие требованиям, ищут ошибки и дефекты

  5. Инсталляция

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

  6. Поддержка

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

Количество этапов и их содержание может строго не соблюдаться.

Ключевой принцип “водопад” - этапы идут строго последовательно

Из плюсов “водопада”:

Из недостатков:

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

Agile

Agile представляет собой принципы “гибкой” разработки. Эти принципы были описаны в манифесте Agile в 2001 году. В нем были сформулированы главные ценности:

  1. Люди и взаимодействие важнее процессов и инструментов
  2. Работающий продукт важнее исчерпывающей документации
  3. Сотрудничество с заказчиком важнее согласования условий контракта
  4. Готовность к изменениям важнее следования первоначальному плану

Waterfall против Agile

На основе принципов Agile появились конкретные фреймворки для разработки ПО

Scrum

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

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

В конце спринта, который длится несколько (от 1 до 4) недель, команда встречается на совещании результатов спринта с заказчиком - так называемый ревью спринта. Небольшая длительность спринта позволяет снизить риски сделать что-то не так и сделать продукт, более подходящий заказчику

В подходе Scrum существует Scrum-мастер - человек, который проводит митинги и следит за соблюдением принципов Scrum

Ключевые понятия Scrum:

Scrum подходит для проектов с нечеткими или часто меняющимися требованиями, где важна быстрая обратная связь от пользователя (стартапы, веб-приложения, мобильная разработка)

Канбан

Канбан (от японского “рекламный щит”) является другой Agile-методологией. В канбане процесс разработки должен быть наглядным и прозрачным для разработчиков. Канбан жестко ограничивает количество задач, находящихся в работе. Это достигается тем, что задачи расположены на ограниченной канбан-доске, тем самым отсутствует многозадачность у работников

В канбане нет жестких ролей и фиксированных спринтов, в отличии от Scrum. Задачи поступают в работу по мере освобождения ресурсов. Более гибкий и постепенный подход к изменениям

Канбан подходит для осуществления поддержки и доработки существующих продуктов, проектов с постоянным и непредсказуемым потоком задач


Чаще всего применяются гибридные модели разработки. Например в крупных игровых компаниях существует такая модель:

  1. Идеация: брейншторминг новых идей и механик для проекта, составление прототипов
  2. Препродакшен: составление документа геймдизайна, прототипирование механик
  3. Продакшен: разработка, плейтесты
  4. Постпродакшен: фикс багов, подготовка к релизу

Однако на этапах препродакшена и продакшена действует итеративная модель: разрабатывается прототип, проводятся их плейтесты, собирается обратная связь, игровые механики изменяются на основе обратной связи

Документация и базы знаний

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

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


В IT-индустрии знания могут быть разбиты на 4 уровня:

  1. Данные - сырые объективные данные и факты без явного контекста, такие как записи журналов запросов или поток битов
  2. Информация - данные, обработанные и структурированные для понимания контекста, например, отчет об ошибках, график нагрузки на сеть
  3. Знания - понимание закономерностей, принципов и причинно-следственных связей на основе информации

    Знания представляет собой ответы на вопросы “как?” и “почему?”, то есть механизм использования, например, “в 21:00 начинается рекламная пауза, жители включают электрические чайники, из-за чего вырастает потребление электроэнергии, поэтому нужно быстро ввести резервные источники энергии

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

    Мудрость - ответ на вопрос “Что делать в будущем?”, то есть условия использования, например, для приложений, ориентированных на большую аудиторию, целесообразнее выбрать микросервисную архитектуру для простоты масштабируемости

Вместе эти 4 уровня образуют пирамиду DIKW (Data, Information, Knowledge, Wisdom)

В контексте информационных технологий знания - это:


Где же могут храниться знания?

  1. Непосредственно код и тесты

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

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

  2. Системы версионного контроля

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

    Хостинги, такие как GitHub и GitLab, имеют функцию отправки вопросов и проблем (issue) и пулл реквестов для данного репозитория, которые содержат обсуждения проблем и контекст принятия решений

  3. Внутренние вики-системы

    Википедия имеет движок с открытым исходным кодом, поэтому любой желающий может создать свою Википедию

    Помимо этого, существуют современные системы управления знаниями, такие как Notion, Confluence (от Atlassian) или встроенная Wiki в GitHub/GitLab

    Вики-системы содержат вступительные материалы для новичков (как настроить окружение и так далее), архитектурные решения (ADR, Architecture Decision Records), описания бизнес-процессов, инструкции по эксплуатации и глоссарии (термины проекта)

  4. Системы документирования кода

    Для популярных языков существуют фреймворки, например, javadoc для Java, которые превращают комментарии в коде в готовые веб-страницы документаций

    Пример документации в Java

    Для небольших проектов папки docs с файлами на языке Markdown достаточно. Если что-то пришлось объяснять дважды, то самое время это задокументировать

  5. Базы инцидентов

    Инциденты также должны быть задокументированы для их предотвращения. Для такого используются OpsGenie и другие системы


Для работы со знаниями следует помнить следующие принципы:

  1. “Документация как код” (Docs as Code)

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

  2. Единый источник истины - знания должны храниться в одном месте

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

  4. Знания должны быть актуальными

  5. Культура обмена знаниями

    Знания должны активно распространяться, а не просто храниться. Это включает: регулярные техдоки (tech talks), парное программирование, код-ревью как обучение, внутренние блоги и “обеды с обучением” (lunch & learn)


В компаниях для управления знаниями существуют отведенные роли:

  1. Технический писатель (Technical Writer)

    Пишет документацию для пользователей, редактирует технические тексты, создаёт туториалы

  2. Технический амбассадор (Developer Advocate)

    Делится знаниями внутри компании, готовит материалы для конференций и помогает с введением в курс дела новых сотрудников

  3. Менеджер знаний (Knowledge Manager)

    Отвечает за систему управления знаниями, следит за актуальностью, обучает сотрудников работать с базой знаний

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

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

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

Тестирование нужно по разным причинам: проще и дешевле проверить во время разработки, что что-то не работает, нежели выслушивать недовольство заказчика и терпеть репутационные риски

Тестирование осуществляется разным методами и на разных этапах. Глобально всякую кодовую базу (хорошо написанную) можно разделить на функциональные модули. Далее тесты можно разделить на уровни проверки этих модулей:

Эти уровни образуют “пирамиду тестов”. Ближе к вершине количество тестов становится меньше, но сами они становятся дороже и дольше:

Пирамида тестов

Помимо уровней тестирования, существуют различные виды тестирования, сфокусированные на конкретных аспектах качества:


Главное помнить:

Непрерывное интеграция и непрерывная доставка

CI/CD (Continuous Integration и Continuous Delivery/Deployment) включает две основные практики, которые позволяют автоматизировать процесс разработки, тестирования и развертывания ПО. Целью CI/CD является достижение быстрого, безопасного и предсказуемого выпуска обновлений

До CI/CD традиционный подход был таковым: разработка завершается внедрение нового функционала, ручное тестирование находит баги, которые к вечеру пятницы исправляются, чтобы потом в субботу опять сломаться

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

Непрерывная интеграция

Непрерывная интеграция (Continuous Integration, CI) - практика, которая заключается в постоянном слиянии рабочих веток в общую основную ветвь разработки и выполнении автоматизированных сборок проекта

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

Непрерывная интеграция работает так: очередной git push origin приводит к автоматическому запуску процесса

  1. Сборка проекта
  2. Запуск модульных тестов
  3. Статический анализ кода (то есть линтеры)
  4. Сборка контейнера
  5. Запуск интеграционных тестов

Непрерывная интеграция позволяет обнаружить баги заранее и избежать конфликтов при слиянии долго разрабатывающихся веток

Непрерывная доставка и развертывание

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

Непрерывная доставка может выглядеть так: после успешной непрерывной интеграции происходят

  1. Сборка артефакта (это может быть exe-файл, архив или образ Docker)
  2. Развертывание на тестовом окружении (так называемом staging)
  3. Автоматические E2E-тесты на тестовом окружении
  4. Готовность к развертыванию в рабочей производственной среде

Непрерывное развертывание (Continuous Deployment, CD) - все то же самое, но изменения автоматически развертываются в продакшн для пользователей. То есть:

  1. Непрерывная интеграция прошла успешно
  2. Сборка артефакта
  3. Развертывание на тестовом окружении
  4. E2E-тесты на тестовом окружении
  5. Автоматическое развертывание в продакшн-среде
  6. Мониторинг развернутой версии

Для непрерывных интеграции и развертывания существует открытая платформа Jenkins. Для Kubernetes существуют платформы ArgoCD, FLux и Tekton

GitHub и GitLab предоставляют свои инструментарии для непрерывных интеграции и развертывания проектов. Так, например, GitHub Actions позволяет запускать этапы CI/CD в конфиг-файле на языке YAML для исполнения на серверах GitHub или ваших машинах

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

# .github/workflows/deploy.yml
name: CI/CD Pipeline

# Определяем, в каких случаях CI/CD запускается автоматически
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  # Сборка и тестирование
  build-and-test:
    runs-on: ubuntu-latest  # ОС для запуска
    
    steps:
    # Получение кода из репозитория
    - name: Checkout code
      uses: actions/checkout@v4
    
    # Установка Node.js
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '18'
        cache: 'npm'
    
    # Установка зависимостей
    - name: Install dependencies
      run: npm ci
    
    # Запуск линтера
    - name: Run linter
      run: npm run lint || echo "No lint script found, skipping"
    
    # Запуск тестов
    - name: Run tests
      run: npm test -- --passWithNoTests
    
    # Сборка проекта
    - name: Build project
      run: npm run build
      env:
        CI: false
    
    # Сохранение собранного проекта как артефакт
    - name: Upload build artifact
      uses: actions/upload-artifact@v4
      with:
        name: build-output
        path: ./dist  # Папка с собранным проектом


  # Развертывание
  deploy:
    needs: build-and-test  # Выполняется после сборки
    runs-on: ubuntu-latest
    
    # Запускается только при пуше в основную ветку
    if: github.ref == 'refs/heads/main'
    
    steps:
    # Скачиваем артефакт сборки
    - name: Download build artifact
      uses: actions/download-artifact@v4
      with:
        name: build-output
    
    # Развертываем на GitHub Pages
    - name: Deploy to GitHub Pages
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: $
        publish_dir: ./

Здесь две работы: сборка-тестирование и развертывание

Полный CI/CD цикл для коммерческих проектов может включать 8+ этапов:

Круг CI/CD

Также существует несколько стратегий развертывания:

Лицензия ПО

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

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

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

Важно различать:

Лицензия ПО регулирует в первую очередь авторские права, но современные лицензии (Apache 2.0, GPLv3) также затрагивают патентные аспекты


Различают 3 типа программного обеспечения: проприетарное ПО, открытое ПО и свободное ПО

Проприетарное ПО

Проприетарное ПО имеет закрытый исходный код, поставляется в виде исполняемых бинарных файлов, обычно платное и имеет строгие ограничения на использование

Такое ПО имеет собственные лицензионные соглашения (или EULA, End User License Agreement), которые задают правила обычно “только для использования”, а изучение кода, модификация, распространение запрещены

Примером проприетарного ПО служат операционные системы Windows и macOS, продукты компании Adobe и другие

Лицензия для проприетарного ПО может выглядеть так:

УСЛОВИЯ ЛИЦЕНЗИИ НА ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ MICROSOFT
ОПЕРАЦИОННАЯ СИСТЕМА WINDOWS
ЕСЛИ ВЫ ПРОЖИВАЕТЕ В США (ИЛИ ЕСЛИ ЭТА СТРАНА ЯВЛЯЕТСЯ ВАШИМ ОСНОВНЫМ МЕСТОМ ВЕДЕНИЯ БИЗНЕСА), ОЗНАКОМЬТЕСЬ С ПОЛОЖЕНИЯМИ ОБ ОБЯЗАТЕЛЬНОМ АРБИТРАЖЕ И ОТКАЗЕ ОТ ГРУППОВОГО ИСКА В РАЗДЕЛЕ 11. ЭТО ВЛИЯЕТ НА СПОСОБ РАЗРЕШЕНИЯ СПОРОВ.
Благодарим за выбор Microsoft!
В зависимости от того, как вы получили программное обеспечение Windows, настоящий документ является лицензионным соглашением между: (i) вами и изготовителем устройства или установщиком программного обеспечения, который распространяет программное обеспечение вместе с вашим устройством; (ii) вами и корпорацией Microsoft (или одним из ее аффилированных лиц — в зависимости от места вашего проживания либо основного места ведения бизнеса), если вы приобрели программное обеспечение у розничного продавца. Корпорация Microsoft является изготовителем устройств, произведенных Microsoft или одним из ее аффилированных лиц, а также розничным продавцом, если программное обеспечение приобретается непосредственно у Microsoft. Если вы являетесь клиентом программы корпоративного лицензирования, использование данного программного обеспечения регулируется условиями вашего корпоративного лицензионного соглашения.

Открытое ПО

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

Зачастую открытое ПО использует готовые шаблоны лицензий:

Свободное ПО

Для борьбы с патентными троллями в далеких 1980-годах Ричард Столлман основал Фонд свободного программного обеспечения и проект GNU, целью которого было создание с нуля Unix-подобной системы без использования проприетарного кода

Тогда Столлман формулирует 4 свободы ПО:

Свобода запускать программу в любых целях (свобода 0).
Свобода изучения работы программы и адаптация её к вашим нуждам (свобода 1). Доступ к исходным текстам является необходимым условием.
Свобода распространять копии, так что вы можете помочь вашему товарищу (свобода 2).
Свобода улучшать программу и публиковать ваши улучшения, так что всё общество выиграет от этого (свобода 3). Доступ к исходным текстам является необходимым условием.

И понятие “копилефт” (copyleft): если код был лицензирован под копилефтной лицензией, то производные от него продукты должны быть лицензированы под той же или совместимой с ней лицензией

Сейчас распространены две версии свободных лицензий:

Помимо General Public License существуют:

Другие лицензии

Для материалов, не представляющих программный код, популярны лицензии Creative Commons

Далее к этой базовой лицензии добавляются условия:

Какую же выбрать лицензию?

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

Для того, чтобы выбрать лицензию, могут помочь сайт https://choosealicense.com/ или подобная схема:

Как выбрать лицензию

Для простых учебных проектов подойдет MIT License или GNU GPLv3. Для корпоративных проектов отлично подходит Apache License 2.0 или GNU GPLv3. Если важно сохранить открытость исходников, то GPLv3 или Affero GPL

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

Также некоторые лицензии могут содержать несовместимые условия. Так проект с MIT/BSD/Apache лицензией может включать компонент с MIT/BSD/Apache лицензией. Но нельзя:

Совместимость лицензий можно проверить с помощью утилит pip-licenses или scancode