Обновить
52
0.1
Valentin Nechayev @netch80

Программист (backend/сети)

Отправить сообщение
Адовский

begin
  Work;
exception
  when X1 =>
     Y1;
end;


как по мне, ничем, кроме выбора и группировки ключевых слов, не отличается от

try
  Work;
catch X1 =>
     Y1;
end;


А вот то, что исключения в Ada не параметризованы — не переменные, а только типы — сильно усложняет передачу обстоятельств исключения.
> При наличие отступов, фигурные скобки не несут никакого дополнительного смысла.

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

    if условие1:
        ...
        if условие2:
            ... тут пара экранов всякого ...
        #end
    #end


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

В остальном — поддерживаю.
А почему Вы решили, что 120.0 будет обязательно double? Может, это single («float» в C и потомках). А может, вообще должно быть тут десятично точное значение и применена десятичная арифметика, чтобы никакие 1.1 не надо было округлять в мелких знаках.

120 — почему integer, а не short или long? И даже почему не double?

На примере констант это всё не видно, но как только начинаются реальные операции с данными, тип вдруг начинает иметь значение.
> на надо гуглить какое там апи у такого-то модуля — среда разработки сама адекватно всё подскажет.

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

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

Аналогично, для динамически типизированных языков есть средства линтинга, и профессионалы не выпускают код без него. Для Python я с ходу могу назвать 4 таких средства, для Javascript — 2, для многих других есть встроенные анализаторы (например, в Perl исключение по use strict генерируется именно таким контролем, а не ошибкой собственно рантайма типов).

Но есть таки принципиальная разница. Грубо говоря, для статически типизированных языков то, что вычисляется при компиляции, будет аксиомой при выполнении (объект типа X => у его методов будет именно та сигнатура, что у класса X). Для динамически типизированных это не обязательно — Python, Javascript позволяют подменять подложку реализации на ходу. Линтинг в принципе не способен отловить такие ситуации. Их запрет для возможности статического анализа — уже вопрос административной политики при разработке, а не собственно языка.

> не надо постоянно вручную проверять и преобразовывать типы, на случай, если на вход передадут какую-то дичь. Типичный пример: String( arg ).toLowerCase()

Да, фактор существенный. Мне в этом смысле понравились правила от Hola для Javascript: например, если требуется, чтобы на входе функции было число, пишется +x, а если строка — ""+x. Рантайм умеет опознавать эти ситуации и переводить их в конверсию типа.
Но вот lowercase это уже за пределами обычной возможности системы типов, надо делать свой враппер.

> типы вручную пишутся только там, где пользователю это важно — в остальных местах они выводятся автоматически

Пока что это достаточно малая часть таких языков. И даже в них автоматический вывод работает не всегда и не везде адекватно. А главное — что для уверенности программиста, что тип получился именно нужный, приходится его указывать явно.
Строгость типизации — понятие достаточно относительное. По сравнению с JavaScript, где преобразование между числом и строкой — норма, C++ строго типизирован, а по сравнению с Go, где даже если int 32-битный, то преобразовывать между int и int32 можно только явно — нестрого типизирован.
Поэтому, при рассмотрении строгости типизации лучше вводить несколько канонических уровней и сравнивать с ними:
1. Вообще никаких неявных конверсий (Go, или близко к нему).
2. Конверсии по умолчанию — между числами, или только явно разрешённые функции, или только в особых контекстах (основной компилируемый майнстрим, C++, C#, Java и т.п.)
3. Размыта граница между строкой и тем, что она представляет (JavaScript, Perl...)
4. Вообще всё есть строка, оптимизации есть, но это принципиально не отменяют (sh, Tcl...)
А это, считаем, бесплатная альтернатива Azulʼу для простых случаев :)
> Все, кроме гитоводов, привыкли к тому, что ветка растет от ствола или ветки потолще и включает все свои коммиты.
> И только в гите ветка — это именованная голова, а принадлежность коммитов определяется только по связям и работает лишь до первого мержа.

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

