over 3 years ago

前言

這是我退伍後的面試經驗,希望能幫到一些人,雖然只是流水文啦XD
我在找工作的時候,實際Rails程度約半年,有過一次hackathon經驗,上過xdite老師的即戰力課程(還幫我雕履歷跟給建議),本身是私立科大資訊工程系畢業。
有linux的架站跟架設server經驗,以及Css html5 略懂。
以下所有面試的公司,職缺皆鎖定「Rails Programer」。

12/18 科威資訊股份有限公司 (找ASP/ ASP.NET Junior Programer)

這是我第一間面試的公司,說來也很妙,當初HR只是看到我的104履歷上寫的資料非常清楚,就主動打來邀約面談,不過這間是專門寫asp.net的公司,跟我要尋找的方向Ruby on Rails完全搭不上邊啊。

在準時的抵達該公司後,先是填寫一份個人資料以及asp與mysql的考卷,HR還特地走過來跟我說,我知道你是學Rails所以asp部分不會寫沒關係,我們僅作參考而已,至於sql東西應該是大同小異,你先寫看看吧!

其實我很菜啊!!我根本寫不出來Orz

但是還是硬著頭皮寫一些奇怪答案XD,接下來的面談之中聊到的,他們認為我在電話裡面反應他們喜歡,也看到履歷上我只打尋找職缺的地方,只寫Rails Dev,說很少看到新鮮人在期待職缺打這麼明確的,所以找我來面談,但是希望我能用學Rails的底子轉換成去學asp.net,HR與一位RD問了我一些自我介紹跟分享上課與實作經驗,大致上就來到尾聲談薪水了,期望薪資的部分我開35K,他們就和我說新鮮人這裡都開28~30,所以我的期望太高,他會開32給我並且還要討論,之後就叫我等消息了。

結果:無聲卡

12/21 銀濎科技

這間應該是我最尷尬也是面試表現最差的一間了XD

首先來到該公司時,助理小姐很客氣的帶我到了會議室,遞上一杯水,跟一份問卷後,叫我填完和他說,裡面的項目....是我最不會回答的啊,例如寫出自己的優缺點,為什麼是優點,為什麼是缺點之類的,寫的頭很痛啊,還是交卷了,接著兩位RD與一位主管進來開始面談,不意外是自我介紹跟實作經驗,但又要求講自己的優缺點,其實到這裡就覺得有點厭煩了,不是才剛寫嗎XD?,所以我就亂講

優點是我喜歡完成每一件事情才肯休息
缺點是這樣搞身體會很差

他們聽完整個臉色大便啊XD,我當下就知道這間會直接無聲卡了

RD_A發問:請敘述封裝、繼承、多型,分別用一句話形容。
我:......我不太清楚(緊張到腦袋空白,我根本沒準備這題XD)

RD_B發問:所以你有去Rails meetup嗎?
我:之前當兵比較少去。

結果該位RD真的在之後的meetup遇到啊啊啊啊小尷尬

最後談到薪資時,我直接問請問貴公司薪資的部分?
主管只留下我跟他,並且看了履歷回了一句
「這個範圍我們可以接受」(因為我寫30~40)
這答案太出乎我意料之外了,完全就是不想談不想談!

結果:無聲卡

12/31 柑仔店異國零食購

在104投履歷的時候,幾天沒回應想說應該石沈大海,沒想到他Email給我希望我先做線上考題,其實內容我不是全部都會寫,竟然是在家寫考題,不免俗一定會請出谷歌大神,但我知道我實力在哪,基於不欺騙的原則下,我在最後備註寫了

「由於我的程度還只能算是個Rails Juinor,所以在不會的題目中,我嘗試用Google去搜尋解答,並附上連結,謝謝貴公司給我線上測驗的機會」

兩天後,就收到面試邀約了。

面試的時候除了自我介紹跟分享實作以外,幾乎有80%的話語權都在對方手上,很積極的跟我介紹公司未來成長的方向跟要做的內容,該公司的一名CTO以及資深RD,分別負責android與ios的app開發,在兩棲Rails自行寫網站,不過他們說忙不過來,所以在成長狀況穩定下要擴編,由於我一直沒有發話機會,都是聆聽居多,其實我很好奇他們是如何鑑別面試者的,又或者因為我學長講完他們已經定案就是要我學長所以只跟我介紹XD

