業界で働くとき、big-Oは本当に関連性がありますか?


65

私が行ったすべてのインタビューで、big-O表記を含む複雑さの数学的分析についてクイズを受けました。

big-O分析は、業界の開発にどの程度関連していますか?どのくらいの頻度でそれを実際に使用しますか?また、問題に対する研ぎ澄まされた考え方を持つことはどのくらい必要ですか?


5
@ MM01私は高校と大学で勉強しました。私はそれをプログラマーの知識の構成要素として認識していますが、自分の仕事でそれを使用したことはありません。
systempuntoout

27
どのような正確にこれを尋ねたとき、あなたは、業界を考えていますか?月面探査機の制御コードを書いていますか、それともブログのプラットフォームですか?
ティムポスト

14
@systempuntooutでは、他のアルゴリズムよりも高速なアルゴリズムを選択したことはありませんか?

3
@ MM01-それに苦労している場合、最も簡単な(簡略化されているとはいえ)説明の1 つがここに
Tim投稿

6
@ Systempuntoout、O表記法の理解と使用は、厳密な数学的証明を意味するものではありませんが、アルゴリズムの動作を簡単な表現で伝えることができます。1Dでソートする必要がある場合は、O(n log n)アルゴリズムが必要です。フィボナッチ数の実装が必要な場合は、O(n)で実行される実装を選択します。はっきりと声に出さなくても、これはループと再帰の数を凝縮したもので、非常に便利です。たくさんの単語を保存します。(そして、気の利いた人にとって-はい、kが非常に大きいか小さい場合も重要です)。

回答:


76

私の質問は、このテストが業界の発展にどの程度関連しているかということです。

スケーラブルなアルゴリズム、アプリケーション、およびシステムを設計するには、計算の複雑さの理論(大きなO表記など)をしっかり理解することが不可欠です。スケーラビリティは業界のコンピューティングに非常に関連しているため、ビッグO表記も重要です。

どのくらいの頻度でそれを使用しますか?また、問題に対して研ぎ澄まされた考え方を持つことはどれくらい必要ですか?

「それを使用する」という意味に依存します。一方では、私が書いたソフトウェアの計算の複雑さの正式な証明は決してしません。その一方で、ほとんどの場合、スケーラビリティが潜在的な懸念事項であり、設計上の決定には、複雑さの特性に基づいた適切なコレクションタイプの選択が含まれるアプリケーションに対処する必要があります。

(複雑さの理論をしっかりと理解しなくても、スケーラブルなシステムを一貫して実装できるかどうかはわかりません。できないと思います。)


原則が重要だからです。私の業界の経験では、考慮に入れるべき考慮事項であり、大したことではありません。とはいえ、(例)リストの挿入と配列の挿入、またはバブルソートとクイックソートの比較について尋ねられた場合、インタビュアーは知識を評価することを目指しています。また、複雑さ/実行時/スケーラビリティ/パフォーマンスについても考えてみてください。あなたがこれらのことについて考えない/考えられないなら、あなたはうまくやる方法を知らないいくつかの仕事があるでしょう。まれですが、時々登場します。
すぐに

6
まあ、それは可能ですので、真っ暗闇でターゲットを撮影しています。十分な弾丸が与えられれば、最終的には強気の目を打つでしょう。その後、さまざまな設計と実装の要因の結果を経験することで、次回に必要な弾丸が少なくなります。恐らく悪い例えですが、それはいくつかのソフトウェアが書かれている方法を正確に説明しています。私はあなたの答えを投票しました。
ティムポスト

ただし、「本質的に」パフォーマンスは、複雑さとは関係なく、制御できないブラックボックスの問題の影響を受けることが多いことに注意してください。これらのボックスのメンタルモデルは、あらゆるものを最適化するために不可欠です。Nが無限に近づくにつれて、これらの考慮事項はおそらく無効になります。
ベリサリウス博士10年

@Tim Post-「... スケーラブルなシステムを一貫して実装します...」と言いました。幸運を得ることができますが、一貫して幸運を得ることができません。しかし、本当に頭が良くて経験豊富な人なら、教科書やコンピューターサイエンスコースの近くに行かなくても、複雑さを直観的に理解できることを受け入れる用意もあります。
スティーブンC

サイドノートは、男性の同僚が女性の同僚に「あなたはビッグオー問題を抱えているように聞こえる」と語ったとき、仕事の他の意味を理解せずに、仕事で大笑いをしました。彼女はそれが意図された精神でそれを取りましたが、笑いを止めることができませんでした。
ポール

36

これの理由はそれがスケーラビリティを示すからです。

