The Daily WTF 한국어 노트

The Daily WTF 한국어

Daily WTF는 알렉스 파파디무리스가 소프트웨어 개발과 기술 세계에 대한 이야기를 기반으로 하는 프로그래밍 지향적 유머 블로그입니다. 주로 프로젝트 문제, 코드 예제 및 IT와 관련된 재미있는 이야기를 중심으로 합니다. 이 사이트에는 많은 개발자들이 직장에서 경험한 이상하고 재미있는 일화들을 포함하는 광범위한 컬렉션을 보유하고 있습니다. 이러한 경험은 항상 기술과 관련이 있지만 기술적이거나 개인적인 측면에서 다양한 경우를 포함합니다.

노트 스레드

TruStage는 생명 보험 회사로, 2026년 7월 10일에 중대한 사이버 보안 사고를 겪었으며, 사고 발생 몇 달 후에도 주요 비즈니스 기능이 부분적으로만 사용 가능했습니다. 회사는 아직 침해의 범위를 파악하기 위해 노력 중이며, 어떤 데이터가 유출되었는지 또는 서비스가 언제 완전히 복구될지는 결정하지 못했습니다. 보험 운영은 영향을 받았지만, 은행 업무를 위해 신용 조합을 지원하는 시스템은 정상적으로 작동했습니다. 이 사건으로 인해 수많은 소송이 제기되었으며, 보험 산업 내 복잡한 중개자 역할을 부각시킵니다.보험 프로세스에는 종종 여러 파트너가 관여합니다. 예를 들어, Ethos는 AI를 사용하여 고객을 보험 상품과 연결하고, Family First Life(FFL)는 TruStage와 같은 회사와 파트너십을 맺습니다. TruStage의 사이버 보안 사고로 인한 결제 처리 불가로 인해 보험 계약이 실효되고 있습니다. 이 실효는 보험 설계사에게는 수수료 손실을, Ethos 및 FFL과 같은 파트너 회사에게는 차지백을 초래합니다.FFL의 사장인 Shawn Meaike는 업계 컨퍼런스에서 Ethos를 공개적으로 비판하며, 파트너십의 "가장 약한 고리"라고 지칭하고 사과를 요구했습니다. Meaike가 Ethos 직원 Dylan Cummings를 무대에서 굴욕감을 준 것은 특히 민망한 순간으로 여겨집니다. 이 모든 상황은 TruStage의 심각한 사이버 보안 및 재해 복구 실패를 보여주며, 고객에게 부정적인 영향을 미치고 업계에 혼란을 야기합니다. 궁극적으로 이 사건은 TruStage의 제도적 무능력과 단일 발행사에 크게 의존하는 AI 기반 보험 스타트업의 문제적인 비즈니스 모델을 드러냅니다.
Greta는 오래된 Pascal 개발 환경에서 작업하던 중, 파일이 실제로 존재함에도 불구하고 프로그램에서 파일이 존재하지 않는다고 보고하는 버그를 발견했습니다. 그녀는 이 문제를 시스템 라이브러리의 FileExists 함수로 추적했습니다. 이 함수는 파일의 마지막 수정 타임스탬프를 가져오는 FileAge에 의존합니다. FileAge는 다시 시간 형식을 변환하기 위해 FileTimeToDosDateTime을 사용합니다. 결정적인 결함은 FileAge가 FileTimeToDosDateTime의 반환 값을 처리하는 방식에 있습니다. FileTimeToDosDateTime은 성공 또는 실패를 나타내기 위해 부울 값을 반환하고, 실패 시 오류 코드를 설정합니다. 그러나 FileAge는 이 부울 반환 값을 확인하지 않습니다. FileTimeToDosDateTime이 실패하면 FileAge는 -1을 반환합니다. 결과적으로 FileExists는 이 -1을 파일이 존재하지 않는 것으로 해석합니다. Greta의 특정 버그의 근본 원인은 파일을 작성하는 프로세스가 "마지막 쓰기 시간"을 설정하지 않았다는 것입니다. 유효한 마지막 쓰기 시간이 없으면 FileTimeToDosDateTime이 실패하고, 이로 인해 FileAge가 -1을 반환하며, 따라서 FileExists는 파일을 잘못하여 존재하지 않는 것으로 보고합니다. 이는 시스템 라이브러리에서 오류 처리에 있는 미묘한 오류가 중요한 기능 버그로 이어지는 일반적인 문제를 강조합니다.
DNS의 CAA 레코드 타입은 도메인 소유자가 자신의 도메인에 대한 인증서를 발급할 수 있는 인증 기관을 지정할 수 있도록 합니다. RFC6844에 처음 정의되었고 RFC8659에 의해 나중에 업데이트되었지만, 핵심 개념은 동일하게 유지됩니다. CAA 레코드의 주요 기능 중 하나는 "Issuer Critical" 플래그로, 인증서 발급 전에 인증 기관이 레코드를 검증하도록 의도되었습니다.이 중요 플래그는 플래그 비트마스크의 비트 0으로 설계되었으며, 이를 활성화하려면 128의 값이 사용되어야 합니다. 그러나 일반적인 오해로 인해 많은 사람들이 비트 7을 중요 플래그로 해석하여 1의 값을 사용했습니다. 이 오해는 RFC를 철저히 읽지 않은 사용자들 사이에서 널리 퍼져 있습니다.Let's Encrypt와 같은 인증서 발급 기관은 딜레마에 직면했습니다. 사양을 엄격하게 준수하고 잘못 구성된 레코드를 거부하거나, 기능성을 유지하기 위해 널리 퍼진 오류를 수용해야 했습니다. 그들은 후자를 선택하여 사실상 1의 값을 중요 플래그의 별칭으로 받아들였습니다. 이 결정은 원래 사양에 대한 엄격한 준수보다 사용자 오류의 실제 현실을 인정합니다.filterCAA를 위한 제공된 Go 코드 스니펫은 이것이 실제로 어떻게 처리되는지 보여줍니다. "issue" 및 "issuewild" 태그를 필터링하고 인식되지 않는 중요 태그도 확인합니다. 특히, 이 코드는 인식되지 않는 중요 태그가 있는지 여부를 결정하기 위해 플래그가 128(올바른 값) 또는 1(일반적으로 사용되는 잘못된 값)로 설정되었는지 확인합니다. 두 값 모두를 포함하는 것은 중요 플래그에 대한 널리 퍼진 사용자 오류를 수용하는 것을 반영합니다.저자는 이러한 플래그에 비트마스크를 사용하는 것이 혼란과 오류를 야기할 때 그 지혜에 의문을 제기하며, 더 간단한 플래그 메커니즘이 더 읽기 쉽고 오류가 적을 수 있다고 제안합니다. 비트마스크의 유용성을 인정하면서도, 이 일화는 복잡성이 실제 구현에서 상당한 운영 문제를 야기할 수 있음을 강조합니다. 기술 사양, 사용자 이해 및 실제 구현 간의 상호 작용은 반복되는 주제입니다.
Vala는 C#과 유사한 기능과 C에 가까운 성능을 갖춘 Gnome을 위해 설계된 프로그래밍 언어입니다. 함수가 제어권을 양보할 수 있도록 하는 async/await 의미론을 사용하여 비동기 프로그래밍을 지원합니다. Vala의 많은 I/O 라이브러리 함수는 make_directory_async와 같이 비동기적입니다. 그러나 핵심 라이브러리에는 디렉토리 체인을 동기적으로 생성하는 create_directory_with_parents의 비동기 버전이 없습니다. 이러한 누락은 비동기적으로 경쟁 조건을 처리하는 복잡성 때문일 가능성이 높습니다. 저자인 Eri는 이 문제를 접하고 사용자 정의 비동기 솔루션을 구현했습니다. Eri의 초기 접근 방식은 리프 노드에서 위쪽으로 디렉토리를 생성하려고 시도하고 누락된 부모를 배열에 수집하는 것을 포함합니다. 그런 다음 이 배열을 역으로 반복하여 디렉토리를 생성합니다. 이 방법은 제어 흐름에 예외 처리를 사용하기 때문에 세련되지 않은 것으로 간주됩니다. Eri는 특히 비동기 경쟁 조건을 관리하는 데 있어 문제의 어려움을 인정합니다. 메인 루프의 약간 개선된 버전이 제시되지만 접근 방식은 복잡합니다. 어색함에도 불구하고 Eri의 솔루션은 누락된 라이브러리 기능을 효과적으로 해결합니다. 저자는 구현된 함수가 올바르게 작동하면 숨겨야 한다고 제안합니다.
은퇴를 앞둔 저자는 훌륭한 급여를 제시하는 전문 소프트웨어 직책으로 헤드헌팅되었습니다. 초기 온보딩 과정은 더뎠고, 처음 6개월은 접근 권한을 기다리는 데 보냈습니다. 면접관인 프레드는 매우 유능했고 저자와 좋은 관계를 형성했습니다. 프레드는 저자에게 회사의 핵심 소프트웨어를 분석하여 이해하고 잠재적으로 현대화하는 임무를 맡겼습니다.저자가 자신의 분석 결과를 발표하기 전에 프레드는 예상치 못하게 사망했습니다. 이 사건은 회사 내부에 혼란을 야기했고, 저자와 같은 계약직 직원은 대부분 잊혀졌습니다. 이후 18개월 동안 저자는 대부분 무시당했고, 이 시간을 개발 환경을 구축하는 데 사용했습니다. 이 기간 동안 그들은 끊임없이 경영진을 비판하는 동료와 함께 일했습니다.저자의 새 관리자는 적대적이고 무시하는 태도를 보였으며, 마지못해 업무를 할당했습니다. 회사는 시스템을 보호하려는 고령의 직원들과 환영받지 못하는 자동화를 도입하려는 신규 직원들로 구성된 것처럼 보였습니다. 저자는 이 정체된 기간 동안 TDWTF 웹사이트에 기고했습니다. 결국 저자는 아무런 불만 없이 해고되었습니다. 이제 그는 은퇴 전 마지막 몇 년을 우체부로 일하고 있습니다. 저자는 업무 관련 스트레스로 인한 사망 위험이 현실적인 위험이라고 강조합니다.
CdXz5zHNQW_tmcjJ0Qed6.jpeg
미니 스플릿 시스템은 비용 효율성과 에너지 효율이 뛰어나 오래된 주택을 개조할 때 널리 사용되지만, 적외선(IR) 리모컨에 의존해야 한다는 점 때문에 홈 오토메이션과의 연동이 복잡해집니다. 이러한 시스템 내부의 온도 변환 로직, 특히 섭씨와 화씨 간 변환 과정에서 흔히 문제가 발생합니다. 미니 스플릿을 홈 오토메이션에 통합하려는 한 오픈소스 프로젝트에서 결함이 있는 온도 변환 방식이 밝혀졌습니다.이 프로젝트의 코드는 섭씨에서 화씨, 화씨에서 섭씨로 변환하는 데 조회 테이블을 사용합니다. 이 테이블에는 구체적이면서도 종종 부정확한 매핑이 포함되어 있어, 표준 변환 공식과 비교했을 때 불일치가 발생합니다. 예를 들어, 18°C는 (반올림 시) 더 정확한 64°F 대신 65°F로 잘못 매핑됩니다. 이러한 조회 테이블의 설계는 정밀한 수학적 계산보다는 변환값을 대략적으로 추정하려는 시도를 시사합니다.저자는 처음에 이것이 취미 프로젝트의 미숙한 최적화라고 생각했으나, 코드 내 주석에 따르면 이는 “리모컨을 기반으로 한 직접 매핑”임이 밝혀졌습니다. 이는 부정확성이 리모컨 자체에서 비롯되었음을 시사합니다. 리모컨은 부동소수점 연산을 효율적으로 처리하지 못할 수 있는 임베디드 마이크로컨트롤러의 한계로 인해 조회 테이블을 사용하는 것으로 보입니다.결과적으로, 사용자가 리모컨에서 72F와 같은 온도를 설정하면, 리모컨은 내부적으로 이를 대략적인 섭씨 값(예: 22.5C)으로 변환한 후 장치에 명령을 전송합니다. 이러한 근사값은 대부분의 상황에서는 “충분히 괜찮은” 수준이지만, 정밀한 자동화에는 불일치를 초래합니다. 저자에 따르면, 근본적인 문제는 취미 프로젝트의 코드나 리모컨 자체가 아니라, 전 세계적으로 비표준 단위(화씨)가 계속 사용되고 있어 이러한 부정확한 변환이 불가피하게 되는 데 있습니다.
레이첼은 새로운 팀에 합류했으며, 그녀의 상사인 제인은 최저 비용으로 위젯 생산을 극대화하는 데 초점을 맞춘 메트릭 중심 접근 방식을 강조했습니다. 자동화된 생산 라인은 복잡한 소프트웨어를 포함했으며, 테스트 제한으로 인해 변경 사항은 실제 생산에서만 검증되었습니다. 레이첼의 초기 임무는 사용자들이 항상 엑셀을 선호했음에도 불구하고, 6개의 데이터베이스에서 데이터를 가져오는 구글 시트 메트릭 대시보드를 업데이트하는 것이었습니다. 팀은 시스템 동작이나 병목 현상을 설명할 상세 데이터 없이 "단위 시간당 생산된 위젯"과 같은 출력 메트릭만 추적했습니다. 예를 들어, 자동화된 품질 관리 스캐너는 위젯 거부 이유나 거부된 항목의 개수조차 직접 기록하지 않았습니다.소프트웨어 변경 사항은 전체 출력 메트릭에 대해 점수화되었으며, 이러한 메트릭은 소프트웨어 자체 외부의 외부 요인에 의해 영향을 받는 노이즈가 많았기 때문에 검증이 어려웠습니다. 거부된 위젯을 기록하는 변경 사항을 구현하려는 레이첼의 시도는 처음에는 환경 문제로 인한 메트릭 회귀로 인해 방해를 받았으며, 그녀의 코드가 원인이 아니었습니다. 제한된 테스트 실행과 메트릭 회귀를 고려해야 할 필요성 때문에 간단한 변경 사항도 검증하는 데 몇 주가 걸릴 수 있었습니다. 레이첼은 유용한 시스템 모델을 구축하기 위해 더 자세한 데이터를 수집하기 위해 코드에 계측을 추가하기 시작했습니다.그러나 제인은 즉각적인 주요 출력 메트릭 개선에 집착했습니다. 그는 그러한 진단 데이터가 "핵심 메트릭"이 아니라고 말하며, 해당 메트릭이 그렇게 작동하는 이유를 이해하기 위해 데이터를 수집하는 것의 가치를 일축했습니다. 이는 시스템 이해에 대한 레이첼의 열망과 최상위 성과 지표에 대한 제인의 초점 사이에 근본적인 충돌을 야기했습니다. 레이첼은 그녀가 최상위 메트릭을 개선하기 위해 만든 모든 변경 사항에 변경 사항의 동작을 설명하기 위한 계측을 포함하도록 하여 타협점을 찾았습니다. 이 전략을 통해 그녀는 메트릭 개선에 대한 제인의 요구를 충족시키면서 시스템의 관찰 가능성을 점진적으로 향상시킬 수 있었습니다. 궁극적으로, 포괄적인 통찰력 없이 최상위 메트릭을 추진하는 것에 비해 복잡한 시스템을 이해하는 것은 낮은 우선순위로 남았습니다.
이 블로그 게시물은 문제가 있는 PHP 코드 조각을 설명합니다. 저자는 혼자 작업하며, 카타르시스와 블랙 유머를 위해 이를 공유합니다. 기밀 유지를 위해 코드는 일반화되었으며, 이는 잠재적으로 불일치를 야기할 수 있습니다. 코드는 데이터를 가져와 반복하고, 지역화를 위해 동적 속성 접근을 사용하여 세부 정보를 검색합니다. 그런 다음 범주 변수를 기반으로 비용을 형식화하며, 임의의 인덱스를 가진 배열 $mot에 접근합니다. 수량 선택 블록 생성 등 광범위한 HTML 문자열 조작이 존재합니다. 코드는 시간 데이터를 위해 JSON을 디코딩하며, 날짜가 문자열로 저장됨을 나타냅니다. 드롭다운 목록은 $mot 배열 값을 사용하여 구성됩니다. 궁극적으로 처리된 데이터는 템플릿에 삽입됩니다. 이 과정은 자식 항목에 대해 반복되며, 거의 중복된 코드로 이어집니다. 또한, 자식 항목은 형제 항목을 가질 수도 있으며, 이는 유사한 코드 로직으로 또 다른 반복을 필요로 합니다. 저자는 원래 프로그래머가 결국 메서드와 함수를 사용하는 법을 배우기를 희망합니다. 제공된 코드 스니펫은 메인 항목 및 자식 항목에 대한 초기 데이터 가져오기 및 처리 루프를 보여줍니다. 여기에는 비용 계산 및 형식화를 위한 복잡한 조건부 로직이 포함됩니다. 지역화 및 통화를 위한 동적 속성 접근이 강조됩니다. 수량 및 시간 선택을 위한 HTML 스니펫의 도입도 언급됩니다. 메인 항목, 자식 항목 및 형제 항목에 대한 코드의 반복적인 특성은 코드베이스를 비효율적으로 만듭니다.
카키스토크라시, 즉 최악의 자질을 가진 자들의 통치가 관련 개념으로 소개된다. 교사인 Jared B는 해리라는 기계공학 교수가 설립한 에듀테크 회사에서 일했던 경험을 공유한다. 해리는 C 인터프리터를 개발하고 이를 기반으로 회사를 설립하여 C 프로그래밍을 활용한 K-12 커리큘럼을 제공했다. 그의 소프트웨어에는 웹 IDE와 원격으로 C 코드를 실행하기 위한 데몬이 포함된 로컬 설치 Windows 버전이 있었다.그러나 이 데몬에는 인증 기능이 없었고 0.0.0.0에 바인딩되어 있어 같은 네트워크상의 모든 도메인이나 컴퓨터가 임의의 C 코드를 실행할 수 있었다. 이러한 심각한 보안 취약점은 해리가 전적으로 고용한 대학원생 개발자들이 인지하지 못한 채 수년간 존재해 왔다. 이 소프트웨어는 수천 대의 학교 컴퓨터에 설치되었다.Jared는 이러한 문제들을 해리에게 보고했고, 해리는 "보안 개선"을 이유로 업데이트를 출시했지만 IT 리더들에게 업데이트의 중요성을 알리지 않았다. Jared는 또한 해리의 다른 웹사이트에서 쿠키 탈취 취약점과 코드 삽입 취약점을 발견했다. 후자의 취약점은 수천 건의 암호화되지 않은 신용카드 거래 기록을 노출시켰다. 이러한 중대한 보안 결함과 데이터 노출에도 불구하고 해리의 회사는 사업을 계속하고 찬사를 받아왔다. 논평자는 이 상황을 오래된 기술에 갇혀 있었지만 교육 시스템을 위험에 빠뜨리지 않았던 자신이 알던 사람과 대조한다.
CdXz5zHNQW_B1k6IsjyP4.png
저자는 좋지 않은 소프트웨어 문서의 좌절감과 훨씬 더 큰 어려움을 야기하는 잘못 작성된 하드웨어 데이터시트를 대조합니다. 집적 회로에 대한 정확하고 완전한 문서를 찾는 것은 개발자에게 매우 중요합니다. 데이터시트는 종종 불완전하거나, 부정확하거나, 심지어 다른 언어로 되어 있기도 합니다. 현대 칩의 복잡성은 상세한 데이터시트를 필요로 하지만, 일부 공급업체는 부적절한 정보를 제공하여 사용자가 기능을 역설계하도록 강요합니다. 데이터시트와 실제 칩 동작 간의 불일치는 전원 핀을 잘못 식별하거나 부품을 손상시키는 것과 같은 치명적인 오류로 이어질 수 있습니다. 일부 공급업체는 훌륭한 데이터시트를 생산하지만, 임베디드 분야의 비용 고려 사항은 종종 문서화가 제대로 되지 않은 하드웨어로 이어집니다. 저자는 칩의 데이터시트가 "Super User Fantastic Feature Enable Register"를 설명했던 특정 사례를 회상합니다. 이 레지스터는 개발자가 어려운 임베디드 프로젝트를 경험한 것을 반영하여 "SUFFER"로 재미있게 축약되었습니다. 이 기능을 활성화하는 것은 고급 사용자가 디버깅 동작을 변경하도록 의도되었습니다. 이 레지스터의 리셋 값은 모두 1이었으며, 이는 기본적으로 활성화되어 있음을 나타냅니다. "SUFFER" 레지스터라는 이름은 이러한 어려운 문서 작업을 처리하는 느낌을 적절하게 포착합니다.
저자는 한 Microsoft 플랫폼에서 다른 플랫폼으로의 데이터 마이그레이션에 대해 설명하며, 예상치 못한 문제가 발생했습니다. 처음에는 SSIS가 데이터 추출 및 로드를 처리했지만, 저자는 더 나은 제어를 위해 PowerShell로 전환했습니다. 목표는 SharePoint 온프레미스에서 SQL Server 데이터베이스로 고객 문서 및 메타데이터를 마이그레이션하는 것이었습니다. 핵심 필드인 고객 번호는 SharePoint에서 Number 유형으로 저장되었습니다. 내부적으로 SharePoint의 Number 필드는 Double로 표현되며, 이는 10자리 숫자를 정확하게 저장하기에 충분합니다. 그러나 SSIS에서 생성된 SQL Server 스키마는 이 필드에 'float' 데이터 유형을 사용했습니다. 저자는 PowerShell 스크립트의 '.Net' 유형 'float'가 SQL Server의 'float' 유형과 완벽하게 일치할 것이라고 잘못 가정했습니다. SQL Server의 'float'는 기본적으로 배정밀도를 사용하지만 저자는 이러한 표현의 차이를 인지하지 못했기 때문에 이 불일치가 발생했습니다. 결과적으로 숫자가 전송되고 변환될 때, 정밀도 손실로 인해 큰 고객 번호의 마지막 몇 자리가 손실되었습니다. 테스터들은 처음에는 오류를 놓쳤지만, 전체 데이터 로드 중에 발견되었습니다. 팀은 마이그레이션 후 손상된 숫자를 식별하고 수동으로 수정해야 했습니다.
CdXz5zHNQW_ElgNsoYbYY.jpeg
CdXz5zHNQW_LSUkNG7WkF.png
화자는 기술 지원 부서의 드론으로, 승진을 거부하고 회사에 사직서를 제출하기로 결정했습니다. 얼마 지나지 않아 신임 인사부장인 레일라가 화자에게 임원층으로 오라는 이메일을 보냈고, 이는 화자에게 긴장감과 호기심을 불러일으켰습니다. 화자는 레일라를 만났고, 레일라는 화자의 사망한 멘토인 애기의 죽음에 대한 애도를 표했습니다. 레일라는 화자가 신고했던 문제 있는 관리자를 해고했다고 밝히며 유대감을 형성했습니다. 그런 다음 레일라는 화자에게 상당한 승진과 내부 채용 권한을 부여하는 새로운 변화 관리 팀의 리더 자리를 제안했습니다. 화자는 매력적인 제안에도 불구하고 친구들과 함께 프리랜서로 일하겠다는 원래 계획을 고수하기로 결정했습니다. 레일라는 이 결정을 우아하게 받아들였고, 지원을 제안하며 화자의 퇴사에 대한 슬픔을 표현했습니다. 화자는 이후 친구인 메건과 레이날도에게 레일라의 제안에 대해 알렸지만, 그들 역시 프리랜서 계획에 전념하고 있었습니다. 산제이도 그들의 프리랜서 사업에 합류했고, 전 동료인 "드라큘라"가 첫 번째 고객 추천을 해주었습니다. 화자와 친구들은 경비를 충당하는 수평적 계층 구조의 회사인 "RD IT Solutions"를 설립하고 기업가 정신의 어려움을 헤쳐나가기 시작했습니다. 화자는 새로운 목적의식을 느끼고 과거의 불안감에서 벗어나 더 건강한 생활 방식을 누렸습니다. 그들의 첫 번째 고객은 웹사이트 코드를 팩스로 요청하는 예상치 못한 어려움을 안겨주었습니다.
이 게시물은 기술이 시간을 잘못 처리하여 터무니없는 상황을 초래한 여러 사례를 유머러스하게 탐구합니다. Robert는 OnePlus로부터 배송 날짜가 "어제"라고 명시된 이메일을 받았는데, 이는 운전자가 시간 여행을 해야 함을 암시합니다. Kinkster는 Fetlife에서 흥미로운 버그를 발견했는데, 신규 회원의 프로필 사진이 커뮤니티에 가입하기 한 시간 전에 게시된 것처럼 보였습니다. ERIC P.는 2008년 포드 차량의 사진을 공유했는데, 이 차량은 GPS 날짜 롤오버 버그를 겪어 1024주 전의 날짜를 표시했습니다. Marc Würth는 Netvibes에서 피드가 정상화되기 전에 261년 후의 시점으로 가져와지는 이상한 크롤링 통계를 관찰했습니다. 익명의 사용자는 로마의 브리튼 정복 이전에 소포를 받았다고 농담으로 보고했으며, 통합 알림 날짜가 기본적으로 유닉스 타임스탬프로 설정되었습니다. 이러한 일화는 날짜 및 시간 계산과 관련된 일반적인 소프트웨어 오류를 강조합니다. 이 게시물은 이러한 무작위적인 버그를 시간 여행이라는 주제와 연결합니다. 시간 처리 코드가 예상치 못한 방식으로 실패하는 경우가 얼마나 많은지를 강조합니다. 소개된 예시는 다양한 유형의 소프트웨어 및 하드웨어를 아우릅니다. 각 사례는 프로그래밍 문제에 대한 가벼운 시각을 제공합니다.
CdXz5zHNQW_YVzQh2u0YS.png
Frederick A.는 ConferenceService 클래스의 IsCalling 메서드에서 null 검사 문제를 공유합니다. 이 메서드는 잠재적으로 null인 객체 체인인 m_ConnectionService.Core.State.IsWebRTCConnected에 접근하여 웹 컨퍼런스가 활성 상태인지 확인하려고 합니다. 원래 코드는 잠재적인 NullReferenceException을 처리하기 위해 try/catch 블록을 사용하며, 체인의 일부라도 null이면 false를 반환합니다. 이 접근 방식은 초기화되지 않은 객체의 근본적인 문제를 효과적으로 숨깁니다. Frederick은 C# null 병합 연산자(?.)를 직접적인 수정으로 사용할 것을 제안하며, 이는 다음과 같이 체인의 객체가 null이면 간결하게 false를 반환합니다: m_ConnectionService?.Core?.State?.IsWebRTCConnected ?? false. 이것은 기능적인 해결책이지만, 작성자는 이것이 더 깊은 아키텍처 문제에 대한 근본적인 수정은 아니라고 주장합니다. 핵심 문제는 연결 상태가 관리되는 방식에 있으며, 이는 적절한 상태 머신으로 처리되어야 한다고 제안합니다. 중요한 상태 정보에 대해 부울 플래그를 사용하는 깊은 객체 체인에 의존하는 것은 잘못된 설계 선택을 나타냅니다. 완전한 상태 머신 구현이 더 강력한 해결책이 될 것이지만, 작성자는 상당한 리팩토링이 필요하다는 것을 인정합니다. 그러나 이 예시는 개발자들이 이러한 null 검사 복잡성을 피하기 위해 상태 관리 전략을 신중하게 고려하도록 강력하게 상기시켜 줍니다.
"메인프레임에서 흔히 사용되는 플랫 파일 데이터베이스는 고정 폭 필드에 데이터를 저장합니다. "JOHN SMITH 12343rd St"와 같은 일반적인 항목은 "JOHN"이 8자, "SMITH"가 8자 등을 차지한다는 것을 아는 것에 의존합니다. 이러한 엄격한 구조는 중간 이니셜 추가와 같은 수정 작업을 매우 어렵게 만들며, 종종 새로운 테이블, 데이터 마이그레이션, 그리고 모든 소비 소프트웨어의 업데이트를 필요로 합니다.이를 완화하기 위해 숙련된 개발자들은 레코드 내에 추가 문자를 예약하는 "패딩"을 도입했습니다. 예를 들어, 레코드는 사용되지 않은 16자의 공간으로 끝날 수 있습니다. 중간 이니셜과 같은 새로운 필드가 필요할 때, 패딩을 줄여서 삽입할 수 있으며, 전체 레코드 길이에 대한 변경을 피할 수 있습니다. 이 방법은 우아하지는 않지만, 비용이 많이 드는 스키마 재작업과 데이터 셔플링을 방지합니다.패딩은 종종 레코드 전체에 분산되어 새로운 열이 이러한 예약된 공간을 소비할 수 있도록 합니다. 결국 패딩이 부족해질 수 있지만, 이 전략은 주요 개편 없이 플랫 파일 스키마의 운영 수명을 크게 연장합니다.브렌다의 팀은 이러한 VSAM 플랫 파일을 사용하는 메인프레임 시스템을 지원했으며, 이는 현대적인 RDBMS로의 데이터 추출을 필요로 했습니다. ETL 프로세스가 생성되었고, 메인프레임 팀은 파일 구조를 자세히 설명하는 "카피북"을 제공했습니다.그러나 ETL 개발자들은 패딩을 잘못 처리하여 필드를 분할했고, 패딩의 일부가 별도의 데이터 요소로 취급되었습니다. 처음에는 패딩 문자가 보고서에서 제거되고 필드를 연결하여 재구성이 이루어졌기 때문에 무해해 보였습니다.결정적인 오류는 패딩을 소비하는 인플라이트 기능이 없는 프로덕션 메인프레임에 대해서만 테스트했다는 것입니다. 이러한 기능이 프로덕션 메인프레임에서 라이브로 전환되었을 때, ETL 프로세스에서 생성된 보고서는 이제 사용된 패딩의 불필요한 데이터로 손상되었습니다.ETL 개발자들은 계약자였고 그들의 솔루션은 제한된 테스트를 기반으로 "설계대로 작동했기" 때문에 재작업을 거부했습니다. 결과적으로 메인프레임 팀은 기존 보고서에 영향을 미치지 않기 위해 대체 패딩 필드를 찾아야 했습니다."
.NET의 TimeSpan 구조체 소스 코드에는 해당 기능에 대한 설명을 담은 주석이 포함되어 있습니다. TimeSpan은 양수 또는 음수일 수 있는 기간을 나타냅니다. 내부적으로는 밀리초 단위로 저장됩니다. 이 표현 방식은 시간이나 일과 같은 단위에는 잘 작동하지만, 더 긴 기간에는 부정확해집니다. 예를 들어, 월은 28일에서 31일까지 길이가 다양할 수 있습니다. 마찬가지로, 1년은 365일 또는 366일이 될 수 있으며, 10년에는 1개에서 3개의 윤년이 포함될 수 있습니다. 이러한 불일치 때문에 TimeSpan 구조체는 연도 또는 월에 대한 메서드를 제공하지 않습니다. 연도에 대해 언급된 "364일"은 작성자가 "fat-finger typo"라고 부르는 사소한 오류이며 코드의 동작에는 영향을 미치지 않습니다. 이 주석은 12년 동안 변경 없이 코드에 그대로 남아 있었습니다. 본질적으로 밀리초 래퍼인 TimeSpan 클래스 자체도 변경된 바가 없습니다. 월 또는 연도를 더하는 것과 같은 더 복잡한 날짜 계산은 다른 날짜-시간 객체에서 처리됩니다. 큰 문제는 아니지만, 주석과 클래스의 역사는 주목할 만합니다. TimeSpan 클래스는 또한 사용 중단된 생성자와 Silverlight를 포함한 이전 .NET 버전에 대한 컴파일 타임 지원을 보여줍니다. 이미 사라진 기술인 Silverlight는 이 클래스의 오랜 존재감을 강조합니다.
Windows Presentation Foundation는 Windows용 UI 프레임워크로, 컨트롤을 데이터 바인딩할 수 있게 해줍니다. 즉, 텍스트 상자를 모델 클래스의 숫자 필드에 연결할 수 있습니다. 이 프레임워크는 사용자 지정 유형을 변환하는 방법에 대한 지침이 필요하며, 여기서 IValueConverter 인터페이스가 사용됩니다. 이 인터페이스는 Convert와 ConvertBack의 두 가지 메서드를 가지고 있으며, 이를 사용하여 유형 간에 데이터를 변환할 수 있습니다. 이 인터페이스를 구현하는 클래스는 예를 들어 색상을 브러시로 변환하는 데 사용될 수 있습니다. 그러나 이 인터페이스의 API는 호감받지 못하며, 명명 규칙이 혼란스러울 수 있습니다. Fredrika의 제출은 텍스트 상자를 double 필드에 바인딩할 때 빈 문자열을 null로 변환하지 않는 내장 컨버터의 문제를 강조합니다. 이 문제를 해결하기 위해 사용자 지정 컨버터가 작성되었지만, 변수 이름이 잘못 지정되고 논리가 불분명하여 구현이 이상적이지 않습니다. 컨버터는 변환할 때 값을 double로 캐스팅하고, 다시 변환할 때 문자열로 캐스팅하므로 혼란을 야기할 수 있습니다. WPF에서 컨버터를 사용하는 전반적인 접근 방식은 호감받지 못하며, 이 구현은 문제를 명확히 하는 데 도움이 되지 않습니다. 빈 텍스트 상자를 null 값으로 취급하기 위해 컨버터를 사용하는 것은 향후 문제를 야기할 수도 있습니다. 전반적으로 컨버터 API와 이 경우의 구현은 잘 설계되지 않았으며 혼란과 잠재적인 문제를 야기할 수 있습니다.
화자는 갑작스러운 질병으로 사망한 친구이자 멘토인 애기 쇼(Aggie Shaw)의 갑작스러운 상실에 대처하기 위해 고군분투하고 있습니다. 화자는 슬픔에 압도되어 상사의 기대에도 불구하고 평소처럼 업무에 복귀하는 것이 불가능하다고 느낍니다. 그들은 감정을 처리하고 상실을 받아들이기 위해 유급 휴가를 사용하기 시작합니다. 화자의 친구 메건이 연락하여 만나자고 제안하며, 절실히 필요한 경청과 위안을 제공합니다. 만남 동안 화자는 직장에 대한 자신의 감정과 좌절감을 털어놓고, 메건은 동등한 파트너와 함께 자신들만의 IT 그룹을 시작할 수 있다고 제안합니다. 화자는 이 아이디어에 영감을 받아 프리랜서로 일하거나 메건과 함께 새로운 사업을 시작하는 등 다양한 옵션을 탐색하기 시작합니다. 조사하고 계획하면서 위험과 불확실성에도 불구하고 목적의식과 흥분을 느낍니다. 화자는 직장으로 돌아가지만, 2주간의 통지를 하고 새로운 미래를 계획하기 위해서입니다. 그들은 애기의 옛 사무실에서 애기의 존재를 상징하는 고무 오리를 발견하고, 이는 그들에게 연결감과 앞으로 나아갈 동기를 부여합니다. 화자는 메건과 함께 옛 직장을 뒤로하고 새로운 장을 시작하기로 결심합니다. 화자가 직장을 그만두기로 한 결정은 단순히 어려운 업무 환경에서 벗어나기 위한 것이 아니라, 새로운 목적의식과 성취감을 찾기 위한 것입니다.
CdXz5zHNQW_k8sU0XsDKx.png
레미는 불쾌한 날씨 때문에 어둡고 환기가 안 되는 동굴로 후퇴하자고 유머러스하게 제안합니다. 이러한 감정은 관리자들이 괴짜 소프트웨어 개발자들을 용인했던 과거 직장 역학 관계를 반영합니다. 90년대 후반, IT 붐과 함께 관리자들은 개발자들의 특이한 행동에 익숙해져 있었습니다. 훌륭한 추천서를 받은 스텐을 채용하면서 배리와 그의 팀은 괴짜스러움에 대비했습니다.첫날, 스텐은 자연광이 없고 환기구를 닫을 수 있는 작업 공간을 요청했습니다. 배리는 지하에서 스텐의 사무실을 발견했고, 스텐은 형광등을 제거하여 공간을 어둡게 하고 있었습니다. 스텐은 자신을 "스텐"이라고 지칭하며 대명사를 혼란스럽게 사용하는 등 오직 3인칭으로만 말했습니다. 그는 또한 많은 양의 비타민과 이상한 냄새가 나는 차를 마셨습니다.스텐의 코딩 스타일도 마찬가지로 특이했는데, 모든 변수와 메서드에 여자 이름들을 사용했으며, 이는 그의 여자친구들이라고 주장하는 사람들의 이름을 따서 지은 것이었습니다. 일부 명명 규칙이 존재했지만, 문서화되지 않았고 해독하기 어려웠습니다. 코드 리뷰는 복잡한 서사가 되었고, 실제 로직을 이해하기 어렵게 만들었습니다.그의 괴짜스러움과 코딩 스타일에도 불구하고, 스텐의 주된 몰락은 느린 생산성이었습니다. 그는 팀의 요구 사항을 따라가지 못했고, 결국 해고되었습니다. 배리는 나중에 다른 회사에 조심스러운 추천서를 제공하며, 스텐에게 자신의 코드를 설명하도록 하라고 제안했습니다. 그 회사는 스텐을 채용하지 않았고, 배리는 감사 선물 바구니를 받았습니다.
기술자들은 제대로 관리되지 않은 인프라와 비정상적인 해결책으로 인해 반복되는 문제에 직면합니다. 흔한 문제 중 하나는 전력이 부족한 에어컨에서 발생하며, 이는 서버실 문이 열려 있는 근처에서 넘어질 위험에 주의하라는 경고를 유발합니다. 또 다른 기술자는 광범위한 문제 해결과 회선 테스트에도 불구하고 습한 날씨에만 간헐적으로 작동하는 팩스 기계로 어려움을 겪었습니다. 이 문제는 결국 케이블이 보호되지 않은 채 방치된 노출된 통신 사업자 금고에서 비롯되었으며, 경영진에게 사진 증거가 전송된 후 신속하게 수정되었습니다.또 다른 불안한 발견은 소프트웨어 회사 내 나무 서버 랙 위에 임의로 놓인 "오프사이트 백업" 드라이브와 관련이 있었습니다. 임시방편적인 해결책의 추가적인 예로는 표준 전기 관행에서 벗어나 적절한 설치 대신 노출된 연결을 선호하는 비정상적인 배선 사용이 있습니다. 맨해튼의 한 호텔은 네트워크 장비가 공용 계단에서 케이블에 위태롭게 매달려 있고 전혀 고정되지 않은 상태임을 드러냈습니다. 중국에서는 금속 가공 공장의 기둥에 몇 미터 높이로 볼트로 고정된 스위치가 발견되어 산업 환경에서의 더욱 특이한 설치를 강조했습니다.이러한 사건들은 다양한 환경에 걸쳐 IT 인프라 관리에서 전문적인 표준의 만연한 부족을 강조합니다. 이는 모범 사례를 준수하기보다는 즉흥적인 대처와 방치를 보여주는 패턴을 시사합니다.
CdXz5zHNQW_LC8T1Da23x.jpeg
제공된 Ruby 코드는 boolean value의 약자인 bv라는 함수를 정의하며, 이는 boolean 값을 보기 좋게 출력하고 문자열로 변환하는 데 사용됩니다. 이 함수는 속성 이름, true 값, false 값, null 값을 각각 나타내는 prop, tv, fv, nv의 네 가지 매개변수를 받습니다. 이 함수는 send 메서드를 사용하여 이름으로 클래스의 멤버에 접근하는데, 이는 문자열을 통한 메타프로그래밍을 허용하는 Ruby 관용구입니다. 이러한 접근 방식은 비 boolean 필드에 대해 "Not Specified"를 반환하는 것과 같이 오해의 소지가 있는 잠재적인 문제를 야기할 수 있습니다. 비 boolean 필드에 함수를 사용하려고 시도하면 대신 예외가 발생해야 한다고 주장됩니다. 속성이 존재하지 않거나 접근하는 것이 매개변수를 받는 함수인 경우 예외가 발생하므로 함수의 동작은 놀라울 수 있습니다. Ruby 문서는 이러한 문제를 피하기 위해 허용되는 boolean 값의 좋은 목록을 갖는 것을 권장합니다. 그러나 문자열을 전달하여 런타임 메타프로그래밍을 사용하는 것은 여전히 문제를 야기하고 코드베이스를 유지 관리하기 어렵게 만들 수 있습니다. 텍스트의 저자는 이 접근 방식을 싫어하며, 더 간단하고 명확하다고 생각하는 C++ 템플릿을 메타프로그래밍에 사용하는 것을 선호합니다. 저자는 사소하지 않은 Ruby 코드베이스가 메타프로그래밍의 사용으로 인해 유지 관리할 수 없게 되는 경우가 많다고 믿습니다. 전반적으로 코드와 그 접근 방식은 문제가 있고 오류가 발생하기 쉬운 것으로 간주됩니다.