Archive for the 'Engineering' category

PHP Composer parallel install,讓你每月多省六小時

四月 14 2016 Published by under Engineering

logo-composer-transparent2

 

相信有在用 PHP 開發的大家多少都有用到 composer 來協助管理 dependency 的經驗,

composer 可以幫助我們用很簡單的方式管理與使用相關的 packages;

如果沒有聽過或用過的讓我簡單介紹一下:

 

從前我們在寫 PHP 的時候,如果要使用第三方的 library or SDK,

常常會看到在各個檔案開頭的時候有以下的程式碼:

 

require ‘library/foo’;

require ‘library/bar’;

require ‘library/baz’;

 

這樣雖然可以很方便的在各檔案中直接呼叫相關的 library,

不過當專案慢慢越來越大時,

常常會遇到某個檔案需要但卻忘了呼叫;

或是其實某個檔案根本不需要這些 library,

但卻為了方便在某個 config 檔案中把所有 library 一次全部載入,

造成 include 很多不必要的 libary。

 

Composer 的出現可以讓我們用比較"優雅"的方式在 project 中 include 與呼叫各種 3rd party packages,

並且可以輕易的幫我們解決 dependency 的問題。

詳細的使用與安裝方法可以參考官方的說明文件

這邊就不再多詳細說明。

 

等 build 比寫 code 還花時間

當使用 composer 一陣子後,

各位碼農一定有被它"優雅"的速度深深 抱怨 吸引,

常常執行 composer install 卻卡了半天,

或是遇到在CI (Continuous integration) 的環境 build 或跑 unit test時卡住。

 

如何加速

之前有看過國外的大大使用 HHVM 去加速 composer,

不過我個人在 local 測試是沒有太大的差異。

 

直到發現 prestissimo 這個 composer 的 plugin,

安裝方式也非常簡單,

只要透過

 

composer global require hirak/prestissimo

 

就可以啟用享受 parallel install 的效果。

 

根據作者實際安裝 laravel 的測試來看,

直接 composer install 的速度可以從本來 288秒 提升到 26秒 (足足省了快五分鐘)。

 

實際運用

Screen Shot 2016-04-12 at 11.27.10 PM

我們也實際運用在 EZTABLE 的 project 中,

原本透過 travis-ci 的環境執行 composer install 執行完成的時間為 106秒,

透過 parallel install 後只需要25秒,跑一次就省下81秒。

簡單計算一下,

如果每天需要透過CI跑10次,

一個月就可以多省下約 (81 * 10 * 30 / 60 = 405分鐘)

如果大家有什麼其他好方法,

也歡迎大家一起討論唷~

 

P.S. 在travis-ci 的環境中,

由於composer 是預先包好在它們的image中的,

所以記得要先透過 composer self-update 更新才能使用 prestissimo 這個 plugin 唷。

 

歡迎訂閱EZTABLE IDEAS天天都有新玩意

Mark

No responses yet

【Workshop】Client side caching in android

八月 26 2014 Published by under Engineering

【Workshop@140822】
Topic: Client side caching in android
Speaker: Blaise Tuffet

 

 

Today,  we are honored to invite Blaise for the talk focuses on client side caching on our android app.

 

2-IMG_3372

 

 

slide1

 

#issue

We face the issue that we have numerous services we need to query in order to display 2 main pages:
– Restaurant page : 5 api
– Restaurant search : 2 very slow apis

This is due to legacy apis that are not designed for mobile device and didn’t stand evolution of the business.
In order to mitigate the issue, we decided that it was important to turn to cache mechanism to make relevant data available as fast as possible.

 

#solutions

Basic available cache mechanism we survey are as follow :
– no cache/ service level cache (memcache) : speed up the service, but doesn’t resolve latency issue (us->asia roundtrip).
– CDN cache : accelerate significantly abroad services, mostly useful for public/static data
– local cache : same as CDN, can be covered by local db or libraries like volley. First time access is still slow, need to prefetch and refresh in the background.
– db sync: trivial for read only data. more complex for concurrent write situation, either too expensive or conflicts have to be resolved. We want to avoid syncing big db

 

#action

We focus on improving core experience : restaurant info and restaurant search.

 

 

6-IMG_3383_01

 

 

## Restaurant Info

This api requires more data, we don’t want to store it all on the client.
We decided to improve on roundtrips by grouping required data in a single call via service proxy (parse.com) and to enable close cdn to make delivery from us faster. In addition we use simple local cache to enable offline browsing for pre-cached items.
We want to preload some items like favorites, or restaurant with a reservations to avoid having user.

 

## Restaurant Search

Search api is provided by Solr system with aggregation of multiple data on the server side. Those extra data includes availability information which is not easily cacheable and slow to retrieve and slow down the api drastically.
Ideally we would like to make search instant, while it was taking over 1-5 second per page of 10.
To do so, we decided to extract key data from restaurant info, the one we intent to display:

– title,
– thumbnail

and the one we want to index for search (and maybe display) :

– price
– discount,
– food type,
– …

By syncing this index to the device daily, we can have up to date and instant search experience.
We decided not to use Parse.com local cache capability even though we use parse to aggregate our data. We found that parse local cache didn’t meet our expectation in terms of pinning speed and query time.

One critical issue yet to resolve is the restaurant availability for booking. Availability changes rapidly, especially for next few days and for popular restaurants. Moreover it is expensive to compute in our current backend system.
We are experimenting with caching availability for all restaurant at once per day with a CDN expiration of 5 minute for next days and longer for later days. this would leave us with a single api call on search for availability.

 

# Future step

Make Quota cache more powerful by improving caching logic and server performances. Using CDN cache only is not optimal since once in a while a user will experience a very slow experience, the lesser the amount of user the more will experience the slowdown.

 

3-IMG_3376

 

 

5-IMG_3382 

 

 


 

 

如果您喜歡這篇文章可以點擊「讚」&「分享」
並歡迎訂閱EZTABLE IDEAS!  😀

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

EZTABLE at Linkedin-Senior Mobile Software Engineer

 

 

No responses yet

【Workshop】Head First Gird System

八月 24 2014 Published by under Design, Engineering

 【Workshop@140815】

Topic: Head First Gird System
Speaker: Candy Chen
slideshare: Head First Gird System

 

 

