Русский   English  
ДонНТУ   Портал магістрів

Реферат за темою випускної роботи

Зміст

Вступ

Перш за все відзначимо, що передача досвіду важлива в будь-якій сфері виробництва, включаючи програмування. Незважаючи на те, що західноєвропейські дослідники кажуть: немає срібної кулі [1], розумно припустити, що програмування може і повинно бути автоматизовано.

Як же відбувається передача досвіду програмістів: бібліотек багаторазових програмних модулів, шаблонів класів і т. створюються. Але це все одна сторона медалі. Чи є інші способи зробити це. Звичайно, є.

Програміст сидить за робочим столом і пише код. Незалежно від того, чи використовує він готові бібліотеки або готові рішення, він все одно пише код. Можливо, це заняття приносить йому естетичне задоволення. Але це займає багато часу. Актуальним є питання скорочення часу, що витрачається на створення програми. Так що програмні проекти перестають зривати терміни здачі.

Незважаючи на очевидну ефективність впровадження нових технологій програмування, як і раніше, необхідно слідувати принципам, які були доведені до програмної інженерії протягом десятиліть. Низька якість програмного продукту обумовлена недотриманням цих принципів [2]. Наприклад, спроба перелічити всі типи геометричних фігур в одному модулі призводить до необхідності змінювати цей модуль кожен раз, коли з'являється завдання з конкретними, раніше невідомими фігурами [3]. Дійсно, неможливо знати все, і програміст, створює таку бібліотеку, повинен передбачити можливість реалізації шляхом додавання нового функціоналу, а не модифікації існуючого модуля.

Якісне оформлення програми передбачає можливість її використання при розробці інших програм. В іншому випадку ніякої передачі досвіду не відбудеться. І програма залишиться вузькоспеціалізованою іграшкою в руках її творця. Гранично допустима концентрація окису вуглецю в атмосфері може зрости на порядок з-за помилки програми, допущеної в результаті спроби адаптувати існуючу програму до нової задачі.

Метою даної роботи є розробка нового способу автоматизації процесу програмування, заснованого на використанні твердих принципів і технології синтезу програмного коду з використанням онтологій.

У даній статті планується вирішити наступні завдання;

  1. пошук існуючих способів автоматизації програмування;
  2. розробка методу синтезу діаграм класів;
  3. оцінка отриманих модулів об'єкта.

Наукова новизна полягає саме у використанні твердих принципів для автоматичного синтезу діаграм класів.

1. Обґрунтування практичної застосовності результатів дослідження

Розробляється система синтезу шаблонів проектування. Але є і готові викрійки. Чому б не використовувати їх. Дійсно, готові рішення орієнтовані на існуючі проекти, але для нових проектів це не ідеальне рішення.

Підготовчим етапом є збір інформації про рішення типових задач проектування архітектури програмного забезпечення. Архітектура-це те, що незмінно протягом усього життєвого циклу проекту. Незмінними є мова програмування і діаграма класів. Використання шаблонів проектування спрощує створення первинної архітектури програми.

По правді кажучи, ці патерни далеко не так застосовні, як описано. Якщо архітектура автоматизованого проектування архітектури програми сліпо копіює їх в схему класів, то схема буде дуже складною. Розуміння у фахівця немає. Шаблони повинні бути винайдені для кожного завдання. Фундаменти - це ті стійкі структури, які були сформовані в результаті багаторічного досвіду архітекторів програмного забезпечення.

Що відрізняє ці конструкції від класів від звичайних схем, хаотично зібраних з основних елементів, так це застосування принципів твердого тіла. Шаблон, в якому ці принципи не дотримуються, називається антипатерном, наприклад Active Record [4].

Бажано уникати використання антипаттернов. Тоді забезпечується оптимальна розширюваність системи і запобігає ефект снігової кулі, коли планується внести корективи в один модуль, і програма буде переписана [2].

Генерація UML-діаграм [5] в поєднанні з використанням CASE-інструментів, що дозволяють переводити діаграми класів в код [5], значно спрощує процес створення об'єктно-орієнтованої програми.

2. Огляд існуючих рішень

Отже, в чому різниця між командним інтерфейсом і віконним інтерфейсом [6]. Командний інтерфейс Працює з командною мовою. Прикладом такого типу інтерфейсу є текстовий редактор vim. У ньому за допомогою команд виконуються операції переміщення по рядках, вставки, видалення рядків, файлові операції.

Однак більшість текстових редакторів мають віконний інтерфейс. У цих програмах текст вводиться з клавіатури, а операції з файлами і повнотекстовий пошук супроводжуються показом форм користувачеві.

Для кожного завдання є відповідний вибір типу інтерфейсу. Це не означає, що інтерфейс форм краще, ніж інтерфейс команд, або навпаки.

Якщо мова програмування є графічним, то користувальницький інтерфейс компілятора буде графічним. Це справедливо для перекладача графічної нотації UML в об'єктно-орієнтований код мови опису текстового класу [5]. Тепер уявіть, що компілятор тексту програми має інтерфейс форми. При кожній компіляції з'являється вікно із завданням параметрів оптимізації, вибором набору інструкцій і т. д. Звичайно, в цьому випадку командний інтерфейс зручний, так як всі ці параметри можна вказати в аргументах виклику програми компілятора і записати отриману командний рядок в файл автоматизації збірки.

Що стосується багаторівневої бази знань. Що таке вкладеність-це деталі. Деталізація-це процес додавання деталей в проект програмного забезпечення. І деталі програмного проекту мають свої особливості на кожному рівні деталізації.

Вкладеність модулів знань стосовно системи автоматизованого проектування програмного забезпечення проявляється при розгляді рівнів деталізації програмного проекту: рівня архітектури та рівня програмного коду. На рівні архітектури описані API-інтерфейси. Це оголошення функцій в термінах мови Сі. На рівні коду описуються високорівневі і низькорівневі алгоритми. Це визначення функцій в термінах мови Сі.

Рівень програмного коду, в свою чергу, має підрівні: високорівневі і низькорівневі алгоритми; опис алгоритму в псевдокоде і на конкретній мові програмування. Істотною відмінністю мови високого рівня від мови алгоритмів низького рівня є те, що вони описують процедуру вирішення конкретної задачі за допомогою дій, зрозумілих людині. А підпрограми нижчого рівня переводять ці дії на мову, зрозумілу операційній системі.