> Отсоединеннный коммит — это вообще уникальная гитофича, похожая до степени смешения на багу.

Оно существует только при особых режимах работы. Меня вот множественные головы напрягают больше :)

> Необходимость помнить, запушен ли коммит, после мерка вымораживает.

Этого не понял совсем. Сравнение с Hg или CVS/SVN? В любой распределённой системе локальный коммит может быть не запушен.

> Любовь к rebase есть любовь к фальсификации истории в угоду чисто эстетического профита от няшной линеечки коммитов.

«Эстетический профит» превращается в реальную потребность понимать, что происходило, при разборе через 1-2-5-10 лет, когда никто не помнит подробностей происходящего. И главное не линейка, а чёткость и законченность каждого отдельного действия, а также разделение действий по характеру (как минимум, ни в коем случае не смешивать форматирование, рефакторинг и изменение функциональности). Линейчатость удобна, но не критична.

> но посмотрев и сравив, выбрали и мерк и не пожалели ни разу.

Ну так не CVS же выбрали (имел я дело с одной конторой в 2015-м, принципиально сидящей на CVS — это был ужас). Но стоит таки оценить, как это повлияло на методы работы с кодом и с задачами.
> Фальсификация истории системой контроля версий с внесением ошибок туда, где их не было — это «вообще ни о чем»? Ну-ну.

Да, именно. Если убрать эмоции и само слово «фальсификация», которое уже содержит в себе эмоциональную оценку, то надо начать с признания, что истории, если она не зафиксирована в некоем авторитетном хранилище, вообще нет. Даже без SCM на локальных файлах можно написать любую историю, а с distributed SCM любого вида это становится тривиально — всегда есть возможность взять другую ветку или рабочую копию и повторить начисто. Поэтому вопрос должен стоять так — чего мы хотим от истории? Видеть коммит промежуточного кривого состояния каждый раз, когда программист отшёл в туалет, или всё-таки набор логически цельных изменений? Не знаю, как у вас, а вокруг меня второе таки преобладает.

> Это еще почему? Вы после слияния конфликты не правите, тесты не прогоняете, упавшие сразу не чините?
> Полностью автоматического слияния в общем случае не бывает, ручные правки являются частью процесса.

Именно потому, что ручные правки при merge предполагают правки именно конфликта, а не произвольного места.
Если у вас в foo.h поменялось getFoo() на getFoo(FooContext*), это не повлияет на неправильное использование уже несуществующего getFoo() в bar.c.
Чаще (по тому, что я видел) делают таки правки после мержа, чтобы разделять логически разные действия в разные диффы. Но это требует возможности отменить тестирование самого merge commit.

> Вот только если вы те же самые коммиты склеите ребейзом — вы получите целую цепочку нерабочих коммитов и заведомо неверный результат поиска места ошибки, если она всплывет не сразу.

Именно поэтому я и рекомендовал при таком ребейзе надо править нерабочие коммиты, а не делать правку им вдогон.
Это не настояние на ребейзе вместо мержа или наоборот. Это именно как сделать такой ребейз беспроблемным для будущего поиска.

> У гита есть аналог cherry pick но он ссылку на оригинальный коммит добавляет только опциально и только в комментарий.

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

> И какой смысл рассказывать про чудо-индекс, если хороший тон — это маленькие коммиты, а mq в мерке кроет индекс как бык овцу?

Не кроет он никак индекс, потому что для представления патча для mq он уже должен быть чистым от прочих изменений.
> Так а чем именно? После 3.8 его практически не правили.

Я про «до».

> Ну это, в гите наличие индекса существенно усложняет чуть менее, чем весь интерфейс. А пользы — чуть.

Ну вот тут и видна фатальная разница. Для меня это не «чуть», это критично. И соответственно ценность всех остальных механизмов, если они это не поддерживают, снижается в разы.