以往,在做一個 Event ,有Designer、負責實做的 Developer、以及提出 Event 的人 (SMMMC, Social Media, Marketing, Monetization & Communications),三方在合作時,總會發生許多溝通上的問題,導致 Event 進行時,諸多的不順。

 

而今,如果有一個「共通的語言」,便能輕鬆知道對方腦袋裡在思考些什麼。

今天邀請 Candy 介紹共通的語言──Gird System,讓各位 “think",Designer 做些什麼,Frontend 在切版時做些什麼,和SMMMC 在提供內容時要如何與兩位溝通。

 1-IMG_7214

投影片20-1

  • 在做一個 Event 時, Designer 會與 Developer 和 others(ex: SMMMC) 溝通。

 

 

 

 

 

 

 What is Grid and Grid system?

投影片3 投影片4

  •  如果 GOOGLE Grid & Grid system 會得到以上的圖,可是到底什麼是 Grid & Grid system 呢?

 

 

 

 

 

 

Is this a Gird system?

投影片5-01投影片6-01投影片7-01投影片8-02

  • 先想一想,以上四張圖,哪張是 Grid system ?

 

 

 

 

 

 

Ans: 3、4是 Grid system !

 

 

 

 

 

 

投影片9

  • Grid 提供一個視覺上非常和諧的畫面,把複雜簡化,同時 Grid 還可以重複複製套用在不同的情況。
  • Grid system 中文稱為格線系統,除了格子和線以外,還必須要可以歸納出小小的單位-Units (如圖:紫色區塊)。

 

 

 

 

 

 

 Designer 與 Developer 間的溝通問題

 3-IMG_7220投影片10

  • 右圖: 今年 EZTABLE 最佳錯誤示範: 草食肉食企劃。首先針對 Designer 與 Developer 間的溝通做解說。

 

 

 投影片11  投影片12

  • 一般的 Designer 心理想的 Grid 樣子(上圖左),把螢幕分成兩塊,左邊半塊是綠色、右邊是橘色,然後再將產品放上去,中間畫一條線,設定產品高度。
  • 在兩個產品上很符合,但若把這個 Grid 套在三個產品上,便會 GG! 前面提到,Grid 是可以重複複製的,理論上複製到整個頁面都要能符合才行。

 

 

投影片13  投影片14 

  • 而在 Frontend 眼裡,只有所謂的 Div ,沒有所謂的顏色和左右半邊,對它來說綠色橘色都只是一大塊的背景,它看到的只是把產品放上去這件事情。所以對 Frontend 來說,它的 Grid 是一個產品一塊;但一樣的情況,套用在三個產品裡就 GG 了。

 

 

投影片15  投影片25

  • Magic! 用真正的格狀系統便能解決以上問題,我們將可以依照格狀系統,把產品排好放在裡面!

 

 

2-IMG_7216

 

 

Grid System 中的四大變數

 投影片17

格狀系統中有四大變數:

  • 1. 總 columns 數
  • 2. 一個 column 的寬度
  • 3. column 和 column 間的間距(空隙)
  • 4. 左有兩邊的寬度

 

 

Grid 帶來的價值 

  • 1. 視覺上的和諧: 不會像上面舉例的,套用在另一種情況時,發生 GG 的情況。
  • 2. 解決多個產品放置的問題: 雖然有時兩個、三個對 Designer、Developer 是件很複雜的事情,但有了格狀系統將能幫你解決兩個、三個、四個、甚至更多個時的問題。
  • 3. 四大變數,套用在 Designer、Developer 的工具上,都是一樣的概念。

 

 

 

Grid 工具

投影片18投影片19

  • For Designer-Photoshop GuideGuide: 提供你調整格狀系統中的四大變數。
  • For Frontend-Susy: 它提供你客製化的 function,讓你產生自己定義的 Grid。
  • 基本上會把總 column 數訂為 12,因為 12 是個 magic number,12= 3*4、2*6,可以符合多個狀況。

小結論: 共通語言是用 Grid 考量時,而不再是用以往的幾 pixel 時,便不會出現往左偏 1pixel、或往右偏 1pixel的問題;也因為共通使用這四大變數,因此 Designer 只要提供 Developer 四個變數,便可以 co-work,解決了 Designer 與 Developer 間的溝通!

 

 

 

 

 

 

Designer 與 SMMMC 思維上鴻溝問題

9-IMG_7250

 接下來解決 Designer 與 SMMMC 思惟上鴻溝的問題

 

 

*Mobile First

Mobile First 是什麼? 

回到一開始,在執行一個手機上的 Event(草食肉食)時,似乎把 Mobile First 當做一個口號,往往最後才被考慮進去,因此發現 user 的瀏覽體驗非常差。

 

 

投影片21-01  投影片22-01

 

舉個誇張的例子:

當身處在 PC 時代時,我們會傾向把使用者的螢幕塞滿各式各樣的食物(資訊),非常的豐富看起來很吸引人(上圖);而當使用手機時,把這些食物放在上面,便會像一團廚餘(上圖右)。

 

mobile 和 PC 的瀏覽體驗非常的不同,Mobile First 策略下,提供內容的人必須換個角度思考: mobile 螢幕如此小,要如何提供使用者豐富的資訊,如何把資訊清楚的排列在上面,而不是想要在一個螢幕下塞滿所有資訊,如下圖。

投影片23

 

 

投影片26

Mobile First 有兩種,一是指我們要做 responsive 的狀況下,依照不同螢幕的大小做調整。
而另一種,是提供額外一個 mobile 專屬的頁面(像 EZTABLE mobile web ),這便是直接客製化成 mobile 可以觀看的頁面只有手機瀏覽時才會出現

 

如果是 Event 的話,會要求手機平板電腦可以看,但要如何解決像草食肉食手機的體驗非常差的狀況呢?

希望大家的思維是由小裝置→大裝置,來提供內容! 你必須先限制框架在小小的螢幕上,而不是天馬行空的將它排在10幾20吋的電腦螢幕,這樣才有辦法提供我們的 mobile user 一個最好的瀏覽體驗!

 

 

投影片27 投影片28

 

投影片29

 

例子: shopping,是我們第一個導入 Grid System,也是第一個做得最好的網頁。第一次做時互相溝通了許久,但花的時間是值得的,最後做出的效果很棒,回應的評價很好!

 

 

 

 

 

 

 

投影片30-01