O(n ^ 2)のプロセスは、O(n log n)のプロセスよりもスケーリングが悪くなりますが、O(n ^ 3)またはO(n!)のプロセスよりも優れています。

違いがわからない場合、およびそれらが適用されるタイミングは、機能の適切な実装の選択や、テストパフォーマンスの実稼働パフォーマンスへの外挿にはあまり適していません。


編集:http://www.codinghorror.com/blog/2007/09/everything-is-fast-for-small-n.htmlの48nとn ^ 3の比較(これはProgramming Pearlsのものです)

ここに画像の説明を入力してください


8
+1:プロセスがスケールしないことを確認する最悪の方法は、叫んでいる顧客の束を一度に表示することです。
ラリーコールマン

22
@Larry、少なくとも悲鳴は顧客の数に比例して増加します!

10
まあ、それはビッグOの重要性を示していると思いO(log Customers)ます。音は実際にはdBです。
MSalters

4
@MSaltersは、[OK]を、私は修正スタンド:「NUMBER悲鳴のは、顧客の数に比例スケール」。音のレベルは別の問題です。

1
@ThorbjørnRavn Andersen:私はそれがより対数スケールであることを示唆するいくつかの研究を読んだことがあります。彼らは、顧客ベースに大きい、ことを示している多くのより多くの人々がその問題を持っている、とだけで何も言われませんか競争しようとしています。
スティーブンエバーズ

32

それはあなたが何をしているかに依存します。

(私のような)Web開発者にとって、これは通常非常に重要です。Webアプリを拡張したい。アプリケーションにO(n ^ 2)に比例するボトルネックがあり、サーバーが1000人の同時ユーザーを処理できるため、これで十分だと思う場合は、気にする必要はないようです。大事なことは、2倍だけを処理するには(これは一晩で発生する可能性がかなり高い)、4倍の計算能力が必要になるということです。ハードウェアは合理的な一定のユーザー/サーバー比で安価であるため、WebアプリをO(n)でスケーリングすることが理想的です。

一般的に、10万個のオブジェクトがあるアプリでは、大きなOがあなたを食べに来ます。あなたはピークに対して非常に脆弱です。たとえば、現在、3Dゲームに取り組んでいます。これは、大量のデータを処理するアプリです。レンダリングとは別に、衝突チェック、ナビゲーションなどがあります。明らかな方法を実行するだけの余裕はありません。効率的なアルゴリズムが必要であり、多くのキャッシングが必要なので、効率の悪いアルゴリズムは償却されます。等々。

もちろん、インターフェイスデザイナーにGUIを配置してモバイルアプリを作成するようなものであれば、それをいくつかのWebサービスと結び付ければ、複雑さの問題は発生しません。あなたが呼び出すウェブサービスはすでにそれを処理しているからです。


モバイルアプリを作成することは、GUIをまとめるだけではありませんが、2010年にそのような声明を作成することをお許しください。ただし、ネイティブのデータ構造とアルゴリズムを使用する必要があるため、生のBig Oは(少なくともiOSでは)無関係です。
PostCodeism

21

私は実際に私の仕事の生活の中で規則を正式に適用したことはありません。

ただし、その概念に精通し、アルゴリズムを設計するたびに直感的に適用する必要があります。

ルールは次のとおりです。

特定のタスクについて、正式に計算する必要があるのか​​、直感的に評価するのに十分なのか、完全にスキップできるのかを判断できるように、O表記に十分精通している必要があります。他の多くの基本的な数学的概念と同じです。


10

まあ、おそらくそれは間違いなく必要な理由を少し物語があなたを啓発します:

私が取り組んでいるプロジェクトには、あらゆる種類のドキュメント(ラベル、ピッキングリストなど)を印刷するプログラムがありました。このプログラムは2つの部分で構成され、1つはデータベースからすべての必要なデータを読み取り、 .iniスタイルのファイル、およびそれらのファイルを読み取ってテンプレートに入力する別の部分。これは、ラベルと小さなリスト(フィールドが数個しかない)で十分に機能しましたが、約20ページの「大きな」リストを印刷しなければならなかった場合、ほぼ10分間実行されました。これらのiniファイルにアクセスするとO(n²)アクセス時間が発生するため、nは印刷するフィールドの数です。

このプログラムの元のプログラマーがO表記を理解していたなら、彼らはそのようにしたことはなかったでしょう。その愚かさをハッシュテーブルに置き換えると、ずっと速くなりました。


8

Big-Oパフォーマンスは重要ですが、大部分は内部化されています。

