|Tools| Git v.s Repo

一般跟別人合作開發都是使用 git。那 repo 是什麼?
repo 是 Google 開發出來的工具,用來管理 Android 的。

一份 Android code 是由許多 project 組成的,每個 project 就是一個 git project。
repo 這個工具,就是可以管理 branches 以及眾多的 git project!

> repo init 後,可以找到 .repo/manifest.xml 這會記錄你控制的 projects


repo git
repo init -u URL -m ooxx.xml -b remote_branch git clone URL
repo sync -c git pull URL remote_branch:local_branch
repo start branch_name –all git branch branch_name
git status git status
git add git add
git commit git commit
repo upload . git push

*git 好用指令:
 > 查詢遠端的server 位置及名字
 git remote -v
 > 新增一個遠短 server
 git remote add {given_name} URL
 > 強迫 reset
 git reset –hard {local_branch}
 > 把 commit 推到遠端 branch
 git push {given_name} {local_branch}: refs/for/{remote_branch}
 > 從遠端 branch 拉 code 下來
 git pull {given_name} {remote_branch}:{local_branch}
 > 當前一個修改已 commit,又想把這次修改跟上一個修改一起 commit
 git commit –amend
 > 想上 patch 到某個已經 push 出去的 change
 git push {given_name} {local_branch}:refs/changes/{change_id}
 > 查詢某行的歷史
 git blame -L [行數] [檔案名]
 > 檢別 branch 的 commit 到目前的 branch
 git cherry-pick [sha-1]

 > git commit 的模板:
 新增一個  ~/.git-template
 然後 git config commit.template ~/.git-template

 > 設置reviewers, git push rest,就會自動帶上 reviewers
 到 .git/config 編輯
 [remote “test”]
 pushurl = ssh://account@server_address:port/project_name
 push = {local_branch}:refs/for/{remote_branch}%r=someone1@mail, r=someone2@mail

*製作 patch,打 patch
 (在 branch A)
 git log
 git format-patch -1 [sha-1]
 mv ooxx.patch ~/
 (換到 branch B)
 git am [~/ooxx.patch]

*把特定檔案還原到指定的 git log 時期的樣子
 git checkout {指定的 git log} {file name}

*如果沒有圖形化介面的 gitk,可用
  git log –oneline –graph

*查看現在 local branch 是從哪的 remote 抓來的
 cat .git/FETCH_HEAD

pull 的 server / review 的 server / push 的 server 可能不同,
設置 push 的 server 時,請去確認 repo upload 時,到底是推到哪?

ref. [Coding] repo & git 的使用方法

Featured post

|Python| cvs <-> json

From .csv to .json
The format of data.csv:
country, location, school_name,url

I save every row as a dictionary “row = {}”
And “data” is the list of dictionaries.

import json
import csv

data = []
with open('data.csv', newline='') as csvFile:
csvReader = csv.DictReader(csvFile)
for each in csvReader:
 row ={}
 row['country'] = each['country']
 row['location'] = each['location']
 row['name'] = each['name']
 row['url'] = each['url']

jsonFilePath = 'saved.json'
with open(jsonFilePath, 'w') as write_file:
 write_file.write(json.dumps(data, indent = 4))

From .json to data structions

The format of saved.json:
// saved.json
  ”country”: “US”,
  ”location”: “TX”,
  ”school”: “University of Texas”,
  ”url”: “https://ece.utdallas.edu/&#8221;
  ”country”: “US”,
  ”location”: “CA”,
  ”name”: “University of California”,
  ”url”: “”

I put the array as dictionary.
Hence, I pull every array of json_array, then put into tmp_dict.

import json

with open('saved.json', 'r') as input_file:
    json_array = json.load(input_file)

store_dict_as_list = []
for item in json_array:
    tmp_dict = {}
    tmp_dict['country'] = item['country']
    tmp_dict['location'] = item['location']
    tmp_dict['name'] = item['name']
    tmp_dict['url'] = item['url']

|Python| Make your Line Bot on Heroku

Making Line bot is very simple.
There are 3 parts.
1. Apply Line Message API
2. Apply Google sheet API (This is not necessary. )
3. Deploy your service on Heroku

I design a robot. Every user can ask some information.
Those information were collected by everyone and wrote on online google sheet.

My Demo LineBot app

There are some Heroku usage:
// After install CIL tool…
heroku login
// If you need to see the log of backend
heroku logs
// If you want to run commands on Heroku
heroku run {some cmd you want to use in backend}
heroku run ls
//If you want to do some regular job

You can NOT save file as running schedule job.
Heroku is IMMUTABLE.
You can not save file by your process.

1. for Line:
Line business
2. for Google:
Google console
3. deploy on Heroku

|Linux| what is the difference between subsys_initcall and module_init ?

