面接でされた技術質問まとめ

実際にエンジニア転職の際された質問を解説も込みでまとめてみました。
皆さんのお役に立てれば幸いです。

① ActiveRecord
② オブジェクト指向プログラミング言語
③ Webアプリケーションフレームワーク
④ WebサーバーとWebクライアント
⑤ 仮想化
⑥ 最適なクラス設計

# ① ActiveRecord
Active Recordとは、MVCで言うところのM、つまりモデルに相当するものであり、ビジネスデータとビジネスロジックを表すシステムの階層です。Active Recordは、データベースに恒久的に保存される必要のあるビジネスオブジェクトの作成と利用を円滑に行なえるようにします。Active Recordは、ORM (オブジェクト/リレーショナルマッピング) システムに記述されている「Active Recordパターン」を実装したものであり、このパターンと同じ名前が付けられています。

## O/Rマッピング
オブジェクト/リレーショナルマッピング(O/RマッピングやORMと略されることもあります)とは、アプリケーションが持つリッチなオブジェクトをリレーショナルデータベース(RDBMS)のテーブルに接続することです。ORMを用いると、SQL文を直接書く代りにわずかなアクセスコードを書くだけで、アプリケーションにおけるオブジェクトの属性やリレーションシップをデータベースに保存することもデータベースから読み出すこともできるようになります。

## Active Recordパターン
パターン名としてのActive RecordはMartin Fowler『Patterns of Enterprise Application Architecture』という書籍で記述されました。Active Recordパターンにおいて、オブジェクトとは永続的なデータであり、そのデータに対する振る舞いでもあります。Active Recordパターンは、データアクセスのロジックを常にオブジェクトに含めておくことで、そのオブジェクトの利用者にデータベースへの読み書き方法を指示できる、という立場に立っています。

## ORMフレームワークとしてのActive Record
Active Recordにはさまざまな機能が搭載されており、その中でも以下のものが特に重要です。

・モデルおよびモデル内のデータを表現する
・モデル同士の関連付け(アソシエーション)を表現する
・関連付けられているモデル間の継承階層を表現する
・データをデータベースで永続化する前にバリデーション(検証)を行なう
・データベースをオブジェクト指向スタイルで操作する

## Active RecordにおけるCoC(Convention over Configuration)
他のプログラミング言語やフレームワークでアプリケーションを作成すると、設定のためのコードを大量に書く必要が生じがちです。一般的なORMアプリケーションでは特にこの傾向があります。しかし、Railsで採用されているルール（慣習）に従っていれば、Active Recordモデルの作成時に書かなければならない設定用コードは最小限で済みますし、設定用コードが完全に不要になることすらあります。これは「設定がほとんどの場合で共通ならば、その設定をアプリケーションのデフォルトにすべきである」という考えに基づいています。つまり、ユーザーによる明示的な設定が必要となるのは、標準のルールでは足りない場合だけです。