ソートと検索のBig-Oのパフォーマンスは重要ではありません。人々は通常、システムが提供するものを使用するため、それらは可能な限り優れたものになります(一般的に有用である必要がある場合)。さまざまなものに対してより効率的なデータ構造がありますが、それらは通常、一般的な原則に基づいて選択できます(通常、現代の言語に組み込まれています)。スケーリングするかしないかのアルゴリズムにはある程度の意味があります。

その結果、正式な問題は実際にはめったに出てきませんが、実践は同じ原則に基づいています。


これに本当に気付くのは、Big-Oを内部化していない人によって書かれたコードを見たときであり、そのサブシステムが本番環境で非常に恐ろしく動作することに驚いています。基本的な理解さえあれば、同じ2つの巨大な配列に対する4つのネストされたforeachループに疑問を抱かせることができます。
eswald

6

多くのコンピュータサイエンスプログラムでは、多くの学生が雑草の中をさまよいます。これらのプログラムは、計算科学が何であるかについての全体像をまったく伝えません。学生は業界に参入し、学習した概念をどのように適用するかを模索しますが、実際の世界との関係についてはほとんど洞察がありません。

計算科学の核心は、計算について推論する能力だと思います。そして、これを行うためのさまざまな方法と技法を学び、それらを抽象化された問題に適用します。抽象化された問題は、多くの現実世界の問題に見られるプロトタイプのプリミティブです。秘Theは、これらのプロトタイプのプリミティブを現実世界で見つけてから、正確性、複雑性、時間などの事柄について推論することです。部品がどのように動作するかの洞察は、全体がどのように動作するかの洞察を頻繁に提供します。そして、同じ一般的な方法と手法を全体に適用することもできますが、より小さく、抽象化され、明確に定義された部品に与えられるのと同じ厳密さではありません。しかし、最終的には、計算の科学は、合理的にする能力を与えます さまざまな条件下でどのように動作するかについての真の洞察とともに、計算を配置する方法に関する決定。


5

自己へのメモ!:

私と他の多くの人は、この質問を定期的に自問しています。

私たちがこれを尋ねる本当の理由は、怠け者になったからだと思います。

この知識は決して古くなったり、時代遅れになることはありません。毎日直接適用することはできませんが、無意識に使用し、設計上の決定にプラスの影響を与えます。ある日、あなたや他の人のコーディングの時間と日を節約するかもしれません。

より多くの問題がサードパーティのライブラリとツールによってカプセル化され、ますます多くの開発者が利用できるようになると、この知識を知って他の人と区別し、新しい問題を解決する必要があります。


5

あんまり。基本的に、データベースにアクセスするときだけを考えます。私は通常、コードを見て、「それはn + 1個のクエリを実行しています。1または2だけ実行するように変更する必要があります」と言います。

すべてのデータがデータベースから読み取られてユーザーに表示されるため、線形アルゴリズムとO(n ^ 2)アルゴリズムの違いがかなり大きくなるまで、使用するデータ量を最小限に抑えようとします無視できる。

問題がある場合は、後でプロファイリングして修正します。


1
実際、このカジュアルな「n + 1」クエリは危険なものだと思います。特に、n ^ d個のクエリ(d> = 2)が「n + 1」として却下されたコードを見たことがあります。
哲学者

3

あなたが入れた3つの質問と私は、短い形式の答えがこれまでに与えられたより長い議論を助けると思う

このテストは、業界の開発にどの程度関連していますか?

業界に依存します。

コードの速度やコードスペースが問題になる場所はどこでも、関係する業界に完全に関連しています。多くの場合、ルーチンにかかる時間、または必要なメモリ(オンライン/オフライン)の量を知る必要があります。

どのくらいの頻度でそれを使用しますか?

業界に依存します。

パフォーマンスとスケーリングが目の前のジョブにとってほとんど問題にならない場合、まれに、深刻なパフォーマンスの不足がある場合のみです。高度に使用される重要なシステムのエンジニアであれば、おそらく毎日でしょう。

問題に対する研ぎ澄まされた考え方を持つことはどのくらい必要ですか?

完全に必要です。

毎日使用するか、ひどい状況でのみ使用する必要があります。しかし、時にはそれが必要になります。窒息システムを必死にプロファイリングするよりも、問題が発生する前の設計中に行うことが望ましい。


3

非常に頻繁だと思います。一般に何かが特定のbig-Oを持っていることを証明しませんが、アイデアを内部化し、特定のデータ構造とアルゴリズムのbig-Oの保証を記憶/熟知し、特定の用途に最も速いものを選びます。JavaコレクションライブラリやC ++ STLなど、すべてのオプションでいっぱいのライブラリを用意すると便利です。あなた暗黙のうちに、自然ビッグOを使用し、毎日あなたが使用することを選択したときにjava.util.HashMapO(1)代わりに、ルックアップ)java.util.TreeMapO(lg n)ルックアップ)し、確かに全体で線形検索を実行しないことを選択java.util.LinkedListO(n)検索)を使用すると、ソートされたアクセスを必要としない何かのため。

