2019年12月22日 星期日

[LeetCode] 50. Pow(x, n)

我覺得這題應該算Easy,

如果說歸在Medium的原因,

應該是看你能不能一次把Edge Case考慮到位.


題目很單純,

給定x, 輸出x的n次方

大致上需要考慮的Edge Case:

n = 0的情況

x = 1 or x = -1

跟平方的結果overflow的情況.

2019年12月20日 星期五

sqrt(x)的實作方法

A tour of Go裡面學到的

給定一個值x, 找出z, 使得z平方最接近x
(找出x的平方根)

裡面提到可以運用Newton's Method

z -= (z * z - x) / (2 * z)

z從1開始猜,
跑個十次, 每次的值會越來越接近x

double sqrt(int x) {
    double z = 1;
    for (int i = 0; i < 10; ++i) {
        z -= (z * z - x) / (2 * z)
    }
    return z;
}

2019年12月19日 星期四

關於shared library

Compile Time:
編譯時系統預設會從/lib, /usr/lib尋找so檔.

但如果你的so檔不在預設目錄裡面,
就必須指定, ex:
g++ -L /usr/local/lib -I /usr/local/include test.cc -lfoo -o test

-l: 程式會用到libfoo.so這個library
-L: 從/usr/local/lib位置尋找library
-I:  從/usr/local/include位置尋找header

Runtime:
執行時找不到library的情況

1. LD_LIBRARY_PATH
設定後會從這個目錄找library, ex:
LD_LIBRARY_PATH=/usr/local/lib test

指定目錄後執行test

2. 添加系統預設搜尋目錄
在/etc/ld.so.conf裡面添加目錄
然後執行sudo ldconfig更新目錄cache

接著再執行test

3. 編譯時加入rpath選項
rpath可以指定執行時搜尋目錄
g++ -L /usr/local/lib -I /usr/local/include -Wl,-rpath=/usr/local/lib test.cc -lfoo -o test

2019年12月16日 星期一

在Yocto啟動ICECC Distributed Compiler

安裝icecc
$ apt install icecc
會裝icecc跟icecc-scheduler

在區網中找一台啟動icecc-scheduler
其他啟動iceccd

在local.conf裡面加入
# Support icecc
ICECC_PARALLEL_MAKE = "-j 24"
INHERIT += "icecc"

就ok了

2019年11月22日 星期五

[LeetCode] 77. Combinations

題目:
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.

Example:
Input: n = 4, k = 2
Output:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
思路:
用遞迴的方式, 從後面排回來
12
13
   -> 23
14
   -> 24
   -> 34

n = 4, k = 3
123
124
   -> 134
           -> 234

https://gist.github.com/richardneko/6870d498e3916733728917b0d9c8ba7f






[LeetCode] 46. Permutations

題目:
Given a collection of distinct integers, return all possible permutations.

Example:
Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
思路:
從1開始排
1

接著2可以插在1的前面或後面, 兩種排列方式
12
21

最後3可以分別插入12和21前中後的位置
12
312
132
123

21
321
231
213

https://gist.github.com/richardneko/8ec0f82967460a6c2a4bdc0740269164

僅為自己刷完題後的紀錄, 不一定是最佳解...

2019年10月27日 星期日

Dump MySQL database and diff

加入--slip-out, 輸出為方便diff的格式

mysqldump --skip-opt -u $MY_USER -p$MY_PASS mydb1 > /tmp/dump1.sql
mysqldump --skip-opt -u $MY_USER -p$MY_PASS mydb2 > /tmp/dump2.sql

修復MySQL無法啟動的問題

在備用的server上發現MySQL無法啟動

從mysql error log (/var/log/mysql/mysql/error.log)
看起來有可能是資料毀損

補救方式:
1. 先使用recovery mode啟動:
    /etc/mysql/my.cnf裡面加入innodb_force_recovery = 1
2. 啟動MySQL:
    $ service mysql start
    如果還是啟動失敗就修改my.cnf的值, ex:
    innodb_force_recovery = 2, 再啟動看看
    依照毀損的嚴重程度最多加到6
3. Dump database的SQL
    mysqldump -u 'name' -p -A > dump.sql
4. 關閉MySQL:
    $ service mysql stop
5. 把舊的資料庫內容刪除(最好先備份)
    $ cd /var/lib/mysql
    $ rm ib*
    $ rm -rf [DATABASE_NAME]
6. 在my.cnf裡面將innodb_force_recovery = 1移除
    啟動MySQL
7. 將dump的資料庫寫回去:
    $ mysql -u 'name' -p < dump.sql
8. 寫入途中, 修正所有發生的error
9. service mysql restart
10. 啟動成功

不過要注意的時,修正途中可能造成資料遺失
必須看看怎麼補救

Ref:
https://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html

2019年10月1日 星期二

使用cURL取得Google搜尋結果

Google最簡單的搜尋Pattern:
比如說我想搜尋nintendo switch,
https://www.google.com/search?q=nintendo+switch

但如果直接使用curl:
curl "https://www.google.com/search?q=nintendo+switch"
會出現錯誤

需要加上User Agent, 如下:
curl -A 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0' "https://www.google.com/search?q=nintendo+switch"

就可以產生搜尋的結果了

Get and push AOSP projects to local Gerrit server

1. Get Git MIRROR from AOSP
$ mkdir aosp_mirror
$ repo init -u https://android.googlesource.com/platform/manifest --mirror
$ repo sync


2. Create a project as parent in Gerrit of all other AOSP projects
2.a. In Gerrit Web UI, Browse->Repositories-> Create New
2.b. Set "Only server as parent for other repositories" to true


3. Create groups to manage access of your project
3.a. Browse->Groups->Create New
3.b. Create 2 groups, android10-admin, android10-user


4. Add your group to access Android10 project
4.a. Browse->Repository->AOSP
4.b. Click access on left tab
4.c. Modify it as you want


5. Add projects to Gerrit
5.a. Add projects to Gerrit
$ repo forall -c 'echo $REPO_PROJECT; ssh -p 29418 admin@10.10.10.10 gerrit create-project --owner android10-admin Android10/$REPO_PROJECT;'

5.b. Add parent project of added projects
$ repo forall -c 'echo $REPO_PROJECT; ssh -p 29418 admin@10.10.10.10 gerrit set-project-parent --parent AOSP Android10/$REPO_PROJECT;' 

2019年8月27日 星期二

Error while loading shared libraries: libxxx.so.3: cannot open shared object file: No such file or directory

Typically, it will check /lib, /usr/lib as default library folder while running.

But if your program is using library from another folder,
you should specify it use -L option in gcc:
gcc -Wall hello.c -L/usr/local/lib/x86_64-linux-gnu -lhello -o hello

It will load libhello.so in /usr/local/lib/x86_64-linux-gnu folder

But I still get error after running above command.
To fix it:
$ sudo ldconfig /usr/local/lib/x86_64-linux-gnu

Then build again, it can run successfully.

2019年8月26日 星期一

Install pip3 on ubuntu16.04

1. Get get-pip.py on https://bootstrap.pypa.io/get-pip.py

2. Run sudo python3.5 get-pip.py --prefix=/usr/local/
    It will install pip packages in /usr/local folder

3. Then you can check packages are up-to-date by command:
    pip install --upgrade pip setuptools wheel

Reference:
https://packaging.python.org/tutorials/installing-packages/#requirements-for-installing-packages

2019年8月19日 星期一

Usage of Linux csplit

csplit是將一個文件分成數個小區塊的工具

如果有個檔案text內容為:
  Title 1
  aaa
  bbb

  Title 2
  ccc
  ddd

  Title 3
  eee
  fff

想根據"Title"來分段:
$ csplit text -s -f title -b "%02d.log" /Title/ {*}

-s: 靜默模式
-f: 產生的檔名的前綴, 這邊為titlexxx
-b: 產生的檔名的後綴, 這邊為xxx00.log
/Title/: Parse用來分段的pattern
{*}: 執行pattern的次數, {1}為找一次, *為找到沒有為止

執行結束後會產生幾個檔案:
title00.log title01.log title02.log title03.log

通常會發現第一個檔案(title00.log)是空的
因為第一個檔案存的是第一個Title之前的資料,
如果text內容如下:
  zzz
  Title 1
  aaa
  bbb
  ...

那title00.log內容就會是zzz

其他依序如下
title01.log:
  aaa
  bbb

title02.log:
  ccc
  ddd

title03.log:
  eee
  fff

注意檔案內容不會包含pattern

2019年8月3日 星期六

[工作] Setup docker image時出現no space

最近發現在setup docker時會出現no space然後失敗

稍微查了一下發現
docker setup後會存放在/var/lib/docker目錄下
這個目錄占了我大概70G的空間(setup許多docker的結果)
而我的kernel只分配100G左右
幾乎被占滿了

目前好像沒有好方法
只能盡量把沒用到的image刪一刪了

還有之後有用docker的話
重新建系統可能考慮把root空間加大了

2019年7月23日 星期二

[工作] iSCSI配置 並搭配OCFS2達到多台共享

前陣子實驗了一下iSCSI, 做個筆記
以下都是最陽春的配置

iSCSI主要分為target跟initiator
iSCSI target: 分享空間資源(server)
  Package: sudo apt install tgt

iSCSI initiator: 連到target並且使用資源(client)
  Package: sudo apt install open-iscsi

Target配置:
裝完package後, 修改config
# vim /etc/tgt/targets.conf

