2019年2月28日
気をつけよう:プログラミングのキャリアの話 – 後編
(2018-5-12)by Vardan Grigoryan
本 記事は、原著者の許諾のもとに翻訳・掲載しております。
デスクトップ
ここでは、実際にデスクトップアプリケーションにならしめているデスクトップアプリケーションの一部についてお話しします。特定のスキルセットを必要とするデスクトッププラットフォームは大量に存在しています。例えば、Photoshopは画像を扱うアプリケーションなので、Photoshopなどで何か書きたければ、画像の処理を行うアルゴリズムと技法を絶対に知っておく必要があります。Dropboxなどで何か書きたい場合は、ソケットプログラミングを絶対に知っておく必要があります。そしてVisual StudioなどでコンパイラやIDEをビルドしたければ、コンパイラの操作方法を絶対に知っておく必要があります。ここではその詳細には触れません。デスクトッププラットフォームに取り組みたい場合に最も使う可能性のある言語について見ていきます。
デスクトッププラットフォームに関して言えば、プログラマはC++とJavaとC#の中で、どれを選択するか苦労しています。正しい判断をするための簡単な基準があります。Microsoftが好きであれば、C#を選びます。Oracleが好きであれば、Javaを選びます。そして、プログラミング言語は特定の企業に所有されるべきではないと考えているならば、C++を選びます。あまり参考にならないようでしたら、実際のサブプラットフォームについて検討してみましょう。Windowsユーザのためだけにソフトウェアを書く場合、C#が最良の選択です。両方ともMicrosoft社のプロダクトなので最も適合するのは明らかでしょう。しかし、C#の開発者たちは、.Net Coreのリリース以降、C#はLinux環境下でも使用できると主張しています。私は個人的に、Linuxを使いたい場合はC++を選択することをお勧めします。重要なのは、C++はクロスプラットフォームのプログラミング言語として作られているため、すべてのOSにおいて(MacOSであっても)うまく機能するという点です。この状況におけるクロスプラットフォームでは、それぞれの実際のOSでアプリケーションの”異なる”実行ファイルを生成するために、すべてのOSでC++プロジェクトを別々にコンパイルしなければならないと仮定しています。正直なところ、C++にはGUIがいくらか欠けています。いい口実としては、”C++はハードコア開発者のためのもので、ハードコア開発者はTerminal(コマンドラインインターフェイス)だけ使っている”という事実です。しかし、親切な開発者たちが集まり、C++に完璧に合う最高のクロスプラットフォームのGUIライブラリであるQtを作ってくれました。
最後に、C++が複雑であることに腹を立てていて、ユーザが完璧なGUI体験をするにはQtのような独立したライブラリに結合するべきで、異なるOSのためにプロダクトの異なる実行ファイルをコンパイルして送り出すのが嫌だという事実に対して怒りを覚えているならば、Javaを使いましょう。Javaには実行ファイルが送りやすいように仮想マシンがあります。アプリケーションは、JVM(Java仮想マシン)がインストールされているすべてのOS上で同様にうまく機能します。
モバイル
Javaと言って最初に頭に浮かぶのはAndroidです。Kotlinが世界に発表されたのよりずっと前に、JavaはAndroidアプリケーションを実装するための標準言語でした。近頃ではKotlinは開発者の心を魅了し、Androidプラットホームの開発アプリケーションでさらに素晴らしい体験をさせてくれています。ですから、Androidアプリケーションを作りたければ、JavaかKotlinのどちらかを選ぶべきです。正しい選択をするためには、裏の部分を見なくてはなりません。重要なのは、GoogleはOracleとはあまり相性が良くないという点です。OracleはJavaを所有しており、JavaはGoogleのAndroidにおいて優位に立っているため、いくらか柔軟性を持たせるためにGoogleは良い面(あるいは悪い面であるかは人それぞれですが)としてオプションを導入せざるを得なかったので、 ”サポートする素晴らしい言語があるのに、どうしてJavaなんて使うの” と言わんばかりにKotlinを導入しました。Android開発者としてのキャリアを歩み始めたばかりであれば、個人的にはKotlinから使ってみることをお勧めします。ただし、市場において優秀な開発者になるためには、すでにJavaで実装されたアプリケーションをサポートしなければならないので、Javaを理解しておけばおまけの特典として履歴書に書けるでしょう。
最後はiOSについてです。これは全く別の話になります。長い間、Objective-CはiOSの主要な言語であり、本当に正直に言えば、Objective-Cを習得するためには真面目に取り組めて厳しい目を持ち根気がある必要がありました。これは比較的少数のObjective-C開発者にとっての主要な問題であり、AppleはSwiftを導入することでついに正しい判断を下しました。SwiftはObjective-Cよりはるかに習得しやすく、iOS開発者の数を増やす一因となりました。つまり、iOSの開発者になるためには、Swiftを知っておく必要がありますが、本当に自信満々な開発者になるためには、Objective-Cでこれまでに書かれたアプリ(大量のアプリ)をサポートできるようにObjective-Cを習得しておいてください。
ここで、React Nativeに触れておきましょう。というのもReact Nativeを使えばJavaScriptだけでAndroidとiOS両方のプラットホーム用のアプリを作成することが可能だからです。市場における新規プレーヤーや急速に変化するプレーヤーとして、React Nativeが存在しており、もしJavaScriptだけしか知らなくても、すでに簡単なアプリを作ることができると考えてみましょう。
コーディング面接の準備
プログラミングの世界には、基本的な概念が存在しています。技術面接のほとんどは、問題解決能力と、これらの概念を知っているかどうかを見極めるためのものです。ですから、プログラミング言語を習得することに加えて、プログラマの武器として必要になる何らかの概念の理解を深めておく必要があります。私の最近の SoloLearn でのレッスン記事からの抜粋を示します(以下は、AndroidとiOSのアプリへのリンクです)。
SoloLearn。無料でコードを学ぶ。Google Playのアプリ
SoloLearnには、無料のコード学習コンテンツがたくさんそろっています。初心者から上級者に至るまで。たくさんある中から選んでください。
SoloLearn。App Store上でコードを学ぶ。
レビューを読む、評価を比較する、画面を確認する、SoloLearnについてもっと学ぶ。コードを学ぶ。ダウンロード。
コーディング面接の準備をうまくやるには、以下の分野について自信を持つ必要があります。
- アルゴリズムとデータ構造
- コンピュータの構成とオペレーティングシステム
- コーディング
- システム設計
アルゴリズムとデータ構造
プログラマに最も必要とされているスキルセットです。すべてのプログラマが精通しておかなければならないテーマを挙げておきます。
アルゴリズムの複雑性
O-記法とアルゴリズムの複雑性の計算方法。つまり、それらの複雑性に基づき、どのアルゴリズムがよりよいのかを知ること。例えばO(N)対O(logN)。
基本的なデータ構造とアダプタ
配列、連結リスト、スタック、キュー。
ソートと探索
さまざまなソートアルゴリズムを知っていると、プロジェクトに対して、実現しうる最適な実装を特定するのに役立ちます。訓練のために、挿入ソート、選択ソート、マージソートを実装して、線形探索と二分探索の違いを見分けてみてください。
木とグラフ
木とグラフは、Facebookの”フレンドグラフ”やGoogle検索の”ナレッジグラフ”など、至る所で使用されています。
ハッシュテーブル
世界でいちばん効率的なデータ構造の1つであることから、ハッシュテーブルは常に最善の選択となります。ハッシュテーブルを実装して、衝突を解決するテクニックを身につけることができるはずです。
コンピュータの構成とオペレーティングシステム
以下のようなトピックに詳しくなることを強くお勧めします。
- ビット演算
- CPUはどのように機械語を実行するのか
- スタティックRAMとダイナミックRAMの違いについて
- どのような種類のOSカーネルが存在しているのか
- “ミューテックス”と”セマフォ”の違い
- デッドロックとは何か。またライブロックとは何か。
コーディング
少なくとも1つ、プログラミング言語に精通しておくべきです。すべての利点と問題点を知ることで、お気に入りの言語のベストプラクティスをもとに常に効率的でこなれて読みやすいコードを書くことができるでしょう。
困難な課題を解く訓練を行うことを強くお勧めします。例えば次のようなものです(以下に示した課題は SoloLearn で確認することができます)。
- ヨセフスの問題
- ハノイの塔
- 文字列の圧縮
- Balanced Parenthesis
- 双子素数
システム設計
オブジェクト指向プログラミングを学ぶことは、今のプログラマにとっては絶対に必要なことです。システム設計とは、システム全体のことを考えながら、そのアーキテクチャを設計し、それをクラスに分割し、オブジェクトの相互作用を定義できることを意味します。
以下の質問に答えて準備をしておきましょう。
- Googleサーチをどのように設計するのか。毎秒、数百万もの同時リクエストがあったらどうなるのか。
- Facebookの友達検索をどのように実装するのか。
- リレーショナルデータベース管理システムをなぜ使用するのか。
- NoSQLデータベースをなぜ使用するのか。
正しい設計のひな形を知り、使用することを強く推奨します。例えば、コンボジットとデコレータの違いを理解しておくべきです。
若手開発者は、大抵、優れた問題解決のスキルを求められますが、最初の仕事では上に挙げたような項目をすべて知っている必要はありません。この一覧は、キャリアプランにとても役立つでしょう。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa