跳到主要內容

發表文章

目前顯示的是 2017的文章

Cucmber 環境設定 on Mac

因為最近開始開發iOS 但對於測試一直沒有很棒的解法 因此團隊成員發了狠,去徹底研究一個測試框架cucumber跟appium 這裏簡單記錄一下怎麼安裝與設定 主要是參考成員的blogger的設定,再用自己的理解記錄在自己的blogger這邊 首先要安裝 xcode,目的是為了 iOS 模擬器 第二步驟要安裝主角 cucumber  terminal 中指令 sudo gem install cucumber 第三步驟是安裝Appium library terminal 中指令 sudo gem install appium_lib 前往網站 http://appium.io  並點擊 "download appium" 然後選擇下載 " appium-desktop-1.2.7.dmg " 第四步驟安裝RubyMine IDE,目的是為了讀取 feature 檔案並可以透過 IDE 自動產生step 的語法 前往 JetBrain 官網去下載安裝 安裝 pry 套件,這個套件是為了debug用的,特別是他的killer feature "binding.pry" terminal 中指令 sudo gem install pry 即可安裝 安裝 homebrew,這個是個套件管理工具提供 Homebrew 互補了macOS,可以使用 gem 安裝 ruby 套件,而利用brew來安裝依存軟體 安裝方法 terminal 中打指令 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 安裝 carthage,這個套件是類似於 CocoaPods 的功能,也是 iOS 套件管理用 terminal 中打指令 brew install carthage 到這已就完成了環境預備安裝 接下來就是打開appium server 然後在已經寫好 feature 的 測試範例專案 位置 透過 terminal 執行 cucumber 就可以跑測試 ---------

[學習iOS之路] Lifecycle 比較

在開發Android很多年之後終於開始學習寫iOS了 契機就是工作需要,果然工作需求就是推開最大靜摩擦力的原動力啊! 在這邊寫下學習Swift的一些筆記,希望在自己忘記或是需要給別人教學的時候可以起到一點點作用。 因為對Android比較熟悉,所以透過比較來熟悉iOS架構 首先是iOS與android的比較 可以參考這張圖 Android vs iOS lifecycle 與這張 iOS 詳細state 流程 Android lifecycle OnCreate -> OnStart -> OnResume ->(running) -> OnPause -> OnStop -> OnDestroy                        ^                  ^                                  |               |                         |                  |-------------------v               |                         |-----<-----   OnRestart   ------<---------v iOS lifecycle LoadView -> ViewDidLoad -> ViewWillAppear -> ViewDidAppear -> (running) -> ViewWillDisappear -> ViewDidDisappear -> ViewWillUnload -> ViewDidUnload -> dealloc 於ViewDidDisappear之後view就看不見了,如果view要再次被看到且view還存在 那就會是ViewWillAppear,否則就是LoadView從頭開始 下一篇是語言的比較 Java vs Swift

[學習重構筆記] Part1.了解什麼是重構

重構 (Refactor) 是: [在不改變程式碼外在行為的前提下,對程式碼做出修改,進而改進程式的內部構造] Input & Output沒有變動 重構目的 改進軟體設計 重構可以讓設計不用一步到位 使軟體容易理解 使軟體容易維護與擴張 容易發現 Bug 壞味道 (Code smell) 這邊僅列出重點想學的幾個 Duplicated Code Long Method Long Parameter List Large Class Magic Number Shotgun Surgery Divergent Change Feature Envy Data Clumps Primitive Obsession 簡單的說就是 重複了、做太多事情了、命名不符其實、太多公開函式、不太像物件導向 何時進行重構? 完成 Feature 時 修完 Bug 時 Code Review 時 何時不要進行重構? 程式無法執行時 交付時間緊迫時

Refactor 學習筆記 I Extract Method

