code

Perl로 C를 쓰는 사람을 고용해야합니까?

codestyles 2020. 12. 26. 10:06
반응형

Perl로 C를 쓰는 사람을 고용해야합니까?


제 동료 중 한 명이 최근에 취업 후보자를 인터뷰했고 한 명이 Perl 경험이 매우 좋다고 말했습니다.

제 동료는 Perl을 몰랐기 때문에 그는 잠재적 인 고용인이 작성한 (오프 사이트) 코드에 대한 비판을 요청했습니다. 그래서 저는 한 번 살펴보고 제 우려 사항을 그에게 말했습니다 (주요한 것은 원래 댓글이 없다는 것입니다 그리고 우리가 그들에게 충분한 시간을 준 것도 아닙니다).

그러나 코드가 작동하므로 추가 입력 없이는 안된다고 말하는 것이 싫습니다. 또 다른 우려는이 코드가 기본적으로 C로 코딩 한 방식과 정확히 일치한다는 것입니다. Perl을 수행 한 지 한참 지났지 만 (많은 일을하지 않았고, 빠른 스크립트를위한 Python bod에 가깝습니다) 이 사람이 사용한 것보다 훨씬 더 표현력이 풍부한 언어라는 것을 기억하기 위해.

실제 Perl 코더의 의견과 개선 방법에 대한 제안을 찾고 있습니다 (Perl 코더 개선 방법을 알아야하는 이유 ).

또한 한 언어를 완전히 다른 언어로 쓰는 사람들이 고용되어야하는지 (또는 고용되어서는 안되는지)에 대해 서정적 일 수 있습니다. 나는 당신의 주장에 관심이 있지만이 질문은 주로 코드에 대한 비판입니다.

사양은 다음과 같이 CSV 파일을 성공적으로 처리하고 개별 필드를 출력하는 것입니다.

User ID,Name , Level,Numeric ID
pax, Pax Morgan ,admin,0
gt,"  Turner, George" rubbish,user,1
ms,"Mark \"X-Men\" Spencer","guest user",2
ab,, "user","3"

출력은 다음과 같을 것입니다 (잠재적 고용자의 코드가 실제로 이것을 출력 함).

User ID,Name , Level,Numeric ID:
   [User ID]
   [Name]
   [Level]
   [Numeric ID]
pax, Pax Morgan ,admin,0:
   [pax]
   [Pax Morgan]
   [admin]
   [0]
gt,"  Turner, George  " rubbish,user,1:
   [gt]
   [  Turner, George  ]
   [user]
   [1]
ms,"Mark \"X-Men\" Spencer","guest user",2:
   [ms]
   [Mark "X-Men" Spencer]
   [guest user]
   [2]
ab,, "user","3":
   [ab]
   []
   [user]
   [3]

제출 한 코드는 다음과 같습니다.

#!/usr/bin/perl

# Open file.

open (IN, "qq.in") || die "Cannot open qq.in";

# Process every line.

while (<IN>) {
    chomp;
    $line = $_;
    print "$line:\n";

    # Process every field in line.

    while ($line ne "") {
        # Skip spaces and start with empty field.

        if (substr ($line,0,1) eq " ") {
            $line = substr ($line,1);
            next;
        }

        $field = "";
        $minlen = 0;

        # Detect quoted field or otherwise.

        if (substr ($line,0,1) eq "\"") {
            $line = substr ($line,1);
            $pastquote = 0;
            while ($line ne "") {
                # Special handling for quotes (\\ and \").

                if (length ($line) >= 2) {
                    if (substr ($line,0,2) eq "\\\"") {
                        $field = $field . "\"";
                        $line = substr ($line,2);
                        next;
                    }
                    if (substr ($line,0,2) eq "\\\\") {
                        $field = $field . "\\";
                        $line = substr ($line,2);
                        next;
                    }
                }

                # Detect closing quote.

                if (($pastquote == 0) && (substr ($line,0,1) eq "\"")) {
                    $pastquote = 1;
                    $line = substr ($line,1);
                    $minlen = length ($field);
                    next;
                }

                # Only worry about comma if past closing quote.

                if (($pastquote == 1) && (substr ($line,0,1) eq ",")) {
                    $line = substr ($line,1);
                    last;
                }
                $field = $field . substr ($line,0,1);
                $line = substr ($line,1);
            }
        } else {
            while ($line ne "") {
                if (substr ($line,0,1) eq ",") {
                    $line = substr ($line,1);
                    last;
                }
                if ($pastquote == 0) {
                    $field = $field . substr ($line,0,1);
                }
                $line = substr ($line,1);
            }
        }

        # Strip trailing space.

        while ($field ne "") {
            if (length ($field) == $minlen) {
                last;
            }
            if (substr ($field,length ($field)-1,1) eq " ") {
                $field = substr ($field,0, length ($field)-1);
                next;
            }
            last;
        }

        print "   [$field]\n";
    }
}
close (IN);

