それは僕こそが知りたい知識です。

土地勘がないコード群の中に突然投げ込まれて問題を解決せよと言われる状況というのは実は大きいソフトウェア企業では割と日常茶飯事に分類され、みんなどうにか血反吐を吐きながら解決している筈です。もちろん自分の担当するコードから出ずに仕事ができたら楽ですが、世の中そううまくは行きません。

僕が過去にそういう事態に直面した時にどう足掻いたか列挙しますので参考になれば幸いです。

バグの再現環境をまず作る

再現できないバグは、仮に神がかった直感に基づいたコード修正で解決できたとしても、解決に成功した証拠が得られないため修正できたという証明ができません。ビルドに1時間かかろうがタイムリミットが短かろうがデプロイ先でしか走らなかろうがどうにかして再現する状況を作るのが必須です。運良くユニットテストなりE2Eテストなりで再現する仕組みを作れたらその問題は半分解決できたようなものです。しかし現実は厳しく、手作業かつ低確率でしか発生しないようなバグには涙を堪えながら毎回手作業で再現させていたりもします。

作業メモは必ず残す

問題解決までの道筋は常に複数考えられます。結局のところ試みている道筋は何らかの理由で頓挫する事が多いので、何故この道筋を選んでどこまで進んで何故頓挫したのかをメモします。これは自分の思考を整理するためにも後で他の人に助けを求めるためにも有用です。もしくはなぜ不可能なのかを最終的に説明する際の下書きにもなるというか、むしろ不可能であることを客観的に証明するためにやってるんだぐらいの気持ちで作業している方が気が楽です。やっている事の実態は科学的な実験であるので、仮説を立てて検証するサイクルを意図的に回し、自分が何をしているのかを自分自身に説明するよう意識しないとわけのわからない試行錯誤に陥りがちなのが僕の悪い癖です。

コードを容赦なく壊す

コードを斜め読みして今回のバグと関係がありそうな箇所を名前で決めつけてコメントアウトします。それでもバグが再現するなら今回行うであろう修正とは関係がないはずなのでその細部の探索は後回しにできます。コードが複雑に絡み合ってると関数呼び出し一つスキップするだけで色んな所に波及してしまうので日頃から自分だけでもそういうコードを書かないよう心がけるばかりです。あと「この箇所を通っているかどうかすら分からない」「何故かこのコードが実行されているがどこから呼び出されたのか追いきれない」なんて事もザラにあるので、クラッシュしてスタックトレースを吐くように細工するのはコードを頭に押し込む手助けにもなります。ありがちなのが「問題箇所と全く関係ないところを被疑箇所にしてしまっていた」パターンなので、自分が常に狙った通りの箇所を観測できているかは疑い続ける必要があります。更にはこれを言ってしまうと力量を疑われると思いますが、わかりきっている事でもログ出力に足してみたり自分の脳内トレースと出力が一致しているかを確認するだけでもだんだんと目の前のコードが自分ごととして考えられるようになってきて心理的な抵抗感が薄れていきます。

なお巨大なコードは余りに巨大でありデバッガをアタッチしたらそのまま固まってしまうので僕はデバッガに頼りません。

ドキュメントに目を通す

いやもうこれ最初にやれよと後になって思うのですが、巨大なコードとは得てしてドキュメントも巨大である事が多いのでいきなり頭から全部ドキュメントを読んでいたらそれだけで一生が終わってしまいます。しばらくコードに浸かっていれば問題箇所に関係がありそうな固有名詞がいくつか目星がつくのでそれらで検索をかけて関係がありそうなドキュメントを掻き集めます。特に英語だと「ほげほげ101」とか「Life of ほげほげ」みたいなタイトルのドキュメントはそのドメインでの目的や問題意識を初歩から説明してくれるので特に役に立つことが多いです。

例えばChromiumのコードと格闘しているなら Life of a Pixel なんかは有用なドキュメントと言える筈です。

Life of a Pixel

This is the evergreen copy of "Life of a Pixel". Video of the presentation at Chromium University (Nov 2020): http://bit.ly/loap-2020-video LIFE OF A Steve Kobes skobes@chromium.org Nov 2020 slides: bit.ly/lifeofapixel with special thanks to past presenters dknox@, chrishtr@, pdr@ "The unexamined...