Refactor 學習筆記 I Extract Method . 現在的公司對於程式技術上有一定的要求。雖然不是說不會寫程式,但是寫了多年程式並沒有深入研究 Refactor (重構)技巧。所以這次技術健檢的分數不甚理想XD。因此想要開始惡補一下。 Extract Method 動機 . 這是最常被使用的重構手法之一。這應該是看到一個過長的函式或是需要需要註解才能了解的程式碼,就應該將此段程式法放到一個獨立的函式中。 . 主要目的是為了有簡短而且良好命名的函式。因為如果每個函式的顆粒度都很小,那麼就容易彼此復用。再者如果函式都是很細的顆粒度,那麼要覆寫(Override)也會更簡單。 . 關鍵倒不是真的長度,而是函式名稱跟函式邏輯本體之前的語意距離太長。如果提煉出來可以增加清晰度,那就該做,就算函式名稱比原本程式碼還長也無所謂。 . 作法 . 函式名稱應該用意圖來命名,以[做什麼]來命名而不是[怎麼做]。但如果想不出一個更有意義的命名就別動 . 如果有僅用於被提煉碼的暫時變數,可以在目標函式宣告為暫時變數。 . 如果被提煉的程式碼會賦予區域變數值,那就要使用Replace Temp With Query來將暫時變數消滅再提煉。 感想ㄎ . 雖然 Extract Method 觀念最簡單,也最常用。但是也不是隨便亂提煉就行。自己要有一個中心思想,就算提煉顆粒度很細小,他人不太習慣,但自己有自己的理由可以提出與他人溝通即可。並非一定要有多處同時使用才提煉。也可以先提煉,然後才更容易復用。 . 最難處裡的就是被提煉的程式碼有賦予區域變數的情況,這可能是最需要特別訓練的部分。

物件導向複習筆記

參考網址:  https://dotblogs.com.tw/ace_dream/2016/01/10/oop1 物件導向的三大特性: 封裝:(Encapsulation):指的是將一組相關的屬性、方法和其他成員,視為單一單位或物件。 繼承(Inheritance):則是描述依據現有類別來建立新類別的能力。 多型(Polymorphism):指的是您可以有多個交替使用的類別,即使每個類別是以不同的方式來實作相同的屬性或方法。 封裝:(Encapsulation): 物件都會擁有物件內部的私有部分(屬性、方法...)而這些部分必須是外界無法直接存取,這樣才能保有物件的完整性。 如果"破壞封裝"的話,會有可能無法恢復原來的功能,因此物件必須將私有的部分封裝在物件的內部,而使用者只能藉由物件所提供的方法、屬性來操控物件,以保持物件的完整性,這就是封裝的特性。 繼承(Inheritance): 一個物件A得到另一個物件B特性的過程稱為“A繼承B”,物件B則屬於“父類別”或稱基礎類別(Base class),物件A則屬於子類別或稱為衍生類別(Derived class)。 子類別可以繼承父類別的能力,直接使用父類別非私有的屬性和方法。 子類別只能繼承一個父類別。 父類別的方法若宣告為虛擬(virtual),則表示該方法可以被子類別覆寫(非必需)。 父類別的方法若宣告為抽象(abstract),則表示該子類別一定要覆寫該方法(子類別為抽象類別除外)。 類別若包含抽象成員,則該類別必需宣告為抽象類別。 父類別又叫做基底類別(Base Class)。 子類別又叫做衍生類別(Derived Class)。 若方法或屬性宣告為密封(sealed),則不可以被子類別覆寫 多型(Polymorphism):又稱同名異式,是透過動態繫結的方式讓我們在程式執行時期可以動態決定物件參考所要執行的方法,多型允許我們在程式中使用名稱相同的方法或屬性,但不須考慮當時使用的物件型別是什麼。若要設計多型,子類別就必須先覆寫父類別同名稱的方法或屬性,接著再使用父類別的物件參考來選擇所要執行子類別物件實體的方法。由於多型的使用上會在類別中建立名稱相同的成員(屬性或方法),多載(Overloading)和覆寫(Overriding)也可以建立

持續的做你不會做的事

持續的做你不會做的事 這個觀念雖然很早就聽過,但從來沒好好做到過。以前聽過,如果你一直做你現在每天會做的事情,那你得到的東西就是你現在擁有的而已。這個觀念其實也只是反過來換句話說的觀念而已。為什麼現在會對這個觀念特別有感觸呢?是因為現在真的想要改變,不希望自己永遠都是這樣,知而不行。但現在雖然狠下心要好好做,卻覺得真的好困難。每天要逼自己離開舒適圈,做自己平常不會做的事情。所以需要找人一起這樣做來提高動力,第一個受害者就是我老婆了。我跟她一起在家裡跑 Scrum 來達成一些人生目標,並且一起刻意練習一些事情。首先我自己的事情就是天天寫15分鐘的部落格。不管內容,不管長短,就是要逼自己每天花時間坐在電腦前開始狂打鍵盤。有沒有效果我也不管,反正先做了再說,每個 Sprint 再來做 Retro 就好了阿。Show, Don't Tell 這句話是公司內最近常聽到的話,希望可以改變我自己,繼續努力,加油! 持續的做你不會做的事 是的,現在最重要的事情就是[改變],除了每天寫部落格以外,還要每天進步一點點。另一件事情就是開始聽得到 App ,或許這並不是實質上的有效,但這是改變的開始阿!!還有另一件事情就是減肥,每天運動固定的時間,雖然沒有辦法抽出時間去健身房,但是堅持自己每天運動。不管強度,不管任何動作,只要每天持續下去,希望撐過幾個 Sprint 後可以真的有點改變。希望真的有效,可以給自己的改變打一劑強心針。

