Чи справді великий-O актуальний при роботі в галузі?


65

У кожному інтерв'ю, в якому я був, я перевіряв математичний аналіз складності, включаючи нотацію великого рівня.

Наскільки важливий аналіз великого виходу для розвитку в промисловості? Як часто ви його справді використовуєте, і наскільки потрібно мати відточений спосіб мислення?


5
@ MM01 Я вивчав це в середній школі та університеті. Хоча я визнаю це складовим елементом знань програміста, я ніколи не використовував його в жодній своїй роботі.
systempuntoout

27
Яку саме галузь ви задумуєте, запитуючи це? Ви пишете контрольний код для місячного ровера або платформи для блогів?
Tim Post

14
@systempuntoout, ви ніколи не вибирали алгоритм, який був швидшим за інший, тому що він був швидшим?

3
@ MM01 - Якщо ви боретеся з цим, одне з найпростіших (хоча і над спрощеними) пояснень можна знайти тут: rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation
Tim Повідомлення

6
@Systempuntoout, розуміння та використання O-позначень не передбачає жорсткого математичного доказування, але може передати простим виразом те, як поводиться ваш алгоритм. Якщо вам потрібно сортувати в 1D, вам потрібен алгоритм O (n log n). Якщо ви хочете реалізувати число Фібоначчі, ви вибираєте ту, яка працює в O (n). Навіть якщо ви прямо не говорите це вголос, це все-таки скорочена версія кількості циклів і рекурсій, яка надзвичайно корисна. Економить багато слів. (А для нитких - так, k також важливий, якщо він значно великий чи малий).

Відповіді:


76

Моє запитання: наскільки цей тест є актуальним для розвитку в промисловості?

Добре розуміння теорії складності обчислювальної техніки (наприклад, велика нотація O) є важливим для розробки масштабованих алгоритмів, додатків та систем. Оскільки масштабованість має велике значення для обчислень у промисловості, велике позначення O теж є.

Як часто ви користуєтеся ним реально і наскільки потрібно мати відточений спосіб мислення?

Залежить від того, що ви маєте на увазі під "реально користуватися цим". З одного боку, я ніколи не надаю офіційних підтверджень складності обчислень для програмного забезпечення, яке я пишу. З іншого боку, більшість днів мені доводиться мати справу з програмами, де масштабованість є потенційною проблемою, а дизайнерські рішення включають вибір (наприклад) відповідних типів колекції виходячи з їх складних характеристик.

(Я не знаю, чи можна послідовно реалізовувати масштабовані системи без чіткого розуміння теорії складності. Я був би схильний думати, що це не так.)


+1, оскільки принципи важливі. З мого досвіду галузі, його врахування слід враховувати, а не на чомусь зупинятися. При цьому сказано - це вас запитують про порівняння (прикладу) вставки списку проти вставки масиву або сортування міхура проти кваксорту, тоді інтерв'юер має на меті визначити ваші знання. І отримайте оцінку, якщо ви навіть думаєте про складність / час роботи / масштабованість / продуктивність. Якщо ви не можете / не можете думати про ці речі, знайдуться деякі роботи, які ви не знатимете, як робити добре. Рідкісний, але час від часу виникає.
quick_now

6
Що ж, можливо, так це і стрільба по цілях у темній темній темряві. Подавши достатню кількість куль, врешті-решт потрапите в око бику. Потім, випробовуючи результат різних факторів проектування та реалізації, в результаті чого наступного разу буде потрібно менше куль. Можливо, погана аналогія, але вона точно описує спосіб написання певного програмного забезпечення. Я підкреслив вашу відповідь.
Tim Post

Але також зауважте, що "реально" виконання частіше зачіпається проблемами, які не мають нічого спільного зі складністю, але з чорними скриньками, які не знаходяться під вашим контролем. Ментальна модель цих скриньок є необхідною для оптимізації будь-чого. Ці міркування, ймовірно, стають недійсними, оскільки N наближається до нескінченності, що ніколи не робиться реально.
Доктор Белісарій

