働き方はじめに11~12月あたりにシンガポールのGO-JEKとGrabのiOSエンジニア求人を受けてみたのでその時のことを書いていく。これらはそれぞれインドネシア・シンガポール発のユニコーンである。GO-JEKとGrabシンガポールのエンジニア転職情報はまだまだ少ないが、アメリカに比べビザも圧倒的に取りやすいしアリだと思う。結論は、GO-JEKとGrabではない、他のアーリーステージのスタートアップ※にジョインすることにしたので、GO-JEKは後半の方で辞退、Grabは普通に途中で落ちた。ここでは触れていない会社です。英語やビザの話はここでは触れずに、実際にどういうことが聞かれたのか日程感はどんな感じなのか、という話にフォーカスする。海外で働いてみたいけど面接ってどんな感じなんだろう、どういう準備をすればいいのだろうという人の参考になれば良いなと思う。LinkedInのプレミアム機能で、求人に応募している人がどのエリアから来ているのか見ることができるのだが、インドからの応募がめちゃくちゃ多いのが分かった。シンガポールの求人に対して一番応募しているのがインドなことが多い。日本からもっとガツガツそういうところに出ていく人が増えるといいなと思った。TL;DR英語はコミュニケーションできるくらいには必要だけど、営業できるレベルまで求められない。アメリカ英語のような慣れ親しんだ英語ではないと思ったほうが良い。平気で1ヶ月とかかかる。シンガポールに限った話ではないと思うが、思ったより時間がかかるのだなと実感した。面接はどれも平日の日中に行われたが、正社員で働きながらだとかなり大変そう。アルゴリズムというよりは、アーキテクチャやテストといった実践的なことが重視されているように感じた。⬇参考までに、ここに一般公開されているGO-JEKの採用フローが書いてある。応募するLinkedInの求人からGO-JEKの採用ページに飛んで、そこで自分でペイメントのiOSエンジニアを応募してみた。Resume(履歴書)はこのサイトで作成した。最初の返信が来る応募の返信が23日に返ってきた。応募してから返信が来るまでに一週間もかかってないとは思うが記録がなくて正確にはわからない。you.軽く30分くらいコールしましょう、ということだったので、いついつが開いてるよ、と20分後に返信した。その日のうちに、Googleカレンダーで招待が来て27日にコールすることになった。最初のコールをするエンジニアではなく採用担当と思われる女性の方とコールをした。お互い自己紹介をした後、会社や求人のポジションの説明を受けた。それに関して質問をしたり、という感じ。これで落ちることはないと思われる。この後、2日間かけてやってほしい課題を送るので時間を確保できる時にメールをしてくれ、と言われた。何かを作る課題だろう...。技術課題を行うこの日とその翌日はまるまる時間が確保できそうだったので、朝9時半過ぎに、課題を送ってくれと催促した。その30分後くらいに以下のような返信が来た。work.添付されていたPDFに仕様とデザインが書いてあり、それに従ったアプリを作る、というものだった。その仕様やデザインについてはここでは伏せるが、iOSアプリを好きにMVVMなりMVPなりで設計して実装、それに関連してUIテスト、ユニットテストを書きなさいという感じ。APIについては彼らがHerokuで立てたものを利用する。2日間でこれを実装できる人いるのか?という量だったが、とりあえずざっくりと機能を実装して、QuickとNimbleを使ってドメイン周りとバリデーションに関してユニットテストを書いた(UIテストは画面数も少なかったので気持ち書いたくらい)。時間が足りず、デザインは一部断念した箇所もあったが、12月1日の日付が変わる頃(12月2日の0時過ぎ)にメールで提出した。機能で言うと一応仕様通りにできてはいるが、デザインが一部当てれていなかったり、実装ミスでネットワークエラーの表示がうまくいかない状態だったので少々不安...。技術課題の結果が来るコードを提出したのが土日で、コード見るから少し待っててね、と3日月曜の朝に言われて、7日にメールが来た。技術面接に進むので日程を教えて欲しいということだった。技術課題はパスしたらしい!この後、技術面接の日程調整の連絡をして11日に行うことになった。馴れない英語での説明、ということだったので以下のようなリンクを参考にして勉強をした。GlassdoorGlassdoorというサイトで他の人が実際に受けた面接内容とか色々見れる。www.glassdoor.co.inソートや探索のアルゴリズムこのGitHubのリンクがiOSエンジニアのアルゴリズム勉強には最強だと思う。クイックソートやバブルソートの実装、バイナリツリーの実装など良く耳にするアルゴリズムはできるようにしておいた。このリンクにはたくさんの情報が載っているが、その中でも聞いたことあるが不安というところだけ確認した。github.comiOS開発についてiOS自体のライフサイクルと、ViewControllerのライフサイクルは以下のリンクで確認した。なんとなく分かっていたが、英語でちゃんと説明はできなかったのでいい復習になった。GitHubglassonion.hatenablog.comqiita.com以下で、普段なんとなく利用しているパッケージマネージャについても一応確認しておいた。Libaryの違いとか。技術面接のコールをするシンガポール人とインドネシア人がそれぞれリモートで参加して自分を含めて3人でコールをした。英語はシンガポールなまりとインドネシアなまりで結構辛かった。以下iOSエンジニア前提で質問されたこと日本語で見ると普通の内容に見えるけど英語でやると結構難しく感じた。参照型と値型について教えて変数がポインタであるか、値そのものを持つか。クラスは参照型なのである箇所で中身を変更すると、同じモノを参照している他の箇所の変数の値が変わってしまう。一方で、構造体は値型なので同じモノを参照していた他の変数に何も影響がない、的な話をした。みたいな英文になってしまい説明になってなくね?って自分で思って少々焦り、クラスと構造体を引き合いに出して説明した。Counterにカウントされるが、弱参照はカウントされない。ViewControllerがお互い参照する時は、弱参照を使わないとお互い参照しあってメモリリークする、みたいな話をした。先の技術課題で採用したアーキテクチャ(ここではMVP)について説明してViewはユーザからのイベントを受け付けてPresenterに伝え、Presenterからの通知を受けて描画する。重要なのはロジックを持たないようにすること。PresenterはUIロジックを主に担当する。ビジネスロジックは持たないようにして、必要に応じてモデルに処理を移譲する。Modelはビジネスロジックを主に担当し、API通信や端末のキャッシュアクセスとかはこの階層で行う。クリーンアーキテクチャの経験あるならそれについても教えてMVPの特にモデルについてUseCase、Repository、Datastore、Entityと細かく分けることによってそれぞれの責務を明確にした感じ。UseCaseはビジネスロジックに集中し、データアクセスの詳細については関与しない。することによって、モック化しやくなり、ビジネスロジックについてのユニットテストが容易になる。いうフワッとした説明をした。クリーンアーキテクチャでデータはどう扱うの?(具体的にどう聞かれたかは覚えていない...)domain層からpresentation層にデータを渡す時はトランスレータを噛ましてUIが扱いやすいように変換する。APIからのデータはEntityを使ってマッピングするが、Entity自体はメソッドを持たないただのイミュータブルなオブジェクトとして扱う方が好き、という話をした。(先の技術課題のコードを見ながら)この部分(Presenterが保持しているModelをセットする関数をPresenterのinit以外で実行可能になっている箇所)の意図を教えてイニシャライザ以外で変更可能なのは嫌だったけど、Presenterについてのユニットテストを書く時にモデルのモックをセットする用にやむを得ずそうした。時間があったらそこの部分を直したかったんだよね。時間的制約から仕方がない、と思ってさぼっていたところを突かれた。コメントくらいつけておけば良かった。(先の技術課題のコードを見ながら)この部分(Protocolで重複している箇所)をBaseProtocolみたいにして抽象化するのは考えなかった?可能ではあるけど、Base〇〇という親クラスみたいなものを作る方針が好きじゃなかったからそうしなかった。重複量が多いなら考えるけどここはそこまで大きくならないところなのでこのままにした、これは好みの問題かもしれない、と話した。(先の技術課題のコードを見ながら)この部分(PresenterやModel用にそれぞれProtocolを宣言している箇所)の意図を教えてPresenterやModelに対してユニットテストを書く時に、Presenter・ModelのProtocolを採用したモックを使うことで、ユニットテストを簡潔に書けるようになるから。