最後總結,SMMMC 以前可能會覺得說我就提供 content 給你便行,可是在你提供 content 時可能會想說,提供的內容越多越清楚越好,或是越豐富越好,但是還需要把 Portability(攜帶性) 考慮進去,這樣最終才能讓 EZTABLE 成為一個 Mobile First 的公司!

 

 5-IMG_7244

 

 


 

如果您喜歡這篇文章可以點擊「讚」&「分享」
並歡迎訂閱 EZTABLE IDEAS!  😀

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

104 人力銀行-Visual Designer 視覺設計師

EZTABLE at Linkedin 

 

 

No responses yet

【Workshop】TDD: Spies, Stubs, and Mocks

八月 15 2014 Published by under Engineering

 【Workshop@140808】

Topic: TDD: Spies, Stubs, and Mocks
Speaker: Hao-Kang 
slideshare: TDD: Spies, Stubs, and Mocks

 

 

繼之前 Andy 在 Workshop 中介紹何謂 TDD,我們了解到為何要做 TDD 的原因以及 TDD 上手的三原則!(詳情請見:《TDD介紹》)

今日有請 HaoKang 繼續為TDD這個主題做延伸介紹,

什麼是 Spies, Stubs, and Mocks ? 讓我們看下去。

3-IMG_1989

 

 

投影片1

  • test spy 是什麼?

  • stubs 是什麼?

  • mocks 是什麼?

  • mocks 使用時機?

  • 何時不該使用 mocks?

 

 

 

 

test spy 是什麼?

投影片2

  •  spy 簡單來講它是一個 function,它會記錄被呼叫的時候的參數、回傳值,用來確認該物件如何被使用。

 

 

stubs 是什麼?

投影片3

  • stub 可以去監聽別人的 methods,而且測試物件行為是否有如預期。

stub 基本上與 spy 相同,但它比 spy 強一點點,它有 pre-programmed behavior。

 

  • pre-programmed behavior: 你默默得到一個假的 server,並可以叫它做任何事情。

假設你使用的是網頁,用 address 去呼叫 API 並回傳值,因為是在寫 unit test,所以 API 回傳什麼內容我並不確定,如果今天 API 掛掉,unit test 便會fail。為了防止這個問題,我們 stub address 的 code,原本的 code 一行都不用改,直接用 stub 把它換掉,stub 可以做任何事情,例如收到某個 URL,就回傳這個data,有了 stub 等同於有假的server存在!

 

因此,在測試上有兩個好處: 
1. 你呼叫正確的 API,我回傳正確的值給你,你要有辦法正確的運作,所以我在裡面寫理想中的回傳值,你就得照這個理想值去測試。
2. 你呼叫錯誤,或是有任何問題server會回傳錯誤, 你要有辦法handle 這個 error。

 

 

 

 

mocks 是什麼?

投影片4

  •  mock 像是 spy+stub,它也有 pre-programmed behavior,但是它還有 pre-programmed expectations,當 expectations fail 時,你 test 便會 fail。

 

所以 pre-programmed expectations 是什麼意思呢?

mock opinion 很強烈,例如,假設我們預期 controller 需要呼叫 model,便 mock model 在裡面寫說如果它內容不一樣時,就fail。然後測試 controller, controller 給它一個 input,讓使用者輸入他的 email,理論上輸入完後應該要呼叫它的 model 更新它的 email,如果沒有這樣做,就犯了它的 test fail,直接 fail! 連討論都不用討論。

 

 

 mock 

看 code 範例,它在這邊  mock  我們的 API,同時在實際  run 之前,已先把它的 expectation 定義清楚,當這個 mock 不是這樣被呼叫的時候,它就直接顯示 error! 所以實際上我們在測試之前會把它要的結果先寫出來,強迫它這樣走,如果測試後不符合它要的要求,將會直接 fail!

 

 

 spy method

讓我們比較 spy method,
spy case 也是要 spy 某個 method,但它後面若要 assert,你可以選擇性的不 assert,如果你不 assert 你的 test case 就不會 fail,但 mock 不是,mock 根本沒有 assert 的這兩行,你若失敗將直接 fail,所以這是 mock 意見強大的地方,它要求你一定要這樣做!

 

順帶一提,spy 加 assert 後就如同 mock 一樣,不過你可以選擇性的加 assert;然後 assert 可以加入 if else 等的邏輯判斷,或是你可以偵測你的環境,如果環境有點不一樣,你可以選擇性的不執行。

  • 小結論: spy 比較靈活,mock 很硬

 

 

mocks 使用時機?

投影片5

  •  mock 只能用在測試上,在每個 unit test 裡最好只能存在一個!

不太懂意思,那往下看。

 

 

何時不該使用 mocks?

投影片6

  • 如果不確定實行的 detail,不要使用 mock。

mock 的 built-in expectations 很強烈,它會逼著你的 expectation detail 一定要照著它那樣走。
例如,你大致上寫了一個 unit test ,而 expectation 還不確定時你使用 mock,結果可能會是你正在調整內容,結果它一直 fail 你 fail 你 fail 你,直到要不你把它刪掉,要不想辦法符合它的 expectation。

 

  • 簡單的規則,如果你不想要那麼強烈的意見的話,就不要使用mock!

再次強調 mock 的意見非常非常的強! 如果你可以spy+assertion,就用spy+assertion 因為它比較flexible,或是你有 stub 就用 stub,沒事不要用mock。

 

  • 在一般狀況下,一個 test 裡不應該超過一個以上的mock,

  

 1-IMG_1987

 

 

總結

投影片7

以上是大概的介紹,大部分的內容在網路上找得到,
所以,要如何去找到你們要的答案,

1.  GOOGLE。
2. 看人家的 code。

將會有助於你對 TDD: Spies, Stubs, and Mocks  的了解。

 

最後,簡單的規則,

要 Spy、要 Assert、最後要測試你的假設,

我知道現在 call base 有很多各式各樣的問題,但不要妥協!

 

 

 2-IMG_1988

 

 

 

相關閱讀

 

 


 

如果您喜歡這篇文章可以點擊「讚」&「分享」
並歡迎訂閱EZTABLE IDEAS!  😀 

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

EZTABLE at Linkedin-Senior Mobile Software Engineer

 

No responses yet

【Workshop】EZTABLE Design Library

八月 14 2014 Published by under Design, Engineering

 【Workshop@140808】

Topic: EZTABLE Design Library
Speaker: KC Liu
slideshare: EZTABLE Design Library

 

 

