По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Это продолжение статьи про пакетную коммутацию. Первая часть тут. Схемы агрегации каналов берут несколько физических каналов и объединяют их в один виртуальный канал. В целях протоколов маршрутизации и алгоритмов предотвращения петель, таких как связующее дерево, виртуальный канал обрабатывается, как если бы он был одним физическим каналом. Агрегирование каналов используется для увеличения пропускной способности между узлами сети без необходимости замены более медленных физических каналов на более быстрые. Например, два канала 10 Гбит/с можно объединить в один канал 20 Гбит/с, тем самым удвоив потенциальную полосу пропускания между двумя узлами, как показано на рисунке 6. Слово «потенциал» было выбрано тщательно, поскольку агрегированные каналы на практике не масштабируются линейно. Проблема, с которой сталкивается агрегация каналов, заключается в определении, какие пакеты должны быть отправлены по какому элементу связи. Интуитивно это может показаться не проблемой. В конце концов, казалось бы, имеет смысл использовать группу каналов связи в циклическом режиме. Первоначальный фрейм будет отправлен по первому элементу связки, второй фрейм - по второму элементу и так далее, в конечном итоге возвращаясь к первому элементу связки. Таким образом, канал должен использоваться идеально равномерно, а пропускная способность - линейно. В реальной жизни существует очень мало подобных реализаций, в которых агрегированные каналы используются на такой циклической основе, как эта, потому что они рискуют доставить неупорядоченные пакеты. Предположим, что первый кадр Ethernet отправляется первому звену нисходящего канала, а второй кадр - второму элементу нисходящего канала сразу после него. По какой-то причине второй кадр попадает на другой конец раньше первого кадра. Пакеты, содержащиеся в этих кадрах, будут доставлены принимающим узлам в неупорядоченном порядке - пакет два перед пакетом один. Это проблема, потому что теперь на хост возлагается вычислительная нагрузка по переупорядочению пакетов, чтобы можно было правильно собрать всю дейтаграмму. Поэтому большинство поставщиков реализуют хеширование потоков, чтобы гарантировать, что весь поток трафика использует один и тот же элемент пакета. Таким образом, нет никакого риска того, что хост получит пакеты не по порядку, так как они будут отправляться последовательно через один и тот же элемент канала. Хеширование потока работает путем выполнения математической операции над двумя или более статическими компонентами потока, такими как MAC-адреса источника и получателя, IP-адреса источника и получателя, протокол управления передачей (TCP) или протокол дейтаграмм пользователя (UDP). номера портов для вычисления элемента связи, который будет использовать поток. Поскольку характеристики потока статичны, алгоритм хеширования приводит к идентичным вычислениям для каждого кадра или пакета в потоке трафика, гарантируя, что один и тот же канал будет использоваться в течение всего срока службы потока. Хотя хеширование потока решает проблему неупорядоченных пакетов, оно создает новую проблему. Не все потоки имеют одинаковый размер. Некоторые потоки используют большую полосу пропускания, например те, которые используются для передачи файлов, резервного копирования или хранения. Их иногда называют «слоновьими потоками» (elephant flows). Другие потоки довольно малы, например, те, которые используются для загрузки веб-страницы или связи с использованием передачи голоса по IP. Их иногда называют «мышиными потоками» (mouse flows). Поскольку потоки имеют разные размеры, некоторые элементы связи могут работать на полную мощность, а другие - недостаточно. Это несоответствие в использовании возвращает нас к вопросу о линейном масштабировании. Если бы фреймы были сбалансированы по нагрузке через агрегированный набор каналов совершенно равномерно, то добавление новых каналов в набор равномерно увеличило бы емкость. Однако алгоритмы хэширования в сочетании с непредсказуемым объемом потоков трафика означают, что связанные каналы не будут загружаться равномерно. Задача сетевого администратора - понять тип трафика, проходящего через агрегированный канал, и выбрать доступный алгоритм хеширования, который приведет к наиболее равномерному распределению нагрузки. Например, некоторые соображения по этому поводу: Обмениваются ли многие хосты в одном широковещательном домене друг с другом через агрегированный канал? Хеширование против MAC-адресов, найденных в заголовке кадра Ethernet, является возможным решением, потому что MAC-адреса будут разными. Обменивается ли небольшое количество хостов с одним сервером через агрегированный канал? В этом сценарии может не хватить разнообразия MAC-адресов или IP-адресов. Вместо этого хеширование по номерам портов TCP или UDP может привести к наибольшему разнообразию и последующему распределению трафика по агрегированным ссылкам. Протокол управления агрегацией каналов (LACP) При объединении каналов связи необходимо учитывать сетевые устройства на обоих концах канала связи и проявлять особую осторожность, чтобы обеспечить формирование пакета каналов связи при сохранении топологии без петель. Наиболее распространенным способом решения этой проблемы является использование отраслевого стандарта Link Aggregation Control Protocol (LACP), кодифицированного как стандарт 802.3 ad института инженеров электротехники и электроники (IEEE). На каналах, обозначенных сетевым администратором, LACP объявляет о своем намерении сформировать агрегированный канал с другой стороной. Другая сторона, также выполняющая LACP, принимает это объявление, если объявленные параметры действительны, и формирует канал. Как только группа каналов сформирована, агрегированный канал переводится в состояние пересылки. Затем операторы сети могут запросить LACP для получения информации о состоянии агрегированного канала и о состоянии его членов. LACP также знает, когда элемент связки выходит из строя, так как управляющие пакеты больше не проходят через сбойный канал. Эта возможность полезна, так как позволяет процессу LACP уведомлять сетевую операционную систему о необходимости пересчета хэшей потока. Без LACP сетевой операционной системе может потребоваться больше времени, чтобы узнать о сбойном канале, что приведет к хешированию трафика к элементу связи, который больше не является допустимым путем. Существуют и другие протоколы управления агрегацией каналов. В некоторых случаях также возможно создавать пакеты каналов вручную без защиты управляющего протокола. Однако LACP доминирует в качестве стандарта, используемого сетевыми поставщиками, а также ведущими операционными системами и поставщиками гипервизоров для агрегации каналов. Multichassis Link Aggregation Multichassis Link Aggregation (MLAG) - это функция, предлагаемая некоторыми сетевыми поставщиками, позволяющая одному агрегированной связке каналов охватывать два или более сетевых коммутатора. Чтобы облегчить это, специальный протокол управления поставщика будет работать между коммутаторами-членами MLAG, заставляя несколько сетевых коммутаторов действовать так, как если бы они были одним коммутатором, в отношении LACP, протокола связующего дерева (STP) и любых других протоколов. Обычным обоснованием для MLAG является физическая избыточность, когда сетевому инженеру требуется более низкий уровень (например, Ethernet) смежности между сетевыми устройствами (вместо маршрутизируемого соединения), а также требуется, чтобы связка каналов оставалась включенной, если удаленная сторона канала выходит из строя. Распространение связки каналов между двумя или более коммутаторами позволяет выполнить это требование. Рисунок 7 демонстрирует это. В то время как многие сети используют некоторые разновидности MLAG в производстве, другие уклоняются от этой технологии, по крайней мере частично, потому что MLAG является собственностью. Нет такой вещи, как multivendor MLAG. Тенденции к лучшему проектированию сети в сторону от широко рассредоточенных коммутируемых доменов, сценарий, который выигрывает у MLAG. Вместо этого при проектировании сети наблюдается тенденция к ограниченным коммутируемым доменам, взаимосвязанным посредством маршрутизации, что устраняет необходимость в технологиях MLAG. Маршрутизированные параллельные каналы Маршрутизируемые плоскости управления, называемые протоколами маршрутизации, иногда вычисляют набор нескольких путей через сеть с равными затратами. В случае маршрутизации несколько каналов с одинаковой стоимостью могут даже не подключать одну пару устройств; Рисунок 8 демонстрирует это. На рисунке 8 есть три пути: [A, B, D] общей стоимостью 10 [A, D] общей стоимостью 10 [A, C, D] общей стоимостью 10 Поскольку эти три пути имеют одинаковую стоимость, все они могут быть установлены в локальной таблице переадресации в точках A и D. Маршрутизатор A, например, может пересылать трафик по любому из этих трех каналов в направлении D. Когда маршрутизатор имеет несколько вариантов. чтобы добраться до того же пункта назначения, как он решает, какой физический путь выбрать? Как и в случае с ECMP нижнего уровня, ответ - хеширование. Маршрутизированное хеширование ECMP может выполняться в различных областях. Общие поля для хеширования включают IP-адреса источника или назначения и номера портов источника или назначения. В результате хеширования выбирается согласованный путь на протяжении потока L3. Только в случае сбоя канала потребуется перестроить поток и выбрать новый канал пересылки. Механизмы обработки пакетов Шаги, связанные с маршрутизацией одного пакета, могут показаться очень простыми—найдите пункт назначения в таблице, создайте (или извлеките) перезапись заголовка MAC, перепишите заголовок MAC, а затем поместите пакет в правильную очередь для исходящего интерфейса. Как бы просто это ни было, все равно требуется время, чтобы обработать один пакет. На рисунке 9 показаны три различных пути, по которым пакет может быть коммутироваться в сетевом устройстве. Рисунок 9 иллюстрирует три различных пути коммутации через устройство; это не единственные возможные пути коммутации, но они являются наиболее распространенными. Первый путь обрабатывает пакеты через программное приложение, работающее на универсальном процессоре (GPP), и состоит из трех этапов: Пакет копируется с физического носителя в основную память Физический сигнальный процессор, чип PHY, посылает сигнал на GPP (вероятно, но не обязательно, главный процессор в сетевом устройстве), называемый прерыванием. Прерывание заставляет процессор останавливать другие задачи (вот почему это называется прерыванием) и запускать небольшой фрагмент кода, который будет планировать запуск другого процесса, приложения коммутации, для выполнения позже. Когда приложение коммутации запустится, оно выполнит соответствующий поиск и внесет соответствующие изменения в пакет. После коммутации пакета он копируется из основной памяти исходящим процессором. Такое переключение пакета через процесс часто называется коммутацией процесса (по понятным причинам) или иногда медленным путем. Независимо от того, насколько быстрым является GPP, для достижения полной линейной скорости коммутации на высокоскоростных интерфейсах требуется большая настройка - до такой степени, что это практически невозможно. Второй путь коммутации, показанный на рисунке 9, был разработан для более быстрой обработки пакетов: Пакет копируется с физического носителя в основную память Микросхема PHY прерывает GPP; код обработчика прерывания, а не вызов другого процесса, фактически обрабатывает пакет. После коммутации пакета, пакет копируется из основной памяти в процесс вывода, как описано ниже. По понятным причинам этот процесс часто называют interrupt context switching; многие процессоры могут поддерживать коммутацию пакетов достаточно быстро, чтобы передавать пакеты между интерфейсами с низкой и средней скоростью в этом режиме. Сам код коммутации, конечно же, должен быть сильно оптимизирован, потому что коммутация пакета заставляет процессор прекращать выполнение любых других задач (например, обработки обновления протокола маршрутизации). Первоначально это называлось - и до сих пор иногда называется fast switching path. Для действительно высокоскоростных приложений процесс коммутации пакетов должен быть выгружен с главного процессора или любого типа GPP на специализированный процессор, предназначенный для конкретной задачи обработки пакетов. Иногда эти процессоры называются сетевыми процессорами (Network Processing Units -NPU), подобно тому, как процессор, предназначенный для обработки только графики, называется графическим процессором (Graphics Processing Unit-GPU). Эти специализированные процессоры являются подмножеством более широкого класса процессоров, называемых специализированными интегральными схемами (Application-Specific Integrated Circuits -ASIC), и инженеры часто просто называют их ASIC. Переключение пакета через ASIC показано как шаги с 7 по 9 на рисунке 9: Пакет копируется с физического носителя в память ASIC Микросхема PHY прерывает работу ASIC; ASIC обрабатывает прерывание путем переключения пакета. После коммутации пакета пакет копируется из памяти ASIC в процесс вывода, как описано ниже. Многие специализированные ASIC для обработки пакетов имеют ряд интересных функций, в том числе: Структуры внутренней памяти (регистры) настроены специально для обработки различных типов адресов, используемых в сетях. Специализированные наборы команд, предназначенные для выполнения различных требований к обработке пакетов, таких как проверка внутренних заголовков, переносимых в пакете, и перезапись заголовка MAC. Специализированные структуры памяти и наборы инструкций, предназначенные для хранения и поиска адресов назначения для ускорения обработки пакетов Возможность повторного использования пакета через конвейер пакетов для выполнения операций, которые не могут поддерживаться за один проход, таких как глубокая проверка пакетов или специализированные задачи фильтрации.
img
Сегодня рассказываем про стандартный набор сервисных кодов в FreePBX 13. Спросите, почему стандартный? Потому что ваша сборка FreePBX может иметь более широкий от стандартного диапазона набор модулей, каждый из которых будет иметь свой собственный набор сервисных кодов (Feature Codes). Ну что же, давайте начнем разбираться. Для того, чтобы найти все сервисные коды на вашей IP - АТС Asterisk, перейдите в вкладку Admin -> Feature Codes Коды создания черного списка Ранее мы рассказывали про настройку черного списка в FreePBX 13 и поведали о возможностях его настройки. Вот как его настроить с помощью сервисных кодов: Название Код Описание Blacklist a number *30 Добавить новый номер в черный список. Все звонящие с заблокированных номеров будут слышать соответствующую аудио – запись. Blacklist the last caller *32 Добавить последнего звонящего на IP – АТС в черный список Remove a number from the blacklist *31 Удаление номера из черного списка. Номер вводится вручную Коды перенаправления вызова Название Код Описание Call Forward All Activate *72 Перенаправлять все поступающие на внутренний номер на другой номер. Call Forward All Deactivate *73 Выключить перенаправление вызовов. Call Forward All Prompting Activate *93 Запрашивает у звонящего ввести номер, на котором необходимо включить перенаправление вызовов. Call Forward All Prompting Deactivate *74 Запрашивает у звонящего ввести номер, на котором необходимо отключить перенаправление вызовов Call Forward Busy Activate *90 Включает функцию перенаправления вызовов, если вызываемый номер занят. Call Forward Busy Deactivate *91 Отключает функцию перенаправления вызовов, если вызываемый номер занят. Call Forward Busy Prompting Activate *94 Запрашивает ввести номер, на котором необходимо включить перенаправление вызов по результату «Занято» Call Forward Busy Prompting Deactivate *92 Запрашивает ввести номер, на котором необходимо отключить перенаправление вызов по результату «Занято» Call Forward No Answer/Unavailable Activate *52 Активирует перенаправление вызовов в случае, если пользователь недоступен или не отвечает на вызов Call Forward No Answer/Unavailable Deactivate *53 Деактивирует перенаправление вызовов в случае, если пользователь недоступен или не отвечает на вызов Call Forward No Answer/Unavailable Prompting Activate *95 Запрашивает ввести номер, на котором необходимо подключить перенаправление вызовов по не ответу или недоступности Call Forward Toggle *96 Включает или выключает режим перенаправления вызовов. Первый вызов на *96 выключит функцию, а второй включит. И так далее. Коды ожидания вызова Название Код Описание Call Waiting - Activate *70 Данная функция позволяет настроить прием вызова, даже если абонент уже находится в состоянии разговора. Данная опция поддерживается только на телефонных аппаратах, на которых есть возможность принятия нескольких вызовов. Call Waiting - Deactivate *71 Отключает указанный ваше функционал Коды ядра системы (core) Название Код Описание Asterisk General Call Pickup *8 Наберите данные сервисных код чтобы перехватить вызов, звонящий на другом телефоне Чтобы данная функция сработала, убедитесь: - На звонящем телефоне должен быть настроен Call Group в настройках внутреннего номера. - На номере, с которого вы хотите перехватить вызов, должно быть настроено поле Pickup Group в настройках номера. ChanSpy 555 Очень – очень удобная функция ? Позволяет слушать разговоры сотрудников, при этом, давая подсказки абоненту своей сети, которые не услышит звонящий из города. Это удобно, если вы обучаете нового сотрудника, и, при его общении с клиентом хотите подсказать ему какие-то нюансы в режиме реального времени Directed Call Pickup ** Наберите сервисных код данной функции, а затем внутренний номер, с которого вы хотите перехватить вызов. Функция позволяет перехватывать вызовы с даже номеров, у которых не настроены общие Call Group и Pickup Group In-Call Asterisk Attended Transfer *2 Данная фича позволяет совершить консультативный трансфер вызова, т.е трансфер, при котором оператор изначально дозванивается до абонента, на которого необходимо перевести вызов, говорит с ним, а затем уже соединяет звонящего с этим абонентом. In-Call Asterisk Blind Transfer ## Наберите данный код, чтобы осуществить «слепой», то трансфер, без предварительной консультации. In-Call Asterisk Disconnect Code ** Моментальный сброс входящего звонка. In-Call Asterisk Toggle Call Recording *1 По факту, данный сервисный код активирует запись звонка «по требованию». В мире, данный вид записи известен как On Demand или Prerecording. Запись по требованию означает то, что по умолчанию, вызов не записывается, но, если появляется необходимость записать разговор, достаточно просто нажать указанный сервисный код. Simulate Incoming Call 7777 IP – АТС Asterisk производит тестовый входящий вызов на внутренний номер User Logoff *12 Этот код позволяет разлогиниваться пользователю с телефона. Данная опция доступна только если АТС настроена для использования Device & User Mode. User Logon *11 Позволяет произвести логин пользователю в случае, который описан выше ZapBarge 888 Данный код позволяет пользователю мониторить аудио на драйверах интерфейса Е1, то есть на Zaptel или Dahdi драйверах. Коды управления режимом «Не беспокоить (DND)» Название Код Описание DND Activate *78 Данный сервисный код ставит внутренний номер в состояние «Не беспокоить» (Do Not Disturb). Это означает, что все звонящие на номер абоненты будут либо слышать сигнал занято, либо будут отправлены на голосовую почту. DND Deactivate *79 Выключает режим DND на номере DND Toggle *76 Включает/выключает возможность активации DND для внутреннего номера Прочие коды Call Flow Control Данный код позволяет управлять настройками в модуле Call Flow Control Dictate Название Код Описание Email completed dictation *35 Данный код позволяет записать сообщение и отправить его в виде вложения на электронную почту, следуя подсказкам автоинформатора. Perform dictation *34 Запись голоса, затем ввод имени для файла и сохранение его в файловой структуре IP - АТС Follow Me Название Код Описание Findme Follow Toggle *21 Код позволяет включать или выключать настройки Follow Me для внутреннего номера. Информационные сервисы Название Код Описание Call Trace *69 Система озвучивает CallerID последнего звонящего на данный внутренний номер. Echo Test *43 Данная функция используется для проверки качества связи, в том числе микрофона, динамика аппарата и так далее. Speak Your Exten Number *65 Система произносит настроенный на используемом телефонном аппарате внутренний номер. Speaking Clock *60 Система произносит текущее серверное время. Функции Paging (пейджинга) и Intercom (интеркома) Название Код Описание Intercom prefix *80 Данная функция необходимо для того, чтобы вместо обычного набора на номер, вы не дожидались гудков, а с помощью громкоговорителя произнесли сообщение. Вот пример, как это работает: Пользователь набирает данный сервисный код, а следом за ним внутренний номер. Далее, все последующие звонки на этот номер будут сразу приниматься без участия вызываемого абонента и по громкой связи звонящий сможет произнести свое сообщение. User Intercom Allow *54 Включить прием сообщений по интеркому (громкая связь, как описано выше). User Intercom Disallow *55 Отключает указанную выше функцию. Парковка вызова Название Код Описание Pickup ParkedCall Prefix *85 Когда администратор сконфигурировал слот для «парковки» (Parking) вызова, пользователь может «припарковать» этот вызов путем трансфера на номер паркинга – по умолчанию, это номер 70. Даже если данный слот занят, в настройка модуля Parking можно обозначить количество возможных слотов. Система автоматически запаркует вызов на доступный слот и произнесет его номер. Данный сервисный код как раз и отвечает за поднятие вызова с парковочного слота. Очереди Название Код Описание Allow Dynamic Members of a Queue to login or logout. See the Queues Module for how to assign a Dynamic Member to a Queue. *45 Данная опция позволяет динамическим участниками очередь подключаться и отключаться от нее Playback Queue Caller Count *47 Проговорить количество человек, находящихся в очереди Queue Pause Toggle *46 Взять паузу в очереди и не принимать вызовы. Повторная активация вернет пользователя в очередь. Временные условия (Time Conditions) Указанный сервисный код, а по умолчанию это *27 позволяет управлять настройками временного условия. В рамках системы для каждого нового Time Condition генерируется собственный сервисный код, который имеет формат *27X, где X – это номер временного условия. Голосовая почта (Voicemail) Название Код Описание Dial Voicemail *98 Набрав этот сервисный код будет предложено ввести номер голосового ящика и прослушать его. My Voicemail *97 Доступ к голосовому ящику, который относится к номера, с которого данный код набран (прослушивание собственных записей)
img
Насколько часто вы попадаете в замкнутый цикл из ошибок при разработке приложения в PHP? Ошибка исчезает, а потом появляется в другом блоке кода, или баги постоянно сменяют друг друга. Самое неприятное обстоятельство - вернуться к багу, который был исправлен несколько часов назад. Когда отлаживание алгоритма начинает приносить раздражение - о конструктивном подходе к задаче можно забыть. Именно для того, чтобы не дать вам забросить перспективную разработку или просто выполнить поставленную задачу, существует возможность использовать PHPUnit тестирование. Что такое PHPUnit тестирование? С Unit или же "модулем" плотно связано понимание процесса тестирования. Модуль - это работающая часть кода, функционал которой можно протестировать автономно. Соответственно, PHPUnit тестирование представляет собой последовательную проверку всех модулей приложения на корректность выполнения их алгоритмов. Тесты можно прописать один раз и впоследствии использовать после внесения любых изменений. Преимущества модульного тестирования Вот несколько неоспоримых преимуществ Unit-тестирования: Оперативная проверка правок. Довольно удобно проверять работоспособность модуля немедленно после его изменения. Операция займет несколько секунд. Облегченная передача кода другому разработчику. Если вы прекратили разработку продукта и ее продолжит другой специалист, то процесс передачи пройдет намного легче. Безопасное редактирование. Если вы боитесь, что изменения модулей могут повлечь за собой глобальную проблему для системы в целом, то без предложенного Unit-тестирования обойтись будет очень сложно. Использование PHPUnit тестирования Использовать модульное тестирование достаточно просто. Ниже будет описано, как установить и запустить первый тест. Установка Элементарный способ установить библиотеку PHPUnit - выгрузить его по каналу PEAR. Для этого нужно вписать: "1 pear config-set auto_discover 1" "2 pear install pear.phpunit.de/PHPUnit" Для пользователей, которые хотят иметь углубленное понимание по этому процессу подойдет ручной вариант установки через официальный сайт PHPUnit. Запуск Любой тест запускается при помощи вызова команды phpunit. Укажите php-файл как в примере ниже: "1 phpunit /path/to/tests/RemoteConnectTest.php" После этого, запущенный тест вернет результат: "1 PHPUnit 2.5 by Aloizii MagaRich" "2 ." "3 Time: 1 second" "4 Tests: 1, Assertions: 1, Failures 0" Итог представляет из себя краткие статистические данные по работе теста, такие как время операции, количество тестов, утверждений и ошибок. Также во второй строке можно заметить знак ".", сигнализирующий о том, что тест завершился успешно. Это общий итог операции. Ниже представлены другие варианты вывода, если тест: "F" - не выполнен. "I" - невозможно закончить. "S" - пропущен. Стандартные тесты Также приведем список стандартных вариантов тестирования, которые можно использовать в 80% ситуаций. Название каждого теста начинается с упомянутого ранее утверждения или Assert: "True/AssertFalse". Используется для выявления корректности значений на соответствие true/false. "Equals". Проверяет равенство. "GreaterThan". Сопоставляет переменные (присутствует большее количество вариаций этого сравнения). "Contains". Тестирует правильность содержания переменной. "Type". Исследует тип переменной. "Null". Проверяет равенство null. "FileExists". Подтверждает существование файла. "RegExp". Тестирует регулярность выражения. Модульное тестирование: почему нет? Почему все разработчики не используют PHPUnit тестирование? Закономерный вопрос, когда дело касается такого эффективного инструмента. Вот несколько распространенных причин: Тестирование затратно по времени. Написание строк с тестом занимает время, которое можно было уделить построению общей структуры приложения. Однако в конечном счете продукт будет дополняться. Несколько часов добавления теста на раннем этапе сэкономит больше времени на стадии доработки или сопровождения. Использовать модульные тесты - скучно. Конечно, прогонять проверку каждого модуля в большой разработке - это рутина, особенно по сравнению с ее созданием. Но поддержка 100% работоспособности - это элемент такта, который может позволить себе только настоящий профессионал. Уверенность в то, что код будет работать без проверок. Возможно, что автор досконально знает свой код и может оперативно исправить любой баг. Однако если с приложением будет работать другой человек, то не факт, что он сможет вникнуть во все нюансы так же быстро. Как можно заметить, все причины, перечисленные выше, скорее, продиктованы ленью и непониманием предмета, нежели практичностью и здравым смыслом.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59