제가 인터뷰를 할 때마다 big-O 표기법을 포함하여 복잡성에 대한 수학적 분석에 대한 퀴즈를 받았습니다.
산업에서 개발에 큰 O 분석이 얼마나 관련이 있습니까? 실제로 얼마나 자주 사용합니까? 문제에 대한 갈등을 갖기 위해서는 얼마나 필요합니까?
제가 인터뷰를 할 때마다 big-O 표기법을 포함하여 복잡성에 대한 수학적 분석에 대한 퀴즈를 받았습니다.
산업에서 개발에 큰 O 분석이 얼마나 관련이 있습니까? 실제로 얼마나 자주 사용합니까? 문제에 대한 갈등을 갖기 위해서는 얼마나 필요합니까?
답변:
제 질문은이 테스트가 산업 개발과 얼마나 관련이 있습니까?
확장 가능한 알고리즘, 응용 프로그램 및 시스템을 설계하려면 계산 복잡성 이론 (예 : 큰 O 표기법)을 제대로 이해해야합니다. 확장 성은 산업 컴퓨팅과 관련성이 높기 때문에 큰 O 표기법도 있습니다.
Reeeally 얼마나 자주 사용합니까? 문제에 대한 갈등을 갖기 위해서는 얼마나 필요합니까?
"reeeally 그것을 사용하는"의 의미에 따라 다릅니다. 한편으로는 필자가 작성한 소프트웨어에 대해 계산 복잡성에 대한 공식적인 증거를 절대로 내리지 않습니다. 다른 한편으로, 확장 성이 잠재적 인 관심사 인 응용 프로그램을 처리해야하는 대부분의 날에는 설계 결정에 복잡성 특성에 따라 적절한 수집 유형 (예 : 적절한 수집 유형)이 포함됩니다.
복잡성 이론을 제대로 이해 하지 않고 확장 가능한 시스템을 지속적으로 구현할 수 있는지 여부는 알 수 없습니다. 그렇지 않다고 생각하는 경향이 있습니다.
그 이유는 확장 성 을 나타 내기 때문 입니다.
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 (프로그래밍 진주)에서 n ^ 3과 48n의 비교
O(log Customers)
. 사운드는 실제로 dB입니다.
그것은 당신이하는 일에 달려 있습니다.
웹 개발자 (예 : 나와 같은)의 경우 이는 일반적으로 중요합니다. 웹 앱을 확장하고자합니다. 앱에 O (n ^ 2)로 확장되는 병목 현상이 있고 서버에서 동시 사용자 1,000 명을 처리 할 수 있기 때문에 이것이 문제가되지 않는다고 생각하면 신경 쓰지 않아도됩니다. 문제는 단지 밤에 일어날 가능성이 상당히 높은 2 배를 처리하기 위해서는 계산 능력의 4 배가 필요하다는 것입니다. 하드웨어가 합리적인 사용자 / 서버 비율로 저렴하기 때문에 웹 앱을 O (n)으로 확장하는 것이 이상적입니다.
일반적으로 100000 개의 객체가있는 앱에서는 큰 O가 와서 먹을 것입니다. 당신은 봉우리에 엄청나게 취약합니다. 예를 들어, 저는 현재 많은 데이터를 처리하는 앱인 3D 게임을 만들고 있습니다. 렌더링 외에도 충돌 검사, 탐색 등이 있습니다. 분명한 방법으로 감당할 수는 없습니다. 효율적인 알고리즘이 필요하고 캐싱이 많이 필요하므로 효율성이 떨어지는 알고리즘이 상각됩니다. 등등.
물론 인터페이스 디자이너에서 GUI를 통합하여 모바일 앱을 만드는 것과 같은 일이 있다면 웹 서비스와 연결하면 복잡해집니다. 호출하는 웹 서비스가 이미 관리하고 있기 때문입니다.
글쎄, 아마도 약간의 이야기가 왜 그것이 꼭 필요한지 알려줄 것입니다.
내가 작업했던 프로젝트에는 모든 종류의 문서 (라벨, 피킹리스트 등)를 인쇄하는 프로그램이있었습니다.이 프로그램은 두 부분으로 구성되어 있습니다. 하나는 데이터베이스에서 필요한 모든 데이터를 읽고 .ini 스타일 파일 및 해당 파일을 읽고 템플릿에 채운 다른 부분. 이것은 레이블과 작은 목록 (몇 개의 필드 만 있음)에 대해서는 합리적으로 잘 작동했지만 ~ 20 페이지의 "큰"목록을 인쇄해야 할 때 거의 10 분 동안 실행되었습니다. 이러한 ini 파일에 액세스하면 O (n²) 액세스 시간이 발생 했으므로 n은 인쇄 할 필드 수입니다.
이 프로그램의 최초 프로그래머가 O- 표기법을 이해했다면, 그렇게하지 않았을 것입니다. 그 어리 석음을 해시 테이블로 바꾸면 훨씬 빨라졌습니다.
Big-O 성능이 중요하지만 크게 내재화되었습니다.
정렬 및 검색의 Big-O 성능은 중요하지 않습니다. 사람들은 일반적으로 시스템이 제공하는 것을 사용하기 때문에 최대한 유용 할 것입니다 (일반적으로 유용해야 함). 서로 다른 것들에 대해 더 효율적인 데이터 구조가 있지만 일반적으로 일반적인 원칙에 따라 선택할 수 있습니다 (일반적으로 현대 언어로 구축 됨). 확장 또는 축소되지 않는 알고리즘이 있습니다.
결과적으로 공식적인 문제는 실제로 거의 발생하지 않지만 실천은 동일한 원칙을 기반으로합니다.
IMHO 많은 컴퓨터 과학 프로그램은 많은 학생들이 잡초에서 방황하고 있습니다. 이 프로그램은 계산 과학이 무엇인지에 대한 큰 그림을 절대로 전달하지 않습니다. 학생들은 실제 세계와의 관계에 대한 통찰력을 갖지 않고 배운 개념을 적용하는 방법을 이해하면서 업계에 진입합니다.
나는 계산 과학의 핵심은 계산에 대한 추론 능력이라고 말합니다. 그리고 당신은 이것을하기위한 다양한 방법과 기술을 배우고, 많은 실제 세계 문제에서 발견되는 프로토 타입 프리미티브 인 추상 문제에 적용합니다. 비결은 실제 세계에서 이러한 원형 프리미티브를 발견 한 다음, 정확성, 복잡성, 시간 등과 같은 것들에 대해 추론하는 것입니다. 부품의 작동 방식에 대한 통찰력은 종종 전체의 작동 방식에 대한 통찰력을 제공합니다. 더 작고 잘 추상화 된 잘 정의 된 부분에 제공되는 동일한 엄격 성이 아니라 동일한 일반적인 방법과 기술을 전체에 적용 할 수도 있습니다. 그러나 결국 계산 과학은 합리적 으로 만드는 능력을 부여합니다. 다양한 조건에서 어떻게 작동하는지에 대한 실제 통찰력을 통해 계산 방법에 대한 결정.
자기 메모! :
저와 많은 사람들이이 질문을 정기적으로합니다.
우리가 이것을 요구하는 진짜 이유는 우리가 게으 르기 때문이라고 생각합니다.
이 지식은 결코 데이트를하거나 구식이되지 않을 것입니다. 매일 적용 할 수는 없지만 잠재 의식적으로 사용하면 디자인 결정에 긍정적 인 영향을 미칩니다. 언젠가는 코딩 시간을 절약 할 수 있습니다.
더 많은 문제가 타사 라이브러리 및 도구에 의해 캡슐화되고 점점 더 많은 개발자가 사용할 수 있으므로 다른 사용자와 자신을 구별하고 새로운 문제를 해결하는 데 도움이되도록이 지식을 알아야합니다.
실제로는 아닙니다. 기본적으로 내가 생각한 유일한 것은 데이터베이스에 액세스 할 때입니다. 나는 보통 코드를보고 "그것이 n + 1 쿼리를하고있다, 당신은 단지 1 또는 2를 수행하도록 변경해야한다"라고 말할 것이다.
모든 데이터가 데이터베이스에서 읽혀지고 사용자에게 표시되므로 선형 및 O (n ^ 2) 알고리즘의 차이가 예쁜 지점에서 작업중인 데이터 양을 최소화하려고합니다. 무시할 만하다.
문제가 있으면 나중에 프로파일 링하여 수정합니다.
당신이 세 가지 질문을하고 짧은 형식의 답변이 지금까지 주어진 긴 논쟁에 도움이 될 것이라고 생각합니다.
이 테스트는 산업 개발과 얼마나 관련이 있습니까?
산업에 따라 다릅니다.
코드 속도 나 코드 공간이 문제가되는 모든 곳은 관련 산업과 전적으로 관련이 있습니다. 루틴이 얼마나 오래 걸리는지, 또는 얼마나 많은 메모리 (온라인 / 오프라인)가 필요할지 알아야합니다.
얼마나 자주 Reeeally 사용합니까?
산업에 따라 다릅니다.
성능과 스케일링이 당면한 작업에 거의 관심이 없다면, 성능이 심각한 경우에만 드물게 발생합니다. 당신이 많이 사용하는 중요한 시스템의 엔지니어라면 매일 매일 그렇습니다.
문제에 대한 갈망을 갖는 것이 얼마나 필요합니까?
완전히 필요합니다.
매일 또는 심한 환경에서만 사용해야 할 수도 있습니다. 그러나 때로는 필요할 것입니다. 질식 시스템을 필사적으로 프로파일 링하는 것보다 문제가 발생하기 전에 설계하는 것이 바람직합니다.
매우 빈번하다고 말하고 싶습니다. 우리는 일반적으로 어떤 것이 특정 big-O를 가지고 있음을 증명 하지는 않지만 , 아이디어를 내재화하고 특정 데이터 구조 및 알고리즘에 대한 big-O 보증에 익숙해 지거나 기억하고 특정 용도에 가장 빠른 것을 선택합니다. Java 콜렉션 라이브러리 또는 C ++ STL과 같은 모든 옵션으로 가득 찬 라이브러리를 갖는 데 도움이됩니다. 당신은 암시 적으로 자연스럽게 큰-O를 사용하여 매일 당신이 사용하도록 선택하는 경우 java.util.HashMap
( O(1)
대신의 조회) java.util.TreeMap
( O(lg n)
조회) 및 확실히에 걸쳐 선형 검색을 실행하지 않는 선택 java.util.LinkedList
( O(n)
당신이 정렬 된 액세스를 필요로하지 않는 무언가에 대한 조회).
누군가가 차선의 구현을 선택하고 더 잘 아는 사람이 와서 코드를 볼 때, 그것은 우리의 어휘 중 하나입니다. 대신 피자를 주문할 때 영어를 사용하는 것처럼 자연스럽고 자동으로
아이디어를 전달하는 것 외에는 그다지 중요한 점을 발견하지 못했고 성능에 중요한 분야 (레이트 레이싱, 이미지 및 메시 처리, 파티클 시스템, 물리 엔진 등)에서 일하며 많은 독점 알고리즘과 데이터 구조를 고안해야했습니다. R & D에서 일할 때 이러한 영역에서 종종 매우 효율적인 데이터 구조와 알고리즘이 완전히 새로운 최첨단 제품을 생산할 수있는 반면, 어제 알고리즘은 기존 제품을 더 이상 사용하지 않으므로 항상보다 효율적으로 작업을 수행해야합니다. 그럼에도 불구하고 필자는 내가 고안 한 알고리즘에 관한 논문을 발표 한 적이 없다. 그들은 모두 독점적이었습니다. 내가했다면 증거 등을 공식화하기 위해 수학자의 도움이 필요할 것입니다.
그러나 제 생각에는 반복 당 계산 작업의 양은 알고리즘의 확장 성이 좋지 않은 경우 알고리즘의 확장 성보다 더 즉각적인 관심의 대상입니다. 누군가가 레이트 레이싱을위한 최첨단 기술을 생각해 내면이 경쟁적이고 혁신적인 시나리오에서 합리적인 확장 성이 이미 주어지기 때문에 알고리즘 복잡성보다 데이터를 표현하고 액세스하는 방법과 같은 계산 기술에 더 관심이 있습니다. 확장 성이없는 알고리즘은 경쟁에서 벗어날 수 없습니다.
물론 이차 복잡성을 선형 이론과 비교하는 경우에는 큰 차이가 있습니다. 그러나 내 분야의 대부분의 사람들은 서사시 입력에 2 차 복잡성 알고리즘을 적용하지 않도록 충분히 유능합니다. 따라서 확장 성은 깊이 내포되어 있으며 "GPGPU를 사용 했습니까? SIMD? 병렬로 실행됩니까? 데이터를 어떻게 표현 했습니까? 캐시 친화적 인 액세스 패턴을 위해 데이터를 재구성 했습니까?" 많은 메모리가 필요합니까?이 경우를 강력하게 처리 할 수 있습니까? 특정 처리를 연기하거나 한 번에 모두 수행합니까? "
전자가보다 최적의 패턴으로 메모리에 액세스하거나 멀티 스레딩 및 / 또는 SIMD에 더 적합한 경우 선형 선형 알고리즘조차도 선형 시간 알고리즘보다 성능이 우수 할 수 있습니다. 때로는 선형 알고리즘조차도 이러한 이유로 로그 알고리즘보다 성능이 우수 할 수 있으며 자연 선형 시간 알고리즘은 작은 입력의 로그 알고리즘보다 성능이 우수합니다.
더 중요한 것은 데이터 표현 (메모리 레이아웃, 핫 / 콜드 필드 분할 등의 액세스 패턴 등), 멀티 스레딩, SIMD 및 때때로 GPGPU와 같은 일부 사람들이 "미세 최적화"라고 부르는 것입니다. 모든 사람이 항상 새로운 논문이 출판되는 모든 것을 위해 알맞은 알고리즘을 사용할 수있는 능력을 갖춘 분야에서 알고리즘 마법사를 꺾는 경쟁 우위는 알고리즘 복잡성의 개선에서 직접적이지 않습니다. 계산 효율.
저의 분야는 훌륭한 수학자들이 지배하지만 항상 그들이하는 일의 계산 비용이나 코드 속도를 높이기위한 많은 저급 트릭을 아는 것은 아닙니다. 그것은 훨씬 덜 정교하면서도 더 빠르고 더 엄격한 알고리즘과 데이터 구조를 고안하는 데있어 일반적으로 저의 우위입니다. 나는 정말 정교한 알고리즘보다 몇 번 더 작업을 반복하더라도 하드웨어가 좋아하는 것을 비트와 바이트로 재생하고 각 반복 작업을 훨씬 저렴하게 만듭니다. 제 경우에는 작업이 훨씬 저렴합니다. 내가 작성한 코드도 훨씬 간단한 경향이 있습니다. 사람들이 마이크로 최적화 버전의 간단한 알고리즘과 데이터 구조를 이해하고 유지하기 어렵다고 생각한다면,
기본적인 예로, 충돌 감지 및 중복 포인트 제거를 위해 회사에서 KD- 트리를 능가하는 간단한 그리드 구조를 생각해 냈습니다. 내 어리석은 조잡한 그리드는 알고리즘이 훨씬 덜 복잡하고 중간 지점을 찾는 그의 새로운 방법으로 KD-tree를 구현 한 사람보다 수학 및 알고리즘 적으로 훨씬 어리석지 만 그리드의 메모리 사용 및 액세스 패턴을 조정했습니다. 그것은 훨씬 더 정교한 것을 능가하기에 충분했습니다.
내가 가진 것보다 훨씬 똑똑한 사람들이 지배하는 분야에서 살아남을 수있는 또 다른 장점은 내가 개발 한 소프트웨어를 사용하기 때문에 사용자가 어떻게 작동하는지 이해하는 것입니다. 그것은 사용자 관심사와 매우 즉시 일치하는 알고리즘에 대한 아이디어를 제공합니다. 기본적인 예로, 대부분의 사람들은 공간 인덱싱을 사용하여 충돌 감지와 같은 것을 가속화하려고합니다. 예를 들어 캐릭터가 얼굴에 손을 대면 공간 인덱싱 구조는 노드를 분할하고 캐릭터가 비싼 경우 업데이트를 수행 해야하는 유기적 모델에 대해 거의 20 년 전에 간단한 경력 형성 관찰을했습니다. 얼굴에서 손을 took습니다. 대신 정점 위치가 아닌 연결 데이터를 기반으로 분할하는 경우, 매우 빠르게 업데이트되고 트리를 분할하거나 다시 균형을 조정할 필요가없는 안정적인 계층 구조로 끝날 수 있습니다 (애니메이션 프레임마다 경계 상자를 업데이트하기 만하면됩니다) ...이 같은 것-무거운 수학적 배경이없는 아이 알고리즘 기본 개념을 이해했다면 결과를 얻을 수 있었지만, 사용자가 작업 방식에 너무 근접한 방식으로 생각하지 않았기 때문에 수학자들을 피하게 된 개념은 기하학이 아닌 기하학의 속성에 대해서만 너무 많이 생각하고있었습니다. 일반적으로 사용되었습니다. 알고리즘 마법사보다 일반적인 계산 지식과 사용자 엔드 지식에 더 집중함으로써 충분히 잘 지냅니다. 어쨌든 알고리즘 복잡성에 중점을 두는 것이 실제로 중요하지 않다는 것을 알았습니다.
면담에서 묻는 질문은 당신이 사물 을 설명 하고 논리적으로 생각할 수 있는지 알아 내기 위한 것 입니다. 면접관은 또한 당신이 관련된 문제를 해결하기 위해 알고있는 것을 사용할 수 있는지 알아 내려고 노력하고 있습니다 .
소프트웨어 엔지니어링에 대한 가치있는 연구를 해 본 사람이라면 누구나 "Big O"를 발견했을 것입니다. 또한 "Big O"에 대한 좋은 질문에 답하기 위해서는 표준 데이터 구조 및 알고리즘에 대해 이해해야합니다.
교직원과 면담 할 때 주어진 세부 기술을 이미 알고있는 사람이 아니라 빨리 일을 배울 수있는 사람을 찾고 있으므로 면접관과 면담자가 공통적으로 이해하는 질문을 선택하기가 매우 어려울 수 있습니다 의.
따라서 "big O"에 대한 질문은 인터뷰 프로세스와 매우 관련이 있습니다.
적어도 매년 컴퓨터 프로그래머로서 오랜 기간 동안 누군가가 올바른 데이터 구조와 알고리즘을 이해하지 못하여 느려진 코드를 수정해야했지만 Big O에 대한 자세한 이해 없이이 문제를 해결할 수 있습니다. 그러나 Big O tent을 이해하는 사람들은 처음부터 이러한 문제를 피할 수 없습니다.