git ローカルブランチの整理方法
マージ済みのブランチを抽出して一括で削除する
$ git checkout master && git branch --merged | grep -v '*' | xargs -I % git branch -d %
Compute EngineのインスタンスにGUIを追加
実現したいこと
GCEのインスタンスにGUIをインストールして、ローカルPCからGUIで操作する
やり方
GCEにSSHしてから、コマンド実行
$ sudo apt-get update
$ sudo apt-get install gnome-core
sudo apt-get install gnome-panel
sudo apt-get install vnc4server
tcp:5901のポートを開ける
Finder → 移動 → サーバーへ接続 → vnc://IPAdress:5901を入力して接続する
VNCの解像度変更
sudo vi /usr/bin/vncserver
して、$geometry = "1280x800";
の値を変更。
gnomeのショートカット変更
defaultの設定だと、s,hなどキーがショートカットになるため、文字入力ができない。
gnomeのショートカットキーの修正 export DISPLAY=:1 gsettings set org.gnome.desktop.wm.keybindings show-desktop "['<Shift><Alt>F1']"; gsettings set org.gnome.desktop.wm.keybindings maximize "['<Primary><Super>Up','<Alt>KP_5']"; gsettings set org.gnome.desktop.wm.keybindings panel-main-menu "['<Alt>F1']"; gsettings set org.gnome.desktop.wm.keybindings minimize "['<Primary><Super>Down','<Alt>F5']";
Google Cloud Platform タスクキューの利用
タスクキューは色々便利。
タスクはApp Engineのアプリとして動作する。
利用イメージ
- 時間のかかる処理をタスクとしてタスクキューに登録する。
- タスクキューはタスク(API)を呼ぶ。
- タスクが処理される。
利点
- 非同期処理が可能。
- リトライが可能。
go言語の指针 & *
Go语言保留着C中值和指针的区别,但是对于指针繁琐用法进行了大量的简化,引入引用的概念。所以在Go语言中,你几乎不用担心会因为直接操作内寸而引起各式各样的错误。Go语言的指针,基本上只剩下用于区分 byref 和 byval 语义。
运算符就是简单的 & 和 * 一个取地址、一个解析地址。
package main
import(
"fmt"
)
func main(){
var i int // i 的类型是int型
i=1 // i 的值为 1;
var p *int // p 的类型是[int型的指针]
p=&i // p 的值为 [i的地址]
fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p)
*p=2 // *p 的值为 [[i的地址]的指针] (其实就是i嘛),这行代码也就等价于 i = 2
fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p)
i=3 // 验证想法
fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p)
}
这段代码执行结果:
i=1;p=0x4212f100;*p=1
i=2;p=0x4212f100;*p=2
i=3;p=0x4212f100;*p=3
函数的参数传递可以看下面例子:
package main
import "fmt"
type abc struct{
v int
}
func (a abc)aaaa(){ //传入的是值,而不是引用
a.v=1
fmt.Printf("1:%d\n",a.v)
}
func (a *abc)bbbb(){ //传入的是引用,而不是值
fmt.Printf("2:%d\n",a.v)
a.v=2
fmt.Printf("3:%d\n",a.v)
}
func (a *abc)cccc(){ //传入的是引用,而不是值
fmt.Printf("4:%d\n",a.v)
}
func main(){
aobj:=abc{} //new(abc);
aobj.aaaa()
aobj.bbbb()
aobj.cccc()
}
输出结果:
1:1
2:0
3:2
4:2
传值与传指针
当我们传一个参数值到被调用函数里面时,实际上是传了这个值的一份copy,当在被调用函数中修改参数值的时候,调用函数中相应实参不会发生任何变化,因为数值变化只作用在copy上。
传指针比较轻量级 (8bytes),只是传内存地址,我们可以用指针传递体积大的结构体。如果用参数值传递的话, 在每次copy上面就会花费相对较多的系统开销(内存和时间)。所以当你要传递大的结构体的时候,用指针是一个明智的选择。
Go语言中string,slice,map这三种类型的实现机制类似指针,所以可以直接传递,而不用取地址后传递指针。(注:若函数需改变slice的长度,则仍需要取地址传递指针)
要访问指针 p 指向的结构体中某个元素 x,不需要显式地使用 * 运算,可以直接 p.x ;
一个稍微复杂的例子
package main
import "fmt"
type S map[string][]string
func Summary(paramstring)(s*S){
s=&S{
"name":[]string{param},
"profession":[]string{"Javaprogrammer","ProjectManager"},
"interest(lang)":[]string{"Clojure","Python","Go"},
"focus(project)":[]string{"UE","AgileMethodology","SoftwareEngineering"},
"hobby(life)":[]string{"Basketball","Movies","Travel"},
}
return s
}
func main(){
s:=Summary("Harry")
fmt.Printf("Summary(address):%v\r\n",s)
fmt.Printf("Summary(content):%v\r\n",*s)
}
输出:
Summary(address): 0x42131100
Summary(content): map[profession:[Java programmer Project Manager] interest(lang):[Clojure Python Go] hobby(life):[Basketball Movies Travel] name:[Harry] focus(project):[UE Agile Methodology Software Engineering]]
exit code 0, process exited normally.
参考资料:
使用Go语言一段时间的感受
http://blog.jobbole.com/14386/
[Go 语言] 指针,地址,形参,实参
http://my.oschina.net/nalan/blog/77373
从例子中学习 go 语言 —— 数据结构、指针
http://ilovers.sinaapp.com/drupal/node/33
Google App EngineにGoのWebAppをデプロイするために、いろいろ調査
Users API
Users Go API Overview | App Engine standard environment for Go | Google Cloud Platform
Users APIで何ができる?
- ログイン中のuserを確認する
- 認証用のページへユーザを誘導。(redirect)
- Googleアカウントを持ってないユーザに新しいアカウントを作ってもらったり。
ユーザ認証
認証済の場合、ログアウト用のURLを取得し、ページに表示させる。 未認証の場合、ログイン用のURLを取得し、ページに表示させる。
import ( "fmt" "net/http" "google.golang.org/appengine" "google.golang.org/appengine/user" ) func welcome(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-type", "text/html; charset=utf-8") ctx := appengine.NewContext(r) u := user.Current(ctx) if u == nil { url, _ := user.LoginURL(ctx, "/") fmt.Fprintf(w, `<a href="%s">Sign in or register</a>`, url) return } url, _ := user.LogoutURL(ctx, "/") fmt.Fprintf(w, `Welcome, %s! (<a href="%s">sign out</a>)`, u, url) }
管理者としての登録を強制させる
登録必須のページが存在する場合、app.yamlを利用して、ユーザに強制登録してもらうことが可能。
必要なロールなどを設定に任せば、認証メカニズムを独自に実装しなて済む。
詳細はyamlの設定を参照。
app.yaml Reference | App Engine standard environment for Go | Google Cloud Platform
OAuthの利用
標準ユーザ認証以外に、OAuthを利用することも可能。
※OAuthは認証プロトコルで、ユーザは第三者(アプリケーション)に許可を与えることで第三者がユーザの情報にアクセスできる。
import ( "fmt" "net/http" "google.golang.org/appengine" "google.golang.org/appengine/user" ) func welcomeOAuth(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) u, err := user.CurrentOAuth(ctx, "") if err != nil { http.Error(w, "OAuth Authorization header required", http.StatusUnauthorized) return } if !u.Admin { http.Error(w, "Admin login only", http.StatusUnauthorized) return } fmt.Fprintf(w, `Welcome, admin user %s!`, u) }
認証のoptions
認証方法を選択することも可能。(設定変更することで)以下の方法がある。
Googleアカウントと開発サーバー
開発サーバーのシミュレーターはダミーの認証を提供する。これを利用すればユーザ認証、管理者認証のテストが容易にできる。
Android GridViewのItemの背景を変える
簡単かと思ったが、やってみたらけっこうはまった。
やり方
ArryAdapterにitemのlayoutを設定、itemのbackgroundにtextViewの背景を変更するselectorを設定。
ハマったところ
selected状態に色を変えたくて、android:state_selected
を設定してもぜんぜん効かない。
なんと、android:state_activated
に変えたらいけた。
ソース
ArrayAdapter<RoomBean> adapter = new ArrayAdapter<>(getApplicationContext(), R.layout.grid_room_item, result); gridView.setAdapter(adapter); gridView.setChoiceMode(GridView.CHOICE_MODE_SINGLE); gridView.setItemChecked(0, true);
<GridView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="0.17" android:id="@+id/gridViewRoom" android:numColumns="3" android:layout_marginTop="10dp" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" android:padding="10dp" android:background="#999999" android:listSelector="@android:drawable/list_selector_background"> </GridView>
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="match_parent" android:textSize="30sp" android:padding="20dp" android:background="@drawable/item_room_selector" android:text="TextView" />
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" > <shape android:shape="rectangle"> <solid android:color="@color/LightBlue" /> </shape> </item> <item android:state_pressed="true" > <shape android:shape="rectangle"> <solid android:color="@color/LightBlue" /> </shape> </item> <item> <shape android:shape="rectangle"> <solid android:color="@color/White" /> </shape> </item> </selector>
LinearLayoutの中のボタンをbottomに表示させる
androidのlayoutを理解してないまま、gravityとかでやってみたが、 だめだった。
結局、開けたいスペースにSpaceを入れて高さがいっぱいまで設定したらうまくいった。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- Other views --> <Space android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <!-- Target view below --> <View android:layout_width="match_parent" android:layout_height="wrap_content"> </LinearLayout>