何謂 Design Library?  Design Library 的重要性是什麼?

今天邀請到 Front-end engineer KC,介紹屬於我們 EZTABLE 的 Design Library。

 

 

6-IMG_1969-001

很多人通常都有使用過 Twitter bootstrap 的經驗。透過 bootstrap,不需要寫什麼 CSS ,即可快速建構出有一定設計水準的網站;如果 EZTABLE 自己的網站在開發時,可以有一套類似 bootstrap 的元件庫,那就可以加速網站開發流程。

 

 

 

 

Why need it?

2-IMG_1952-001投影片1_01

有了 EZTABLE Design Library,因為有一個公開的設計元件庫可以參考,所以大家對於 EZTABLE 的設計風格會有一定的共識 ,像是大家對於 Logo 的 style、顏色,button 的種類等等,因此可以減少同事們在許多設計方面的溝通成本 (例如 Front-end engineer 跟 Designer 的溝通或是 PM 跟 Designer 的溝通)。以下列出為何我們要打造 EZTABLE Design Library 的原因:

  • learn from Bootstrap, Semantic UI
  • better communication
    使用共通的語言可以加快團隊溝通速度,甚至到不用溝通的程度。
    當大家對這些 Style 都有共識時,很多細節我們便不用再多花時間做確認和調整。
    例如在和 Designer 一起工作時,常常需要跟對方要說我這 button 的顏色、CSS 的色碼,
    如果有 Design library 的話,Designer 便可直接看到,便不需要再與他們做確認,這將會節省許多時間。
  • consistency  
    設計風格保持一致的水準,不會有很大的變動。
  • reusable components
    通常用來用去不外乎某幾個button、顏色,有了Design Library將可以重複使用,不用重新寫那些 CSS 的詳細項目。
  • boost development 
    加速開發,不用寫到很細的 CSS 的設定,便可以直接拿到需要的樣式。

 

 

 

 

 SASS+KSS

投影片2

 

所以我們要如何設計一個專屬於 EZTZBLE Design Library 呢?

經過調查之後,我們最終決定使用這兩個──SASS+KSS。

 

 

 

投影片3

 

SASS 如果有稍微寫過前端的 code 的人應該都知道,SASS 有一些 CSS 沒有的好處,例如可以設定變數、style 比較精簡,還有很重要一點是 Modular file structure with @import

 

1-投影片4

(↑pic: Demo_01)投影片5

(↑pic: Demo_02)

  • Modular file structure with @import

Design Library 會用到的東西,都可以寫成 SASS 的架構,例如顏色,可以全部寫在 color.sass 的檔案裡,按鈕則寫在 button.sass 的檔案。(pic: Demo_01)

因為 SASS 是一個變數,因此可以對 CSS 色碼做 naming,橘色可叫做 ez-red ,方便在語意的表達上更清楚。

 

顏色(pic: Demo_02)
定義灰色,在 SASS 裡面可用變數直接對每種顏色做定義,
如圖定義出 EZTABLE 的紅色($ez-red:f04e2f),之後在其他 SASS 檔裡便可以直接運用這個變數,我們就不用在背那個色碼,可以用更語意的方式來 coding 。灰色白色藍色亦是如此,只要你有定義的話,之後都可重複使用。

 

所以說 SASS 本身的架構和用法已經很符合我們心目中 EZTABLE Design Library 的樣子。
不輪是顏色、字型等等,我只要定義好一次便可以一直使用! 

但還必須要有一套系統來把 SASS  的內容做視覺化的呈現。

 

 

 投影片6

 

  投影片7

KSS 是一套由 Github 的設計師撰寫的 styleguide 產生工具,支援多種語法,例如 CSS、SASS、SCSS 等,你可以在 SASS 裡面直接寫註解,在註解那邊定義好必須呈現的元件, KSS 就可以自動幫你產生一個網頁式的 styleguide ,KSS 產生出的網頁裡會有你剛剛定義好的那些內容這樣便不用花額外的時間去寫 documentation;因此你可以更視覺化,從一個網頁上看到剛剛放上去變數的樣子。

 

 

 投影片8

  • KSS 本身是用 Ruby 寫的, 但也有人另外改寫出 Node.JS 的版本。

 

 

投影片9_01

  • 這邊示範了註解的撰寫方式

 

 

投影片10

投影片11

  • KSS 產生出來的網頁。 

 

5-IMG_1961 

 

 

3-IMG_1957-001

 

 

總結

  • 1. Design Library 有助於加快團隊溝通速度,甚至到不用溝通的程度,並保持設計風格一致,加速開發。
  • 2. 直接使用 SASS 來打造 Design Library。
  • 3. 除了字型、button 外,還有許多像 table, check box, segmented buttons, alert 等各種元件, 均可以放入 Design Library 。
  • 4. 只要將註解寫成 KSS 的格式,就可以直接由 KSS 產生 Design Library 網頁。
  • 5. 用 KSS 時,只要專心寫你的 SASS 、寫你的註解,寫完之後它會幫你自動產生出來! 同時這樣還有一個好處,這樣的 SASS 可以直接 import 在各個 project 裡面,所以它其實是同步在與你的網站更新的,不會有網站上有寫這個style,可是下面註解卻不見的情況。

 

有了 EZTABLE  Design Library,使我們 EZTABLE 裡的 PM、Designer、 Front-end engineer 的溝通以往更順暢!

並提升我們的開發速度,增進效率,可謂一舉多得!

 

 參考連結

http://sass-lang.com/guide

http://semantic-ui.com/

https://speakerdeck.com/kneath/a-better-future-with-kss

https://github.com/kss-node/kss-node

 4-IMG_1960

 

 


 

如果您喜歡這篇文章可以點擊「讚」&「分享」
並歡迎訂閱 EZTABLE IDEAS!  😀

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

104 人力銀行-Visual Designer 視覺設計師

EZTABLE at Linkedin 

 

 

No responses yet

文化──是有同樣熱情做事的一群人所形成的影響力

 

1-IMG_6382_fotor

Hi~~I’m intern, Wellington.

 

我和另外一位intern, Dada,受CTO Atwood大大指示,

要推廣並加強EZTABLE的Engineering Culture,並招募更多的Developer進入EZTABLE。

 

 

 

 

何謂文化? 

culture