Висхідні підпрограми завжди викликають спадні підпрограми. Коли виникає необхідність перейти від однієї реалізації алгоритму нижчого рівня до іншої, на допомогу приходить механізм поліморфізму. Поліморфний клас описує підпрограму для створення шару нейронної мережі.

2.1 Сутність об'єктно-орієнтованого програмування

Інтерпретація понять об'єктно-орієнтованого програмування. Дійсно, програмування можливо тільки за допомогою мови. Таким чином, існування ООП нерозривно пов'язане з мовами програмування, які його підтримують. Розробник мови C++ визначає ООП як розробку модульної парадигми програмування, що дозволяє виявляти відмінності між модулями шляхом успадкування [3]. Принцип приховування даних, або так звана інкапсуляція, спочатку був присутній в парадигмі модульного програмування, в таких мовах, як Modula-2. Спочатку поліморфізм був абстракцією даних, яка стала частиною ООП.

Існує думка, що перехід до використання ООП стався передчасно [7]. Але це не так, адже вивчення ООП пов'язане з його використанням, оскільки воно є методом програмування.

Хоча, можна використовувати ООП в мовах, які не мають ООП парадигми [8]. В такому випадку поліморфний метод класу замінюється покажчиком на підпрограму. Тоді в одному випадку цей покажчик вказує на процедуру створення шару з окремих нейронів, а в іншому — на операцію запису матриці в пам'ять процесора. У будь-якому випадку, сигнатури цих функцій повинні бути однаковими. Якщо одна реалізація для CPU, а інша для GPU, то програма зможе вибрати потрібну реалізацію в залежності від наявності GPU в системі використовуючи відповідні алгоритми.

2.1.1 Чи може программа сама себе запрограмувати?

Найбільш суперечливе і злегка філософське питання: чи здатна машина до самопрограмування [9]. Рішення прикладних задач на ПК здійснюється за допомогою програмного забезпечення, яке розробляють люди. Іншими словами, людина постачає машину програмами, які він сам створює за допомогою машини. Однак навіщо людині обтяжувати себе виконанням цієї трудомісткої операції, якщо частина роботи можна було б перенести на машину.

Отже, існує два види робіт зі створення програмного забезпечення: автоматизовані [10] та неавтоматизовані. Перша група включає в себе:

В результаті людина навчила машину виконувати ряд автоматизованих операцій зі створення програмного забезпечення. Однак більша частина роботи припадає на його творчість. Перерахуємо заходи другої групи:

У чому причина неавтоматизації другої групи процесів. Як бачите, з цих двох списків можна скласти таблицю:

| ==== | Людська робота | Діяльність машини | алгоритм кодування | компіляція | документація | генерація документації | перевірка | статичний аналіз коду | реінжиніринг | зворотний інжиніринг | побудова діаграм | генерація коду діаграми | Автоматизація збірки | збірка програм | установка програми | доставка програми | написання тестів | виконання тестів | ====

Виходить, що людина кодує, а машина компілює. А чому не навпаки? Припустимо, що стовпці перевернуті. Тепер машина придумує алгоритми, і людина повинна привести їх в дію. Поки машина диктує інструкції своєю мовою, людина повинна виконувати ці дії. Рано чи пізно людині набридає виконувати однотипні операції, і у нього з'являється бажання скоротити, змінити порядок дій. А машина продовжує диктувати інструкції. Виникає питання: навіщо вони йому потрібні, адже людина без машини здатна сама вирішувати, які дії виконувати. А машині, навпаки, потрібна така інструкція. Ця властивість називається силою волі, якою машина не володіє. Машина виконує тільки ті дії, які потрібні людині, і тільки тоді, коли вона змушена їх виконувати.

Чому машина не може сама себе проінструктувати? Людські вчинки диктуються здоровим глуздом і потребами. Машина не має ніяких потреб, так як вона була створена людиною для вирішення його проблем. Невідомо, що було б, якби машина потребувала їжі ... Хоча, дійсно, машина споживає електрику, і навіть здатна висловити свою потребу в ньому, коли його не вистачає. Однак така поведінка запрограмована людиною і усвідомленням необхідності вижити,а те, що для цього потрібна електрика, у автомобіля відсутня. Тоді, можливо, машина не інструктує себе просто тому, що їй потрібна електрика для виконання будь-якої дії. І оскільки їй потрібна ця електрика, щоб функціонувати, вона не хоче витрачати його даремно. Правильно, навіщо щось робити, якщо ця дорога операція не приносить користі. У чому користь дії для автомобіля? Так, в оптимізації системи, наприклад. І сенс оптимізації полягає в скороченні втрат ресурсів ПК. І зменшіть відхід для зменшення матеріальних цін і для прискорення вирішення прикладних проблем. А це, в свою чергу, необхідно тільки людині, так як ПК все одно, скільки електрики він їсть і скільки відеокарт йому вистачає, людина все одно забезпечує його всім. В результаті виходить, що тільки людині потрібні всі дії машини, а машині вони не потрібні. Ось чому машина не самопрограмується: їй не потрібні ніякі дії. Але людині це потрібно, йому всього мало, йому потрібно більше. Він створив ракету, двигун, комп'ютер, обмотав світ волоконно-оптичним кабелем і сидить, радіє. І комп'ютер покірно виконує його вказівки.

2.2 Методи автоматизації кодування алгоритмів

Якщо поміняти місцями стовпці не можна, то залишається намагатися змістити центр ваги на користь автоматизації кодування алгоритмів. Так, алгоритми потрібні людині, а не машині. Тому тільки людина приймає рішення про створення алгоритму. А для того, щоб передати його машині потрібен спільну мову, який буде зрозумілий і людині, і комп'ютера. Отже завдання людини — записати алгоритм на такій мові, а комп'ютер буде цей алгоритм виконувати. Для того і потрібні мови програмування, і від них не можна позбутися з тієї причини, що вони забезпечують комунікативний зв'язок людини з комп'ютером. Приходимо до розуміння того, що зрушення центру ваги на користь автоматизації проводиться шляхом полегшення процесу кодування алгоритмів [16]. При цьому мова змінюється, але повинна залишатися повною і зберігати однозначність. Повнота мови означає можливість його засобами пояснювати хід вирішення будь-якої існуючої задачі. Чогось принципово нового можна придумати в даній області, що полегшило б процес кодування.

В окремих випадках, графічний мову програмування, напр. Scratch [17] (ця ж мова покладена в основу авторського проекту з візуального програмування на Java [18]), здатний полегшити кодування алгоритмів при навчанні програмування. Кодування алгоритмів проводиться шляхом перетягування заготовок готових блоків коду у вікні редагування. Є ще кілька візуальних мов програмування: ДРАКОН.