誰かが次善の実装を選択し、より良く知っている誰かがやって来てコードを見るとき、それらを修正することは私たちの語彙の一部です。「実装は二次の時間を要しますが、英語を使用してピザを注文するのと同じくらい自然かつ自動的に」


3

はい

正式な分析を行う必要はないかもしれませんが、少なくともアルゴリズムの複雑さの順序と、その周りの2つのアルゴリズムを比較する方法を直感的に理解することは、自明でない作業を行い、うまくいくようにする場合に重要です。

私は初期の開発では問題ないと思われた2つの異なるシステムに取り組んできましたが、O(n ^ 2)アルゴリズムを使用したため、実稼働テストでハードウェアをひざまずかせました。そして、どちらの場合も、修正はO(n)アルゴリズムの些細な変更でした。


1

おそらく、消費用のAPIを開発している場所で使用されます。C ++ STLは、アルゴリズムに複雑さの制限が課されている数少ないAPIの1つです。しかし、日常的に働くプログラマー/シニアプログラマー/デザイナー/アーキテクトにとっては、あまり気になりません。


優れたコレクションAPIは、これらの保証を行います。たとえば、JavaコレクションAPIのドキュメントにもこれらの保証があります。
ケンブルーム

1

アイデアを伝えることを除いて重要だとは思っていませんでした。パフォーマンスが重要な分野(レイトレーシング、画像およびメッシュ処理、パーティクルシステム、物理エンジンなど)で働いており、独自のアルゴリズムとデータ構造をたくさん考案しなければなりませんでしたR&Dで作業するとき。これらの分野では、非常に効率的なデータ構造とアルゴリズムのほんの一握りがまったく新しい最先端の製品を生み出すことが多く、昨日のアルゴリズムは既存の製品を廃止するため、より効率的に物事を追求することが常にあります。ただし、警告として、私が考案したアルゴリズムに関する論文を公開したことはありません。それらはすべて独自のものでした。もしそうなら、証明などを定式化するために数学者の助けが必要でしょう。

しかし、私の意見では、アルゴリズムのスケーリングが本当に不十分な場合を除き、反復ごとの計算作業の量は、アルゴリズムのスケーラビリティよりも直接的な関心の対象になることがよくあります。誰かがレイトレーシングの最先端技術を思いついたら、この競争的で革新的なシナリオでは合理的なスケーラビリティがすでに与えられているため、アルゴリズムの複雑さよりもデータの表現方法やデータへのアクセス方法などの計算技術に興味があります。スケールしないアルゴリズムを考え出すのは競争力がありません。

もちろん、2次の複雑さと線形を比較する場合、それは大きな違いです。しかし、私の分野のほとんどの人は、壮大な入力に2次複雑度アルゴリズムを適用するのを避けるのに十分な能力を備えています。したがって、スケーラビリティはしばしば暗示され、より意味のある興味深い質問は、「GPGPUを使用しましたか?SIMD?それは並行して実行しますか?データをどのように表現しましたか?キャッシュフレンドリーなアクセスパターンのために再編成しましたか?大量のメモリを必要としますか?このケースを堅牢に処理できますか?特定の処理を延期するのか、それともすべてを一度に実行するのですか?」

前者がより最適なパターンでメモリにアクセスする場合、またはマルチスレッドやSIMDに適している場合、線形アルゴリズムでも線形時間アルゴリズムよりも優れています。線形アルゴリズムでさえ、これらの理由で対数アルゴリズムよりも優れている場合があり、自然に線形時間アルゴリズムは、小さな入力に対して対数アルゴリズムよりも優れています。

私にとって重要なのは、データ表現(メモリレイアウト、ホット/コールドフィールド分割を使用したアクセスパターンなど)、マルチスレッド、SIMD、時にはGPGPUなど、一部の人々が「マイクロ最適化」と呼ぶものです。誰もがすでに新しい論文が絶えず発表されているため、すべてにきちんとした最先端のアルゴリズムを使用するのに十分な能力がある分野では、アルゴリズムのウィザードを打ち負かすことの競争力は、アルゴリズムの複雑さの改善から直接得られるものではありません計算効率。

