Ключовим словом для роздумів про ці речі є абстракція .
Абстракція означає лише свідоме ігнорування деталей системи, щоб можна було думати про неї як про єдиний неподільний компонент при складанні більшої системи з багатьох підсистем. Це немислимо потужно - написання сучасної прикладної програми при розгляді деталей розподілу пам'яті та реєстрування розливу реєстру та транзисторних режимів було б можливим деяким ідеалізованим способом, але це незрівнянно простіше недумати про них і просто використовувати замість цього операції високого рівня. Сучасна обчислювальна парадигма вирішальним чином покладається на кілька рівнів абстракції: твердотільну електроніку, мікропрограмування, машинні інструкції, мови програмування високого рівня, API програмування для ОС та веб-програм, програмовані користувачем рамки та програми. Практично ніхто не міг осягнути всю систему в наші дні, і немає навіть можливого шляху, по якому ми могли б повернутися до такого стану речей.
Відворот сторони абстракції - це втрата сили. Залишаючи рішення щодо деталей на нижчих рівнях, ми часто приймаємо, що вони можуть бути зроблені з неоптимальною ефективністю, оскільки нижчі рівні не мають «Великої картини» і можуть оптимізувати свою роботу лише за допомогою місцевих знань, а не такі (можливо) розумний як людина. (Зазвичай. Насправді, компіляція HLL до машинного коду нині часто робиться краще машинами, ніж навіть самими обізнаними людьми, оскільки архітектура процесора стала такою складною.)
Питання безпеки є цікавим, тому що недоліки та «витоки» абстракції часто можуть бути використані для порушення цілісності системи. Коли API постулює, що ви можете викликати методи A, B і C, але тільки якщо умова X виконується, легко забути умову і бути непідготовленим до випадіння, що трапляється при порушенні умови. Наприклад, класичне переповнення буфера використовує той факт, що запис у комірки пам'яті призводить до невизначеної поведінки, якщо ви самостійно не виділили цей конкретний блок пам'яті. API лише гарантує щосьце відбудеться як результат, але на практиці результат визначається деталями системи на наступному нижньому рівні - про що ми свідомо забули! Поки ми виконуємо цю умову, це не має ніякого значення, але якщо ні, то зловмисник, який глибоко розуміє обидва рівні, зазвичай може керувати поведінкою всієї системи як потрібно і спричиняти погані речі.
У випадку помилок розподілу пам'яті особливо погано, оскільки виявилося, що це дуже, дуже важко керувати пам’яттю вручну без єдиної помилки у великій системі. Це можна сприймати як невдалий випадок абстракції: хоча з C можна зробити все необхіднеmalloc
API, зловживати їх просто легко. Частини спільноти програмування зараз вважають, що це було неправильним місцем для введення межі рівня в систему, і замість цього просувати мови з автоматичним управлінням пам’яттю та збиранням сміття, що втрачає деяку потужність, але забезпечує захист від пошкодження пам’яті та невизначеної поведінки . Насправді, основною причиною використання C ++ на сьогоднішній день є саме той факт, що він дозволяє точно контролювати, які ресурси купуються та вивільняються коли. Таким чином, основний розкол між керованими та некерованими мовами сьогодні можна розглядати як розбіжність щодо того, де саме визначити шар абстракції.
Те саме можна сказати і для багатьох інших головних альтернативних парадигм в обчислювальній техніці - ця проблема справді виникає весь час, коли потрібно будувати великі системи, оскільки ми просто не в змозі розробити рішення з нуля для складних вимог, які сьогодні є загальними. (Загальна точка зору в AI в ці дні є те , що людський мозок на насправді робить роботу як то - поведінка , що виникає через петлю зворотного зв'язку, в широкому масштабі , з'єднані між собою мережі і т.д. , а не з окремих модулів і шарів з простим, відведеної інтерфейси між ними, і що саме тому ми мали такий маленький успіх у моделюванні власного інтелекту.)