> Таким образом, без дополнительных телодвижений новые головы просто-напросто не выпинываются.

OK, принято. Я не помню, откуда взял про передачу всех голов — скорее всего, это утверждал один из апологетов Hg, а я не проверил. Осталось не разрешать их локально по умолчанию :)
> Да и нет,

Я не говорил о публично выставленной части (тут скорее надо сослаться на концепцию Phases), хотя и тут есть разные мнения — иначе бы в `git help rebase` не было секции «Recovering from upstream rebase». Но именно свою локальную работу привести в порядок, по-моему, обязательно.

> вероятно, речь об угадывании rename/copy вместо записывания

Тут я тоже удивляюсь, что мешает в Git добавить запись этих данных, если автор явно хочет. Вероятно, они не считают частный случай настолько существенным (над частичным разбросом содержимого в разные файлы), а детект по содержимому сейчас работает достаточно неплохо (и для log, и для merge).
> Не совсем понятно, чем именно вас не устраивает hg histedit

До последних версий (3.8? я сбился с историей нумерации) он был непригоден. Сейчас надо перещупать заново.

> частичный коммит реализован искаробочным плагином record

1) deprecated 2) принципиальная разница в отсутствии явного индекса, я не могу перед коммитом посмотреть, что же получилось. (В описании вообще подтасовка — «interactively select changes to commit» не подразумевает самого коммита, но он происходит.) Да, можно потом корректировать историю, но это много лишних движений. Ещё и легко ошибиться (strip без --keep потеряет изменения).

> hg shelve (правильно, это тоже искаропки)

И снова без возможности учесть индекс. Как-то его, я смотрю, в Hg совсем не оценили, и всё сравнение в итоге утыкается в него.

> Mercurial же просто записывает всё за пользователем.

Я бы оценил эту фичу в варианте 1) автоматически не включена, 2) препятствует внешнему обмену, пока не указана конкретная голова или не осталась одна. Но в текущем варианте это источник тяжёлых диверсий.
> Это в каком виде? В виде, не соответствующем реальности? А зачем? Какой прок от недостоверной истории?

Должна ли история сохранять все опечатки и душевные метания программиста? Я лично живу в мире, где лучше, что автор выставляет некоторое «предложение», и только с момента его принятия оно становится частью истории, независимо от того, какие внутренние процессы привели к нему.

Ссылки на статьи после этого — забавны, но не имеют отношения к текущему обсуждению, и, по-моему, вообще ни о чём. Если требуется рабочее состояние после каждого коммита, то это должна обеспечить автоматизированная проверка. Например, у нас к Gerritʼу для этого был прикручен Jenkins. Если коммиты были отправлены под другую версию, и корректировка под новое API была сделана потом одним рывком, а не на каждый участвующий, то проверка не прошла, и это уже вопрос административный, допускать такое вообще или нет. Но хуже то, что с merge, которое предложено взамен, если это именно merge, то по любому получим неработающую версию после слияния, а если тут же править результат слияния, то это будет уже не честное слияние, а доработка. По-моему, тут идеального выхода нет вообще.

> Оно всего-лишь создаёт скрытую локальную ветку для незаконченной работы. Это даже в SVN не сложно реализовать,

Локальную — в SVN?

> Чувствую у вас не редки ситуации, когда у вас на машине «всё работает», а у того, кто пульнёт ваши изменения, всё сломается, ибо вы то забыли закоммитить, то закоммитили чего лишнего.

Бывают — там, где нет автоматизированной проверки коммита. (Сейчас я расслабился, потому что основную компоненту веду один. Раньше за счёт центрального Gerrit с code review такое не проходило, и приходилось заботиться сразу.) Но доля таких ситуаций всё равно в разы меньше, чем грязи в процессе, когда вначале коммитится со всеми локальными мотлохами, а потом они вычищаются (а часто даже тупо забываются, пока не всплывают на продакшене). Так что чисто статистически от этого тоже польза.