刻意練習

學習效率 想要多花點時間學習,但常常覺得沒有效果。最近這樣的想法困擾著我,剛好公司內部在提倡導師文化,而我的導師是公司比較資深的員工。因此就在與導師每天的會面提出了這樣的問題。 首先導師先詢問我是怎麼學習的,我就提出我現在嘗試著花時間來寫部落格,統整自己的想法,彙整自己的一些技能跟知識。另外希望每個月可以看一本書,可以提升自己程式能力並且立即用在工作上。但事實上進公司已經三個月了,很多書其實都沒有看完,可能看了一些內容又轉換去看了其他書。又或者某些看完的書的內容,現在也有點模糊,並沒有真正的內化為自己的能力,效率真的很差。 因此導師提出了他的想法,簡單的說就是每天固定時間固定長度逼自己看書。每天如果都做自己會的事情,或是做平常就會做的事情是很難進步的。因此要刻意的讓自己在固定的時間固定的長度來學習,這種比較刻意的學習是比較有用的。如果只是給自己一個一個月要看完一本書的期許,通常過了一個月這件事情不會發生,而且就算發生了或許效果也打折扣。不如每天都讓自己抽出時間來做,每天固定學習幾頁,這樣一個月過去一本書也可以看完。這個想法的確比較踏實。畢竟時間就是這樣不構,而且平常生活比較放鬆,時間顆粒太大了。覺得找不到時間來看書與學習。所以打算給自己一個課題,每天看三十分鐘的書,每天寫15分鐘的部落格。不管是不是有寫到一個段落,或是有足夠長的時間來做。給自己隨時計時,隨時累計,只要累計超過這個時間就可以停止。希望讓自己可以在固定的TimeBox中學習念更多書,或是寫更多部落格內容。 刻意練習 這些觀念跟最近看的一本書有一樣的觀念,而這觀念在很多地方都有,今天中午同事在看的影片也在提。這個影片是邏輯思維的羅胖在講解如何成為高手,他說到學習就是要學習套路,任何人都是學習以前的人歸納的重點,舉例來說,古代的人要顯示自己很有知識都是要背詩經,孔子:不知詩無以言。在科學上也是如此,了解一些定律,根據這些前人累積的套路作為基礎,然後繼續發展。 但學習不僅僅是知道拿前人的經驗作為基底,更重要的事情是要能及時反饋,越快得到反饋越好。如果可以刻意的練習然後修正,這樣的效果是最好的。除了反饋即時性以外,還有要脫離舒適圈。舒適圈就是每個人很熟系的環境,在這個環境不管做什麼都不太需要思考,也因此沒有效果。例如一個計程車司機開車開了十年,或許開車技術上還過得去,但

Google文件寫Blogger

緣起 想好好開始練習寫部落格來把一些學到的東西內化,但從來不知道如何開始。在公司開始跑 Scrum 後,想說把自己的一些目標都列下來,然後像跑 Scrum 一樣每兩週一個 Sprint。其中一個 Story 就是想要每個 Sprint 寫下一篇 Blog,因此上網查到用 Google 文件可以直接寫好然後直接貼到 Blogger 裡面。目標是每天寫15分鐘的文章,慢慢的累積,讓自己可以更上層樓。

C# 泛型