저는 사람들에게 Perl 프로그래머, C 프로그래머, Java 프로그래머 등을 절대 고용하지 말라고 조언합니다. 좋은 사람을 고용하세요. 내가 Perl을 작성하기 위해 고용 한 프로그래머들은 다른 다양한 언어에도 능숙했습니다. 그들은 좋은 프로그래머 였고 좋은 프로그래머는 여러 언어를 다룰 수 있기 때문에 그들을 고용했습니다.

이제이 코드는 C와 비슷해 보이지만 Perl도 괜찮다고 생각합니다. 당신이 좋은 프로그래머를 고용한다면, 그의 벨트 아래에 약간의 Perl 연습이 있으면 그는 잘 따라갈 것입니다. 사람들은 보조 영역에서 일을 더 간단하게 만드는 정규식의 부족에 대해 불평하고 있지만 그 더러운 CSV 데이터를 구문 분석하는 정규식 솔루션을 누구에게도 원하지 않습니다. 나는 그것을 읽거나 유지하고 싶지 않습니다.

나는 종종 그 반대의 문제가 더 번거 롭다는 것을 알게된다. 좋은 Perl 코드를 작성하는 좋은 프로그래머를 고용하지만 나머지 팀은 Perl의 기초 만 알고 따라갈 수 없다. 이것은 잘못된 형식이나 잘못된 구조와는 아무런 관련이 없으며 고급 주제 (예 : 클로저)에 대한 기술 수준 일뿐입니다.


이 논쟁에서 상황이 약간 뜨거워지고 있습니다. 그래서 이런 일을 어떻게 처리하는지에 대해 더 설명해야한다고 생각합니다. 나는 이것을 정규식 / 정규식 없음 문제로 보지 않습니다. 나는 후보자가했던 방식으로 코드를 작성하지 않았을 것입니다. 그러나 그것은 그다지 중요하지 않습니다.

나도 꽤 형편없는 코드를 작성한다. 첫 번째 패스에서는 일반적으로 구문보다 구조와 프로세스에 대해 더 많이 생각합니다. 나는 그것을 조이기 위해 나중에 돌아 간다. 그렇다고 응시자의 코드가 좋다는 의미는 아니지만 인터뷰에서 처음 통과 한 경우 너무 가혹하게 판단하지 않습니다. 그가 얼마나 많은 시간을 써야했는지 등을 알지 못하기 때문에 내가 작업하는 데 오랜 시간이 걸렸을 것으로 판단하지 않습니다. 인터뷰 질문은 실제 작업을 위해 실제로하려는 일을 할 수 없기 때문에 항상 이상합니다. 처음부터 시작하여 15 분 안에 수행해야한다면 CSV 파서 작성에 대한 질문도 실패 할 것입니다. 사실, 나는 오늘 코드를 가지고 전체 뼈대가되어 그 이상을 낭비했다.

Text :: CSV_XS 의 Pure Perl 사촌 인 Text :: CSV_PP 의 코드를 살펴 보았습니다 . 정규식을 사용하지만 특수한 경우를 처리하는 많은 정규식이 여기에 제시된 코드와 구조적으로 다르지 않습니다. 코드가 많고 다시는 볼 필요가없는 복잡한 코드입니다.

