Как работает серверный вызов в 1С

Программирование - Теория программирования

Клиент-серверная архитектура заложена в платформе изначально — со времен «1С:Предприятие 8.0». Однако при разработке на 8.0 и 8.1 о разделении кода на клиентскую и серверную часть можно было не заботиться, поскольку на клиенте (на толстом клиенте) был доступен тот же функционал, что и на сервере. Всё изменилось с выходом платформы «1С:Предприятие 8.2», когда появился тонкий клиент. Теперь на клиенте доступен один функционал, на сервере — другой. Клиент и сервер «общаются» между собой с помощью серверного вызова. Конечно, это усложнило процесс разработки, но с другой стороны – можно создавать более оптимальные (быстрые) решения, поскольку все сложные задачи выполняются на сервере.

Немного базовой теории

Перед тем, как перейти к содержательной части, договоримся о некоторых ограничениях:

  • Мы подразумеваем, что Вы знаете о существовании четырёх директив компиляции, доступных в модулях формы: «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста».

  • Все примеры будут опираться на работу «1С:Предприятие 8» в клиент-серверном режиме. Файловый вариант по сути является эмуляцией клиент-серверного режима, с небольшими отклонениями (для данной статьи это не критично).

  • В рамках этого материала рассматривается исключительно взаимодействие клиента и сервера 1С. Работа с базой данных, преобразование данных и прочие нюансы работы системы – это темы других статей.

Далее, освежим в памяти немного теории.

Директивы, в имени которых упоминается «Клиент», устанавливают ограничение на обращение к базе данных.

Процедуры или функции, написанные под директивой «Без контекста», не имеют доступа к контексту (данным) формы. Исходя из этой информации, легко представить ограничения директив по доступу к данным в виде следующей таблицы:

Директива Данные формы База данных
 &НаКлиенте +
 &НаСервере + +
 &НаСервереБезКонтекста +
 &НаКлиентеНаСервереБезКонтекста

 

Опережая вопрос «Для чего же директива с самым длинным названием, если она ограничивает и использование контекста форм, и обращения к базе данных?», напомню: любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

Отсюда делаем вывод: у методов, описанных под директивой «&НаКлиентеНаСервереБезКонтекста», единственным источником данных являются эти самые переданные параметры.

Не стоит забывать и про доступность вызова одних процедур и функций из других. Для этого стоит запомнить, что можно вызывать только те процедуры и функции, которые находятся под одноимённой (с родительским методом) директивой или под директивой, находящейся ниже (чем у родительского метода) согласно списку:

  • &НаКлиенте;
  • &НаСервере;
  • &НаСервереБезКонтекста;
  • &НаКлиентеНаСервереБезКонтекста.

То есть из метода, описанного под директивой «&НаКлиенте», можно вызывать процедуры и функции, описанные под любой директивой. А вот «из-под» директивы «&НаСервереБезКонтекста» можно вызывать только то, что описано под директивой «&НаСервереБезКонтекста» или «&НаКлиентеНаСервереБезКонтекста». 

Теперь про серверный вызов

Серверный вызов — это передача какой-то информации с клиентской части «1С:Предприятие 8» на серверную часть с целью вернуть обратно некий набор данных.

Самый первый серверный вызов инициализируется в момент начала сеанса работы 1С. То есть когда пользователь выполняет вход в информационную базу:

Серверный вызов в момент входа пользователя в информационную базу

Рисунок 1

«Оу! При чём тут Библиотека?!» — спросите Вы.

Всё очень просто:

Рисунок 2

Обратите внимание, что доступ к базе данных есть только на серверной части, а соединение между клиентом и сервером имеет ограниченную пропускную способность. Это и неудивительно – ведь соединение между клиентской и серверной частью может быть установлено даже по нестабильному низкоскоростному каналу связи (например, посредством мобильного интернета).

Кроме этого, передача данных между клиентом и сервером возможна только посредством серверного вызова.

Но, для того чтобы перейти к основной теме данной статьи, необходимо сначала разобраться – где будет выполняться программный код, написанный под определенными директивами. То есть на какой части приложения «1С:Предприятие 8» будут доступны процедуры и функции, описанные под директивами «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» и «&НаКлиентеНаСервереБезКонтекста»:

Рисунок 3

Видим, что на стороне клиента у нас будут доступны процедуры и функции, написанные под двумя директивами из четырёх, а на стороне сервера – под тремя из четырёх.

Сразу возникают вопросы: «Зачем такое многообразие и чем оно полезно?», «Как метод, описанный под директивой «&НаКлиентеНаСервереБезКонтекста» может выполняться и на клиенте, и на сервере?».

Сейчас мы постараемся понять особенности работы системы при использовании директив и почему необходимо уметь правильно использовать каждую из существующих директив компиляции.

И в этом нам помогут наши новые друзья, знакомьтесь!

Это процесс клиентской части приложения «1С:Предприятие 8». Он запускается на компьютере пользователя и сожительствует в оперативной памяти с другими процессами (38 вкладок браузера, поток аудио из социальной сети, telegram и другие). Может порождать серверный вызов.

Это процесс серверной части приложения «1С:Предприятие 8». Он существует на сервере 1С. Знает, какие клиентские сеансы в данный момент запущены, но самостоятельно не может инициировать взаимодействие с ними. Работает с клиентской частью только через полученный от неё серверный вызов.

А это серверный вызов. Как было сказано выше, он порождается процессом клиентской части и призван «прислуживать» ему. Он передает запросы со стороны клиента на сторону сервера, а также занимается транспортировкой данных с клиента на сервер и обратно.
 

Итак, давайте рассмотрим несколько особенностей работы программного кода в «1С:Предприятие 8», написанного под разными директивами.

Действие 1. Открытие пользователем формы с данными.

Рисунок 4

Рисунок 5

В момент нажатия Пользователем кнопки открытия формы из интерфейса, происходит передача управления на Сервер. По переданным параметрам получаются необходимые для построения данные из БД и происходит формирование контекста формы, который затем отправляется на клиентскую часть. У пользователя на экране отображается запрошенная форма.

Действие 2. Получение из открытой Пользователем формы дополнительных данных из Базы данных.

Рисунок 6

Получение этих данных может быть описано под двумя директивами — «&НаСервере» и «&НаСервереБезКонтекста». Рассмотрим оба случая.

Явление 1. Директива «&НаСервере»

Рисунок 7

При вызове процедуры или функции под директивой «&НаСервере» из формы со стороны клиента происходит «упаковка» всего контекста формы и отправка его на сторону сервера.

После выполнения метода на сервере, весь этот «пакет» транспортируется обратно. Таким образом, форма со всеми элементами и данными дважды проходит через самое узкое место системы.

Явление 2. Директива «&НаСервереБезКонтекста»

Рисунок 8

При вызове процедуры или функции под директивой «&НаСервереБезКонтекста» из формы со стороны клиента происходит передача на сторону сервера только тех данных, которые были указаны в качестве параметров. Обратно же передаётся только необходимая информация в уже подготовленном виде.

Таким образом, серверный вызов не несёт лишней нагрузки, и для передачи данных между клиентом и сервером потребуется меньше ресурсов.

Из примеров видно, что далеко не всегда оправдано указание директивы компиляции «&НаСервере» с точки зрения использования контекста (данных) формы на сервере.

Если возможно решить возникшую задачу путём отправки на сервер только определённого набора данных, то надо эту возможность использовать и описывать метод под директивой «&НаСервереБезКонтекста». Это позволит уменьшить нагрузку на серверный вызов, а также не занимать сервер обработкой и хранением ненужной в текущий момент информации.

Кстати, именно поэтому до версии платформы 8.3.7.1759 на сложных формах для управления видимостью элементов рекомендовалось использовать панели со страницами, а не свойство «Видимость». Только начиная с этого релиза отработка изменения видимости элементов стала выполняться на стороне клиента.

До этого момента при каждом изменении свойства «Видимость» происходил серверный вызов, как при использовании директивы «&НаСервере».

Но использование директивы «&НаСервереБезКонтекста» не является панацеей. Помимо нагрузки на серверный вызов, всегда необходимо задумываться ещё над одним параметром.

Действие 3. Обработка данных табличной части формы с получением дополнительной информации из Базы данных.

Рисунок 9

Явление 1. Построчная обработка табличной части на стороне клиента с организацией серверного вызова для получения дополнительной информации из базы данных.

Мы уже знаем – лучше использовать директиву «&НаСервереБезКонтекста».

Рисунок 10

Рисунок 11

При таком построении программного кода происходит множественное обращение со стороны клиента на сервер – по количеству элементов цикла, запущенного на стороне клиента.

Явление 2. Предварительная обработка табличной части на стороне клиента с целью подготовки требуемых к обработке на сервере данных и «упаковки» их в набор параметров. Затем передача этого набора на сервер для получения дополнительной информации из базы данных.

