면책조항 : 이 기사는 오로지 재미를 위해 작성되었습니다. 직장에서 그것을 반복하려고 하지 마십시오. 하지만 집에서 하고 싶은 대로 하세요.
우리 개발자들은 정기적으로 버그를 발견합니다. 이는 우리 업무의 일부일 뿐입니다. 그러므로 얼핏 보면 “일부러 버그를 만들 수 있는가?”라는 질문이 떠오른다. 진부해 보일 수도 있습니다. "예, 물론 버그를 작성할 수 있습니다." 그러나 생각해 보면 모든 것이 더 이상 그렇게 명확해 보이지는 않습니다.
사실은 버그가 손상된 코드와 동일하지 않다는 것입니다. 버그는 오류이며 일반적으로 결함입니다.
작업 프로그램.
소프트웨어 문제와 관련된 "버그"라는 용어는 1947년 Harvard Mark II 컴퓨터에서 나방이 오작동을 일으켰을 때 유래되었습니다. 엔지니어들은 문자 그대로 릴레이 중 하나에 나방이 끼어 있는 것을 발견했으며 이를 "실제 버그가 발견된 최초 사례"라고 언급했습니다.
세상은 수학 공식으로 잘 설명되는 것으로 알려져 있습니다. 그리고 공식은 실제로 알고리즘입니다. 따라서 일부 현상을 수학적으로 설명할 수 있다면 결과 공식을 수정하여 때때로 잘못된 결과를 제공하는 것은 사소한 작업이 아닙니다. 그럼에도 불구하고 절망할 때가 아닙니다. 여기서 우리에게 도움이 되는 경계 조건이 올 수 있습니다. 우리는 모두 if index == 0 {…} else if index == n-1 {…}
보았습니다. 경계에는 항상 문제가 있습니다 🤷♀️. 따라서 버그를 생성하는 첫 번째 아이디어를 살펴보겠습니다. 극단적인 경우를 무시합니다 .
일반적으로 배열을 반복하는 것은 잠재적인 버그의 창고입니다. 그 중 가장 흔한 것은 index out of ranges 입니다. 그런 일을 우연히 발견한 적이 없다면 코딩을 해본 적이 없는 것입니다. 불행하게도 이 버그는 너무 유명해서 사람들은 array[safe: index]
와 같은 안전한 배열 래퍼를 작성하기 시작했습니다. 따라서 오늘날 동료들은 이것이 없으면 어떤 코드도 승인하지 않을 것입니다. 시도해 볼 수는 있지만 가능성은 낮습니다…
일반적인 버그에는 스택 오버플로가 포함됩니다. 재귀 알고리즘은 종료 조건이 없을 때 무한히 반복될 수 있습니다. 여기서 재귀는 선택 사항인 것 같습니다. while true
작성하면 완료됩니다. 그러나 이번에도 버그의 인기가 우리에게 불리하게 작용하고 있습니다. 개발자들은 무한 루프의 잠재적인 문제를 잘 알고 있으며, 코드 리뷰에서 그들의 눈은 분명히 이와 같은 것을 발견할 것입니다 👮
교활한 계획을 계속 프로덕션에 적용하려면 종료 조건에 전역 변수를 사용하고 외부에서 조용히 변경해 보세요.
var coditionCounter = 0; class A { func foo() { while coditionCounter < 10 { coditionCounter++; B.boo(); } } } class B { func boo() { coditionCounter--; } }
버그 작성에 관해서는 ChatGPT조차도 도움을 거부한다는 것이 재밌습니다. 어쩌면 프리미엄 구독이 필요할 수도 있습니다… 🤔
긍정적인 측면에서 AI는 버그 없는 코드 작성에 기여하는 일련의 일반 규칙(작은 증분 코드, 코딩 표준 따르기, 단위 테스트 작성 및 bla-bla-bla)을 제공합니다. 우리는 스파게티 코드를 작성하고 SOLID를 잊어버리는 반대 작업을 시도할 수 있습니다. 그러나 이렇게 하면 우리가 작성하는 모든 코드에 대한 통제력을 잃게 됩니다 . 우아한 핀포인트 무기 대신에 우리는 우리의 프로그램을 정복할 수 없는 혼란을 겪게 됩니다.
버그 생성 문제를 해결할 때 하위 작업을 결정하는 것이 좋습니다. 먼저, 몇 가지 드문 경우를 생각해 내야 합니다. 둘째, 코드 검토를 통과하려면 버그를 일반 코드로 위장해야 합니다. 셋째, QA 부서의 관심을 둔화시켜야 합니다. 넷째, 당장 잡히지 마세요. 그러나 이것은 이미 선택 사항입니다.
내 일반적인 조언은 다음과 같습니다(댓글에서 귀하의 조언을 공유합니다).
액세스 수준을 조작합니다 . 다시 되돌리려면 가장 예상치 못한 위치에서 중요한 매개변수의 값을 변경하십시오. 마치 VPN인 것처럼 여러 클래스를 통해 이를 수행하세요.
하위 클래스에 예상치 못한 논리를 구현합니다. 즉, SOLID 에서 L 원칙을 깨뜨립니다 .
class A { func decrease() { x--; } } class B: A { override func decrease() { x++; } }
더 큰 기능에서 교활한 변경 사항을 숨기세요. 줄이 많을수록 좋습니다. 군중 속에서 길을 잃으세요.
끌어오기 요청에도 동일한 원칙을 사용하세요. 소규모 PR에서는 주목받을 확률이 더 높습니다.
버그를 여러 부분으로 나누고 다른 끌어오기 요청 에 넣어보세요. 가능하다면 다른 리뷰어에게도 제공됩니다.
QA의 약점을 찾아 그의 신뢰를 얻으세요. 또는 점검 중에 대화를 통해 주의를 분산시키십시오.
그런데 혹시 하이젠버그(Heisenbug)라고 들어보셨나요? 이는 조사/ 디버깅 중에 사라지거나 동작이 변경되는 버그입니다. 슈뢰딩거의 고양이처럼. 수정 문제가 귀하에게 할당되지 않는 경우 완벽합니다.
heisenbug의 일반적인 예 중 하나는 프로그램이 최적화 컴파일러로 컴파일될 때 나타나는 버그이지만, 동일한 프로그램이 최적화 없이 컴파일될 때는 나타나지 않습니다(디버거로 검사할 목적으로 자주 수행됨). 디버깅하는 동안 최적화된 프로그램이 일반적으로 레지스터에 유지하는 값이 주 메모리로 푸시되는 경우가 많습니다.
자신을 믿으세요! 역사는 매우 심각한 회사에서 버그가 생산에 허용된 사례를 알고 있습니다.
Ariane 5 Flight 501: 가장 비용이 많이 드는 소프트웨어 버그 중 하나는 1996년 클러스터 임무를 수행하는 Ariane 5 로켓이 이륙 후 40초 만에 폭발했을 때 발생했습니다. 실패는 로켓 유도 시스템의 소프트웨어 버그로 거슬러 올라갑니다.
NASA의 화성 기후 궤도선: 1999년 NASA는 소프트웨어 오류로 인해 화성 기후 궤도선을 잃었습니다. 이 소프트웨어는 미터법 단위(뉴턴초) 대신 영국식 단위(파운드초)를 사용하여 우주선이 화성 대기에서 불타게 만들었습니다.
또한 Mario 의 벽 점프나 Civilization 의 Mahatma Gandh 행동과 같은 일부 버그는 기능이 될 수 있습니다.
버그 개발은 알고리즘을 통해 생각하고 가능한 문제를 철저하게 예측하는 능력입니다. 따라서 코드에 버그를 남길 이유가 없더라도 고려해 볼 가치가 있습니다.