아침에 도착하면 어제 저녁에 떠났는데도 소프트웨어가 더 이상 작동하지 않는다는 것을 알게됩니다.
너 뭐하니? 먼저 무엇을 확인합니까? 화를 내지 않고 문제를 해결하기 위해 무엇을합니까? 당신은 당신의 동료를 비난하고 그들에게 직접 가나 요? 그러한 상황에 처하지 않도록 어떻게 할 수 있습니까?
아침에 도착하면 어제 저녁에 떠났는데도 소프트웨어가 더 이상 작동하지 않는다는 것을 알게됩니다.
너 뭐하니? 먼저 무엇을 확인합니까? 화를 내지 않고 문제를 해결하기 위해 무엇을합니까? 당신은 당신의 동료를 비난하고 그들에게 직접 가나 요? 그러한 상황에 처하지 않도록 어떻게 할 수 있습니까?
답변:
일반적인 용의자는 다음과 같습니다.
당신은 그것이 어제 효과가 있다고 생각했지만 하루 종일 일한 후에는 효과가 없다는 것을 깨닫기에는 너무 맹목적이었습니다.
오늘 아침 더 이상 어제 IDE 캐시 메모리에 있던 것을 참조 할 수 없습니다.
워크 스테이션이 어젯밤에 재부팅되었거나 야간 유지 관리 작업으로 / tmp 디렉토리가 지워졌습니다.
코드베이스에 어떤 변화가 생겼습니다 : 누군가 (아마도 자신의) 어제 마지막 컴파일과 오늘 마지막 컴파일 사이에 변경 사항을 적용했는지 확인하십시오.
지원 라이브러리에서 변경된 사항 : 해당 라이브러리가 다시 컴파일되었는지 또는 업그레이드되었는지 확인하십시오. 원인은 특정 라이브러리의 프로젝트 내부이거나 외부에 독립적 인 패키지의 새 버전이 배포 된 경우 외부에있을 수 있습니다.
테스트 환경에서 변경된 사항 : 가상 머신의 새 버전, 수정 된 스텁, 원격 데이터베이스 서버의 변경 사항 ...
컴파일 체인에서 변경된 사항 : Makefile, IDE의 새 버전, 컴파일러, 표준 라이브러리의 변경 사항 ...
1) 오늘 작동하지 않으면 어제 작동하지 않았습니다.
당신 은 그것이 효과가 있다고 생각 했지만 그렇지 않았습니다.
2) 문제가 있으며 해결해야합니다 .
누가이 일에 책임이 있는지 또는 다른 사람을 비난하는 것에 대해 생각하지 마십시오.
어제와 오늘 사이에 아무런 변화가 없다면 (질문을 읽는 것으로 가정 함) 실제로 코드가 작동하기 전에 코드를 테스트하는 데 더 나은 작업을 수행해야 함을 의미합니다.
이러한 상황을 피하려면 적절한 테스팅 및 디버깅 을 수행해야합니다 .
"작업"을 정의하고 코드 루틴의 경계를 테스트하십시오.
이를 수행하는 한 가지 방법은 야간에 자동화 된 광범위한 테스트 세트를 실행하여 다음 날에 문제가 발생했는지 확인하고 문제를 해결할 수 있도록하는 것입니다.
책임을 져야 할 사람을 찾으려고 시도하는 것은 건설적인 것이 아니며 문제를 해결하지 못합니다. 하지마
어제 효과가 있었지만 지금 작동하지 않는 경우 (경쟁 조건과 같은) 비 결정적 동작이 있고 어제 작동 한 것은 운이 좋았거나 그때와 현재 사이에 변화가 있었으며 무엇을 찾아야합니다. 입니다.
상황을 정확히 파악하는 방법은 상황의 세부 사항에 따라 다르지만 항상 원인을 제거하는 데 체계적으로 도움이됩니다. 즉, 한 번에 5 가지 사항을 변경하지 말고 도움이 될 경우 찾기를 중단하십시오. 어떤 특정 문제가 문제를 일으켰는지 확인하고 문제를 해결하는 방법을 적어 3 주 후에 다시 발생할 때 찾아 볼 수 있습니다.
적절한 진단 도구 (디버거, 프로파일 러, 네트워크 분석 도구)를 사용하면 큰 차이를 만들 수 있습니다.
나는 하룻밤 사이에 변경 된 것으로 보이는 코드로 작업했으며 잠시 후에 이것은 밤에 내 코드베이스로 크롤링하는 악의적 인 픽키가 어제 효과가 있었음에도 불구하고 사물을 변경했기 때문이라고 결론지었습니다. 전혀 작동하지 않습니다. 실제로 고전적인 Schroedinbug 스타일에서는 현재 작동하지 않을뿐만 아니라 이전에는 없었던 방법이 없다는 것이 분명합니다 .
시간이 지남에 따라 나는 실제로 pixies가 그것과 아무 관련이 없으며 아마도 내 "집에 갈 시간이 충분할 것"이라는 마지막 실현 가능성이 있음을 깨달았습니다. .
내가 아침에 이것을 만났을 때의 첫 번째 가정은 아마도 내가 작업하고있는 소프트웨어의 기능이나 코너를 책임지는 사람이기 때문에 아마도 내 잘못이라고 생각한다. 두 번째 가정은 지금 그 커피를 얻을 수 있다는 것입니다. 원숭이가 알아낼 수 있다는 것이 명백히 명백하지 않은 경우 (때로는 그렇습니다) 이전 버전의 라이브러리에서 드래그 할 가능성이 높으며 롤백 할 필요가없는 파일을 실수로 롤백했습니다. 확인하지 않고 빌드로 가져온 무언가를 캐시하거나 어딘가에 캐시하십시오. 최근 소스 제어 활동을 수행하면 내가 한 일을 드러내는 경향이 있으며 빌드를 정리하면 종종 잘못된 캐시 버전이 제거됩니다.
때로는 실제로 나와 관련이 없습니다. 누군가가 언급하지 않고 종속성을 업데이트 한 경우 WindowsUpdate는 환경을 변경하여 코드가 작동하지 않는 것을 설치했습니다. 많은 배경 가능성이 있지만 일반적으로 대부분의 사람들처럼 기본적으로 바보입니다.
버전 관리를 사용하십시오. diff를하거나 VCS의 책임 기능을 사용하십시오. :
diff
: 모든 VCS. 다른 버전의 차이점을 보여줍니다.blame
: 예를 들어 git. 누가 무엇을 변경했는지 한 줄씩 표시합니다.자신이나 상사의 잘못이 아닌 버전 제어가없는 경우 파일의 변경 날짜를보고 OS의 로깅 기능을 살펴볼 수 있습니다.
그 외에도 : 모든 것을 다시 컴파일하고 보조 라이브러리도 다시 컴파일하십시오.
물론 : 오류의 원인을 찾은 경우, 침착하게 행동을 취하고, 왜 변경했는지 물어보고, 문제를 설명하고, 두 가지 모두를 행복하게 만드는 해결책을 제안하십시오. 그녀에게 소리 치지 마십시오. 그것은 생산성에 독이 될 것입니다.
전혀 변경 사항이 없으면 시스템에서 변경된 내용을 볼 차례입니다. 예를 들어, 최근 Mac OS 컴퓨터는 일부 구성이 유효하지 않은 새로운 버전의 Apache로 업데이트되었습니다.
git blame
이 존재 몰랐다 ...하지만 AWESOME FCKING 것
자, 오늘이 아니라 "어제 작동 한"코드의 실제 예가 있습니다. 이번 달 초부터입니다.
해당 응용 프로그램은 날짜별로 데이터베이스에서 정보를 가져 오며 기본 동작은 현재 날짜의 데이터를 가져 오는 것입니다. 이것은 8 월 8 일에는 잘 작동했지만 9 일에는 실패했습니다. 이보다 먼저 테스트되지 않았습니다. 또한 9 월 9 일과 10 월 10 일에도 작동했을 것입니다 ...
또 다른 단서는 우리가 영국에 있고 문제의 데이터베이스가 미국에 있다는 것입니다.
따라서 먼저 확인해야 할 사항에 대한 귀하의 질문에 대한 답변은 날짜와 월 필드를 혼합하면 완벽하게 작동하지만 매월 1 일에만 작동하기 때문에 날짜 형식을 지정하는 방법을 다시 확인하는 것입니다.
무언가가 작동을 멈출 때 가장 먼저해야 할 일은 스스로에게 물어 보는 것입니다. 무엇이 바뀌 었습니까?
어제 밤에 효과가 있었지만 오늘 아침에 실패했을 때 분명히 변경된 것은 날짜와 시간입니다. :)
나는 작업중 인 논리의 일부가 날짜에 달려 있고 시간이 지남에 영향을받을 수 있는지 생각하고 싶습니다. 그러한 문제의 원인이 몇 번인지는 놀랍습니다.
이것이 실패하면 여기에 제공된 다른 훌륭한 조언을 따라야합니다.
일종의 짧은 대답 (작성)이지만 요점을 얻는 데 너무 오래 걸림 : 왜 프로그램이 실패 했는지 : Andreas Zeller의 체계적 디버깅 안내서
오늘 코드가 실패하는 이유는 두 가지 뿐이지 만 어제 작동했습니다.
데이터를 봐
테스트하지 않았거나 설명하지 않은 데이터가 있습니다. 데이터가 올바르게 검증되지 않았거나 예상치 못한 논리 조건이 발생할 때까지 논리 오류가 표시되지 않았습니다. 이것은 어제 버그가 있었지만 유효한 데이터 아래 숨겨져 있음을 의미합니다.
몇 주 동안 주문 항목 코드가 정상적으로 실행되었습니다. 나는 어느 날 집에 가서 죽었다. 다음날 조사에 따르면 함수 호출 체인에 버그가 숨겨져 있음이 밝혀졌습니다. 약한 유형의 언어에서 long int를 사용해야했을 때 정수를 선언했습니다. 언어는 숫자가 정수에 맞는 것을 초과했기 때문에 두 언어를 자동으로 변환하지 못했습니다. 주문 번호 32768에서 시스템이 실패했습니다.
변경된 내용보기
그것이 효과가 있었던 이후로 무엇이 바뀌 었는지보십시오. IT 섹션에서 OS 업데이트가 진행 되었습니까? 다른 코더가 프로그램에서 사용하는 코드를 수정 했습니까? 사용자의 권한이 변경 되었습니까? 종종 변경된 내용을 찾으면 버그를 발견하게됩니다.
어려운 JavaScript 오류에 특히 효과적입니다. 기본적으로 코드 절반을 주석 처리하고 오류가 코드의 절반에 해당하는지 확인하십시오. 다시 반으로 진행하십시오.
코드가 잘 캡슐화되어 있으면 시간을 절약 할 수있는 환상적인 스트레스 해소 도구입니다.
유죄 코드를 발견하면 자체 테스트 페이지에서 오류를 격리하는 것이 좋습니다.
물론 그러한 상황에 처하지 않도록 어떻게 할 수 있습니까?
이 질문을 해결하기 위해 CI (Continuous Integration) 를 살펴볼 수 있습니다 . 간단히 말해 CI는 개발자가 하루에 여러 번 자주 모든 코드를 통합하고 테스트하는 프로세스입니다. 다른 모듈을 손상시키는 한 모듈에 대한 변경 사항은 빠르게 발견됩니다.
실제로 CI를 사용하는 대부분의 팀은 CI 서버를 사용합니다 ( Wikipedia 's list 참조 ). CI 서버는 일반적으로 SCM 리포지토리를 모니터링하고 변경 사항이 표시되면 빌드를 시작하도록 설정됩니다. 빌드가 완료되면 일련의 자동 테스트를 실행하고 빌드 및 테스트의 전자 메일 및 / 또는 웹 페이지를 통해 결과를 작성하여 빌드를 유발 한 변경 내용을 게시합니다. 무언가가 빌드 나 테스트를 중단 할 때, 약간의 변경 만 가해 져서 더 빨리 해결되기를 바랍니다.
사용할 CI 서버에 대한 다른 질문이 있으므로 관심을 가질 수 있도록하겠습니다. 개인적으로 저는 Jenkins의 열렬한 팬입니다.
[일이 망가지면 어떻게해야합니까?]
다른 사람들이 이미 말했듯이, 무엇이 고장 났는지 알아 내고 고치려고 노력하십시오. 비난을 시도하는 데 소요되는 시간은 문제를 해결하지 못한 시간입니다.
휴일을 할 때 일반적으로 일어나는 일입니다 :-)
더 진지하게, 나는 먼저 그들에게 말할 것입니다 :
나는 무엇이 잘못되었고 무엇이 뿌리가 될 수 있는지를 조사 할 것이다.
무슨 일이 일어나고 있는지 볼 기회가 생기면 30-60 분 안에 기지 를 만질 것입니다
그 후, 나는 무슨 일이 있었는지, 그리고 아직 수정되지 않은 경우 수정하는 데 걸리는 시간과 적용 가능한 경우 우리가 잃어버린 데이터 (그러나 백업이 좋으므로 결코 발생하지 않는 추정치)의 위험에 처할 수 있습니다 희망적으로).
비난 부분에 관해서는 :
그것이 단지 동료 오타라면, 그것을 언급 할 필요가 없습니다 : 똥이 발생하고 버그로부터의 공포는 그에게 교훈을 주었을 가능성이 높으며 희망적으로 그는 다시는하지 않을 것입니다.
그가 의도적으로 내가하지 말라고 한 일을했다면 (예를 들어 프로덕션 서버의 루트 암호를 새로운 사람에게 제공하고 감독없이 직접 수정하도록 지시하십시오) (예, 이미 일어난 ...) 언급해야합니다.
일반적인 버그 추적 방법이 작동하지 않고 모든 것이 완전히 혼란 스러우면 쉽게 복원 할 수있는 백업을하는 것이 좋습니다.
이것은 오전 8시에서 오후 6 시까 지 자동으로 로컬에서 실행하는 것입니다.
rdiff-backup /path/to/mystuff /path/to/mybackup
간단 해?
무엇이든 복원해야하는 경우
rdiff-backup -r 24h /path/to/mybackup/specific/dir /tmp/restored
rdiff-backup 은 다른 파일 만 저장합니다. Linux, mac 및 win에서 rdiff-backup을 사용할 수 있습니다.
물론 이것이 유일한 백업이되어서는 안됩니다. 그러나 로컬 백업을하는 것은 매우 쉽고 저렴한 방법입니다.
이제는 이것을 일반적인 버그 수정 방법으로 권장하지는 않지만 다른 모든 것이 실패하면 대체입니다.
버그가 이미 존재했지만 외부 요인이나 심각한 시스템 문제로 인해 숨겨져있을 수 있습니다.
이것은 나에게 일어났다. 프로젝트의 두 빌드 사이에서 버그가 발생했습니다. 말 그대로, 우리가 한 유일한 변화 는 기본 라이브러리 중 하나의 최신 빌드로 업데이트하는 것입니다.
당연히 우리는 그들을 비난했습니다. 그러나 그들이 한 유일한 변화 는 더 빠른 컴파일을 위해 헤더를 리팩터링하는 것이었다. 나는 그것이 시스템을 망쳐서는 안된다는 데 동의했다.
많은 디버깅 끝에 문제가 수년간 내 코드 에서 잠복했던 불량 포인터 버그라는 것이 밝혀졌습니다 . 어떻게 든 리팩토링이 실행 파일의 배열을 변경할 때까지 트리거되지 않았습니다.