코딩시 버그 수를 줄이는 방법은 무엇입니까?


30

누구도 완벽하지 않으며, 우리가 무엇을 하든지, 때때로 버그가있는 코드를 생성 할 것입니다. 새 소프트웨어를 작성하거나 기존 코드를 변경 / 유지할 때 생성하는 버그 수를 줄이는 방법 / 기술은 무엇입니까?


좋은 방법은 더 선행적인 디자인을하는 것입니다 (너무 많지는 않지만 코드를보다 체계적이고 이해하기 쉽게 만들 수 있습니다).
조르지오

답변:


58

화려한 코딩을 피하십시오. 코드가 복잡할수록 버그가있을 가능성이 높습니다. 일반적으로 현대 시스템에서는 명확하게 작성된 코드가 빠르고 작습니다.

사용 가능한 라이브러리를 사용하십시오. 유틸리티 루틴을 작성하는 버그가없는 가장 쉬운 방법은 작성하지 않는 것입니다.

더 복잡한 것들을위한 몇 가지 공식적인 기술을 배우십시오. 복잡한 조건이있는 경우 펜과 종이로 잘 정리하십시오. 이상적으로는 몇 가지 증명 기술을 알고 있어야합니다. 코드가 정확하다는 것을 증명할 수 있다면, 수정하기 쉬운 크고 멍청한 명백한 버그를 제외하고 거의 항상 좋습니다. 분명히, 이것은 지금까지 갔지만 때로는 작지만 복잡한 것에 대해 공식적으로 추론 할 수 있습니다.

기존 코드의 경우 리팩토링 방법, 종종 자동화 된 도구를 사용하여 동작을 변경하지 않고 코드를 더 읽기 쉽게 만드는 코드를 약간 변경하는 방법에 대해 알아 봅니다.

너무 빨리 아무것도하지 마십시오. 올바른 일을하고, 행한 일을 확인하고,하고있는 일에 대해 생각하기 위해 약간의 시간을 미리 내면 나중에 큰 시간을 할애 할 수 있습니다.

코드를 작성했으면 코드를 잘 활용하십시오. 단위 테스트는 훌륭합니다. 테스트를 미리 작성하는 경우가 많으며, 이는 피드백이 될 수 있습니다 (일관 적으로 수행하면 테스트 중심 개발). 경고 옵션으로 컴파일하고 경고에주의하십시오.

다른 사람이 코드를 보도록하십시오. 공식적인 코드 검토는 좋지만 편리한 시간에 있지 않을 수 있습니다. scm이 비동기식 검토를 허용하지 않는 경우 요청을 가져 오십시오. 친구 확인은 덜 공식적인 검토 일 수 있습니다. 페어 프로그래밍은 두 쌍의 눈이 모든 것을 볼 수있게합니다.


x2-Ryan이 말한 것.
JBR 윌킨슨

2
또한 대부분의 언어는 다소 까다로울 수 있습니다. 가능한 한 까다롭기를 원합니다.

1
"더 복잡한 것들을위한 몇 가지 공식적인 기술을 배우십시오."
Dan Rosenstark

1
@Yar :이 책에서 설명 된 시스템과 같은 것을 기대합니다 : amazon.com/Verification-Sequential-Concurrent-Programs-Computer/… ; 비록 특정 책이 지나치게 건조하고 칙칙하다고 말해야하지만, 아마도 더 좋은 책이있을 것입니다 (그러나 그것은 내가 읽은 유일한 책입니다).
Joeri Sebrechts

30

단위 테스트를 통해 두 번째로 나타나는 버그 수를 줄일 수 있습니다. 코드에서 버그를 발견하면 단위 테스트를 작성하여 나중에 다시 나타나지 않도록하십시오. (또한 모든 경우를 생각하고 수천 단위의 단위 테스트를 미리 작성하는 것은 때로는 어려운 일입니다)


3
"모든 경우를 미리 생각하면"깨끗하고 완전하게 지정된 인터페이스가 만들어 지는데 이는 좋은 일이 될 수 있습니다. 단위 테스트는 테스트를 염두에두고 설계되지 않은 코드에 개조하는 경우에만 작성하기가 어렵습니다.
Mike Seymour