在實習的第一週,剛好看到Airbnb上的一篇關於culture的文章,讓我重新更重視所謂的"culture"。

 

 

投影片4
Culture is simply a shared way of doing something with passion.

文化是件很重要的事情,在同樣的地方每個人都有一樣的熱情在做一樣的事情。

 

 

 投影片6

如同我們Alex老大所說,EZTABLE正在積極的尋找新鮮的肉體,有能力、有型的工程師!

因此,我們從內部提升及外部擴展兩個方向著手!

 

 

 

 

內部提升 

投影片7

(內部部分,主要是由我的partner Dada負責,我針對外部。)

我們現在開始每周五固定舉辦workshop,

每次會有1~2位講師分享他們的經驗以及專業領域。

(workshop內容會定期PO在EZTABLE IDEAS上,歡迎各位觀看)

 

 

外部擴展

 投影片8

↑這是我們的計畫。 

 

 

 投影片9

 
所以第一個方式是我們先在stackoverflow──一個最大程式設計領域的問答網站,
開啟我們Career Page,讓知名度更擴展國際。
(BTW 我們是在stackoverflow第三個PO職缺的台灣公司。)
 

 

投影片11
我們在stackoverflow上,開了兩個職缺(Senior Android Software Engineer & Senior iOS Software Engineer)
在兩個禮拜內,每個職缺都達到400~500的瀏覽量!
在這網站裡求職的幾乎都是外國人,
同時我們開始著手面試這些外國人,希望把更加多元的國際的文化帶進EZTABLE。
 

 

投影片15

stackoverflow連絡人說:
EZTABLE的Career Page發佈後,在兩周內達到400以上的瀏覽量,幾乎是他從來沒有聽過的狀況!
所以代表,我們EZTABLE在國際間有不少的人感到有興趣,並且有一定的知名度。

 

 

投影片13投影片14

目前在短短的兩個禮拜內,有32個的外籍工程師申請! (截至08/01早上)

 

 

 

 

 投影片16

之後在未來的一周內,

我們會在Linkedin內PO上我們EZTABLE的資訊,

相信這將會快速拓展EZTABLE的名聲!

 

所以希望不論是現在或是曾經在EZTABLE工作的夥伴,

趕快跟EZTABLE的做連結,

只要讓我們彼此的network更強大,

大家就會更知道EZTABLE這個公司!

 

 

to be continued..

 


 

如果您喜歡這篇文章可以點擊「讚」&「分享」
並歡迎訂閱EZTABLE IDEAS!  😀 

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

EZTABLE at Linkedin-Senior Mobile Software Engineer

 

No responses yet

【Workshop】知名網站架構分析

八月 05 2014 Published by under Engineering, 創業故事, 經營兩三事

【Workshop@140801】

Topic: 知名網站架構分析
Speaker: Penny Yi

 

 

 3-IMG_1355

大家好,我是Penny,先不免俗地介紹我自己,

2000年開始工作
2004年到2012年都在上海某交友網站工作
2012回到台灣

加入EZT前在搞什麼:Lead Mobile Team + Build API Service (v3)
個人感興趣領域:
Python、Performance Tuning、Lua、Go、LBS、Restful Service、Infrastructure

 

 

今天要分享的是某大交友網站 ,創辦人和EZTABLE一樣是4個有為青年

1-IPART 

04年加入,他們架構就是這個PHP4+MYSQL+ APACHE2直接做
05稱為侏儸紀,正式進入中國,用的東西更多了
08年 公司最茁壯的一年,加上了一些衛星服務
12年 正準備回台時,市場服務又更進一步成熟

 
 
 
 2-IMG_1353
 

中國之旅

網路南北大不同(北網通~南電信~)

網路南北大不同

在中國大陸,很多技術論壇裡的第一個問題是問:你們家機房放哪裡? 是網通還是電信?
如果你了解、講得出來「北網通,南電信」,代表專業,你真的有在大陸混過!

在中國大陸,北網通、南電信,兩方互看對方不爽,導致兩邊的機房不合。
假設你公司的機房放在網通的機房,而用戶透過電信的機房去連,這時用戶的速度大約跟"撥接"差不多。

 

所以那些你叫得出名字的大家公司都是自建機房,
像是阿里巴巴非常聰明接了兩條線進來,再自己的機房裡做交換,自己把這兩方的gap修補起來。
而騰訊比較囂張,對電信表示我的機房比你好,把你的server放在我的機房。
(這家公司大到的程度,已經反客為主了)

 

因為網通、電信很奇怪 ,兩個地方彼此沒有連接,是各自為陣,
所以他們透過另外一個節點,再繞到對方那。
這個節點上有學術網路、還有一個叫「鐵通」。

PS.鐵通的網路是跟著鐵路所佈,網路是跟著鐵軌走的,
所以火車走過去時網路會變慢,交通比較頻繁時很糟糕,常會收到客訴 😛

 

 

CDN服務

Screen-Shot-2012-07-10-at-10.00.31-AM1

因為網通和電信間的關係,中國的CDN彭勃發展,
擁有比較大的CDN可能在全中國都有機房,可以佈署到全中國,使各地的網路品質維持在同個水準。

 

 

CDN服務可達到的優點

  • 加速網頁瀏覽效能:已將緩存資料放在最近的機房中,不需重新向伺服器讀取。
  • 有效分流(頻寬):所有用戶都不再向同一個伺服器讀取資料,大幅降低集中流量。
  • 網站穩定度:網站流量分散網站的穩定度大幅提高。
  • 安全性增加:因網站透過CDN分散出去,駭客較難直接攻擊網站本體。

補充:
「常在打別人,意味著常被打」
駭客表示,打他們成本很高,他們機台分散在全中國,這將會影響駭客的策略: 到底要打哪一台?
駭客的軟實力是技術,硬實力是到底操做多少台PC ,
駭客想的是,打哪個節點效率最高,可是你很難猜,而且每打一次你的漏機又會少掉一堆。
因為server被攻擊後,就把你的IP封鎖掉,
這樣你手上的機子馬上瞬間 6000大軍→600→60,
因此會讓心懷不軌的駭客放棄對你的攻擊,
否則下次軍備競賽時,你的硬實力輸人家!

 

 

 4-IMG_1358

 2005年踏上中國土地,我很無助,我把台灣這塊系統搬到大陸去,結果一天就被打趴了,