> Я так и не уловил этого тонкого различия. Почему вы противопоставляете часть (голова) целому (ветка)? Ветка метро — это всё множество последовательно соединённых станций, или только лишь конечная станция?

Потому что Hg позволяет быть нескольким безымянным головам одновременно. А это уже в случае метро не одна ветка, а несколько, вплоть до всей сети.

> Ничего удивительного. Git — это этакий прокачанный CVS, который отслеживает не отдельные файлы, а группы файлов, и плевать он хотел на историю их содержимого (которое кочует между файлами).

Я не понял логики этого замечания. CVS следил за каждым файлом отдельно, а Git, оказывается, «прокачанный CVS», но за одним файлом уже не следит.
Вот именно, что эти аналоги очень неполные.

> ShelveExtension

Нет аналога --keep-index. Также непонятно, относится это только к файлам, которые уже под контролем, или вообще ко всем. В Git это управляется опциями, можно stashʼем убрать вообще всё, можно только то, что в известных ему файлах.

> hg commit --interactive

В Git я могу набирать индекс по частям и постепенно, анализируя, что получилось, возвращая части и снова добавляя, сравнивая диффы между рабочей копией и индексом, и что попало в сам индекс, могу что-то подправлять прямо в самих диффах (в варианте add -e), могу сложить его в stash. (Как правило, нужно в таких диффах удалять дополнительную отладку или специфические локальные опции, но иногда бывает и то, что должно идти в следующий коммит.)

hg commit --interactive это набор подмножества патчей одним махом. Если они меня не устраивают в таком виде — начинается некрасивая работа по бэкапу файлов и ручной вычистке ненужного.

И описанные тут «могу» и «приходится вручную» относятся к реальным и регулярным случаям.

> А про «легче переходить», скорее всего, обычно имеется в виду более согласованный синтаксис команд в Mercurial,

Аргументация сторонников Hg тут, как правило, была иной — им нравилась хотя бы частичная эмуляция стиля линейной последовательной истории, начиная с номеров коммитов для локального репо. Синтаксис команд звучал как аргумент, но не для лёгкости перехода. Я не психоаналитик, чтобы раскапывать тут реальные связи, поэтому ограничился наблюдаемым.
Основные и чрезвычайно ценные вкусности Git — это interactive rebase, index и stash.

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

Stash позволяет формировать внятную последовательность изменений в типичном (в моих краях и задачах) случае, когда, начиная какую-то мелкую правку, обнаруживаешь, что вслед требуется цеплять что-то более крупное, а там и докатываться до больших рефакторингов. Изменения, которые стронули лавину, откладываются, и так может быть несколько раз. И даже без этого, после приёма новых чужих изменений из аплинка, он помогает их аккуратно скрестить. (Аналог — говорят про queues, но это только частичная замена, и говорят, что их выпилят за концептуальную несовместимость.)

Index (с add -i, add -e) или помогает stashʼу, или позволяет отправлять только часть изменений; например, в моих задачах типично, что я навешиваю в локальных функциональных и интеграционных тестах расширенную отладку, которая не должна попадать аплинку; также могут быть адаптации под локальную платформу, и т.п. (Замечу, что Tortoise клиенты дают такое для всех поддерживаемых SCM; но «из коробки» в Hg и SVN этого нет.)

Теперь про «ветки» в Hg — тут есть ряд злобных засад. В Hg понятие ветки это смешение нескольких разнородных сущностей в одну не сильно приятную (именно из-за смешения) кашу:
  1. «Голова» процесса развития, которых может быть несколько в пределах одной рабочей копии или «ветки» в другом понимании. При операциях push, pull передаются все эти головы. В некоторых местах это называется напрямую словом head.
  2. Некий установленный локальным режимом тег под названием «branch», который приклеивается к каждому новому changesetʼу, и больше ничего не делает. Именно его чаще всего называют «веткой».
  3. Полный пучок п.1, между которыми тоже можно переключаться.


