🤱

新入社員の頃の技術メモを振り返る

2023/11/12に公開

背景

私が入社当時から続けている習慣として

  • 聞きなれない単語はメモして、あとからゆっくり調べる
  • もし分からなければ誰かに質問する

というものがあります。過去のメモを整理していると、新入社員の頃に書き留めたものがたくさん出てきました。私のこのメモも誰かの助けになるのではないか、という思いから今回は

  • 一般的なプログラミング用語であり
  • 他の初心者の方に共有しても有益そうなもの

をピックアップ、整理して5個公開したいと思います。

当時のメモは外部サイトをそのままコピーしたままものが多かったので、

  • そのソースのリンクを張り、
  • 「いまの私ならこう説明する」といった内容を加える

といった形で進めます🙋‍♂️

参考:入社当時の私はこんな感じでした

入社時のレベルは人や会社によって大きく異なるはずです。記事のレベル感の参考として、私の入社当時の背景をまとめておきます。

  • プログラミングというものはほとんど未経験
    • 入社するまでクラスもGitも知りませんでした
  • 使ったことがあったものは以下
    • 卒論修論などは\LaTeXで書いた
    • 先輩の書いたIgorやMathematicaのコードを実行するくらいは経験済み

Git用語とその仕組み

大抵の現場で使われているであろうGitですが、用語の数がとても多いです。そして

🤔Gitってなんなの

という状態以前に、そもそも私は入社当時

🙄なんで差分管理なんてする必要があるの

という状態でした。そんな疑問が湧いている状態で意味を説明されても飲み込めません。この状態を克服するためには

  1. まず必要性を理解して
  2. 実際に使ってみて
  3. わからない単語の意味を正確に押さえる

という手順が必要になります[1]。とくに「なぜ必要なのか」というのは実体験を伴わないとなかなか納得できません(でした)。

Gitの必要性については初心者向けに優れた記事がたくさん出てくるので割愛しますが、あくまでその操作を覚えるためには、GUIのGitクライアントを利用して色々いじってみることとよいです。

しかし、変な操作をするとリモートリポジトリに影響を与えてしまうかもしれません。そのため、まずは誰か先輩を捕まえて一連の操作を説明してもらいましょう。実際の操作、たとえば「プルリクエストを作成したいが、操作に不安があるので見てほしい」と具体的な説明をお願いすればスムーズだと思います[2]

その上で単語をひとつずつ押さえて行けばよいです。数は多く見えますが、はじめは

用語 説明
リポジトリ プロジェクトのソースを格納する場所。変更履歴、ドキュメント、コードなどが含まれる。 リモートにあるものをコピー(クローン)してきて作業する。
コミット コードの修正部分の単位。変更を記録し、あとから特定の状態に戻すことができる。
ブランチ 編集履歴の流れを記録していくためのもの。自由に分岐でき、複数人の同時編集を可能にする。
マージ 異なるブランチを一つに統合するプロセスのこと。

くらいを覚えれば十分なので、まず仕組みを理解することを優先しましょう。それがわかれば理解の大きな助けになります。それに口頭ではあまり使わない単語もたくさんあるので、一度に全部覚えようとする必要はありません[3]

OSS

オープンソースソフトウェア(Open Source Software)の略称です。これはソースコードが無償で公開されており、ライセンスのもとで利用や改変、再配布などが許可されているソフトウェアのことを指します。具体的には、Android OS(のコア部分)やNode.jsなどがOSSです。他にもものすごくたくさんあります。

車輪の再発明をしないためにもOSSは積極的に使うべき、というよりは、使うことが当たり前過ぎてOSSが関わらないプロジェクトは考えにくいです。

注意しなくてはならないのは、そのライセンスです。

OSSには必ずライセンスが宣言されており、再配布するためにはこれに基づく必要があります。たとえば、GitHubのプロジェクトルートには大抵LICENCEのようなファイルが置かれています。これがライセンスファイルです。当然英語ばかりですが、一度は実際に覗いてみましょう。

OSSのライセンスは本当にさまざまなものがありますが、基本的な考えとして

  • 著作権表示:著作権を明示すれば自由に使ってよい
  • 無保証:OSSを利用して発生した問題について一切その責任を負わない

という点があります。注意するべき点として、これらはコピーレフトの有無により2つ大別されます。

  • コピーレフト型
  • 非コピーレフト型

これらの中間として準コピーレフト型もあります。このコピーレフトというのをざっくり言うと

  • 再配布の際には、そのソースコードを開示する
  • 改変したコードにも同一のライセンスを適用し、これを明記する

というものです[4]。つまり「改変して再配布してもいいけどコードは全部開示して同じライセンスを付けてね」ということです。とくに商用利用では、コピーレフトライセンスを使用する場合は注意が必要になります。

ちなみに先述のAndroid OSはApache License 2.0, Node.jsはMIT Licenseですが、これらは非コピーレフトライセンスの代表例なので自由に使えます[5]

ユニットテスト

ユニットテストとは、プログラムを小さな単位(ユニット)の組み合わせとして見て、それら各々の機能が正しく動いているかを確認するテスト手法のことです。ユニットテストのメリットは非常に多くあるので具体例を用いて説明します。

数を2つ受け取り、その商 a/b を整数に切り捨てて戻す関数が必要になったとします。それを受けて、あなたはJavaScriptで次のコードを書きました

/**
 * 除算 (a/b) を求め、その結果を整数に切り捨てた値を戻す
 * @param {number} a 割られる数
 * @param {number} b 割る数
 * @returns {number} 計算結果
 */