1
가능하다면해야합니다. 불행히도, 대부분의 장소에서 단위 테스트는 단순히 "버그를 빠르게 수정하는 것"이상의 비용이 드는 것으로 여겨졌습니다. 따라서 가능하면 테스트를 미리 작성해야하지만 "비용 효율적인"것으로 보이지 않으면 버그 수정과 함께 작성하면 단위 테스트 작성에 예산을 너무 많이 쓰지 않고 시간이 지남에 따라 테스트를 작성하는 데 도움이됩니다. .
Ryan Hayes

4
"테스트는 버그가 아닌 존재를 보여줍니다." -E. Dijkstra. 즉, 자동화 된 테스트는 소프트웨어 품질을 유지하고 향상시키는 매우 유용한 방법입니다.
limist

9

두 단위 테스트 설명에 +1

그 외에도 컴파일러에서 제공하는 최고 경고 수준을 설정하고 경고가 오류로 처리되는지 확인하십시오. 버그는 종종 "오류"오류에서 숨겨집니다.

마찬가지로 컴파일 타임에 실행되는 정적 분석 도구에 투자하십시오 (이를 추가 수준의 컴파일러 경고로 간주합니다).


정적 분석 주석의 경우 +1 모든 정보를 무료로 얻는 것은 매우 귀중합니다 :)
Morten Jensen

9

언급 된 것 외에도 :

  • 오류 코드를 무시하지 마십시오. 예를 들어 유효한 결과를 얻거나 파일이 성공적으로 생성되었다고 가정하지 마십시오. 언젠가는 무언가가 발생할 것입니다.
  • 코드가 어떤 조건에 절대 들어 가지 않는다고 가정하지 말고 "그 조건을 무시해도 안전합니다".
  • 코드를 테스트 한 다음 다른 사람이 테스트하도록하십시오. 내 자신의 코드를 테스트하는 것이 최악의 사람이라는 것을 알았습니다.
  • 휴식을 취한 다음 코드를 다시 읽고 "명백한 부분을 놓쳤는 지"확인하십시오. 종종 나에게 일어난다.

내가 지금 잊어 버린 다른 많은 것들이 있지만 다른 사람들은 분명히 그것들을 생각할 것입니다. :)


7
조건 X가 발생하지 않을 것이라고 확신하는 경우 조건 X가 발생하면 예외 또는 로깅 등을 통해 알 수 있도록 어설 션을 사용하십시오 .
Frank Shearar

@MetalMikester : 단위 테스트가 좋습니다. 그러나 고급 언어와 우수한 라이브러리를 사용하면 대부분의 하드 버그에 통합 및 회귀 테스트가 필요합니다.
벡터

9

기본 언어는 C ++ 및 Python 임에도 불구하고 상당히 기능적인 프로그래밍 스타일을 개발했습니다. 모든 컨텍스트를 함수 (또는 메소드)에 전달하면 해당 함수가 작업을 수행해야하고 의미있는 데이터를 반환하면 코드가 훨씬 강력 해집니다.

암시 적 상태는 적이며 내 경험상 버그의 # 1 소스입니다. 이 상태는 전역 변수 또는 멤버 변수 일 수 있지만 결과가 함수에 전달되지 않은 항목에 의존하는 경우 문제를 요청합니다. 분명히 상태를 제거하는 것은 불가능하지만 최소화하는 것은 프로그램 신뢰성에 큰 긍정적 영향을 미칩니다.

또한 동료들에게 모든 분기 (예 :? : :)가 버그 일 가능성이 있다고 말합니다. 버그의 징후가 무엇인지 말할 수는 없지만 코드의 조건부 동작이 적을수록 실행 중 코드 적용 범위가 더 일관성이 있기 때문에 버그가 없을 가능성이 높습니다.

이 모든 것들도 성능에 긍정적 인 영향을 미칩니다. 승리!


내 경험상, 방법이 작을 경우 모든 호출에 대해 모든 주를 통과하는 것이 지루해질 수 있습니다. 이 문제는 객체 수명이 짧은 여러 개의 불변 클래스를 사용하여 해결할 수 있습니다. 이렇게하면 임시 상태를 필드로 저장하고 더 이상 상태가 필요 없을 때 객체를 버릴 수 있습니다. :-)
Jørgen Fogh

지루한 상황에 대한 또 다른 고려 사항은 아마도 너무 많은 주를 통과하려고한다는 것입니다. :)
dash-tom-bang