Мова ДРАКОНа заснований на парадигмі двовимірного структурного програмування [19]. Це означає, що алгоритми описуються у вигляді креслення, а не тексту. Двомірність полягає в тому, що структурні блоки алгоритму розташовані на площині креслення так, що зір проектувальника переміщується як горизонтально так і вертикально при читанні алгоритму. Приблизно те ж саме відбувається в разі написання багатопотокових програм: проектувальнику доводиться часто переміщатися між декількома паралельними потоками робіт. В Дракона для опису багатопоточності використовуються блоки розпаралелювання і синхронізації, як на діаграмах діяльності UML. Складовими частинами ДРАКОН-схеми (т. зв. ікони) є елементи блок-схем і деякі додаткові блоки.

До цих пір немає великого проекту, який повністю написаний на візуальному мовою програмування [20]. Обов'язково зустрінеться честь коду іншою мовою. Основні причини низької популярності візуальних мов програмування:

Хоча, останні дві причини не мають відношення до Дракона. Дійсно, ця мова має зв'язок з іншими текстовими мовами. Текстовий синтаксис запозиченої мови дозволяє використовувати бібліотеки, написані на ньому. Існують різні варіації Драконів, кожна з яких відрізняється синтаксисом текстової частини. І що стосується третього зауваження, то воно не дійсно щодо ДРАКОНа, оскільки не всі реалізації цієї мови мають комерційну ліцензію. Тоді що ж обумовлює низьку популярність цієї мови? Можливо, його вузька спрямованість. Незважаючи на те, що блок-схеми здатні описати будь-який алгоритм, в той час, як текстові мови передбачають кінцеве число ключових слів, ДРАКОН оперує кінцевим числом графічних нотацій замість цих слів. Різні комбінації цих ікон покликані забезпечити можливість опис будь-якої алгоритмічної конструкції. Ось мова Асемблера, з команд якого складається будь-яка програма. Є така команда, як пауза, вона забезпечує затримку в циклі активного очікування.

Неможливість розширення можливостей шляхом створення нових структурних елементів є причина вузької спеціалізації мови ДРАКОНа.

Ще одна причина в тому, що є послідовні алгоритми, які легше описувати одномірними структурами. Блок-схема такого алгоритму має вигляд ланцюжка прямокутників, на кінцях якої два термінальних елементи: назва і кінець. І таких алгоритмів багато, особливо в системному програмуванні. Використання графічної нотації в даному випадку недоцільно, оскільки веде до надмірної надмірності дій, пов'язаних із створенням і розміщенням нових блоків. Цього, звичайно можна уникнути, спростивши процедуру створення і розміщення блоку, але читаність алгоритму буде страждати через великі відстані між операторами, і як наслідок алгоритм може зайняти не одну сторінку своєю блок-схемою.

Є ще причина, яка обумовлена самою парадигмою двовимірного структурного програмування. Вона проявляється, коли в коді необхідно виправити програмну помилку. У чому легше знайти помилку, в тексті або в картинці? Якщо в тексті, то людина переглядає його рядок за рядком і його увагу рівномірно поширюється на кожен оператор. А у випадку з кресленням з блок-схем очі розбігаються в різні боки і увага нерівномірно розсіюється на різні оператори алгоритму. Однак, все вірно, можна переглядати алгоритм послідовно, не пропускаючи ні одного оператора. Невелика ймовірність пропустити оператор, коли переглядаєш блок-схему. У цьому перевага візуального програмування: можливість обійти всі переходи і оператори при тестуванні по метолу білої скриньки.

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

Якщо переклад блок-схеми в код призводить до втрати очевидності, то це ознака недбалого програмування [19]. При перекладі в код виникло повторення умови в блоці розгалуження і циклу. Ось як я зазвичай роблю, щоб уникнути цього:

WHILE  (кінець послідовності циклу) DO
  IF (поточний стан задовольняє умові пошуку) THEN
    RETURN (стан знайдено)
  END
END
RETURN (стан не знайдено)

Лістинг 1 — Приклад алгоритму пошуку елемента в списку

Як бачите, ніякого повторення немає. Це був приклад того, що порівняння блок схем і коду залежить від того, як автор висловив алгоритм в коді. Таким чином, недоліки, що присвоюються традиційному структурному програмуванню, не мають об'єктивного характеру.

Погляньте на блок схему і на код. Що більше? Так, звичайно, блок-схеми забезпечують наочність алгоритму. Але, коли мова йде про великі проекти, для опису алгоритмів використовується код, т. к. він займає менше місця на екрані, що дозволяє зберігати великі обсяги програмного коду в репозиторіях (напр. GIT).

Та й це ще одна причина, чому блок-схеми не використовуються для програмування великих проектів. Адже команда розробників цього проекту пише окремі ділянки коду, і настає час, коли всі розробки необхідно з'єднати разом. У цьому випадку дві версії програмного коду порівнюються і знаходяться відмінності, а потім вибирається один з варіантів кожного рядка. Справа в тому, що код впорядкований і йде зверху вниз, а блок схеми спрямовані в усі сторони, що ускладнює їх автоматичне порівняння та злиття декількох версій одного алгоритму стає обтяжливою завданням для програміста.

До питання про те, для чого потрібні класи. ООП — просто хороший спосіб згрупувати підпрограми, що мають щось спільне. Звідси випливає, що ООП корисно лише при розробці великих програм з безліччю функцій.

Відповідність класів предметам навколишнього світу використовується тільки для навчання програмуванню, оскільки розробляти великі проекти поодинці неефективно. Насправді, модель матеріального світу не має до ООП ніякого відношення. Програма оперує інформацією [21] а не фізичними об'єктами.

У назвах патернів ООП всі слова вжиті в переносному сенсі. Напр. фасад — це не те, що Ви звикли бачити, проїжджаючи по головній вулиці міста. В ООП це слово проводить аналогію з фасадом будівлі, як додатковий шар між користувачем і бібліотекою, який покликаний спростити її використання.

Нехай класи не успадковують предмети матеріального світу, але самі підпрограми, з яких вони складаються, мають щось спільне з системами. Кожна підпрограма має набір входів і виходів, а також внутрішні змінні. У системному аналізі [22] для позначення таких систем використовується матриця виду:

(1)

У першій чверті знаходяться коефіцієнти змінних стану. Це матриця передавальної функції.

Вихід системи обчислюється за формулою (2).