ex.
<target iqn.2019-07.ric.builder1:builderiscsi>  
    backing-store /dev/nvme0n1   
</target>

這裡我使用的iqn為: iqn.2019-07.ric.builder1:builderiscsi
並且加入一顆磁碟到target

然後重啟服務
# systemctl restart tgt

使用command查看狀態, 看看新增的target有沒有被加入
(同常為LUN1 ~ LUNX)
#tgt-admin --show

沒問題的話target設定完成

Ininiator配置:
一樣裝完package後, 修改config
修改initiator的iqn, 每個initiator必須唯一
# vim /etc/iscsi/initiatorname.iscsi

ex.
InitiatorName=iqn.2019-07.ric:iscsi

接下來做discovery, 偵測target
# iscsiadm -m discovery -t sendtargets -p 192.168.100.254
192.168.100.254:3260,1  iqn.2019-07.ric.builder1:builderiscsi

偵測完後開始進行連線
# iscsiadm -m node -T iqn.2019-07.ric.builder1:builderiscsi --login

登入後cat /proc/partition或是fdisk -l會看到多的device,
可以對它做fdisk跟mkfs, 切partition跟建立filesystem
注意第一台initiator做完之後其他台就不用做了

接下來就能使用這個檔案系統了
ex.
mount /dev/sdb1 /mnt/test

使用上有幾個問題:
1. initiatorA新增檔案後, initiatorB並不會馬上看到檔案,
    需要umount後再mount才看得到
2. initiatorA跟initiatorB同時寫入檔案,
    有很大的機會發生檔案毀損

因為SAN本身設計並不是用來共享檔案的,
iSCSI意思是SCSI protocol over IP,
對每個initiator來說就是多一個SCSI硬碟做讀寫,
並不會知道其他initiator做了什麼事

解決方案: 透過clustered filesystem
這裡透過OCFS2來處理,
OCFS2透過daemon監控每個node的狀態,
達到node間同步跟避免同時寫入時造成毀損

Package: ocfs2-tools ocfs2-tools-dev

裝完package後, 一樣編輯config
# vim /etc/ocfs2/cluster.conf
ex.
cluster:
        node_count = 2
        name = ocfs2

node:
        number = 0
        cluster = ocfs2
        ip_port = 7777
        ip_address = 192.168.100.2
        name = machine1

node:
        number = 1
        cluster = ocfs2
        ip_port = 7777
        ip_address = 192.168.100.3
        name = machine2

其中name必須與cat /etc/hostname一樣

編輯完後啟動o2cb
# service o2cb load
# service o2cb configure
# service o2cb online

接著建立掛載ocfs2檔案系統
mkfs.ocfs2 /dev/sdb1
mount -t ocfs2 /dev/sdb1 /mnt/test

在每一台initiator都做一樣的動作(mkfs只須做一次)
可以試著在initiatorA建立檔案測試
然後看initiatorB是否立即同步

這方式可以達到同步跟同時寫入
不過缺點是OCFS2不支援overlayfs upper...

參考資料:
http://www.voidcn.com/article/p-wmzavzze-xe.html
https://blog.51cto.com/nosmoking/1873507
http://linux.vbird.org/linux_server/0460iscsi.php#server















2019年6月25日 星期二

[工作] Android從bootloader直接進edl的方式

fastboot erase sbl1
fastboot reboot

開機後因為sbl1 partition不見,
系統會直接進edl

平台為Qcom的8909, 滿舊的.
不知道較新的平台適不適用就是了.

[工作] Jenkins資料備份方式

預設Jenkins的資料放在home目錄的.jenkins下

所以備份只要把.jenkins用tar保存起來就好