結果:感謝函

01/11 冠通網路科技公司

這間在面試前做了一下該公司的功課,發現是主機商兼接案商,整個服務是一條龍的,抱著好奇的心態去赴約,剛開始親切的RD主管跟我說了一下該公司的服務項目,接著叫我自我介紹,於是聊到我以前寫一些腳本外掛開發經驗跟未來的規劃,讓我介紹了自己最近的三個作品,分別遇到什麼困難,最後就開始講福利了,以為要結束的時候,就請了總經理來與我面談。

總經理大致上就是跟我敲定薪水跟上班時間,他說其他的部分,剛剛面試我的主管他很信任,所以給他決定。
於是口頭offer get!

結果:Get Offer (Email寄錄取通知書)

01/13 sharelike

因緣際會下發現我以前社區小時玩伴朋友在這裡作設計師,稍微打聽了一下就去面試了,與我邀約的CEO沒有出現,兩位RD面試,先是介紹了一下自家產品特色,問我了解的程度,然後展示一些功能給我看,在聊到之後要做的方向,與如何給予用戶更好的服務,電子集點的產品算是滿特別的,來到了你問我答的時間,因為該公司想找後端狂熱份子,但說實在以我當下junior的水準實在戰戰兢兢,題目是問:當在網頁上按下一個按鈕後,送出表單到回傳的之間的過程,在底層是如何運作的?後端API之間是如何運作的?
好吧這兩個問題我答的非常爛....最後還是GG了,看了一下我朋友工作的地方,離開。

結果:感謝函

01/26 益科股份有限公司

(第一次面試)
這是xdite在slack上面通知大家這間有缺Rails的dev,所以我就去投履歷,但是翻了一下紀錄,原來我兩個禮拜前就有投過了XD

這間投了第三次直到我的cover letter內文加上xdite,馬上就面試邀約了XDDD

這間面試是兩位RD leader,首先不免俗的基本技能,自我介紹講完後,就考了我一些基本Ruby model架構,一對多與多對多的關係解釋,這次面試另我印象最深刻的是,我從沒遇過的白板題啊,要畫資料庫並完成要求,雖然最後用的不是最好的方法完成,但是兩位RD還願意跟我討論更好的作法,我就覺得不管有沒有offer,都是獲益良多。

面試的時候還說到了Amazon服務,剛好最近在架server給朋友們玩game,遇到了一些困難也都有解決,面試的時候就更有話題講,真不知道該不該感謝要我架server的好朋友啊XDDD

結果:邀約第二次面試

(第二次面試)
這次是1v1的戰役,面對的是該公司總經理,言談之中得知也是名大學講師,問了我許多除了Rails以外的經驗,大致上就是聊我國小做什麼外掛、國中寫什麼遊戲腳本、等等,還被要求了用兩句話講完某個作品,時間感覺很趕,二十分鐘內就面試結束,等候通知。

結果:Offer Get

01/27 瑞豪資訊有限公司

這間公司也是新創公司,主打旅遊包車服務,服務項目不只有台灣,面試的過程中一樣起手式來個自我介紹之後,就拿出五題的全英文考卷給我寫,考我Rails的code跟一些使用方法,其實還滿難的,有些算是高階寫法,我這個菜鳥完全沒碰過,最後直接繳械投降說我不會,沒想到創辦人還一題一題告訴我解答,真的是錯中學啊,原本想說應該直接結束,因為表現太差了。

結果叫我拿出手機掃QR CODE!!
他說要作一個冰與火之歌人物的心理測驗......我差點呆掉

不免俗的一樣是全英文題目,說實在有的看不太懂就亂按,結果最後結果是一個很奇怪的角色啊啊啊

創辦人還說「竟然是joffrey,所以你是很極端的人嗎?」
嗯對我的確是,就叫我舉了幾個例子給他。

這間公司不多人大概五個左右,杭州還有客服的辦公室,讓人覺得要能待在這實力要很堅強啊
沒意外應該是無聲卡科科

結果:感謝函

也許你需要的職缺搜尋平台

  1. 1111人力銀行
  2. 104人力銀行
  3. 66K工作網
  4. Ruby Job Taiwan
  5. 518人力銀行
  6. Appwork徵才
  7. Inside Job
 
over 3 years ago

想法