Используем всё ту же директиву «&НаСервереБезКонтекста».

Рисунок 12

В данном случае количество серверных вызовов сведено к минимуму за счёт предварительной подготовки параметров.

Большое количество текущих серверных вызовов может свидетельствовать о неоптимальном программном коде.

Избегайте создания серверных вызовов внутри цикла. Подготовьте набор параметров и единожды выполните его передачу для обработки на сервер. Если предполагается сложная обработка большого количества данных формы – передайте её полностью на сервер (при помощи директивы «&НаСервере») и выполните все действия на стороне сервера.

Если цель серверного вызова, созданного внутри цикла – получить какую-либо информацию из базы данных, то данная операция включает в себя запрос в цикле. А это очень негативно влияет на производительность всей системы в целом.

С директивой «&НаСервереБезКонтекста» вроде бы разобрались. Она нужна для того, чтобы уменьшить объем информации, передаваемой в рамках одного серверного вызова. Дополнительно разобрались с количеством текущих серверных вызовов – необходимо стремиться к их минимизации.

Давайте теперь попробуем разобраться, для чего нужна директива «&НаКлиентеНаСервереБезКонтекста».

Действие 4. Выполнение обработки данных.

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

Рисунок 13

Та-дам!

Рисунок 14

Для копирования у нас есть ксерокс. Но куда его поставить? На сторону клиента или сервера? Под какой директивой его разместить?

Как было озвучено ранее – любая процедура и функция поддерживает обработку информации, переданной в неё в качестве параметров.

 

Давайте для начала попробуем разместить копировальный аппарат на стороне клиента. Для этого описываем процедуру или функцию «Ксерокс» под директивой «&НаКлиенте». Тогда процесс клиентской части в любой момент сможет без проблем обратиться к ней и все действия будут выполнены в соответствии с программным кодом.

Но что произойдёт, если потребность в копировании возникнет на стороне сервера? Например, для подготовки данных, передаваемых на сторону клиента, потребуется сделать копию? Напомню – процесс серверной части не имеет возможности самостоятельно инициировать клиентские вызовы. 

Рисунок 15

Получается, что использовать директиву «&НаКлиенте» неправильно, а директиву «&НаСервере», как мы изучили ранее – нежелательно. Давайте посмотрим поведение системы при использовании директивы «&НаСервереБезКонтекста».

Рисунок 16

Вроде бы результат достигнут – и с сервера, и с клиента доступно копирование. Но для того, чтобы получить копию данных, используемых на клиенте, приходится делать серверный вызов. А это опять ведет к лишней нагрузке на соединение и временным затратам.

Избавиться от излишней передачи на сервер при сохранении возможности копирования на клиенте и на сервере можно при помощи директивы «&НаКлиентеНаСервереБезКонтекста».

Рисунок 17

Не углубляясь в детали, отметим, что метод, описанный под данной директивой управления, создаётся в двух копиях – и на стороне клиента, и на стороне сервера. Это позволяет выполнить необходимые действия там, где появилась потребность в них (клиент/сервер), без лишних серверных вызовов.

Конечно, вместо того чтобы выделять повторяющийся программный код, описывать его в отдельном методе под директивой «&НаКлиентеНаСервереБезКонтекста», можно поступить по-другому. Просто взять и написать один и тот же участок кода и в клиентской, и в серверной процедуре.

С точки зрения выполнения программы результат будет одинаков. Но объяснение «почему так не надо делать» – это уже совершенно другая тема…

Вместо заключения

В данной статье мы на наглядных примерах рассмотрели влияние различных директив компиляции на такое явление системы «1С:Предприятие 8», как серверный вызов. Как видно, основная причина для выбора правильной директивы – производительность транспортировки данных между клиентской и серверной частью.

Придерживайтесь при разработке следующих правил:

  • По возможности не передавайте контекст формы на сторону сервера
  • Минимизируйте количество текущих серверных вызовов
  • Длительные и ресурсоёмкие задачи запускайте на выполнение на стороне сервера (при возможности – в фоновом режиме).

Учитывайте потребность в доступности тех или иных видов данных, обоснованность передачи управления и не стесняйтесь при необходимости дробить процедуры и функции. И будет Вашему серверному вызову всегда легко, а Вы от пользователей Вашей программы получите «молчаливую благодарность»!

Так ли это важно думать об оптимизации? Тут имеет смысл вспомнить одну историю.

Программист Иван при доработке 1С на своём предприятии сделал ошибку в выборе директивы компиляции. Из-за неё длительность одного из серверных вызовов была больше возможной на полсекунды.