많은 경우에 그것은 사실이지만 종종 그렇지 않습니다. 일부 도메인에서는 변경 가능한 상태 가 많지 않아도 많은 상태에 액세스해야합니다 . 현재 여러 심볼 테이블에 액세스 해야하는 코드 생성기에서 작업하고 있습니다. 나는 그것들을 각각의 모든 방법으로 전달하고 싶지 않습니다.
Jørgen Fogh

8
  • 더 많은 코드를 작성하십시오.
  • 낮은 수준의 영향과 높은 수준의 영향에 대해 생각하십시오
  • 코드에서 생성중인 추상화를 고려하십시오.
  • 가능한 경우 필수적인 복잡성 만 작성하십시오.

나는 "더 적은 것을 쓰면 쓸수록"(IOW는 당신이 이용할 수있는 도구를 알고 사용합니다)로 요약되는 큰 글을 쓸 것입니다. 대신 +1하겠습니다.
Kaz Dragon

1
그러나 적은 코드를 얻으려고 할 때 멋진 코드를 얻지 않도록주의하십시오.
gablin

1
@gablin : 공상은 여러면에서 보는 사람의 눈에 있습니다. 저는 4 년 전에 불완전했을 코드를 오늘 읽고 쓸 수 있습니다. 하스켈은 오늘 나에게 환상적입니다. :)
Paul Nathan

8

약간 덜 기술적 인 답변 : 피곤하거나 (9h / day면 충분 함) 취하거나 '구운'상태 일 때는 프로그래밍하지 마십시오. 피곤할 때 깨끗한 코드를 작성하는 데 필요한 인내심이 없습니다.


2
대부분의 프로그래머는 이것을 깨닫기 위해 보통 몇 년이 걸립니다. 중요한 포인트입니다.
Jeff Davis


5

단위 테스트 및 도구에 관한 몇 가지 훌륭한 답변이 있습니다. 내가 그들에게 추가 할 수있는 유일한 것은 이것입니다 :

가능한 빨리 테스터를 참여 시키십시오

테스트 팀이 있다면 코드 품질의 게이트 키퍼로 취급하고 결함을 잡아내는 함정에 빠지지 마십시오. 대신, 그들과 함께 일하고 가능한 한 빨리 참여하십시오 (민첩한 프로젝트에서는 이것이 프로젝트의 시작부터 이루어 지지만, 실제로 시도하면 항상 더 일찍 참여할 수있는 방법을 찾을 수 있습니다).

  • 테스트 계획이 무엇인지 알아보십시오. 테스트 사례를 검토하십시오. 코드로 모두 다루고 있습니까?
  • 요구 사항에 대한 이해를 요청하십시오. 당신과 같은가요?
  • 탐색 테스트를 수행하기 위해 초기 작업 빌드를 제공하십시오. 개선 사항에 놀랄 것입니다.

테스터와 좋은 관계를 유지한다는 것은 나쁜 가정과 결함이 손상되기 전에 조기에 파악할 수 있음을 의미합니다. 또한 테스터는 제품 설계를 돕고 해결할 시간이있을 때 유용성 문제를 포착 할 수있는 권한이 있다고 생각합니다.


4

정적 분석 도구

FindBugs 와 같은 플러그인 및 앱은 코드를 크롤링하고 잠재적 인 버그 가 있는 곳을 찾습니다 . 변수가 초기화되지 않고 사용되지 않거나 10에서 9 번 나오는 미친 것들이 있으면 버그가 발생하기 쉬워집니다. 이와 같은 도구를 사용하면 뼈가 아직 버그가 아닌 경우에도 헤드가 길 아래로 이동하는 것을 방지 할 수 있습니다.

추신 : 도구가 나쁜지를 알려주는 이유 를 항상 연구해야합니다 . 배우기 위해 아프지 마십시오 (모든 상황에서 모든 것이 옳은 것은 아닙니다).


3

코드 검사 또는 페어 프로그래밍과 같은 다른 형태의 동료 검토.

Fagan 검사와 같은 구조화 된 코드 검토 는 최소한 단위 테스트 만큼 효과적이고 효율적일 수 있으며 경우에 따라 단위 테스트보다 나은 것으로 입증되었습니다. 검사는 소프트웨어 수명주기 초기에 코드 이외의 아티팩트와 함께 사용할 수도 있습니다.

Karl Wiegers의 Software의 Peer Reviews는 이 주제에 관한 훌륭한 책입니다.


2

여기에있는 다른 모든 제안 외에도 가능한 모든 경고를 최고 수준의 민감도로 설정 하고 오류로 처리하십시오. 또한 언어에있는 보푸라기 도구를 사용하십시오.

