Як програмне забезпечення перетворюється з телефонії на біткойн
Кожен програміст там знайомий з роздуттям. Це скрізь: корпоративне програмне забезпечення, яке вимагає від підприємства змінити свої процеси (інакше "чому курси в Cornell мають 4-значні номери?"), Фінансове програмне забезпечення (будь-якого виду, крім HFT), фреймворки javascript (незважаючи на спроби повторного використання лівої клавіатури ), веб-сервер (привіт там джанго-проміжне програмне забезпечення), СУБД, ОС, драйвери USB, браузери, плагіни браузера, програми перегляду PDF, які насправді є системами публікації документів, телефонні програми.
Але команди розробників не мають "дошки завдань scrum" з прикріпленими до них повідомленнями, на яких написано "ДОДАТИ БЛУТ". Іранські сплячі осередки не подають запити на витяг проти проектів з відкритим кодом (коли спецслужби додають бекдори, як це було зроблено з Juniper, вони, здається, роблять це дуже елегантно, змінюючи попередні бэкдори - ніякого роздуття!). Отже, як програмне забезпечення роздувається? Хто за цим стоїть? Який процес винен?
Хто не за спиною

Знайшли винуватця.
Наївна точка зору полягає в тому, що роздуття походить від невідомих розробників, які не зовсім знають, що роблять. Ми всі писали згорнутий код, особливо коли ми недостатньо добре розуміли базові примітиви.
Але здуття великого, добре фінансуваного, значного програмного проекту, як правило, не є результатом безглуздості. Я думаю, що це випливає з простого зауваження, що продуктивність програмного забезпечення слідує за розподілом Zipf: велику частину коду, як правило, вносять лише декілька компетентних програмістів, тому безглузді не мають такої кількості можливостей для хаосу.
Тоді Хто є?
З мого досвіду, програмне забезпечення роздувається майже завжди походить від розумних, часто найрозумніших розробників, які технічно найбільш компетентні. Поєднуючи їх здібності з кількома вузько інтерпретованими обмеженнями, доброзичливими зусиллями врятувати день (зокрема, зберегти сьогодні за рахунок завтрашнього дня) та вуаля, ми маємо таку історію.
Казка про розширені структури
Мабуть, найкращий приклад роздуття, який мені передали, коли я працював у великій телекомунікації, включає флагманський телефонний комутатор. Це був монстр-перемикач, здатний керувати великим метрополітеном з мільйонами передплатників. У його основі якраз працював Unix, але ОС була трохи побічною, порівняно з жахливою реалізацією протоколу сигналізації, за чутками, якщо я добре пам’ятаю, приблизно 15 мільйонів рядків коду.
Припустимо, ви працюєте на базі коду такої великої, і ви хочете додати поле до структури. Скажімо, ви хочете додати поле до структури запису даних дзвінків (CDR), щоб вказати, чи викликана сторона входить до короткого списку друзів та сім'ї. Розумним завданням було б перейти до визначення структури та вставити "uint is_friend_fam: 1;" Це додало б додатковий біт до структури, і тоді ви можете робити все, що завгодно, у всьому коді.
Але коли код настільки великий, і коли ваш граничний час простою становить 2 години за 40 років, і якийсь польовий технік, який замінював резервний блок живлення ще в 1987 році, натиснув неправильний вимикач і пропустив половину вашого бюджету простою в районі Чикаго його товстими пальцями ви не можете просто змінити розмір структури. Оскільки це може змінитись там, де розподіляються структури CDR, скільки зайвого місця є навколо об’єкта CDR, і що відбувається з кодом, який помилково пише поза структурою. Це мало б невимовні, непередбачувані наслідки, жоден з них не мав б хороших наслідків.
Тож розробники комутаторів придумали абсолютно геніальну ідею. Я дам вам хвилинку, щоб подумати про те, що ви зробили б у подібній ситуації. Можна припустити, що код відповідає багатошаровій архітектурі, типовій для мережевого коду.
Добре, подивіться, чи відповідає ваше рішення наступному блискучому рішенню:
Шлях до пекла вимощений добрими намірами та розумними фокусами.
Отже, ви переходите до визначення структури CDR. Знайдіть поле, яке здається найменш важливим і найменш використовуваним в цілому, і переконайтесь, що воно взагалі не використовується нижче вашого шару в стеку викликів. Припустимо, CDR містить щось під назвою "uint inap_ain23", яке використовується виключно над вашим шаром. Ви не повинні уявляти, що таке inap_ain23 чи що робить. Потрібно зберегти значення, збережене в inap_ain23, коли потік управління проходить через ваш шар. Отже, під вашим шаром "inap_ain23" більше немає. Ви просто "переробили" це. Зараз це "is_friend_fam". Ви можете псевдонім так: "#define is_friend_fam inap_ain23", щоб полегшити вам роботу. І плюс до того, у вас є додаткові шматочки! Бонус!