docs.google.com

そして、ドキュメントに目を通してからソースコードに戻ってくるとなんと驚くことに相変わらずわけがわかりません。もっと頭が良い人ならドキュメントを見て理解できるのかも知れませんが、僕のように凡庸なプログラマはドキュメントとコードを交互に眺めて氷塊を少しずつ溶かすように実装者の気持ちを理解していく必要があります。この過程は時には週単位での時間を必要とします。

土地勘のある人の発信をよく読む

自分ではとても難しそうに見える事をいとも容易くやっている人たちの脳内には目的のコードに対する自分より精巧な脳内モデルが完成しており、そのモデルに基づいて行われる発言は意識的にも無意識的にも自分とは異なる物になっているはずです。ドキュメントに限らずチャットやブログなどのログにも目を通して、自分との差分に着目しながら何を思いながら該当箇所のコードを書いたかを想像することで現状のコードを理解する助けになることがあります。運良く開発者と会話できるのであれば、どういうつもりでコードと接しているのかを観察する事が時折自分の理解の助けにもなります。と言ってもやはり何がなんだか分からない状態をしばらく続ける事になりますし巨大なコードはどう折りたたんでも巨大なので認知能力の差に絶望するだけの事もままありました。

さて書き並べてみるといよいよもってただ藻掻いているだけですね…。もっと経験の深いソフトウェアエンジニアの方々がどのようにこの問題を解決しているのか、ぜひ広く意見を伺いたいです。

1日(18時間更新)
💌 スーパーレターへの回答方針

機密事項は一切答えません。


0 / 20000
¥0

利用規約プライバシーポリシーに同意の上ご利用ください

