프로그래밍Perl 개발자 (백엔드/데이터)

Perl에서 이터레이터와 제너레이터는 어떻게 구현되고 작동합니까? 느린 계산의 일반적인 패턴은 무엇이며 그 제한 사항은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변

Perl에는 Python과 같은 네이티브 제너레이터가 없지만 클로저, 렉시컬 변수의 상태 추적 및 제너레이터 함수를 사용하여 느린 계산 및 이터레이터를 구현할 수 있습니다:

sub counter { my $x = shift; return sub { return $x++; }; } my $it = counter(5); print $it->(), ", ", $it->(); # 5, 6

복잡한 이터레이터의 경우 종종 CPAN 모듈(Iterator::Simple, List::Gen)을 사용합니다. 고전적인 느린 패턴은 저장된 상태로 익명 서브프로그램을 반환하는 것입니다.

단점: yield에 대한 기본 지원이 없으며 많은 CPAN 모듈은 합성성이 부족합니다. 재귀는 스택 크기에 제한됩니다.

함정 질문

Perl에서 메모리 부족 없이 무한한 느린 피보나치 수열을 구현할 수 있습니까?

답변: 예, 클로저를 사용하여:

sub fibonacci { my ($a, $b) = (0, 1); return sub { ($a, $b) = ($b, $a+$b); return $a; }; } my $fib = fibonacci(); print $fib->(), ", ", $fib->(), ", ", $fib->();

그러나 결과를 배열에 저장하면 시간이 지남에 따라 메모리가 부족해집니다(즉, 실제로는 생성기만 "느린" 것입니다).

주제에 대한 미세한 사항을 모르는 실제 오류 사례


이야기

프로젝트에서 거대한 파일을 탐색하기 위해 고유한 이터레이터가 작성되었고, 이는 객체 내의 배열을 통해 구현되었습니다. 이터레이터는 전체 파일을 메모리에 로드하여 파일 크기가 증가함에 따라 서비스가 여러 인스턴스 실행 시 OOM을 호출하게 되었습니다.


이야기

보고서의 세부 사항 시퀀스에 대한 클로저 제너레이터는 우연히 큰 입력 데이터 배열에 대한 참조를 유지하여 메모리 누수가 발생하여 가비지 컬렉터가 제대로 작동하지 못하게 했습니다.


이야기

깊이를 추적하지 않고 재귀를 사용하여 복잡한 생성기를 구현하려는 시도는 실제 큰 데이터를 처리할 때 스택 한도를 초과하게 했으며, 예상된 "느린" 탐색 대신에 발생했습니다.