[Java][Heroku][程式設計週記] 新年快樂...來寫code吧.. Go-martini跟 Java Srping Boot

前言: 新年新希望…. 繼續寫程式啊…. 之後要把Go Web Server逐漸到真的能使用的部分. 筆記: [Golang][Heroku] 將buildpack upgrate到Go1.4 最近的需求,將Go拿出來重新的翻了一下.除了之前發現沒有更新到Go1.4之外.也發現原來之前透過martini寫出的REST server並不完全是JSON的格式.於是最近開始把Go-herokuo-server翻了一下. 以下紀錄如何將你的heroku更新到1.4 重新跑godep 記得將godep目錄下的檔案全部一併更新上去 或是可以參考kr/heroku-buildpack-go [Golang]關於Json資料的Get/Post處理 發現martini原先雖然有做REST API但是並沒有針對JSON資料來處理.而要處理JSON的資料其實在Go裡面還是有一些地方要處理. 幾個值得注意的地方如下: 從網頁抓來的資料可以由http.Request.Form或是http.request.Body抓來處理. Request.Form 資料可以從 curl -X POST -d “DATA” “http://address” Request.Body 資料不僅僅可以抓 curl的資料,也可以抓取http.NewRequest(“POST”, url, bytes.NewBuffer(jsonStr))來的資料. 抓取來的資料都可以透過map interface來接,再慢慢去處理. 如果JSON資料比較複雜類似 { A:a1 B:[ { B1: b1, B2:b2}]} 就透過以下邏輯來解決 先透過第一層map拿到B內容 [ { B1: b1, B2:b2}] 透過 array interface拿到 { B1: b1, B2:b2},記住內縙 ary[0] 再透過map接過來繼續解出其他的內容. 參考資料: 傳送JSON POST資料方式 透過Request.Body抓取資料 Golang Example的JSON 這邊有關於Request.Body部分的處理方式 以下把部分程式碼擷取出來: //資料來源 //curl -X POST -d "{ \"name\"" : \"that\", \"num\": \"3\"}ttp://localhost:5000/fruits" // 透過Request.Form的資料 r.ParseForm() var dat map[string]interface{} for key, _ := range r.Form { fmt.Println("r.form") fmt.Printf("key = ") fmt.Println(key) err := json.Unmarshal([]byte(key), &dat) if err != nil { fmt.Println(err.Error()) } } for key, value := range dat { fmt.Println("Key:", key, "Value:", value) } // 透過Request.Body再把Json資料Unmarshall body, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Println("read error") } fmt.Println(body) fmt.Println(reflect.TypeOf(body)) fmt.Println(string(body)) var dat map[string]interface{} err = json.Unmarshal(body, &dat) if err != nil {...
繼續閱讀

[UNIX][python][Golang][程式設計週記] 20141231

前言: 接下的時間可能會比較忙碌,盡量也會多花一點時間玩Go… 筆記: [Golang] 關於一些實用的鏈結 如何優雅的處理伺服器遇到SIGNAL問題時候重啟: Graceful server restart with Go 關於Go 1.4 關於測試的新功能: My reason to be excited for Go 1.4 關於Golan許多工具的介紹: An incomplete list of Go tools Go for the paranoid network programmer: 挺多講解許多網路工程師應該會用到關於Go的部分 Go Everyday: 一個連續寫了三個多月Go的工程師把他的心得整理一下,裡面也包含他常用的工具 My Thoughts on Martini: 一篇專門討論一些Go上面Martini缺點的網頁,當然主要也是推廣自家好用的web framework negroni [Docker] 這個禮拜Docker.Taipei 有辦年末小聚.雖然沒辦法參加把相關文件收集一下: Carl Su: Docker 發展近況簡報釋出,內容涵蓋 Machine, Swarm 和 Compose。 用docker開出desktop環境:DOCKER DESKTOP: YOUR DESKTOP OVER SSH RUNNING INSIDE OF A DOCKER CONTAINER Docker.Taipei 年末小聚,現場錄影 zerotier: 可以將docker服務串接在一起 Docker Infra 架構簡介與實例: 可以做到cluster與分流的架構 [Python] 一些網路上看到的有用文章 [Python] IPython簡單使用技巧速記 透過Facebook傳送訊息 via Python 根據作者的說明如下: 可以做到 Graph API 無法做到的事,例如傳訊息至朋友或群組,也可以上傳照片,還可以接收訊息.所以可以用 Facebot 來寫一些通知功能,甚至是和你聊天的機器人. [Google]透過經緯度顯示Google Map 經過這一篇stackoverflow問答可以查到詳細方式 http://maps.google.com/maps?z=12&t=m&q=loc:38.9419+-78.3020 z is the zoom level (1-20) t is the map type (“m” map, “k” satellite, “h” hybrid, “p” terrain, “e” GoogleEarth) q is the search query, if it is prefixed by loc: then google assumes it is a lat lon separated by a +
繼續閱讀