熊崎 宏樹さんの過去の回答
  • 呼べないと思います。Haskell詳しくないので何故に僕にレターを送ったのかよくわからないですが、僕の知る限りではそもそも「多くの解説ではそれらを包括して「純粋」と呼んで」はいないんじゃないかと思います。

    入力から出力が確定する特性いわゆる参照透過性が無いものは純粋とは呼ばないので、オブジェクトが内部に変数を持っていてそのメンバ関数を呼んでその変数が書き換わってその後の出力が変わるなら参照透過性は存在せず、よって純粋と呼べないと思います。Haskellでも標準入出力はIOであり参照等価ではないという扱いだった記憶です。

    27日
  • DDD以外の設計手法についてご教示いただきたく、DDDの主張をある程度正確に理解した上でDDDをこき下ろしているイメージの強いくまぎさんに質問させていただきました。 最近はソフトウェアの設計について調べると、DDDについての記事ばかりで辟易する一方、私がエンジニアになった頃にDDDに勢いがあった影響もあって私自身DDD以外の良い設計とされているものを知らず、DDDに胡散臭さを感じつつもDDDの考え方にとらわれている、毒親の影響を受けた子供のような状態から抜け出せずにいます。 その最たる例がリポジトリパターンです。 よく依存性の逆転・DIと一緒に語られますが、くまぎさんがおっしゃる通り余計にインターフェースを切るのはイケてないと感じます。また、DI抜きにしても、リポトリパターン由来の様々な問題(N+1やバルクアップデート、管理画面用のメソッド生やしたくなる問題など)に対する解決策として提示されている手法をみて、自分で問題をでっち上げているように見えます。その一方で、ドメインのモデルを集約という単位で、リポジトリを介してDBに出し入れするのは便利そうに感じます。リポジトリパターンを使わずにドメインのモデルの入出力が書き散らされるとモデルにプロパティを追加するときなどにあちこち修正の必要が出て面倒です。 そもそもリポジトリパターンのようなDBとのやりとりをするところにドメイン知識を持ち込まないという考えに無理があるのでしょうか?別の方への回答に「DDDの人たちが言うようなドメインロジックを中心に据えてストレージをリポジトリやインフラ層に追い出したりするアイデアには反対です。疎結合を有難がる風潮が念仏のように唱えられがちですが、データはアプリケーションの本尊そのものであって、脇に置いたりあとから気軽に挿げ替えたりするものではありません。言い換えるとそこに疎結合を求めてはいけません。」と書いていましたが、くまぎさんがアプリケーションを書くときは、DBとドメインロジックをベッタリさせて書いていますか?ドメインロジックのテストを書くときはDBを立ち上げてデータを入れてテストしているのでしょうか? くまぎさんが実践しているプラクティス等あればぜひご紹介いただきたいです。

  • 消えません。

    産業革命の時ですら「蒸気機関で労働が消える」などと騒いでいたという話がありますが一向に労働はなくなっていません。汎用AIをうまく使える人にさらなる仕事が降り注ぐだけであって、飛脚100人分の労働がトラックの運転手一人で置き換わったみたいな話がそこかしこで起きるだけと見ています。

    2か月
  • 趣味として何かを作ってるぶんには「影響力の大きいものを作った」という事を持ってして「あいつは技術力が高い」としています。

    ソフトウェアエンジニアの本職としては「あの人がいると仕事が進む」というのが技術力の高い人の肌感覚です。つまり仕様を手早く整理して人に伝え懸念点を素早く解決し、メンバーの疑問に答え役割分担を適切にこなしながらマネージャからの信頼も厚い、そういう人が強いです。

    2か月
  • 「日本はいつでも自販機でミルクティーが買えるのが嬉しい」とインド系の人が言っていたのが意外でした。午後の紅茶が好きみたいです。

    2か月
  • 再帰とか抽象構文木とかマクロですかね…。人によって「最低限」の基準が違うので論じにくい話です。

    この手のメタな知識はまさにLISPの世界で熱心に研究され続けて来たので「計算機プログラムの構造と解釈」通称SICPという本に集まっており、だからこそ熱心なプログラマはこの分厚い本を崇めたりLISP使いになったりします。昔はSICPがマサチューセッツ工科大学の教科書だったりしたのですが最近はPythonをやるようになったという噂もあって、それほどLISPが必須知識として見做されなくなってきた風潮を感じます。もちろん興味が有るのであれば是非邁進してください。

    3か月
  • テック企業で働く気ならスキルセットをテックに寄せる方が近道ですし、アメリカ系の企業なら社内の公用語は英語でしょうから英語を社内公用語に使っている会社なら英語の練習にもなっていいですね。

    英語が公用語かつテック系で日本にオフィスを置いている会社は都内にたくさんありますのでぜひ検索してみてください。

    4か月
  • そんなに高い志など無く、自分が好きな分野の中で社会から需要がある所を選んだ感じです。ただし、MLとかデータサイエンティストなどは数式とにらめっこする時間の方が長そうなので、数学力ではなくてCPUアーキテクチャとかそういう知識が活かせそうな分野を選びました。

    最近は「異世界転生するなら俺TUEEEできる所を狙いたい」というモチベーションぐらいで充分なんじゃないかと思っています。

    4か月
  • いつもXでmondの回答拝見して参考にさせて頂いたいます。 今回初質問になりますが、よろしくお願い致します。 相談内容は「どうすれば自分がわからない部分を言語化して自分で解決して理解できるようになるか」です。 自分は普段Webアプリケーション開発に従事しておりエンジニア歴は6年目になります。 簡単なCRUDのAPIを実装したり、フロントエンドで画面を構築はできるつもりです。 しかし、少しでも知識の深掘りが要求されると途端につまづいてしまいます。 例としてパフォーマンスの高いSQLを書けるようになるためRDBMSにおけるB-Tree Indexの仕組み(なぜインデックスを貼るとクエリ処理が早くなるのか)を勉強したものの、どんな入門書やネットの解説記事、各種RDBMSの公式リファレンスを読んでも理解出来ませんでした。 他にもRDBだけでなくアルゴリズムとデータ構造やネットワークなどあらゆる分野で少し難しいレベルが要求されると何が分からないのかが分からず八方塞がりになってしまいます。 そんな状態がここ2,3年続いており、自分のエンジニアとしての技術レベルが停滞しています。認めたくないものの自分のエンジニアとしては限界なのかもしれないと感じています。 もちろん、他の方が自分の何倍も技術に向き合われていて単に自分の努力不足であることは承知しております。 しかし、「何を勉強しても何を勉強しても何が分からないのかを言語化できず、自学自習のサイクルを回せない」のではエンジニアとして失格であると考えています。 しかしエンジニアであることを諦められないため、「どうすれば自分がわからない部分を言語化して自分で解決して理解できるようになるか」をアドバイス頂きたいです。 お手数おかけしますがお手数おかけしますが、ご回答頂けますと幸いです。

  • お世話になっております。コンピュータサイエンスについて質問があります。 現在 23 歳の高卒ソフトウェアエンジニアで CS を体系的に学びたく学士を取得しようと思っています。やる気があれば修士以降もやりたいです。 単純にコンピュータやコードを書くのが好きでもっと詳しくなりたかったり、自分に出来ることを増やしたりビッグテックで働いてみたいなど理由は色々あります。 選択肢は2つ考えていて、働きながら海外の大学のオンライン講義を受けるか、国内の大学で学ぶため受験からやり直すかです。 単純に比較をするのは難しく懸念点も様々ですが、気にしているのは卒業後の年齢で入社しようとしても足切りされるのではないかという点を心配しています。高度な仕事をやりたくて勉強したのに土俵に立つことすら出来なくなってしまったら少し悲しいです。社会人大学生としてやっていく方がリスクが少ないのは分かっているのですが、まだ決め切れておらず kumagi さんが同じ立場だったらどうするか意見をいただきたいです。 色んな求人を見たりするのですが大体必須条件に CS の学士・修士または同等の実務経験と書かれていることが多く CS に関する知識の必要性を日々感じています。コーディングテスト?は受けたことが無いので分からないのですが一応 AtCoder 黄なのでなんとか行けるかな、、と思っていたりもするのですが… 競プロをやってきて凄い人に沢山出会うのですが、経歴を見ると大体東大を通っていて凄い事をやりたいなら自分もそういうところで学ぶべきなのかと考えてしまいます。 長文になってしまいました、申し訳ありません。 お手数をおかけしますがご回答いただけますと幸いです。

  • 全くですね。アセンブラを眺めるのなんて顕微鏡で拡大して観察するようなもので、今どこを見ているかを把握することすら難儀です。

    僕はアセンブラと日常的に戯れるエンジニアではないのですが、自分の書いたC++が自分の狙った通りの機械語に変換されているかを確認するために godbolt.org にコード片を入れています。ベンチマークを取っている時にタイトなループの内側でインライン化することを期待していた関数がやけに遅い時などに役立ちます。

    6か月
  • どれだけ正確に覚えているかは個人差があると思いますが、うちの子は語ってくれます。ただし「ママのおなかのなかにいるときにあーまーどこあくりあしたの」ぐらい適当な事いうので僕も「うんうん、お腹の中は暇だろうからプレステ入れといたんだよね」と応じています。

    9か月
  • 僕ならPostgreSQLを選びます。

    ローカルで立ち上がるのでアプリ開発中のデバッグが簡単なのとSpannerやAlloy DBやAurora PostgreSQL等のクラウドネイティブなRDBMSが互換インタフェースを備えている事が理由です。

    追記型という形を取っているため行内の更新が多いとインデックス側の更新が多くなりMySQLに乗り換えるUberのような事例もありますがそういうのは発生してから対策しても遅くないのでEarly Optimizationと割り切って行きます。

    1年
  • 岐阜県の山間部で育って東京に来ました。

    都心部の休日に出歩いている人間の多さに驚きました。こんな人だかりは夏祭りですら見たことねぇ!今日は何の祭りなの?えっ何もなくてこの人数!?!?

    1年
  • 特に気にしていません。美味しければ何でもOKです。カレーに牛乳は何だかカレーを甘く感じれて美味しいですよね。

    1年
  • 僕の専門ではありませんが、競技プログラミングの分野では異口同音にtouristことゲンナジー・コロトケビッチ氏の名前が挙がります。

    彼は競技プログラミングの分野で幼少(11歳!?)の頃から目覚ましい成果を出し続け、2023年に29歳になります。競技プログラミングの大抵の有名な大会で優勝を総なめにしています(詳細はwikipedia参照)。

    1年