技術面接 質疑応答まとめ[未経験転職]

技術面接があったため，振り返りとして質疑応答をまとめました．
解答について間違いがあればご指摘お願いします．

## この記事を読んで分かること

オブジェクト指向やHTTPなどのwebの基礎知識に関する知識

## 前提

筆者は未経験でバックエンドエンジニアを志望しています．そのため質問内容はそれに関連したものになります．

# 質疑応答

## 質問1：RESTについて教えてください

webのアーキテクチャスタイルの一つ  
RESTfulなWebサービスの性質として，以下の4つがあげられる

アドレス可能性：URIによりリソースを一意に指し示す性質  
接続性：リソースをリンクで接続することでアプリケーションを形成する性質  
統一インターフェース：命令体系が(HTTPメソッドで)統一されている
ステートレス性：サーバーがクライアントのアプリケーションの状態を保存しない性質

## 質問2：HTTPについて教えてください

WebブラウザがWebサーバと通信する際に主として使用する通信プロトコル
webコンテンツの送受信に使われる

## 質問3：HTTPステータスのついて教えてください

HTTPレスポンスのステータス（状態）を表現する3桁の数字からなるコード

## 質問4：HTTPステータスコードの違い(2XX,3XX,4XX,5XX)ついて教えてください

2XX：成功  
3XX：リダイレクト  
4XX：クライアントエラー  
クライアントのリクエストが原因のエラー（入力ミス，未認証等）  
5XX：サーバーエラー  
サーバ側が原因のエラー

## 質問5：HTTPメソッドについて教えてください

クライアントがサーバーリクエストを投げるとき「サーバーにしてほしい操作」を伝えるための情報
全部で8つあるが，「CRUD(Create,Read,Update,Delete)」という性質を持つ以下の4つが主に使われる

GET  
リソースの取得

POST  
子リソースの作成，リソースの追加，他のメソッドで対応できない処理（GETリクエストが非常に長くなる場合など）

PUT  
リソースの更新，作成

DELETE  
リソースの削除

POSTとPUTの違い
どちらもリソースの作成が可能で，使い分けとして正解は存在しない．しかし一般的な設計上の指針では以下のようになっている  
リソース作成の際，POSTではリソースのURIはサーバーが，PUTではクライアントが決める  
そのため，Twitterのように投稿のURIをサーバ側で自動決定するサービスはPOST，wikiのようにクライアントが決めたタイトルがそのままURIになるサービスはPUTを使うのに適している．特別な場合以外はPOSTが望ましい

## 質問6：身の回りの素数を使ったアルゴリズムについて教えてください

通信の暗号化に使われているRSA暗号など

## 質問7：RSA暗号について教えてください

オーダーが大きい合成数の素因数分解が困難なことを安全性の根拠にした暗号  
キーとなる素数などの値を知っていれば暗号化，復号化は容易なので広く使われている  
方式は以下のようになっている

大きな2つの素数をp,qとし，その積をnとする
1 (p−1)(q−1)と互いに素な整数aを決める
2 ab≡1(mod(p−1)(q−1))なるbを決める
{p,q}は秘密鍵，{n,a}は公開鍵となる

```math
​暗号化： c = m^{k_1}\bmod{n} \\
復号化： m = c^{k_2}\bmod{n}
```
（mは送る文書，Cは送られてきた文書)


## 質問8：オブジェクト指向について教えてください

プログラムの設計の考え方の一つ．互いに密接に関連するデータと処理をオブジェクトと呼ばれる単位で定する．様々なオブジェクトを組み合わせてシステム全体を構築していく手法．

## 質問9：クラス，モジュールについて教えてください

オブジェクト指向の概念ではクラス≒モジュールとなっているが，Railsではその機能はかなり異なる．
クラスはオブジェクトの設計図となるもので，そのオブジェクト特徴づけるパラメータやメソッドが記述されている
モジュールはクラスと違いインスタンス生成能力が無く，機能を付加させることが主な役割．主にmix-inによるクラスの機能拡張や名前空間の作成などに使用される．

## 質問11：継承について教えてください

特定のクラスの機能を引き継いで使うこと  
継承を利用することでコードの再利用性が高まり，汎用的・抽象的な機能の実装を親クラスに任せ，子クラスにはその機能を利用した個別具体的なコードを書くだけでよくなる

例 :
勇者や魔法使いはどちらもキャラクターであり，HP，攻撃力などのパラメータ（プロパティ）や攻撃，防御などの行動（メソッド）が共通している．この場合，`Charactor`に共通部を記述し，`Hero`や`wizard`がこれを継承することで，コードの重複を抑えることができる


## 質問12：セキュリティ攻撃や対策について教えてください

代表的な攻撃とその対策として以下のようなものがあげられる