내가 싫어하는 것은 주어진 입력만을 다루는 인터뷰 답변입니다. 아직 발견하지 못했을 수있는 사례를 처리해야하고 향후 문제를 처리 할 수있는 유연성이 필요한 현실 세계에서는 거의 항상 잘못된 일입니다. Stackoverflow에 대한 많은 답변에서도 누락 된 부분이 있습니다. 솔루션의 사고 과정은 나에게 더 많은 것을 알려줍니다. 사람들은 사물에 대한 생각을 바꾸는 것보다 쉽게 ​​언어에 능숙 해집니다. 나는 사람들에게 더 나은 Perl을 작성하는 방법을 가르 칠 수 있지만 대부분의 경우 그들의 웻웨어를 바꿀 수는 없습니다. 그것은 상처와 경험에서 비롯됩니다.

나는 후보자가 해결책을 코드화하거나 후속 질문을하기 위해 거기에 없었기 때문에 그가했던 방식으로 작성한 이유를 추측하지 않을 것입니다. 여기에서 본 다른 솔루션 중 일부의 경우 인터뷰에서 똑같이 가혹할 수 있습니다.

경력은 여정입니다. 나는 모든 사람이 전문가이거나 같은 경험을 할 것이라고 기대하지 않습니다. 사람들이 속임수 나 관용구를 모르기 때문에 글을 쓰면 여행을 계속할 기회를주지 않습니다. 응시자의 코드는 상을받지 못하지만 제안을 고려하여 최종 3 개에 진입하는 것으로 충분했습니다. 그 남자는 거기 일어나서 시도했고, 내 인생에서 본 많은 코드보다 훨씬 더 잘했고, 그것은 나에게 충분합니다.


그의 코드는 약간 장황합니다. Perl은 모듈에 관한 것이므로이를 피하면 삶이 힘들어집니다. 다음은 내가 약 2 분 동안 작성한 글과 동일한 내용입니다.

 #!/usr/bin/env perl

 use strict;
 use warnings;

 use Text::CSV;

 my $parser = Text::CSV->new({
     allow_whitespace   => 1,
     escape_char        => '\\',
     allow_loose_quotes => 1,
 });

 while(my $line = <>){
     $parser->parse($line) or die "Parse error: ". $parser->error_diag;
     my @row = $parser->fields;
     print $line;
     print "\t[$_]\n" for @row;
 }

나는 Perl로 C를 작성하는 것이 C로 Perl을 작성하는 것보다 훨씬 더 나은 상황이라고 주장합니다. SO 팟 캐스트에서 자주 언급되는 것처럼 C를 이해하는 것은 오늘날 모든 개발자 (일부 좋은 개발자조차)가 갖는 미덕입니다. 그들을 고용하고 그들을 위해 Perl Best Practices 의 사본을 사면 당신은 준비 될 것입니다. 모범 사례 후 중급 Perl 의 복사본을 사용하면 문제가 해결 될 수 있습니다.


끔찍하게 관용적 인 Perl은 아니지만 완전히 끔찍한 Perl도 아닙니다 (훨씬 더 컴팩트 할 수 있지만).

두 개의 경고 벨-shebang 라인에는 ' -w'가 포함되지 않고 ' use strict;'도 ' use warnings;' 도 없습니다 . 이것은 매우 오래된 스타일의 Perl입니다. 좋은 Perl 코드는 경고와 엄격을 모두 사용합니다.

이전 스타일의 파일 핸들 사용은 더 이상 권장되지 않지만 자동으로 나쁘지는 않습니다 (아마도 10 년 이상 전에 작성된 코드 일 수 있음).

정규식을 사용하지 않는 것은 좀 더 놀랍습니다. 예를 들면 :

# Process every field in line.
while ($line ne "") {
    # Skip spaces and start with empty field.

    if (substr ($line,0,1) eq " ") {
        $line = substr ($line,1);
        next;
    }

다음과 같이 작성할 수 있습니다.

while ($line ne "") {
    $line =~ s/^\s+//;

이것은 코드가 루프를 반복하지 않고 정규식을 사용하여 모든 선행 공백을 잘라냅니다. 나머지 코드의 상당 부분도 신중하게 작성된 정규 표현식의 이점을 누릴 수 있습니다. 이것들은 특징적으로 Perl 관용구입니다. 그들이 사용되지 않는 것을 보는 것은 놀랍습니다.

효율성이 선언 된 관심사라면 (정규식을 사용하지 않는 이유), 질문은 "측정 했습니까"와 "어떤 종류의 효율성에 대해 논의하고 있습니까-기계 또는 프로그래머"입니까?

작업 코드가 중요합니다. 다소 관용적 인 코드가 더 좋습니다.

물론 CSV 구문 분석을 처리하는 데 사용할 수있는 Text :: CSV 및 Text :: CSV_XS 모듈도 있습니다. 그들이 Perl 모듈을 알고 있는지 문의하는 것은 흥미로울 것입니다.


인용 된 필드 내에서 인용 부호를 처리하기위한 여러 표기법도 있습니다. 코드는 백 슬래시 인용이 적절하다고 가정하는 것 같습니다. Excel에서 이중 따옴표를 사용한다고 생각합니다.

"He said, ""Don't do it"", but they didn't listen"

다음과 일치 할 수 있습니다.

$line =~ /^"([^"]|"")*"/;