(2)

Змінна стану обчислюється за формулою (3).

(3)

Спочатку обчислюється вихід системи, а потім оновлюється змінна стану. Таким чином, стан зберігається після виклику функції.

Все, що складно, не повторюється двічі. Складні системы складаються з простих. Прості системи елементарні. Системоутворюючими елементами кожної програми є дії і змінні. Процес обробки інформації складається з послідовності дій, збудованих в певному порядку. Порядок дій відіграє важливу роль, зміна його може порушити логіку обробки інформації,особливо коли мова йде про багатопоточності. У багатопотокових програмах враховується час, що витрачається на виконання кожного елементарного дії. Розглянемо приклад реалізації такої алгоритмічної структури, ка бар'єр, схематично зображуваної так:

Схема бар'єру багатопоточності

Рисунок 1 — Схема багатопотокової програми з двома бар'єрами (анімація з 20-и кадрів об'ємом 15 Кб)

Процедура входу в бар'єр повинна повертати позитивний результат тільки для того потоку, який вийшов останнім з нього. перевірка значення, що повертається, дозволяє визначити, що бар'єр більше не зайнятий і готовий до повторної ітерації.

Мовою асемблера код буде такий:

  MOV AX, threads 	; записати в акумулятор загальне число потоків
  LOCK INC wait 	; збільшити лічильник очікують потоків
  LOCK CMPXCHG wait, 0 	; порівняти лічильник з акумулятором
  JNE idle		; перейти вниз в разі нерівності
  MOV AX, 1		; повернути значення TRUE
  RET
idle:
  CMP wait, 0 		; порівняти лічильник очікують потоків з нулем
  JNZ idle 		; чекати поки лічильник обнулиться іншим потоком
  Xor AX,AX 		; повернути значення FALSE
  RET

Лістинг 2 — Алгоритм бар'єру багатопоточності

Дивний той факт, що ця, здавалося б, настільки елегантна реалізація бар'єру містить одну невелику проблему, вирішення якої призводить до ланцюгової реакції: появи нових внаслідок рішення предудыщих.

Для реалізації бар'єру використовуються дві загальні змінні: кількість потоків (threads) і кількість очікують потоків (wait). Логічно, що потік повинен чекати, поки кількість очікують потоків не стане дорівнює кількості всіх потоків. Для перевірки даної умови використовується команда порівняння з обміном [23], яка за одну атомарну операцію порівнює перший операнд (кількість очікуючих потоків) з акумулятором (загальна кількість потоків) і записує в цей операнд значення константи.

Здавалося б, що такого, якщо поміняти перші два рядки. Запис в акумулятор загальної кількості потоків потрібно тільки для CAS в третьому рядку. Якщо поміняти рядки, то буде так:

  LOCK INC wait 	; прийшов новий потік, якого чекали
  MOV AX, threads 	; і записав собі відоме число
  LOCK CMPXCHG wait, 0 	; порівняв свій номер з цим числом
  JNE idle 		; якщо він прийшов останнім, стрибка не буде
  MOV AX, 1 		; а буде вихід з позитивною відповіддю
  RET
idle:
  CMP wait, 0 		; інакше буде чекати поки прийде останній
  JNZ idle 		; в циклі активного очікування
  XOR AX, AX		; а дочекавшись вийде з негативною відповіддю
  RET

Лістинг 3 — Алгоритм бар'єру з переставленими рядками

Відомо, що доступ до пам'яті довше ніж до регістрів. Тому така перестановка робить хорошу паузу між INC і CAS. Виходить негарна ситуація, коли кілька потоків спочатку збільшили лічильник очікують потоків, а потім перший з'ясував, що потоків максимальна кількість і вийшов з бар'єру, обнуливши лічильник чекають потоків, а другий потік слідом за ним порівняв цей нуль з к-ом потоків і залишився чекати1 першого, щоб він його збільшив. А перший вже давно його збільшив і вийшов. Це призводить до таких симптомів:

  1. процесор перегрівається;
  2. потоки плутають наступний бар'єр з попереднім;
  3. програма не завершується.

Це підтвердження того, що несуттєве для послідовного програмування зміна порядку дій може порушити роботу многопоточной програми. Очевидно, що елементарними частинами програм є дії. А тепер повернемося до системного аналізу. Підпрограми — це Системи зі зворотним зв'язком і матриця такої системи описує її передавальну функцію. Так, і тепер з'являються два різновиди функцій. У чистих функцій, не мають побічних ефектів, коефіцієнти нижнього ряду (1) дорівнюють нулю.

2.3 Автоматизація налагодження програм

Є помилки, які викликані багатопотоковістю, але ви також можете виділити:

Відомо, що основними критеріями якості програмного забезпечення є правильність його роботи і відсутність в'язкості програмного коду. Останнє необхідне для оперативного внесення змін до логіки обробки інформації з метою забезпечення відповідності новим вимогам.

Традиційним підходом до встановлення коректності програми є модульне тестування. Однак при великій кількості рядків коду варіантів тестового випадку може бути багато, і написання модульних тестів для такої програми важко. Для таких випадків вони придумали fuzzing [24], коли програма сама генерує свідомо неправильні набори тестів і звіти, які призвели до збою. Для такої процедури досить описати структуру вхідних даних і встановити критерії коректної роботи програми.

Оскільки програмне забезпечення було написано в різний час, використовувалися різні парадигми і підходи до організації програмного коду. Нові концепції ламають сформовані стереотипи про алгоритми кодування. Наприклад, функціональна парадигма [25] внесла істотні зміни в код, перетворивши його з опису процедур опис функцій. Функціональний підхід змінив тактику написання коду від декомпозиції до деталізації. Функціональний підхід замінив цикли викликом підпрограми.

Результатом впровадження шаблону проектування в мову програмування є JavaScript. Прототип ООП, закладений в його основу, виключає необхідність реалізації прототипного шаблону. Smalltalk [26] - це єдина мова програмування, який повністю усуває необхідність в генеративних шаблони проектування. Замість реалізації абстрактної фабрики він надає можливість створювати об'єкт з класу об'єктів.

Технології COM/DCOM [27] надають можливість створювати об'єкт і викликати його методи, використовуючи рядковий подання їх імен. В інших совах ім'я викликається процедури задається під час виконання.

Більшість особливостей притаманне мові Ruby [28]. Цей послідовник Smalltalk успадкував від нього принцип все є об'єкт. Клас - це об'єкт, який створює об'єкти свого класу [29]. Крім того, ця мова поєднує в собі строкову ідентифікацію COM-класів і об'єктно-орієнтований підхід Smalltalk.