@Tim Post - Я сказав "... послідовно впроваджувати масштабовані системи ...". Звичайно, ти можеш пощастити, але не можеш пощастить послідовно. Але я також готовий визнати, що справді розумна / досвідчена людина може розвинути інтуїтивне розуміння складності, не проходячи ніде поблизу підручника чи курсу інформатики.
Стівен С

Побічна примітка, це призвело до гарного сміху на роботі, коли чоловік-колега сказав жінці-співробітниці: "Здається, у вас проблема Big O", не розуміючи іншого значення цього терміна. Вона сприйняла це в дусі, як це було призначено, але не могла перестати хихикати.
Пол

36

Причина цього полягає в тому, що вона вказує на масштабованість .

Процес, який є O (n ^ 2), буде масштабуватися гірше, ніж той, що є O (n log n), але краще, ніж один в O (n ^ 3) або навіть O (n!).

Якщо ви не знаєте відмінностей і коли вони застосовуються, ви менш підходять для вибору правильних реалізацій функціоналу, а також для екстраполяції тестових показників у продуктивність.


EDIT: Порівняння 48n з n ^ 3 від http://www.codinghorror.com/blog/2007/09/everything-is-fast-for-small-n.html (що, в свою чергу, з програмування Pearls)

введіть тут опис зображення


8
+1: Найгірший спосіб з’ясувати, що ваш процес не розширюється, - це те, що купа кричучих клієнтів з’являється все відразу.
Ларрі Коулман

22
@ Ларі, принаймні крики лінійно масштабуються з кількістю клієнтів!

10
Ну, я думаю, це просто показує, наскільки важливим є big-O: звук насправді O(log Customers)dB.
MSalters

4
@MSalters, добре, я виправлюся: « ЧИСЛО криків масштабироваться лінійно з числом клієнтів». Рівень звуку - інша справа.

1
@ Thorbjørn Ravn Andersen: Я прочитав деякі дослідження, які означають, що це скоріше логарифмічна шкала, тому певні класи скарг клієнтів настільки важливі! Вони показують , що, чим більше клієнтська база, багато більше людей мають цю проблему, і просто нічого не говорять або збираються на конкурс.
Стівен Еверс

32

Це залежить від того, що ти робиш.

Для веб-розробників (таких як я) це зазвичай має велике значення. Ви хочете, щоб веб-додатки масштабували масштаб. Якщо у вашої програми є вузьке місце, яке масштабується з O (n ^ 2), і ви вважаєте, що це просто добре, тому що ваш сервер може працювати з 1000 одночасними користувачами, вам здається, вам це не потрібно. Річ у тім, що для обробки всього вдвічі більше (що досить вірогідно трапиться за ніч) вам знадобиться обчислювальна потужність у 4 рази. В ідеалі ви хочете, щоб веб-програми масштабувались на O (n), оскільки апаратне забезпечення дешеве при розумному постійному співвідношенні користувача / сервера.

Як правило, в додатках, де у вас є 100000 об'єктів, великий O прийде і з'їсть вас. Ви надзвичайно вразливі до піків. Наприклад, я зараз працюю над 3D-грою, що є додатком, який обробляє навантаження даних. Крім візуалізації, у вас є перевірка зіткнення, навігація тощо. Ви не можете дозволити собі просто йти очевидним шляхом. Вам потрібні ефективні алгоритми, вам потрібно багато кешування, щоб амортизувати менш ефективні. І так далі.

Звичайно, якщо те, що ви робите, - це щось на кшталт створення мобільного додатку, об'єднавши графічний інтерфейс в дизайнер інтерфейсів, з'єднавши його з деякими веб-сервісами, і це все, то у вас ніколи не виникне складності. Тому що веб-сервіси, які ви телефонуєте, вже про це піклуються.


Створення мобільного додатку - це не лише випадок об'єднання графічного інтерфейсу, але я пробачу вас за те, що виступили з цим заявою в 2010 році :) Є складність в архітектурі, потоці даних, зберіганні даних, мережних черг, мобільних пристроях. Але сировина Big O не має значення (принаймні, в iOS), тому що ви повинні використовувати власні структури даних та алгоритми.
PostCodeism