약간의주의를 기울이면 따옴표 사이의 텍스트 만 캡처 할 수 있습니다. 포함 된 큰 따옴표를 제거하려면 캡처 된 텍스트를 사후 처리해야합니다.

인용되지 않은 필드는 다음과 일치합니다.

$line =~ /^([^,]*)(?:,|$)/;

이것은 표시된 반복 및 부분 문자열보다 훨씬 짧습니다.


다음은 질문의 코드에 사용 된 백 슬래시-큰 따옴표 이스케이프 메커니즘을 사용하는 코드 버전입니다.

#!/usr/bin/perl -w

use strict;

open (IN, "qq.in") || die "Cannot open qq.in";

while (my $line = <IN>) {
    chomp $line;
    print "$line\n";

    while ($line ne "") {
        $line =~ s/^\s+//;
        my $field = "";
        if ($line =~ m/^"((?:[^"]|\\.)*)"([^,]*)(?:,|$)/) {
            # Quoted field
            $field = "$1$2";
            $line = substr($line, length($field)+2);
            $field =~ s/""/"/g;
        }
        elsif ($line =~ m/^([^,]*)(?:,|$)/) {
            # Unquoted field
            $field = "$1";
            $line = substr($line, length($field));
        }
        else {
            print "WTF?? ($line)\n";
        }
        $line =~ s/^,//;
        print "   [$field]\n";
    }
}
close (IN);

원본의 약 70 개에 비해 공백이 아닌 주석이없는 행이 30 개 미만입니다. 원래 버전은 필요한 것보다 약간 더 큽니다. 그리고 저는이 코드를 가능한 최소한으로 줄이려고 노력하지 않았습니다.


엄격한 / 사용 경고 사용, regexp 대신 substr의 체계적인 사용, 모듈 사용 없음. 이것은 확실히 " 아주 좋은 Perl 경험 "을 가진 사람이 아닙니다 . 적어도 실제 Perl 프로젝트에는 해당되지 않습니다. 여러분과 마찬가지로 저는 Perl에 대한 기본적인 지식을 가진 C 프로그래머 일 것입니다.

특히 주변에 다른 Perl 사람들이 있기 때문에 그들이 배울 수 없다는 의미는 아닙니다. 그것은 그들이 직업에 대한 자격을 과장했다는 것을 의미하는 것 같습니다. 아주 좋은 Perl 경험 을 정확히 어떻게 얻었는지에 대한 몇 가지 질문이 더 있습니다.


그가 정규 표현식을 사용했는지 여부는 상관하지 않습니다. 나는 또한 그의 Perl이 C처럼 보이는지 상관하지 않습니다. 정말 중요한 질문은 이것이 좋은 Perl입니까? 그리고 나는 그것이 아니라고 말하고 싶습니다.

  1. 그는 사용하지 않았다 use strict
  2. 그는 경고를 활성화하지 않았습니다.
  3. 그는 구식의 2 인수 open 버전을 사용하고 있습니다.
  4. "파일 열기"주석은 상처를주고 그가 일반적으로 작성하는 코드에 주석이 포함되어 있지 않다는 인상을줍니다.
  5. 코드는 유지하기 어렵다
  6. 그는 CPAN 모듈을 사용할 수 있었습니까? 훌륭한 Perl 프로그래머는이 옵션을 먼저 살펴볼 것입니다.

나는 여기에 표현 된 대부분의 견해에 동의하지 않습니다.