私の分野は優秀な数学者に支配されていますが、自分がしていることの計算コストやコードを高速化するための多くの低レベルのトリックを常に知っているわけではありません。私の洗練度ははるかに低いにもかかわらず、通常は、より高速でより厳密なアルゴリズムとデータ構造を考案する上で、私はそれらに勝っています。私はハードウェアが好きなものに取り組んでおり、ビットとバイトに向かって、本当に洗練されたアルゴリズムよりもいくつかの反復作業を行っている場合でも、作業の各反復をはるかに安くしています。私の場合の作業は大幅に安くなっています。私が書いたコードもずっとシンプルになる傾向があります。単純なアルゴリズムとデータ構造のマイクロ最適化バージョンを理解し、維持するのが難しいと人々が考える場合、

基本的な例として、単純なグリッド構造を思い付きました。これは、衝突検出と冗長ポイントの削除に関して、最終的に当社のKDツリーを上回る結果となりました。私の愚かな原油グリッドはアルゴリズム的にそれほど洗練されておらず、私は数学的にもアルゴリズム的にも中央値を見つけるという彼の斬新な方法でKDツリーを実装した人よりもはるかに愚かですが、グリッドのメモリ使用量とアクセスパターンを調整しましたそれは、はるかに洗練された何かを上回るのに十分でした。

私よりもはるかに賢い人々が支配する分野で生き残るために私が持っているもう1つの利点は、同じ方法で開発したソフトウェアを使用しているため、ユーザーがどのように機能するかを本当に理解することです。これにより、ユーザーの関心にすぐに合致するアルゴリズムのアイデアが得られます。そこの基本的な例として、ほとんどの人は空間インデックスを使用して衝突検出のようなものを加速しようとします。数十年前に、たとえばキャラクターが顔に手を置いた場合、空間インデックス構造はノードを分割し、キャラクターが高価な更新を行う必要があるという有機モデルについて、簡単なキャリア形成観測を行いましたその後、顔から手を離しました。代わりに、頂点の位置ではなく接続性データに基づいてパーティションを分割する場合、非常に迅速に更新され、ツリーを分割または再バランスする必要のない安定した階層構造になります(アニメーションのフレームごとに境界ボックスを更新するだけでよい)...このようなもの-重い数学的な背景のない子供基本的な概念を理解していれば思いつくかもしれませんが、数学者はユーザーの働き方にあまり近い方法で物事を考えておらず、幾何学の方法ではなく幾何学のプロパティについて考えすぎていたため、数学者を逃れました一般的に使用されていました。アルゴリズムの魔法よりも、一般的な計算の知識とユーザーエンドの知識に頼ることで、十分に仲良くなります。とにかく、アルゴリズムの複雑さに焦点を合わせることがそれほど重要だとは思いませんでした。


0

はい、業界では複雑さが重要です。クリティカルパスウェイがNの2乗(何かの数を2倍にすると、システムの負荷が4倍になる)で設計することになった場合、Nでスケーリングするものよりもはるかに高速にスケーリングのボトルネックにぶつかります。

ただし、通常は、何かが特定の複雑さにあるという適切で正式な証拠として行われるわけではないため、操作のパターンがどのような複雑さを持っているかを直感的に理解することは良い出発点です。


0

私は数学的な観点から大きなOを決して考えません。尋ねられない限り、大きなOについてはまったく考えません。頭の中にアルゴリズムが表示されているだけで、Nごとにメモリを複数回ループしているために悪いのか、分割して征服するのかなどがわかるのです。必要に応じて、数秒でそれを大きなO表記に変換できますが、数学的な観点を考えるよりも、アルゴリズム/コンテナがメモリでどのように機能するかを知る方が簡単です。


-3

インタビューで尋ねられる質問は、物事を説明し、論理的な方法で考えることができるかどうかを調べるためにあります。インタビュアーはまた、あなたが知っていることを使って関連問題を解決できるかどうかを見つけようとしています。

ソフトウェアエンジニアリングの価値ある研究を行ったすべての人は、「ビッグO」に出くわすでしょう。また、「ビッグO」についての良い質問に答えるには、標準のデータ構造とアルゴリズムについてもある程度理解する必要があります。

スタッフのメンバーにインタビューするときは、特定の一連の詳細なスキルを既に知っている人ではなく、すぐに仕事を学ぶことができる人を探しているので、インタビュアーとインタビュイーの両方が共通の理解を持っている質問を選択することは非常に困難ですの。

したがって、「ビッグO」に関する質問は、インタビュープロセスに非常に関連性があります。

少なくとも毎年、コンピュータープログラマーとして長い間、使用する正しいデータ構造とアルゴリズムを理解していないために遅いコードを修正する必要がありましたが、Big Oを詳しく理解しなくてもこれらの問題を解決できます。ただし、Big Oテントを理解している人は、そもそもこれらの問題を避けられません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.