[Railsガイド](https://railsguides.jp/active_record_basics.html)　より引用

https://railsguides.jp/

# ② オブジェクト指向プログラミング言語とは

プログラミングとは、コンピュータが理解できる言葉を並べてプログラムを作ることです。その際に、プログラマの意図した順番通りにコンピュータを動作させる指示を出しているのです。

プログラムを意図した順番通りに表現する代表的な方法が下記の３つです。

|プログラムの表現方法|プログラムの流れ|
|---|---|
|オブジェクト指向プログラミング|「もの」を組み立てる様に表現してコンピュータに指示する|
|手続き型プログラミング|プログラムを上から順番に処理を実行する|
|関数型プログラミング|関数の組み合わせによってプログラムを組み立てる様に表現する|

Rubyは、「もの」を組み立てる様に表現してコンピュータに指示するオブジェクト指向プログラミング言語です。「もの」を組み立てる際の設計図を「クラス」と呼び、その「設計図から作成された実物体」のことを「インスタンス」と呼びます。


[【Ruby】たい焼きで理解するオブジェクト指向におけるクラスの概念](https://pikawaka.com/ruby/class)　より引用

https://pikawaka.com/ruby/class


# ③ Webアプリケーションフレームワークとは
開発のための技術の発達によってWebアプリケーションを作るのはだいぶ楽になりました。
しかし、実際の開発現場は大変でした、アプリケーションが非常に大規模なものになってきたからです。
こういったものをゼロからサーブレットやJSPで作っているとコーディング量は莫大なものになり完成までにたくさんのお金と時間がかかってしまいます。また、システムが大規模化したことで開発に携わる人間の数もどんどん増えていきます。その状況だと開発者が勝手に独自のライブラリやクラスを作ってしまい、後で結合がうまくいかなかったり不整合が怒ったりという問題が出てきてしまいます。
なので大規模なアプリケーションを効率よく開発するには「再利用」という考え方が有効です。
一度作ったプログラムは何度でもコピーして利用できます。よく利用される処理は「ライブラリ」と呼ばれるプログラムを部品として整備され、何度も同じプログラムを作成しなくても良いようになってます。
この考え方をさらに押し進め再利用できる部分を増やしてアプリケーションを開発しやすくするための土台として作られたのが「フレームワーク」です。

# ④ WebサーバーとWebクライアント

WWWによるハイパーテキストの公開と閲覧はWebサーバーとWebクライアントというソフトウェアで実現されています。
クライアントとサーバーという言葉はそれぞれコンピューターやその上で動作するソフトウェアをさしています。
WWWではWebサーバーがネットワーク上に公開するハイパーテキスト(HTML)を蓄積しWebクライアントの要求(リクエスト)にしたがって適切なファイルを渡す（レスポンス）仕組みになっています。


## Webサーバーのプログラムについて
Webサーバーは上のとおり、クライアントからのリクエストを解釈し、サーバー上に用意された該当ファイルを返すことが基本となっている。

このやり取りの流れは、 HTTPという決まりごと(通信プロトコル)の上で動いているため、この決まりを処理できるプログラムがWebサーバーと言われる。

Webサーバーとしての機能を持つプログラムは多数存在するが、以下のものが有名なものである。

## Apache
Webサーバーとして非常に有名なものだ。デファクトスタンダードと言われるWebサーバーである。何も注意なく、Webサーバーと言われたら大体Apacheだ。

モジュールとして機能を後から出し入れでき、動作性能も一般的には問題ない。

 Apacheはオープンソースなものであり、利用の際の制限がほぼ無いため、一般的なLinuxディストリビューションの標準Webサーバーとして配布されている

## Nginx
「エンジンエックス」と発音する、最近人気の上がっているWebサーバーだ。

Apache同様オープンソースなWebサーバーのひとつで、並行処理性能の高さ、比較的メモリ消費が少ないなどの特徴を持っている。

オープンソースの開発形態ではあるが、強化された商用版も別途存在している。 現状では、処理性能のためにプログラム構築時に必要な機能を組み込む機構になっている。 このため、配布されているパッケージ版では不要な機能が組み込まれていることもある。 性能を調整したい時などはソースコードを入手して調整する必要もある。

[今更聞けない！Webサーバーの仕組みと構築方法](https://eng-entrance.com/web-server-mechanism)　より引用

https://eng-entrance.com/web-server-mechanism

「プロになるためのWeb技術入門」　より引用

https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352

# ⑤ 仮想化とは？

## 仮想化とは
仮想化とは、サーバーなどのハードウエアリソース（CPU、メモリ、ディスクなど）を抽象化し、物理的な制限にとらわれず、ソフトウエア的に統合・分割できるようにする技術です。

現代のように仮想化技術が普及していなかった頃は、サーバーは用途ごとに専用のハードウエアを用意して構築するのが一般的でした。つまり、Webサーバー、メールサーバー、ファイルサーバーなど、サーバーの種類や数が増えるごとに保有するハードウエアの台数も増えていたわけです。しかし、サーバーを仮想化することで、1台の物理サーバーの上に複数の仮想サーバーをソフトウエア的に作成し、同時に動かすことができるようになりました。

サーバーの仮想化を行うには、専用の仮想化ソフトウエアが必要になります。仮想化ソフトウエアとしては、主にPCで利用されているオラクルの「Virtualbox」、ニフクラで採用しているVMwareの「VMware vSphere」、Microsoftの「Hyper-V」などが有名です。また、サーバーだけでなく、ストレージやネットワーク、デスクトップ環境やアプリケーションといったリソースの仮想化も利用されています。

## 仮想化のメリット
従来のようにハードウエアをそのまま利用するのに比べ、仮想化には多くのメリットがあります。サーバーの仮想化を例にとると、具体的には以下のメリットが挙げられます。

### 効率的なリソースの活用
従来のように、サーバーごとに専用のハードウエアを利用していると、用意したハードウエアの性能を効率よく使い切ることができません。その理由は、サーバーごとの稼働率の違いです。例えば、社内用のファイルサーバーはほとんど使われていないのにインターネットに公開しているWebサーバーはアクセスが多く、常に高い負荷がかかっているというようなケースが考えられます。

また、サーバーのスペックは多くの場合、ピーク時の負荷を捌ききれるように考えて選択されるため、ピーク時以外では必然的に余剰リソースが発生してしまいます。しかし、ハードウエアの間を越えて、CPUやメモリなどのリソースを融通しあうことはできません。そのため、あるサーバーは常にリソースを余らせているにもかかわらず、その隣のサーバーは常にリソース不足に苦しんでいる、というジレンマも発生しがちです。

しかし、サーバーを仮想化すれば、複数の仮想サーバーを1台の物理サーバー上に集約できます。物理サーバーが持つリソースを複数の仮想サーバーに自由に配分できるため、リソースを効率的に使用できます。また、物理サーバーが持つリソースを越えて仮想サーバーにリソースを割り当てる「オーバーコミット」という仕組みを利用すれば、さらに集約効率を高めることも可能です。

仮想化によるリソースの最適化によって「余剰設備」を保有しなくて済み、導入コストや運用コストの削減に繋がります。

### ハードウエアの運用工数が軽減
複数のサーバーを1台のホストに集約すれば、保有するハードウエアの数を少なくすることができます。これはハードウエアの導入コストだけでなく、メンテナンスにかかる工数の削減にも繋がります。また、仮想化にVMware製品の「VMware vSphere」を利用している場合、仮想サーバーのメンテナンス作業やパッチの実装がダウンタイムなしで可能となり、結果として運用負荷をより軽減することができます。

### ファイル感覚でサーバーを管理
仮想サーバーは、ソフトウエアとして扱えるサーバーです。CPU、メモリ、ディスクといったサーバーの構成情報やディスク内にインストールされているOSやアプリケーションといったデータもすべてファイルとして管理できます。つまり、一般的なファイルをコピーや移動、削除するのと同じ感覚でサーバーを管理できるのです。

これにより、サーバーのバックアップやサーバーの複製といった作業も手軽に行えるようになります。例えば、サーバーのハードウエアが故障した場合、従来であればハードウエアの修理や交換、あるいはディスクを取り出して予備のハードウエアに移植するといった作業が必要になり、復旧までに時間がかかるのが常でした。しかし、仮想サーバーであれば、サーバーを別のホストマシン上で再起動するだけで復旧が可能です。こうした特長は、「可用性」の向上にも繋がります。

## 仮想化のデメリット
仮想化は、メリットばかりのように思えるかもしれませんがデメリットも存在します。

仮想サーバーは、処理速度や応答速度などのパフォーマンスが物理サーバーを直接利用した場合に比べて、低下してしまうことがあります。こうした仮想サーバーのパフォーマンスの問題は、クラウド環境であれば、オンデマンドにリソースを追加することで対応できます。しかし、オンプレミスに仮想化環境を構築している場合は、ホストマシンのリソースが枯渇してしまうと、それ以上仮想サーバーをスケールアップできなくなってしまいます。そのため、必要な仮想サーバーを十分に動かせるだけのリソースを事前にしっかりと確保する必要があるでしょう。とはいえ、リソースを余分に確保しすぎると、今度は使用されていない余剰リソースが増えてしまい、仮想化による集約・最適化のメリットが薄れてしまいます。余裕の確保と無駄の削減は表裏一体の関係にありますから、どこで折り合いをつけるのかを見極めることも大切です。

仮想化環境は仮想サーバーをはじめ、仮想化ソフトウェアによって作られた様々なコンポーネントによって構成されています。そのため、単独の物理サーバーやその上で動作するOSやアプリケーション単位で行ってきた従来のセキュリティ対策では不十分なことがあります。また、運用には物理環境とは異なる仮想化環境に特有の知識やワークフローが必要になることもあり、「今までの常識が通用しない」「仮想化環境を熟知した運用担当者が必要」といった事態も起こりがちです。

とはいえ、今や仮想化技術はさまざまなサービスの根幹をなす基礎技術です。デメリットがあるから避けるのではなく、仮想化環境に特有の事情を理解した上で、正しく活用していくことが求められています。

[「仮想化」とは？ 仕組みやクラウドとの違いを確認しよう](https://pfs.nifcloud.com/navi/beginner/virtualization.htm)　より引用

https://pfs.nifcloud.com/navi/beginner/virtualization.htm

# ⑥ 最適なクラス設計

## クラス設計とは
今回のテーマは「クラス設計」です。クラス設計とは、設計書などに記載されている要件からクラス候補を抜き出し、クラスの属性と操作を決めて、クラス間の関連性を設計することを指します。

属性とはクラスのインスタンスが持つデータ定義のことです。クラスのフィールド、つまり変数にあたります。操作とはクラスのインスタンスの振る舞い（機能）のことです。クラスのメソッドにあたります。

ちなみに、クラス設計をしなくてもプログラムは動きます。例えばクラスを1つだけ用意し、処理の全てをそのクラスに書いても期待する動きをします。

しかし、それが得策ではないのは、実際の業務では仕様変更や機能追加、障害対応などが頻繁に発生するためです。クラス設計を行わずにクラス1つで全ての処理を行おうとした場合（クラスが1つというのは極端な例ですが）、当然ながらクラスのソースコード量は肥大化し、if文などの条件分岐もコードのあちこちに現れ、非常に可読性が落ち、結果として修正工数が膨らむという事態になります。

クラスを作った担当者がチームにいれば工数が膨らむ程度で済みますが、担当者がチームから離れた場合、引き継いだ社員がソースコードを正しく理解できずに、バグを埋め込んだまま納品してしまう可能性もあります。

したがって、クラス設計をしっかりと行い、クラス間の結合度を下げたり、プログラムの再利用性を高めたりしてプログラムを修正しやすく、またバグの原因も特定しやすくするべきです。

[オブジェクト指向によるクラス設計](https://thinkit.co.jp/article/13112)　より引用

https://thinkit.co.jp/article/13112