假設我們擁有兩個資料表,一個是商品分類資料表,一個則是商品管理資料表,而該如何將這兩個資料表在Rails上建立關聯?

一個分類裡面可以查詢到很多商品 -> 一對多
一個商品只有對應到一個分類 -> 一對一

實際操作

首先,先將兩個資料表建立,我們在終端機中輸入以下

rails g model category name:string position:integer

這個指令會建立catagory的model,並且有一個name的欄位型態為字串和position欄位型態為整數。

接下來我們在建立第二個資料表,輸入以下

rails g model item description:integer price:integer

這個指令會建立item的model,並且有一個description的欄位型態為整數和price欄位型態為整數。

在實作的時候輸入以上兩行指令只會建立model,並聰明的在db裡面建立兩個migrate檔案,但真正的資料庫表還沒有建立。

所以我們還要輸入 rake db:migrate 讓資料庫表建立起來。

這樣Rails會將migrate的檔案執行,建立出兩個我們剛才輸入的資料庫表

資料庫表兩個是建立起來了,但還沒將他們兩個之間的關聯做出來,所以我們繼續看下去

將原先的

model/category.rb
class Category < ActiveRecord::Base
end

改為

model/category.rb
class Category < ActiveRecord::Base
has_many :items
end

因為一個category可以有很多的items,也就是我們在一開始提到的想法,分類對應多項商品。

再來將

model/item.rb
class Item < ActiveRecord::Base
end

改為

model/item.rb
class Item < ActiveRecord::Base
belongs_to :category
end

因為item對應到一個category,一個商品只會被分到一種分類。

但是在兩個實體的資料表上還沒有建立關聯,因為item裡面並沒有category_id的欄位

所以我們回到終端機輸入

rails g migration add_category_id_to_items

這裡的migration雖沒有硬性規定命名方式,但是為了之後的維護跟可讀性,慣性必須打上淺顯易懂且具有意義的snake_name命名方式

接著到migrate檔案裡面,應該看到我們剛剛建立的檔案,名稱前面會是一些數字,我們需要修改它。

原先

db/migrate/一堆數字add_category_id_to_items.rb
class AddCategoryIdToItems < ActiveRecord::Migration
    def change
    end
end

改為

db/migrate/一堆數字add_category_id_to_items.rb
class AddCategoryIdToItems < ActiveRecord::Migration
    def change
    add_colums :items, :category_id, :integer
    end
end

這樣就建立起兩個資料表彼此的關聯了。
建立完成一定要讓他跑db:migrtae跟server restart,否則會吃不到更新的檔案喔!

簡單的關聯先筆記到這邊
之後我們在做多型關聯的筆記吧XD

 
over 3 years ago

這兩天挑戰了12 in 12 Challenge的作法,目前第一關有學到一個投票的gem,筆記下來怕以後忘記。

不外乎這個gem的名稱正是acts_as_votable

以下是實作方法

首先先建立變數,這裡照著作者給的方法直接輸入,db資料庫會幫你把內容都建好,算是相當方便,連vote的變數都不用自己設。

rails generate acts_as_votable:migration

之後一樣rake db:migrate

我們可以到db來看是否已經建立好?

接下來我們需要在控制該頁面的model加入作者設計的語句acts_as_votable
範例:

app/model/link.rb
class Link < ActiveRecord::Base
+  acts_as_votable
end

我們在到與該model相對應的conrtoller實作方法

app/controller/links_controller.rb
  def upvote
    @link = Link.find(params[:id])
    @link.upvote_by current_user
    redirect_to :back
  end

  def downvote
    @link = Link.find(params[:id])
    @link.downvote_by current_user
    redirect_to :back
  end

upvote則是票數+1,當票數+1時紀錄當時的登入者id作為紀錄,downvote則相反為-1票。

我們在view的頁面將他實作

本機端測試成功

一個帳號只能對一個link做出like或是dislike其中一項選擇。

以上是比較簡易的作法,詳細內容請閱讀該作者的文件!

 
over 3 years ago

generate和destroy是相反

rails generate controller FooBars baz quux
rails destroy controller FooBars baz quux
rails generate model Foo bar:string baz:integer
rails destroy model Foo

migrate和rollback相反

rake db:migrate
rake db:rollback

回到初始狀態

rake db:migrate VERSION=0
 
over 3 years ago