문제의 코드는 관용적 Perl에서 훨씬 더 간결하고 유지 관리 할 수 ​​있으므로 응시자가이 솔루션을 개발하는 데 얼마나 많은 시간을 소비하는지, 그리고 관용적 Perl을 사용하는 데 익숙한 사람이 얼마나 많은 시간을 소비했는지에 대한 질문을 제기해야합니다.

이 코딩 스타일은 엄청난 시간 낭비 (따라서 회사의 돈)라는 것을 알게 될 것입니다.

나는 모든 Perl 프로그래머가 언어 익힐 필요가 있다고 주장하지 않습니다 . 불행히도 너무 어리석은 일입니다.하지만 그들은 코드에서 핵심 언어 기능을 반복해서 다시 구현하는 데 오랜 시간을 소비하지 않도록 충분히 알고 있어야합니다.

편집 코드를 다시 보면 좀 더 과감해야합니다. 코드가 매우 깨끗해 보이지만 실제로는 끔찍 합니다. 죄송합니다. 이것은 Perl이 아닙니다. "어떤 언어로든 Fortran을 프로그래밍 할 수 있습니다"라는 말을 알고 있습니까? 그래 넌 할수있어. 하지만 그렇게해서는 안됩니다.


이것은 프로그래머에게 후속 조치가 필요한 경우입니다. 이렇게 썼는지 물어보세요 .

아주 좋은 이유가있을 수 있습니다. 아마도 이것은 기존 코드와 동일한 동작을 따라야했기 때문에 완전한 호환성을 위해 의도적으로 한 줄씩 번역을 수행했습니다. 그렇다면 적절한 설명을 위해 포인트를 제공하십시오.

또는 그는 Perl을 몰라서 그날 오후에 질문에 답하기 위해 배웠습니다. 그렇다면 빠르고 민첩한 학습 기술에 대한 점수를 부여하십시오.

유일하게 실격되는 코멘트는 "항상 Perl을 이런 방식으로 프로그래밍합니다. 정규 표현식을 이해하지 못합니다."일 수 있습니다.


나는 그의 코드가 적절한 해결책이라고 말하고 싶습니다. 작동하지 않습니까? 그리고 가능한 한 적은 수의 코드로 작성하는 대신 "긴 손으로"작성함으로써 유지 보수성에 이점이 있습니다.

Perl의 모토는 " 여러 가지 방법이 있습니다."입니다. Perl은 일부 언어처럼 코딩 스타일에 대한 당신의 주장을 받아들이지 않습니다.


작동합니까? 허용되는 기간 내에 작성 했습니까? 유지 보수가 가능하다고 생각하십니까?

이 세 가지 질문에 답할 수 있다면 죽음의 다리 ( * )를 통과 할 수 있습니다 .


제 동료 중 한 명이 최근 일자리를 구하기 위해 몇몇 후보자를 인터뷰했고 한 명이 Perl 경험이 매우 좋다고 말했습니다.

이 사람이 Perl 경험이 매우 좋다고 생각하고 Perl을 이렇게 쓴다면 그는 아마도 Dunning-Kruger 효과 의 희생자 일 것입니다 .

그래서, 그것은 고용하지 않습니다.


가장 큰 문제는 그 또는 그녀가 정규식에 대한 지식을 보여주지 않았다는 것입니다. 이것이 Perl의 핵심입니다.

문제는 그들이 배울 수 있는가? 이 코드 조각을 지나서 후보에서 찾을 것이 너무 많습니다.


I wouldn't accept the candidate. He or she isn't comfortable with Perl's idioms, which will result in suboptimal code, less work efficieny (all those unnecessary lines have to be written!) and a inablilty to read code written by an experienced Perl coder (who of course uses regexes etc. at large).

But it works...


Forgive this guy. I would not have dared to parse CSV with a regex even though it can be done.

The DFA in structured code is more obvious than the regex here and DFA -> regex translation is nontrivial and prone to stupid mistakes.