在台灣了不起user 500~600,而在這一個禮拜我們經營的user到1000,再過一個禮拜達到6000! 

我發現以台灣的架構過去,擋不住那麼多人進來;之後,針對能最快解決的方法 ,我們打算從DB下手。

 

BTW我回到台灣的母校跟教資料庫的老師說,我進到中國這個領土,做到第5正規化,可是..毀了..
因為我Join太多blalba一堆,結果無法讓DB 的loading降下來,
老師: 你最後怎麼解決?
我: 最後我把第五正規化變成第一正規化,就解決問題了。

 

 

 資料庫優化

  • 減少PHP連線數

透過PHP連DB,如果你的連線數一直維持在一個非常高的連線量,
那DB跟本完全動不了,前面user也不會快,整個網站卡死。

  • 拆分Database,拆分Table

因此我們策略是 既然一個instance沒有辦法負荷那麼多,
那就拆DB,拆掉後有些東西不好拆,那拆table。 

  • CPU升級/SSD硬碟

再者,速度慢有無更好的提升方式──花錢! 只要是錢可以解決的就不是難事。
解Slow Log解了兩天,換了SSD後兩秒鐘搞定,效率提升很跨張。

  • Slow Log優化,和遷移更多的Query到Backup Database

當Data有再做Backup時沒事,而平常沒事做時花錢很討厭,
在高峰時也做些事,然尖峰時間的每台DB的loading 100%、CPU 100%

分享一個概念: 
阿里巴巴有一次在論壇裡分享,他們有幾萬台機台 ,而每一台KPI CPU 98%,代表幾乎是以100%在跑,
他認為100%在跑不見得是壞事,只要確認一件事──CPU跑到100%不會掛掉!
他總是在追求CPU 100%然後不會掛掉的神的境界!

  • API 化 – 以方便針對性擴容,共享

(EZTABLE在這方面做的很徹底。)

  • 靜態網頁CDN Caching

user連到一個網頁,整篇看完後他可能連我們的DB都不用連到,
只要不去改裡面的內容、照片,將會永遠存在上面。

但後來發現這個方案有點弱,不動很方便,但只要有改到內容便會變得很麻煩;
更動後,要把靜態網頁回收重製,

但因為CDN太多,觸發到各地的時間不一,所以可能更改完後,
CDN目前只觸發到北京,北京的資訊新的,而河南還未觸發,資訊是舊的。

  • 盡可能使用緩存(Redis/Memcache)

最後用記憶體的方式,前者EZ用狠多,兩者很有趣優缺點可以是互補

 

 

之後的workshop會再繼續介紹一些還沒提到的內容。

 

 

 

 


 

如果您喜歡這篇文章可以點擊「讚」&「分享」
並歡迎訂閱EZTABLE IDEAS!  😀 

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

EZTABLE at Linkedin-Senior Mobile Software Engineer

No responses yet

Internship Experience in EZTABLE

 

1-1-CAM03109 

Interning at EZTABLE this summer has been a fun, exciting and enlightening experience. I was led to EZTABLE through AppWorks, and they seemed more interested in my old and rusty programming background. Prior to this experience, I was desperately searching for my future career path, and programming was not on the list of candidates. However, my experience working at EZTABLE as an Android developer has deepened my insight in regards to the world of jobs and what one’s background should look like. It especially boosted my self-confidence, both in regards to my own competence as a programmer but also in my ability to decide on a future career path. Finally, the experience as a whole was a very fun and gratifying one which I shall certainly remember in the distant future.

 

I am a self-taught programmer, and this comes with its pros and cons. I started to learn web development around the age of thirteen. Prior to that I spent quite a lot of time online opening various kinds of discussions boards using pre-made platforms such as phpBB. However, I wanted to start my own websites and design them to do exactly what I wanted. I thus started with the basics, first learning front-end programming and subsequently back-end. As a beginner, everyone suggested I start with PHP and MySQL since they are very widespread.

 

When I started writing PHP, my life radically changed. I felt empowered. All of my brothers and my mother have always been very good at building things, painting, drawing, etc… Being very bad at art (I can draw stick figures!), painting, drawing, or any other things in which I must use my hands, programming was the only tool with which I could build things. I became increasingly addicted to coding, spending hours in my room writing and reading guides, tutorials and discussions online mostly about PHP, AJAX, Web 2.0 etc… At first, in order to properly learn, I restrained myself from using frameworks (such as Prototype or jQuery for Javascript) and tried to build stuff from scratch each time. As time passed by, I would have a favorite IDE, setup my own web server under Ubuntu, and contributed to various projects on the Internet.

 

Many people have asked me why I did not pursue computer science in college. It all comes down to one problem: mathematics. Programming only doubled my already existing hatred for the subject. While certainly helpful, one does not necessarily need to be a math god to be able to write code. With proper reading and practice, programming is an open world available to all those who fully dedicate themselves to it. The math requirements for CS majors repelled me, and I decided to keep it a “hobby” or simply work as a freelancer, which I did for a startup upon moving to Los Angeles. When that startup was aborted by its founder, I found myself in a rather difficult financial situation, and decided to work part-time at various jobs while focusing on my studies. My studies would keep me busy for a good four years, during which I did not write much code (learning Chinese has been a time-consuming challenge as well!). That was until I arrived at EZTABLE.

 

1-CAM02954

While searching for an internship, I realized that even though four years of college surely has taught me a lot, it did not help me make much progress in regards to my future career. After all, what kind of jobs does Asian studies lead one to? Translation? No thanks, I’ll pass. I certainly did not waste time, college was a time of personal growth and where I obtained an excellent education, both in general subjects and in Asian Studies; I was also able to explore various kinds of jobs while working part-time. Arriving on my first day at EZTABLE for an interview, Atwood’s offer for me to join the Android team was a surprise to me. I did not think any employer would look past the two words “Asian Studies.” Indeed, I thought my future prospects as a programmer were doomed the day I stopped writing code and started learning Chinese instead. I decided to toughen up and give it a try. After all, this might be my last and only chance to get back on the boat.

 

