The Daily WTF 日本語 ノート

The Daily WTF 日本語

The Daily WTFは、Alex Papadimoulisが作成したプログラミング志向のユーモアブログです。このブログは、ソフトウェア開発とテクノロジーの世界に関する話を中心にしています。主に、プロジェクトの問題、コードの例、ITに関するおかしな話を基にしています。このサイトには、多くの開発者が仕事で遭遇する奇妙でおかしな体験の膨大なコレクションが含まれており、技術的に関連するものであれば、技術的なものか個人的なものかにかかわらず、すべてがテック関連です。

ノートのスレッド

TruStageは生命保険会社であり、2026年7月10日に重大なサイバーセキュリティインシデントを経験しました。数ヶ月後も主要な事業機能は部分的にしか利用できない状態でした。同社は現在も侵害の範囲を把握しようとしており、どのデータが侵害されたのか、またはサービスがいつ完全に復旧するのかを特定していません。保険業務は影響を受けましたが、信用組合向けの銀行業務をサポートするシステムは稼働を続けていました。このインシデントは多数の訴訟を引き起こし、保険業界における複雑な仲介者の役割を浮き彫りにしています。保険プロセスには、顧客を保険契約に結びつけるためにAIを利用するEthosや、TruStageのような企業と提携するFamily First Life(FFL)など、複数のパートナーが関与することがよくあります。サイバーセキュリティインシデントによりTruStageが支払い処理できなくなったことで、保険契約が失効しています。この失効は、エージェントのコミッションの損失と、EthosやFFLのようなパートナー企業へのチャージバックにつながっています。FFLの社長であるShawn Meaikeは、業界カンファレンスでEthosを公に批判し、彼らをパートナーシップの「最も弱い環」と呼び、謝罪を要求しました。MeaikeがEthosの従業員であるDylan Cummingsをステージ上で辱めたことは、特に気まずい瞬間と見なされています。この一連の状況は、TruStageによる深刻なサイバーセキュリティと災害復旧の失敗を示しており、顧客に悪影響を与え、業界に混乱を引き起こしています。最終的に、このインシデントはTruStageにおける組織的な無能さと、単一の発行者に大きく依存するAI主導の保険スタートアップの、問題のあるビジネスモデルを明らかにしています。
コードの自動フォーマットは、可読性を維持するための標準的かつ不可欠なプラクティスです。エディタに統合されているか、ビルドステップとして実行されるかにかかわらず、何らかの形式の自動フォーマッタを利用しない正当な言い訳はありません。Visual Studio のような多くの IDE でさえ、このプロセスを自動化することに非常に積極的です。これは、古い ASP.Net アプリケーションからのコードサンプルを特に不可解なものにしています。Page_PreInit 関数は完全に 1 行に収まっており、その直後に Page_Load の宣言が続きます。このフォーマットの決定は、Logic() 関数がどこで呼び出されているかについて大きな混乱を引き起こします。元の開発者は、ブラウザ文字列で「Safari」をチェックするためにユーザーエージェントのスニッフィングも実装しました。もし「Safari」が検出された場合、Page.ClientTarget は不可解な「uplevel」値に設定されます。これは、悪い命名規則、ユーザーエージェントのスニッフィング、および列挙型がより適切かもしれない場所で文字列を使用することの組み合わせを示しています。最も懸念されるのは、この問題のあるパターンがアプリケーションの複数のページにわたって繰り返されていることです。これは、開発者が意図的にこの混乱していて読みにくいスタイルを選択し、再利用可能な実行可能なソリューションと見なしたことを示唆しています。
このスクリプトは、すべてのアクティブディレクトリユーザーとその最終ログオン時刻を報告することを目的としていますが、非効率的で複雑なアプローチを採用しています。ユーザーアカウントをフィルタリングするためにアルファベットの各文字を反復処理しますが、これは完全にアルファベット順のソートを保証するものではありません。各文字に対して、新しいDirectorySearcherオブジェクトを作成し、「name」プロパティのみを明示的に要求し、一致するすべての comptes を検索します。その後、取得された各名前に対して、スクリプトはさらに別のDirectorySearcherを作成します。この新しい検索erは、すべてのプロパティを取得するために特定のユーザーアカウントをクエリするために使用されます。ユーザー名の検索では1つの結果のみが期待されますが、FindAll()メソッドが使用され、配列が返されます。これにより、単一要素の配列を反復処理するための不要なループが必要になります。最後に、ユーザー名と最終ログオン時刻をコンマで連結して出力します。スクリプトの設計は、検索erのインスタンス化の繰り返し、冗長なクエリ、および非論理的なフィルタリング方法により、非常に非効率的です。その欠点にもかかわらず、マネージャー向けのCSVを生成できる能力により、組織内で「ミッションクリティカル」となっています。
グレタは、古いPascal開発環境で作業中に、プログラムがファイルの存在を報告しないというバグに遭遇しました。彼女はこの問題をシステムライブラリのFileExists関数にまでたどりました。この関数は、ファイルの最終更新タイムスタンプを取得するFileAgeに依存しています。FileAgeは、さらにFileTimeToDosDateTimeを使用して時間形式を変換します。決定的な欠陥は、FileAgeがFileTimeToDosDateTimeの戻り値を処理する方法にあります。FileTimeToDosDateTimeは、成功または失敗を示すためにブール値を返し、失敗時にはエラーコードを設定します。しかし、FileAgeはこのブール値の戻り値をチェックしません。FileTimeToDosDateTimeが失敗した場合、FileAgeは-1を返します。その結果、FileExistsはこの-1をファイルが存在しないと解釈します。グレタの特定の問題の根本原因は、ファイルを書き込んでいるプロセスが「最終書き込み時刻」を設定していなかったことでした。有効な最終書き込み時刻がないと、FileTimeToDosDateTimeは失敗し、FileAgeは-1を返し、したがってFileExistsは誤ってファイルを存在しないと報告します。これは、システムライブラリで一般的な問題であり、エラー処理における微妙なエラーが重大な機能バグにつながることを浮き彫りにしています。
CdXz5zHNQW_L7qyl0OcGp.jpeg
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のソリューションは、欠けているライブラリ機能を効果的に解決しています。作者は、実装された関数が正しく動作したら隠すべきだと示唆しています。
CdXz5zHNQW_tmcjJ0Qed6.jpeg
ミニスプリットシステムは、コストパフォーマンスとエネルギー効率の高さから、古い住宅の改修に広く利用されていますが、赤外線リモコンに依存しているため、ホームオートメーションとの連携が複雑になります。 これらのシステム内部の温度変換ロジック、特に摂氏と華氏間の変換において、よくある問題が発生します。ミニスプリットをホームオートメーションに統合しようとするオープンソースプロジェクトにより、この温度変換方法に欠陥があることが明らかになりました。このプロジェクトのコードでは、摂氏から華氏、および華氏から摂氏への変換にルックアップテーブルを使用しています。これらのテーブルには特定の(しばしば不正確な)マッピングが含まれており、標準的な変換式と比較して不一致が生じます。例えば、18℃は(四捨五入した場合)より正確な64°Fではなく、誤って65°Fにマッピングされています。 これらのルックアップテーブルの設計からは、正確な数学的計算というよりは、近似的な換算を試みていることがうかがえます。筆者は当初、これを趣味のプロジェクトによる単純な最適化だと考えていましたが、コード内のコメントにより、これらが「リモコンに基づく直接的な対応関係」であることが明らかになりました。これは、不正確さがリモコン自体に起因していることを示しています。 リモコンは、浮動小数点演算を効率的に処理できない可能性のある組み込みマイコンの制限により、ルックアップテーブルを使用していると考えられます。その結果、ユーザーがリモコンで72Fのような温度を設定すると、リモコンは内部でそれを概算の摂氏値(例:22.5C)に変換してから、ユニットにコマンドを送信します。この近似は、ほとんどの状況では「十分」ですが、精密な自動化においては不整合を引き起こします。 著者によれば、根本的な問題は、この趣味のプロジェクトのコードやリモコンそのものではなく、世界的に非標準の単位(華氏)が依然として使用されていることにあり、それがこうした不正確な換算を余儀なくさせているのです。
レイチェルは新しいチームに参加し、そこでは上司のザーンが、最低コストでウィジェット生産を最大化することに焦点を当てた、メトリクス主導のアプローチを強調していました。自動化された生産ラインは複雑なソフトウェアを伴い、テストの制約から、変更は実際の生産でのみ検証されていました。レイチェルの最初のタスクは、ユーザーは常にExcelを好んでいましたが、6つのデータベースからデータを取得するGoogleスプレッドシートのメトリクスダッシュボードを更新することでした。チームは、「単位時間あたりのウィジェット生産数」のような出力メトリクスのみを追跡しており、システムの動作やボトルネックを説明するための詳細なデータはありませんでした。例えば、自動品質管理スキャナーは、ウィジェットが拒否された理由、さらには拒否されたアイテムの数を直接記録していませんでした。ソフトウェアへの変更は全体的な出力メトリクスに対してスコアリングされ、これらのメトリクスはノイズが多く、ソフトウェア自体以外の外部要因の影響を受けていたため、検証が困難でした。拒否されたウィジェットを記録する変更を実装しようとするレイチェルの試みは、当初、彼女のコードではなく環境問題によって引き起こされたメトリクスの後退によって妨げられました。限られたテスト実行とメトリクスの後退を考慮する必要性から、単純な変更でさえ検証に数週間かかることがありました。レイチェルは、有用なシステムモデルを構築することを期待して、より詳細なデータを収集するためにコードにインストルメンテーションを追加し始めました。しかし、ザーンは主要な出力メトリクスの即時改善に固執していました。彼は、そのような診断データは「主要メトリクス」ではないと述べ、それらのメトリクスがそのように動作する理由を理解するためのデータを収集することの価値を却下しました。これは、システムの理解を求めるレイチェルの願望と、トップラインのパフォーマンス指標に焦点を当てるザーンとの間に根本的な対立を生み出しました。レイチェルは、トップレベルのメトリクスを改善するために行った変更が、その変更の動作を説明するためのインストルメンテーションも含まれるようにすることで、妥協点を見つけました。この戦略により、メトリクスの改善に対するザーンの要求を満たし、システムのオブザーバビリティを段階的に向上させることができました。最終的に、包括的な洞察なしにトップレベルのメトリクスを推進することと比較して、複雑なシステムの理解は低い優先順位のままでした。
このブログ記事では、問題のあるPHPコードについて説明します。著者は一人で作業しており、カタルシスとブラックユーモアのために共有しています。機密性を保護するため、コードは一般化されており、矛盾が生じる可能性があります。コードはデータを取得し、それを反復処理し、ローカライゼーションのために動的なプロパティアクセスを使用して詳細を取得します。次に、カテゴリ変数に基づいてコストをフォーマットし、任意のインデックスを持つ配列$motにアクセスします。数量選択ブロックの生成を含む、広範なHTML文字列操作が存在します。コードは時間のデータをデコードするためにJSONをデコードしており、日付が文字列として保存されていることを示しています。ドロップダウンリストは$mot配列の値を使用して構築されます。最終的に、処理されたデータはテンプレートに挿入されます。このプロセスは子アイテムに対しても繰り返され、ほぼ重複したコードにつながります。さらに、子アイテムは兄弟を持つこともでき、同様のコードロジックで別の反復処理が必要になります。著者は、元のプログラマーが最終的にメソッドと関数を使用することを学ぶことを願っています。提供されたコードスニペットは、メインアイテムと子アイテムの初期データ取得と処理ループを示しています。コスト計算とフォーマットのための複雑な条件付きロジックが含まれています。ローカライゼーションと通貨のための動的なプロパティアクセスが強調されています。数量と時間の選択のためのHTMLスニペットの導入も指摘されています。メインアイテム、子アイテム、兄弟アイテムのコードの繰り返し性は、コードベースを非効率にしています。
提供されたC++コードスニペットは、Deadlock例外の例外ハンドラを示しています。この例外をキャッチすると、コードはretryを試みます。しかし、retryは標準的なC++キーワードではなく、おそらくマクロです。著者は、このマクロがgotoステートメントを使用して実装されていると推測しています。中心的な問題は、retryがデッドロックを解決するという仮定にあります。デッドロックは、2つ以上のスレッドが無限にブロックされ、それぞれが別のスレッドが保持しているリソースを待機している場合に発生します。retryが効果的であるためには、デッドロックされたスレッドが現在保持しているリソースを解放する必要があります。コードの著者であるKevinによると、retryマクロはいかなるリソースも解放しません。代わりに、単にcatchブロックの先頭にジャンプします。これは、スレッドがデッドロック状況に閉じ込められたままであることを意味します。Kevinは、システムがすでに多数のデッドロックに苦しんでいたと指摘しています。コンサルタントがリソースアクセスの順序を変更し、ミューテックス関連の問題を特定することによって、これらの問題に対処するために雇われました。コンサルタントによるretryの実装は、意図せずにさらに多くのデッドロックを導入したようです。Kevinは、コンサルタントが独自のデッドロックを追加するつもりだったのではないかとユーモラスに示唆しています。
カキストクラシー、すなわち最悪で最も資格のない者による統治という概念が、関連概念として導入される。教師であるジャレッドBは、ハリーという機械工学教授が設立したEdTech企業での経験を共有する。ハリーはCインタプリタを開発し、それを基盤とした企業を設立し、Cプログラミングに基づいたK-12カリキュラムを提供していた。彼のソフトウェアには、Web IDEと、Cコードをリモートで実行するためのデーモンを備えたローカルインストール版Windowsが含まれていた。しかし、このデーモンには認証機能がなく、0.0.0.0にバインドされていたため、同じネットワーク上の任意のドメインやコンピュータが任意のCコードを実行できる状態だった。これらの重大なセキュリティ脆弱性は、ハリーが専属で雇っていた大学院生開発者たちに見過ごされたまま、長年存在していた。このソフトウェアは数千台の学校用コンピュータにインストールされていた。ジャレッドはこれらの問題についてハリーに報告し、ハリーは「セキュリティ改善」を理由にアップデートをリリースしたが、ITリーダーにアップデートの重要性を伝えることはなかった。ジャレッドはまた、ハリーの別のウェブサイトでクッキースティーリングエクスプロイトとコードインジェクションの脆弱性を発見した。後者の脆弱性により、数千件の暗号化されていないクレジットカード取引記録が漏洩した。これらの重大なセキュリティ上の欠陥とデータ漏洩にもかかわらず、ハリーの会社は事業を継続し、称賛を受けている。コメンテーターは、この状況を、古い技術に固執していたが教育システムを危険にさらさなかった知人と対比させている。
CdXz5zHNQW_B1k6IsjyP4.png
著者は、糟糕なソフトウェアのドキュメントのフラストレーションと、さらに大きな課題である質の悪いハードウェアデータシートを対比させている。集積回路の正確で完全なドキュメントを見つけることは、開発者にとって非常に重要である。データシートはしばしば不完全であったり、不正確であったり、あるいは異なる言語で書かれていたりする。現代のチップの複雑さは詳細なデータシートを必要とするが、一部のベンダーは不十分な情報しか提供せず、ユーザーに機能の逆アセンブルを強いる。データシートと実際のチップの動作との間の不一致は、電源ピンの誤認識やコンポーネントの損傷といった重大なエラーにつながる可能性がある。優れたデータシートを作成するベンダーもいる一方で、組み込み分野におけるコストの考慮事項が、しばしばドキュメントの不十分なハードウェアにつながる。著者は、チップのデータシートに「Super User Fantastic Feature Enable Register」と記載されていた具体的な事例を回想している。このレジスタは、開発者が困難な組み込みプロジェクトで経験することから、ユーモラスに「SUFFER」と略された。この機能の有効化は、高度なユーザーがデバッグの動作を変更することを意図していた。このレジスタのリセット値はすべて1であり、デフォルトで有効になっていることを示している。「SUFFER」レジスタという名前は、このような困難なドキュメントに対処する際の感情を的確に捉えている。
著者は、あるMicrosoftプラットフォームから別のプラットフォームへのデータ移行について説明しており、予期せぬ問題が発生しました。当初、データ抽出とロードはSSISによって処理されていましたが、著者はより多くの制御を得るためにPowerShellに切り替えました。目標は、SharePoint on-premisesからSQL Serverデータベースへ顧客ドキュメントとメタデータを移行することでした。重要なフィールドである顧客番号は、SharePointではNumber型として格納されていました。内部的には、SharePointのNumberフィールドはDoubleとして表現されており、10桁の数値を正確に格納するには十分です。しかし、SSISによって生成されたSQL Serverスキーマでは、このフィールドに'float'データ型が使用されていました。著者は、PowerShellスクリプト内の'.Net'型'float'がSQL Serverの'float'型と完全に一致すると誤って仮定しました。この不一致は、SQL Serverの'float'がデフォルトで倍精度であるにもかかわらず、著者がこの表現の違いに気づかなかったために発生しました。その結果、数値が転送および変換される際に、大きな顧客番号が精度損失により最後の数桁を失いました。テスターは当初このエラーを見逃していましたが、完全なデータロード中に発見されました。チームは、破損した数値を特定し、移行後に手動で修正する必要がありました。
CdXz5zHNQW_ElgNsoYbYY.jpeg
ソフトウェア開発には、エディタやコンパイラだけでなく、さまざまなサポートツールが必要です。ソース管理はその代表的な例です。しかし、多くの重要な開発ツールは、優れたものではなく、単に「十分良い」ものに過ぎないと言えます。ビルドシステムはそのようなカテゴリの一つであり、真に優れた選択肢が欠けています。チケットおよびタスク管理ツールもこの問題のあるカテゴリに属し、Jiraはその中でも特に批判されている例です。Jiraが企業に支持されるのは、その豊富な機能にありますが、残念ながらそれが複雑さにつながり、ユーザーはカスタムワークフローをプログラムする必要があります。これにより、実際のプロジェクトの進捗ではなく、プロジェクトマネージャーによる終わりのない設定が行われる可能性があります。Jiraは、チケットワークフローをステートマシンとして定義することを可能にし、チームメンバー間の自動ルーティングも含まれます。その後、テキストは、混乱したJiraワークフローに遭遇したKlinstenを紹介します。表示されたワークフローの例は、バイリンガル(オランダ語と英語)で、過度に複雑です。この過剰な状態と遷移の数は、チームの作業シーケンスを明確にするという目的を損なっています。著者は、ブラウザタブを閉じたいと思った経験に例えて、フラストレーションを表明しています。Klinstenのワークフローの複雑さは、理解して効果的に使用することを困難にしています。
CdXz5zHNQW_LSUkNG7WkF.png
フリーランサーのマチェイは、サポートが必要なレガシーPHPコードに頻繁に遭遇します。彼は、特に間隔を置いてデータを投入するためのHTTPリクエストメカニズムが欠けているプロジェクトを発見しました。これを実装しようとする以前の試みは失敗していました。元の開発者は、コードベース全体にわたって類似のcURL初期化および設定ブロックを複数回コピー&ペーストしていました。これらのブロックには多数のcurl_setopt呼び出しが含まれており、HTTPリクエストを行うことを意図していました。そのようなオプションの1つであるCURLOPT_TIMEOUTは、$intervalという名前の変数を使用して設定されており、その機能の誤解を示唆している可能性があります。根本的な問題は、CURLOPT_TIMEOUTの誤用というよりも、curl_execによって取得されたデータが決して使用されなかったことでした。リクエストは機能しているように見えましたが、取得されたコンテンツは$sという変数に格納され、その後無視されました。この見落としにより、マチェイは、以前の開発者はリクエストを機能させることができなかったのではなく、タスクを開始したが興味を失ったのではないかと考えるようになりました。プロジェクトには他の複雑なコードが含まれていましたが、この未使用のデータ取得はマチェイにとって特に目につきました。
語り手であるテックサポートのドローンは、昇進を断り、会社を辞めることにした。まもなく、人事部の新しい責任者であるレイラから、語り手を役員フロアに招待するメールが届き、語り手は緊張と好奇心を抱いた。語り手はレイラと会い、レイラは語り手の亡くなったメンターであるアギーに哀悼の意を表した。レイラは、語り手が報告した問題のあるマネージャーを解雇したことを明かし、親密な関係を築いた。その後、レイラは語り手に、新しいチェンジマネジメントチームのリーダー職を、大幅な昇進と社内での採用権付きで提案した。語り手は、魅力的なオファーにもかかわらず、友人たちとフリーランスになるという当初の計画を貫くことにした。レイラは、語り手の決断を優雅に受け入れ、サポートを申し出て、語り手の退職を残念に思った。その後、語り手は友人であるミーガンとレイナルドにレイラのオファーについて伝えたが、彼らもまたフリーランスの計画にコミットしていた。サンジェイも彼らのフリーランス事業に加わり、元同僚の「ドラキュラ」が最初のクライアントを紹介してくれた。「RD IT Solutions」というフラットな階層構造の会社を設立し、経費をカバーし、起業家精神の課題を乗り越え始めた。語り手は、新たな目的意識、過去の不安からの解放、そしてより健康的なライフスタイルを経験した。最初のクライアントは予期せぬ課題を提示し、ウェブサイトのコードをファックスで要求してきた。
この投稿では、テクノロジーが時間を誤って処理し、不条理な状況につながったいくつかの事例をユーモラスに探求しています。RobertはOnePlusから、配達日が「昨日」であるというメールを受け取り、ドライバーがタイムトラベルする必要があることを示唆しています。KinksterはFetlifeで興味深いバグを見つけました。そこでは、新規メンバーのプロフィール写真がコミュニティに参加する1時間前に投稿されたように見えました。ERIC P.は、2008年式Fordの写真を共有しました。この車はGPS日付ロールオーバーバグを経験し、ディスプレイに1024週間前の日付が表示されました。Marc WürthはNetvibesで奇妙なクロール統計を観察し、フィードが正規化される前に261年後の未来に取得されたことを示しました。匿名のユーザーは、ローマ人がブリテンを征服する前に小包を受け取ったと冗談めかして報告しました。通知の合計日付はデフォルトでUnixエポックになりました。これらの逸話は、日付と時間の計算に関連する一般的なソフトウェアのグリッチを浮き彫りにしています。この投稿は、これらの無作為に見えるバグをタイムトラベルというテーマに結びつけています。時間の処理コードが予期せぬ方法で失敗することがいかに多いかを強調しています。紹介されている例は、さまざまな種類のソフトウェアとハードウェアにまたがっています。各インスタンスは、プログラミングの課題を軽快に見ています。
CdXz5zHNQW_YVzQh2u0YS.png
CdXz5zHNQW_y9bbMWp6RY.png
Frederick A. は、ConferenceService クラスの IsCalling メソッドにおけるヌルチェックの問題を共有しています。このメソッドは、潜在的にヌルであるオブジェクトチェーン m_ConnectionService.Core.State.IsWebRTCConnected にアクセスすることで、Web 会議がアクティブかどうかを判断しようとします。元のコードでは、try/catch ブロックを使用して潜在的な NullReferenceException を処理し、チェーンのいずれかの部分がヌルであれば false を返します。このアプローチは、初期化されていないオブジェクトの根本的な問題を効果的に隠蔽します。Frederick は、C# のヌル合体演算子 (?.) を直接的な修正として使用することを提案しており、チェーン内のいずれかのオブジェクトがヌルであれば、簡潔に false を返します。例えば、m_ConnectionService?.Core?.State?.IsWebRTCConnected ?? false のようになります。これは機能的な解決策ですが、著者は、それがより深いアーキテクチャ上の問題に対する根本的な修正ではないと主張しています。根本的な問題は、接続状態の管理方法にあり、適切なステートマシンで処理されるべきだと示唆しています。重要な状態情報のために、ブールフラグを持つ深いオブジェクトチェーンに依存することは、設計上の誤りを示しています。完全なステートマシンの実装はより堅牢な解決策になりますが、著者はかなりのリファクタリングが必要であることを認めています。しかし、この例は、開発者がこのようなヌルチェックの複雑さを避けるために、状態管理戦略を慎重に検討することを強く思い出させるものとなります。
提供されたコードスニペットは、頻繁な提出者であっても、Optional型の誤用を示しています。文字列が空でないかどうかを確認し、その後、nullでないdtoOptional.ofNullableでラップしています。この実践は、Optionalの意図された利点、つまり潜在的にnullの値を適切に処理するという利点を無効にします。本質的に、Optionalが型をボックス化するために提供する便利な構文糖の使用を回避しています。単独では問題ありませんが、このパターンはコードベース全体に浸透しています。著者は、Optional型が、nullを返す可能性のない関数でさえも、広く散在していると指摘しています。Optionalのこの広範で不正確な適用は、コードの品質を向上させたり、バグを減らしたりしません。むしろ、バグが多くエラーが発生しやすいコードの原因となります。著者は、この問題がいつか修正される可能性について懐疑的な見方を示しています。これは、強力な言語機能が誤解され、誤って適用されるという一般的な問題点を浮き彫りにしています。過剰なボクシングとアンボクシングは、不要な複雑さを加えています。最終的に、null参照例外を防ぐためにOptionalを使用するという目的を損ないます。この例は、最新のプログラミング構造の不適切な採用に関する注意喚起として機能します。
フラットファイルデータベースはメインフレームで一般的であり、固定幅フィールドにデータを格納します。例えば、「JOHN SMITH 12343rd St」のような典型的なエントリは、「JOHN」が8文字、「SMITH」が8文字を占めることを知っていることに依存しています。この厳格な構造は、ミドルネームのイニシャルを追加するような変更を非常に困難にし、多くの場合、新しいテーブル、データ移行、およびすべての消費ソフトウェアの更新が必要になります。これを軽減するために、スマートな開発者は「パディング」を導入し、レコード内に余分な文字を予約しました。例えば、レコードは未使用スペース16文字で終わる場合があります。ミドルネームのイニシャルのような新しいフィールドが必要になった場合、パディングを縮小することで挿入でき、レコード全体の長さの変更を回避できます。この方法は、洗練されてはいませんが、高価なスキーマの再作業やデータのシャッフルを防ぎます。パディングはレコード全体に分散されることが多く、新しい列がこれらの予約されたスペースを消費できるようになります。最終的にパディングがなくなる可能性がありますが、この戦略は、大規模なオーバーホールなしでフラットファイルスキーマの運用寿命を大幅に延ばします。ブレンダのチームは、そのようなVSAMフラットファイルを使用するメインフレームシステムをサポートしており、最新のRDBMSへのデータ抽出が必要でした。ETLプロセスが作成され、メインフレームチームがファイル構造を詳細に説明する「コピーブック」を提供しました。しかし、ETL開発者はパディングを誤って扱い、フィールドを分割して、パディングの一部が個別のデータ要素として扱われるようにしました。当初、パディング文字はレポートから削除され、フィールドを連結することで再構築が機能したため、これは無害に見えました。決定的なエラーは、インフライト機能がパディングを消費していなかった本番メインフレームのみでテストしたことでした。これらの機能が本番メインフレームで稼働を開始すると、ETLプロセスによって生成されたレポートは、使用されたパディングからの余分なデータで破損しました。ETL開発者は請負業者であり、彼らのソリューションは限定的なテストに基づいて「設計どおりに機能した」ため、彼らはそれをやり直すことを拒否しました。その結果、メインフレームチームは、既存のレポートへの影響を避けるために、代替のパディングフィールドを見つけることを余儀なくされました。
TimeSpan 構造体の .NET ソース コードには、その機能について説明するコメントが含まれています。TimeSpan は、正または負の期間を表します。内部的には、ミリ秒単位で格納されます。この表現は、時間や日などの単位には適していますが、より長い期間では不正確になります。たとえば、月は 28 日から 31 日まで長さが異なります。同様に、年は 365 日または 366 日になり、10 年間には 1 回から 3 回のうるう年が含まれる可能性があります。これらの不整合が、TimeSpan 構造体が年または月に対するメソッドを提供しない理由です。年について言及されている「364 日」は、作者が「指のミス」と呼ぶ軽微なエラーであり、コードの動作には影響しません。このコメントは 12 年間変更されずにコードに残っています。TimeSpan クラス自体も、基本的にミリ秒のラッパーであるため、変更されていません。月または年を加算するようなより複雑な日付の計算は、他の日時オブジェクトによって処理されます。これは大きな問題ではありませんが、コメントとクラスの歴史は注目に値します。TimeSpan クラスは、非推奨のコンストラクターや、Silverlight を含む古い .NET バージョンに対するコンパイル時サポートも明らかにしています。廃止されたテクノロジーである Silverlight は、このクラスの長年の存在を浮き彫りにしています。
Windows Presentation Foundationは、コントロールをデータバインド可能にするWindows用のUIフレームワークです。これは、テキストボックスをモデルクラスの数値フィールドにリンクできることを意味します。このフレームワークでは、カスタム型の変換方法に関する指示が必要であり、そこでIValueConverterインターフェイスが登場します。このインターフェイスには、ConvertとConvertBackの2つのメソッドがあり、これらを使用して型間でデータを変換できます。このインターフェイスを実装するクラスは、たとえば色をブラシに変換するために使用できます。しかし、このインターフェイスのAPIはあまり好まれておらず、命名規則が混乱を招く可能性があります。Fredrikaによる提出は、テキストボックスをdoubleフィールドにバインドする際に、空の文字列をnullに変換しない組み込みコンバーターの問題を強調しています。この問題に対処するためにカスタムコンバーターが作成されましたが、その実装は、命名規則が不適切な変数や不明瞭なロジックにより理想的ではありません。コンバーターは、変換時には値をdoubleとしてキャストし、逆変換時には文字列としてキャストするため、混乱を招く可能性があります。WPFでコンバーターを使用する全体的なアプローチはあまり好まれておらず、この実装は問題を明確にするのに役立ちません。空のテキストボックスをnull値として扱うためにコンバーターを使用することも、将来的に問題を引き起こす可能性があります。全体として、コンバーターAPIとそのこのケースでの実装は、うまく設計されておらず、混乱や潜在的な問題を引き起こす可能性があります。
語り手は、突然の病で亡くなった友人であり指導者でもあるAggie Shawの突然の死に対処することに苦労しています。語り手は悲しみに打ちひしがれ、上司の期待にもかかわらず、いつものように仕事に戻ることが不可能だと感じています。彼らは感情に対処し、喪失を受け入れようと、有給休暇を使い始めます。語り手の友人Meganは連絡を取り、会うことを提案し、非常に必要な聞き役と慰めの感覚を提供します。会っている間、語り手は仕事に対する感情や不満を打ち明け、Meganは対等なパートナーと独自のITグループを始めることができると提案します。語り手はこのアイデアに触発され、フリーランスになることやMeganと新しいビジネスを始めることなど、選択肢を模索し始めます。彼らが調査し計画を進めるにつれて、リスクと不確実性にもかかわらず、目的と興奮の感覚を見つけます。語り手は仕事に戻りますが、それは2週間の辞職を伝え、新しい未来の計画を立てるためだけです。彼らはAggieの古いオフィスで、彼女の存在の象徴であるアヒルのおもちゃを見つけ、それがつながりの感覚と前進するためのモチベーションを与えます。語り手は、古い仕事を捨て、Meganをそばに置いて、新しい章を始めることを決意しています。語り手が仕事を辞めるという決断は、困難な職場環境から逃れるだけでなく、新しい目的と充実感を見つけることでもあります。
詐欺師は、ユーザーにコンテンツを最後まで視聴するように強く求めます。これは、今日の「Error'd」エピソードで長期的なコミットメントとしてユーモラスに提示されたタスクです。Amazonは最近、数千人の顧客に大幅に値上げされた請求書を送り、かなりの警戒を引き起こし、広範な懸念を引き起こしました。顧客の一人であるWillyは、Amazonの価格の突然の上昇について懸念を表明し、財政的な精査を予想しました。Dave A.は、アクションがオプションなのか必須なのかを疑問視し、ソフトウェアプロンプトの優柔不断さを強調しました。匿名のユーザーは、屋根掃除会社のためにX軸とY軸の両方に表示されたユニークな5つ星評価システムを発見し、ユーモラスにそれが「屋根の外」であると述べました。Richard H.は、ランダムに生成された請求書番号を参照する疑わしいQuickBooksのメールに遭遇し、それが詐欺であることを強く示唆しました。B.J. H.は、異常に冗長で警告的なシステムメッセージを受け取り、そのようなテキストが「正常」と見なされた場合の緊急プロトコルに関する懸念を引き起こしました。このエピソードでは、移行の困難を軽減することを約束する.NET 9への移行ガイドの広告も含まれていました。
CdXz5zHNQW_k8sU0XsDKx.png
レミーは、不快な天候のため、暗くて換気の悪い洞窟に後退することをユーモラスに提案する。この感情は、マネージャーが風変わりなソフトウェア開発者を容認していた過去の職場力学を反映している。90年代後半、ITブームの中、マネージャーたちは開発者たちの普段と違う行動に慣れていた。輝かしい推薦状を持っていたステンを採用するにあたり、バリーと彼のチームは風変わりなことに備えていた。初日、ステンは自然光がなく、換気口を閉じられるワークスペースを要求した。バリーは地下にあるステンのオフィスを発見し、ステンはそこを暗くするために蛍光灯を取り除いていた。ステンは終始三人称で話し、「ステン」と自分を呼び、代名詞を混乱させるような使い方をした。また、大量のビタミン剤と奇妙な匂いのするお茶を摂取していた。ステンのコーディングスタイルも同様に奇妙で、彼のいわゆるガールフレンドにちなんで、すべての変数とメソッドに女性の名前を使用していた。命名規則は存在したが、文書化されておらず、解読が困難だった。コードレビューは手の込んだ物語となり、実際のロジックを理解するのが難しくなった。彼の風変わりな性格とコーディングスタイルにもかかわらず、ステンの主な欠点は生産性の低さだった。彼はチームの要求に追いつけず、解雇につながった。バリーは後に別の会社に慎重な推薦状を提供し、ステンに彼のコードを説明するように提案した。ステンはその会社に採用されず、バリーは感謝のギフトバスケットを受け取った。
技術者は、整備不良のインフラストラクチャと型破りなソリューションに繰り返し直面しています。一般的な問題の1つは、電力不足のエアコンから生じており、サーバー室の開いたドアの近くでつまずきの危険に注意するよう警告が発せられています。別の技術者は、広範なトラブルシューティングと回線テストを行ったにもかかわらず、雨天時にしか断続的にしか機能しないファックス機に苦労しました。この問題は最終的に、ケーブルが保護されていなかった露出した電話会社の保管庫にたどり着き、経営陣に写真証拠が送られた後、迅速な修正につながりました。さらに不穏な発見として、ソフトウェア会社の木製サーバーラックの上に無造作に置かれた「オフサイトバックアップ」ドライブがありました。場当たり的なソリューションのさらなる例としては、標準的な電気工事から逸脱し、適切な設置よりも露出した接続を好む、型破りな配線が使用されています。マンハッタンのホテルでは、ネットワーク機器が公共の階段の吹き抜けでケーブルから不安定にぶら下がっており、完全に固定されていませんでした。中国では、金属加工工場で柱に数メートル高くボルトで固定されたスイッチが見つかり、産業現場でのさらに珍しい設置が浮き彫りになりました。これらの事件は、さまざまな環境におけるITインフラストラクチャ管理における専門的な基準の普及の欠如を強調しています。これらは、ベストプラクティスへの準拠ではなく、即興と怠慢のパターンを示唆しています。
CdXz5zHNQW_LC8T1Da23x.jpeg
CdXz5zHNQW_dTcL1Jd4qx.jpeg
カレンは、仕様テストで数千回に数回発生する不安定さに遭遇しました。これらの複雑でタイミングに敏感なテストは、寛大なタイミングウィンドウと合格した単体テストにもかかわらず、時折失敗しました。問題はJavaScriptのsetTimeoutに起因しており、ドキュメントではそれ以上待つ可能性があると示唆されているにもかかわらず、Node.jsでは指定された時間が経過する前にコールバックを呼び出すことができます。カレンの単純な待機関数は、当初、遅延を導入するためにsetTimeoutを使用していました。広範なデバッグの後、彼女はこのタイミングの不一致が不安定なテストの根本原因であることを発見しました。これを解決するために、彼女は経過時間を1ミリ秒ごとに継続的にチェックするように待機関数を書き直しました。この新しい関数は、ターゲット期間が満たされた後にのみ操作が完了することを保証し、早期のタイムアウトを防ぎます。効果的ではありますが、このソリューションは非効率的と見なされ、機能テストの厄介な時間感度を浮き彫りにしています。また、Node.jsランタイムのスケジューリング保証の欠陥も指摘しています。著者は、そのような回避策が必要であることに落胆を表明しています。
提供されたRubyコードは、ブール値の pretty-print と文字列への変換に使用される、boolean value の略である bv という名前の関数を定義しています。この関数は、それぞれプロパティ名、true の値、false の値、null の値を表す prop、tv、fv、nv の 4 つのパラメータを取ります。この関数は send メソッドを使用して、クラスのメンバーに名前でアクセスします。これは、文字列によるメタプログラミングを可能にするRubyのイディオムです。このアプローチは、ブール値以外のフィールドに対して「Not Specified」を返すなど、潜在的な問題につながる可能性があり、誤解を招く可能性があります。ブール値以外のフィールドに関数を適用しようとした場合は、例外をスローすべきであると主張されています。プロパティが存在しない場合や、アクセスされているものがパラメータを取る関数である場合、例外がスローされるため、関数の動作は驚くべきものになる可能性があります。Rubyのドキュメントでは、これらの問題を回避するために、許可されるブール値の良いリストを持つことが推奨されています。しかし、文字列を渡すことによる実行時のメタプログラミングの使用は、依然として問題を引き起こし、コードベースの保守を困難にする可能性があります。テキストの著者はこのアプローチを嫌っており、メタプログラミングにはC++テンプレートの使用を好んでおり、よりシンプルで明確であると考えています。著者は、重要度の高いRubyコードベースは、メタプログラミングの使用により、しばしば保守不能になると考えています。全体として、コードとそのアプローチは問題があり、エラーが発生しやすいと考えられています。