Основное неприятное тут то, что именно авторы Hg принципиально поддерживают этот бардак. (И я ещё не вспомнил bookmarks, которые тоже ветки, но иначе.) Прямая цитата из родной вики: «The term branch is sometimes used for slightly different concepts. This may be confusing for new users of Mercurial.» Но в результате те, кто хвалят ветки Hg за их персистентность, имеют в виду только ветки-2 и только факт явной пометки в истории. Но на самом деле эти пометки не являются ветками — это теги ченжсетов. (А почему именно один такой тег и только branch, если механизм таких тегов в принципе существует, почему он не расширяем?)
Аналог «веток-2» (тегов коммитов) для Git делается не прямо, но через pre-commit hook можно редактировать сообщение коммита. Но если такое делают, то лучше вписывать не какой-то непонятный branch name, а ссылку на тикет, в рамках которого это делается; на моей прошлой работе такое делали — такой хук вылавливал номер тикета из имени локальной ветки (в смысле Git).

По всему описанному, для меня пробы работы под Hg закончились только возмущением «и как в этом бардаке можно что-то делать?», после продирания через грязные коммиты с посторонним мусором, зависшие головы и невозможность без дикого напряга привести всё это в порядок (в итоге я перекинул всё в Git и успокоился). Некоторые из этих возможностей Hg, однако, выглядят иногда полезно. Безымянные головы (но при условии — только в рабочей копии, и нельзя делать push, пока их больше одной, и не по умолчанию). Или автоприклеиваемые к сообщению коммита строки (лучше — набор с именами и содержимым). Но и без них отлично работается.

И ещё одно — очень часто говорят, что на Hg легче переходить после CVS и SVN, чем на Git. Мне получилось строго противоположно — после CVS Git оказался лёгким и простым, а с SVN и Hg резко не сложилось.
> вместо screen — лучше tmux — ctrl+a я использую часто, а вот ctrl+b — не используем и хорошо подходит для контрольной последовательности.

Всё почти наоборот. screen'у элементарно заменить переключающую последовательность — опции типа -e ^ba (для Ctrl+B) и так далее; есть и умолчание для screenrc. Я не пользуюсь Ctrl+A, у меня в зависимости от места Ctrl+F, B, N, местами ещё более редкие.

tmux'у с некоторых пор это тоже делается, но сильно более громоздко — например, для новой сессии надо сказать

tmux new-session \; set-option prefix ^n


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

Ещё из специфичного, что нужно мне — при общем utf-8, есть контексты, в которых надо запускать терминалы под koi8. Screen умеет перекодировки в обе стороны (и я ему ещё и koi8-u добавлял), tmux — нет.
> Также напрашивается очевидный вывод, что в настоящее время не стоит использовать glue record для домена .RU

Совсем не использовать не получится — где-то они таки должны быть. И использовать для своего домена — совершенно нормально.

Скорее всего, система формирования зоны .ru допускает, что регистраторы домена 2 указывают glue-записи для домена 1. По-нормальному glue-записи внутри какого-то домена могут указываться только регистраторами этого же домена, независимо от того, кто иной использует их как NS. Это не гарантия полного избавления от проблемы неверных IP адресов, но позволяет значительно упростить диагностику и локализацию. В .ua, для сравнения, эта политика форсирована, как и (насколько я помню) в .com, .org и аналогичных местах.
Проблему следует лечить непосредственно у администратора зоны, регистратор тут не поможет, если чужие glue-записи будут залипшими из данных другого регистратора.