### CSRF  
ログイン機能があるサービスで，ログインした利用者からのリクエストに，利用者が意図したリクエストかどうかを識別する仕組みを持たないと外部サイトを経由した悪意のあるリクエストを受け入れてしまう場合がある．これにより予期しない処理が実行されてしまう

例：金銭処理が発生するサイトの予期せぬ処理

対策：
- 処理実行直前のページで再度パスワードの入力を求める
- 重要な操作を行った際に，メールアドレスに自動送信する

### SQLインジェクション  
概要  
データベースと連携したウェブアプリの多くは，利用者からの入力情報を基にSQL文を組み立てている．ここで，SQL文の組み立て方法に問題がある場合，攻撃によってデータベースの不正利用をまねく可能性がある．

例
- データベースに蓄積された非公開情報の閲覧  
個人情報の漏えい 等

- データベースに蓄積された情報の改ざん，消去  
ウェブページの改ざん，パスワード変更，システム停止 等

- 認証回避による不正ログイン  
ログインした利用者に許可されている全ての操作を不正に行われる

対策：
SQL文の組み立ては全てプレースホルダで実装する  
SQL文の雛形の中に変数の場所を示す記号（プレースホルダ）を置いて，後に，そこに実際の値を機械的な処理で割り当てる

## 質問13：ブラウザでページが表示されるまでに何が起きているか教えてください

URLを分解し，プロトコル，ドメイン名，パス名を調べる  
ドメインからDNSにWebサーバーのIPアドレスを問合せる  
DNSからWebサーバーのIPアドレスを受け取り，送信する
HTTPサーバーでリクエストを処理し，レスポンスを返す  
レスポンスを受け取り，レンダリングを行う

## 質問14：対象のIPアドレスを格納したDNSをどのように見つけているか教えてください

ドメイン名を使用することで特定が可能  
ドメイン名は右から順にラベルを追うと対象サーバーにたどり着ける，ツリー上の階層構造（ドメインツリー）になっている

## 質問15：認証と認可について教えてください

認証
対象の特定を行う  
例：特定アカウントが自分のものであると証明するためにパスワード認証を行う

認可  
リソースに対する権限の確認を行う  
例：バスに乗る権利があるか確認するために乗車券の提示を求める  

認証は対象の特定のみを行い，権限の有無は関係しない
認可は権限の有無のみを行い，対象が誰かは関係しない

## 質問16：秘密鍵をネット上で渡す方法を教えてください

 共通鍵を公開鍵暗号方式で渡すハイブリッド方式で渡せる

## 質問17：ポインタについて教えてください

オブジェクトは値が保存される際，メモリ上のアドレスに配置されることでpcに記憶される．このメモリ上のアドレスの位置を指し，アドレス値などを格納した変数のことをポインタという

ポインタを使う理由，メリット
- オブジェクトに変更を加える際（関数が引数を変更するなど）は，ポインタ渡しが必須
- 操作対象の位置を表すメモリアドレス値を直接参照したり書き換えができるため，低レベルの操作や制御が可能．
- ポインタはメモリアドレスなので比較的軽くいため(64bit8byte)，大きな構造体はポインタで渡すことが推奨されている．値渡しの場合，毎回のコピーでリソース（メモリや処理速度）が消費されてしまう


ポインタを使うデメリット  
- 不正な値の入力などで実行時にメモリ上の予期せぬ位置のデータやコードを読み書きしてしまい，深刻なバグが発生する可能性がある

## 質問18：値渡し，参照渡しについて教えてください

「値渡し (call by value)」  
引数の値をコピーする渡し方．メソッドの結果を引数に反映させたくない場合に使用

「参照渡し (call by reference)」  
引数を共有する渡し方．メソッドの結果を引数に反映させたい場合に使用．変数のメモリ番地を渡す．  

```値渡し.rb
def foo(a, b)     # a, b を「仮引数」という
  a += 1
  b += 2          # a と b を変更する
end
x = 10
y = 20
foo(x, y)         # x, y を「実引数」という
puts x            #=> 10  # 変更されてない
puts y            #=> 20  # 変更されてない
```

```参照渡し.rb
def foo(a, b)     # a, b を「仮引数」という
  a += 1
  b += 2          # a と b を変更する
end

x = 10
y = 20
foo(x, y)         # x, y を「実引数」という
puts x            #=> 11   # 変更されている!
puts y            #=> 22   # 変更されている!
```

# 参考：

Webを支える技術 ―― HTTP，URI，HTML，そしてREST  
図解入門TCP/IP　仕組み・動作が見てわかる  
[RSA暗号 wiki](https://ja.wikipedia.org/wiki/RSA%E6%9A%97%E5%8F%B7)  
[MDN](https://developer.mozilla.org/ja/)  
[RailsGuide](https://railsguides.jp/)  
[情報処理推進機構](https://www.ipa.go.jp/security/vuln/index.html)  
[るびま](https://magazine.rubyist.net/articles/0032/0032-CallByValueAndCallByReference.html)