Как можно определить понятие жизни программы? Жизнь программы можно описать повторяющейся последовательностью конечных процессов в компьютере выполненных в контексте выбранной предметной области. Обязательно конечных, в каком-то разумном временном отрезке.
design
Когда появляется программа? Скорее всего, программа появляется в голове у проектировщика/разработчика, можно назвать это design-time. Но так как этот момент не поддаётся контролю компьютера (пока), то предположим, что моментом появления программы является момент создания минимального запускаемого (о подробном смысле этого термина стоит поговорить отдельно) исходного кода.
В контексте модульных языков или языков с ООП — программа рождается, когда появляется минимальный модуль/класс. Дальнейшее рассмотрение будем проводить для модульных систем, так как в немодульных/скриптовых системах те или иные этапы обычно редуцированы/слеплены в единый этап.
Можно обоснованно выделить design-time в отдельную категорию, но не как процесс в голове разработчика, а чисто утилитарно, опираясь на процесс кодирования. Здесь можно описать автокомплит, автоподсветку (как уже реализованные программы), программирование макросов ide, генерацию схем БД и ДРАКОН-схем, и так далее.
compile
Затем, после этапа написания некоторого программного кода, программа передается компилятору. Компилятор обеспечивает т.н. compile-time — время компиляции. В результате выполнения процесса компиляции мы получаем компилят (то есть непосредственный результат обработки нашего исходного кода).
Во время компиляции наш исходный код влияет на работу компилятора по определенным законам, которые выражены в коде компилятора.
В то же самое время, никто не мешает уже на этапе компиляции управлять действиями компилятора (точнее, исполнителя в целом) не опосредованно, через написание текста нашей программы, а непосредственно, через написание кода общего назначения, который будет выполнен компилятором.
То есть такого кода, который хоть и относится к задуманной программе, но не переводится компилятором в компилят непосредственно. Так называемый CTFE, но в более общем смысле. Понятно, что нахождение в контексте процесса работы компилятора может накладывать некоторые ограничения на код времени компиляции, однако может и не накладывать.
Здесь мы можем заметить, что выполнение любого процесса жизненного цикла предполагает наличие результата, в явном или неявном виде.
load
После получения компилята, над ним, сразу или отложенно должен быть исполнен процесс связывания или линковки. Так как компилят обычно хранится в файле, то возникает время загрузки — load-time.
В это время над компилятом могут быть произведены дополнительные преобразования в код целевой платформы, и в это время может быть выполнен код времени загрузки, например, обработка компилята оптимизирующим компилятором.
На данный момент известна только одна технология, WebAssembly (slim-binaries), поздняя кодогенерация на целевой платформе, которая хоть как-то описывает время загрузки.
link
Обычно, линковка необходима, так как компилятор всегда производит компилят для одного модуля для непосредственного исполнения на целевой машине. Однако в реальной модульной системе на машине одновременно будут исполнены несколько модулей.
Эта ситуация в многомодульной системе приводит к необходимости связывания. В старых системах связывание могло производиться непосредственно после компиляции, но этот вырожденный случай мы не рассматриваем. Итак, возникает время связывания, или link-time.
Мало что известно про выполнение кода во время связывания, однако понятно, что в момент связывания возможно выполнение кода, например, Dependency Injection и динамического наследования/проксирования, как это может быть реализовано в рамках работы внутри jvm.
Такой контроль над еще не запущенным в действие, но уже готовым к исполнению кодом программы позволяет реализовывать автоматизированную настройку и так далее. После связывания и настройки код непосредственно готов к запуску.
init, run, close
Запуск и дальнейшая работа. Наиболее известные широкой публике этапы. Представлены временем инициализации (init-time) и временем исполнения (run-time). В сущности, результат работы этого этапа жизненного цикла и является обычно непосредственной целью написания программы.
Можно дополнительно выделить время завершения работы программы (close-time). Однако сейчас все три времени работы обычно принято называть run-time, а логическое деление на три этапа реализовывать уже в рамках клиентского программного кода.
Такой подход снижает требования к среде исполнения (run-time environment) но не дает гарантий исполнения того или иного этапа в нужной последовательности из-за возможных ошибок исполнения (run-time error) после которых исполнение, обычно, должно завершиться аварийно.
death
Отдельным важным временем жизни программы является посмертное время (death-time), в которое, вопреки распространенным представлениям тоже является частью жизненного цикла программы. Объяснение тут простое, так как целью работы программы обычно является некий результат, обычно зависящий от входных данных, которых может быть очень много, программы строятся с применением методов, позволяющих итеративно обрабатывать входные данные и производить выходные данные, которые могут быть поданы на вход следующей итерации.
Обычно такие данные структурированы (БД), версионны (результат взаимодействия со сторонним API) и их содержимое и интерпретация зависит от реализации работающей программы. То есть, программа это алгоритмы и данные, в том числе внешние и степень связанности этих внешних данных с программой никак не влияет на сам факт наличия такой связанности на любом этапе жизненного цикла.
Проще говоря, программа запущенная вновь будет работать по разному, в зависимости от результата, который был ею же получен на прошлом этапе жизненного цикла. И если внести в эти данные изменения во время, которое программа не запущена, программа тоже будет работать иначе, то есть, внося изменения в данные мы программируем программу работать иначе. Что есть этап жизненного цикла программы.
Итоги
Итак, рассмотрены этапы жизни программы: design-time -> compile-time -> load-time -> link-time -> init-time -> run-time -> close-time -> death-time. Как можно заметить, все этапы присутствует в цикле разработки и использования любой программы, а значит в любой из этих этапов может быть выполнен пользовательский код, который позволит получить результат, наиболее соответствующий целям разработчика. На сегодняшний день нет такого языка, фреймворка или экосистемы, в котором данные этапы были бы реализованы во всей полноте. Науке, бизнесу и сообществу есть куда стремиться.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Комментарии (10)
Sirion
30.10.2016 14:52+1Пользовательский код в голове у разработчика?
Заголовок спойлера
По-моему, я только что прочёл эталонную хрень.napa3um
30.10.2016 15:38-1> На сегодняшний день нет такого языка, фреймворка или экосистемы, в котором данные этапы были бы реализованы во всей полноте. Науке, бизнесу и сообществу есть куда стремиться.
https://ru.m.wikipedia.org/wiki/UML
S_A
30.10.2016 16:53Нравится подход.
Беда в том, что контексты меняются. Написал например на windows, собрал на mac, запустил и закрыл на iOS, получил push-уведомление…
third112
30.10.2016 20:10+1Когда появляется программа? Скорее всего, программа появляется в голове у проектировщика/разработчика, можно назвать это design-time. Но так как этот момент не поддаётся контролю компьютера (пока), то предположим, что моментом появления программы является момент создания минимального запускаемого (о подробном смысле этого термина стоит поговорить отдельно) исходного кода.
Не понял, что значит не «поддаётся контролю компьютера»? О каком контроле речь? О размере какого-то рабочего файла? Нет ли тут ошибки обобщения, когда пусть из частых, но частных случаев, пытаются сделать общий вывод? Нпр., работа над программой компилятора с языка Х может начаться с описания этого языка на BNF, а может с поиска подходящего языка в Инете (есть задача, для которой нужен спец. язык с определенными свойствами). Далее по BNF может быть сделано задание для Yacc, а может написание кода на универсальном ЯП в полном объеме, а может в минимальном + компилятор Х, написанный на Х, с последующей раскруткой по Вирту и др. Но до этого может быть длительный этап обсуждений, сравнений измерений и т.д. А в другой задаче может быть нужен хитрый алгоритм. И снова поиск, а если не удалось найти, то разработка алгоритма. В результате алгоритм м.б. записан на псевдокоде, а далее последуют работы по мат. доказательству корректности этого алгоритма и его теоретическим оценкам. И.т.д. ИМХО у ПО разного типа бывает разное рождение.xuexi
31.10.2016 11:16Речь о более общем контроле, на данном историческом этапе компьютер не может задизайнить (разработать, создать, довести до необходимого состояния, короче) программу по ТЗ самолично, без участия программиста.
Поэтому возможности «исполнителя» (компьютера) на первом этапе ограничены возможностями IDE, которую можно дополнить пользовательским кодом в виде плагинов. Как раз этот код подлежит исполнению в design-time.
Например, сгенерированный по WSDL-описанию java-класс будет слегка бесчеловечным, что определит дальнейшую работу с этим классом, а значит, повлияет на программу в целом.
lookid
30.10.2016 23:04> На сегодняшний день нет такого языка, фреймворка или экосистемы, в котором данные этапы были бы реализованы во всей полноте. Науке, бизнесу и сообществу есть куда стремиться.
Автор какой-то сферический демагог в вакууме. Как это нету? А всё, что окружает вас? Вообще всё? Любая программа, которая не крашится и не засирает систему, не оставляет после себя следов. Которая просто работает и выполняет свою задачу. Как это нету-то?DarkEld3r
31.10.2016 01:00+1Автор хочет выполнять произвольный код во время (например) линковки. Как к этому относятся программы, которые "не крашатся и не засирают систему"?
Нужно ли это — другой вопрос.
Akon32
31.10.2016 15:26рассмотрены этапы жизни программы: design-time -> compile-time -> load-time -> link-time -> init-time -> run-time -> close-time -> death-time
Какая-то каша из разработки ПО и выполнения программы. Программа ведь не один раз запускается, а по схеме — один.
Если брать жизненный цикл ПО, его этапы примерно такие: 1) сбор требований; 2) проектирование, реализация, отладка; 3) внедрение; 4) поддержка; 5) замещение другой системой. Этапы могут пересекаться.
У "жизненного цикла" программы (процесса?) этапы уже 1) инициализация; 2) выполнение; 3) финализация.
Для чего это смешивать?
xuexi
31.10.2016 18:00Нет, это именно жизнь программы, исполняемой компьютером, смартфоном, браузером, исполнителем, короче. Жизненный цикл у неё состоит из повторения последовательности этапов, которые я описал.
Возможно, вас смутило созвучие с «жизненным циклом ПО». Надо было явно обозначить «цикл».
ryzkot
До трёх таймов я бы сократил. design,compile,run