Специфика BIND9 здесь может быть в том, что он воспринимает glue-записи от чужого домена в additional, но использует их только для дальнейшей рекурсии, не сохраняя в основном кэше, и внутренне привязывая только к тому домену, для которого они были получены. Это лучше, чем более ранняя тотальная анархия с приёмом любых подобных записей (ещё лет 8 назад выяснение «откуда взялась эта запись в кэше?» могла выливаться в полноценный детективный роман), но по сравнению с тотальным игнорированием чужих glue-записей может давать описанные проблемы. К слову, указание BIND9 недостаточно подробно (например, существенные изменения в алгоритме были с переходом 9.3 -> 9.4).
Мне тут подсказали, что техзадание обычно пишут тем же методом. Так что всё в порядке.
Сначала общее впечатление от статьи: непонятно, зачем она в таком виде. Кто с этой тематикой не знаком в принципе — ничего в описанном не поймёт. Кто знаком — будет активно возражать. Большинство упомянутых утверждений следовало бы вводить постепенно, по ходу. Кстати, в этом случае и контекст помогал бы их правильно и уместно сформулировать именно для своей цели.

> недостатком является большое зависимости производительности процессора от шины

В статье очень много таких странных грамматических несогласований, и орфографических ошибок («она пригодиться нам в статьях с практикой.»). А тут вообще непонятно, что имелось в виду:

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

«Инструкции для таблицы прерываний» это вектора прерываний, что ли? Тогда они обычно не инструкции, если не применён стиль i8080. Если же данный стиль — то лучше было описать в статье с реализацией прерываний.

Рекомендую тщательно вычитать и исправить.

По отдельным пунктам:

> CISC — Complex Instruction Set Computer — ее особенность в увеличенных количествах действий за инструкцию.

Основные признаки CISC:
1. Ориентация на написание ассемблерного кода человеком, или компилятором, транслирующим типичные операции ЯВУ дословно, без их переработки. Во времена слабых компиляторов (считаем, до середины 80-х) это неизбежно.
2. Как следствие (1) — стремление к ортогональности операций и адресации операндов, и предоставление средств для идиоматических действий типа «доступ по адресу, снимаемому с вершины стека».
3. Экономия памяти под инструкции. Этот признак не имеет причиной концепцию CISC, но современен ему (основные разработки шли в условиях дорогой, но быстрой памяти, сравнимо со скоростью процессора). Отсюда — обязательность разной длины инструкций.

Яркие примеры — PDP-11, VAX, M68K. Упоминать здесь x86 не совсем адекватно. У x86, например, у основного блока команд допускается не более одного операнда в памяти (исключения вроде MOVS крайне редки). В этом смысле, x86 — полу-RISC. Ещё жёстче это, например, в линии S/360...z/Arch в блоке RX-команд — в памяти только второй источник, но не первый источник, он же приёмник.

Просто о количествах действий тут говорить нельзя. Например, можно увеличить указатель стека, сняв один из операндов со стека, но не делают инструкции, в которых увеличивается указатель стека, когда стек вообще не участвует. Линия с явным заданием нескольких одновременных действий это EPIC (многими считается как вариант VLIW), но это другая линия.

> Reduced Instruction Set Computer — Архитектура с уменьшенным временем выполнения инструкций (из расшифровка RISC можно подумать, что это уменьшенное количество инструкций, но это не так)

Не так, но и не по-вашему. RISC это уменьшенная сложность одной инструкции. А по второй расшифровке — Rational Instruction Set Computer — оптимизация построения на типичные применения с отбрасыванием лишнего, и на современные компиляторы с их логикой работы.
Время выполнения одной инструкции может быть в типичном случае даже выше, за счёт подъёма всех до 4-5 тактов, но это компенсируется простотой построения параллельного исполнения.

> Архитектура фон Неймана

Есть и другой метод называния — принстонская архитектура (а фон Неймана — общее у принстонской и гарвардской).

> У данной архитектуры большим недостатком является большое зависимости производительности процессора от шины.

