По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Что такое парадигмы программирования? Это не более, чем просто замысловатое название для популярных способов и стилей организации процесса написания программного кода. Я постараюсь разбить эту тему на части и дать простое пояснение по каждой парадигме. Таким образом, вы сможете легко понять, о чем говорят люди, когда произносят такие слова, как «объектно-ориентированный», «функциональный» или «декларативный». Давайте начнем! Что такое парадигма программирования? Парадигмы программирования – это различные способы и стили, которые используются для организации программы или языка программирования. Каждая парадигма состоит из определенных структур, функций и взглядов на то, как следует решать известные задачи программирования. Вопрос о том, почему существует так много различных парадигм программирования, схож с вопросом о том, почему существует так много языков программирования. Определенные парадигмы лучше подходят для определенных типов задач. Именно поэтому имеет смысл использовать разные парадигмы для разных типов проектов. Кроме того, методики, которые составляют каждую парадигму, развивались с течением времени. Благодаря достижениям как в области программного, так и аппаратного обеспечения появились различные подходы к решению задач, которых раньше просто не было. И последняя причина – я думаю, это просто творческое начало в человеке. По своей натуре, нам просто нравится создавать новые вещи, улучшать то, что другие когда-то создали, и адаптировать инструменты под себя и свои предпочтения или просто делать их более эффективными (в нашем понимании). Все это привело к тому, что на сегодняшний день мы имеем огромное количество вариантов, которые могут помочь нам написать и структурировать ту или иную программу. Чем парадигма программирования не является? Парадигмы программирования – это не языки и не инструменты. Вы не сможете ничего «создать» с помощью парадигмы. Они больше похожи на некий набор образцов и руководящих принципов, о которых условились большое количество людей, которым они следовали и которые они подробно изложили. Язык программирования не всегда привязан к определенной парадигме. Есть языки, которые были созданы с учетом определенной парадигмы и имеют функции, которые облегчают программирование в этом контексте больше, чем другие (хороший пример – 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 onClick={() => console.log('You clicked me!')}>Click me</button> Здесь у нас есть кнопка (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() Преимущество ООП заключается в том, что оно облегчает понимание программы за счет четкого разделения задач и обязанностей. Итоги Как мы увидели, парадигмы программирования – это различные способы решения задач программирования и организации нашего кода. Одними из самых популярных и широко используемых на сегодняшний день парадигм являются императивная, процедурная, функциональная, декларативная и объектно-ориентированная. Знание о том, что они из себя представляют, полезно для общего развития, а также для лучшего понимания других тем, связанных с программированием.
img
Когда синхронизация менее важна, чем фактическая доставка, трафиком часто можно управлять с помощью метода взвешенной справедливой организации очереди на основе классов (CBWFQ). В CBWFQ участвующие классы трафика обслуживаются в соответствии с назначенной им политикой. Например, трафику, помеченному как AF41, может быть гарантирована минимальная пропускная способность. Для трафика, помеченного как AF21, также может быть гарантирована минимальная пропускная способность, возможно, меньшая, чем объем, предоставленный трафику AF41. Немаркированный трафик может получить любую оставшуюся полосу пропускания. CBWFQ имеет понятие справедливости, когда различные классы трафика могут доставляться по перегруженному каналу. CBWFQ обеспечивает справедливое обслуживание пакетов в очереди в соответствии с политикой QoS. Пакеты будут отправляться всем классам трафика с назначенной им полосой пропускания. Например, предположим, что пропускная способность канала составляет 1024 Кбит / с. Для класса трафика AF41 гарантирован минимум 256 Кбит / с. Для класса AF31 гарантирована скорость минимум 128 Кбит / с. Для класса AF21 гарантирована скорость минимум 128 Кбит / с. Это дает нам соотношение 2: 1: 1 между этими тремя классами. Остальные 512 Кбит / с не распределены, то есть доступны для использования другим трафиком. Включая нераспределенную сумму, полное соотношение составляет 256: 128: 128: 512, что сокращается до 2: 1: 1: 4. Чтобы решить, какой пакет будет отправлен следующим, очередь обслуживается в соответствии с политикой CBWFQ. В этом примере пропускная способность 1024 Кбит / с делится на четыре части с соотношением 2: 1: 1: 4. Для простоты предположим, что перегруженный интерфейс будет обслуживать пакеты в очереди за восемь тактов: Тактовый цикл 1. Будет отправлен пакет AF41. Тактовый цикл 2. Будет отправлен еще один пакет AF41. Тактовый цикл 3. Будет отправлен пакет AF31. Тактовый цикл 4. Будет отправлен пакет AF21. Тактовые циклы 5-8. Пакеты с другими классификациями, а также неклассифицированные пакеты будут отправлены. В этом примере предполагается, что есть пакеты, представляющие каждый из четырех классов, находящихся в буфере, поставленных в очередь для отправки. Однако не всегда все бывает так однозначно. Что происходит, когда нет пакетов из определенного класса трафика для отправки, даже если есть место в гарантированном выделении минимальной полосы пропускания? Гарантированная минимальная пропускная способность не является резервированием. Если класс трафика, которому назначен гарантированный минимум, не требует полного распределения, другие классы трафика могут использовать полосу пропускания. Также нет жестких ограничений гарантированного минимума пропускной способности. Если объем трафика для определенного класса превышает гарантированный минимум и полоса пропускания доступна, трафик для класса будет проходить с большей скоростью. Таким образом, происходящее могло бы выглядеть примерно так: Тактовый цикл 1. Отправляется пакет AF41. Тактовый цикл 2. Нет пакета AF41 для отправки, поэтому вместо него отправляется пакет AF31. Тактовый цикл 3. Отправлен еще один пакет AF31. Тактовый цикл 4. Нет пакета AF21 для отправки, поэтому отправляется неклассифицированный пакет. Тактовые циклы 5-7. Отправляются пакеты с другими классификациями, а также неклассифицированные пакеты. Тактовый цикл 8. Нет более классифицированных или неклассифицированных пакетов для отправки, поэтому отправляется еще один пакет AF31. В результате неиспользованная полоса пропускания делится между классами с избыточным трафиком. Перегрузка CBWFQ не увеличивает пропускную способность перегруженного канала. Скорее, алгоритм предусматривает тщательно контролируемое совместное использование перенапряженного канала, отражающее относительную важность различных классов трафика. В результате совместного использования CBWFQ трафик доставляется через перегруженный канал, но с меньшей скоростью по сравнению с тем же каналом в незагруженное время. Невозможно переоценить различие между "совместным использованием перегруженного канала" и "созданием полосы пропускания из ничего". Распространенное заблуждение о QoS заключается в том, что, несмотря на точки перегрузки на сетевом пути, взаимодействие с пользователем останется идентичным. Это совсем не так. Инструменты QoS, такие как CBWFQ, по большей части предназначены для того, чтобы максимально использовать плохую ситуацию. При выборе того, когда и когда пересылать трафик, QoS также выбирает, какой трафик отбрасывать. Среди потоков, передаваемых по сети, есть "победители" и "проигравшие". LLQ является заметным исключением, поскольку предполагается, что трафик, обслуживаемый LLQ, настолько критичен, что он будет обслуживаться, исключая другой трафик, вплоть до назначенного ограничения полосы пропускания. LLQ стремится сохранить пользовательский опыт. Другие инструменты управления перегрузкой QoS Формирование трафика - это способ изящно ограничить классы трафика определенной скоростью. Например, трафик, помеченный как AF21, может иметь скорость 512 Кбит / с. Формирование изящное. Он допускает номинальные всплески выше определенного предела перед отбрасыванием пакетов. Это позволяет TCP более легко настраиваться на требуемую скорость. Когда пропускная способность сформированного класса трафика отображается на графике, результат показывает нарастание до предельной скорости, а затем постоянную скорость передачи на протяжении всего потока. Формирование трафика чаще всего применяется к классам трафика, заполненным слоновьими потоками. Слоновидные потоки - это долговечные потоки трафика, используемые для максимально быстрого перемещения больших объемов данных между двумя конечными точками. Слоновые потоки могут заполнять узкие места в сети собственным трафиком, подавляя меньшие потоки. Распространенная стратегия QoS состоит в том, чтобы формировать скорость трафика слоновьих потоков, чтобы в узком месте оставалась достаточная пропускная способность для эффективного обслуживания других классов трафика. Применение политик аналогично формированию трафика, но более жестко обращается с избыточным (несоответствующим) трафиком. Вместо того, чтобы допускать небольшой всплеск выше определенного предела пропускной способности, как при формировании перед сбросом, применение политик немедленно отбрасывает избыточный трафик. При столкновении с ограничителем трафика затронутый трафик увеличивается до предела пропускной способности, превышает его и отбрасывается. Такое поведение отбрасывания заставляет TCP заново запускать процесс наращивания мощности. Полученный график выглядит как пилообразный. Применение политик может использоваться для выполнения других задач, таких как перемаркировка несоответствующего трафика на значение DSCP с более низким приоритетом, а не отбрасывание.
img
У нас есть Windows Server 2008 R2 и сейчас мы сделаем из него Контроллер домена - Domain Controller (DC). Погнали! Первым делом – запускаем Server Manager: Затем выбираем опцию Roles и добавляем новую роль для нашего сервера, нажав Add Roles: Нас встречает мастер установки ролей, а также просят убедиться, что учетная запись администратора имеет устойчивый пароль, сетевые параметры сконфигурированы и установлены последние обновления безопасности. Прочитав уведомление кликаем Next Сервер, выступающий в роли DC обязан иметь статический IP адрес и настройки DNS Если данные настройки не были выполнены заранее, то нас попросят выполнить их в дальнейшем на одном из этапов. В списке доступных ролей выбираем Active Directory Domain Services. Мастер сообщает, что для установки данной роли нужно предварительно выполнить установку Microsoft .NET Framework. Соглашаемся с установкой, нажав Add Required Features и кликаем Next Нас знакомят с возможностями устанавливаемой роли Active Directory Domain Services (AD DS) и дают некоторые рекомендации. Например, рекомендуется установить, как минимум 2 сервера с ролями AD DS (т.е сделать 2 DC) на случай, чтобы при выходе из строя одного сервера, пользователи домена все ещё могли бы залогиниться с помощью другого. Также, нас предупреждают о том, что в сети должен быть настроен DNS сервер, а если его нет, то данному серверу нужно будет дать дополнительную роль – DNS. После того, как прочитали все рекомендации, кликаем Next чтобы продолжить установку. Наконец, нам предоставляют сводную информацию об устанавливаемой роли и дополнительных компонентах для подтверждения. В данном случае, нас уведомляют о том, что будет установлена роль AD DS и компонент .NET Framework 3.5.1. Для подтверждения установки кликаем Install. Дожидаемся пока завершится процесс установки роли и компонентов. Через какое-то время перед нами появится результат установки, он должен быть успешным как для роли так и для компонентов Installation succeeded. Закрываем мастер установки, нажав Close. Вернувшись в Server Manager мы увидим, что у нас появилась роль AD DS, однако ее статус неактивен. Чтобы продолжить настройку кликаем на Active Directory Domain Services. Перед нами открывается уведомление о том, что наш сервер пока ещё не является контроллером домена, и чтобы это исправить нам следует запустить мастер настройки AD DS (dcpromo.exe). Кликаем на ссылку Run the Active Directory Domain Services Installation Wizard или же запускаем его через Пуск – Выполнить – dcpromo.exe. Перед нами открывается мастер настройки AD DS. Расширенный режим установки можно не включать. Для продолжения кликаем Next Нас встречает уведомление о том, что приложения и SMB клиенты, которые используют старые небезопасные криптографические алгоритмы Windows NT 4.0 при установке соединений, могут не заработать при взаимодействии с контроллерами домена на базе Windows Server 2008 и 2008 R2, поскольку по умолчанию, они не разрешают работу по данным алгоритмам. Принимаем данную информацию к сведению и кликаем Next Далее нам нужно выбрать принадлежность данного контроллера домена. Если бы у нас уже имелся лес доменов, то данный DC можно было бы добавить туда, либо добавив его в существующий домен, либо же создав новый домен в существующем лесу доменов. Поскольку мы создаем контроллер домена с нуля, то на следующей вкладке мы выбираем создание нового домена и нового леса доменов Create a new domain in a new forest и кликаем Next. После этого нам предлагают задать FQDN корневого домена нового леса. В нашем случае мы выбрали merionet.loc. Сервер проверит свободно ли данное имя и продолжит установку, нажимаем Next. Далее задаем функциональный уровень леса доменов. В нашем случае - Windows Server 2008 R2 и кликаем Next. Обратите внимание, что после задания функционального уровня, в данный лес можно будет добавлять только DC равные или выше выбранного уровня. В нашем случае от Windows Server 2008 R2 и выше. Далее, нам предлагают выбрать дополнительные опции для данного DC. Выберем DNS Server и нажимаем Next. В случае, если ваш сервер ещё не имеет статического IP адреса, перед вами появится следующее предупреждение с требованием установить статический IP адрес и адрес DNS сервера. Выбираем No, I will assign static IP addresses to all physical network adapters Устанавливаем статические настройки IP адреса и DNS. В нашем случае – в роли DNS сервера выступает дефолтный маршрутизатор (Default Gateway) нашей тестовой сети. Далее, установщик предлагает нам выбрать путь, по которому будут храниться база данных Active Directory, лог-файл и папка SYSVOL, которая содержит критичные файлы домена, такие как параметры групповой политики, сценарии аутентификации и т.п. Данные папки будут доступны каждому DC в целях репликации. Мы оставим пути по умолчанию, но для лучшей производительности и возможности восстановления, базу данных и лог-файлы лучше хранить в разных местах. Кликаем Next. Далее нас просят указать пароль учетной записи администратора для восстановления базы данных Active Directory. Пароль данной УЗ должен отличаться от пароля администратора домена. После установки надежного сложного пароля кликаем Next. Далее нам выводят сводную информацию о выполненных нами настройках. Проверяем, что все корректно и кликаем Next. Мастер настройки приступит к конфигурации Active Directory Domain Services. Поставим галочку Reboot on completion, чтобы сервер перезагрузился по завершении конфигурирования. После перезагрузки сервер попросит нас залогиниться уже как администратора домена MERIONET. Поздравляем, Вы создали домен и контроллер домена! В следующей статье мы наполним домен пользователями и позволим им логиниться под доменными учетными записями.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59