당신은 될 것이다 깜짝 놀라게 많은 단순한 실수가 경고과 이러한 간단한 것들의 많은 코드에서 실제 버그로 번역에 의해 체포 할 수있는 방법에.


2

여기에 많은 좋은 답변이 있지만 몇 가지 추가하고 싶었습니다. 실제로 요구 사항을 이해해야합니다. 사용자가 요구 사항이 X를 의미한다고 생각하고 프로그래머가 Y를 의미한다고 생각했을 때 많은 버그를 보았습니다. 열악하거나 모호한 요구 사항에 대한 설명을 위해 다시 푸시하십시오. 나는 우리 모두가 뛰어 들고 코딩하는 것을 좋아하지만 이해를 보장하는 데 더 많은 시간을 할애할수록 재 작업과 버그 수정이 줄어 듭니다.

지원하는 비즈니스에 대해 알아보십시오. 요구 사항에 누락되거나 추가 설명이 필요한 사항이있는 경우가 종종 있습니다. 명시된대로 작업 Y를 수행하면 기존 기능 Z가 중단됩니다.

데이터베이스 구조를 이해하십시오. 많은 버그는 구문 적으로 올바른 쿼리의 결과이지만 잘못된 결과를 반환합니다. 결과가 재미있을 때 인식하는 방법을 배웁니다. 복잡한보고 쿼리를 작성하는 경우 항상 기술 전문가가 내 결과를 검토 할 준비가되기 전에 내 결과를 검토하도록하여 필자가 놓친 데이터에서 무언가를 보게됩니다. 그런 다음 자신이 파악한 내용을 메모하고 다음에 비슷한 것을 할 때 기억하십시오.


1

가장 중요한 기술은 시간걸리는 것 같습니다 . 새 모듈을 코딩하는 데 이틀이 필요하다고 생각하지만 보스는 하루 만에 코드를 작성하도록 강요합니다 ... 코드가 더 버그가있을 수 있습니다.

나는 얼마 전에 읽은 책 중 하나는 말했다 당신이 라이브해서는 안 깨진 창문 anotherone 깨진 ... 같은 코딩, 모든 사람이 뭔가 일의 첫 번째 인 관심을 것입니다 도착하면 사람들이 관심이 없기 때문에, 나쁜 그러나 빠르지 만 버그는 많고 디자인과 스타일이 매우 나쁜 지옥 코드 하나는 신경 쓰지 않습니다 .


1

Code-test-code-test 대신 Test-Code-Test 연습을 따릅니다. 이를 통해 유스 케이스를 생각하고 논리를 적절하게 구성 할 수 있습니다.


1

사용 코드 검사 도구 같은 ReSharper에서 또는 같은 IDE를 하게 IntelliJ IDEA 많은 복사 및 붙여 넣기 예를 들어 있다고 변수 지적에 의해 버그와 다른 사람을 "에 기록됩니다,하지만 읽어 본 적이"에 대해 경고한다. 많은 시간을 절약했습니다.


1

놀랍게도, 다음 세 가지 중요한 점은 아직 언급되지 않았습니다.

  • 어설 션을 자유롭게 사용하십시오. 항상 스스로에게 물어봐야 할 질문은 "내가 이것을 주장해야 하는가?"가 아닙니다. "어설 션을 잊어 버린 게 있나요?"

  • 불변성을 선택하십시오. (최종 / 읽기 전용을 자유롭게 사용하십시오.) 변경이 적은 상태 일수록 문제가 더 적을 수 있습니다.

  • 조기 최적화하지 마십시오. 많은 프로그래머들이 성능 문제에 대해주의를 기울여 성능이 문제가 될지 여부를 사전에 알지 않고도 불필요하게 코드를 복잡하게 만들고 설계를 개성있게 만들었습니다. 먼저, 성능을 무시하고 소프트웨어 제품을 학문적 인 방식으로 구축하십시오. 그런 다음 성능이 저하되는지 확인하십시오. (아마도 그렇지 않을 것입니다.) 성능 문제가있는 경우 전체 코드베이스를 조정하고 해킹하는 대신 제품이 성능 요구 사항을 충족하도록 멋지고 공식적인 알고리즘 최적화를 제공 할 수있는 하나 또는 두 곳을 찾으십시오. 여기 저기 클락 사이클.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.