21

Я ніколи фактично не застосовував офіційно це правило у своєму робочому житті.

Однак ви повинні бути знайомі з цією концепцією та застосовувати її інтуїтивно зрозуміло щоразу, коли розробляєте алгоритм.

Правило таке:

Ви повинні бути достатньо ознайомлені з позначенням O, щоб мати можливість визначити для даного завдання, чи потрібно його формально обчислити, або достатньо лише його інтуїтивно оцінити, або ви можете просто пропустити його повністю. Як і багато інших основних математичних понять.


10

Що ж, можливо, невеличка історія просвітить вас, чому це ДЕФІНІТНО потрібно:

У проекті, над яким я працював, була програма, яка відповідала за друк різного роду документів (етикетки, збирання списків тощо). Ця програма складалася з двох частин, одна з яких читала всі необхідні дані з бази даних і записувала їх у файл у стилі .ini та інша частина, яка читала ці файли та заповнювала їх у шаблони. Це досить добре працювало для міток та невеликих списків (із лише кількома полями), але воно тривало майже 10 хвилин, коли йому довелося надрукувати "великий" список ~ 20 сторінок. Оскільки доступ до цих ini-файлів призводив до часу доступу O (n²), n - кількість полів для друку.

Якби оригінальні програмісти цієї програми розуміли O-нотацію, вони ніколи не зробили б це так. Заміна цієї дурості на хештейн зробила його так швидше.


8

Продуктивність Big-O важлива, але вона значною мірою інтерналізована.

Ефективність сортування та пошуку Big-O не має значення, оскільки люди, як правило, використовують системи, що постачаються системою, і вони будуть настільки ж хорошими, як можуть бути (враховуючи, що вони повинні бути загалом корисними). Існують структури даних, які ефективніші для різних речей, але їх, як правило, можна вибирати на загальних принципах (і, як правило, вбудовуються в сучасні мови). Існує певний сенс алгоритмів, які роблять або не масштабують.

Результатом є те, що формальні питання рідко виникають на практиці, але практика будується на тих же принципах.


Де ви справді помічаєте це, коли дивитесь на код, написаний тим, хто не інтерналізував Big-O, і дивується, що їх підсистема настільки жахливо працює у виробництві. Навіть базового розуміння достатньо, щоб змусити вас поставити під сумнів чотири вкладені петлі передбачення над тими ж двома величезними масивами ...
eswald

6

ІМХО багато програм з інформатики залишають багато студентів, що блукають там, у бур'янах. Ці програми ніколи не передають загальної картини того, про що йдеться в галузі обчислень. Студенти вступають у галузь, бореться з тим, як застосовувати засвоєні ними поняття, мало розуміючи, як вони стосуються реального світу.

Я б сказав, що основою науки про обчислення є здатність міркувати про обчислення. І ви вивчаєте різні методи і прийоми для цього, і застосовуєте їх до абстрагованих проблем, які є прототиповими примітивами, знайденими в багатьох проблемах реального світу. Хитрість полягає в тому, щоб помітити ці прототипічні примітиви в реальному світі, а потім міркувати про такі речі, як правильність, складність, час і т. Д., Які, можете погодитися, справжні проблеми, про які вам потрібно хвилюватися. Розуміння того, як поводяться частини, часто дає вам уявлення про те, як поводиться ціле. І ті самі загальні методи і прийоми можна також застосувати до цілого, тільки не з тією ж суворістю, яку надають менші, добре абстраговані, чітко визначені частини. Але врешті-решт наука обчислення наділяє вас здатністю до розумного рішення про те, як організувати обчислення, з реальним розумінням того, як він буде вести себе в різних умовах.


5

Пам'ятка самому !:

Я та багато інших задаю собі це питання регулярно.

Я думаю, що справжня причина цього ми просимо в тому, що ми стали лінивими.

Ці знання ніколи не застаріють і не застаріють. Ви не можете застосовувати його щодня безпосередньо, але ви будете використовувати його підсвідомо, і це позитивно вплине на ваші дизайнерські рішення. Один день це може заощадити вас та інші години та дні кодування.