今天在看12to12 challenge時,看到作者輕鬆用了一小段語法就可以叫出一整串語法
上網查了一下發現是 Sublime Text 2的外掛插件

Emmet

安裝方式 clone或是download下來之後放進Sublime Text 2的Package資料夾內

使用範例如下:
輸入 ul>li*3

按下tab鍵後自動生成

 
over 3 years ago

這是一個新增Facebook讚與留言的功能
我們將他實作在

app/helpers/application_helper.rb
def social_plugin(plugin_name, options)
  width  = options.delete(:width)
  height = options.delete(:height)
  style  = "border:none; overflow:hidden; width:#{width}px; height:#{height}px;"
  src    = "http://www.facebook.com/plugins/#{plugin_name}.php?#{options.to_param}"

  content_tag(:iframe, "", src: src, scrolling: "no", frameborder: "0", style: style, 
              allowtransparency: "true")
end

def fb_like(like_url, custom_options={})
  options = {
    href: like_url,
    send: false,
    layout: "button_count",
    show_faces: false,
    width: 90
  }

  options.merge! custom_options

  social_plugin("like", options)
end

def fb_comments(url, custom_options={})
  options = {
    href: url,
    num_posts: 10
  }

  options.merge! custom_options

  social_plugin("comments", options)
end

然後把這二個功能放入到app/views/products/show.html.erb

before

after

現在我們想把這個 helper 拆出來,包到 Gem 裡面,讓我以後不用再做這些設定,直接在 view 去用它就好

bundle fb_like_comment

找出這個gem的路徑

安裝在你的 Rails 專案裡面, 設定 path: xxx <== 只抓取你本機端的資料夾

在跑bundel install之前
必須先把你創建的gem裡面的xxx.gemspec檔案作一些小修改
不然直接跑bundle install會跳錯誤

錯誤如下

這裡的gem以fb_like_comment作示範

fb_like_comment.gemspec
...
spec.summary       = "修改為任意內容"
spec.description   = "修改為任意內容"
...

接下來跑bundle install可以看到已經將我們自己製作的gem加入了

設定 dependency 'railries'

gem的根目錄裡面的xxx.gemspec必須加入

spec.add_dependency "railties"

fb_like_comment.gemspec
...
+  spec.add_development_dependency "railties"
...

Gem 的資料夾跑 bundle install, 把這個 gem 讀進去

設定 railties.rb

建一個新檔案: lib/fb_like_comment/railtie.rb

lib/fb_like_comment/railtie.rb
module SampleGemHelper
  class Railtie < Rails::Railtie
    initializer "SampleGemHelper.view_helpers" do
      ActionView::Base.send :include, FbLikeComment
    end
  end
end

把一開始在 Rails 新做的功能丟進去

lib/fb_like_comment/fb_like_comment.rb
require "fb_like_comment/version"
require "fb_like_comment/railtie" if defined?(Rails)

module FbLikeComment
def social_plugin(plugin_name, options)
    width  = options.delete(:width)
    height = options.delete(:height)
    style  = "border:none; overflow:hidden; width:#{width}px; height:#{height}px;"
    src    = "http://www.facebook.com/plugins/#{plugin_name}.php?#{options.to_param}"

    content_tag(:iframe, "", src: src, scrolling: "no", frameborder: "0", style: style,
                allowtransparency: "true")
  end

  def fb_like(like_url, custom_options={})
    options = {
      href: like_url,
      send: false,
      layout: "button_count",
      show_faces: false,
      width: 90
    }

    options.merge! custom_options

    social_plugin("like", options)
  end

  def fb_comments(url, custom_options={})
    options = {
      href: url,
      num_posts: 10
    }

    options.merge! custom_options

    social_plugin("comments", options)
  end
end

把原本寫在 rails 的 application_helper 移除掉, 並把 rails 重新跑 bundle install + rails s

若設定有錯誤,就會在 bundle install 這邊出現錯誤

這樣基本的 Gem 就完成了

把寫好的gem push到github上面就可以給別人使用囉

以後要給別人用,直接請它安裝

gem "fb_like_comment", github: "niclin/fb_like_comment"

就可以直接使用了!!

 
over 3 years ago

為何要使用Service Object:

顧名思義,Service Object是因為有某些類似的特定功能,像是一個『service』,跟資料庫中的model並無直接關係,因此拉出來獨立成為一個class,在邏輯上會更容易管理。不過在文章中有定義了幾個需要使用service object的情況:

  • method邏輯極其複雜的時候
  • 跨Model使用,無法特別歸類於特定Model
  • 與外部服務有較多關連
  • 並非重要功能
  • 同一種method有許多類似的使用方法

Service Object 使用時機

以登入機制為範例,將登入的authenticate功能另外放在UserAuthenticator這個class當中,非常簡單的一個介紹。但通常在實作中會遇到的情況都複雜許多:

實作規格:

  1. Group、Post、Comment 三個model
  2. 要能將Post輸出成四種格式:html、json、xlsx、pdf
  3. 在每種格式中要能列出相對應Group和Comment,並依據數量畫出圖

聽起來就需要非常多分門別類的功能,但應該不難看出,這些功能幾乎都是使用外部服務,包括gem 'jbuilder' (https://github.com/rails/jbuildergem)、 'axlsx' (https://github.com%20/randym/axlsxgem)、 'prawn' (https://github.com/prawnpdf/prawngem)、 'gruff' (https://github.com/topfunky/gruff) 四個都是不需要自己土法煉鋼的功能,而是直接使用gem安裝以後,就可以將格式輸出了。

因此,這些內容都是專門處理『輸出』(render)的部份,可以將他們收攏為一個service object,管理比較方便。

 
over 3 years ago

Helper:

使用 Helper 的情境多半是:

  • 產生的 HTML code 需要與原始程式碼進行一些邏輯混合,但不希望 View 裡面搞得太髒。
  • 需要與預設的 Rails 內建的一些方便 Helper 交叉使用。

使用 Helper 封裝程式碼可以帶給專案以下一些優點:

  • Don't repeat yourself(DRY)程式碼不重複
  • Good Encapsulation好的封裝性
  • 提供 view 模板良好的組織
  • 易於修改程式碼

partial:

Partial 簡單說就是程式碼中的一小段,通常使用在 HTML 中讓 View的Code 可以更乾淨,將重複使用到的區塊切成獨立的 Partial,比方說頁首頁尾、表單、社群插件等等,讓任何一個頁面都可以讀取這段Partial而不用重複寫一次一模一樣的Code。

使用 的情境是:

  • long template | 如果當檔 HTML 超過兩頁
  • highly duplicated | HTML 內容高度重複
  • independent blocks | 可獨立作為功能區塊

什麼時機使用:

partial 負責處理大片的 HTML code,或是之後要利用 ajax render 出來的片段。

helper 則負責處理跟邏輯判斷有關的東西。

 
over 3 years ago

delayed_job (https://github.com/collectiveidea/delayed_job) 使用關聯式資料庫,非常方便安裝使用。

sidekiq (http://sidekiq.org/) 使用高效能的Redis (http://redis.io/:) key-value store來儲存要執行的任務,並且善用多執行序來增加效能,號稱可以以一個process抵上20個delayed_job的processes。

 
over 3 years ago

development environment 開發模式,用在你的開發的時候

使用 Rails 開發可以快速的原因之一,就是當你修改一個小東西,只要重新整理瀏覽器就可以馬上看到修改後的結果。這個秘訣就在於 cache_classes = false 會讓每一次的 HTTP 請求都重新載入類別檔案。更仔細的說,當這個值是 false 的時候,Rails 會改用 Ruby 的 load 方法,每次執行都會重新載入一次。
Rails只有在連線是來自本地端的時候,才會將發生錯誤時的Call stack trace資訊給瀏覽器顯示。這個設定將所有連線都當做本地端連線,好讓開發模式時所有人連線都可以看到錯誤訊息。

test environment 測試模式,用在自動測試時

cache_classes = true 表示在 production 中,類別檔案載入進記憶體中就快取起來了,大大獲得效能。不像在 development 環境中每一次 HTTP 請求就會重新載入一次。
不同於 development,如果在 production 環境出現例外錯誤,不會顯示程式 call stack 訊息,而是回傳 public/500.html 頁面。

production environment 正式上線模式,用在實際的上線運作環境

不同於 development 或 production 碰到例外會捕捉例外後,給瀏覽器顯示出 call stack trace 或 public/500.html 畫面,在 test 模式就不處理,讓例外直接爆出。