I will always remember that interview, especially when I was told “you have four weeks to learn Java.” It was a challenge I had long not been given, either by myself or by someone else. At the time I was still taking classes at National Taiwan University, which limited my time. I would learn the usual way: read brief tutorials, brief language references, do local tests, read “Dos and Don’ts” articles etc… The best way to learn after all, just like [human] languages, is to simply start coding! Having prior experience with programming certainly helped me learn Java faster, however the multi-thread and event-based nature of the language was a challenge during my first few weeks writing the Android application. As a matter of fact, writing Java for the first time in the Android environment was both a challenge but also a big help in itself. While online documentation (e.g., Stack Overflow, android doc, oracle doc) is certainly plentiful, it still took a short while to accustom myself to the different environments. Furthermore, the EZTABLE Android SDK was also an extra challenge and help.

 

The EZTABLE Android SDK was a clear example of the importance of team work. To Annie and I, the SDK was very helpful in that it laid important grounds to start developing the Hong Kong tourist app and provided many useful functions. However, it also felt like a jungle at times and we only discovered the existence of some functions after having coded them ourselves. Make no mistake here: I wish not to criticize the SDK or its developers, but simply wish to point at the importance of properly familiarizing oneself with the team’s code upon arrival. Indeed, when working within a team, in addition to being fast and efficient, code should be well-formatted and properly documented, with clear comments wherever needed; this is a practice I’ve tried to keep for ages, but it was nonetheless a good reminder. In addition to the aforementioned points, GIT is a crux of team work. While it surely has a learning curve, its importance is not to be debated and thus should be mastered within the smallest time frame as possible. Working with Annie, and later with Leo, proper GIT procedures had to be clearly established and regularly followed (I.E., frequent commits & clean branching). Working at EZTABLE certainly was a great lesson of team work.

  

1-2-CAM03108

Writing our application was not limited to our own ability and time, but also depended on the input of other teams within the company. I could not express how pleasant and fun it was to work with Nisha, our project manager. Nisha is a master of team organizing and keeping everyone updated and on track on the latest directives, decisions and issues. Indeed, we often had to wait for data input, but had to keep coding in the meanwhile. This taught me to be flexible in my working style and be ready to face the reality that radical changes may occur at any given moment. Annie and I arrived precisely when the API for articles was in the process of being changed, causing us to have to re-write a portion of the code. Some of the data given to us depended fully on us to be implemented, and we thus had to think of solutions that would best fit within the existing data structure. While it seemed a little stressful for us at first, I cannot fathom what Nisha must endure on a daily basis. Despite this, she always remains calm and friendly to everyone, keeping all of the teams functional and happy at all times. Thanks Nisha!! (Side note: this experience has even caused me consider Project Management as a very desirable option in the future.)

  

Finally, I came to realize that a career depends not necessarily on one’s educational background, but solely on one’s determination. Many people at EZTABLE who excel at their positions and duties did not necessarily study the matter in college but perform excellently. All it takes is passion and enthusiasm for what one loves to do in life; this is a respectable lifestyle. This might seem a little cheesy but to me remains a hard fact. My own experience writing the Hong Kong tourist app has lead to me fully reconsider my future career plans and while I am still open to new experiences, programming has definitely made it to the top of the ladder. Most importantly, I leave this great company with stronger self-confidence, knowing in the future that with determination, one can overcome any challenge.

 

906317_10152562882314788_1706867461786321617_o

I have very high regards for the employees at EZTABLE and the atmosphere that everyone strives to bring together. I could not be more grateful to have interned in such a great company this summer. I would like to personally thank all of the people I got to meet during the past three months and for what they have taught me personally and professionally. I would furthermore like to thank Alex, Atwood, Blaise, Mike, and Nisha for the opportunities, experiences and help they have given me. I could not express how lucky I have been to work with Annie this summer; Annie’s liveliness, honesty, great teamwork skills, and willingness to help are all things I hope people she meets in the future will notice and appreciate. I have made many friends within all teams (and not “departments”..!) this summer and I  could not be more grateful about how life-enhancing their presence has been. Once again, Thank you EZTABLE!

 

Christopher Burroughs, intern of EZTABLE

 


 

如果你也有野心、學習力強,歡迎一起加入我們 
EZTABLE實習生計畫全年無休
歡迎將你/妳的履歷寄到 CTO Atwoos, atwood@eztable.com

EZTABLE at Linkedin-Senior Mobile Software Engineer

 

 

No responses yet

【Workshop】From Web Development to iOS

七月 28 2014 Published by under Engineering

【Workshop@140725】

Topic: From Web Development to iOS
Speaker: Zakk
slideshare: iOS 101 for web developer

 

 

寫過web,想轉化跑道試試寫iOS卻不知從何下手?
想知道web開發和iOS的開發上,有何相同、相異之處?
今天請到EZTABLE的Zakk  為我們介紹 iOS的開發! 

 1-Photo 25-07-2015

 

 

 

Photo 25-07-2014 15 04 46--投影片2

Objective-C–蘋果的作業系統

  • Interface & Implement──java 裡的class,等同於 Objective-C裡的interface,在class寫之前先定義interface。
  • Property──跟java一樣。
  • Strong & Weak Reference
    宣告成Strong,就是希望這個變數指過去的對象不會被release。 
    宣告成Weak, 就是允許這個變數指過去的對象可以被release。 
  • Protocol & Category
    類似JAVA的interface就是Protocol 。
    Category: 若要對某些class加一些意義的function,可直接宣告Category,然後就可以對class直接增加一些你定義的function。
  • Delegate & Code Block
    使用者點button,然後你的code會收到點button這個事件,後面這就是用Delegate來寫的。
    Code Block就像是JavaScript code back function,可以把你code block包在裡面, 傳來傳去。

 

 

 

 

投影片3

Application Life Cycle

 

 

 

2-Photo 25-07-2014 15 16 25_1投影片4

Application Architecture

框框是APP,APP透過API與Server溝通。
主要是由Controller在做所有的動作(btw 你大部分都是在寫Controller),
update view、管理model、update server等,
比說如Controller owns Model,Controller可以叫Model去update Data,回來後跟Controller講,再去own這個view,再去update。

 

投影片5

Decenterlized Routing

在iOS裡很麻煩,它不像web有個Routing,有很多framework,訂好Routing的規則。
iOS全部都是Controller決定!

ex:使用者點了某個button,然後Controller收到,知道這個button要跳到哪一頁,
所以寫程式的人,整個藍圖、整個APP要怎麼跑都是在寫程式的人的腦袋裡的,
沒有像web一樣可以讓你很清楚的看出是怎麼運行的。

 

 

投影片7投影片8

Page Transitions 