$ tar zcvf jenkins-backup.tgz .jenkins/* --exclude=./war

就算你的Jenkins重新安裝, 只要把檔案解壓縮回去.jenkins,

資料也會馬上回復.

2019年6月11日 星期二

[工作] Ubuntu增加一個開機執行的service的方式

Ubuntu 16.04後使用systemd控管service,
user可以透過systemctl控管.

想增加自己的service,
先新增.service檔案在/lib/systemd/system下

ex.
/lib/systemd/system/myservice.service

一個基本的service的內容為
[Unit]
Description=nfsmount

[Service]
Type=simple
ExecStart=/bin/bash /usr/bin/myservice
ExecStop=/bin/kill -s QUIT $MAINPID

[Install]
WantedBy=multi-user.target

ExecStart為開後或執行systemctl start nfsmount後對應的
ExecStop為執行systemctl stop nfsmount

完成之後執行
systemctl enable nfsmount.service
systemctl daemon-reload

之後每次開機後就會執行你的service

2019年4月15日 星期一

[工作] vim分頁的一些用法

1. 將其中一個頁面用新分頁開啟
    a. 看目前分頁的編號
:ls
  1  a   "src/java/com/android/internal/telephony/PhoneSubInfoController.java" line 0
  2  a   "src/java/com/android/internal/telephony/Phone.java" line 0
  3  a   "src/java/com/android/internal/telephony/PhoneFactory.java" line 0
  5 #a   "src/java/com/android/internal/telephony/RIL.java" line 89
  6 %a   "src/java/com/android/internal/telephony/GsmCdmaPhone.java" line 1

找到要開啟新分頁的編號, 然後
:tab sb 6

將編號6的頁面用新分頁開啟

2. 保存現在開啟的所有分頁, 並在下次全部開回來
保存
:mksession [session_file_name]

重開
:source [session_file_name]

2019年3月21日 星期四

[工作] Ubuntu下讓user使用sudo command不需要密碼

修改/etc/sudoers檔案, 文件建議使用visudo修改

$ sudo visudo

然後加入:
username     ALL = NOPASSWD: /bin/mount, /bin/umount

這樣之後那個user下sudo mount/sudo umount都不需要再輸入密碼.

如果要讓所有command都不用密碼:
username     ALL = NOPASSWD: ALL

修改完之後儲存, 登出再登入後生效.

2019年3月11日 星期一

[工作] Linux shell: Here document用法 (cat << EOF)

在shell裡面看到usage的用法:
cat >&2 <<- _USAGE_
Usage:
    aaa
    bbb
    ccc
_USAGE_

意思就是把第一個_USAGE_後面所有文字都導到&2(錯誤輸出)去,
直到第二個_USAGE_為止.

也可以導到檔案裡面:
cat >output.txt <<- _USAGE_
Usage:
    aaa
    bbb
    ccc
_USAGE_

2019年3月10日 星期日

[工作] multi-user環境build Android N/O時遇到jack的相關問題

根據這篇
jack基本上不支援multi-user build code,
而且因為有許多問題,
Android P跟之後的版本已經拿掉了.

主要問題發生在build machine上,
UserA成功build完一版,
UserB也想要build, 會發生jack error.

主因是UserA build的時候, launch jack server, 佔用8076 & 8077 port,
UserB要build的時候, 會再launch一次, 發現port已經被佔走了, 產生error.

目前只能用workaround的方式cover.
在error之後,
到$HOME/.jack-server/config.properties裡面把port改掉:
jack.server.service.port=8086
jack.server.admin.port=8087

然後$HOME/.jack-settings也改:
SERVER_PORT_SERVICE=8086
SERVER_PORT_ADMIN=8087

再重新build, 就可以了.

ps. .jack-server, .jack-settings會再build的途中, start jack時產生.

2019年2月28日 星期四

[工作] Data Structure & Algorithm

Big O比較
n! > 2^n > n^2 > n log n > n > log n > 1

Stack: push / pop O(1)
Queue: add / remove O(1)

Binary Search Tree
find: O(log n)

2019年2月27日 星期三

[工作] 六年來工作心得

目前在系統廠擔任軟體RD六年
福利還算不錯
工作很單純
身邊同事也都很好相處

目前工作大概是
改改Android BSP (From Qualcomm or Intel)
跟vendor要driver, 改改driver
跟HW debug
有問題call vendor解決

一般幾乎寫不到什麼code
driver也大都是改個i2c address, GPIO number之類的

但心裡總是想做的更多

有試著面試過幾間外商公司
不知道是不是目標放得太高(聊過Dell, nVidia, Google...等等)
總是覺得力不從心
許多問題都答不上來

系統廠摸到的東西真的太廣
audio, camera, sensor, touch, power management幾乎都碰過
但是就是沒有一樣能專精

在目前的工作上
能力是受到肯定的
案子assign的task都能馬上處理完
處理完後多的時間也會協助需要幫忙的同事
沒有的話就自己充實
遇到困難的bug也都能找到方法處理
後來其他同事bug無法處理主管都會請我幫忙

也難得的有能自己implement code的機會
在遇過的案子中
有開發過整個Android service的機會
也有開發過整個driver, 並且與上層溝通
做完之後真的非常有成就感
我想我工作就是為了這個吧
但在系統廠中真的很少有這種機會

每次與主管面談時
得到的都是讚賞
分紅最多, 加薪最多, 會升最快等等

但是出去面試聊過之後
覺得自己真的是非常非常不足
真的很不想要只是拿別人的code來改
想自己能有更多寫code的機會
想得到更多

所以我想還是要繼續充實自己
希望今年能成功轉到能讓我得到更多成就感的公司

















2019年2月19日 星期二

[工作] Execute docker command without sudo

You should add your user to your docker group:
  sudo usermod -aG docker your-user

Then logout and login to take effect.