Just the initial block indicates that he has missed the fundamentals about Perl.

    while ($line ne "") {
    # Skip spaces and start with empty field.

    if (substr ($line,0,1) eq " ") {
        $line = substr ($line,1);
        next;
    }

That should at least be written using a regular expression to remove leading white space. I like the answer from jrockway best, modules rock. Though I would have used regular expressions to do it, something like.

#!/usr/bin/perl -w
#
# $Id$
#

use strict;

open(FD, "< qq.in") || die "Failed to open file.";
while (my $line = <FD>) {
    # Don't like chomp.
    $line =~ s/(\r|\n)//g;
    # ".*?[^\\\\]"  = Match everything between quotations that doesn't end with
    # an escaped quotation, match lazy so we will match the shortest possible.
    # [^",]*?       = Match strings that doesn't have any quotations.
    # If we combine the two above we can match strings that contains quotations
    # anywhere in the string (or doesn't contain quotations at all).
    # Put them together and match lazy again so we can match white-spaces
    # and don't include them in the result.
    my $match_field = '\s*((".*?[^\\\\]"|[^",]*?)*)\s*';
    if (not $line =~ /^$match_field,$match_field,$match_field,$match_field$/) {
        die "Invalid line: $line";
    }
    # Put values in nice variables so we don't have to deal with cryptic $N
    # (and can use $1 in replace).
    my ($user_id, $name, $level, $numeric_id) = ($1, $3, $5, $7);
    print "$line\n";
    for my $field ($user_id, $name, $level, $numeric_id) {
        # If the field starts with a quotation,
        # strip everything after the first unescaped quotation.
        $field =~ s/^"(.*?[^\\\\])".*/$1/g;
        # Now fix all escaped variables (not only quotations).
        $field =~ s/\\(.)/$1/g;
        print "   [$field]\n";
    }
}
close FD;

The fact that he hasn't used a single piece of regex in the code should make you ask him a lot of questions about why he did write like that.

Maybe he's Jamie Zawinski or a fan and he didn't want to have more problems?

I'm not necessarily saying that the whole parsing should be a huge amount of unreadable CSV parsing regex like ("([^"]*|"{2})*"(,|$))|"[^"]*"(,|$)|[^,]+(,|$)|(,) or one of the many similar regex around, but at least to traverse the lines or instead of using substring().


Maybe ask him to write more versions of the same code? When in doubt about hiring, ask more questions to candidate.


Not only does the code suggest that the candidate doesn't really know Perl, but all those lines that say $line = substr ($line,1) are dreadful in any language. Try parsing a long line (say a few thousand fields) using that type of approach and you will see why. It just goes to show the sort of problem that Joel Spolsky discussed in this post.


An obvious question might be, if you don't use Perl at your company in the first place, does it matter how pretty his Perl code is?

I'm not sure the elegance of his Perl code says much about his skills in whatever language you're actually using.


As a non Perl (?programmer?), I have to say, that is probably the most legible Perl I have ever read! :)

Hiring someone over something like a scripting language that can be learned in days to weeks (if it's a worthwhile scripting language!) seems highly flawed in the first place.

Personally I would probably hire this person for different reasons. The code is well structured and reasonably well commented. Language specifics can easily be taught later.


The crucial point here is - naturally after assuring that it works as expected - whether the code is maintainable.

  • Did you understand it?
  • Would you feel comfortable fixing a bug in it?

Perl programs have a tendency for looking like what a cat types by accident when walking on the keyboard. If this person knows how to write readable Perl code that fits to the team, this is actually a good thing.

Then again, you may want to teach him about regular expressions, but only carefully :-)


Code looks clean and readable. For that size, it does not require that much comments (perhaps none at all.) It's not just about good comments, but also good code, and the later is more important than the former.

If we were looking at a more complex/larger piece of code, I would say that comments are needed. But for that (specially the way it was written - well written), I don't think so.

I think it is unfair and vain to put doubt on the applicant given the piece of code submitted by him/her is quite acceptable and did the job.


Hmm, I don't see anything in the request that quotes should be removed, and words should be removed. The input file had the word " rubbish", and it's not in the output.

I've seen CSV files, exported with quotes, would expect those same quotes back. If your specification had been to remove quotes and extraneous words past quotes, maybe this work would be required.

I'd watch that, and the verbosity. Look for somebody lazier (compliment in Perl).

open (IN, "csv.csv");
while (<IN>) {
    #print $_;
    chomp;
    @array = split(/,/,$_);
    print "[User Id] =  $array[0]  [Name] = $array[1]  [Level] =  $array[2] [Numeric ID] = $array[3]\n";    
}

ReferenceURL : https://stackoverflow.com/questions/968441/should-we-hire-someone-who-writes-c-in-perl

반응형