<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>cubatic's blog</title><link>https://blog.121306.xyz/</link><description>Recent content on cubatic's blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 03 Nov 2025 15:33:10 +0800</lastBuildDate><atom:link href="https://blog.121306.xyz/index.xml" rel="self" type="application/rss+xml"/><item><title>Map_noswiss</title><link>https://blog.121306.xyz/posts/golang/map_noswiss/</link><pubDate>Mon, 03 Nov 2025 15:33:10 +0800</pubDate><guid>https://blog.121306.xyz/posts/golang/map_noswiss/</guid><description>以下代码为 golang 1.25.3
map_noswiss 常量 const ( // 每个 bucket 能够容纳的最大 key/val 的数量 bucketCntBits = abi.OldMapBucketCountBits // 当桶的平均装载量（load factor）超过 13/16 = 0.8125 时，会触发 map 扩容。 // 因为 bucketCnt 至少是 8，所以在对齐规则下性能是合理的。 // 这里用两个整数（分子 / 分母）来避免使用浮点数计算。 loadFactorDen = 2 loadFactorNum = loadFactorDen * abi.OldMapBucketCount * 13 / 16 // map 桶（bmap）结构中数据区（keys、values）相对于结构体起始地址的偏移量。 // 即 bmap 头部之后，键值对数据的起始位置。 // 为保证对齐，在某些架构（如 amd64p32）上，即使指针是 32 位，也要使用 64 位对齐。 dataOffset = unsafe.Offsetof(struct { b bmap v int64 }{}.v) emptyRest = 0 // 这个槽为空，并且后面不会再有非空项（用于快速扫描结束） emptyOne = 1 // 这个槽为空，但后面可能还有数据 evacuatedX = 2 // 此键值对已经迁移到新表（新表前一半） evacuatedY = 3 // 此键值对已迁移到新表（新表后一半） evacuatedEmpty = 4 // 桶已迁移完成，此槽为空 minTopHash = 5 // 正常已填充槽的最小 tophash 值 // flags iterator = 1 // 有迭代器正在使用当前 buckets oldIterator = 2 // 有迭代器正在使用旧的 old buckets（扩容时） hashWriting = 4 // 有 goroutine 正在写 map（防止并发写入） sameSizeGrow = 8 // 当前 map 扩容时，新旧 map 大小相同（即仅搬迁，不扩容） // 这是迭代器检查时的特殊哨兵值（bucket ID）， // 用于标识“不需要检查”的情况。 // 1&amp;lt;&amp;lt;(8*goarch.</description></item><item><title>Openwrt Build</title><link>https://blog.121306.xyz/posts/openwrt/build/</link><pubDate>Thu, 04 Sep 2025 11:50:15 +0800</pubDate><guid>https://blog.121306.xyz/posts/openwrt/build/</guid><description>build openwrt on debian 13 (trixie) install dependencies sudo apt update sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \ bzip2 ccache clang cmake cpio curl device-tree-compiler flex gawk gettext \ genisoimage git gperf haveged help2man intltool libelf-dev libfuse-dev libglib2.0-dev \ libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libpython3-dev \ libreadline-dev libssl-dev libtool llvm lrzsz msmtp ninja-build p7zip p7zip-full patch pkgconf \ python3 python3-pyelftools python3-setuptools qemu-utils rsync scons squashfs-tools subversion \ swig texinfo uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev \ python3-dev python-is-python3 libdebuginfod-dev systemtap-sdt-dev clone openwrt git clone https://github.</description></item><item><title>Go Channel</title><link>https://blog.121306.xyz/posts/golang/chan/</link><pubDate>Wed, 09 Jul 2025 09:10:33 +0800</pubDate><guid>https://blog.121306.xyz/posts/golang/chan/</guid><description>以下代码为 golang 1.24.5
chan chan 底层 结构 const ( maxAlign = 8 // 最大对齐字节数（通常与架构相关） hchanSize = unsafe.Sizeof(hchan{}) + uintptr(-int(unsafe.Sizeof(hchan{}))&amp;amp;(maxAlign-1)) // hchan 结构体的大小（含对齐填充） debugChan = false // 调试标志，是否开启 channel 调试 ) // Go 语言运行时中 channel 的底层结构 type hchan struct { qcount uint // 队列中当前的元素数量 dataqsiz uint // 环形缓冲区的大小（也就是 buf 中元素的总数） buf unsafe.Pointer // 指向实际数据缓冲区（数组，元素个数为 dataqsiz） elemsize uint16 // 每个元素的大小（字节） synctest bool // 是否用于 sync 包的测试中（true 表示在 synctest 模式中创建） closed uint32 // 标志位，表示 channel 是否已关闭 timer *timer // 用于超时操作的定时器指针（如 select 的超时） elemtype *_type // 指向元素类型的类型描述符 sendx uint // 当前发送的索引（用于环形缓冲区） recvx uint // 当前接收的索引（用于环形缓冲区） recvq waitq // 等待接收的 goroutine 队列（recv 阻塞队列） sendq waitq // 等待发送的 goroutine 队列（send 阻塞队列） // lock 保护 hchan 中的所有字段， // 以及阻塞在该 channel 上的 sudog 的多个字段。 // ⚠️ 在持有该锁时不要修改其他 G 的状态（尤其是不要唤醒 G）， // 否则可能与栈收缩操作发生死锁。 lock mutex } // 等待队列结构，用于接收和发送阻塞的 goroutine 链表 type waitq struct { first *sudog // 队首 goroutine last *sudog // 队尾 goroutine } 先来解释 maxAlign = 8 和 hchanSize = unsafe.</description></item><item><title>Base64</title><link>https://blog.121306.xyz/posts/golang/base64/</link><pubDate>Mon, 07 Apr 2025 16:30:25 +0800</pubDate><guid>https://blog.121306.xyz/posts/golang/base64/</guid><description>什么是 Base64 Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。
HTTP 的全称是 HyperText Transfer Protocol（超文本传输协议），最初设计的目的确实是：
传输 超文本（HTML） 但实际上作为应用层协议，HTTP 可以传输任意类型的数据。
HTTP Header 不能直接放图片字节进去，只能用 ASCII 字符（Base64 就是 ASCII-safe） Email 内容（MIME 协议）SMTP 协议历史原因只支持 7-bit ASCII，不能发图片，怎么办？Base64！ JSON / XML 这些格式都是文本格式，不能放二进制文件进去，必须转 Base64 编码后作为字符串存放 Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24)，然后把6Bit再添两位高位0，组成四个8Bit的字节，也就是说，转换后的字符串理论上将要比原来的长1/3。
例如：
11111111,11111111,11111111 -&amp;gt; 00111111,00111111,00111111,00111111 知道了 byte 的表示，但是还需要一张表，作为 base64 的编码表。
base64 中的 64 表示 64 个字符：
// StdEncoding is the standard base64 encoding, as defined in RFC 4648. var StdEncoding = NewEncoding(&amp;#34;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&amp;#34;) // URLEncoding is the alternate base64 encoding defined in RFC 4648.</description></item><item><title>Neovim_config</title><link>https://blog.121306.xyz/posts/vim/neovim_config/</link><pubDate>Fri, 28 Mar 2025 11:34:07 +0800</pubDate><guid>https://blog.121306.xyz/posts/vim/neovim_config/</guid><description>load plugin h 'runtimepath'
List of directories to be searched for these runtime files: filetype.lua filetypes |new-filetype| autoload/ automatically loaded scripts |autoload-functions| colors/ color scheme files |:colorscheme| compiler/ compiler files |:compiler| doc/ documentation |write-local-help| ftplugin/ filetype plugins |write-filetype-plugin| indent/ indent scripts |indent-expression| keymap/ key mapping files |mbyte-keymap| lang/ menu translations |:menutrans| lsp/ LSP client configurations |lsp-config| lua/ |Lua| plugins menu.vim GUI menus |menu.vim| pack/ packages |:packadd| parser/ |treesitter| syntax parsers plugin/ plugin scripts |write-plugin| queries/ |treesitter| queries rplugin/ |remote-plugin| scripts spell/ spell checking files |spell| syntax/ syntax files |mysyntaxfile| tutor/ tutorial files |:Tutor| :help 'write-plugin'</description></item><item><title>Vim help</title><link>https://blog.121306.xyz/posts/vim/vim_help/</link><pubDate>Mon, 10 Feb 2025 11:24:02 +0800</pubDate><guid>https://blog.121306.xyz/posts/vim/vim_help/</guid><description>Number Sequences Sometimes we need to generate a sequence of increasing numbers, like: • 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 • 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 • Or in a vertical list:
We can use the following Vim commands to generate these lists:
:put =&amp;#39;&amp;#39;.join(range(1, 10), &amp;#39;,&amp;#39;) &amp;#34; Generates 1,2,3,...,9 :put =&amp;#39;&amp;#39;.join(range(10, 100, 10), &amp;#39;,&amp;#39;) &amp;#34; Generates 10,20,30,...,90 :put =range(1, 10) &amp;#34; Generates a vertical list of numbers Incrementing Numbers Sometimes we need to change existing numbers, like:</description></item><item><title>pve postgresql</title><link>https://blog.121306.xyz/posts/postgresql/init/</link><pubDate>Wed, 13 Nov 2024 10:30:48 +0800</pubDate><guid>https://blog.121306.xyz/posts/postgresql/init/</guid><description>Install login to pve
bash -c &amp;#34;$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/postgresql.sh)&amp;#34; assume lxc container&amp;rsquo;s id is 201, then login to container
lxc-attach 201 or ssh root@your_container_ip reset password
sudo -u postgres psql ALTER USER postgres WITH PASSWORD &amp;#39;your_password&amp;#39;; create new user
CREATE USER your_username WITH PASSWORD &amp;#39;your_password&amp;#39;; create new database
CREATE DATABASE your_database_name; grant permission to user
GRANT ALL PRIVILEGES ON DATABASE your_database_name TO your_username; \c your_database_name GRANT ALL ON SCHEMA public TO your_username; Reference ProxmoxVE</description></item><item><title>OpenWrt dnsmasq</title><link>https://blog.121306.xyz/posts/openwrt/openwrt_dnsmasq/</link><pubDate>Mon, 26 Aug 2024 10:10:58 +0800</pubDate><guid>https://blog.121306.xyz/posts/openwrt/openwrt_dnsmasq/</guid><description>What is Dnsmasq? Dnsmasq provides network infrastructure for small networks: DNS, DHCP, router advertisement and network boot. It is designed to be lightweight and have a small footprint, suitable for resource constrained routers and firewalls. It has also been widely used for tethering on smartphones and portable hotspots, and to support virtual networking in virtualisation frameworks. Supported platforms include Linux (with glibc and uclibc), Android, *BSD, and Mac OS X. Dnsmasq is included in most Linux distributions and the ports systems of FreeBSD, OpenBSD and NetBSD.</description></item><item><title>Certbot</title><link>https://blog.121306.xyz/posts/debian/certbot/</link><pubDate>Wed, 07 Aug 2024 14:48:33 +0800</pubDate><guid>https://blog.121306.xyz/posts/debian/certbot/</guid><description>install sudo apt install nginx certbot python3-certbot-nginx certbot certbot certonly --nginx certbot renew certbot renew --dry-run crontab -e 0 2 1 */2 * /usr/bin/certbot renew --quiet --renew-hook &amp;#34;systemctl reload nginx&amp;#34;</description></item><item><title>Pipe</title><link>https://blog.121306.xyz/posts/golang/pipe/</link><pubDate>Tue, 30 Jul 2024 15:46:00 +0800</pubDate><guid>https://blog.121306.xyz/posts/golang/pipe/</guid><description>Pipe io.pipe 结构
type pipe struct { wrMu sync.Mutex // 序列化写操作的互斥锁 wrCh chan []byte // 用于从写者向读者发送数据的通道 rdCh chan int // 用于从读者向写者发送读取字节数的通道 once sync.Once // 确保&amp;#39;done&amp;#39;通道只关闭一次 done chan struct{}// 用于指示管道关闭的通道 rerr onceError // 存储关闭时发生的读错误 werr onceError // 存储关闭时发生的写错误 } 第一个select语句检查管道是否已关闭，通过尝试读取p.done通道。如果管道已关闭，则返回错误。 第二个select语句等待从写者通过p.wrCh发送的数据或管道关闭。 如果收到数据，将数据复制到b，并通过p.rdCh将读取的字节数发送回写者。 如果管道没有关闭，则会阻塞，直到管道关闭。 如果管道关闭，则返回错误。 func (p *pipe) read(b []byte) (n int, err error) { select { case &amp;lt;-p.done: return 0, p.readCloseError() default: } select { case bw := &amp;lt;-p.wrCh: nr := copy(b, bw) p.</description></item><item><title>Debian env init</title><link>https://blog.121306.xyz/posts/debian/debian-init/</link><pubDate>Thu, 22 Feb 2024 12:00:05 +0800</pubDate><guid>https://blog.121306.xyz/posts/debian/debian-init/</guid><description>bash script bash &amp;lt;(wget -qO - https://gist.githubusercontent.com/cubatic45/bd5169a1c9fbc643542be06b59e503a4/raw/7e0075aa3214cddb51ca96dac82d6479b8a688f4/init.sh) passwd vb add user adduser vb usermod -aG sudo vb ssh mkdir ~/.ssh echo &amp;#39;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEY8nuiqZYNWjJMC8I4StHzAcv8pJjHMUCwkvPMaVTWY cubatic@K-MacBook-Pro.local ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIALgDy+FJMEy/UG/bYjnBEAYmVTLH6qOVJyXzpXADoFX pc&amp;#39; &amp;gt; ~/.ssh/authorized_keys chmod 0700 ~/.ssh chmod 0600 ~/.ssh/authorized_keys nvim install sudo apt install wget -y wget https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz -O nvim-linux-x86_64.tar.gz tar -zxf nvim-linux-x86_64.tar.gz sudo mv nvim-linux-x86_64 /usr/local/nvim sudo ln -s /usr/local/nvim/bin/nvim /usr/bin/nvim config mkdir -p ~/.config/nvim wget https://raw.githubusercontent.com/cubatic45/dotfiles/refs/heads/main/dot_config/nvim/init.lua -O ~/.config/nvim/init.lua tmux apt install tmux -y echo &amp;#39;set -s set-clipboard on set -g allow-passthrough on set -g mouse on set-option -g repeat-time 0 set -s escape-time 10 set -g default-terminal &amp;#34;tmux-256color&amp;#34; set-option -sa terminal-overrides &amp;#34;,xterm-256color:RGB&amp;#34; set -wg mode-keys vi bind -T copy-mode-vi v send-keys -X begin-selection bind -T copy-mode-vi c send-keys -X copy-selection bind -T copy-mode-vi p send-keys -X copy-selection bind -T copy-mode-vi r send-keys -X rectangle-toggle bind -r h select-pane -L bind -r j select-pane -D bind -r k select-pane -U bind -r l select-pane -R set -g base-index 1 set -g pane-base-index 1 &amp;#39; &amp;gt; ~/.</description></item><item><title>Docker</title><link>https://blog.121306.xyz/posts/debian/docker/</link><pubDate>Thu, 22 Feb 2024 12:00:05 +0800</pubDate><guid>https://blog.121306.xyz/posts/debian/docker/</guid><description>Docker install 1. Install from script curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh 2. Install using the apt repository # Add Docker&amp;#39;s official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ &amp;#34;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;#34;$VERSION_CODENAME&amp;#34;) stable&amp;#34; | \ sudo tee /etc/apt/sources.</description></item><item><title>My First Post</title><link>https://blog.121306.xyz/posts/my-first-post/</link><pubDate>Thu, 22 Feb 2024 12:00:05 +0800</pubDate><guid>https://blog.121306.xyz/posts/my-first-post/</guid><description>hello world!</description></item></channel></rss>