[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...
繼續閱讀

[iOS] HealthKit的初體驗..

前言: 最近開始仔細瞭解HealthKit,發現使用上並沒有那麼的直覺.(可能是我對於許多醫療單位沒有那麼清楚的關係 XD) 使用上有一些要注意的與需要瞭解的部分,稍微做一些紀錄. 筆記: [基本概念] 到目前為止,HealthKit只有iPhone可以用,並且要有iOS8.所以iPad執行程式會失敗. 每一個資料有所屬的資料格式數量(HKQuantity)與該數量的格式(HKQuantityType),而數量(Quantity)本身與單位的格式(HKUnit)有關. 必須要清楚地瞭解,存取的資料數量單位與單位的格式. 比如說,身高要確認是用cm還是inch,體重是使用pound還是kg. 每一個存取都與使用者權限有關,去拿使用者不開放的資料,就會引發錯誤. 所有的動作都是Async的方式: 這邊比較麻煩的是,如果需要抽象化的話可能要把async改成sync這邊可以參考這邊的內容. [基本資料欄位] 關於資料欄位舉例而言,要敘述關於血壓的舒張壓,你就得要撰寫以下的部分: //敘述你的血壓單位是 mmag mullumeter of mercyry unit HKUnit *BPUnit = [HKUnit millimeterOfMercuryUnit]; //透過這個HKUnit去建立單位 HKQuantity HKQuantity *BPSystolicQuantity = [HKQuantity quantityWithUnit:BPUnit doubleValue:SIS]; // 透過建立的單位與數值來建立這個單位類型(HKQuantityType) HKQuantityType *BPSystolicType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodPressureSystolic]; [取得使用者權限] 上面的方式僅僅是拿來作為處理資料欄位而已,接下來要開始去跟HealthKit查詢資料.在查詢資料之前,由於HealthKit上的資料都是儲存在手機上面,屬於個人私密資料.需要取得使用者的權限. //取出體重單位格式 HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass]; //取出身高單位格式 HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight]; // 將身高體重加入要求的權限集合,這裡有分"讀取"與"寫入"的集合 NSSet *writeDataTypes = [NSSet setWithObjects:heightType, weightType, nil]; NSSet *readDataTypes = [NSSet setWithObjects:heightType, weightType, nil]; // 確認HealthKit 存不存在,這裡如果還是iPad 是不會有的,請注意. if ([HKHealthStore isHealthDataAvailable]) { // 要求使用者同意 [self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) { if (!success) { NSLog(@"You didn't allow HealthKit to access these read/write data types. In your app, try to handle this error gracefully when a user decides not to provide access. The error was: %@. If you're using a simulator, try it on a device.", error); return; } //處理成功以後,可能需要的資料讀取部分. }]; } [讀取資料] 關於讀取資料這邊,需要注意的就是必須要取得正確的單位. 還是一樣,讀到資料以後是async,所以可以用另外的thread來更新UI 以下提供取得”心跳(Heart Rate)”的方式 //心跳屬於複合資料欄位,需要用字串來找到HKUnit.文件不好找到. HKUnit *dataUnit = [HKUnit unitFromString:@"count/min"];...
繼續閱讀