Оскільки більше проблем інкапсульовано сторонніми бібліотеками та інструментами та доступно для все більшої кількості розробників, вам потрібно буде знати ці знання, щоб відрізнити себе від інших та допомогти вирішити нові проблеми.


5

Не зовсім. В основному єдиний раз, коли я коли-небудь замислююся про це, коли отримую доступ до бази даних. Я зазвичай переглядаю код і скажу "Це робиться n + 1 запитів, вам слід змінити його на 1 або 2"

Оскільки всі мої дані читаються з бази даних та показуються користувачеві, я намагаюся мінімізувати кількість даних, з якими я працюю, до тієї точки, коли різниця між лінійним та алгоритмом O (n ^ 2) досить велика незначний.

Якщо є проблема, ми профіліруємо її та вирішимо пізніше.


1
Я фактично думаю, що ця випадкова запит "n + 1" є якось небезпечною. Зокрема, я бачив код, у результаті якого n ^ d запитів (де d> = 2) відхилено як "n + 1", що зробило справді жахливу ситуацію просто поганою.
philosodad

3

Три питання, які Ви ставите, і я думаю, що короткі форми відповіді могли б допомогти більш тривалим аргументам, наведеним до цих пір.

Наскільки цей тест важливий для розвитку у промисловості?

Залежить від галузі.

У будь-якій точці, де швидкість коду чи простір коду є проблемою, він цілком актуальний для галузі. Часто потрібно знати, скільки часу займе рутина або скільки пам'яті знадобиться (в режимі офлайн / офлайн).

Як часто ви використовуєте його реально?

Залежить від галузі.

Якщо ефективність та масштабування мало хвилюють цю роботу, то рідко, лише коли є серйозний дефіцит ефективності. Якщо ви інженер для критично використовуваної критичної системи, мабуть, кожен день.

Наскільки необхідно мати налагоджену думку про проблему?

Цілком необхідні.

Можливо, вам доведеться використовувати його щодня або лише у важких обставинах; але іноді це знадобиться. Переважно під час проектування до появи проблеми, ніж відчайдушно профілювати задушливу систему.


3

Я б сказав, що це дуже часто. Ми, як правило, не доводимо, що щось має особливий великий-O, але ми втілили цю ідею, запам'ятовували / ознайомлюємося з гарантіями big-O для конкретних структур даних та алгоритмів, і ми вибираємо найшвидші для конкретного використання. Це допомагає мати бібліотеку з усіма параметрами, як, наприклад, бібліотека колекцій Java або STL C ++. Ви неявно і природно використовуєте big-O щодня, коли ви вирішили використовувати java.util.HashMap( O(1)пошук) замість java.util.TreeMap( O(lg n)пошуку) і, звичайно, вирішите не здійснювати лінійний пошук через java.util.LinkedList( O(n)пошук) для чогось, де вам не потрібен відсортований доступ.

Коли хтось обирає неоптимальну реалізацію, а хтось, хто знає краще, приходить і бачить їх код, це частина нашого словника, щоб виправити їх "Ваша реалізація займає квадратичний час, але ми можемо звести це до n-log-n часу, зробивши це таким чином "настільки ж природно і автоматично, як ми використовували б англійську мову для замовлення піци.


3

Так

Можливо, вам не доведеться робити офіційні аналізи, але хоча б глибоке розуміння порядку складності алгоритму - і як порівнювати два алгоритми навколо цього - критично важливо, якщо ви хочете виконати нетривіальну роботу і мати її добре.

Я працював над двома різними системами, які здавалися чудовими на початку розробки, але на виробництві тестували обладнання на коліна, бо хтось використовував алгоритм O (n ^ 2). І в обох випадках виправлення було тривіальною зміною алгоритму O (n).


1

Він, ймовірно, використовується там, де розробляють API для споживання. STL C ++ - один з небагатьох API, який має обмеження щодо складності, накладені на його алгоритми. Але для щоденного працюючого програміста / старшого програміста / дизайнера / архітектора це не дуже замислюється над їх думкою.