Пользователей, применяющих этот функционал, – 25 человек, и каждый из них за рабочий день в среднем совершает 110 таких операций. Всего впустую за рабочий месяц потрачено 28875 секунд (21 рабочий день * 25 человек * 110 операций * 0,5 секунды) = 8,02 часов.

Иван, каково тебе осознавать, что за месяц ты задолжал своему предприятию целый рабочий день?

О статье

Данную статью я написал для проекта «Курсы-по-1С» и она вызвала там достаточно высокий интерес. Для того, чтобы ещё больше начинающих (и не только) 1С-разработчиков могло получить пользу от прочтения данного материала, размещаем его полностью тут.

Читайте также и другие мои статьи: [ Наглядно о непонятном ] – Про «догмы» в 1СОтображение прогресса длительных операций в 8.3.10 (и более ранних версиях)Система взаимодействий в платформе 8.3.10.

Надеюсь, материал кому-то принесет пользу, а кого-то просто позабавит. Спасибо за внимание! :)

См. также

Вознаграждение за ответ
Показать полностью
Комментарии
1. Дамир Закиров (Dzenn) 80 18.11.17 13:32 Сейчас в теме
где-то это уже было
корум; AlexGroovy; Evil Beaver; KroVladS; +4 Ответить
2. Антон Грачев (Fragster) 767 18.11.17 14:34 Сейчас в теме
(1) курсы-по-1с рф/news/2017-03-09-how-server-call-works/
(не работают ссылки на национальные домены :) )
DrAku1a; KroVladS; +2 Ответить
3. Роман Уничкин (unichkin) 699 18.11.17 14:46 Сейчас в теме
Подумал что плагиат сначала - поставил минус, потом увидел что автор тот же) Спасибо, хороший материал.
4. Александр Крынецкий (echo77) 780 19.11.17 13:01 Сейчас в теме
Отдельный плюс за картиночки! Информация преподнесена легко и доходчиво.
kuzyara; kraynev-navi; +2 Ответить
5. Andrey Kubrik (Malfarion) 107 19.11.17 13:25 Сейчас в теме
Очень хороший материал, все правильно и понятно описано. Продолжайте.
6. Сергей Маслов (LexSeIch) 188 19.11.17 21:06 Сейчас в теме
Спасибо за статью. Читал Вас на курсах по 1С. Ждём других статей на актуальные темы...
7. script Мальчинко (script) 196 19.11.17 22:14 Сейчас в теме
В 8.3.11 появилась возможность передачи информации на клиент по инициативе сервера.
Так что статью нужно немного дополнить, мне кажется.
Передача информации по инициативе сервера
корум; BigB; +2 Ответить
8. Павел Ванин (pahich) 274 19.11.17 22:55 Сейчас в теме
(7) Спасибо за прочтение и замечание. Отмечу, что "возможность передачи информации на клиент по инициативе сервера" является механизмом системы взаимодействий, а не стандартной возможностью платформы. Поэтому, рассматривать ее в рамках данного материала не совсем правильно. Рекомендую к прочтению статью про систему взаимодействий, а также про длительные операции.
malenushka1; +1 Ответить
9. Игорь Фелькер (Brawler) 343 19.11.17 23:54 Сейчас в теме
10. ValeriTim (ValeriTim) 20 20.11.17 10:17 Сейчас в теме
Отличная статья! И наглядно и читать приятно, и что самое главное - понятно :) Держи звездочку!

Огромное спасибо.

