Парадигмы программирования — парадигмы жизни
В данной статье я постараюсь поверхностно, не углубляясь в дебри, раскрыть понятие “Парадигма программирования”. Стоит отметить, что статья написана простым языком, в ней практически не рассматриваются сложные термины и специфичные для языков программирования понятия, поэтому она подойдет для прочтения как опытным программистам, так и людям, которые никогда не писали код.
Парадигма программирования
Ну что же, приступим. Скорее всего, многим данное словосочетание покажется пугающим, но, на самом же деле, здесь нет ничего сложного. Что же такое “Парадигма программирования”? Возьмем определение из википедии: “Парадигма программирования – это совокупность идей и понятий, определяющих стиль написания компьютерных программ (подход к программированию). Это способ концептуализации, определяющий организацию вычислений и структурирование работы, выполняемой компьютером”.
Если говорить самым простым языком, то парадигма программирования – это подход к написанию кода. Читатели без опыта программирования, вероятнее всего, зададутся вопросами: “А что это за такие подходы? То есть, например, ты пишешь код сначала левой рукой, потом правой? Или же ты пишешь код час, а потом полчаса отдыхаешь? Что это за подходы?!”. На самом же деле, подходы подразумевают под собой совсем другое и далеки от примеров, описанных до этого.
Чтобы понять, что это такое, давайте рассмотрим два основных подхода, то есть две основные парадигмы: Объектно-ориентированное программирование (ООП) и Функциональное программирование (ФП). ООП основано на том, что все можно представить в виде объектов, у которых могут быть какие-то характеристики (поля) и они могут выполнять какие-то действия (методы/функции). ФП же основано на описание процессов (функций), а не объектов. Понимаю, пока не понятно, поэтому давайте разберем простейший пример. Представим, что нам нужно как-то складывать и вычитать два числа (a и b). На картинке ниже представлен код, реализующий это в ООП и ФП (код был специально упрощен, чтобы сделать упор именно на разнице двух подходов). Вы сразу можете заметить функции “sum” (сложение) и “subtract” (вычитание), которые мы хотели реализовать.
— Так, ну функции я вижу, а почему в ООП есть еще “class Calculator”, что это значит?
Как уже было сказано выше, ООП основано на том, что все можно представить в виде объектов: например, есть объект “Вселенная”, она состоит из галактик (объект “Галактика”), та, в свою очередь, состоит из планет (объект “Планета”), на каждой планете могут быть люди (объект “Человек”) и так далее. Возьмем, например, объект “Человек”, его характеристиками (полями) могут быть: цвет кожи, пол, рост, возраст (что-то еще). И также он может выполнять следующие действия (методы/функции): бегать, кушать, работать и так далее. Вы легко можете спроецировать такой подход (парадигму) на жизнь, представить все вокруг с помощью объектов и вы поймете, что любое действие (метод/функция) связано с каким-либо объектом, оно не может существовать само по себе, кто-то должен его выполнять. Именно по этой причине наши действия (методы/функции) “sum” и “subtract” находятся внутри объекта “Calculator” (Калькулятор).
— Интересно! Про ООП я понял, а почему в ФП все функции ни к чему не привязаны, находятся сами по себе?
Помните я говорил, что ФП основано на процессах (функциях)? Давайте опять попробуем спроецировать это на нашу жизнь. Например, возьмем процесс (функцию) создания вселенной, галактики, планеты, человека, процесс (функцию) сложения, вычитания и т.д. Сам процесс (функция) никому не принадлежит — он общий, пользоваться может кто угодно, но при этом каждый процесс (функция) имеет определенные условия, в зависимости от которых получается тот или иной результат. Рассмотрим простой пример из жизни, процесс “Приготовление ужина”: данный процесс может осуществить кто угодно, даже ваш кот или собака, но так как опыта у них нет, то, вероятнее всего, ужин просто не будет приготовлен. То есть получается, что воспользоваться могут все, но результат будет разный.
— Фух, ну теперь понятно, что такое парадигма программирования. Ну все-таки остался вопрос: почему где-то используется одна парадигма, а где-то другая?
Вы удивитесь, но на самом деле, две эти парадигмы можно использовать одновременно. Опять-таки, давайте рассмотрим простой пример, спроецированный на реальную жизнь. Представим, что у нас есть:
- [ООП] Объект “Человек”, который не имеет никаких характеристик (полей) (например, пол, рост и количество лет), но зато умеет готовить (имеет действие (метод/функцию) “приготовить ужин”)
- [ООП] Объект “Собака”, у которой есть такие характеристики (поля), как цвет шерсти, возраст. И также она умеет бегать (имеет действие (метод/функцию) “бежать”)
- [ФП] Процесс (функция) “Приготовление ужина”.
Заключение
Итак, в этой статье мы можно сказать на пальцах, без специфических терминов, разобрали основные различия парадигм ООП и ФП. К сожалению, тут нам пора остановиться. Теперь ваш ход – самостоятельно углублять знания с помощью дополнительной литературы.
Должен сказать, что я немного творчески подошел к написанию данной статьи: упростил терминологию, а где-то и вовсе заменил понятия метафорами, но все это только для того, чтобы любой человек, даже не имеющий никаких знаний в этой области, мог погрузиться в тему парадигм программирования. Я надеюсь, что данная статья была полезна будущем программистам и после ее прочтения удивительный мир программирования стал чуть ближе для каждого.
Парадигмы программирования: примеры парадигм для новичков
Что такое парадигмы программирования? Это не более, чем просто замысловатое название для популярных способов и стилей организации процесса написания программного кода.
Я постараюсь разбить эту тему на части и дать простое пояснение по каждой парадигме. Таким образом, вы сможете легко понять, о чем говорят люди, когда произносят такие слова, как «объектно-ориентированный», «функциональный» или «декларативный». Давайте начнем!
Что такое парадигма программирования?
Парадигмы программирования – это различные способы и стили, которые используются для организации программы или языка программирования. Каждая парадигма состоит из определенных структур, функций и взглядов на то, как следует решать известные задачи программирования.
Вопрос о том, почему существует так много различных парадигм программирования, схож с вопросом о том, почему существует так много языков программирования. Определенные парадигмы лучше подходят для определенных типов задач. Именно поэтому имеет смысл использовать разные парадигмы для разных типов проектов.
Кроме того, методики, которые составляют каждую парадигму, развивались с течением времени. Благодаря достижениям как в области программного, так и аппаратного обеспечения появились различные подходы к решению задач, которых раньше просто не было.
И последняя причина – я думаю, это просто творческое начало в человеке. По своей натуре, нам просто нравится создавать новые вещи, улучшать то, что другие когда-то создали, и адаптировать инструменты под себя и свои предпочтения или просто делать их более эффективными (в нашем понимании).
Все это привело к тому, что на сегодняшний день мы имеем огромное количество вариантов, которые могут помочь нам написать и структурировать ту или иную программу.
Чем парадигма программирования не является?
Парадигмы программирования – это не языки и не инструменты. Вы не сможете ничего «создать» с помощью парадигмы. Они больше похожи на некий набор образцов и руководящих принципов, о которых условились большое количество людей, которым они следовали и которые они подробно изложили.
Язык программирования не всегда привязан к определенной парадигме. Есть языки, которые были созданы с учетом определенной парадигмы и имеют функции, которые облегчают программирование в этом контексте больше, чем другие (хороший пример – Haskel и функциональное программирование).
Однако существуют и «многопарадигмальные» языки. Это означает, что вы можете адаптировать свой код, чтобы он подходил под какую-то из парадигм (хороший пример – JavaScript и Python).
При этом парадигмы программирования не являются взаимоисключающими в том смысле, что вы можете без каких-либо проблем использовать приемы из различных парадигм одновременно.
Популярные парадигмы программирования
Теперь, когда вы знаете, что такое парадигмы программирования, а что к ним не относится, давайте рассмотрим самые популярные из них, их характеристики и сравним их.
Имейте в виду, что этот список не полный. Существуют и другие парадигмы программирования, которые мы здесь рассматривать не будем. Здесь я расскажу вам только о самых популярных и широко используемых.
Императивное программирование
Императивное программирование – это набор подробных инструкций, которые даются компьютеру, чтобы тот выполнил их в заданном порядке. Этот тип программирования называется «императивным», потому что мы некоторым образом указываем компьютеру (как программисты), что он должен делать.
Императивное программирование концентрируется на описании того, как программа работает, шаг за шагом.
Допустим, вы хотите испечь торт. Ваша императивная программа для такого рода задачи может выглядеть следующим образом:
1- Pour flour in a bowl 2- Pour a couple eggs in the same bowl 3- Pour some milk in the same bowl 4- Mix the ingredients 5- Pour the mix in a mold 6- Cook for 35 minutes 7- Let chill
Воспользуемся конкретным примером и предположим, что мы хотим отфильтровать массив чисел так, чтобы остались только числа, которые больше 5. Наш императивный код тогда будет выглядеть следующим образом:
const nums = [1,4,3,6,7,8,9,2] const result = [] for (let i = 0; i < nums.length; i++) < if (nums[i] >5) result.push(nums[i]) > console.log(result) // Output: [ 6, 7, 8, 9 ]
Обратите внимание, что мы указываем программе, что нужно перебрать каждый элемент массива, сравнить каждый из них с 5 и, если элемент больше 5, то поместить его в конечный массив.
Наши инструкции предельно детализированы и конкретны, и именно это и является императивным программированием.
Процедурное программирование
Процедурное программирование – это производное от императивного программирования только с функциями (также известных как «процедуры» или «подпрограммы»).
Процедурное программирования предлагает пользователю разделить выполнение программы на функции, чтобы оптимизировать модульный принцип организации.
Вернемся к нашему примеру с тортом. Процедурная программа для этого примера будет выглядеть следующим образом:
function pourIngredients() < - Pour flour in a bowl - Pour a couple eggs in the same bowl - Pour some milk in the same bowl >function mixAndTransferToMold() < - Mix the ingredients - Pour the mix in a mold >function cookAndLetChill() < - Cook for 35 minutes - Let chill >pourIngredients() mixAndTransferToMold() cookAndLetChill()
Как вы можете видеть, благодаря реализации функций, мы можем просто прочитать три вызова функций в конце файла и понять, что делает наша программа.
Такое упрощение и абстрактное представление является одним из преимуществ процедурного программирования. Однако внутри функций находится все тот же императивный код.
Функциональное программирование
Функциональное программирование продвигает концепцию создания функций немного дальше.
В функциональном программировании функции рассматриваются как «полноправные граждане». Это означает, что их можно присваивать переменным, передавать в качестве аргумента и возвращать в качестве результата других функций.
Еще одна ключевая концепция – это идея чистых функций. Чистая функций – это функция, которая, чтобы получить результат, полагается только на свои входные данные. И при одних и тех же входных данных всегда будет один и тот же результат. Кроме того, эти функции не имеют никаких побочных эффектов (то есть не вносят никаких изменений вне контекста функции).
С учетом всех этих концепций, функциональное программирование призывает писать программы с помощью функций. Оно также поддерживает идею о том, что модульность кода и отсутствие побочных эффектов облегчают определение и разделение обязанностей внутри кодовой базы. Таким образом, это облегчает сопровождение кода.
Вернемся к примеру с фильтрацией массива. В императивной парадигме мы можем использовать внешнюю переменную для хранения результата функции, что по сути может считаться побочным эффектом.
const nums = [1,4,3,6,7,8,9,2] const result = [] // External variable for (let i = 0; i < nums.length; i++) < if (nums[i] >5) result.push(nums[i]) > console.log(result) // Output: [ 6, 7, 8, 9 ]
Для того, чтобы преобразовать это в функциональное программирование, мы можем сделать следующее:
const nums = [1,4,3,6,7,8,9,2] function filterNums() < const result = [] // Internal variable for (let i = 0; i < nums.length; i++) < if (nums[i] >5) result.push(nums[i]) > return result > console.log(filterNums()) // Output: [ 6, 7, 8, 9 ]
Это практически тот же самый код, но мы проворачиваем все итерации внутри функции, в которой мы также сохраняем и массив результатов. Таким образом, мы можем гарантировать, что функция не будет ничего менять за своими пределами. Она создает переменную только для обработки своей собственной информации, и после завершения своей работы удаляет ее.
Декларативное программирование
Декларативное программирование скрывает всю сложность и приближает языки программирования к человеческому языку и мышлению. Это абсолютная противоположность императивному программированию, хотя бы потому что программист дает инструкции не о том, как компьютеру следует решать задачу, а о том, какой требуется результат.
Будет намного понятнее, если мы приведем пример. Воспользуемся примером с фильтрацией массива. Декларативный подход здесь будет выглядеть следующим образом:
const nums = [1,4,3,6,7,8,9,2] console.log(nums.filter(num => num > 5)) // Output: [ 6, 7, 8, 9 ]
Обратите внимание, что, используя функцию фильтрации filter , мы явно не указываем компьютеру перебирать массив или сохранять значения в отдельном массиве. Мы просто говорим о том, что мы хотим («filter») и условие, которое необходимо выполнить («num > 5»).
Что хорошего в таком подходе? Его легче читать и понимать, и зачастую он более емкий в записи. Хорошими примерами декларативного кода являются функции filter , map , reduce и sort в JavaScript.
Еще один хороший пример – современные фреймворки/библиотеки JS, такие как React. Посмотрите, например, на этот код:
Здесь у нас есть кнопка (button) с приемником событий, который запускает функцию console.log при нажатии кнопки.
Синтаксис JSX (то, что использует React) совмещает HTML и JS. Это упрощает и ускоряет написание приложений. Но это не то, что браузеры читают и выполняют. Код React позже преобразуются в обычный HTML и JS, а вот это уже то, с чем работают браузеры.
JSX является декларативным, поскольку его цель заключается в том, чтобы предоставить разработчикам более удобный и эффективный интерфейс для работы.
Здесь также важно отметить, что в декларативном программировании компьютер все равно обрабатывает информацию как императивный код.
Если снова вернуться к примеру с массивом, то компьютер по-прежнему выполняет итерацию по массиву, как в цикле for , но нам, как программистам, не нужно писать это напрямую. Декларативное программирование скрывает всю сложность от программиста.
Объектно-ориентированное программирование
Одной из самых популярных парадигм программирование является объектно-ориентированное программирование (ООП).
Основная концепция ООП заключается в разделении понятий на сущности, которые описываются как некие объекты. Каждая сущность группирует заданный набор информации (свойств) и действий (методов), которые может выполнять эта сущность.
ООП широко использует классы. Классы — это способ создания новых объектов с помощью макета или шаблона, который задает программист. Объекты, которые были созданы с помощью класса, называются экземплярами.
Вернемся к примеру с приготовлением пищи на псевдокоде. Предположим, что в нашей пекарне у нас есть главный повар (по имени Фрэнк) и помощник повара (по имени Энтони). У каждого их них есть определенные обязанности. Если бы мы использовали ООП, то наша программа бы выглядеть следующим образом:
// Create the two classes corresponding to each entity class Cook < constructor constructor (name) < this.name = name >mixAndBake() < - Mix the ingredients - Pour the mix in a mold - Cook for 35 minutes >> class AssistantCook < constructor (name) < this.name = name >pourIngredients() < - Pour flour in a bowl - Pour a couple eggs in the same bowl - Pour some milk in the same bowl >chillTheCake() < - Let chill >> // Instantiate an object from each class const Frank = new Cook('Frank') const Anthony = new AssistantCook('Anthony') // Call the corresponding methods from each instance Anthony.pourIngredients() Frank.mixAndBake() Anthony.chillTheCake()
Преимущество ООП заключается в том, что оно облегчает понимание программы за счет четкого разделения задач и обязанностей.
Итоги
Как мы увидели, парадигмы программирования – это различные способы решения задач программирования и организации нашего кода.
Одними из самых популярных и широко используемых на сегодняшний день парадигм являются императивная, процедурная, функциональная, декларативная и объектно-ориентированная. Знание о том, что они из себя представляют, полезно для общего развития, а также для лучшего понимания других тем, связанных с программированием.
Новосибирский государственный университет
Словарь-справочник по информатике (онтология информатики)
Парадигмы программирования
Синонимы: парадигмы программирования; парадигма программирования; стиль программирования;
Парадигма программирования — исходная концептуальная схема постановки задач и их решения вместе с языком, ее формализующим, и формирующая стиль программирования.
Парадигма (παράδειγμα, «пример, модель, образец») — совокупность фундаментальных научных установок, представлений и терминов, принимаемая и разделяемая научным сообществом и объединяющая большинство его членов. Обеспечивает преемственность развития науки и научного творчества.
Парадигма является инструментом грамматического описания фактов, событий, явлений и процессов, возможно, не существующих одновременно, но интуитивно объединяемых в общее понятие. Парадигма представляет (и определяет) то, как программист видит выполнение плана решения поставленной задачи (программы).
Важно отметить, что парадигма программирования не определяется однозначно языком программирования; практически все современные языки программирования в той или иной мере допускают использование различных парадигм (мультипарадигмальное программирование). Создатели языков придерживаются точки зрения, гласящей, что ни одна парадигма не может быть одинаково эффективной для всех задач, и следует позволять программисту выбирать лучший стиль программирования для решения каждой отдельной задачи.
Так на языке Си, который не является объектно-ориентированным, можно работать в соответствии с принципами объектно-ориентированного программирования, хотя это и сопряжено с определёнными сложностями, функциональное программирование можно применять при работе на любом императивном языке, в котором имеются функции.
- состояний программы и команд, изменяющих их (императивное программирование),
- математических функций без состояний (функциональное программирование),
- объектов и взаимодействий между ними (объектно-ориентированное программирование),
- алгоритмов и контейнеров, оперирующих с типами данных, переданными как параметр (обобщенное программирование),
- значений и операций, преобразующих значения (программирование на уровне значений), и т.д.
Ключевые термины, связанные с термином «парадигмы программирования»:
- Аспектно-ориентированное программирование
- Декларативное программирование
- Императивное программирование
- Логическое программирование
- Модель программная
- Объектно-ориентированное программирование
- Программирование структурное
- Функциональное программирование
Литература
© 2007-2024, Новосибирский государственный университет, Новосибирск
© 1998-2024, Институт вычислительных технологий СО РАН, Новосибирск
© 1998-2024, Федотов А.М.
Дата последней модификации: 22.12.2013
Парадигмы программирования: что это такое
Понимание значения парадигм программирования — это основа. В этой статье мы кратко, но емко коснемся этой захватывающей темы и расскажем простым языком о самом главном. Мы дадим понятное определение — что это такое, зачем они нужны разработчикам ПО и какие существуют основные виды.
Даниил Фам
Исполнительный директор
12 декабря 2022
Что такое парадигмы программирования: понятие, пример
Для погружения в эту непростую тему сначала дадим определение этому понятию: парадигма программирования — это набор концепций, терминов, правил и абстрактных идей, которые определяют стиль написания кода. То есть, это модель, содержащая нотации для оптимальной реализации программы.
При этом сразу стоит обратить внимание, что это понятие не тождественно языкам программирования. Языки могут быть мультипарадигменными и подчиняться не одной модели. Другими словами: это когда при кодинге на одном и том же языке — для решения разных задач применяются наиболее подходящие для этого подходы. Получается, что много парадигмальность языка — большой плюс, так как он позволяет переключаться между подходами, оставаясь в знакомой среде.
Более того — новые языки создаются именно на базе существующих парадигм.
Примеры парадигм программирования: идея функциональной модели базируется исключительно на применении функций, а вот объектно-ориентированное уже основано на взаимодействии классов и объектов.
Для чего нужны парадигмы программирования: происхождение и применение
Далее рассмотрим два важных вопроса: как появились парадигмы языков программирования и зачем их стали использовать?
Делов том, что за время существования программирования, разработчиками ПО — было создано множество оптимальных по эффективности методик для решения различных задач. Далее они были отточены опытным путём и сформированы в парадигмы.
Это было сделано для облегчения работы программистов. Ведь зачастую теперь достаточно определить классификацию задачи, чтобы понять — при помощи какой методики можно её решить наилучшим способом.
Получается, что парадигмы программирования — можно сравнить с готовым набором инструментов, лучше всего решить поставленную задачу при разработке программы.
Соответственно — в каждой методологии сформирован конкретный подход к применению ключевых конструкций, определены стандарты написания кода и построения архитектуры приложений для получения требуемого результата оптимальным образом.
Также использование таких готовых моделей позволяет довольно быстро преодолевать проблему отсутствия опыта в написании кода на новом языке.
Какие виды существуют: кратко об основных парадигмах программирования
Теперь поговорим про основные виды парадигм программирования, а также кратко рассмотрим — на чём базируется написание программного кода в них.
Из используемых моделей можно выделить две контрастирующие между собой:
- Императивное — строится на последовательности логических команд для компьютерного железа, которые четко описывают алгоритмы работы ПО
- Декларативное — не требует подробных указаний, так как представляет собой описание задачи и требуемого результата
Здесь стоит отметить, что большинство языков программирования поддерживают оба подхода к написанию исходного кода ПО, но всё же больше заточены только под одну из них.
Также есть различные подвиды, например:
- Объектно-ориентированное
- Процедурное
- Структурное
- Функциональное
- Логическое
- Обобщённое
Естественно — это далеко не все виды моделей кодинга, так как их уже создано достаточно, при этом периодически появляются новые подходы. Некоторые из них являются подвидами основных, но при этом в силу своих особенностей зачастую рассматриваются отдельно. Также многие современные парадигмы программирования достаточно часто пересекаются в некоторых аспектах (например: в наборе понятий, правил или концепций).
Так как все методы в рамках небольшой статьи рассмотреть невозможно — для наглядности немного подробнее рассмотрим три из них, которые используются разработчиками чаще всего: это две контрастирующие (императивный и декларативный), а также обобщенный в силу его постоянно нарастающей популярности в программистской среде.
Императивная парадигма программирования: почему этот подход используется чаще всего
Здесь мы кратко рассмотрим — что такое императивная парадигма программирования.
Данный подход отталкивается от написания последовательности команд, которые должен выполнить процессор для выполнения программной задачи. То есть написанная таким методом программа буквально напрямую отдаёт приказания железу.
Но, несмотря на строгость концепции — эта модель даёт разработчикам значительно больше свободы при реализации прикладного программного обеспечения. Соответственно — она чаще применяется для решения творческих задач, особенно в которых необходимо четкое соблюдения последовательности действий.
Бывает нескольких подвидов этого подхода, которые определяются языками программирования: процедурная, структурная, аспектно- и объектно-ориентированная (которая также может быть агентно-, компонентно-, прототипно-ориентированной, а также сюда относится обобщенная модель создания кода).
Декларативная парадигма программирования: подробнее о подходе
Так как мы рассматриваем основные парадигмы программирования, необходимо обязательно описать и эту модель, ориентированную на описание задачи и ожидаемого результата.
В декларативной парадигме разработчик описывает проблему и ожидаемый результат, но не пишет никаких инструкций. В декларативном программировании отсутствуют переменные, состояние и прочие понятия, которые свойственны императивной.
Здесь разработчику не нужно расписывать инструкции, использовать переменные, состояния и другие инструменты. Программист не думает о том, как программа будет выполнять задачу, он просто пишет, какой результат ему нужен.
Да, такой подход к созданию кода требует намного меньшего количества когда и оно значительно легче, чем императивное. Но оно абсолютно не подходит для реализации идей, где необходимо получать данные о состоянии программы в определённый момент (например: выполнено ли пользователем конкретное действие), соответственно — нет возможности указать, что программа должна реагировать.
Для наилучшего понимания ситуации, важно озвучить один нюанс. Несмотря на то, что эта модель считается контрастирующей с императивной — её можно считать «надстройкой», так как для осуществления возможности работы декларативной сначала создаются инструкции, без которых невозможно взаимодействие железа и ПО.
К декларативной парадигме относятся: функциональное и логическое программирование.
Обобщённое программирование: в чём уникальность этого подхода
Эта модель относится к метапрограммированию, но одна из востребованных в данном виде. Поэтому мы рассмотрим именно её.
Суть подхода основана на алгоритмическом мышлении и обработке абстрактных описаний требований структур контейнеров, которые не привязываются к определённому типу используемых данных и позволяют работать с различными их видами, не меняя сами описания.
Поклонники развития этой модели стремятся к максимально универсальным шаблонным решениям для схожих задач, способным одинаково эффективно работать с любым типом данных (которые в данном случае будут использоваться в роли входящих параметров для контейнеров и алгоритмов).
В итоге структура алгоритма программы, была написана с использованием обобщённой модели применяется для любых типов данных, которые подходят по концепции (то есть — по набору требований описания интерфейса и семантического поведения).
Итого
Тема, действительно очень интересная и объёмная. А о том, какие подходы к программированию использовать в той или иной ситуации можно прочитать не одну лекцию. К тому же — это вопрос неоднозначный и вызывающий немало холиваров среди разработчиков.
Одно можно сказать с уверенностью — с практической точки здания для эффективного решения задач при написании исходного кода ПО стоит знать особенности различных моделей в разных языках.
Информация была полезна?
15 оценок, среднее 3.9 из 5