1. > If you trace two macro, both macro will be replace by __define_initcall(fn, *).
Hence, we can know that subsys_initcall will run earlier than module_init after INIT deamon stars ( do_initcalls ).

2. >
subsys_initcall() can only be used by a built-in (statically linked) module.
module_init can be used by either built-in or loadable modules.
For loadable *.ko modules, subsys_initcall() is mapped to the same as module_init() i.e. device_initcall()
ONLY one module_init() per driver module.


|Design| Benefits of using Macro

What is the Macro?
If you write as “#define” in your code, that is “Macro” .

Macro will handle by the preprocessor.
You can think Macro as a method to replace the String which appears in you code..

– run faster than writing as function

– occupy memories

– there is no the concept of pointer in macro.
just “replacing the string”

An question:
What is the output of the following code?

#define macro_to_func(pp) ({printf("in Macro ...\n"); minus ;})

void do_something(int *a, int *b){
    int c;
    c = *a + *b;
    printf("do_something %d \n", c);

int minus(int *a, int *b){
    int c;
    c = *a - *b +1;
    printf("minus a = %d \n", *a);
    printf("minus b = %d \n", *b);
    printf("minus %d \n", c);
    return c;

int main()
    int (*do_something)(int* c, int* d);
    //printf("fptr 1 do_something %p\n", &do_something);

    int m = -1;
    int n = 7;

    printf("do_something = macro_to_func\n");
    do_something = macro_to_func(pp);
    //printf("fptr minus %p\n", &minus);
    //printf("fptr 2 do_something %p\n", &do_something);
        printf("in IF!!\n");
        do_something(&m, &n); --------------------------->???
    return 0;


do_something = macro_to_func
in Macro …
in IF!!
minus a = -1
minus b = 7
minus -7

“int (*do_something)” is a local function pointer.
In the macro, the macro_to_func will be replaced as “minus”, but do_something !!!

|Code| LLVM initial

One day, if you want to implement a module on the platform x86_64 for arm64, you will need to know the tool chain, “cross compiler”.
The famous modern compiler is LLVM.

Why should we understand the compiler?
– build for multi-platform
– improve the efficiency of your code
– …..

I have a conclusion for the developer whose library is under the user space.
Use suitable optimization provided by LLVM, and make your code readable.
Dazzle coding is meaningless.

你所不知道的 C 語言:編譯器和最佳化原理篇
[共筆] 不深不淺,帶你認識 LLVM
“編譯器 LLVM 淺淺玩” by Pokai Chang

|Jobs| Who is worthy of being called "Engineer" ?

The core competencies of engineer are
– never complain
– segmenting problems
hands-on problem solving
– not defeatist

You can win if you want.

If I am an interviewer, I just want to know ……
Will he/she want to solve problems?
Is he/she a defeatism?
Will he/she look down on other fields?
I don’t like whom disregard others.
It means he/she ignore details in him/her life.

|LTE| 開啟行動上網 ……

若想知道更多,可利用 > 後的關鍵字去做搜尋。

我們一開機,不是在飛航模式 ……
– UE 會向 NW 做 “initial attach”
> RRC connection (手機告訴網路說:我想要連線啦~基地台快醒來服務我)
> Attach request (我要送東西ㄛ~大概是一個包裹的大小,
> EMM 通知後端網路及認證 (電信商的櫃台忙著聯絡服務中心)
> RRC reconfiguration (開始配送貨車來服務客人送貨)


– Initial attach 之後,表示 UE 已經向網路拿到派發的 IP
– 這時候手機裡的 data service 會向 modem 取得 IP address
– 設定 Linux 裡的 “rmnet_data”、”DNS” ……
但還沒有要送封包出去哦 ……

開始要送封包 ……
封包從 APP 開始,會經過:
– IP
– rmnet driver 走出去到網路端啦~
The packet flow, from userspace to kernel driver in Linux network stack


LTE initial attach

|Jobs| How can operators detect tethering?

出國玩,買 SIM卡 一定要注意,這張卡是否能夠當作 WiFi hotspot 分享給別人,


在某次出差 (2017),我發現,電信業者是有能力知道這張 SIM卡是否有能力 WiFi hotspot,並且禁止這張卡做分享。

我一直以為是 framework 的行為(軟體端去擋),但是我做了一些實驗,發現電信商是可以控制的。(最近的新案子也有談到類似的東西)



How can phone companies detect tethering (incl. Wifi hotspot)

  1. Your phone tells your network that you are tethering
  2. Inspecting the network packets for their TTL (time to live)
  3. MAC address inspection
  4. TCP/IP Stack Fingerprinting
  5. Looking at the Destination IP/URL


電信商可以利用Tether Guard的機制來得知。基本上,你要用APN:dun建立連線才能 tethering給別人,



Tethering on UK Networks: Which Mobile Networks Allow You To Tether?


Up ↑