Самоаналіз в ООП-це здатність викликати метод класу, знаючи тільки його ім'я. Ви можете створювати об'єкти, знаючи його ім'я. Конструктор служить виключно для ініціалізації об'єкта.

2.4 Автоматизовані інтегровані середовища розробки

Отже, ми з'ясували, що мова драконів не здатна зрушити центр ваги на користь автоматизації алгоритмів кодування. Чи є інші способи зробити це. Там немає жодного. Існує така технологія, як IntelliSence, що додає ім'я функції по перших буквах. Ця технологія приписується Microsoft, однак ця функція реалізована в інших IDE, є також окрема програма ctags, яка індексує імена функцій і інші ідентифікатори. Отже, це завершення коду змінило зусилля програміста?

Як працює ця технологія. Вводимо перші літери назви функції, програма показує випадаючий список з назвами функцій, які починаються з заданих символів. Знаходимо потрібну функцію в цьому списку і вибираємо.

Можливий випадок поєднання візуального програмування і завершення коду. У тому ж драконі інтер'єри геометричних фігур заповнені кодом. Цей код містить імена функцій, які можуть і повинні бути заповнені для автоматичного додавання.

Автоматизація алгоритмів кодування досягається за рахунок вдосконалення мов програмування [30]. Кожне оновлення мови враховує особливості програмного забезпечення, що розробляється на момент його випуску. Нова мова призначена для спрощення тих розділів існуючого програмного коду, які занадто заплутані через відсутність виразних мовних засобів. Наприклад, є так звані. сигнал. А для того, щоб після завершення програми було виконано певну дію, необхідно було створити підпрограму і передати адреса цієї підпрограми реєстратор сигналів. Тоді назва цієї процедури ніде не використовувалося. З появою стандарту 2011 року в мову були додані анонімні функції, що значно спростило реєстрацію обробника сигналів.

Однак дехто [31] не згоден з цим положенням. Навпаки, вони вважають, що впровадження нових мов програмування в практику не прискорює процес розробки. А для цього пропонується змінити конструкцію систем автоматизації і організувати конвеєрну збірку програм. Повторне використання коду розглядається як основний спосіб автоматизації програмування.

Є обмежений ресурс для поліпшення виразних засобів, або що буде далі з мовами програмування. Гр. Буч сказав, що мови програмування будуть розвиватися в напрямку шаблонів проектування. Як уявити собі мову програмування з вбудованими шаблонами? Занадто лінива написання шаблонів вручну призводить до того, що компілятор буде вбудовувати їх в програму. Геть ручні каракулі.

Подальше вдосконалення мови C++ не виконує мрії Гр. Буча, так як його стандартизатори дотримуються зворотної сумісності з існуючими програмами, написаними на ньому. Для цих цілей необхідна принципово нова шаблонно-орієнтована мова програмування. Ця парадигма означає: запишіть, які макроклассы потрібні, і що в них системно важливо, і з'явиться програма з необхідними структурами. Зрештою, клас-це структура даних. Структура даних-це складний тип даних, тобто складається з декількох простих або складних типів. Простими типами є двійкові числа, масиви символів і покажчики функцій. Клас в звичайному розумінні мови C++ являє собою набір типів даних (як компоненти структури) і таблицю віртуальних функцій. Методи класу-це просто функції, які мають ім'я, що складається з імені класу та імені методу, розділених двома крапкою. Вхідні дані функції перераховані в списку параметрів. Першим параметром методу функції є покажчик на структуру даних в пам'яті, що містить вказівник на таблицю віртуальних функцій, містить покажчик на цю функцію. Немає нічого особливого в ООП-звичайному структурному програмуванні.

2.5 Автоматизація збірки програм

Чому система сама не генерує правила складання? Задаємо їй питання:

А потім система повинна цей файл запам'ятати і при повторному запиті видавати його.

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

Насправді така система вже є і називається CMake. Вона генерує Makefile з опису проекту, який містить:

Для того, випадку, коли система не знає алгоритму складання файлу, можна написати модуль з визначенням правил складання і використовувати його при описі проектів, що містять файли даного формату.

Давайте детально розберемо процес автоматизації складання проектів. Проект складається з текстових файлів і його необхідно перевести в бінарний формат для того, щоб виконувати на комп'ютері користувача.

Для автоматизації збірки застосовуються імперативний і декларативний підхід.

Таблиця 1 — Види засобів автоматизації збірки
Мова проекту Тип автоматизації
Імперативний Декларативний
С, С++, Pascal Make Automake, CMake
Java Ant Maven, Gradle

Приклад імперативного підходу: файли збірки для системи Make складаються з:

Для великих проектів такий підхід автоматизації збірки стає занадто виснажливим, тому світове співтовариство придумало ряд засобів, що автоматизують створення файлів з правилами складання: Autoconf/Automake, CMake [13].

Файл опису проекту для CMake носить назву CMakeLists.txt і містить:

У підсумку виходить трохи більше даних вміщається в опис проекту, але це позбавляє від необхідності введення команд виклику компілятора в файл збірки. База даних CMake містить всю необхідну інформацію про компіляторах, які використовуються для кожного типу вихідних файлів.

Аналогічне відповідність склалося в системах збірки для Java. Ant переслідує імперативний підхід опису алгоритму збірки, а Maven і Gradle — декларативну.

У системі збірки Maven опис проекту міститься в XML файлах. Gradle позбавляє від необхідності використання цього надлишкового формату, пропонуючи описувати проект на мові Groovy. Опис проекту для цих систем збірки містить:

Відмінною особливістю Maven і Gradle є те, що вони автоматично завантажують і підключають всі залежно проекту. Крім того, список вихідних файлів для складання формується автоматично, оскільки їх розташування задано стандартом.

Система складання проектів автоматизує не тільки компіляцію програми, але і її установку. Так, наприклад для Ruby бібліотеки поставляються у вигляді архівів, які автоматично розпаковуються в теку з бібліотеками. Для створення таких архівів використовується система Rake. Скрипт автоматизації збірки rakefile включає:

Для мови Perl існує кілька аналогічних підходів до автоматизації створення архівів з бібліотекою, але всі вони зводяться до того, що на комп'ютері користувача генерується Makefile з опису проекту, яке включає такі поля.

У сфері виробництва ПЗ Автоматизація йде великими темпами, ніж в інших сферах. Пояснюється це тим, що для автоматизації програмування не потрібно залучати фахівців з інших областей. Самі розробники бажають спростити собі життя, і придумують різні інструменти для задоволення своїх потреб. На відміну, від напр. САПР літаків, там залучаються авіаконструктор, який висуває своє бачення майбутньої програми. Для САПР ПЗ сам виконавець є замовником і узгодженість вимог істотно прискорює розробку подібних інструментів.

Відмінність середовища розробників ПЗ від наукового середовища в тому, що створюється неконтрольовано велика кількість програмних продуктів. Спочатку нові засоби апробуються в ненаукових колах, а потім з'являються статті в наукових журналах, де результати цих апробацій, грубо кажучи, перекопируются.

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

Давайте автоматизуємо програмування. І тут з'ясовується, що воно отже вже гранично автоматизовано. Варто тільки почати виконувати однотипні операції, і з'являються кошти, які їх виконують самі.

Об'єктно-орієнтоване програмування нічим не відрізняється від процедурного. Якщо поглянути на вихідний код поштового клієнта sulpheed написаного на процедурній мові Сі, який підтримує кілька протоколів: POP3, IMAP, NNTP. Як він працює? Для кожного протоколу реалізовано набір операцій: отримання списку листів, читання листів.

Net Framework з'явився результатом автоматизації технології COM/DCOM. Якщо до цього потрібно було вручну забивати UUID у визначення компонента, то зараз C# це робить всередині сам. Є можливість прикрутити компоненти COM до додатка на мові C#. На цей випадок є спеціальний інтерфейс COM. Таким чином, C# є не що інше, як спрощений процес створення COM компонентів в байт коді.

Повернемося до Sulpheed. Отже, в цьому поштовому клієнті при додаванні облікового запису вказується тип протоколу отримання пошти. Кожен протокол визначає різні алгоритми читання листів. При цьому листи в Sulpheed для кожного протоколу відображаються однаково. Як це зроблено: розробник створив таблицю покажчиків для кожної процедури роботи з поштовою скринькою; потім для кожного протоколу реалізував набір операцій і записав їх покажчики в таблицю. Т. ч. поліморфізм був реалізований засобами процедурного мови. Якби програма була написана на C++, то цю роботу виконував би компілятор. Ось що я називаю автоматизацією програмування. Однак, чому був обраний саме мова Сі? Напевно, з міркувань продуктивності.

Для протоколу POP3 відмінною рисою є те, ято читання листів пов'язане зі збереженням їх на комп'ютері користувача. Для IMAP листи зберігаються на поштовому сервері, і надається повний доступ для їх читання. NNTP — це новинний протокол, і листи розсилаються по широкомовним каналах, читання яких надається без аутентифікації.

Що ще є в автоматизації програмування, так це снипплеты. Той же vim є повноцінне середовище розробки або САПР по тільки за рахунок плагінів, які до нього підключаються. Є певні команди, які користувач вводить і отримує готовий фрагмент коду, який можна заповнити потрібними даними.

Однак велика кількість команд запам'ятати неможливо, тому популярністю користуються також середовища розробки з графічним інтерфейсом. IntelliJ IDEA і цілий ряд подібних йому середовищ розробки для різних мов програмування від компанії JatBrains, витісняють всіх його попередників на ринку IDE. І вже витіснило всі IDE для мови Java. На те є вагомі причини, чому розробники Java воліють IDEA замість аналогічних Eclipse і NetBeans. По-перше, середовище зручніше і користуватися нею значно ефективніше. По друге, в ній автоматизували рутинні операції з рефакторингу коду.

CLion [32] — це єдине середовище розробки для мов C/C++, яка вперше автоматизувала роботу з проектами, які використовують CMake в якості засобу складання. Це середовище розробки використовує файли CMakeLists.txt для опису проектів, що дозволяє повністю автоматизувати рутинні операції додавання нових файлів вихідного коду в проект. При додаванні файлу вихідного коду CLion автоматично оновлює CMakeLists.txt, додаючи в його список новий файл. А при оновленні цього текстового файлу автоматично запускається генерація Makefile для всього проекту.

Крім того, починаючи з третьої версії CMake може сам автоматизувати внесення нових файлів вихідного коду в список за допомогою команди

Оскільки основна рутинна робота програміста у створенні однотипних операцій, які послідовно виконуються незалежно від специфіки задачі, CLion дозволяє згенерувати стандартну реалізацію конструктора, методів доступу до полів, а решта класу — на розсуд користувача.

Коли потрібно виправити написання слова, яке пишеться з двома літерами с, то неважливо, де додати букву с до чи після вже наявної букви с. Так само в програмуванні, неважливо що автоматизувати, створення інтерфейсу методу або його реалізацію. Є засоби, які генерують реалізацію по інтерфейсу методу.

В C++ явно не вистачає інтроспекції. Це добре відчули розробники системи об'єктно-реляційного відображення ODB [33]. При використанні цього засобу програміст описує структуру бази даних за допомогою директив препроцесора. Система ODB використовує цю інформацію, щоб згенерувати процедури запису позначених з їх допомогою структур в реляційні таблиці.

Недоліком генераторів програмного коду є старіння стандарту, на якому генерується код. ODB генерував код у стандарті 2014 року. Деякі можливості цієї мови оголошені втомленими в 2017 році. І тепер те, що генерується системою ODB, не придатне для использвоания з новим компілятором мови C++ . Хто візьметься оновити генератор коду, якщо кожен третій рік виходить новий стандарт.

Інший спосіб автоматичної реалізації методу полягає в безпосередній генерації нового коду при компіляції. Метапрограмування на шаблонхх дозволяє будувати алгоритми для компілятора. Однак мовою C++ явно бракує інтроспекції. Вирішує дану проблему Java зі своїми анотаціями. Бібліотека Hibernate дозволяє генерувати SQL запити знаючи тільки назва процедури і її аргументи. Використовуючи анотації позначаються поля структури, що використовується для автоматичного управління базою даних.

Писати генератор коду для таких мов як Ruby не має сенсу, оскільки в ньому реалізований механізм рефлексії. У компільованих мовах такого механізму немає. Тому генератор коду доцільно створювати для них.

За однією класифікацією Perl та, слідом за ним, Ruby визнані надвисокорівневими мовами. Тобто на них можна написати метапрограму. Цілком очевидно, що синтезирвоать код надвисокорівневої мови не потрібно.

