なんとなーく、ぼんやりと
学校の勉強だけじゃ仕事できないっしょ?とは思ってた。何となく。
でも、具体的に何が足りないんだろう。
よくわかんねぇな。
そうだ、インターンシップへ行こう。
貯金もなくなったし。
と、いうわけで。
夏休みの大半をインターンシップして過ごしていたので、そのご報告をしようと思います。
※ 「勉強」のためのプログラミングと「仕事」のためのプログラミングはさすがに比べられないので、比べられそうなのをピックアップして書き出します。
命名規則というものがある
命名規則。その名の通り命名に関するルールというものが存在します。
変数名は小文字スタートで単語区切りを大文字でやりましょうね(fooBarみたいな感じ)とか。
クラス名は大文字スタートでやりましょうね(FooBarみたいに)とか。
あと、共通認識のようなもので「こういう単語、こういう命名は避けよう」みたいなのもありました。
それはクラスの命名のアンチパターンとかを見るといいと思う。
他にもいっぱいQiitaにこういう記事あるから探して読んでみるといいかもね!
ファイルを細かく分けてプログラムを書く
Twitterとかでたまに怨嗟の声を耳にする...
1,000行の関数、10,000行のソースコードを避けるためにファイルは細かく分けるのが定石(っぽい)。
10,000行もコードがあるとどこに何が書かれているのか、探すのがとても面倒くさいし時間がかかる。
だから、細かく「あなたは〇〇をするファイル」、「あなたは△△をするファイル」と分けて書くことで、ファイル名だけで何が書いてあるかおおよそ察しがつき、探す時間が大幅に短縮できるし、面倒くささもマシになる。
ひとつのファイルをひとことで言い表せるのがベスト。
ひとことで言い表せないのなら、そのファイルはまだまだ分割できる。
ただ、分割したファイルの名前を適当に付けたら無意味どころか共働している人たちを錯乱させかねないのでやめようね。
的確な名前を付けよう。
コンピュータサイエンスで難しいことはたった二つだけだ。キャッシュ削除と命名だ。
という言葉があるらしいです。ようわからんけど。
命名は時間がかかってもいいからちゃんとしようね。
バージョン管理システムを使う
まぁ、勉強で書くコードは短いし二度と触れることなんかないから、バージョン管理なんてそもそも必要ないんだけども。
Processingの実験のときとかは使ったほうがスムーズだったね。
バージョン管理システムというのはコードの歴史を刻む仕組みのこと。
「動かなくなったやべぇ、どうしよう... 書き換えたコードがわからないよ...」なんてことを防ぐことができる。
Gitというのがメジャーなバージョン管理システムで、使いこなせるといろいろ楽になる。
Processingの実験で例えると、段階ごとにファイル分けなくても、段階ごとに歴史を刻む(コミットする)ことでその状態へいつでも戻すことができる。
コミットするのを忘れるとどうしようもないけどね。
まぁ、でもワンクリックでできるし楽ちんよ~。
あ、Gitそのものはコマンドで扱うものだけどGUIクライアントなるものも存在しているから、それを使うとGUIで操作できるし、自分の進捗を目で見て感じられるのでオススメです。
僕が使っているのはGit Kraken。
Gitは複数人で同じプロジェクトのコードをいじくるときとかは必須レベルで必要。
ブランチと言って、プロジェクトの進捗を枝分かれさせて、別々に作業ができたり。
ブランチとブランチをマージすることで、複数の進捗を自動的にひとつにまとめることもできます。
ガチ便利なので機会があれば使うことをオススメします。
効率的なツールを使う
まぁ、当り前っすよね。
Emacsでコード書くのはマゾいっすよ。やっぱり。
開発環境を使うと、変数名や関数名を補完してくれたり、構文エラーをコンパイルする前に教えてくれたりと、快適にコードを書くことができます。
正直、素のテキストエディタでプログラム書くのはマジキチ。
インターンで使っていたのはJetBrainsという会社のIDE。
Java用であればIntelliJ IDEA、Python用であればPyCharmなどなど。
強力な入力補完と、サジェスト表示が魅力的なIDEです。
IntelliJ IDEAとPyCharmは無料版あるのでぜひぜひ。
大学のメアド使えばJetBrainsのEducationライセンスをもらうこともできるからProfessionalが使いたくなったら無料で使うこともできます。
Professionalのライセンスがまぁー高いんすわ。
お仕事に使うものだから当然といえば当然なのかもだけども。
学生は無料で使えるから無料で使えるうちに無料で使うといいでしょう。
ちょっと余談。
EmacsはM-/
で入力補完ができるみたいデス。
Vimの人はCtrl+p
でできます。
変数名とかの誤字とかしょうもないので、こういう機能を活用してヒューマンエラーを防ぎましょう。
使えるものは使っちゃえ!!
最後に
20回くらいしか出勤してないから、まだまだこれから得ることもあると思うけど、夏休みはとりあえずこんな感じでした。
これから授業で「この構文ホンマに必要か...?」と思うことが多々あると思う。
高校でJavaを習ってるときに、俺は思いまくった。
でも、実際どれも使いこなせると便利な構文なんだけど、うまく授業でその便利さを教わることが難しい。
規模の大きいソフトを作るときなんかに有用なものが多いので...
授業でちょろっと書いただけでは魅力がわからんのですよ...
インターンシップでコード書いて、そう感じました。
また、インターンはハズレも多いようです。
コード書きたくてインターン申し込んだのに雑用したかやらしてくれない!!みたいのもあるらしい(?)ので、インターンを探すときはその辺を疑ってかかるといいかもしれねぇっす。
あと、インターンを探すサイト全般メールがクソウゼェので捨てメアドで登録したほうがいいかも。
以降2019/01/19 追加
アーキテクチャなるものがある
ぼくがいじくってるやつはMVCというアーキテクチャを採用している。
アーキテクチャっていうのは、クラスとクラスの関わり合いに名前を付けたもの。
前述のMVCアーキテクチャはソフトウェアを構成するクラスを大まかにModel、View、Contorollerの3つに分け、ここの依存関係をあまり密接でないようにしよう!というもの。
クラスとクラスの関わり合いが多すぎると、管理しにくいし、バグが発生したときの確認箇所がたくさんあって大変になっちゃうから、それをできるだけ楽にしようって感じなのかなぁ...?
テストをかけ
学校でプログラムを書くと、だいたいは先生が答えを持ってて、その答えっぽければ正解、だよね...?
動かなかったら不正解。正しい答えが得られなければ不正解。この正誤の判定は先生、もしくは自分がやるんだけど。
コンピュータにやってもらおうよっていうのがテスト。
テストコードを書いて、自分の書いたメソッドがバグを吐かないか、期待する結果が得られるものであるかを確認する必要がある。
テストをやるにはテストを行うための環境を整える必要があるけど、IDEを使えば簡単に整えられるのでぜひ試してみてほしい。
例えば、引数に与えられた数値を足し算するメソッドを書いたとする。
int tashizan(int num1, int num2){
return num1+num2;
}
これをテストしよう!と思ったらざっくりこんな感じになる。
public class SampleTest {
@Test
public void testTashizan() {
assertThat(tashizan(1, 2), is(3));
}
}
メソッドを実行させて、その右の引数には自分が予想した帰ってきてほしい戻り値を書いておく。
このテストを実行すれば、そもそもメソッドが止まらずちゃんと動くのか。1+2=3
という期待した答えを返してくれるのかを確かめることができる。
assert〇〇()
はどの言語でも大体あるし、いろいろ種類があるので適切なものを使おう。
そして、このテストコードは消さずにとっておくことで、未来の自分であったり、協働している他のプログラマがそのプログラムを使うときにテストコードを見て使い方を理解したり、どういう機能を提供するものなのかを実際に動くもので確かめることができるからとっても大事。
あとはAndroidとか、webアプリとか、ちょっとだけ試すのがめんどくさい環境でもテスト環境を整えればコマンド一発でさっくりメソッドの動作を確かめることができるので、より早く効率的に開発が進められるよ!!
作ったソフトを効率的に運用する
Webアプリを動作させるには、実行するマシンにwebサーバを整えたり、必要なライブラリとか、言語プロセッサをインストールしたり、いろいろめんどくさい。
また、開発途中でそれらをアップデートしたくもなるし、必要ないものは消したくなるかもしれない。
これらを簡単に行うためにぼくのインターン先ではDockerというものを使っている。
Dokcerはとっても軽いVMwareみたいな感じで仮想環境を構築してくれる。
どんな環境を構築するのかをファイルに書きこんで置くことができるので、開発を始めるときも、サーバーマシンで動かすときも、git pull
してきてdocker-compose up
ってやるだけで環境を整えてプログラムを実行してくれる。便利。
その他にもいろいろ恩恵はあるんだけど、うまく説明できないというか、それだけでエントリ書けるくらいなので割愛。
条件分岐を厳密にやりたい
プログラムでモードを切り替えたい。なーんてときに数字とか、文字列とかでやってきたと思う。
switch(kind){
case "fruit":
/* くだもの */
break;
case "meat":
/* おにく */
break;
case "fish":
/* さかな */
break;
}
でもこれって、あんまり厳密じゃない。
条件分岐をするのにString型は普遍的すぎてやりようが多すぎる。
さっきの例なら"fruit"
と"fru" + "it"
と"FRUIT".toLowerCase()
が全部同じ結果になる。
それに、もしも誤字っちゃって"frit"
とか打っちゃったら正しく動かない。
最近の言語なら大体Enumとかそういうのがあるから、そういうのを使おうよ...!
Enumは列挙型と呼ばれるもので、条件分岐とかに使うと超便利。
enum class Kind(val value: Int){
fruit(1),
meat(2),
fish(3)
}
とか書いておくと、さっきのSwitch文がこんなかんじになる。
(さっきの例はKotlinだけど、Switch文はJavaで書いちゃう)
switch(kind){
case Kind.fruit:
/* くだもの */
break;
case Kind.meat:
/* おにく */
break;
case Kind.fish:
/* さかな */
break;
}
こうなればkind
にはさっき宣言したEnumのKind.fruit
、Kind.meat
、Kind.fish
のいずれかのみしか受け付けないようになる。
また、たいていのEnumには逆引きできるメソッドが備わっているので、String型のものを変換して扱うことができる。
というかそもそも条件分岐をさせないようにすればいいんだけどね。