function divideAndFloor(a, b) {
  return Math.floor(a / b);
}

この関数は

  • divideAndFloor(5, 2)2 を戻す
  • divideAndFloor(-5, 2)-3 を戻す
  • divideAndFloor(-5, -2)2 を戻す

といった動作が予想できます。これを実際に

const isOk = divideAndFloor(5, 2) === 2
console.log(isOk ? 'OK😊' : 'NG🤮')

のように試してみるのがユニットテストです。実際にはJavaScriptならJest, Pythonならpytestなどのテストライブラリで実装するので、このコードはあくまでイメージであることに注意してください。

さて、いずれも問題なさそうです。しかし、それを確認してからあなたは気づきます。0で割ったらどうなるのでしょう。InfinityNaN ではどうでしょう。これらは同じNumber型なので、あとから他の誰かが実行してしまうかもしれません。このように、ユニットテストを書く中でエラーケースの検討を強制できます。他にも

  • テストコードを読むことで、その使用者は実装者がその関数がどう動くかを想定していたかを確認できる
  • 使い捨てではなく永続的にコードを残すことで、あとからその部分が確実に動いていることを確認できる

といった点からバグの削減につながります。

そして重要な点として、一般に

というシグナルがあります。そのようなコードは密結合であったり、スパゲッティコードになっているはずだからです。つまり、ユニットテストを書くことを意識するだけで、コードの質が上がることが多いのです。

一方で、逆に

ことに注意してください[6]

ユニットテストは非常に奥が深いので、ここではこの程度に留めます。もし興味があればテスト駆動開発(TDD)やスタブ、モックなどについて調べてみてください。

コールバック

プログラミングにおけるコールバックとは「あらかじめ処理Aを登録しておき、処理BによってAを実行する」というフローのことです。処理Aが実行されることを「コールバックされる」と表現します

たとえば、「画面の色を変える」という処理Aを「アイコンをクリックする」という処理Bのコールバックとして登録しておきます。すると、そのアイコンがクリックされたタイミングで画面を色を変えることができます。

具体例として、JavaScriptでは次のようなイベントリスナを設定することが多いと思います。

const el = document.getElementById('changeColorButton');
el.addEventListener('click', () => {
    document.body.style.backgroundColor = 'lightblue'; // 背景色を変更
});
補足:第一級オブジェクトについて

ここではアロー関数 () => {}addEventListener の引数に渡しています。これはJavaScriptにおける関数が、他の値(数値、文字列など)と同じように扱うことができる 第一級オブジェクト (first-class object) であるからです。

このような関数が第一級オブジェクトである言語として他にPython, Ruby, Rustなど、逆にそうではない言語してC言語やJavaがあります。C言語は関数ポインタ、Javaはラムダ式や関数型インタフェースを用いて類似の処理が実装できます。このような違いを意識して学習すると見通しがよくなるでしょう。

参考までに、私は当時の先輩から

💁‍♂️コールバック関数というのは、引数として渡せる関数のことだよ

という説明を受けて混乱したことを覚えています。これは確かに正しいのですが

🙆‍♂️コールバックとは別のトリガーのためにセットしておいた処理が発火すること
🙆‍♂️コールバック関数はその処理内容として渡す関数のこと

と理解したほうがスムーズだと思いました。

ポーリング

システムが定期的に特定の状態をチェックする処理のことを言います。たとえば、10分おきに温度計の数値を確認し、もし30℃以上ならクーラーの電源を入れる、などですね。

もう少しプログラミング的な観点から言えば

  • 一定間隔で実行される関数を設定して、特定のパラメータの状態を監視する
  • このパラメータが特定の条件を満たした場合、別の処理を実行する
    • たとえば、ある値がtrueになったり、上限値を超えたりした場合

といったイメージです。逆に、あるパラメータが頻繁に更新されることが予想される場合、一定時間更新がないことを確認して特定のアクションを取ることもできます。

何かイベントが発生したら別の処理を行う、というのはコールバックと類似していますね。それぞれに向いている処理は次のようにまとめられます。

まとめと感想

今回は私のメモ帳から、初心者向けにメジャーなトピックを5個整理してご紹介しました。

過去のメモというのは日記帳みたいなもので、まとめていてとても暖かい気持ちになりました。たとえば「フォアグラウンド」はフォグラウンドとメモされていました。かわいいです。こういう機会でないととなかなか自分の成長は実感できないものですね😛

はじめは軽い気持ちで記事を書こうと思っていたのですが、想像以上に時間がかかりましたし、改めて調べることで勉強になることもありました。また機会を見つけて書いてみようと思います。

脚注
  1. 手順には一応番号を振りましたが、これらは前後したり並行したりします。 ↩︎

  2. ある程度慣れてからは、GitHubに適当なプライベートリポジトリをつくって好き勝手にいじるのが効果的だと思います。 ↩︎

  3. たとえばハンク (hunk) なんて意味は簡単ですが、一度も口頭で使ったことはありません🙃 ↩︎

  4. 著作権 (copyright) をもじってcopyleftという名前になりました。私はこの記事を書くまで知りませんでした…。 ↩︎

  5. 普段はあまり意識しませんが、これらにはちゃんと違いがあります。利用する際には別途調べてください。 ↩︎

  6. Vladimir Khorikov著『単体テストの考え方/使い方 プロジェクトの持続可能な成長を実現するための戦略』を参考にしました。 ↩︎

Discussion