所以 view Controller你可以決定頁面是要push一個頁面進來,還是跳下一頁,
同樣的button"cancel"在不同業面叫出來時會有不同的反應,
用Push進來的話,這個cancel button是要做Pop,
用Present進來的話,這個cancel button是要做Dismiss,
所以就要考慮清楚!!這個button定義的是什麼動作,會因為別人怎麼用而有所不同!

 

 

 投影片6

Switch Between Apps

在APP之間的切換,在iOS非常的不明顯,
原因是因為你很難知道別人的APP是怎麼被叫出來,
你也很難確定使用者在它手機裡是不是有裝某個APP。

 

使用者點某個button叫出APP做某件事情,要先判斷存不存在。

例如在我們APP中,要用Line來邀請朋友來用餐,那你就要判斷使用者手機裡的Line到底存不存在,
以及用Line邀請完後,要有一個 button讓它直接回來,因為它不像web有個"上一頁"。
所以
1.你就會想說把人找出,用LINE這樣管道好不好。
2.你要知道LINE的語法,你才知道如何發訊息給LINE的朋友。

 

 

投影片9 投影片10投影片11投影片12 

Code範例(可點及圖片放大看 or 點sildeshare)

Target──這是view通知Controller 使用者做的動作。
Delegate──是可以宣告一個Protocol,讓view controller去實做。
Block──意思是它是一段程式碼,自己可以包裝成一個變數。
Data-Binding in ios: KVO

 

 

知道以上的技巧後,memory的控制小心一點,
不要有Dead-Lock、不要有讓你的變數指到空的記憶體,
然後知道view如何跟Controller溝通跟Model溝通,就差不多知道如何寫iOS了!

 

 

 


 

如果您喜歡這篇文章可以點擊「讚」&「分享」

並歡迎訂閱EZTABLE IDEAS!  😀

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

EZTABLE at Linkedin-Senior Mobile Software Engineer

 

 

No responses yet

【Workshop】TDD介紹 (Test-Driven Development, 測試驅動開發)

七月 28 2014 Published by under Engineering

【Workshop@140725】

Topic: TDD介紹 (Test-Driven Development,測試驅動開發)
Speaker: Andy Huang
slideshare: TDD

 

  

相信許多developer聽過、嘗試過所謂的TDD,

前陣子一篇針對 TDD 的文章︰TDD is dead. Long live testing. 在開發者中又引起不少的討論,

但至於何謂TDD?,TDD的重要性又是什麼呢?

今天請到EZTABLE的Andy來為我們介紹  🙂 

 Photo 25-07-2014 14 40 45

 

 

 TDD= Test-driven development

投影片1

  • TDD和寫測試是兩回事 ,TDD是把這個測試的階段,拉在開發前做一個調整,形成紅燈綠燈的概念(紅燈:失敗,綠燈:通過)。

 

 

投影片2

流程

  • 先寫測試→檢查測試有無失敗→再寫code→跑所有的測試→最後清乾淨code。

 

 

 投影片3

The Three Laws of TDD

TDD 若要上手有簡單的三原則可以遵循

1.除非它是讓紅燈變綠燈,否則你不允許寫任何 production code(你沒有先寫測試的話,你不能先寫production code)。
2.你先寫測試,你也不能先寫太多,因為一存檔發現fail,就代表你要寫production code。
3.確保寫測試只針對一個點,所以一有fail,就代表你要寫production code, 開始寫Implementation時,只要Implementation讓紅燈變綠燈,那你就應該繼續回去寫測試。

 

 

投影片4

 

 

 

投影片7

TDD Sucks–對TDD的嘲諷

  • 當我完成主要功能後,我根本沒有足夠的時間來寫測試。
  • 測試是不是我的工作,因為它是QA的工作 。
  • Unit tests不需要,因為我的code非常完美。
  • 我不喜歡TDD,因為我很享受花我時間在debug上!(XDDD)

 

 

投影片8

  • 所以,所以你會花在更多的時間在debug上,因為你很容易寫A壞B!

 

 

Photo 25-07-2014 14 47 58

投影片9

Benefits好處!

  • 我們通常寫一個程式,然後馬上測試它,都是餵一樣的資料,看它結果對不對,TDD把這個自動化了,因為它always幫你自動測,所以增加效率。
  • Code質量──當然因為TDD所有的code都是有經過測試的。
  • Over-engineering (YAGNI)── 一次只做一件事情,做需要的部分!Implement後只需要pass綠燈,所以它可以避免工程師先想很多,然後加了general的東西,結果最後用不到。(YAGNI(You Ain’t Gonna Need It)意思是我們不應該為程式碼加入尚未用到的功能)
  • 更好的界面 ── 你先寫測試的話,是用client的角度去寫module,因為你是個user,所以Implementation都還沒做,而是(憑空)想像我是個user該如何用測試code,所以能幫你寫出更好的Interface。
  • Documentation──測試它的input、output,如果它寫的好的話,你很容易看出每個module,它的input、output寫了什麼,所以它可以順便當Documentation。
  • 測試要更好測話,需要更多的modeule更多的彈性,因為你先寫測試,所以它讓你自然而然有這樣的特性。

 

 

投影片10

Best Practices

  • 要寫的非常的小跑得夠快,因為我們每次都要一直跑它。
  • 每個uni test,不需要測Implementation的detail因為它可能會掛主要程式,只要測結果就對了。
  •  test code、production code是同個等級,你需要好好maintain、善待。
  • 低耦合使每個單位有效地獨立進行測試。 
  • Less Mock & Stub

  

 

 投影片11 

Anti-Pattern

  • Avoid dependencies between test cases. –每個case test都需要獨立,這樣比較容易debug。
  • Do not test implementation details.
  • Avoid slow running tests.
 
 
投影片12
  •  可Google搜尋"TDD is dead"相關文章閱讀。

 

 

當然TDD並不是完美,在不同類型的開發上可能並不試用,

總之,大家可以動手嘗試看看,感受一下紅燈轉綠燈的快感 😛

 

 

 


 

如果您喜歡這篇文章可以點擊「讚」&「分享」

並歡迎訂閱EZTABLE IDEAS!  😀

如果你是學習力強,而且經驗值高的人才,
歡迎一起加入我們 EZTABLE!! 

EZTABLE at Linkedin-Senior Mobile Software Engineer

 

No responses yet

« Newer posts Older posts »