Это существенно только для реализаций, исполняющих всю команду за один такт. Такие используются, да, в очень «мелких» реализациях, но как только мы выходим за пределы встраивания процессора в двухкопеечную монету, общая шина к памяти перестаёт быть узким местом. На нынешнем x86 она не является таковым. На мелких RISC конфликты доступа за память только немного притормаживают конвейер.

> В x86 регистров достаточно мало.

Было мало. В современных имеем, даже считая 32-битку,
1) 8 основных (eax, ebx, ecx, edx, esp, ebp, esi, edi)
2) 8 FP или MM
3) 8 XMM/YMM/ZMM
4) 8 предикатных (K0-K7) (AVX512)
и значительную часть целочисленных операций можно использовать на них всех, и тем более эти регистры можно применять для временного сохранения значений без доступа к памяти.
В 64 битах добавляется ещё 8 основных и 8 XMM/YMM/ZMM. Это уже больше, чем 32.

Пока остановился. Ещё раз сводное — в таком виде статья просто бесполезна. Лучше всё описанное вводить постепенно, и на реальных примерах. Потом, после всего цикла, уже можно сделать что-то похожее на эту статью в качестве резюме, но тогда и формулировки каждого пункта будут совсем другими.
> обязан регулярно слать подтверждения своей готовности принять данные (т.е. сведения о состоянии окна приёма).

Только при изменении этого окна.

> надо послать ей «нулевые данные»

«Нулевые данные» невозможно послать средствами уровня сокетов. И противоположная сторона не обязана это подтверждать (она воспринимает такое просто как дежурный ACK). Единственный гарантированный способ получить ответ другой стороны — послать реальные данные.

В случае TCP — только на уровне сессии можно это лечить надёжно и кроссплатформенно (keepaliveʼами протокола уже выше уровнем, нежели TCP, тогда можно вводить собственный таймаут).
> Однажды решил он обыграть хостера в «интеллектуальном поединке».

Универсальный вариант для решения таких проблем — выделение времени на нестандартные/дополнительные хотелки по принципу token bucket.
Например: в целом на всех клиентов — до полчаса в рабочий день от каждого саппортера, если нет авралов, но до 2 часов в день в пике.
На одного клиента — до 5 минут в день, в пике до часа, и если есть время из пункта в целом на всех клиентов. Потратил свой час (подсказывает кэп) — дальше по 5 минут в день, если будет тратить каждый день:) Пул запросов рассматривается как очередь (FIFO), запросы «протухают» за неделю, если не подтверждены повторным сообщением от клиента.

Преимущества такого подхода:
1. Чётко прописанный алгоритм (можно опубликовать и вывесить на сайте).
2. Гибкая буферизация перегрузки за счёт постепенного вползания в перегрузку, которая детектируется простейшими методами и поддаётся статистическому контролю.
3. Обучение юниоров и интернов на реальных ситуациях с реальными людьми :) (из можно и до половины времени направлять на решение этих доп. вопросов)

И тот «хитрож…мудрый» клиент в этом случае просто получил бы часть такого резервного времени, если есть. Если он один такой — ну, молодец, получил бонус и дал саппорту чуть больше опыта. Если бы было много — он бы столько ресурсов не получил.

Что не решается, очевидно — проблема плачей типа «ну и что, я самый больной клиент на свете, мне нужно варенье в первую очередь», нужна сила воли, чтобы удержаться от перекосов (ну или желание сделать таки выбор по своим критериям, а не по громкости плача). И начальство может говорить «это же значит, что сотрудники недозагружены», тогда надо тщательно объяснять, что разумная недозагрузка это как раз нормально, потому что даёт гибкость и перспективу.

> с другой — все эти «мелочи», когда они идут потоком, ну просто нереально отвлекают сисадмина.

Всё равно надо закладывать резерв времени на непредвиденное, и если нет явных внутренних проблем, то пусть это время пойдёт на клиента.

Информация

В рейтинге
3 468-й
Откуда
Киев, Киевская обл., Украина
Дата рождения
Зарегистрирован
Активность