Template Toolkit [34] є засіб для генерації файлів, в т. ч. і perl-скриптів за шаблоном. Саме там є вкладеність, що дозволяє говорити про реалізацію на ньому модулів знань інтелектуального САПР ПЗ.

Правда, російські дослідники вже задалися питанням реалізації генератора UML-діаграм [35,36]. Крім того, є ще система ПРВЗ [37], яка справила величезне враження на вчених.

Підведемо невеликий підсумок того, що зроблено для автоматизації програмування.

Таблиця 2 — Огляд існуючих досягнень в автоматизації програмування
Світ Країни СНД ДонНТУ
Автоматизація кодування Scratch, Block ДРАКОН Мовний ввід
Автоматизація тестування Фаззинг
Автоматизація збірки CMake, Gradle
Проектування UML Rational Rose Синтез діаграм за описом Пр. Обл.
Бази даних ODB, Hibernate Генератори SQL запитів
Синтез алгоритмів Lex/Yacc ПРИЗ ?

Детальніше засоби автоматизації програмування описані в пострадянських дослідженнях [38,39].

3. Сутність дослідження і наукова новизна

Повернемося до ООП і патернам проектування. Об'єктно-орієнтована структура програми повинна задовольняти принципам SOLID для забезпечення гнучкості процесу розробки. Є патерни, які задовольняють цим принципам, і антипатерни, які навпаки, суперечать їм.

Нехай система спочатку не знає жодного патерну проектування. Вона повинна їх вивести сама з принципів SOLID. Для використання ГА необхідно представити патерн в двійковому коді і вивести функцію екстремуму.

Функція екстремуму повинна показувати, наскільки система задовольняє принципам SOLID. Від вибору цієї функції залежить якість оптимізаційного процесу.

Існує багато патернів, які не відповідають вимогам принципу єдиною обов'язки. Давайте ж синтезуємо нові патерни, які будуть задовольняти всім принципам SOLID.

Нехай солідність оцінюється за п'ятибальною шкалою. Це сума п'яти характеристик, що відповідають кожному принципу. Визначимо першу характеристику

(4)

де Cm — кількість класів з кількома обов'язками; C — загальна кількість класів у системі.

Як визначити, що клас має кілька обов'язків. Для цього встановлюється кількість вимог, зміна яких призводить до його модифікації. Клас, який має єдиний обов'язок має рівно одну причину для зміни.

Я вважаю, що аналіз вимог полягає в розбитті вимог так, щоб кожній вимозі відповідав один клас. А не те, щоб викладається за курсом АВПЗ.

Трохи складніше завдання визначення відкритості-закритості системи. Під цим принципом розуміється відкритість для додавання і закритість для зміни. Додавання нових вимог призводить до створення нових класів а не зміни існуючих. Це повинно забезпечити стійкість системи до появи помилок.

Механізми рефлексії поставили на конвеєрну стрічку програмне забезпечення.

На пострадянському просторі розвиток технологій і наступна за ним автоматизація людської праці розглядається як шлях до соціалізму. Капіталістичні країни бачать в цьому підвищення прибуткового податку [40], як спосіб вирішення проблеми масового безробіття, що виникла внаслідок заміни людини на заводах, підприємствах сфери обслуговування і т. д. машинами.

Тюменцев визначає достатня умова лінійності процесу розробки [41,42], як дотримання принципів відкритості-закритості та зменшення розміру модулів.

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

Ключові принципи програмної інженерії, про які часто забувають згадувати, з'являються в пошуку шляхів оптимізації процесу розробки.

