【解答編】入門エンジニア技能試験(Ruby/HTML/CSS/Rails)


> 入門エンジニアのための技能試験解答編です。
> 問題編は[こちらのエントリー](http://qiita.com/Yama-to/items/fc0de97a4914c391ed41)で公開しています。

## 配点構成

1: Rubyアルゴリズム問題（**40点**）

- 共通問題 :20点
- 選択問題 :20点

2: HTML/CSS問題（**20点**）

- HTML問題 :各2点 × 6問 / 12点
- CSS問題　:各2点 × 4問 / 8点

3: Rails論述問題（**40点**）

- 共通問題 :各10点 × 2問 / 20点
- 選択問題 :各10点 × 2問 / 20点

計: **100点満点**

## 1: Rubyアルゴリズム問題
- 共通問題
 1. メンバー年齢管理アプリ作成

**　■ 模範解答**

```ruby:メンバー年齢管理アプリ作成
def post_member(a_members)
  member = {}
  puts "メンバーの名前を入力してください："
  member[:name] = gets.chomp
  puts "年齢を入力してください："
  member[:year] = gets.to_i
  return a_members << member
end

def index_members(a_members)
  num = 1
  a_members.each do |member|
    puts "[#{num}] : #{member[:name]}の情報"
    num += 1
  end
  puts "年齢を見たいメンバーの番号を入力してください："
  input = gets.to_i
  puts "名前 : #{a_members[input - 1][:name]}\n年齢 : #{a_members[input - 1][:year]}"
end

def sort_members(a_members)
  puts "メンバーの年齢の範囲を設定してください。\n何歳以上のメンバーを見ますか："
  s_input = gets.to_i
  puts "何歳以下のメンバーを見ますか："
  f_input = gets.to_i
  names = []
  a_members.each do |member|
    names << member if member[:year] >= s_input && member[:year] <= f_input
  end
  names = names.sort {|a,b| b[:year] <=> a[:year]}
  if names.count == 0
    puts "該当するデータは存在しません。"
  else
    puts "該当するメンバーは以下のとおりです。"
    names.each do |name|
      puts "名前 : #{name[:name]}\n年齢 : #{name[:year]}\n----------------"
    end
  end
end

def end_program
  puts "ご利用ありがとうございました。"
  exit
end

def execption
  puts "無効な値です。もう一度入力してください。"
end

members = []

while true do
  puts "メンバー数：#{members.count} 人"
  puts "[0]メンバーを登録する"
  puts "[1]メンバーの一覧を見る"
  puts "[2]メンバーを年齢別に見る"
  puts "[3]アプリを終了する"
  input = gets.to_i

  if input == 0 then
    members = post_member(members)
  elsif input == 1 then
    index_members(members)
  elsif input == 2 then
    sort_members(members)
  elsif input == 3 then
    end_program
  else
    exception
  end
end
```
- 選択問題
 1.  うるう年問題
 2.  耳の遠いおばあちゃん問題

**　■ 模範解答**

```ruby:うるう年問題
leap_years = []
line = "----------------------"
puts "plz input start year"
s_year = gets.to_i
puts "plz input finish year"
f_year = gets.to_i
puts line
while s_year <= f_year
  if s_year % 100 == 0
    leap_years << s_year if s_year % 400 == 0
  elsif s_year %4 == 0
    leap_years << s_year
  end
  s_year += 1
end
puts "#{leap_years.join(',')}\n#{line}\nthere're #{leap_years.count} leap years.\n#{line}"
```

```ruby:耳の遠いおばあちゃん問題
bye_count = 0
while true do
  puts "SAY SOMETHING:"
  input = gets.chomp
  if input == "BYE"
    bye_count += 1
  else
    bye_count = 0
  end
  if bye_count >= 3
    puts "BYE-BYE, SUNNY!"
    break
  end
  if input != input.upcase
    puts "WHAT!?"
  else
    puts "NO! I'M #{50 + rand(31)} YEAR-OLD!"
  end
end
```

## 2: HTML/CSS問題
- HTML問題
    1. imgタグに付与する `alt属性` はどのような役割を持つか.
    2. `<%= link_to "一覧画面へ", "/tweets" %>` という記述を `index.html.erb` に記述した場合どのようなHTMLに変換されるか.
    3. フォームを生成するタグに指定する `type属性`・`name属性`・`placeholder属性`の役割を具体例と共に示せ.
    4. インライン要素とブロック要素とは何か.
    5. `<br />`のようにタグ内部にスラッシュを使用する場合の目的は何か.
    6. `HTMLで水平線は「 <hr> 」のように記述できます`という説明文をHTMLファイルにそのままコピペしても勝手に文章中に水平線が挿入されてしまうがその解決策を示せ.

**　■ 模範解答**

```html:HTML問題
1. 画像の読み込みに問題があり表示されない際の代替テキストとなる。またブラウザの音声読み上げ機能を使用した際にもこのalt属性に設定した文章が読まれるため、画像の内容を正確に反映した内容でなければならない。

2. <a href="/tweets">一覧画面へ</a>

3. type属性はフォームの形式を指定する。例えば「type="checkbox"」と指定するとチェックボックスが生成される。name属性は入力する情報に識別のための名前を付与する。例えば「name="title"」と指定するとその情報は「title」というキーとともにサーバーに送られる。placeholder属性は入力欄に初期表示する値を指定する。例えば「placeholder="感想を入力してください"」と指定するとその入力欄には何も入力していない状態で「感想を入力してください」と表示される。

4. ブロックレベル要素は、見出し・段落・表などウェブサイトの基本構成を担う要素で多くの場合前後に改行の入るひとつのかたまりとして扱われる。インライン要素は、文字強勢・リンク・画像参照など主にブロック要素の内部を構成し多くの場合前後に改行が入らず文章の一部として扱われる。

5. 閉じタグが存在しないmetaタグなどの末尾に付与し、閉じタグが必須なタグとを区別することができる。HTML4では非推奨だったもののHTML5からは文法的正規表現方法となった。

6. 文字実体参照または数値文字参照を利用し「&lt;hr&gt;」または「&#60;hr&#62;」と記述する。
```

- CSS問題
    1. `colorプロパティ` の値を `#000` と設定したがこれは何色か.
    2. セレクタに `a:hover` と指定したがこれはどのような指定をしているか.
    3. ヘッダーを画面上部に固定したい.どのようなプロパティと値を指定すればよいか.
    4. `li要素` にデフォルトで付与される点を消して表示したい場合どのようなプロパティと値を設定すべきか.

**　■ 模範解答**

```css:CSS問題
1. 黒

2. a要素にマウスオーバーした際の挙動を指定している。「:hover」は擬似クラスと呼ばれウェブサイト閲覧者が指定のアクションを起こした際に適用される。他にも「:active」という、指定の要素にマウスオーバーしクリックし続けている間の動作を指定するのに用いられる擬似クラスが存在する。

3. header { position: fixed; }

4. li { list-style: none; }
```

## 3: Rails論述問題
- 共通問題（2問必答）
    1. `MVC` とは何か.具体的に説明せよ.
    2. Modelが `ActiveRecord::Base` を継承していることで何を実現しているのか.具体例を用い説明せよ.

**　■ 模範解答**

```text:共通問題
1. Model・View・Controllerを使用して処理を行うシステムのこと。Modelはデータベースとのやり取りを担う要素にあたり、Viewはアプリケーションの見た目を制御し、Controllerはユーザーからのリクエストを受けモデルに適切な動作を要求しどのビューを表示するかを決定する。

2. ActiveRecord::Baseを継承することでallメソッドやfindメソッド等の、データベースへのアクセスを行うメソッドが使用可能になる。
```

- 選択問題（2問選択）
    1. `callback` とは何か.具体例を用いて説明せよ.
    2. `has_many throughオプション` と `polymorphic association` の違いと具体的な使用例を示せ.
    3. ルーティングにおける `resources` の7つのアクションについて全て挙げそれぞれ用途を示せ.
    4. メソッドに `method(*arg)` のようにアスタリスク付きの引数を渡すとどのようなことが実現できるか.
    5. Modelでアソシエーションに対し `orderオプション` を使用する際には `lambda` を使用する.それはなぜか.

**　■ 模範解答**

```text:選択問題
1. 作成/保存/更新/削除/検証/等、特定のイベント発生時に呼び出されるメソッドのこと。例えば「after_update :update_content」とUserモデルに指定した場合、Userクラスのインスタンスに更新がかかったタイミングで自動的にupdate_contentメソッドが発火する。

2. has_many throughオプションは中間テーブルを間に挟むことで実現された多対多の関係を表し、polymorphic associationは複数の親テーブルに共通する要素を抽象化し子テーブルにまとめている関係を表す。例えばInstagramの写真とタグの関係はhas_many throughオプションで表現できる。ひとつの写真は複数のタグと関連付けられ、同様にひとつのタグは複数の写真に関連付けられているという多対多の構造を実現するためには、中間テーブルで写真とタグの組み合わせを全て記録してやることが必要である。スーパーにおける各コーナーの商品リストと全体購買履歴の関係はpolymorphic associationで表すことができる。各コーナーの商品リストは個別で管理していたいがどの商品がいつ買われたかという情報は全体一括で管理したいというニーズがあった際に、購買履歴が記録されるひとつのテーブルが複数の商品リストのテーブルに紐付いているという状態をpolymorphic associationで定義すれば実現できる。

3. indexアクションは一覧画面を表示する用途。showは個々の詳細画面を表示する用途。newアクションは新たな要素を生成・追加するための画面を表示する用途。createアクションは生成された新たな要素を保存する用途。editアクションは要素を編集するための画面を生成する用途。updateアクションは保存されている要素の情報を編集した内容で更新する用途。destroyアクションは任意の要素を削除する処理を実行するための用途。

4. 複数の値を配列の形にして渡すことができる。例えばmethod(num1,*num2)というメソッドをmethod(1,2,3,4,5)という形で呼び出した場合、呼び出されたメソッド側には引数が2つしか設定されていないが渡した引数が自動的に配列に入って実行されmethod(1,[2,3,4,5])と変換されるため、エラーが発生しない。

5. メソッドを引数として別のメソッドに渡す際にはprocとしてオブジェクト化しなければいけないため。アソシエーションの定義に使用しているhas_manyはActiveRecord::Relationに定義されているメソッドであり、通常は「has_many(:users)」という形でひとつの引数を渡している。メソッドそのものを他のメソッドの引数とする際にはメソッドをオブジェクト化、つまりprocの形にしなければ渡せないため、「->{ order('updated_at DESC') }」とlambdaを用いてorderメソッドをprocにしている。
```

期待値: **70点** / 100点満点

---

解答はあくまで一例にすぎません。
もっと良いコードがあるよという場合はぜひ採用してください。

自分の周りでは学習開始一ヶ月半の人たち全員に受験してもらい、
一定のレベルを保てた人のみ継続してコミットしていく仕組みです。
この試験が皆さんのモチベーションに何かしらの形で寄与できたら幸いです。

それでは今後も引き続き頑張ってください。