API хороших колекцій дає ці гарантії, наприклад, API колекцій Java також має ці гарантії у своїй документації.
Кен Блум

1

Я не вважаю, що це важливо, окрім як передавати ідеї, і я працюю в критичних для продуктивності сферах (обробка променів, обробка зображень та сіток, системи частинок, фізичні двигуни тощо), і мені довелося розробити безліч фірмових алгоритмів та структур даних. під час роботи в НДДКР. У цих областях часто декілька дуже ефективних структур даних і алгоритмів можуть давати цілі нові передові продукти, тоді як алгоритми вчорашнього дня застаріли продукти, тому завжди потрібно робити ефективніше. Як застереження, я ніколи не публікував жодних робіт про алгоритми, які я розробив. Всі вони були власницькими. Якби я це зробив, мені знадобиться допомога математика, щоб сформулювати докази тощо.

Однак, на мою думку, обчислювальна робота за ітерацію часто представляє більш безпосередній інтерес, ніж масштабованість алгоритму, якщо алгоритм не масштабується дуже погано. Якщо хтось придумує сучасну техніку промінювання, мене більше цікавлять обчислювальні методи, такі як їх представлення та доступ до даних, ніж алгоритмічна складність, оскільки розумна масштабованість вже дана в цьому конкурентному та інноваційному сценарії. Ви не можете бути конкурентоспроможними, розробляючи алгоритми, які не змінюють масштаб.

Звичайно, якщо ви порівнюєте квадратичну складність з лінійної, це величезна різниця. Але більшість людей у ​​моїй галузі досить компетентні, щоб уникнути застосування алгоритму квадратичної складності на епічному введенні. Тому масштабованість часто глибоко має на увазі, і більш змістовні та цікаві питання стають на зразок: "Чи використовували ви GPGPU? SIMD? Чи працює він паралельно? Як ви представляли дані? Ви реорганізували їх для зручних кеш-схеми доступу? Як багато пам’яті займає? Чи може вона надійно поводитися з цією справою? Ви відкладаєте певну обробку чи робите це все за один раз? "

Навіть лінійно-алгоритмічний алгоритм може перевершити алгоритм лінійного часу, якщо колишній звертається до пам'яті в більш оптимальному шаблоні, наприклад, або краще підходить для багатопотокового та / або SIMD. Іноді навіть лінійний алгоритм може перевершувати логарифмічний алгоритм з цих причин, а природно алгоритми лінійного часу перевершують логарифмічні для підліткових входів.