[Golang]關於Slice在Append的一些發現

前言: 當初主要是RUST在官網上提出他們可以避免掉std:vector.push_back造成的referene 問題. 於是我也很好奇,究竟Golang會怎麼樣處理這樣的問題. 也由於Go本身把vector拿掉,我們就用Slice來試試看. 筆記: Slice 本身的結構包含資料本身,長度(len)與容量(cap),根據Slice Internal Document裡面提到的.而且操作slice的append的時候,會根據你目前的容量(cap)來決定是否要重新分配記憶體位置. 比起std::vector好的是,如果記憶體重新分配了,原先參照的參數不會得到空的記憶體位置,而會變成是複製的內容. 但是要注意的是,參照的變數就不會跟著變動了. 這聽起來就是比較安全一點,不過程式不會造成pointer to null並不代表比較好,因為在這種狀況下.所參照的數值已經被修改,你可能會遇到更不能預測的問題. 所以比較優雅的方式,還是事先要保留足夠的資料.避免append造成的資料重新建立. 奇怪的狀況,cap增長的大小根據compiler的不同 我本來是很清楚這樣的狀況,直到我把我以下的程式跑在本地端(Mac/Win)還有遠端的Golang Playground發現結果不一樣了. 是的! 靚過第一次slice append之後,cap(slice)增長的數值竟然不一樣?? (Playground是2,本地端是1) 一樣的狀況.類似的操作在c++ std::vector 就沒看到 (Win/Mac/Coliru online compiler) 增加過後的的cap都維持為”1”. 這裏有參考的C++程式碼. 於是我在Stackoverflow詢問了這樣的問題,也引起了一些人的注意,幫我把問題發到了Golang上面.雖然沒有辦法說服大家把這樣類似的問題放入spec或是warning,但是真的提醒大家,真正在使用slice的時候,必須像使用std::vector一樣的小心.最好的方式是不要參照,如果真的要參照的話,也建議使用保留的slice大小來避免記憶體重新的分配所造成的參照失效. 以下是完整的Golang 測試程式碼 package main import "fmt" func main() { var a []int var b []int fmt.Printf("a len=%d, cap=%d \n", len(a), cap(a)) a = append(a, 0) b = append(b, 0) p := &a[0] fmt.Printf("a[0] = %d pointer=%d, len=%d, cap=%d, p = %d \n", a[0], &a[0], len(a), cap(a), *p) a[0] = 2 fmt.Printf("a[0] = %d pointer=%d, len=%d, cap=%d, p = %d \n", a[0], &a[0], len(a), cap(a), *p) /* a[0] = 0, p = 0 a[0] = 2, p = 2 */ var c []int var d []int fmt.Printf("c len=%d, cap=%d \n", len(c), cap(c)) c = append(c, 0) d = append(d, 0) p2 := &c[0] fmt.Printf("a[0] = %d pointer=%d, len=%d, cap=%d, p2 = %d \n", c[0], &c[0], len(c), cap(c), *p2) c...
繼續閱讀

[UNIX][python][Golang][程式設計週記]20141227

前言: 今年年底到數第二週,可以開始深入研究一些自己有興趣的東西.本週主要研究signal的處理,regex與新程式語言RUST學習,當然其中也有一些新的MOOCs學習.加上這個禮拜週六要補班,所以整個內容應該會比較多一點. 筆記: [Unix]關於Signal PIPE 更深入的研究 前言: 雖然加上了signal pipe的handler但是並沒有真正的測試到類似的狀況. 這個禮拜應該會花一些時間好好的研究詳細的內容. 筆記: 關於Signal: signal就是去接受或是傳送process間的溝通方式.系統設定好,也比較為人所知的就是 SIGINT (就是ctrl + c), SIGTERM(process 結束)或是 SIGKILL(被 kill,不過系統預設是不能catch 這個signal). 而這裡探討的是如何把接受到signal要做的一些處理做起來.這裏有更多的說明. 如何處理Signal: 基本上會收到任何signal,表示你的程式正在收到不可預料的狀況(以系統的signal為例),但是無法明確的了解哪些問題的發生.通常會建議把一些資源回收後,準備重啟的相關動作. [12/22]關於測試sigaction 的部分: 可以使用 kill -s (signal) process_id 來傳送signal 不過並不是完全可以接收的到. 以下是接受的清單: SIGINT (02)(handle ctrl + c signal) SIGSEGV (11) SIGALRM (14) SIGTERM (15) SIGSTOP (17) SIGTSTP (18)(handle ctrl + z signal) 以下接收不到: SIGSYS (12) SIGPIPE (13) SIGCONT (19) [12/23]於是我把我發現的事情,整理過後試著去stackoverflow詢問.得到了回應是他們測試是可以的,可能是我底層元件出了問題. 經過測試真的如網友回應的,看來底層的元件有把SIG_PIPE收走,造成我在上層無法接收加以處理. 得繼續研究如何解決類似的問題….. [12/24]最後網友提出解決方式就是在3rd party library 後面去加入sigaction,這樣就可以了. 參考: 來自wiki常見的signal與指令的mapping 列出所有的signal 我的問題與回答 關於Linux signal programming 的簡介 #include #include #include #include void handle_pipe(int sig) { printf("SIG_PIPE happen, error code is %d", sig); exit(0); } int main(int argc, char **argv) { struct sigaction action; sigemptyset(&action.sa_mask); action.sa_handler = handle_pipe; action.sa_flags = 0; //not work sigaction(SIGPIPE, &action, NULL); //Not work with kill -13 process_id //works well sigaction(SIGINT, &action, NULL); //work with kill -2 process_id sigaction(SIGSEGV, &action, NULL); //work with kill -11 process_id sigaction(SIGALRM, &action, NULL); //work with kill -14 process_id sigaction(SIGSTOP, &action, NULL);...
繼續閱讀

[C][RUST][Python][Go]關於vector的push_back造成的記憶體參考(reference)問題

前言: 很基本的概念,是從RUST官方網頁在介紹他的記憶體管理的部分看到的.覺得是很有趣的vector與記憶體處理的問題,由於RUST有比對它的程式語言設計架構,於是很好奇地把其他手邊常用的程式語言找了一下相關的範例. 主要問題(C/C++/ObjectC) 主要是講解,說在vector裡面的記憶體管理其實有一些技巧.尤其是在push_back的部分,每次的push_back如果目前的大小超過他的容量,就會放棄目前的記憶體位址,而去建立一個新的vector記憶體.而原本的記憶體位置就沒使用變成了garbage. 如此一來會造成原本去參考v[0]的記憶體位置變成了garbage,而會crash. 這邊可以參考vector的push_back說明. 這裏在ObjectC與C/C++結果不同,他不會crash但是會沒值.(ObjectC原本設定概念) 在C/C++/ObjectC解決方式: 其實只要先把記憶體保留起來,就可以解決這樣的問題. vector.reserve(specific_size); #include #include #include int main(int argc, const char * argv[]) { //Init new vector here std::vector<std::string> v; //v.reserve(128); could resolve this issue, 128 is arbitrarily value. //Put first element "hello" v: "Hello" v.push_back("Hello"); // x refer to v[0] which is "Hello" std::string& x = v[0]; //Push new element but size will over capacity (default is zero, after first push become 1) //So whole memory will deprence and create new memory size =2 //Refer to http://en.cppreference.com/w/cpp/container/vector/push_back v.push_back("world"); // Old reference memory aleady become to garbage, so app crash (depends OS) std::cout << x; return 0; } </pre> **在RUST方面** - 根據[RUST官方網頁](http://www.rust-lang.org/)在介紹他的記憶體的管理方面,由於它定義兩種資料結構mutable 跟 let (這裏跟swift有點像).所以根據以下的程式碼,會造成編譯的時候不成功. fn main() { let mut v = vec![]; v.push("Hello"); //let x = &v[0]; Cannnot compile. because the mutable variable cannot assign to static value. let x = v[0].clone(); v.push("world"); println!("{}", x); } **在Python的部分** - 沒有找到比較像vector的資料結構,我使用list來使用.我也有用codeskulptor來查看[視覺化(Viz mode)](http://www.codeskulptor.org/viz/index.html)的結果. - 在python內有分成兩種方式來參照(reference),如果你參照的是unmutable通常是使用copy,如果是參照mutable就會使用bind.而且整個list變大也不會影響參照的變數....
繼續閱讀

[iOS][Python][unix][golang][程式設計週記] 工作上的一些雜事筆記20141219

前言: 在上完一個禮拜的Intel課程後,本週可以在辦公室專心做事情.可以專心的好好的把工作進度來超前一下.加上coursera的課程都上完了,應該可以有更多的時間可以好好的看看. 本週重點是學習iOS HealthKit 跟 etcd,當然還是有工作上管理伺服器的一些事情….. 筆記: [Unix] 如何增加一個客製化的服務(custom service) 前言: 新增一些伺服器,所以要把舊的伺服器上面的一些服務搬過來. 流程: 複製相關的shell script 到 /etc/default 與 /etc/init.d 這裡要注意,透過windows檔案複製的話會出現”/bin/sh^M : bad interpreter”,解決方式可以參考這裡. 要使用dos2unix 去轉換這些script 增加一些設定檔script到 /etc 記得用”initctl reload-configuration”把這些services重讀,參考這裡 [iOS] 關於錯誤“Capturing [an object] strongly in this block is likely to lead to a retain cycle” 前言: 因為HealthKit都在搞Async process所以經常在GCD的過程中去使用原先的self process,所以容易產生這個問題. 原因: 根據stackoverflow上面的解釋,主要原因是因為block會保留一份在裡面,如果保留的是self就會造成循環的持有. 解決方式: 加上以下的部分就可以了 __weak typeof(self) weakSelf = self; [someprocess setCompletionBlockWithSuccess:^(Operation *operation) { [weakSelf someOperationInSelf]; } [iOS] 關於IPWORKS整合 前言: 公司在用的3rd party component,不過每次整合都會忘記,紀錄一下. 步驟: copy IPWORKs, libSSL Add related framework: libz.dylib libssl.a libcrypto.a Add “Preprocessor Macros” in debug IPWORKS_MINSIZE INCLUDE_IPWORKS_XMPP Change “C++ compiler setting in Apple LLVM 6.0 - Language ++” C++ Language Dialect -> Compiler default. Standard Library -> Compiler default. [Go] 準備好好研究一下etcd 前言: 主要起因是因為這個一月份的Golang聚會,裡面有提到etcd很適合作為IOT(Internet Of Thing)的資料庫,所以打算開始survey.看看是不是真的能讓速度快一點. 筆記: 基本上etcd是一個相當快速的key pairing 資料庫,可以透過http直接存取. 其實發現etcd有以下的幾個優點: 可以透過http來讀取與存取. (讀取直接打網址,存可以用Put跟Post) 雖然是Key Pairing Database,但是還是存有index.所以可以記錄之前的資料.也可以透過wait=true達到key-value observing的效果. 參考: 一些關於python 使用etcd說明 在CoreOS裡面使用etcd的一些使用方式 中文簡介,有提到一些優點 etcd 官網 [iOS] 關於HealthKit的筆記 玩HealthKit到現在,其實有點困難必須得承認就是對於單位與測量數值的標準化. 簡單的說: 你想要量個血壓,你就得知道你要量血壓單位名稱.還有血壓數值一般轉換的方式. 舉例而言: 你現在需要量血壓,血壓有兩種數值收縮壓(Diastolic)與舒張壓(Systolic),這時候你需要知道以下一些東西: 舒張壓的資料型態(Type)是 HKQuantityTypeIdentifierBloodPressureDiastolic HKQuantityType *DiastolicType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureDiastolic]; 舒張壓的單位是(millimeter Of...
繼續閱讀