20 Apr 2023
Go 內建的 map 不具有 thread-safe 的特性,例如執行以下程式碼多次,有時候會成功,但大多時間會出現 concurrent map writes
的錯誤:
package main
import (
"fmt"
"sync"
)
func main() {
var m = map[int]int{}
wg := sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
m[i%5]++
fmt.Println(m)
wg.Done()
}(i)
}
wg.Wait()
}
改善方法:使用 sync.Mutex 或是 sync.RWMutex,來將正在被操作的 map 鎖住。例如以下:
package main
import (
"fmt"
"sync"
)
type m struct {
sync.Mutex
m map[int]int
}
func (m *m) Get(key int) int {
m.Lock()
a := m.m[key]
m.Unlock()
return a
}
func (m *m) Put(key, value int) {
m.Lock()
m.m[key] = value
m.Unlock()
}
func (m *m) Range(f func(k, v int)) {
m.Lock()
for k, v := range m.m {
f(k, v)
}
m.Unlock()
}
func main() {
var mm m
mm = m{m: make(map[int]int)}
wg := sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
mm.Put(i, i%5)
fmt.Println(mm.Get(i))
wg.Done()
}(i)
}
wg.Wait()
}
另外,Go 在 1.9 後的版本引入一個結構叫做 sync.Map
。這個結構的 method 包括以下:
- Load : 用給定的 key 從 map 中取出 value
- Store : 將給定的 key 在 map 中的值設為傳入的 value
- Delete : 移除給定的 key 在 map 中的 entry
以及 LoadAndDelete、LoadOrStore、Range、Swap 等。
範例如下:
package main
import (
"fmt"
"sync"
)
func main() {
var m = sync.Map{}
var wg = sync.WaitGroup{}
wg.Add(1000)
for i := 0; i < 1000; i++ {
go func(i int) {
m.LoadOrStore(i, i)
wg.Done()
}(i)
}
wg.Wait()
i := 0
m.Range(func(k, v interface{}) bool {
i++
return true
})
fmt.Println(i)
}
14 Mar 2023
在有大小標題的情況下,notion 有內建的方法幫助使用者快速建立目錄:
- 在想建立目錄的地方使用命令 /toc
- 在想建立目錄的地方點擊「+」,在 Advanced blocks 欄位下找到 Table of Content,點下去
資料來源
28 Feb 2023
之前在已經有 Windows 系統的電腦安裝了 Ubuntu 雙系統,這邊做的筆記記錄一下!
檢查
- 按下 Win + R 兩個按鍵,並輸入 msinfo32
- 找到 BIOS 模式的欄位,查看值是不是 UEFI
- 不是的話不適用本篇教學
準備工作
- 準備 8GB 以上的空USB
- 下載 Ubuntu ISO (不用放進 USB)
- 分割磁碟,分出一個大於 60GB 的空間
建立 Bootable USB
- 安裝 Rufus
- 照著官方指南操作
開始操作
- Bootable USB 記得插在要安裝 Ubuntu 的電腦
- 進去電腦 BIOS,方法可以參考這篇到 step6
- Advanced Mode → Security Boot → Security Boot Control 改為 Disabled
- 把 Boot 中 USB Ubuntu 優先權移至第一位
- 保存並重啟電腦
Ubuntu 安裝引導
- 進入黑色選擇面板,選第一個就行了
- 在歡迎面板中,選擇英文與 Install Ubuntu
- Keyboard layout,左右都選 English(US) 即可
- 不連接網路
- 更新與其他軟體,這邊我是保持 default 選項並按下一步
- 安裝類型選 其他選項,才能讓 Windows 和 Ubuntu 共存
- 進入分區選項
分區
共有五個分區,以下僅供參考,實際分區要自己的硬碟大小等而定:
EFI
- 大小:200MB - 500MB
- 分區類型:邏輯分區
- 分區位置:空間起始位置
- 用於:EFI 系統分區
Swap
- 大小:4GB 左右
- 分區類型:主分區
- 分區位置:空間起始位置
- 用於:交換空間
掛載點
- 大小:75GB 左右
- 分區類型:邏輯分區
- 分區位置:空間起始位置
- 用於:Ex4 日誌文件系統
- 掛載點(mount) : /
掛載點 /usr
- 大小:180GB 左右
- 分區類型:邏輯分區
- 分區位置:空間起始位置
- 用於:Ex4 日誌文件系統
- 掛載點(mount) : /usr
掛載點 /home
- 大小:300GB 左右,可以更大,視硬碟大小而定
- 分區類型:邏輯分區
- 分區位置:空間起始位置
- 用於:Ex4 日誌文件系統
- 掛載點(mount) : /home
設置安裝啟動設備,選擇 EFI 分區的設備號,彈出視窗確認後按確認。
Turn off RFT
我在安裝 Ubuntu 的時候有遇到這個錯誤,照著以下步驟操作解決問題:
- win + R,輸入 msconfig →系統設定 → 開機 → 開機選項 →安全開機(F)勾起來,下面的選項選最基本安全開機方式(M)
- 在命令提示字元執行
shutdown /t /fw /t 0
會進入 BIOS頁面
- Advanced Mode → Advanced → SATA Configuration → SATA Mode Selection → 將 RFT 選項改為 AHCI
- 重複第一步,但是是把安全開機選項去掉
- 啟動 Ubuntu
安裝一些套件等
ipconfig
sudo apt install net-tools
sudo apt install tree
Vim
Visual studio code
sudo apt update
sudo apt install software-properties-common apt-transport-https curl
curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
sudo apt update
sudo apt install code
# 測試成功了沒
code .
Git
sudo apt update
sudo apt install git
Docker
sudo apt-get install docker.io
service docker status
出現 Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
錯誤的解決方式:
-
建立 docker 群組
-
把當前使用者加到群組
sudo gpasswd -a $USER docker
-
激活更改/重啟docker
newgrp docker
sudo systemctl restart docker
設置 ssh
cd ~/.ssh
pwd
# /home/wei/.ssh
sudo ssh-keygen -o -t rsa -C "your_github_mail_address"
- Enter file in which to save the key (/root/.ssh/id_rsa): /home/wei/.ssh/id_rsa (剛剛
pwd
的路徑加上 /.ssh)
- Enter passphrase: 可以空白也可以輸入
- 重複 passphrase
cat /home/wei/.ssh/id_rsa.pub
,將公鑰複製起來
- 開啟 github →setting →SSH and GPG keys →New SSH key,Title 隨便取,Key Type 維持預設,把複製的東西貼在 Key 的欄位 → Add SSH key
- 記得
sudo chmod 755 /home/wei/.ssh/id_rsa
,後面的路徑改成自己的 id_rsa 位置,來設置權限
-
測試是否成功:ssh -T git@github.com
成功的話會顯示:Hi 用戶名! You’ve successfully authenticated 等字
Go
sudo apt update
sudo apt upgrade
sudo apt search golang-go
sudo apt search gccgo-go
sudo apt install golang-go
# check
go version
資料來源:
https://www.bilibili.com/read/cv16108268?from=search
https://zhuanlan.zhihu.com/p/268620595
https://www.myfreax.com/how-to-install-visual-studio-code-on-ubuntu-20-04/
20 Feb 2023
-
查看目前的 hostname
-
修改 etc/hostname
-
修改 etc/hosts
-
運行以下指令
sudo hostname -F /etc/hostname
重新開啟 terminal ,應該就可以看到新的 hostname 了!
18 Feb 2023
照著 Deep into Container — Build your own container with Golang 這篇教學操作的時候,發現每次結束都需要執行:
sudo mount -t proc proc /proc
上網查之後,發現將 must(syscall.Mount("proc", "proc", "proc", 0, ""))
改為以下程式碼,聲明這個新的 mount namespace 獨立:
must(syscall.Mount("", "/", "", syscall.MS_PRIVATE|syscall.MS_REC, ""))
defualtMountFlags := syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
must(syscall.Mount("proc", "/proc", "proc", uintptr(defualtMountFlags), ""))
Resource