為什麼要使用泛型Generic 這次要提到的是泛型,也是這次我負責上課的部分。 我會就自己的吸收用自己的理解來說明什麼是泛型。 泛型簡單的說就是 C# 2.0 提出的一種新的集合類別,用於汰換掉 .NET 1.1 的非泛型集合類別。 以 List<T> 為例子,就是拿來汰換掉 ArrayList 用的。 以前 ArrayList 提出也是為了解決某些問題而發明出來的類別,主要是解決程式碼重複的問題。 為了儲存 int 需要設計一個儲存 int 的集合類別,為了儲存 string 需要一個儲存 string 的集合類別。 所以不如設計一個 ArrayList 可以儲存 int 也可以儲存 string 。這是怎麼做到的呢? 原理就是因為型別都是來至於 object ,因此只要將所有型別的先轉換成 object 存起來,然後要用的時候再取出來,然後從 object 轉型回原本儲存的型別就好,這就是 ArrayList 。 講完 ArrayList,來說說 List<T> ,泛型是在實例化的時候確定使用的型別,以便於在編譯時期就可以判斷型別安全性,也因此帶出泛型與 ArrayList 比較後的優點。可以讓編譯器來保護程式碼。至於程式碼重複這個優點泛型跟 ArrayList 一樣都有,另外還有一個 優點,那就是效能。 ArrayList 出了什麼問題呢? 最主要的問題就是轉型,因為儲存成 object ,存入時跟取出時都需要做轉型,這稱為 Boxing / UnBoxing,從 int 轉型成 object 稱為 Boxing;反之從 object 轉成 int 就是 UnBoxing了,這耗費效能。但 List<T> 因為在實例化的時候就指定好型別的,因此沒有這個問題。 以上三個好處,程式碼重複使用、型別安全性、效能,就是以泛型集合類別取代非泛型集合類別的好處。

c# recap

最近在新公司受到了文化衝擊以及能力衝擊。剛好公司有開很多課程可以學習。就積極地報名了。 這次的課程是C#的一些介紹 var, dynamic, anonymous type, nullable<T>, extension method 這邊先提到var. var有寫過C#或是JavaScript的人一定都用過。但或許不知道何時該用或是何時不該用。這次的課程讓我比較清楚了點。 var 是隱含型別,也是一種強型別是在C#3.0的時候新增的。是一種在編譯時期就會檢查的型別。使用上必須給預設值,不然會compiler error. Do: 除了不能用的情境以外盡量使用! Don't: var x; 沒有初始化不能使用!

Multiple without multication or addition operator

Given two binary strings, return their sum (also a binary string). For example, a = "1101" // 13 b = "1000" // 8 Return “1101000”. // 104 Solution: implement Binary add to perform multication static int MultipleWithoutOperator(int num, int multiplier) { StringBuilder sb = new StringBuilder(); string binary = Convert.ToString(num, 2); string binaryMultiplier = Convert.ToString(multiplier, 2); string temp = ""; for (int i = binaryMultiplier.Length-1, j=0;i >= 0;i--,j++){ if (binaryMultiplier[i]=='1') { if (string.IsNullOrEmpty(temp)) { temp = binary.PadRight(binary.Length + j, '0'); } else { temp = BinaryAdd(temp, binary.PadRight(binary.Length + j, '0')); } } } return Convert.ToInt32(temp, 2); } static string BinaryAdd(string a, string b) { int carryover = 0; Stri

I found a online free GeoNames lookup service

main page: http://www.geonames.org/ the api overview: http://www.geonames.org/export/ws-overview.html api templte: http://api.geonames.org/method?params=query&username=yourname the jeoquery.js file for jquery using http://tompi.github.io/jeoquery/jeoquery.js var methods = { astergdem: {params: ['lat', 'lng'] }, children: {params: ['geonameId', 'maxRows'] }, cities: {params: ['north', 'south', 'east', 'west', 'lang'] }, countryCode: {params: ['lat', 'lng', 'type', 'lang', 'radius'] }, countryInfo: {params: ['country', 'lang'] }, countrySubdivision: {params: ['lat', 'lng', 'level', 'lang', 'radius'] }, earthquakes: {params: ['north', 'south', 'east', 'west', 'date', 'maxRows', 'minMagnitude'] }, findNearby: {params: ['lat', 'lng', '

Counting program running time

Sometims we want to know how fast our program running, I found two methods on stack overflow. DateTime dt = DateTime.Now; for (.......) { } TimeSpan ts = DateTime.Now - dt; Console.WriteLine("total runtime: " + ts.ElapsedMilliseconds.ToString() + "ms"); or (according to MSDN) if you need better resolution Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); for (.......) { } stopWatch.Stop(); Console.WriteLine("total runtime: " + stopWatch.ElapsedMilliseconds.ToString() + "ms");