Отже, для мене важливіше те, що деякі люди можуть назвати "мікрооптимізаціями", як-от представлення даних (макети пам'яті, шаблони доступу з розбиттям гарячого / холодного поля тощо), багатопотоковість, SIMD та інколи GPGPU. У галузі, де кожен вже достатньо компетентний, щоб використовувати пристойні до найсучасніших алгоритмів для всього, коли нові публікації постійно публікуються, ваша конкурентоспроможність у переборі з майстрами алгоритміки не виходить з покращення алгоритмічної складності настільки, як більш прямого обчислювальна ефективність.

У моєму полі переважають геніальні математики, але не завжди ті, хто знає обчислювальну вартість того, що вони роблять, або безліч хитрощів нижчого рівня для прискорення коду. Це, як правило, моя перевага над ними в розробці більш швидких і жорстких алгоритмів і структур даних, незважаючи на те, що моя є набагато менш складною. Я граю до того, що любить обладнання, до бітів і байтів, і роблю кожну ітерацію роботи набагато дешевшою, навіть якщо я роблю на кілька більше ітерацій роботи, ніж справді складний алгоритм - робота в моєму випадку значно дешевша. Код, який я пишу, також є набагато простішим. Якщо люди думають, що мікрооптимізовані версії простих алгоритмів та структур даних важко зрозуміти та підтримувати,

Як основний приклад, я створив просту структуру сітки, яка в нашій компанії перевершила KD-дерево для виявлення зіткнень та видалення зайвих точок. Моя дурна сира сітка була настільки менш алгоритмічно алгоритмічна, і я набагато тупіший математично і алгоритмічно, ніж хлопець, який реалізував KD-дерево своїм новим способом пошуку медіанної точки, але я просто налаштував використання пам’яті моєї сітки та схеми доступу та цього було достатньо, щоб перевершити щось набагато складніше.

Ще одне ребро в мене, яке дозволяє мені виживати в галузі, де панують люди, розумніші за мене, - це просто дійсно розуміння того, як користувач працює, оскільки я використовую програмне забезпечення, яке я розробляю так само. Це дає мені ідеї щодо алгоритмів, які реально дуже швидко узгоджуються з інтересами користувачів. Як основний приклад там, більшість людей намагаються прискорити такі речі, як виявлення зіткнень, використовуючи просторову індексацію. Я зробив просте спостереження щодо формування кар'єри майже пару десятиліть тому для органічних моделей, які, наприклад, якщо персонаж кладе руки на обличчя, структура просторової індексації хотіла б мати розділення вузлів і робити дорогі оновлення, якщо персонаж потім зняв руку з обличчя. Якщо замість цього ви розділите на основі даних про зв’язок, а не вершинних позицій, Ви можете створити стабільну ієрархічну структуру, яка дуже швидко оновлюється і ніколи не потребує розділення або відновлення балансу дерева (доводиться лише оновлювати обмежувальні поля для кожного кадру анімації) ... такі речі - алгоритми малюка без важкого математичного походження можна було б придумати, якби вони просто зрозуміли основну концепцію, але ті, що ухилялися від математиків, оскільки не думали про речі таким чином, наближеним до того, як користувачі працювали і занадто багато думали лише про властивості геометрії, а не про те, як геометрія широко використовувався. Я досить добре ладжу, спираючись більше на загальні обчислювальні знання та знання користувачів, ніж на майстерність алгоритміки. Так що все-таки я не вважаю таким важливим зосередитись на алгоритмічній складності.


0

Так, складність має значення в галузі. Якщо ви в кінцевому підсумку спроектуєте щось, коли критичний шлях масштабується як N-квадрат (подвоєння кількості чогось робить систему в чотири рази завантаженою), ви потрапите на вузьке місце масштабування набагато швидше, ніж якщо у вас є щось, що масштабується на N.

Однак, як правило, це не є належним, формальним доказом того, що щось є певною складністю, тож мати добру інтуїцію щодо того, яка складність є типовою схемою операцій, - це хороший початок.


0

Я ніколи не думаю про велику О в математичній перспективі, я ніколи не думаю про велику О, якщо не запитують. Я просто бачу алгоритм в голові, і я можу сказати, чи це погано, тому що він робить кілька циклів через пам'ять для кожного N, або якщо він ділиться і перемагає чи щось подібне. Якщо потрібно, я можу перевести це на велику нотацію O за кілька секунд, але мені простіше просто знати, як алгоритм / контейнер працює з пам'яттю, ніж думати про математичну перспективу.


-3

Питання, які задаються в інтерв'ю, є для того, щоб з’ясувати, чи можна пояснити речі і мислити логічно . Інтерв'юер також намагається з'ясувати, чи можете ви використати те, що знаєте, для вирішення пов'язаної проблеми .

Кожен, хто вивчав гідне вивчення програмної інженерії, натрапив на "Big O", щоб також відповісти на гарне запитання щодо "Big O", ви також повинні мати трохи розуміння стандартних структур даних та алгоритмів.

Під час співбесіди для співробітника ви шукаєте когось, хто швидко може навчитися роботі, а не того, хто вже знає заданий набір детальних навичок, тож вибирати питання, які мають і інтерв'юер, і інтерв'юйований, мають спільне розуміння, дуже важко. з.

Тож питання щодо "великого О" можуть бути дуже актуальними для процесу співбесіди.

Принаймні щороку протягом мого тривалого часу, як комп'ютерний програміст, мені доводилося виправляти код, який був повільним через те, що хтось не розуміє правильних структур даних та алгоритмів для використання, але ви можете вирішити ці проблеми, не маючи детального розуміння Big O. Однак люди, які розуміють намет Big O, не уникають цих проблем в першу чергу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.