tag:crieit.net,2005:https://crieit.net/magazines/anonymouse-engineer-ecrit/my-gafa-interviews/feed [連載] GAFA で就活した回想録の投稿 - Crieit Crieitで連載「[連載] GAFA で就活した回想録」の最近の投稿 2019-10-20T08:28:29+09:00 https://crieit.net/magazines/anonymouse-engineer-ecrit/my-gafa-interviews/feed tag:crieit.net,2005:PublicArticle/15492 2019-10-20T08:28:29+09:00 2019-10-20T08:28:29+09:00 https://crieit.net/posts/6729b9bbea0198a976917cfbc1af23df 待てど暮らせど <p><a href="https://crieit.net/magazines/anonymouse-engineer-ecrit/my-gafa-interviews">>> 連載トップ</a> <a href="https://crieit.net/posts/acbf740434bef542013b122e814419a0">> 前回のお話</a></p> <hr /> <p>その昔日本で大学生をしていた時に同級生から聞いた話によると、新卒採用では受かっていると直ぐに電話がかかってくるが、落ちているとなかなか電話がかかってこないらしい。今もその通りなのかは分からないけれど、シリコンバレーでの僕の就職活動の経験(落とされた経験)はそれとは随分違っているように思う。落とすときの連絡は直ぐにくるし、プロセスが進めば進むほど、受かった時の会社側の対応が遅くなる。きっと日本の新卒では「決められた上限一杯になるべく良い人を探す」のが目的なので、面接の結果の良い人から順番に返答をしていくのだろう。一方で僕がやっている転職活動では、基本的に空いているポジションに合った人を探すのが目的なので、合わない人をどんどん切り捨てていく形になるのではないのだろうか?こちらでも (Newly Graduate) と書かれた新卒用のポジションを見ることがよくある(LinkedIn のレコメンデーションシステムがその辺を区別してくれないせいで)が、僕は縁がなかったので実際のところは分からない。昔こちらで面倒を見たインターンの学生が、「Google (のインターン)に受かったんだけど、面接の後のチームマッチングプロセスがクッソ時間かかったから、他に行くことにした」と言ってるのを聞いたことがある。チームマッチングプロセスがとても時間がかかる話はネットでも散見される。<br /> 話は逸れたが、Amazon のコーディングテスト + 抜き打ちインタビューから3日が経った頃、僕は不安になり始めた。「あれ、もう忘れられてるんじゃないの?」そう思ってメールで問い合わせをしてみた。返信が来たのはさらに3日が経った頃だった。リクルーターのアマンダにもまだ結果は分からないから、もう一週間ほど待ってみてとのことだった。この頃から長い間、僕はずっと慢性的な不安に苛まされ流ことになる。</p> <p>結局、連絡が帰ってきたのは3週間も経った頃だった。3月になっていた。アマンダから電話がかかってきて次のステップに進むと言われた。次のステップからは違うリクルーターが話を進めるとのことだった。次のリクルーターはシアトルにいるマシューだった。例のごとくメールでの紹介が済んだあと、電話の予定を決めた。</p> 然るエンジニア🙊 tag:crieit.net,2005:PublicArticle/15380 2019-09-07T10:54:08+09:00 2019-09-07T11:06:11+09:00 https://crieit.net/posts/c91b4d0886e4e5d4e1680a1224edb153 番外編:最近のプライバシー関連の報道で思い起こされる話。 <p>最近のプライバシーに関する報道を見ていて、3月の中頃にこんなメールを LinkedIn 経由でもらったことを思い出した。</p> <hr /> <p><strong>Job Opportunity at Apple!</strong></p> <p>Hi Taro, I came across your profile and wanted to see if you're open to new opportunities. I have an Japanese Language Engineer Position with Apple in Cupertino that you may be a great fit for. I am looking for someone who has experience with ML/NLP and can code in Java, Python, Shell, or equivalent. If interested in further discussion, please pick a time that works best for us to hop on a quick phone call! If you currently are not interested, but know someone within your network that may be, please feel free to forward them my information as we do offer a referral bonus for anyone you refer that is placed on the project. Looking forward to hearing from you!</p> <hr /> <p>クパチーノのアップル本社で日本語の機械学習・自然言語処理のできる「日本語エンジニア」を探しているという話だった。「日本語エンジニア」って肩書きはなんやねんとも思うのだが。</p> <p>「え?何これ?こんなあつらえ向きの話あるの?」</p> <p>メールを何度も読み返して自分の理解が間違ってないことを確認したら、急いで返信のメールを認めた。</p> <p>(今改めて読み返してみると、「Java, Python, Shell もしくは同等の言語で実装の出来る」という表現は、Java と Python を同等とみなすのはよいとしても、Shell をそこに混ぜると何がなんだか分からなくなると思うのだが。)</p> <p>このメールをくれたリクルーターの女性は電話で以下のようなことを言った。</p> <ul> <li>アップルは機械学習の拡大に力を入れていて、英語以外の言語にもリソースを投入しようとしている。</li> <li>仕事の内容は集まった Siri のデータの解析とそれを使用するエンジニアとの調整</li> <li>採用プロセスはマネージャーとの電話のみ</li> <li>労働時間は調整可能</li> </ul> <p>「え、フルタイムじゃないんですか?」</p> <p>「ええ、コントラクターになるの。」</p> <p>コンタラクターか。。。それ以外の内容は申し分ないのに。</p> <p>「コントラクターは、ビザ的に働けるか分からないですね。ちょっと。」</p> <p>「うちで H1B ビザで働いている人は他にもいますよ。成果が認められて正社員にいなった人もいます。</p> <p>労働条件は正社員と同じですよ。給与の支払い元と福祉条件だけが違います。</p> <p>でも、うちもビザのサポートをしてますよ。」</p> <p>「仮になんですけど、不況やらで人員調整の解雇になったらどうなりますか?」</p> <p>「うちを通して他の派遣先を探しますよ。」</p> <p>「ちょっとコントラクターという雇用条件が不明点が多いので、軽くリサーチをしてみますよ。」</p> <p>「分かりました。ではまた追って連絡しますね。」</p> <p>アップルのコントラクターについて軽く調べてみると、あまりいい話は出てこなかった。まあ部署によっても違うのだろうけれど。</p> <ul> <li><p><a target="_blank" rel="nofollow noopener" href="https://www.quora.com/What-is-it-like-to-work-at-Apple-as-a-contractor">What is it like to work at Apple as a contractor?</a></p></li> <li><p><a target="_blank" rel="nofollow noopener" href="https://www.techspot.com/news/78705-apple-contractors-face-second-class-treatment.html">Apple contractors still face second-class treatment</a></p></li> </ul> <p>アメリカでも日本でよく聞く(というか2ちゃんねるでよく見る)派遣・正社員論争とそう変わりないようだった。僕に取っていちばんの問題は LinkedIn に書けないということだった。それでは次の転職の際に苦労することになる。</p> <p>そもそもアップルは正社員でも労働環境が良くないというのに、コントラクターでは中々の地獄を見るのではないだろうか?</p> <p>(今のところシリコンバレーであった人々の中で日曜日も仕事をしているのは、アップルで働く日本人だけだ。)</p> <p>ま、電話がかかってきたら丁寧にお断りするとしよう。そう思ったが、フォローアップの電話はかかってこなかった。</p> <p>時は変わって、2019年も Q2 あたりになるとこの辺の話題のプライバシーに報道が敏感になってきた。</p> <p>4月ごろには Amazon Alexa の会話を従業員が聞いているという報道があった。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.cnn.com/2019/04/11/tech/amazon-alexa-listening/index.html">Amazon reportedly employs thousands of people to listen to your Alexa conversations<br /> アマゾンが Alexa の会話を聞くために数千人規模を雇用しているとの報道</a></p> <p>このようなシステムのバックグラウンドに従事している者としてこのニュースを初めて聞いた時には、そこまで驚きはしなかった。僕自身も似たようなことを仕事柄することもあるからだ。ただしそれは合法的に、前もって明確な了解を得られた会話に限る話だが。まあ僕も、そんな仕事をしていなければ、驚いただろう。</p> <p>そして7月、似たような注目が Apple の Siri にも飛び火した。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.theguardian.com/technology/2019/jul/26/apple-contractors-regularly-hear-confidential-details-on-siri-recordings">Apple contractors 'regularly hear confidential details' on Siri recordings<br /> アップルの契約社員が Siri の録音を定期的に確認していることが判明</a></p> <p>あれ、この契約社員の案件、前に来てたやつじゃん!と思って楽しく記事を読んだ。<br /> 案件の話を聞いている時はプライバシーの話は全くなかったことはないにしても、それでも大きな注目はなかったと認識している。世論は短い時間で大きく変わるものだなあ、と思っていると続報が入ってきた。</p> <p><a target="_blank" rel="nofollow noopener" href="https://techcrunch.com/2019/08/01/apple-suspends-siri-response-grading-in-response-to-privacy-concerns/">Apple suspends Siri response grading in response to privacy concerns<br /> アップルはプライバシー上の懸念に応えてSiriの応答評価を停止中</a> <a target="_blank" rel="nofollow noopener" href="https://jp.techcrunch.com/2019/08/03/2019-08-01-apple-suspends-siri-response-grading-in-response-to-privacy-concerns/">[日本語]</a></p> <p>これは少し僕には予想外だった。まあアップルは昨年の年次会議からプライバシー保護を前面に押し出しているいるので筋の通る話ではあるし、このリアクションこそがアップルが真剣にニュースを受け止めているという証拠だろう。幹部陣の中にもきっと報道を受けて初めてなぜ会話の解析を行う必要があるか説明を受けた人もいることだろう。</p> <p>はて、じゃあ契約社員の人々はどうなったのだろう?やはり契約終了になったのだろうか?僕は雇用条件的にこの仕事に就くことはきっとなかっただろうが、中々他人事にも思えない話だった。</p> 然るエンジニア🙊 tag:crieit.net,2005:PublicArticle/15371 2019-09-03T07:37:31+09:00 2019-10-20T08:30:41+09:00 https://crieit.net/posts/acbf740434bef542013b122e814419a0 不意打ち <p><a href="https://crieit.net/magazines/anonymouse-engineer-ecrit/my-gafa-interviews">>> 連載トップ</a> <a href="https://crieit.net/posts/81831039f649c70bf0465a8915a96430">> 前回のお話</a></p> <hr /> <p>Amazon のコーディングテストを受けてから数日後、オフィスについて車を降りたところでテキサスからの着信があることに気付いた。誰だろうと思って掛け直すと Amazon リクルーターのアマンダだった。</p> <p>「ハイ、タロー。Amazon のアマンダです。コーディングテストの結果とその次のステップの話をしたくて電話しました。それで、結果なんですけど、」</p> <p>こちらが相槌を打つ暇も与えずに、切羽詰まったかの様子でアマンダは話し続けた。</p> <p>「あの、ちょっと今は時間がないので、折り返してもいいですか?えーっと、11時半はどうですか?」</p> <p>「ええ。わかりました、それでは。」</p> <p>リクルーターと電話で話をする際のストレスの一つは、こういった急にかかってくる電話だった。リクルーターにとっては候補者と話をすることは仕事の範疇内だが、候補者にとっては範疇外になる。オフィスで電話を取っても、話をするためにはプライバシーの確保できる場所まで移動しなければならないし、メモも取れない状況で様々な要件をまくし立てられても全部は聞き取れない。携帯電話のような低品質の音声で、相手が外国訛りならほとんど何をいっているか分からない。加えて、求職の身はどうしても遜った態度になりがちになる。電話する場合は緊急の場合を除いては前もって時間を指定するメールをしてほしいものだ。その方が話すべき内容も事前に準備できるのでより良いコミュニケーションになる。</p> <p>そんな訳で、アマンダと話をするために昼前にまたまた例のスターバックスへやってきた。コーディングテストのフィードバックということで、特にヘマをやらかした覚えもないし、次のステップ(電話面接)の予定を決めるのだろうと思い、ある程度の日程に思いを巡らせてから電話に臨んだ。電話に出ると、アマンダは挨拶もそこそこに話始めた。</p> <p>「それで、コーディングテストなんですけど、良い結果が返ってきました。それで次のステップに進んでもらおうと思っていて、それに関していくらか質問したいんです。」</p> <p>「ええ、わかりました。」</p> <p>僕は手元のカレンダーに目を落とした。</p> <p>「ls と cd が何をするかご存知ですか?」</p> <p>「・・・はぁ?」とほとんど声に出かかった反応が僕の頭の中では響いた。</p> <p>「え? Linux のコマンドの話ですか?」</p> <p>「ええ、そうです。ls と cd が何をするかご存知ですか?」</p> <p>「こいつ何言ってんの?」と思いながら、僕は答えた</p> <p>「ls は現在のディレクトリの中身を表示します。cd は引数にディレクトリをとれば、そのディレクトリに移動しますし、そうでなければ、ホームディレクトリに移動します。」</p> <p>「なるほど、分かりました。ハッシュマップの利点と欠点を教えてもらえますか?」</p> <p>「ハッシュマップっていうのはデータ構造の話ですよね?」</p> <p>「ええ、そうです。」</p> <p>「えーとまず、ハッシュマップはコンスタントタイムでのリトリーバルを実現しますね。欠点はバケットのサイズが固定なので、アイテムの数がバケットのサイズに比べて小さい場合にはメモリが無駄になるかと思います。」</p> <p>ハッシュテーブルの話などここ数年していなかったので、ぱっと聞かれてまとまった答えを返すことは叶わなかった。後になって、欠点のメモリの話をする前提のバケットによるハッシュ関数の話をするのを忘れていたことに気付いた。今になって思うと、多分「通常の配列と違いインデックスによるリニアアクセスが出来ない」とかが期待されていた模範回答だった気がする。当たり前すぎるが。</p> <p>「Post-Order Traversal とはなんですか?」</p> <p>「木構造の Depth-first Seatch の話ですよね?」</p> <p>木構造がインタビュー必出の話題とは言え、その前提を飛ばすとはなかなか不親切な聞き方をしてくれる。</p> <p>アマンダは他にいくつかのアルゴリズムとデータ構造に関する質問をした。僕はたじろぎながらなんとか答えをひねり出していった。</p> <p>「分かりました、ありがとう。以上で聞きたかったことは全部です。今日の結果を踏まえたフィードバックを提出しますので、また連絡しますね。」</p> <p>「ええ、ありがとうございます。」</p> <p>なんとも腑に落ちないモヤモヤした気持ちを抱えながら、僕は店を後にした。不意打ちの電話に加えて不意打ちのテストとは。</p> <p>ただ、気になるのは、果たしてアマンダには僕の返答をきちんと理解する知識があったのだろうか?受け答えの感じからして彼女が前もって用意された質問リストから質問を選んでいるのは明らかだった。今日の問答は誰によってどうやって評価されるのだろうか?効率重視の Amazon のことだからおそらく彼女が電話越しに丸バツの判断を下しているのだろう。結果は果たして。。。</p> <p><a href="https://crieit.net/posts/6729b9bbea0198a976917cfbc1af23df">第十話</a>に続く。</p> <p><a href="https://crieit.net/posts/c91b4d0886e4e5d4e1680a1224edb153">番外編:最近のプライバシー関連の報道で思い起こされる話。</a></p> 然るエンジニア🙊 tag:crieit.net,2005:PublicArticle/15320 2019-08-12T11:29:32+09:00 2019-09-03T10:14:27+09:00 https://crieit.net/posts/81831039f649c70bf0465a8915a96430 コーディングテスト - 実践編 <p><a href="https://crieit.net/magazines/anonymouse-engineer-ecrit/my-gafa-interviews">>> 連載トップ</a> <a href="https://crieit.net/posts/f25b2f7288e2fb366eb8923cfe444bd8">> 前回のお話</a></p> <hr /> <p>コーディングテストであれ、次の面接の予定であれ、リクルーターは基本的にはこちらの予定を加味してアポを入れてくれる。毎度毎度予定を詰める段になると、「次のアポまでに予習と準備したいから二週間ぐらい空けるかな。」という発想である程度時間を開けるのだけれど、時間に余裕を持てば持つほどに、本番が近づいてきたときの緊張感とストレスもより一層大きくなる。</p> <p>そんなこんなで、コーディングの練習は十日ほどで見切りをつけて、Amazon のコーディングテストを受けることにした。<a target="_blank" rel="nofollow noopener" href="https://leetcode.com/problemset/all/">Leetcode.com</a> の問題でだいたい Easy を1日3問で一週間。これでメインのトピック<a target="_blank" rel="nofollow noopener" href="トピック">†</a>を網羅した後、Medium を1日1問。それぐらいやると「もう十分だろう、もうやりたくない。」という気持ちで、テストから逃げるモチベーションから早くテストを終わらせたいモチベーションにシフトしていった。</p> <p>コーディングテストではリクルーターが送ってくる専用のリンクにアクセスしてこれらの課題に取り組む。リンクは一週間で失効するので、自分の予定を加味してリクルーターにテストを発行してもらう。Amazon は myamcat.com というオンラインサービス<a target="_blank" rel="nofollow noopener" href="UI">††</a>を使っている。テストを始める際にこのサイトは定期的にスクリーンショットをとる、タイピングを記録するなど、なかなか気持ち悪い要求をしてくる。これを許可しないとテストを受けられないのだがなんともスッキリしない。なんでも、こうしないと課題でズルをする人が後を絶たないからだそうだ。<br /> テストは大体全部で2時間ほどで、コーディングの課題が二問と性格・行動適正診断がある。コーディングテストは全部で二問、合計で最大 90 分かけることが出来る。どちらの問題も「Amazon では、」と、一応問題をそれなりにカスタマイズしたような始まり方だった。一問目は以下のようなものだった。さて、これを読んでいるあなたは何が問われているかお分かりだろうか?</p> <hr /> <p>Amazon では、顧客第一をモットーの一つに掲げていて、商品を配達する際には最も早く商品が配達されなければなりません。出発地点、目標地点、通行不可能な道が与えられた場合に、最短経路を求めるプログラムを実装しなさい。経路情報は2次元配列として与えられます。</p> <pre><code>入力例 [ ['s', '0', '0', '0'], ['0', '0', '1', '0'], ['0', '0', '1', 'g'], ] </code></pre> <pre><code>出力 5 </code></pre> <p>上の例では、<code>s</code>, <code>g</code> はそれぞれ出発地点、目的地点を表し、<code>0</code> は通行可能な経路、<code>1</code> は通行不可能な経路を表します。</p> <hr /> <p>問題の文章はもう少し説明が丁寧だったかもしれないが、まあ大筋は伝わるだろう。二次元のマップが与えられた場合の最短経路はどのようにして求められるだろうか?これを書いている僕の頭の中ではダイクストラ法という言葉が思い浮かんでいるが、それはこの問題にはオーバーキルだろう。この問題を実際に解いている際にはダイクストラ法のことなど思いもしなかったのだが、それはきっと事前練習のおかげで脳がよりコーディングチャレンジ仕様になっていたからかも知れない。では、どうすればよいかというと、模範解答は幅優先探索 (BFS) だろう。</p> <p>木構造に関する知識、探索方法(幅優先(BFS)、深さ優先(DFS))や、深さ優先探索の場合の処理の順番の違いなどは事前に習得していることが期待される知識だ。他にはリンクドリストや、ハッシュマップ、ハッシュテーブル等の特性、ソートアルゴリズムや再帰的な実装がよくテストされる。今回の課題では BFS を使って二次元配列の要素をどのように処理できるかを考える必要がある。</p> <p>と、ここまで尤もらしいことを述べたが、実際には、この「2次元空間の最短距離」の問題は頻出問題の類なので、練習問題を多くこなした人なら大体みたことあるはずだし、課題に取り組む際にはそうであることが理想だと思う。そんな訳で実装の方法は例えば<a target="_blank" rel="nofollow noopener" href="https://www.geeksforgeeks.org/shortest-distance-two-cells-matrix-grid/">ここ</a>で詳しく説明してあるので、ここでは割愛することにする。僕は見た瞬間に「あぁ BFS か。」と思ったので、どのようにしてそこにたどり着いたのかはうまく説明できない。きっと着想方法を説明したサイトも探せばあると思うので、それは読者の皆さんに委ねることにする。</p> <p>二問目も同じような配送をテーマにした2次元配列を扱う問題だった。動的計画法を使うナップサック問題系の課題だったような気がするが、残念ながら忘れてしまった。</p> <p>メインのコーディングが終わると、自身の解法に関する記述課題になる。要は自分の実装を評価するわけだが、ここで大切なのは時間とメモリに関する計算量をきちんと記述すること。O記法(ビッグオーノーテーション)を使って、入力のサイズが変わると、計算時間とメモリ消費量にどのような影響が出るのかを評価する。</p> <p>例えば、上に挙げた最短経路の問題を BFS で解いた場合を考えると、目的地が見つかるまでノードを一つずつ処理していくので、計算にかかる時間は(最悪の場合で)与えられたマップのサイズに比例する。<code>n</code>, <code>m</code> をマップの辺の大きさとすると、<code>O(n*m)</code> となる。メモリ消費量は、辺の長さのうち、短い方に比例するので <code>O(min(m, n))</code> となる。</p> <p>頻出アルゴリズムの時間及びメモリ消費量の性質は覚えておくと、問題を解くときの判断の助けになる。忘れてしまった場合はさっと検索すればすぐに出てくる。</p> <p>さて最後は性格診断である。これは選択問題形式で、日本の就活でよく見る SPI 等とよく似ている。「時間の余裕がない時でも落ち着いて対応できるか」などという実質一択問題がたくさんある。Amazon の場合は<a target="_blank" rel="nofollow noopener" href="https://www.amazon.jobs/en/principles">リーダーシップ理念</a>というものを公に掲げているので、解答に困ったら、それに即したものを選べばよい。<br /> 全てに答えて、提出ボタンを押すとテスト完了となり、リクルーターに結果が送られる。リクルーターは結果を基に次のステップをアレンジする。</p> <p><a href="https://crieit.net/posts/acbf740434bef542013b122e814419a0">第八話「不意打ち」</a>に続く。</p> <p> </p> <p> </p> <p> </p> <h5 id="脚注"><a href="#%E8%84%9A%E6%B3%A8">脚注</a></h5> <h6 id="トピック"><a href="#%E3%83%88%E3%83%94%E3%83%83%E3%82%AF">トピック</a></h6> <ul> <li>Data Structure <ul> <li>Array</li> <li>Tree Structure <ul> <li>Binary Tree Seach</li> <li>Trie</li> </ul></li> <li>Stack / Queue <ul> <li>FIFO / FILO</li> <li>Priority Queue</li> </ul></li> <li>Hash Table <ul> <li>Bucket Implementation</li> </ul></li> <li>Linked List</li> <li>Graph <ul> <li>Directed acyclic graph</li> <li>Adjacency Matrix</li> <li>Adjacency List</li> </ul></li> </ul></li> <li>Algorithms <ul> <li>Sort <ul> <li>Quick Sort</li> <li>Merge Sort</li> </ul></li> <li>Iteration vs Recursion</li> <li>Dynamic Programming</li> <li>String Hashing <ul> <li>Palindrome Detection</li> </ul></li> </ul></li> <li>Others <ul> <li>Big O notation</li> <li>Stack vs Heap</li> </ul></li> </ul> <h6 id="UI"><a href="#UI">UI</a></h6> <p>二年ほど前にもこのテストを受けたことがあるのだけれど、インターフェースが中々分かりにくくて、その時は次の課題に進むボタンだと思って押したボタンが提出ボタンだったことがある。その結果はお察し。</p> 然るエンジニア🙊 tag:crieit.net,2005:PublicArticle/15302 2019-08-05T04:40:21+09:00 2019-09-03T10:14:49+09:00 https://crieit.net/posts/f25b2f7288e2fb366eb8923cfe444bd8 コーディングテスト - 練習編 <p><a href="https://crieit.net/magazines/anonymouse-engineer-ecrit/my-gafa-interviews">>> 連載トップ</a> <a href="https://crieit.net/posts/032b38ba6ac32fcfc16f4707ae8c2a50">> 前回のお話</a></p> <hr /> <p>最初のヤマであるマネージャーとの電話は驚くほどつつがなく終わったので、その次の日曜日に、Amazon の最初のステップとなったコーディングテストを行った。</p> <p>コーディングテストには、きちんと作動するコードが要求される。ブラウザーでテストサービスにアクセスし、専用のエディター上で要求されるコードを実装する。エディターにはテスト機能が付いていて、これを使うと前もって決められた入力パターンを試していき、正しい出力が得られるかどうかを確認する。要はユニットテストである。もしも正しい出力が得られない場合は、時間が許す限りコードを修正することができる。入力テストのパターンには大体エッジケース(特別な例外的な処理が要求される場合)や、入力データのサイズがとても大きい場合等が含まれていて(効率の悪い方法であれば時間内に処理が完了しないので不正解扱いになる)、これらを正しく処理できることが合格の要件になる。</p> <p>このような課題はソフトウェアエンジニアの分野ではよくあるもので、インターネット上には練習に使えるサイトがたくさんある。リクルーターによってはそのようなサイトのリストと練習する際に気をつけることのリストなんかを一緒に送っくれて、受験者にどのように対策をすればいいか助言してくれる。というか、リクルーターの仕事はなるべく多くの採用者を出すことなので、大体のリクルーターがこのような対策用の資料を送ってくれる。例えば Facebook は<a target="_blank" rel="nofollow noopener" href="https://www.facebook.com/careers/life/preparing-for-your-software-engineering-interview-at-facebook">専用ページ</a>で詳しい流れを説明してる。(<a href="#Google">Google は脚注参照</a>)だからテストや面接が始まって予期していなかったということはまずない。</p> <p>練習用サイトでよく名前が挙がる中<a target="_blank" rel="nofollow noopener" href="練習サイト">†</a>では <a target="_blank" rel="nofollow noopener" href="https://leetcode.com/problemset/all/">leetcode.com</a> が使いやすいと思う。日常的にコーディングを行なっている人は、練習する際には要求されていることが普段のエンジニアリングと違うということを意識するとよいだろう。エンジニアリングで重要なことは必ずしも課題を説く上では重要ではない。(メンテのしやすさとか。)僕は leetcode.com でまず Easy を解きながら、一通りのトピックをカバーして、その後 Medium を毎日一問一週間ほど続けた。この時、大事なのはコードを書き始める前にアルゴリズムの全体のプロセスをノートに書きだして整理しておくことだ。これは後のオンサイトインタビューの練習にも通じる。</p> <p>例えば、<a target="_blank" rel="nofollow noopener" href="https://leetcode.com/problems/count-and-say/">38 Count and Say</a> を見てみよう。</p> <blockquote> <p>The count-and-say sequence is the sequence of integers with the first five terms as following:<br /> 1 is read off as "one 1" or 11.<br /> 11 is read off as "two 1s" or 21.<br /> 21 is read off as "one 2, then one 1" or 1211.<br /> Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence.</p> </blockquote> <p>与えられた文字列を「何が」「何回」繰り返されるかによって書き直す。この処理を n 回繰り返したら得られる文字列を出力せよという問題だ。どのようにアプローチすればよいだろうか?</p> <p>まず問題を分析して、必要なコンポーネントを洗い出そう。この問題は Easy なだけあって、全体の流れは簡単だ。まず処理する文字列を “1” で初期化し、与えられた n 回だけ書き換え処理を実行すれば良い。この処理はメインの関数とは別の補助の関数として実行すると良さそうだ。</p> <p>では、どのようにして書き換え処理を実装すれば良いだろうか?まず、ルールを細かく見てコードに直して組み合わせでみよう。</p> <p>まず、文字列全体の書き換えは、部分部分を独立に書き換える処理の組み合わせでできていることが分かる。</p> <p><a href="https://crieit.now.sh/upload_images/4ec966ab393432dc5a27c64d6804fd825d470f75f13b2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/4ec966ab393432dc5a27c64d6804fd825d470f75f13b2.png?mw=700" alt="breakdown" /></a></p> <p>では、どうやって全体の文字列を個別の部分に分割すれば良いだろうか?しばらく図を眺めていると、これは単純に同じ文字の集合で分割すれば良いことがわかる。なるほど、与えられた文字列を前から順番に見ていき、次の文字が前と違っていればそこが分割箇所となるようだ。</p> <p>ここの分割の部分がこの問題の中で最も複雑なので、先に取り出して実装してみよう。以下では Python の Generator 構文を使って分割を実装してみる。多分、普通に初見でこの問題を説く際には Generator を使わずに、全てを一つの関数で処理するだろう。実際僕もそうしたが、ここでは問題を細部まで分割して分析すること主眼におくのでこのような形をとった。関数を分けない場合の回答も後に述べる。</p> <pre><code class="python">def _split(string): char, count = string[0], 1 for c in string[1:]: if char == c: count += 1 else: yield char, count char, count = c, 1 yield char, count </code></pre> <p>この分割ではまず初めに、取り出す文字 <code>char</code> とその文字が連続して出現する回数 <code>count</code> を、与えられた文字列 の最初の文字 <code>string[0]</code> と <code>1</code> で初期化する。そして、順番に残りの文字を確認していき、もし同じ文字が見つかったら回数を 1 増やし、違う文字が見つかった場合は、そこまでで分割が完了しているので、今保持している文字 <code>char</code> とその回数 <code>count</code> を放出する。分割ができれば、文字列変換のプロセスは簡単に以下のように書ける。</p> <pre><code class="python">def _process(string): return_value = '' for char, count in _split(string): return_value += '%d%s' % (count, char) return return_value </code></pre> <p>分割された文字と回数をそのまま文字に変換して繋げるだけの簡単なロジックになる。あとはこれを課題の規定する入出力の形式に揃えるだけで良い。課題では入力は n すなわち変換処理を実行する回数で、文字列の初期値は <code>‘1’</code> なので、</p> <pre><code class="python">def countAndSay(n): string = '1' for _ in range(n-1): string = _process(string) return string </code></pre> <p>となる。 先述した通り、普通に課題に説く場合は Generator を使わないで、新しい文字列の生成と、それに必要な文字の分割、数え上げを一緒に実行するだろう。その場合の実装は以下のようになる。</p> <pre><code class="python">def _process(string): return_value = '' char, count = string[0], 1 for c in string[1:]: if char == c: count += 1 else: return_value += '%d%s' % (count, char) char, count = c, 1 return_value += '%d%s' % (count, char) return return_value </code></pre> <p>全体のコードをまとめると以下のようになる。</p> <pre><code class="python">def _split(string): char, count = string[0], 1 for c in string[1:]: if char == c: count += 1 else: yield char, count char, count = c, 1 yield char, count def _process(string): return_value = '' for char, count in _split(string): return_value += '%d%s' % (count, char) return return_value class Solution: def countAndSay(self, n: int) -> str: string = '1' for _ in range(n-1): string = _process(string) return string </code></pre> <p>このようにして、問題を分析し、1. なるべく簡単な基本要素を定義し、2. 基本要素を組み合わせてフロー全体を組み立てることが出来るとコーディングテストはうまくいく。練習初めは実装を行わなくても、よいだろう。問題を見て、一晩かけて解法を考えて翌日取り掛かってもいい。文法やデータ構造の知識も大切だが、練習する際に大事なのは分析することなのだ。</p> <p><a href="https://crieit.net/posts/81831039f649c70bf0465a8915a96430">第七話「コーディングテスト - 実践編」</a>に続く。</p> <p> </p> <p> </p> <p> </p> <h5 id="脚注"><a href="#%E8%84%9A%E6%B3%A8">脚注</a></h5> <h6 id="Google"><a href="#Google">Google</a></h6> <p>Google は全部 YouTube ビデオになっている。</p> <p>Prep Videos:<br /> <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=ko-KkSmp-Lk">How to: Prepare for a Google Engineering Interview</a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=XKu_SEDAykw">How to: Work at Google — Example Coding/Engineering Interview</a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=XOtrOSatBoY">Interview tips from Google Software Engineers</a></p> <p>More general about hiring at Google:<br /> <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=k-baHBzWe4k">How to: Work at Google — How We Hire</a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.youtube.com/watch?v=1BGAdJ_0FH0">Ask a Google Engineer — How to Work at Google: Prospective Employee Qualities</a></p> <h6 id="練習サイト"><a href="#%E7%B7%B4%E7%BF%92%E3%82%B5%E3%82%A4%E3%83%88">練習サイト</a></h6> <p>Google リクルーターが送ってくれたリンク集。</p> <p>Websites recommended by Google Software Engineers:<br /> Top Coder: <a target="_blank" rel="nofollow noopener" href="https://www.topcoder.com/">https://www.topcoder.com/</a><br /> (If you can handle the DIV I 250 level questions on TopCoder getting around 220+, then you are in good shape.)<br /> HackerRank: <a target="_blank" rel="nofollow noopener" href="https://www.hackerrank.com/">https://www.hackerrank.com/</a><br /> Project Euler: <a target="_blank" rel="nofollow noopener" href="https://projecteuler.net/">https://projecteuler.net/</a><br /> LeetCode: <a target="_blank" rel="nofollow noopener" href="https://leetcode.com">https://leetcode.com</a><br /> 500 Data Structures and Algorithms practice problems/solutions: <a target="_blank" rel="nofollow noopener" href="https://techiedelight.quora.com/500-Data-Structures-and-Algorithms-interview-questions-and-their-solutions?share=1&utm_medium=email&utm_source=hackernewsletter&utm_term=code">Quora</a><br /> Competitive Programmer's Handbook: <a target="_blank" rel="nofollow noopener" href="https://cses.fi/book/index.html?utm_source=hackernewsletter&utm_medium=email&utm_term=books">https://cses.fi/book/index.html</a></p> 然るエンジニア🙊