独学でプログラミングを覚えることは可能でしょうか?もちろん可能だと思います。今はオンラインで手に入るプログラミングの教材がたくさんありますから。
が、自力でプログラミングを覚えるなら、プログラミングの基礎以外にも「これだけは押さえておいた方がいい」と個人的に考えているものが3つあります。今日はそれについて書こうかなぁと。
「記事を全部読むの面倒だからその3つだけ先に教えやがれ」と思ってらっしゃる方の為にそれらをここで説明すると、以下の3つになります。
- データ構造とアルゴリズム
- テストの書き方
- SOLID原則
「ふーんわかったわ」と満足いただけた方はブラウザの”戻る”ボタンを押してもらって結構です。「なんでその3つが必要なの?」と思った方、記事の続きをご覧ください。
そもそもなぜそんな話をするのか
過去の記事でも書いたのですが、私はオーストラリアの大学院のIT学部に学歴ロンダリングをし、そこで本格的にプログラミングを覚えました。しかし、未経験からプログラミングを覚えて海外でITエンジニアとして働きたい人にとって、コスパの面で言うとこれ(=オーストラリア大学院留学)は最適な選択肢とは言えません。
(オーストラリアでは大学(院)卒業後に就労ビザが貰えるので、どうしてもオーストラリアで働きたい人にとってはアリな選択肢だとは思います。詳しい話はこちらの記事をご覧ください。)
その一方、ここ近年ではオンライン上でプログラミングを学習できるサイトやソフトウェアエンジニアを養成するオンラインスクールが注目されてきています。就職までサポートする学校も存在するみたいですね。(俺が20台前後の頃にこんなサービスが存在してれば…)
私も新しい言語やフレームワークを覚えたい時は、Udemyでコースを買って勉強しています。
こういったサービスは非常に使いやすく、コスパの良さでは英語圏への留学とは比べ物になりません。近い将来、わざわざ留学という選択肢をとらなくても、
- オンラインでプログラミングを覚えて
- 日本で職歴を積みながら英語を勉強し
- 日本にいながら海外の求人に応募し
- ビザと一緒に仕事をゲット
みたいなやり方で海外就職/移住を実現する人も出てくるかもしれません。
しかし、これらのオンライン教材の多くはプログラミング言語やフレームワークやDB等についてはきっちり教えてくれる一方で、大学(院)で教わるコンピューターサイエンスあるいはソフトウェア工学でカバーされる知識/手法についてはあまり深く教えてくれません。(私が大手のプログラミングスクールのカリキュラムを見た限りでは…)
そこで、(別に先輩風を吹かすつもりではないのですが)独学でプログラミングを覚えている人に向けて、これら3つを紹介しようかな…などと思った次第です。参考になれば幸いです。
1つ目:データ構造とアルゴリズム
データ構造とアルゴリズムは、大学でコンピューターサイエンスかITを専攻すると履修できる科目です。
なぜエンジニアを目指すならデータ構造とアルゴリズムを勉強するべきなのか?一言で言うと、これがわかってないと効率が悪いコードを書いてしまうかもしれないからです。
そもそも、データ構造とは何のこと?
データ構造とアルゴリズムにおいて、大雑把に言うとデータ構造とは主に以下のようなことです。
- コンピューターがどの様にデータを保存、更新、削除しているか
- コンピューターがポインターを使ってどの様にデータを参照しているか
- 配列やハッシュマップといったデータの集合は、コンピュータ内でどのように構成されているか
じゃあ、アルゴリズムって何?
アルゴリズムとはコンピューターで問題を解くための一連の流れです。
例を挙げると、大学でのデータ構造とアルゴリズムの講義だと、
- 与えられたグラフの中から特定の値を探す
- 数字がランダムに入っている配列を小さい順に(あるいは大きい順に)並び変える
…等といった問題に直面したら、どのようなコードを書けば効率良く問題を解けるか?といったことについて学びます。
え?「その説明を読んでるだけじゃわかんねーよ」って?
じゃあ簡単な例をあげましょう。
var array = [0,1,1,1,2,3,5,6,9,12,17,19,20,20,20,23,….100000];
上記のように、数字が小さい順に並んで入っている配列があったとしましょう。このような配列を与えられた場合、特定の数値(targetと呼びましょう)がその配列に存在するかどうか知るために、あなたはどんなコードを書きますか。
もちろん、for loopを書き、その配列に入っている数字を初めからチェックしていき、その数字がみつかったらtrueを返す、見つからなかったfalseを返す…みたいなやり方でも大丈夫です。
for(var i = 0; i < arr.length; i++) {
if(arr[i] === target){
return true;
}
}
return false;
このやり方だと、運が良ければループの一週目で答えが見つかり、運が悪ければ最後まで配列の中をチェックしなければなりません。この検索方法を線形探索(Linear search)と呼びます。
配列が短い時は別にこのやり方でも問題はありません…が、配列の長さが何百、何千と大きくなっていくにつれて、実用的ではなくなっていきます。
その一方、二分探索(Binary search)なら、巨大な配列の中で特定の値をもっと効率良くさがせます。どんな方法かというと…
- 配列の真ん中の値をチェックする
- 真ん中の値が探している値より大きかったら配列の前半を、真ん中の値が探している値より小さかったら配列の後半の中でその値を探していく(真ん中の値が探している値ならそこで探索終了)
- 探している値が見つかるまで1と2を繰り返す
コードにするとこんな感じ。
function binarySearch(arr, first, last, target){
if (last >= first) {
var mid = first + (first - last) / 2;
if (arr[mid] === target)
return true;
if (arr[mid] > target)
return binarySearch(arr, first, mid - 1, target);
return binarySearch(arr, mid + first, last, target);
}
return false;
}
イラストにすると、このアルゴリズムは以下のように働きます。
(画像はhttps://www.topcoder.com/blog/binary-stride-a-variant-on-binary-search/より)
以下の表を見てください。表の縦軸(Operations)が計算にかかる時間、横軸(Elements)が計算に使われるデータの量(配列だったら、配列の長さ)です。
(画像はhttps://stackoverflow.com/questions/2307283/what-does-olog-n-mean-exactlyより)
線形探索だと配列の長さと計算時間が正比例する(O(n))のに対し、二部探索ではこれよりも計算時間が短くて済むことが証明されています。(O(log n))
「え?線形探索の計算の速さがなんで配列の長さと正比例なの?【配列の長さ÷2】の間違いでは?」と思った方へ。
プログラミングにおけるアルゴリズムの計算の速さ(”計算量”と呼ぶのが一般的です)は、一般的に言って巨大な数値を取り扱う場合を考慮しています。なので、係数(この場合は1/2)は無視するのが一般的です。これについてもっと知りたい方はWikipediaの説明をどうぞ。
このように、アルゴリズムに詳しくなっておくことで効率のいいコードを書けるようになるのです。
「なんか難しそう…」と感じた方もいらっしゃるかもしれませんが、データ構造とアルゴリズムは教科書さえ買えば十分独学で理解可能な分野です。
プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
一通り学部レベルで学ぶアルゴリズムを押さえたら、問題を解きながらアルゴリズムの理解を深めることをお勧めします。個人的にお勧めしたい教材はこれ。
世界で闘うプログラミング力を鍛える150問 ~トップIT企業のプログラマになるための本~
若干値は張りますが、実際にトップ企業の採用テストで使われている問題を解きながら、アルゴリズムの知識とコーディングスキルを磨く事ができます。
2つ目:テストの書き方
なぜテストの書き方を覚えるべきなのでしょうか?
テストを書く目的は様々ですが、個人的にテストを書いておく最大のメリットは既存のシステムの更新がしやすくなることだと思っています。
例えば、あなたが既存のシステムのユニットをいじくらなければならないとしましょう。その更新が他のユニットに影響していないかをチェックするためにはどうすればいいでしょうか?システムが何十ものユニットから造られている場合、手で動かしてテストをするのはあまりにも効率が悪いです。
余談ですけど、面接でも「どのくらいテストを書けるか」と質問されることがあります。オーストラリアで働いていた2年目の頃、オーストラリア国内のかなりいい会社から面接の話を頂きました。その会社からの電話面接と課題をパスして、オンサイト面接までいけたのですが、
「テストは普段書いている?」との質問に
「ウチのチームはそれほどテストを書いていない」と正直に回答したところ、
「じゃあユニットの一部を更新したらどうするの?」「まさかテストは全部手でやってるの?」と(やや厳しく)詰められたことがありました。
その面接をした数日後に結果を尋ねたら「もっと経験のある人が見つかったんだ。すまないけどその人を雇うことにしたよ」との回答。すごく面白そうな会社だったので非常に残念でした。これを読んでいるあなたには同じ目にあってほしくありません。
3つ目:SOLID原則
SOLID原則とはソフトウェアを柔軟でメンテナンスしやすくするための5つの原則です。
その5つをざっくり紹介すると以下の通り。
- S:Single responsibility principle(単一責任の原則):一つのクラスは一つの責任だけを持つべき
- O:Open–closed principle(解放–閉鎖の原則):ソフトウェアの拡張は認めても変更は認めないべき
- L:Liskov substitution principle(リスコフの置き換え原則):プログラム内のオブジェクトは、プログラムに影響を与えずにそのサブクラスのオブジェクトと置き換え可能であるべき
- I:Interface segregation principle(インターフェイス分離の原則):特定のクライアント向けに作られた小さなインターフェイスは、汎用的な大きいインターフェイスよりも良い
- D:Dependency inversion principle(依存逆転の原則):オブジェクトを作る際、クラスではなく、抽象に依存すべき
(もっと具体的な説明はないの?と思っていらっしゃる方にはこちらの記事をおすすめします)
SOLID原則を知るもう一つのメリットは、原則を知っている開発者同士のコードが理解しやすくなる点です。
私はこれらの原則をよく知らずにウェブ開発者として働き始めました。当時、先輩のコードを見ては「なぜこんな小さいインターフェイスを作るのか」「なぜこの人はこういう風にインスタンスを作るのか」と困惑していたのですが、これらの原則を勉強してから少しずつ彼のコードがわかるようになっていったのです。
テストと同様、エンジニア(特にバックエンド開発のポジション)の技術面接においてSOLID原則に関する質問はよく訊かれます。必ず押さえておきましょう!
こんにちは!!突然のコメント失礼します。
自分は大学在学中に留学を決意し今年の1月までオーストラリアに留学をしていました。
現在は三年生で今後の目標として、就職後に貯金をしオーストラリアのQUTの大学院にてITの専攻にいこうと考えていたところ、高橋さんのブログを見つけ、ほぼ自分のやりたいことを実践していて驚きとともに、何かアドバイスが貰えないかと思いコメントとしてご連絡させていただきました。
欲しいアドバイスとしては、
・大学卒業までに学んだ方がいいITに関する知識
・就職先でもITを使う企業に進んだ方が良いか
上記の二点が主に相談に乗っていただきたいことです。
ちなみに大学での学科は経営なのでITに関する勉強は独学またはオンラインでの勉強になります。
sho さん
こんにちは!ご感想、ありがとうございます。
・大学卒業までに学んだ方がいいITに関する知識
shoさんがどういった職業に就きたいかによると思います。
開発関連の職業(ソフトウェアエンジニア)を目指している場合なら、プログラミング言語の本を1冊買ってそれ通りに自分のPCでコードを書くところから始めるのが無難かと思います。
(そしてどのプログラミング言語を選ぶかは、shoさんは何を作るのに興味があるか次第です。)
もし開発関連以外のITの仕事に興味があるようでしたら、申し訳ないですけど私からはアドバイスのしようがないですね…。
(私はずっとウェブ開発の仕事をしてますので、この分野でしたらもっと細かくアドバイスできますが)
・就職先でもITを使う企業に進んだ方が良いか
これも、上の質問と同様ですね。
将来開発者として働きたいのであれば、ITを使わない企業に入る理由はないかと思います。
返信いただきありがとうございます。
つきたい職種に関しましては、個人的にスマホゲームの開発に関われると嬉しなと思いつつ、エンジニアとしての仕事内容がいまいちわかっていないためかウェブの開発にも少し興味があり欲張りな感じになっています。
もしよろしければ、ウェブ開発の分野についてアドバイスを頂けると嬉しいです。
>もしよろしければ、ウェブ開発の分野についてアドバイスを頂けると嬉しいです。
わかりました。そういうことでしたら、やはりウェブ開発の本やネット上の無料のリソースを参考にするなりして、サーバーサイドの言語を一つ使いながら簡単なウェブサイトを作ることから始めるのが良いと思います。
そうする過程で最低でもHTML、CSS、Javascript、サーバーサイドの言語一つそしてデプロイの方法がわかりますから。
それが終わったらGitおよびGithubの使い方を覚えましょう。これらはバージョン管理に使われている技術です。開発者として働くことになったらGitの使い方は必須です。
そしたらHTTP/HTTPS、REST API、SSH/FTP、そして現在使われているOSの基本的なコマンドラインの使い方を勉強されると良いかと思います。(ウェブ開発のポジションはよくフロントエンドかバックエンドかに大別されますが、これらはポジションに関係なく覚えておくべきです。)
現在shoさんは大学に通われているとのことなので一体どれだけの時間をプログラミングに充てられるかわかりませんが、将来ウェブ開発をされるのなら、とりあえずこれらは覚えておいて損はありません。