А остальным только поучиться в оформлении :)
11. Plague Fox (A1ice1990) 58 20.11.17 10:29 Сейчас в теме
Неплохо для новичков. По хорошему стоит углубиться в тему и показать, что именно физически передается между клиентом и сервером (как форма запаковывается в xml).
У меня все лапки не доходят Wireshark'ом отследить.
12. Юрий Ульянов (spy-83) 177 20.11.17 13:07 Сейчас в теме
круто.
очень удобно и понятно! визуальное оформление + комментарии
+++
13. Алексей Папанов (El_Loco) 102 21.11.17 11:15 Сейчас в теме
Комиксы излишние на мой вкус. А текст стоящий.
20. Serj (Serj1C) 466 22.11.17 08:08 Сейчас в теме
(13) А мне больше картинки понравились
14. Саид Абушев (Абушев) 132 21.11.17 11:44 Сейчас в теме
А как же "ПредопределенноеЗначение" на клиенте?
Можно было в статью про него тоже.
17. Павел Ванин (pahich) 274 21.11.17 19:29 Сейчас в теме
(14) :) спасибо! Думаю, что есть много о чем ещё рассказать! Но в рамках данной статьи это будет перегруз...
15. Глеб Зломанов (Glebis) 7 21.11.17 17:12 Сейчас в теме
Почему не описано применение оператора "Знач", который позволяет не возвращать значение параметра с клиента на сервер и тем самым уменьшает размер возвращаемого результата серверного вызова?
18. Павел Ванин (pahich) 274 21.11.17 19:31 Сейчас в теме
(15) ну это уже особенность работы с данными, а не принцип работы серверного вызова.
23. Глеб Зломанов (Glebis) 7 22.11.17 09:31 Сейчас в теме
(15)
с клиента на сервер
*с сервера на клиент.
(18)
(15) ну это уже особенность работы с данными, а не принцип работы серверного вызова.
дык это же серверный вызов не возвращает данные, взятые на сервере по значению. Поэтому и считаю, что нужно рассказывать про это в рамках рассмотрения работы серверного вызова.
28. Павел Ванин (pahich) 274 22.11.17 22:36 Сейчас в теме
(23) Глеб, серверный вызов - транспорт. Что «положат», то и «повезет». Данная тема больше относится к (11) :)
16. Яков Коган (Yashazz) 2148 21.11.17 17:30 Сейчас в теме
Блин. Тоже сначала подумал, что плагиат... Да, неплохая и полезная статья.
19. Константин Хоров (user705522_constantin_h) 1 21.11.17 19:54 Сейчас в теме
Хорошая статья. Спасибо.
21. Андрей Краснокутский (Andry.Boris) 53 22.11.17 08:44 Сейчас в теме
Хорошая и полезная статья.
22. Денис Потапов (DPotapov90) 22.11.17 09:07 Сейчас в теме
Очень полезная статья, особенно для начинающих. Спасибо :)
24. Алексей (Alex) 98 22.11.17 09:31 Сейчас в теме
Очень понравился стиль передачи информации... респект!
25. Seer NaSA (SeerRM) 2 22.11.17 10:53 Сейчас в теме
Круто! Побольше бы таких статей!
26. Андрей Рекин (arekin) 22.11.17 11:22 Сейчас в теме
Роль картинок в этой статьей просто бесценна.
Спасибо за статью.
27. Михаил Крыловицкий (mikl79) 103 22.11.17 14:12 Сейчас в теме
спасибо, все очень понятно
29. Михаил Боровинских (zurapa) 23.11.17 06:50 Сейчас в теме
Статья шикарнейшая - понятно, даже самым маленьким.
А вот вывод из истории в конце не понравился. Оптимизация - это замечательно! Но, говорить, что программист кому-то задолжал?.. Если бухгалтер медленно считает, или продажник немного продаёт - значит ли это, что он задолжал?..
Если так важна скорость работы приложения, то 1С в сухую проигрывает другим решениям на java, PostgreSQL и прочему зоопарку технологий... И базы получаются куда живей и масштабируемей.
Основная прелесть 1С в быстрой удобной разработки и получения результата вчера, при довольно-таки хилом планировании, проектировании... И это играет куда большую роль... А оптимизация в свободное время.
Сразу написать оптимально не всегда получается. А порой не нужно, потому что делается обработка на раз, или два и срочно. Спасибо не скажут за оптимально написанный код за 8 часов и 1 час работы этой обработки, нежели написать за 30 минут, тяп-ляп и выполнение обработки займёт 3 часа... Вот в этом сила 1С. И говорить, что разработчик кому-то должен, за неоптимальный код совершенно не правильно. Генеральный директор компании "Рога и Копыта" вряд-ли лучше напишет.
32. Павел Ванин (pahich) 274 23.11.17 12:55 Сейчас в теме
(29) Михаил, спасибо за прочтение! :)

Цель выдуманной истории - дать пищу для дум на тему "а не стать ли мне еще лучше, чем я есть сейчас" :) Кстати, на эту тему уже холиварят в соседней статье про "Суррогаты" :)
30. Максим Б (Xershi) 284 23.11.17 12:35 Сейчас в теме
Из справки:
&НаКлиенте (&AtClient) — определяет клиентскую процедуру (функцию);
&НаСервере (&AtServer) — определяет серверную процедуру (функцию);
&НаСервереБезКонтекста (&AtServerNoContext) — определяет серверную процедуру (функцию), исполняемую на сервере вне контекста формы. Переменные не могут быть внеконтекстными. В таких методах недоступен контекст формы (включая данные формы). Допустимыми являются вызовы только других внеконтекстных методов. При вызове этих методов не выполняется передача данных формы на сервер и обратно. Применение внеконтекстных методов позволяет существенно уменьшить объем передаваемых данных при вызове серверной процедуры из среды клиентского приложения;
&НаКлиентеНаСервереБезКонтекста (&AtClientAtServerNoContext) — определяет процедуру (функцию), исполняемую в модуле формы на клиенте и на сервере, не имеющую доступа к контексту формы, данным формы, переменным, но имеющую доступ к процедурам и функциям общих модулей – серверных, не глобальных и серверных и клиентских одновременно. Сама процедура (функция) доступна для клиентский, серверных контекстных и неконтекстных процедур и функций модуля формы. Из серверных внеконтекстных методов формы допускается вызов серверных методов общих модулей;
&НаКлиентеНаСервере (&AtClientAtServer) — определяет процедуру (функцию), исполняемую в модуле команды, выполняемую на клиенте и на сервере, имеющую доступ к процедурам и функциям общих модулей – серверных, не глобальных и серверных и клиентских одновременно, не имеющую доступ к переменным. Сама процедура (функция) доступна для клиентских серверных процедур и функций модуля команды.

Почему только 4 описали?
31. Павел Ванин (pahich) 274 23.11.17 12:48 Сейчас в теме
(30) Максим, добрый день!

Аналогичный вопрос задавали мне в "первоисточнике" вот ссылка

Частично цитирую ответ:

"есть директива «&НаКлиентеНаСервере». Она доступна в модуле команды и по сути равна директиве «&НаКлиентеНаСервереБезКонтекста», так как в командах отсутствует контекст формы. Так что любой читатель, столкнувшись с потребностью использовать директиву «&НаКлиентеНаСервере», без труда разберется в её особенностях. Да и в статье указано, что рассматриваются директивы, доступные в модуле формы."

Спасибо за прочтение! :)
33. Максим Б (Xershi) 284 23.11.17 14:02 Сейчас в теме
(31) проверил!
Да действительно «&НаКлиентеНаСервере» выдает ошибку в модуле формы на 8.3.10.
Вот пример обработки кому охота это проверить.
Но я бы все таки оставил оговорку, что 5 метод не для формы!
Прикрепленные файлы:
ВнешняяОбработка1.epf
35. Павел Ванин (pahich) 274 23.11.17 15:33 Сейчас в теме
34. Вячеслав Алпатов (DonAlPatino) 24 23.11.17 14:33 Сейчас в теме
Вот такую бы статью, когда тонкий клиент появился. Помню куча времени ушла, чтобы работу директив осознать. И почему родную 1совскую документацию таким языком пишут, что ничего не понятно :-). Согласен с теме кто одобрил картинки. Картинку с кучей книжке таскаемых туда-сюда в явлении 1 можно на стенку повесить.
36. Максим Б (Xershi) 284 23.11.17 15:37 Сейчас в теме
(34) документацию пишут технари, которые это разработали. А те кто не в теме и не могут понять, что они имели в виду. Для этого такие статьи и разрабатывают, чтобы понизить уровень входа!
37. Элипсандр Эшман (ifilll) 27.11.17 16:47 Сейчас в теме
По поводу "Вместо заключения", есть другой вариант.

Плохой программист Джон сделал ошибку в коде, из-за которой каждый пользователь программы был вынужден потратить в среднем 15 минут времени на поиск обхода возникшей проблемы. Пользователей было 10 миллионов. Всего впустую потрачено 150 миллионов минут = 2.5 миллиона часов. Если человек спит 8 часов в сутки, то на сознательную деятельность у него остается 16 часов. То есть Джон уничтожил 156250 человеко-дней ≈ 427.8 человеко-лет. Средний мужчина живет 64 года, значит Джон убил примерно 6 целых 68 сотых человека.

Как тебе спится, Джон — серийный программист?
корум; +1 Ответить
38. Oleg Space (spacecraft) 27.11.17 16:56 Сейчас в теме
(37) 1,5 землекопа... где-то уже это было :)
39. Элипсандр Эшман (ifilll) 28.11.17 09:31 Сейчас в теме
В русскоязычном интернете это было на habr'е, в мире это уже давний мем, откуда он появился мне не известно, варьируется он деталями, а суть не меняется.
Оставьте свое сообщение