Перелік посилань

  1. Брукс Ф. Мифический человеко-месяц, или Как создаются программные системы / Ф. Брукс . — 2015. — 171 с. — URL: https://nsu.ru/xmlui/bitstream... .
  2. Мартин Р.К. Быстрая разработка программ. Принципы, примеры, практика: Пер. с англ. / Р.К. Мартин, Дж.В. Ньюкирк . — М. : Вильямс , 2004. — 725 с. — URL: http://www.williamspublishing.... .
  3. Страуструп Б. Язык программирования C++. 2-е изд [Электронный ресурс]. — URL: http://www.8361.ru/6sem/books/... .
  4. Pablo's SOLID Software Development [Электронный ресурс]. — 2008. — URL: https://lostechies.com/wp-cont... .
  5. Бочкарёва Л.В. Системы автоматизации проектирования программного обеспечения. Работа в среде Rational Rose : учебно-метод. пособие для студ. спец. Программное обеспечение информационных технологий всех форм обуч. / Л.В. Бочкарёва, М.В. Кирейцев . — Мн. : БГУИР , 2006. — 38 с.
  6. Якоб Р. Интерфейсы пользователя [Электронный ресурс]. — 2017. — URL: http://masters.donntu.ru/2017... .
  7. Ермаков И.Е. Объектно-ориентированное программирование: прояснение принципов? / И.Е. Ермаков . // Объектные системы . — № 1 (1). — 2010. — С. 130–135. — URL: https://cyberleninka.ru/articl... (дата обращения: 02.12.2019) .
  8. Крамаренко А.В. Разработка пользовательских интерфейсов на GTK+ [Электронный ресурс]. — 2011. — URL: http://masters.donntu.ru/2012... .
  9. Автоматический синтез программ – что нового? [Электронный ресурс]. // RSDN . — URL: https://www.rsdn.org/forum/phi... .
  10. Средства автоматизации проектирования программного обеспечения [Электронный ресурс]. — URL: https://poznayka.org/s86065t1.... .
  11. Система автоматизации отладки программного обеспечения [Электронный ресурс]. — URL: http://www.tehprog.ru/index.ph... .
  12. Новичков А. Rational Rose для разработчиков. Часть 2 [Электронный ресурс]. — URL: http://www.interface.ru/fset.a... .
  13. Дубров Д.В. Программирование: система построения проектов CMake. Учебник для магистратуры / Д.В. Дубров . — М. : Издательство Юрайт , 2016. — 422 с. — URL: https://aldebaran.ru/author/vl... .
  14. Clark M. Pragmatic Project Automation. How to Build, Deploy, and Monitor Java Applications / M. Clark . — The Pragmatic Bookshelf , 2004. — 172 pp. — URL: http://index-of.es/Programming... .
  15. Степанченко И.В. Методы тестирования программного обеспечения: Учебное пособие / И.В. Степанченко . — Волгоград : ВолгГТУ , 2006. — 74 с. — URL: http://window.edu.ru/resource/... .
  16. Воробьёв Л.О. К вопросу о самосинтезируемости программ / Л.О. Воробьёв, А.В. Григорьев . // Материалы VI Международной научно-технической конференции Современные информационные технологии в образовании и научных исследованиях (СИТОНИ-2019) . — Донецк : ДонНТУ , 2019. — С. 256–266.
  17. Современное визуальное программирование: Google Blockly [Электронный ресурс]. — URL: http://blogerator.org/page/sov... .
  18. Воробьёв Л.О. Разработка интегрированной CASE-системы для обучения студентов программированию / Л.О. Воробьёв, В.А. Полетаев, Д.Д. Моргайлов . // Информатика, управляющие системы, математическое и компьютерное моделирование в рамках II форума Инновационные перспективы Донбасса (ИУСМКМ-2016): VII Международная научно-техническая конференция . — Донецк : ДонНТУ , 2016. — С. 163–168. — URL: http://iuskm.donntu.ru/electr... .
  19. Ермаков И.Е. Двумерное структурное программирование / И.Е. Ермаков, Н.А. Жигуненко . // Современные информационные технологии и ИТ-образование . — № 6. — 2010. — С. 452–461. — URL: https://cyberleninka.ru/articl... (дата обращения: 21.12.2019) .
  20. Визуальное программирование–будущее написание кода [Электронный ресурс]. — URL: https://www.make-info.com/visu... .
  21. Никольский С.Н. Объекты и информационные технологии [Электронный ресурс]. // Известия ЮФУ. Технические науки . — № 2. — 2002. — URL: https://cyberleninka.ru/articl... (дата обращения: 23.12.2019) .
  22. Чернышов В.Н. Теория систем и системный анализ : учеб. пособие / В.Н. Чернышов, А.В. Чернышов . — Тамбов : Изд-во Тамб. гос. техн. ун-та , 2008. — 96 с. — URL: http://window.edu.ru/resource/... .
  23. Compare-and-swap [Электронный ресурс]. // Wikipedia . — 2019. — URL: https://en.wikipedia.org/wiki/... .
  24. Фаззинг, фаззить, фаззер: ищем уязвимости в программах, сетевых сервисах, драйверах [Электронный ресурс]. // Журнал Хакер . — 2010. — URL: https://xakep.ru/2010/07/19/52... .
  25. Что такое функциональное программирование? [Электронный ресурс]. // Stack Owerflow . — URL: https://ru.stackoverflow.com/q... .
  26. Кирютенко Ю.А. Объектно-ориентированное программирование. Язык Smalltalk / Ю.А. Кирютенко, В.А. Савельев . — М. : Вузовская книга , 2003. — 358 с. — URL: http://www.mmcs.sfedu.ru/jdown... .
  27. Роджерсон Д. Основы COM : 2-е изд / Д. Роджерсон . — М. : Русская Редакция , 2000. — 228 с. — URL: http://index-of.es/Programming... .
  28. Язык программирвоания Ruby [Электронный ресурс]. — URL: https://www.ruby-lang.org/ru/ .
  29. Воробьёв Л.О. Анализ специфики реализации объектного подхода в современных технологиях программирования / Л.О. Воробьёв, А.В. Григорьев . // Программная инженерия: методы и технологии разработки информационновычислительных систем (ПИИВС-2018): сборник научных трудов II научно-практической конференции (студенческая секция) . — Донецк : ДонНТУ , 2018. — Том 2. — С. 27–32. — URL: http://pi.conf.donntu.ru/coll... .
  30. Курочкин В.М. Автоматизация программирования [Электронный ресурс]. — URL: https://www.booksite.ru/fullte... .
  31. Степанова А.С. Конвергентная технология человеко-машинного взаимодействия, на основе программирования / А.С. Степанова . // Объектные системы . — № 3 (5). — 2011. — С. 9–14. — URL: https://cyberleninka.ru/articl... (дата обращения: 02.12.2019) .
  32. CLion [Электронный ресурс]. — мощный инструмент для мощного языка! , 2019. — URL: https://jetbrains.ru/products/... .
  33. Code Synthesis Tools. C++ Object Persistence with ODB [Электронный ресурс]. — 2015. — URL: https://www.codesynthesis.com/... .
  34. Wardley A. Генерация контента сайта с использованием Template Toolkit [Электронный ресурс]. — 2000. — URL: http://www.codenet.ru/webmast/... .
  35. Бикмуллина И.И. Автоматический синтез диаграмм классов языка UML на основе ассоциативных отношений предметной области : диссертация [Электронный ресурс]. — Казань , 2017. — URL: http://www.dslib.net/mat-obesp... .
  36. Бикмуллина И.И. Технология автоматизированного синтеза информационных систем с помощью семантических моделей предметной области / И.И. Бикмуллина . // Открытые семантические технологии проектирования интеллектуальных систем (OSTIS-2015) . — Минск : БГУИР , 2015. — С. 445–450. — URL: https://libeldoc.bsuir.by/hand... (дата обращения: 03.12.2019) .
  37. Ильин А.В. О двух направлениях в автоматизации программирования [Электронный ресурс]. — URL: http://ubs.mtas.ru/bitrix/comp... .
  38. Вичугова А. А. Автоматизация процесса разработки программного обеспечения: методы и средства / А. А. Вичугова . // Прикладная информатика . — № 3(63). — Томск : ТПУ , 2016. — Том 11. — С. 63–75. — URL: http://earchive.tpu.ru/bitstre... .
  39. Соловьев Н.А. Системы автоматизации разработки программного обеспечения / Н.А. Соловьев, Е.Н. Чернопрудова . — Литрес , 2012. — 230 с. — URL: https://pda.litres.ru/e-n-cher... .
  40. Форд М. Роботы наступают: Развитие технологий и будущее без работы [Электронный ресурс]. — М. : Альпина нон-фикшн , 2016. — URL: https://royallib.com/book/ford... .
  41. Тюменцев Е.А. О формализации процесса разработки программного обеспечения / Е.А. Тюменцев . // Математические структуры и моделирование . — № 3(43). — 2017. — С. 96–107. — URL: https://cyberleninka.ru/articl... (дата обращения: 16.12.2019) .
  42. Тюменцев Е.А. Уточнение к статье о формализации процесса разработки программного обеспечения / Е.А. Тюменцев . // МСиМ . — № 1 (45). — 2018. — С. 144–147. — URL: https://cyberleninka.ru/articl... (дата обращения: 16.12.2019) .

  1. насправді другий потік вийде, виявивши нуль в лічильнику потоків. Гонка даних відбудеться в іншому місці (див. індивідуальний розділ.)