[Interface]
-PrivateKey = [WINDOWS_PRIVATE_KEY]
-ListenPort = 51820
-Address = 10.0.0.2/24
-
-[Peer]
-PublicKey = [LINUX_PUBLIC_KEY]
-AllowedIPs = 10.0.0.0/24
-Endpoint = [LINUX_IP]:51820
+一些包比如ddns-scripts-cloudflare和luci-app-ddns
+
+
+配置步骤#
+
+-
+
首先需要Cloudflare创建一条A记录,域名是vpn.kyxie.me
,IP地址可以随便填,反正将来还会被DDNS覆盖,Proxy status选择关闭,只进行DNS不进行代理
+
+
+
+-
+
在这里点击Create Token,创建一个专用的API token
+
+-
+
选择Edit Zone DNS,点击Use Template
+
+-
+
按照下图配置
+
+
+
+-
+
生成API Token后注意保存好,只会显示一次
+
+-
+
然后回到OpenWrt→Service→Dynamic DNS→Services,添加一个ddns_ipv4,下面是详细配置,注意必须要安装了ddns-scripts-cloudflare之后才能在DDNS Service provider找到cloudflare.com-v4
+ddns:
+ "Enabled": true
+ "Lookup Hostname": "vpn.kyxie.me"
+ "IP address version": "IPV4-Address"
+ "DDNS Service provider": "cloudflare.com-v4"
+ "Domain": "vpn@kyxie.me"
+ "Username": "Bearer"
+ "Password": "Your API Token"
+ "Use HTTP Secure": true
+ "Path to CA-Certificate": "/etc/ssl/certs"
-
-
点击运行
+如果OpenWrt为主路由,这样应该可以完成DDNS解析了,但是如果OpenWrt为旁路由,由于路由器的wan口并不知道公网IP,需要使用借助网站来得知自己的公网IP,我们在Service→Dynamic DNS→Services→ddns_ipv4→Edit→Advanced Settings→IP address source选择URL,URL to detect可以选择默认ipv4的urlhttp://checkip/dymdms.com
+
+
+
+-
+
这样DDNS的配置就完成了,以后如果运营商给你换了公网IP也不会影响域名的配对了
+
+-
+
配置完后可以去cloudflare看看ip地址有没有刷新
+
+-
+
现在有了DDNS,我们就可以把Peer的EndPoint改成自己的域名了
+
+-
+
将OpenWrt生成的Configuration填入其他设备,就可以接入VPN了
diff --git a/zh/index.json b/zh/index.json
index 95c7905a..8f4d1e5a 100644
--- a/zh/index.json
+++ b/zh/index.json
@@ -1 +1 @@
-[{"content":"需要的硬件和软件 硬件 一台有网线接口的电脑 内存2GB以上的树莓派4B+ 8GB以上的小SD卡,可以插在树莓派上 SD卡的读卡器 一根网线 显示器(非必须),Micro USB - HDMI线(非必须) 软件 Balena Etcher,MacBook用户可以选择下载这个,也可以选择用命令行代替 VM Virtual Box和Ubuntu虚拟机,非必须,用于编译OpenWrt固件,不过也可以选择下载别人编译好的固件。有一点需要注意,我第一次编译60GB就足够了,但是第二次希望编译一个固件库,想把所有功能全部选上,60GB不够,建议分配128GB储存 SecureCRT或PuTTy,非必须,不知道大家用什么命令行终端,但是我MacBook和Windows都是用系统自带的命令行终端 获得镜像 下载镜像 可以从OpenWrt的官网下载镜像\n编译镜像 但我是比较能折腾的,我找到了这个仓库:Lean,readme有比较详细的编译步骤,于是决定自己尝试一下\n第一次编译 首先在Ubuntu上clone repo\nhttps://github.com/coolsnowwolf/lede.git 安装依赖包\nsudo apt update -y sudo apt full-upgrade -y sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \\ bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib \\ git gperf haveged help2man intltool libc6-dev-i386 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 lrzsz mkisofs 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 更新feed并选择配置\ncd lede ./scripts/feeds update -a ./scripts/feeds install -a make menuconfig 输入这个命令后就开启了配置页面,我使用的是树莓派4B,我目前的常用场景有见这里\n# 编译的目标系统 TargetSystem: - Broadcom BCM27xx Subtarget: - BCM2711 boards (64 bit) TargetProfile: - Raspberry Pi 4B/400/4CM (64bit) # 镜像参数 TargetImages: - ext4 # ext4格式的固件可方便地调整分区大小 - squashfs # squashfs格式的固件可恢复出厂设置 - KernelPartitionSize: 64 # boot分区大小为64M - RootFilesystemPartitionSize: 512 # root分区大小为512M # 可选工具 BaseSystem: - block-mount # 在LuCI界面添加\u0026lt;挂载点\u0026gt;菜单 - blockd # 自动挂载设备 - wireless-tools # 无线扩展工具 Administration: - htop # 添加htop命令 Firmware: - xxx # 选择你需要的网卡固件,默认即可 # 文件系统 KernelModules: Filesystems: - kmod-fs-ext4 - kmod-fs-ntfs - kmod-fs-squashfs - kmod-fs-vfat - kmod-fuse # 网卡支持 NetworkDevices: - kmod-xxx # 有线网卡支持,跟以下几项可根据需求选择性添加 NetworkSupport: - kmod-wireguard WirelessDrivers: - kmod-rt2800-usb # 添加Ralink RT5370芯片的USB无线网卡驱动 USBSupport: - kmod-usb-net: - kmod-usb-net-asix # 添加支持亚信的有线网卡支持 - kmod-usb-net-asix-ax88179 # 添加USB3.0的有线网卡芯片AX88179的驱动 - kmod-usb-net-rtl8152 # 添加USB2/3的有线网卡RTL8152/3芯片支持 - kmod-usb-net-sr9700 # 添加USB2.0的有线网卡SR9700芯片支持 - kmod-usb-core # 启用USB支持 - kmod-usb-hid # USB键鼠支持 - kmod-usb-ohci # 添加OHCI支持 - kmod-usb-storage # 启用USB存储 - kmod-usb-storage-extras - kmod-usb-uhci # 添加UHCI支持 - kmod-usb2 # 开启USB2支持 - kmod-usb3 # 开启USB3支持 # LuCI设置 LuCI: Collections: - luci # 开启luci Modules: Translations: - Chinese(zh-cn) # 中文支持 Themes: - luci-theme-agron # 添加主题 # LuCI应用 Applications: - luci-app-adguardhome # 去广告 - luci-app-alist # 文件共享 - luci-app-aria2 # 下载工具 - luci-app-advanced-reoot - luci-app-filebrowser # 文件管理 - luci-app-filetransfer - luci-app-firewall # 防火墙 - luci-app-frps - luci-app-frpc # 内网穿透 - luci-app-hd-idle # 硬盘休眠 # - luci-app-lucky - luci-app-opkg # 软件包 # - luci-app-openvpn # - luci-app-openvpn-server - luci-app-qos # 服务质量 - luci-app-samba # 网络共享 - luci-app-shadowsocks-libev # 翻墙软件 - luci-app-upnp # UPnP服务 - luci-app-wol # 网络唤醒 Protocols: - luci-protocol-wireguard # 网络工具 Network: DownloadManager: - ariang # Aria2管理页面 FileTransfer: - Aria2Configuration: - *** # 选择Aria2支持的功能 - curl # 添加curl命令 - wget # 添加wget命令 VPN: - wireguard-tools # 实用工具 Utilities: Compression: - bsdtar # tar打包工具 - gzip # GZ 压缩套件 Disc: - fdisk # 磁盘分区工具 - lsblk # 磁盘查看工具 Filesystem: - ntfs-3g # NTFS读写支持 - resize2fs # 分区大小调整 Terminal: - screen # 添加screen - pciutils # 添加lspci命令 - usbutils # 添加lsusb命令 配置完成后选择Save,会保存为一个.config文件。在最后一步安装之前还需要安装screen,用于创建持久会话,否则如果不小心关了ssh之前编译的就都没了(你猜我是怎么知道的)\nsudo apt install screen screen -S buildlede 最后执行命令用8个线程下载dl库,第一次编译用1个线程编译。在这里一开始我用的AWS的Ubuntu一直下不下来,没有办法换成了本地的Ubuntu虚拟机才下载编译成功\nmake download -j8 make V=s -j1 然后就是等待编译,编译完成后在bin\\targets可以选择openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz这个版本进行烧录\n修改默认配置(可选)\n修改默认IP地址到192.168.2.66\nsed -i \u0026#39;s/192.168.1.1/192.168.2.66/g\u0026#39; package/base-files/files/bin/config_generate 单独编译 有时候用着用着发现我们需要安装一个插件,这种情况下我们可以单独编译一个插件\n编辑.config文件\nmake menuconfig 找到我们想单独编译的插件,比如luci-app-diskman,这是个管理路由器上的磁盘和分区的插件,第一次编译选择为[*],意思是作为一个内置模块编译,不可以卸载。这次的话我们可以选择为[M],意思是作为一个模块编译\n使用如下命令可以编译\nmake package/luci-app-diskman/compile V=s 编译完成后在/bin/packages/aarch64_cortex-a72/luci文件夹下能找到luci-app-diskman_v0.2.11_all.ipk\n打开openwrt,System -\u0026gt; File Transfer选择文件上传,右下角安装就可以了\n我安装完后OpenWrt没有立刻出现新安装的插件,过了一段时间才出现的\n如果要单独编译内核模块,比如kmod-wireguard,可以在kernel module中选中它为[M],然后运行\nmake package/kernel/linux/compile V=s 很快编译就完成了,编译出来的包在bin/packages/\u0026lt;target\u0026gt;/\u0026lt;package-repo\u0026gt;/kmod-wireguard_xxx.ipk\n第二次编译 拉取最新feeds\nsudo sh -c \u0026#34;apt update \u0026amp;\u0026amp; apt upgrade -y\u0026#34; git pull ./scripts/feeds update -a \u0026amp;\u0026amp; ./scripts/feeds install -a 清除旧的编译产物(可选)\nmake clean # 源码有大规模更新或者内核更新后执行,以保证编译质量 # 此操作会删除 /bin 和 /build_dir 目录中的文件 make dirclean # 如果要更换架构,例如要从 x86_64 换到 MediaTek Ralink MIPS 建议执行以下命令深度清理 # 此操作会删除 /bin 和 /build_dir 目录的中的文件(make clean),以及 /staging_dir、/toolchain、/tmp 和 /logs 中的文件 编译\nmake defconfig make download -j8 find dl -size -1024c -exec ls -l {} \\; make -j$(nproc) || make -j1 || make -j1 V=s # 如果需要重新配置 # 清除临时文件和编译配置文件 rm -rf ./tmp \u0026amp;\u0026amp; rm -rf .config make menuconfig make download -j8 find dl -size -1024c -exec ls -l {} \\; # 多线程编译失败后进入单线程编译 make -j$(nproc) || make -j1 || make -j1 V=s 烧录 Windows 可以使用Balena Etcher或者其他的disk imager软件将image烧录到SD卡中,非常简单,按顺序一步一步来即可\nMacOS MacOS也可以使用Balena Etcher将镜像导入到SD卡中,但是我不喜欢下乱七八糟的软件,干脆直接使用命令行了\n找到SD卡的磁盘编号,这里我的SD卡磁盘为/dev/disk4\ndiskutil list /dev/disk4 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *7.9 GB disk4 1: Windows_FAT_32 BOOT 67.1 MB disk4s1 2: Linux 109.1 MB disk4s2 (free space) 7.7 GB - 由于我这里以前装过一个不带GUI版本的OpenWrt,SD卡多了几个分区,这次打算重新装一个带着GUI的\n首先恢复分区,这个命令同时把SD卡进行格式化\ndiskutil eraseDisk FAT32 SDCARD MBRFormat /dev/disk4 恢复分区之后\ndiskutil list /dev/disk4 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *7.9 GB disk4 1: DOS_FAT_32 SDCARD 7.9 GB disk4s1 输入以下命令卸载(但不移除) SD 卡,否则会显示busy\ndiskutil unmountDisk /dev/disk4 Unmount of all volumes on disk4 was successful 解压下载的image\ngunzip ./openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz 使用 dd 写入解压后的 .img 文件,注意这一步千万不要抄错了磁盘编号,否则伤害不可逆,dd是个很强的命令\nsudo dd if=/Users/kunyangxie/Desktop/openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img of=/dev/disk4 bs=1M status=progress 286261248 bytes (286 MB, 273 MiB) transferred 69.070s, 4144 kB/s 275+1 records in 275+1 records out 288454957 bytes transferred in 69.735447 secs (4136418 bytes/sec) 如果不报错一般就是成功了\n最后将SD卡从电脑拔出,插到树莓派上,启动树莓派,这时使用网线将树莓派的以太网接口和电脑的以太网接口相连。由于OpenWrt 默认将树莓派的eth0接口桥接到br-lan并使用 IP 地址 192.168.1.1,我们要配置一下电脑端的Ethernet接口是否也在192.168.1.x的子网,x可以选2 - 255的随便一个数\n当树莓派就跟电脑在相同子网后,在浏览器中输入192.168.1.1,就能登录到OpenWrt的GUI(LuCI)了,默认用户名和密码是root和password\n大功告成了\n连接路由器 我家主路由器使用的子网为192.168.2.x,需要将树莓派改为这个子网下(当然如果主路由器子网为192.168.1.x的话就不用多折腾这一步了)。我们先禁用桥接模式和修改IP地址\nvi /etc/config/network 修改文件为\nconfig interface \u0026#39;lan\u0026#39; option device \u0026#39;eth0\u0026#39; option proto \u0026#39;static\u0026#39; option ipaddr \u0026#39;192.168.2.66\u0026#39; option netmask \u0026#39;255.255.255.0\u0026#39; option gateway \u0026#39;192.168.2.1\u0026#39; option dns \u0026#39;192.168.2.1\u0026#39; option ip6assign \u0026#39;60\u0026#39; 禁用DHCP,防止跟主路由器的DHCP冲突\nvi /etc/config/dhcp config dhcp \u0026#39;lan\u0026#39; option interface \u0026#39;lan\u0026#39; option ignore \u0026#39;1\u0026#39; 检查防火墙配置\nvi /etc/config/firewall config zone option name \u0026#39;lan\u0026#39; list network \u0026#39;lan\u0026#39; option input \u0026#39;ACCEPT\u0026#39; option output \u0026#39;ACCEPT\u0026#39; option forward \u0026#39;ACCEPT\u0026#39; 应用设置\n/etc/init.d/network restart 这时由于我们电脑还在192.168.1.x子网,但是树莓派已经到了192.168.2.x子网了,所以连接必定是断开的,我们再把电脑端的Ethernet端口改回192.168.2.x子网,就又能重新访问了\n将树莓派与电脑断开连接,插到路由器的LAN口上,应该能正常访问网络,而且电脑也能访问树莓派了\n设置旁路由 以上步骤只是将树莓派作为一个用网设备加入了家庭的局域网,我们的终端设备还是沿着主路由这条线进行通信,要想作为旁路由还需要进一步设置\n其实很简单,我们只要将Wifi的网关从路由器之前DHCP自动分配的地址改为旁路由树莓派即可,假设我的主路由器IP地址为192.168.2.1,我的电脑IP地址为192.168.2.54,我的树莓派的IP地址为192.168.2.66,我需要这么修改:\nMacBook也一样\n同样的iPhone也可以设置,这里我就不放图了\n因为怕炸网我暂时先使用这种非侵入式的设置,它只影响把网关设置为软路由的终端,这样一旦网坏了只影响部分设备,或者我修改一下网关修改到主路由器的IP地址就可以了\n安装插件 受到韩风Talk的启发,由于刚开始折腾还不知道哪些插件好用,我也觉得我应该制作一个插件库\n卸载插件 可以在System -\u0026gt; Software -\u0026gt; Installed中卸载插件\n或者使用opkg包管理工具,比如\nopkg remove luci-app-samba 可以使用这条命令来删除不需要的依赖项\nopkg remove --autoremove 安装插件 首先需要在Ubuntu上编译插件\nmake menuconfig 在LuCI -\u0026gt; Applications可以把固件全选上,毕竟我们是做个固件库,之后有啥需求就装啥。选择时应该模块化,按空格让前面括号里出现一个M。保存后回到命令行开始编译\nmake -j1 V=s 编译完成后在bin\\packages中就能找到我们编译的全部插件了,而且都为.ipk格式\n常见使用场景 去广告 所需插件(具体配置路径见这里) luci-app-adguardhome 配置参考:【韩风Talk】Openwrt插件对广告说不,怎么做?两款热门插件随你用! 外网访问我的Windows台式机 OpenVPN 所需插件(具体配置路径见这里) luci-app-openvpn luci-app-openvpn-server luci-i18n-openvpn-server-zh-cn luci-i18n-openvpn-zh-cn open-vpn-easy-rsa openvpn-openssl Wireguard Wireguard因为比OpenVPN轻量化速度更快,因此是我目前首选 所需插件(具体配置路径见这里) kmod-wireguard luci-proto-wireguard wireguard-tools luci-app-wireguard(可以不选,而且在我的menuconfig没找到) 详细配置见:Wireguard配置 | Kunyang\u0026rsquo;s Blog ZeroTire 所需插件(具体配置路径见这里)\nluci-app-zerotire 配置参考:【韩风Talk】Openwrt的Zerotier插件玩法,异地组网不求人,大虚拟局域网走起!\n文件管理 所需插件(具体配置路径见这里)\nluci-app-filebrowser:Service -\u0026gt; File Browser luci-app-samba:NAS -\u0026gt; Network Shares,有一点视频里说的点击Path会进入/luci/admin/system/fstab,但是我的menuconfig没有luci-app-fstab,因此会404,好在如果编译了BaseSystem -\u0026gt; block-mount的话这个url:/luci/admin/system/mounts跟视频里的是一样的。我认为这是个bug luci-app-filetransfer:System -\u0026gt; File Transfer,用于上传ipk包 配置参考:【韩风Talk】Openwrt文件管理的玩法合集,这期顺便解决中文乱码问题!\n","permalink":"https://kyxie.me/zh/blog/tech/router/raspberrypi-openwrt/","summary":"需要的硬件和软件 硬件 一台有网线接口的电脑 内存2GB以上的树莓派4B+ 8GB以上的小SD卡,可以插在树莓派上 SD卡的读卡器 一根网线 显示器(非必","title":"使用树莓派4B+安装OpenWrt用作旁路由"},{"content":"Mac用户非常推荐使用Homebrew来安装一些软件,就Python来说如果在官网直接下载会在Launch Pad出现IDLE和Python Launcher两个图标,个人感觉很丑。\n其实MacOS Catalina只有系统就预装了Python3了(在这之前是Python2),如果只想处理一些基本的Python功能直接用系统自带的就好了,但是为了方便版本控制还是挺推荐使用Homebrew再下载一个版本方便管理,避免影响系统的Python。\n安装步骤 首先需要安装Xcode Command Line Tools,Homebrew依赖这些工具来正常工作,可以在命令行直接输入命令。其实安装完这个git也就顺带着一起安装了,但是一样的道理,还是推荐使用Homebrew再安装一个版本的git。\nxcode-select --install 安装Homebrew\n/bin/bash -c \u0026#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\u0026#34; 可能需要输入密码\n验证安装以及更新到最新版本\nbrew -v brew update 安装Python\nbrew install python 这时系统里可能有两个Python,我们需要指定使用哪个Python\nwhich python3 /usr/bin/python3\t# 出现这个就是还在用系统自带的python 我们找到通过Homebrew安装的Python的位置\nbrew --prefix python /opt/homebrew/opt/python@3.13 打开环境变量配置文件,MacOS Catalina之后默认为zsh\nvim ~/.zshrc 在最后一行加入\nexport PATH=\u0026#34;/opt/homebrew/opt/python@3.13/bin:$PATH\u0026#34; 保存,刷新file\nsource ~/.zshrc 然后再查看一下当前使用的哪个Python版本\nwhich python3 /opt/homebrew/opt/python@3.13/bin/python3\t# Homebrew版本 安装git\nbrew install git 验证安装\ngit -v 一般来说git不会出现像Python一样设置PATH的问题。\n配置git的邮箱和用户名,如果要使用GitHub来管理仓库的话,要保持这个邮箱和用户名和GitHub一致\ngit config --global user.name \u0026#34;Your Name\u0026#34; git config --global user.email \u0026#34;your.email@example.com\u0026#34; ","permalink":"https://kyxie.me/zh/blog/tech/others/python-and-git-for-macos/","summary":"Mac用户非常推荐使用Homebrew来安装一些软件,就Python来说如果在官网直接下载会在Launch Pad出现IDLE和Python L","title":"使用Homebrew在M芯片的MacBook安装Python和Git"},{"content":"Header 好久没折腾自行车了,最近刚换了roval的破风把,准备打算在车把也内走线,这样车把握起来就爽快多了。我自己拆车试了一下,结果被Shimano 7020两根油管两根线管一共4根线实在是折磨得不轻,于是有了买套Shimano 8170的念头,故刷起了加拿大的各大自行车网站。这不刷不知道一刷吓一跳,一套Shimano 8170至少得$3000,税后怎么着奔$4000去了。看了一眼淘宝国内的价格居然都跌到¥8000了,干脆从国内空运一套过来,在这里开个帖子记录一下我的装车的全过程。\n先说结论:我自认为我算是动手能力非常非常强的了,但是在装车的过程中还是踩了无数个坑,这里有点心疼国内的技师们,国外装个车就得$300+。\n拆车 想换套件换车把的同时做个大保健,然后开起了漫长的拆车之旅:\n首先是不知道自己该用什么中轴工具,找了半天自己的中轴型号是螺纹中轴(Thread Bottom Bracket) SM-BBR60 BSA,于是乎Temu买工具,等了半个月\n其次是中轴拿不下来,于是乎去the Home Depot买了个橡皮锤和wire cutter\n然后是是手变速线拿不下来,拆掉7020的螺丝之后才发现线头需要跟手变的孔对准(这里提醒大家如果想自己搞一定要勇于拆,一般来说不会装不上,拆下来才能明白他的原理)\n然后是油管自己剪不断,看了可利呼的视频发现应该拿小刀切\n\u003c!DOCTYPE HTML\u003e\r然后是这个线管穿线实在是穿不出来,后来发现了有专门的导线工具,于是我用了替换下来的变速线当导线工具(其实这时我还没有打算换套件,想继续用用7020来着)\n然后发现前刹车油管剪短了\n然后发现四根线根本无法同时从车把里穿出来\n这时由于我的手变没有油堵,刹车油已经弄得我新车把到处都是了(这时有了非常坚定的念头要换套件)\n放弃,套件挂咸鱼(最后竟然一共卖了C$600,也算是出乎我的意料了)\n配置 我的整车配置:\n车架:Specialized Tarmac SL6 Sport 套件:Shimano Ultegra R8170 前轮:Roval Rapide CLII 后轮:Roval Rapide CLX 弯把:Roval Rapide Handlebar 400mm 把立:Specialized Future Stem 100mm 坐垫:Specialized Power Comp 坐管:S-Works Carbon Seatpost 锁踏:Shimano Dura-Ace PD R9100 把带:Supacaz Super Sticky Kush 外胎:Continental GP5000 25c 内胎:RideNow TPU 码表:Garmin Edge 530 尾钩:Sigeyi 表架:扭矩 尾包:Silca Mattone Seat Pack 把包:Rapha Expore Bar Bag 2.4L 装车 后夹器 首先安装后夹器,将前叉拆下来,在穿油管的时候可以线把油管伸出头管,然后套上防止异响的保护套,然后再从头部油管口伸出油管 穿油管还是比较难的,这里淘宝买的引导线救了大命了\n然后用螺丝固定后夹器,注意特殊螺丝靠后\n不要忘记安装垫片\n最后安装保险栓\n前夹器 前叉穿线太痛苦了,再一次感谢淘宝买的引导线 把组 将手变固定在弯把上,放在地上或者使用激光仪调整平衡 千万不要忘记锁紧吊芯,注意吊芯上的箭头应该对准把立螺丝的缝隙(有些车需要对准前面) 调整把组垫片 将弯把固定在把立上 锁紧碗组盖 锁紧把立盖子 将码表架固定在把立上 电池 将电池固定在座管内部,可以用专用的Di2 battery holder,我这里就直接拿电工胶布固定了一下\n电池的三根线成等腰三角形,上面的连接后拨,左边的连接前拨,剩下的不动就行,但是也不要把保护套摘掉。\n后拨 我使用Sigeyi的直装尾勾(不小心买了绿色,但是绿色的实在是太丑了),因此需要先将原厂的吊耳摘下来,这里拧了好久实在是拧不下来,无奈还是去找车店了\n使用Shimano自带的工具将线连接,分别连接后拨电池和前拨电池\n手机下载E-TUBE按住后拨按钮2秒(不要按的时间太长了),就可以开始配对了,注意这里要等后拨电量比较充足的时候才能进行\n不要忘记装电线堵头\n前拨 这里电线要绕一圈然后从车架内进入,最后连接座管内的电池\n注意别忘了装电线堵头\n喜玛诺自带配件中有一个前拨折线配件\n手变 穿线\n首先需要切线,将油管跟手变末端对齐,做一个记号,再在记号后面21mm处再做一个记号,第二个记号就是截管的位置\n使用专用的截管工具截管\n将手变油管堵头螺丝拿下来,注意拿纸垫在下边,用来吸油,然后将橄榄头拿出来\n先穿入手变油管堵头螺丝,然后再将橄榄头穿入油管,最后用专用顶针工具将油针顶进油管(如果先顶针的话橄榄头有可能塞不进去)\n将螺丝拧紧,扭力是8Nm,一定要拧紧,否则会漏油\n灌油\n首先将轮组拿下,一定注意碟片不要沾到油 然后将夹器的来令片拆下来,来令片也不能沾到油,拆掉之后可以用六角扳手用力按压活塞,将活塞撑开到尽可能宽,然后使用专门卡住活塞的工具,顶住活塞 将手变的油缸螺丝拧下来,灌油工具有专门的连接件,一定要先把连接件拧上,再装油杯(也有可能是一体的没有连接件,总之一定要拧紧,直接插入是不行的),否则会漏油 将注射器连着管插入夹器中,然后拧开注油螺丝,就可以开始注油了,注油的同时可以弹一弹油管将空气排出 注意当注油螺丝没有拧紧的时候,刹车是肯定能按倒底的,只有当注油螺丝拧紧后才会按不到底 把多余的油擦干净 中轴 我的中轴规格是SM-BBR60 BSA螺纹中轴 牙盘和曲柄 不要忘记涂抹界面脂\n13N的扭力固定曲柄\n链条 有字面朝外\n我们需要确定链条长度,我使用的是这个方法\n\u003c!DOCTYPE HTML\u003e\r注意:截取链条的时候一定要注意,一定要让我们需要的链条的两端都为内导板(下图只是想介绍什么是内导板和外导板,Shimano的链条基本上都用魔术扣了很少用这样的销钉),如果我们一个为内导板一个是外导板的话魔术扣是装不上的,而且用截链器只截掉一节外导板是非常困难的\n下图办法也可以使用,我最后安装链条的时候不下心多截了一两节让链条变短了,事实证明一两节不太影响\n魔术扣第一次很难装上,我们需要把魔术扣转动到牙盘左上方,而且牙盘正好朝前,这时拿脚用力一踩曲柄就能把魔术扣装上了\n变速 首先将套件调至最大飞,然后调节张力螺丝,配合喜玛诺自带的卡尺,调整后拨和最大飞的间距\n然后在E-TUBE软件中选择Maintainance,按照步骤调节前拨,注意软件上的示意图是从上到下俯视观察的\n\u003c!DOCTYPE HTML\u003e\r然后将后拨调至从大到小第五个飞轮,软件中微调使后拨和飞轮处在同一个水平面\n最后在最大飞轮的情况下,调整限位螺丝,两颗螺丝都贴住限位板但是留一点距离\n\u003c!DOCTYPE HTML\u003e\r缠把带 最后就是缠把带了,虽然缠了好多次了但是还是很不会缠,最好还是找两个例子左边一个右边一个,不然我脑子转不过来,这个网上的教程应该也一大堆了 用电工胶布拧紧的时候要把胶布在车把上粘几圈,否则把带容易往下掉 回想起我第一次缠把带的时候b站找了半天竟然只有一个GCN的缠把带教学视频,如今看来公路车真的火起来了 Footer 最后放几张装好的照片\n文中的装车YouTube视频来自于\nUpdate 不知道为什么刚组装好车的时候没有发现这个问题,大概骑了一个月以后车把开始转不动,火山盖磨车架。一开始以为是苹果酱涂少了,抹酱后发现依旧不行。后边以为是吊芯太紧了,研究了半天如何拆卸闪电的吊芯,发现他实在是太难拆了感觉需要上锤子。实在搞不下来去找了Yonge街上的Bike Depot,阿三店员一脸客气地收了我CAD$10(不过取车的时候Manager并没有收我钱)。从车店取车回家以后用松的吊芯又重新安装了一遍把组,发现依旧磨车架。最终发现是缺少了垫片,无奈淘宝下单,等我妈来加拿大的时候给我捎过来。\n神奇啊我妈带来的0.1mm的垫片竟然给问题解决了,就差0.1mm!\n","permalink":"https://kyxie.me/zh/blog/life/bike/","summary":"Header 好久没折腾自行车了,最近刚换了roval的破风把,准备打算在车把也内走线,这样车把握起来就爽快多了。我自己拆车试了一下,结果被Shiman","title":"Specialized Tarmac SL6装车"},{"content":"Aug 2021, Bank of China 我的第一张信用卡是出国前和我爹一起去中国银行办的卓隽,我用我爹的副卡,不太清楚额度是多少。我只是刚到加拿大的前几天用这张卡,出了隔离之后办了Scotiabank就不再使用了,以后如果回国买水果产品分期的话说不定也会偶尔用用,反正我爹还钱。\n这张卡无年费,开卡奖励不清楚,返现不清楚,但是摸起来比加拿大的银行卡要厚好多,质感好一些,不知道是不是心理作用。据说这张卡现在有了CAD直接结算的,这样的话用起来会更方便。\nSep 2021, Scotiabank Scene+ 由于办学签来加拿大走的是SDS通道需要买个$10000的GIC,光大银行离家近,我就直接办的光大银行的GIC。光大银行对接的是Scotiabank,来到加拿大以后找了家Scotiabank的branch就给我开了checking account和信用卡,额度是$500。由于额度太少了我当时买好多东西都是先提前往里充钱,再刷卡消费,把信用卡花成了prepaid card。因为这是我第一张加拿大信用卡,所以也不会关卡。\n这张卡无年费,开卡送5000 Scene+积分,Sobeys旗下的超市,双立人,Cineplex都是2x积分,其他消费1x积分,之前换电影票好像是1250分,后来变成总价格 * 100 Scene+积分。最开始也没研究怎么薅羊毛,所以我在毕业之前一直在用这张卡。\nJan 2023, BMO Cashback 这个时候找到工作,就开始研究怎么薅羊毛了,最开始申请的是这张BMO的买菜卡,额度$1000。由于一开始只想找个无年费且返现高的就申请了这张,确实这张卡在无年费的里面算比较好的了。\n这张卡无年费,好像也没有什么开卡奖励(好像是前1个月还是3个月买菜10%返现),买菜3%返现(每月$500的cap),流媒体账单1%返现,其他消费0.5%返现,Mastercard应该会把沃尔玛算作Grocery因此也有3%(待考证)。最主要的是由于22年趁着黑五开了Costco,当时一直没有Mastercard来刷Costco,这下终于可以在Costco消费了。这张卡用了半年,基本只有买菜在用,返了$300多,因此还是挺不错的。\n2024年五月关卡。\nMar 2023, CIBC Costco 很快我就发现只有买菜返现可不行,还得再申请一张卡用来对应吃饭的返现,于是开始研究无年费饭卡。本来想申请Simplii是4%返现,但是听说非PR不太好下卡,最后还是选择了Costco的信用卡,刚开始给我的额度是$3000,后来他们给我提升到$6000。\n这张卡无年费,但是必须要有Costco会员,吃饭3%返现,Costco加油3%返现,其他加油站2%返现,Costco网站消费2%返现,但是网站价格要更贵一些,其他消费1%返现。这张卡也用了半年,感觉返现速度比较慢,半年多也才返了$300。打算把Costco停掉之后转到CIBC的其他卡。\n由于取消了Costco会员,2024年五月关卡。\nAug 2023, Triangle MC 这段时间被SportChek店员忽悠着办了一张Triangle的卡。他应该是按照惯例问我要不要办这张卡,我当时还对信用卡研究没有这么深,以为这是那张带着免费拖车的卡,于是稀里糊涂就同意了,这店员一听我同意了也很懵逼,可能是被拒绝惯了。正当我准备拿出自己的信用卡付款的时候店员说不用了,会把消费记到这张新信用卡身上。我问会不会被hard pull,他说可以不激活卡,这样就只会soft pull一下,我又问那我不激活怎么给这张信用卡付款,他说在你checking账户加入payee就可以了,最后我说好吧就这样办了这张卡。后来还是没发现该怎么不激活就还款,也懒得打电话问,干脆就激活了,当时也没管有没有hard pull。总结永远不要办沃尔玛,SportChek这种店员老大妈过来围着问你要不要办的卡。\n其实这张卡也挺不错的,无年费,Triangle加油直接每升便宜5分钱,Canadian Tire旗下包括SportChek都是4%返现。后边办了Cobalt之后基本上油价便宜的时候会去Canadian Tire加油刷这个卡,油价贵的时候去别的地方加油刷Cobalt,所有的返现都会转化成CT Money然后在Canadian Tire旗下的商店使用。\n不过对于加油问题我刚算了一下,假设油价为a,加油体积为b,Triangle真实的加油消费为:(a - 0.04) * b = ab - 0.04b,Cobalt真实加油消费为:ab * (1 - 0.016 * 2) = 0.968ab。也就是说当油价低于1.25的时候Triangle才比Cobalt划算,我来加拿大之后还没有遇见过这么便宜的油价,那这张MC真是屁用没有了,等着买了房子转成黑卡吧。\n黑卡WEMC除了这张普通卡有的服务以外,还有免费拖车和地税服务。不过我也暂时也用不上,等到时候再换卡就可以了。不过所有的WEMC信用卡都有免费的Boingo WiFi,之前在国泰航空上看到过这个,等什么时候有了张WEMC上飞机的时候试试。黑卡还有一点就是长时间不用的话就会自己关卡,所以得等有了房子之后用来交地税才能保证经常用。\nOct 2023, AMEX Cobalt 由于之前一直只想办无年费的信用卡,且觉得加拿大AMEX接受率不高,再加上觉得使用PPP过于麻烦,于是并没有考虑办AMEX的卡。后来在朋友的忽悠下,正好那段时间Cobalt refer别人奖励翻倍,于是我也办了张Cobalt,也幸亏如此,如果再晚一个周开卡的话,Cobalt奖励就从之前的30000MR变成了15000MR,这羊毛又薅到了。\n这张卡月费$12.99,相当于年费$155.88,开卡奖励每月花$500返2500MR持续12个月(现在变成了每月花$750返1250MR持续12个月)。吃饭(美国的餐厅也可以),买菜(建兴超市也可以刷)都是5x积分,流媒体(包括Apple Music)3x积分,酒店Airbnb机票加油 2x积分,其他消费1x积分,refer一个人送5000MR。我开卡两个月就拿了40000MR简直是太爽了(1MR可以看作$0.016)。所有的MR积分都可以1:1地转化为Areoplan积分,刷几个月一张回国机票就出来了。\n经过了几个月的记账之后发现,平时消费最多的地方不在买菜和外出吃饭而在于其他消费。好不容易办一张有年费的信用卡那可得薅个痛快,于是我开始买Paypower Prepaid Mastercard (PPP)。PPP也算是老羊毛了,比较安全,在超市里搭一根香蕉基本不会被FR。\n之前算过买reloadable的PPP和non-reloadable PPP的区别,假设我一个人,每个月买$2500的PPP。\nNon-reloadable:\nNon-reloadable的算法就很简单了,每张卡$9.95+tax就完了,一次买$500,不过这样的话我1个月最多也就买2张PPP,能5x积分的就直接拿Cobalt刷了。\nimport math COBALT_MONTHLY_FEE = 12.99 AMEX_VALUE = 0.016 # Let 1MR = $0.016 TAX_RATE = 1.13 PPP_NONRELOADABLE = 9.95 * TAX_RATE PPP_PER_MONTH = 1 class NONRELOAD: def __init__(self): self.cost = COBALT_MONTHLY_FEE + PPP_PER_MONTH * PPP_NONRELOADABLE self.cashback = round(round(500 + PPP_NONRELOADABLE, 2) * 5) * PPP_PER_MONTH * AMEX_VALUE self.profit = self.cashback - self.cost if __name__ == \u0026#34;__main__\u0026#34;: nonreload = NONRELOAD() print(f\u0026#39;Non-reload ppp cost\u0026#39;.ljust(30) + f\u0026#39;= {nonreload.cost:.2f}\u0026#39;) print(f\u0026#39;Non-reload ppp cashback\u0026#39;.ljust(30) + f\u0026#39;= {nonreload.cashback:.2f}\u0026#39;) print(f\u0026#39;Non-reload ppp profit\u0026#39;.ljust(30) + f\u0026#39;= {nonreload.profit:.2f}\u0026#39;) 按照每个月2张PPP算下来的返现是:\nNon-reload ppp cost = 35.48 Non-reload ppp cashback = 81.79 Non-reload ppp profit = 46.32 剩余的$2500 - $9.95 * 1.13 * 2 - $500 * 2 = $1477 肯定都是5x积分了,当然我是穷逼肯定不会都花完,就当$1000来算,这样最终的返现为:$1000 * 5 * 0.016 + $46.32 = $126.32。\nNon-reloadable的缺点就是每次只能买$500的卡,花完了就得再去超市买,所以如果想买超过$500的商品就比较麻烦了,可以搭配着gift card来使用。另外一个缺点就是最后剩下点钱不知道该怎么办了,本超级社恐肯定是不会厚着脸皮让店员separate to two bills的,我就都拿来充Presto卡了(Good News,最近Presto卡可以加到Apple Pay了,充值更方便,建议不要申请一张新的卡,可以更新Presto App后convert老卡到Apple Pay,这样一张卡更好管理,缺点就是实体卡就不能用了)。\nReloadable:\nReloadable由于需要耗费太多精力了,而且需要找菜店店员帮我充值,所以本超级社恐一直懒得搞,不过要是有人知道Richmond Hill或者Markham哪里可以买reloadable的ppp也麻烦告诉我一下😁。\n基本原理就是这样的,如果有一张其他的高返现的信用卡,比如说Rogers Bank新出的那张红卡,(不太清楚PPP能不能给这张卡还账单毕竟是张新卡,只是拿来举个例子)。0年费,而且只要是Rogers或者Fido用户都可以3%返现,那就可以平时的消费全部刷红卡,然后去超市用Cobalt买PPP用来还红卡的账单。\n当然PPP也是有一定费用的,PPP每次最多充$500,总金额最高是$2500,reload手续费是$6.95,月费是$4.95,每次付账单手续费是$1.95。付账单也有金额限制,每24小时最多$1000,每7天最多$2500,每30天最多$5000。\n假设我1个月花$2000,就需要买4张PPP来还账单:\nimport math COBALT_MONTHLY_FEE = 12.99 AMEX_VALUE = 0.016 # Let 1MR = $0.016 TAX_RATE = 1.13 PPP_NONRELOADABLE = 9.95 * TAX_RATE PPP_PER_MONTH = 2 PPP_RELOAD_FEE = 6.95 * TAX_RATE PPP_BILL_FEE = 1.95 * TAX_RATE PPP_MONTHLY_FEE = 4.95 * TAX_RATE MONTHLY_COST = 1000 # How much do I spend only by ppp per month PPP_BILL_AMOUNT = 1000 # How much PPP can pay bill at a time ROGERS_CASHBACK_RATE = 0.03 class RELOAD: def __init__(self): self.reload_cost = PPP_PER_MONTH * PPP_RELOAD_FEE self.card_cost = COBALT_MONTHLY_FEE + PPP_MONTHLY_FEE self.bill_cost = math.ceil(MONTHLY_COST / PPP_BILL_AMOUNT) * PPP_BILL_FEE self.rogers_cashback = MONTHLY_COST * ROGERS_CASHBACK_RATE self.cobalt_cashback = round(round(500 + PPP_RELOAD_FEE, 2) * 5) * PPP_PER_MONTH * AMEX_VALUE self.cost = self.reload_cost + self.card_cost + self.bill_cost self.cashback = self.rogers_cashback + self.cobalt_cashback self.profit = self.cashback - self.cost if __name__ == \u0026#34;__main__\u0026#34;: reload = RELOAD() print(f\u0026#39;Reload ppp total cost\u0026#39;.ljust(30) + f\u0026#39;= {reload.cost:.2f}\u0026#39;) print(f\u0026#39;Reload ppp total cashback\u0026#39;.ljust(30) + f\u0026#39;= {reload.cashback:.2f}\u0026#39;) print(f\u0026#39;Reload ppp profit\u0026#39;.ljust(30) + f\u0026#39;= {reload.profit:.2f}\u0026#39;) 所以同样是花$2000,这样最终的返现是:\nReload ppp cost = 54.40 Reload ppp cashback = 222.50 Reload ppp profit = 168.09 这样每个月比Non-reloadable多$41,也算是还行吧。\n现在Non-reloadable Paypower也是可以加入Apple Pay了,省的每次还要刷磁条卡刷完再签字显得很埋汰。\nJan 2024, TD Areoplan 最近薅了把TD的羊毛,开checking account绑定工资再还一次账单,能拿$400,新移民能waive掉第一年的年费。开saving账户存$5000能拿$100,存$10000拿$200。开TSFA,FHSA,RRSP 3个账户中的1个存$5000拿$150,3个中的2个各存$5000拿$350。信用卡本来想申请黑色的Areoplan卡结果被拒了说我不是PR,于是打算申请白色的,开卡消费一次送10000Areoplan积分,90天内消费$1000还能再拿10000Areoplan积分,第一年都是免年费的。算下来总共是$750的cash,20000Areoplan积分,免去了$292.4的月费。\n由于这张卡我就是打算薅开户奖励的,因此也不怎么在意返点。它年费是$89,买菜,加油,Air Canada消费1x积分,其他消费$1.5返1Areoplan积分,在星巴克消费可以多返50%Areoplan积分(也就是1.5x积分)。基本上都没有Cobalt好。\n黑卡的话是消费返10000Areoplan积分,半年之内消费$5000返25000Areoplan积分(Jan 3, 2024之后Approve的卡是20000),一年之内消费$7500返15000Areoplan积分(Jan 3, 2024之后Approve的卡是10000),纯开户奖励的话还真没有白卡好,而且必须要PR才行。\nFeb 2024, Rogers WEMC Rogers刚把自家的WEMC给升级了,于是马上办了这张卡,GCR给返了$50。所有消费2%返现,Fido, Rogers用户可以多redeem 50%也就是3%返现,这些跟Rogers Mastercard都一样。多出来的是美元的3%返现,等4月份充个ChatGPT会员看看是不是能4.5%的返现。不过这张卡对我来说也就是WEMC自带的Boingo可能会有点用,毕竟有Cobalt + PPP平时用的可能不怎么多,但不可否认是张很不错的抽屉卡,之后会留着PPP不够用了应急用,或者买一件超过500刀的东西用,或者刷美元时候用。\nMay 2024,AMEX Marriott 已经有计划5月份申请了AMEX Marriott Bonvoy了,目前是史高奖励,开卡后3个月内花$3000送65000万豪分,开卡后6个月内在汽油和旅游上的消费$1额外返3点万豪积分,GCR返$75, $60(又变成$75了)(80000 + $75 $60$75),refer的话能多5000积分(85000),按照1万豪分0.9cents来看的话还是GCR更划算一点。\n这个卡是个抽屉卡,年费$120,第二年开始(交完年费后8个星期)每年送一张35k免房券,在万豪消费$1返5积分,但是不免FX fee比较傻逼。\nSep 2024, AMEX Green 由于要出去旅游申请了AMEX绿卡,我用GCR申请的有CAD$30的返现,3个月刷满CAD$1000送10000MR,然后打电话给AMEX match到刷满CAD$1250送12500MR。\n最基础的无年费AMEX卡,花CAD$1返1分,申请着收藏用。\n","permalink":"https://kyxie.me/zh/blog/wool/credit-card/","summary":"Aug 2021, Bank of China 我的第一张信用卡是出国前和我爹一起去中国银行办的卓隽,我用我爹的副卡,不太清楚额度是多少。我只是刚到加拿大的前几天用这张卡,出了隔","title":"加拿大🇨🇦信用卡薅羊毛心得"},{"content":"安装过程 首先需要安装Hugo,安装Hugo需要利用一个包管理工具,对于Windows系统Hugo可以直接用Winget来安装,打开终端输入\nwinget install Hugo.Hugo.Extended 如果提示not recognized as the name of cmdlet,查找C:\\Users\\Username\\AppData\\Local\\Microsoft\\WindowsApps目录下有没有winget.exe,如果存在则添加这个目录到环境变量,否则去应用商店找winget,这是windows官方提供的windows包管理工具,一般系统里都会自带。\nHugo的tutorial介绍了如何创建一个项目,其中step2(.yml的config文件)和step3(下载主题)要根据PaperMod的guide来配置。\n文件介绍 content:用于放博客内容 data:不用管 layouts:自定义的HTML public:项目导出文件 resources:自定义的CSS和JavaScript static:存放的图片 themes:主题 进入themes/PaperMod则是PaperMod的相关代码,比较主要的目录有:\nassets:PaperMod的CSS和JavaScript代码 layouts:PaperMod的HTML Config.yml 建议直接按照【置顶】hugo博客搭建 | PaperMod主题 | Sulv\u0026rsquo;s Blog (sulvblog.cn)进行配置。\n创建文章 在终端输入hugo new 文章名称.md就会在content文件夹下创建markdown文件,文章头部信息可以修改这篇文章的属性\n常见的头部字段功能\n基本字段\ntitle: 页面标题,用于显示在浏览器标题、文章标题等地方\ndate: 创建日期,例如 2024-11-15T20:00:00+00:00\nlastmod: 最近修改时间,常用于生成更新时间\ndraft: 是否为草稿(true 表示草稿,生成站点时会被忽略)\nauthor: 作者名称 description: 页面描述,用于 SEO 和摘要\nslug: 页面友好的 URL 片段\nurl: 自定义页面 URL type: 页面类型(例如 post、page),决定模板的选择\n分类和标签\ncategories: 页面所属分类,例如 [\u0026ldquo;Tech\u0026rdquo;, \u0026ldquo;Programming\u0026rdquo;]\ntags: 页面标签,例如 [\u0026ldquo;Hugo\u0026rdquo;, \u0026ldquo;Static Site Generator\u0026rdquo;]\n页面内容控制\nsummary: 页面摘要,如果未指定,会自动从内容中提取\nweight: 排序权重,数值越小越靠前\naliases: 页面别名,用于创建 URL 重定向,例如 [\u0026quot;/old-url/\u0026quot;]\nlayout: 指定使用的布局模板,例如 single 或 list\noutputs: 输出格式,默认是 HTML,可以是 JSON、AMP 等\nresources: 页面资源,用于定义图片、PDF 等\nSEO和社交\nkeywords: 页面关键字,例如 [\u0026ldquo;Hugo\u0026rdquo;, \u0026ldquo;Markdown\u0026rdquo;, \u0026ldquo;SEO\u0026rdquo;]\ncanonical: Canonical URL,指定搜索引擎的首选页面地址\nimages: 页面分享时的图片链接(用于社交平台)\n创建子文件夹 可以直接用文件夹来管理目录,比如这是我中文博客的目录\n@Kunyang ➜ blog git(master) tree /F D:. │ _index.md │ ├───Life │\t... ├───Tech │ │ _index.md │ │ │ ├───Web │ │ Papermod.md | | ... │ │ _index.md │ │... │ └───Wool ... 可以看到每一层都有一个_index.md用来管理文件层级,文件中只包含头部信息。由于我使用了多语言,因此第一层不要添加url字段\n# zh/blog/_index.md title: \u0026#34;博客 📒\u0026#34; date: 2022-06-11T21:59:32-04:00 draft: false hidemeta: true 除此之外,在其他的子文件夹中的_index.md建议都添加url字段\n# zh/blog/tech/web/_index.md title: \u0026#34;建站 🚧\u0026#34; date: 2024-11-15T01:01:32-04:00 draft: false hidemeta: true url: \u0026#34;/zh/blog/tech/web/\u0026#34; weight: 1 可以使用weight字段来排序\n最后更新 可以修改post_meta.html加入\n{{- $scratch := newScratch }} {{ $date := .Date }} {{ $lastmod := \u0026#34;\u0026#34; }} {{- if not .Lastmod.IsZero -}} {{ $lastmod = .Lastmod }} {{- end }} {{- if not .Date.IsZero -}} {{- $scratch.Add \u0026#34;meta\u0026#34; (slice (printf \u0026#34;\u0026lt;span title=\u0026#39;%s\u0026#39;\u0026gt;%s\u0026lt;/span\u0026gt;\u0026#34; (.Date) (.Date | time.Format (default \u0026#34;January 2, 2006\u0026#34; site.Params.DateFormat)))) }} {{- end }} {{- if ne $lastmod $date -}} {{- $scratch.Add \u0026#34;meta\u0026#34; (slice (printf \u0026#34;\u0026lt;span title=\u0026#39;%s\u0026#39;\u0026gt;%s%s\u0026lt;/span\u0026gt;\u0026#34; (.Lastmod) (i18n \u0026#34;updated\u0026#34;) (.Lastmod | time.Format (default \u0026#34;January 2, 2006\u0026#34; site.Params.DateFormat)))) }} {{- end }} ... {{- with ($scratch.Get \u0026#34;meta\u0026#34;) }} {{- delimit . \u0026#34;\u0026amp;nbsp;·\u0026amp;nbsp;\u0026#34; -}} {{- end -}} 本地预览 在终端输入hugo server -D启动,建议新建一个.bat文件执行这条指令。 启动服务器后,打开浏览器,本地预览网址为localhost:1313。 网站部署 我用的是GitHub Page\n在GitHub里创建一个仓库,名称叫做你的名字.github.io 当我们本地预览没问题了的时候,在终端输入hugo -F --cleanDestinationDir,在public文件夹下就会生成输出文件 我们将public文件夹作为GitHub Page的本地仓库,每次生成输出文件就推送到GitHub上,GitHub Page就会自动帮我们部署了 自定义域名 建议早一点买个域名,避免配置完一遍结果更换了域名又得重新再配置一遍。\n点击GitHub右上角头像 -\u0026gt; Settings -\u0026gt; Pages -\u0026gt; Add a Domain\n填入自己的域名,我的是kyxie.me,然后会生成一个DNS TXT record,相当于一个用户名和密码,验证一下这个域名是属于你的\n我的域名是在cloudflare申请的,在kyxie.me -\u0026gt; DNS -\u0026gt; Records -\u0026gt; Add Records,添加三条规则,前两条为\nType Name Target CNAME @ kyxie.github.io CNAME www kyxie.github.io 第三条Type是TXT,Name为GitHub生成的Record,TTL选择Auto,Content是GitHub生成的Value\n然后在SSL/TLS -\u0026gt; Edge Certificates -\u0026gt; 勾选Always Use HTTPS\n配置完后回到GitHub,点击Verify,成功后会如图所示\n我的网站框架为Hugo,在static文件下添加一个文件CNAME,没有后缀名,内容为你的域名kyxie.me,然后publish出来push到GitHub就好了\n多语言 如果我们想要使用多语言(中英为例),就需要在content文件夹下准备两个文件夹,例如Chinese和English,一个放中文,另一个放英文。\n在config.yml中需要做以下修改:\ndefaultContentLanguage: en defaultContentLanguageInSubdir: true languages: en: languageName: \u0026#34;English\u0026#34; contentDir: content/English zh: languageName: \u0026#34;中文\u0026#34; contentDir: content/Chinese 搜索功能 分别在中英文的文件夹下创建search.md(hugo new search.md),修改文件头为\ntitle: \u0026#34;Search\u0026#34; date: ... draft: false layout: search config.yml中添加\nmenu: main: -identifier: Search name: Search url: search weight: ... Hover 主要在themes/PaperMod/assets/css/common/header.css中修改。\n左上角Home的hover\n.logo a:hover { transition: 0.15s; color: grey; } 社交媒体hover\nsvg:hover { transition: 0.15s; } .social-icons a:nth-child(1) svg:hover{ color: #C84370 !important; } .social-icons a:nth-child(2) svg:hover { color: grey !important; } ... nth-child可以设置各个图标的hover颜色\n黑夜模式和白天模式的hover\n#moon:hover { transition: 0.15s; color: deepskyblue; } #sun:hover { transition: 0.15s; color: gold; } menu中链接hover\n#menu a:hover { transition: 0.15s; color: grey; } 按钮hover,在themes/PaperMod/assets/css/common/profile-mode.css中修改\n.button:hover { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -ms-transform: scale(1.1); -o-transform: scale(1.1); /* box-shadow: 0 0 0 1px grey; */ transform: scale(1.1) translateZ(0) translate3d(0, 0, 0) rotate(0.01deg); } 自定义社交媒体图标 利用SVG图标制作网站,比如icons8,找到我们需要的图标,例如微信\n可以利用左侧菜单栏的Stroke调节线条粗细\n点击download,SVG Embed,自定义图标大小为24*24,然后点击copy HTML\n在themes/PaperMod/layouts/partials/svg.html中粘贴复制的HTML\n需要修改为fill=currentColor stroke=currentColor,才能适应白天黑夜切换\n微信和微博的图标\n{{- else if (eq $icon_name \u0026#34;wechat\u0026#34;) -}} \u0026lt;svg xmlns=\u0026#34;http://www.w3.org/2000/svg\u0026#34; x=\u0026#34;0px\u0026#34; y=\u0026#34;0px\u0026#34; width=\u0026#34;24\u0026#34; height=\u0026#34;24\u0026#34; viewBox=\u0026#34;0 0 50 50\u0026#34;\u0026gt; \u0026lt;g fill=\u0026#34;currentColor\u0026#34; stroke=\u0026#34;currentColor\u0026#34; stroke-width=\u0026#34;2\u0026#34;\u0026gt; \u0026lt;path d=\u0026#34;M 19 6 C 9.746094 6 2 12.359375 2 20.5 C 2 24.894531 4.292969 28.679688 7.835938 31.324219 L 5.179688 39.304688 L 13.472656 34.167969 C 15.1875 34.707031 17.082031 35 19 35 C 19.746094 35 20.472656 34.945313 21.195313 34.863281 C 23.378906 39.105469 28.328125 42 34 42 C 35.722656 42 37.316406 41.675781 38.796875 41.234375 L 45.644531 45.066406 L 43.734375 38.515625 C 46.3125 36.375 48 33.394531 48 30 C 48 23.789063 42.597656 18.835938 35.75 18.105469 C 34.398438 11.125 27.324219 6 19 6 Z M 19 8 C 26.308594 8 32.328125 12.351563 33.703125 18.011719 C 26.183594 18.148438 20 23.355469 20 30 C 20 31.019531 20.160156 32.003906 20.4375 32.941406 C 19.964844 32.980469 19.484375 33 19 33 C 17.101563 33 15.199219 32.710938 13.632813 32.15625 L 13.183594 32 L 8.820313 34.699219 L 10.1875 30.59375 L 9.5625 30.171875 C 6.082031 27.820313 4 24.445313 4 20.5 C 4 13.640625 10.65625 8 19 8 Z M 13 14 C 11.898438 14 11 14.898438 11 16 C 11 17.101563 11.898438 18 13 18 C 14.101563 18 15 17.101563 15 16 C 15 14.898438 14.101563 14 13 14 Z M 25 14 C 23.898438 14 23 14.898438 23 16 C 23 17.101563 23.898438 18 25 18 C 26.101563 18 27 17.101563 27 16 C 27 14.898438 26.101563 14 25 14 Z M 34 20 C 40.746094 20 46 24.535156 46 30 C 46 32.957031 44.492188 35.550781 42.003906 37.394531 L 41.445313 37.8125 L 42.355469 40.933594 L 39.105469 39.109375 L 38.683594 39.25 C 37.285156 39.71875 35.6875 40 34 40 C 27.253906 40 22 35.464844 22 30 C 22 24.535156 27.253906 20 34 20 Z M 29.5 26 C 28.699219 26 28 26.699219 28 27.5 C 28 28.300781 28.699219 29 29.5 29 C 30.300781 29 31 28.300781 31 27.5 C 31 26.699219 30.300781 26 29.5 26 Z M 38.5 26 C 37.699219 26 37 26.699219 37 27.5 C 37 28.300781 37.699219 29 38.5 29 C 39.300781 29 40 28.300781 40 27.5 C 40 26.699219 39.300781 26 38.5 26 Z\u0026#34;\u0026gt; \u0026lt;/path\u0026gt; \u0026lt;/g\u0026gt; \u0026lt;/svg\u0026gt; {{- else if (eq $icon_name \u0026#34;weibo\u0026#34;) -}} \u0026lt;svg xmlns=\u0026#34;http://www.w3.org/2000/svg\u0026#34; x=\u0026#34;0px\u0026#34; y=\u0026#34;0px\u0026#34; width=\u0026#34;24\u0026#34; height=\u0026#34;24\u0026#34; viewBox=\u0026#34;0 0 172 172\u0026#34;\u0026gt; \u0026lt;g fill=\u0026#34;currentColor\u0026#34; stroke=\u0026#34;currentColor\u0026#34; stroke-width=\u0026#34;4\u0026#34;\u0026gt; \u0026lt;path d=\u0026#34;M120.4,20.64c-2.67406,0 -5.25406,0.26875 -7.74,0.71219c-1.86781,0.3225 -3.1175,2.10969 -2.795,3.9775c0.3225,1.88125 2.10969,3.13094 3.9775,2.80844c2.17688,-0.38969 4.35375,-0.61813 6.5575,-0.61813c20.93563,0 37.84,16.90438 37.84,37.84c0,4.52844 -0.83312,8.85531 -2.31125,12.91344c-0.45687,1.16906 -0.25531,2.48594 0.5375,3.45344c0.80625,0.9675 2.05594,1.42437 3.29219,1.19594c1.23625,-0.22844 2.24406,-1.11531 2.63375,-2.29781c1.73344,-4.75687 2.72781,-9.87656 2.72781,-15.265c0,-24.65781 -20.06219,-44.72 -44.72,-44.72zM120.4,41.28c-1.46469,0 -2.84875,0.14781 -4.16562,0.37625c-1.86781,0.33594 -3.13094,2.10969 -2.795,3.99094c0.3225,1.86781 2.10969,3.1175 3.9775,2.795c1.00781,-0.17469 2.00219,-0.28219 2.98312,-0.28219c9.54063,0 17.2,7.65938 17.2,17.2c0,2.05594 -0.37625,4.01781 -1.06156,5.87219c-0.645,1.78719 0.28219,3.7625 2.06938,4.4075c1.78719,0.645 3.7625,-0.26875 4.4075,-2.05594c0.92719,-2.55312 1.46469,-5.32125 1.46469,-8.22375c0,-13.26281 -10.81719,-24.08 -24.08,-24.08zM72.46844,42.6775c-11.04562,0 -27.50656,8.66719 -42.18031,23.07219c-14.76781,14.76781 -23.40813,30.24781 -23.40813,43.57781c0,25.9075 33.12344,41.3875 65.88406,41.3875c42.47594,0 70.90969,-24.46969 70.90969,-43.91375c0,-11.87875 -10.07812,-18.35562 -19.08125,-21.23125c-2.15,-0.72562 -3.60125,-1.08844 -2.52625,-3.96406c0.72563,-1.73344 1.77375,-5.01219 1.77375,-9.36594c0,-4.945 -3.44,-9.23156 -10.32,-9.9975c-0.79281,-0.08062 -2.13656,-0.14781 -3.82969,-0.14781c-5.6975,0 -15.48,0.71219 -22.52125,3.66844c0,0 -1.38406,0.57781 -2.49938,0.57781c-1.00781,0 -1.80062,-0.48375 -1.11531,-2.37844c2.52625,-7.91469 2.16344,-14.39156 -1.80063,-18.00625c-2.23062,-2.23062 -5.42875,-3.27875 -9.28531,-3.27875zM72.46844,49.5575c1.43781,0 3.37281,0.215 4.43438,1.26313l0.1075,0.12094l0.12094,0.1075c1.54531,1.41094 1.51844,5.61687 -0.09406,10.72312c-1.38406,3.99094 -0.09406,6.75906 0.81969,8.04906c1.51844,2.16344 4.00437,3.39969 6.81281,3.39969c2.28438,0 4.39406,-0.79281 5.14656,-1.11531c5.50938,-2.31125 13.88094,-3.13094 19.87406,-3.13094c1.53187,0 2.60687,0.05375 3.07719,0.1075c2.78156,0.30906 4.1925,1.37063 4.1925,3.15781c0,3.23844 -0.77937,5.61688 -1.23625,6.73219l-0.05375,0.1075l-0.04031,0.09406c-1.075,2.88906 -1.06156,5.50938 0.04031,7.80719c1.62594,3.39969 4.82406,4.46125 6.54406,5.03906l0.28219,0.09406c5.34813,1.70656 14.2975,5.88562 14.2975,14.68719c0,7.90125 -6.81281,17.65688 -18.90656,25.16844c4.77031,-5.54969 7.47125,-12.05344 7.47125,-19.05437c0,-21.01625 -24.37562,-37.47719 -55.48344,-37.47719c-31.10781,0 -55.47,16.46094 -55.47,37.47719c0,0.645 0.01344,1.27656 0.05375,1.90812c-0.45687,-1.76031 -0.69875,-3.60125 -0.69875,-5.49594c0,-11.16656 7.59219,-24.91312 21.33875,-38.65969c14.86188,-14.59313 29.48188,-21.11031 37.36969,-21.11031zM69.875,82.33156c26.84813,0 48.60344,13.69281 48.60344,30.59719c0,16.89094 -21.75531,30.58375 -48.60344,30.58375c-26.83469,0 -48.59,-13.69281 -48.59,-30.58375c0,-16.90437 21.75531,-30.59719 48.59,-30.59719zM66.27375,89.52063c-10.38719,0.08062 -20.47875,5.76469 -24.85937,14.52594c-5.40188,11.13969 -0.36281,23.38125 12.59094,27.33187c12.95375,4.31344 28.42031,-2.16344 33.82219,-14.02875c5.38844,-11.5025 -1.43781,-23.73062 -14.39156,-26.95562c-2.365,-0.61813 -4.77031,-0.88688 -7.16219,-0.87344zM71.63531,104.06c1.98875,0 3.60125,1.59906 3.60125,3.58781c0,1.98875 -1.6125,3.60125 -3.60125,3.60125c-1.98875,0 -3.60125,-1.6125 -3.60125,-3.60125c0,-1.98875 1.6125,-3.58781 3.60125,-3.58781zM56.47781,107.64781c1.12875,0.01344 2.2575,0.18812 3.31906,0.55094c4.60906,1.46469 6.02,5.83188 3.18469,9.47344c-2.4725,3.64156 -8.12969,5.45563 -12.38938,3.64156c-4.23281,-1.81406 -5.29437,-6.19469 -2.82187,-9.46c1.85437,-2.74125 5.30781,-4.24625 8.7075,-4.20594z\u0026#34;\u0026gt; \u0026lt;/path\u0026gt; \u0026lt;/g\u0026gt; \u0026lt;path d=\u0026#34;\u0026#34; fill=\u0026#34;none\u0026#34;\u0026gt;\u0026lt;/path\u0026gt; \u0026lt;/svg\u0026gt; 目录栏目放侧边 详见:Hugo博客目录放在侧边 | PaperMod主题 | Sulv\u0026rsquo;s Blog (sulvblog.cn)。\nMarkdown渲染风格 详见:折腾 Hugo \u0026amp; PaperMod 主题 - Dvel\u0026rsquo;s Blog\n流量统计 这里我使用了不蒜子,在themes/PaperMod/layouts/partials/footer.html中修改:\n{{- if not (.Param \u0026#34;hideFooter\u0026#34;) }} \u0026lt;footer class=\u0026#34;footer\u0026#34;\u0026gt; {{- if site.Copyright }} \u0026lt;span\u0026gt;{{ site.Copyright | markdownify }}\u0026lt;/span\u0026gt; {{- else }} \u0026lt;span\u0026gt;\u0026amp;copy; {{ now.Year }} \u0026lt;a href=\u0026#34;{{ \u0026#34;\u0026#34; | absLangURL }}\u0026#34;\u0026gt;{{ site.Title }}\u0026lt;/a\u0026gt;\u0026lt;/span\u0026gt; {{- end }} \u0026lt;script async src=\u0026#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;span id=\u0026#34;busuanzi_container\u0026#34;\u0026gt; \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css\u0026#34;\u0026gt; Visitors: \u0026lt;span id=\u0026#34;busuanzi_value_site_uv\u0026#34;\u0026gt;\u0026lt;/span\u0026gt; Views: \u0026lt;span id=\u0026#34;busuanzi_value_site_pv\u0026#34;\u0026gt;\u0026lt;/span\u0026gt; \u0026lt;/span\u0026gt; \u0026lt;script\u0026gt; document.addEventListener(\u0026#34;DOMContentLoaded\u0026#34;, function () { const uvElement = document.getElementById(\u0026#39;busuanzi_value_site_uv\u0026#39;); const pvElement = document.getElementById(\u0026#39;busuanzi_value_site_pv\u0026#39;); const initialUv = 10000; const initialPv = 20000; if (!uvElement || !pvElement) { console.error(\u0026#34;Busuanzi elements not found.\u0026#34;); return; } const uvObs = new MutationObserver((mutationsList) =\u0026gt; { for (let mutation of mutationsList) { if (mutation.type === \u0026#39;childList\u0026#39;) { uvObs.disconnect(); mutation.target.innerHTML = parseInt(mutation.target.innerHTML || 0) + initialUv; break; } } }); const pvObs = new MutationObserver((mutationsList) =\u0026gt; { for (let mutation of mutationsList) { if (mutation.type === \u0026#39;childList\u0026#39;) { pvObs.disconnect(); mutation.target.innerHTML = parseInt(mutation.target.innerHTML || 0) + initialPv; break; } } }); uvObs.observe(uvElement, { childList: true }); pvObs.observe(pvElement, { childList: true }); }); \u0026lt;/script\u0026gt; \u0026lt;/footer\u0026gt; {{- end }} 其中initialUV和initialPV可以用于添加初始值,我由于换了个域名初始值都没了,可以在这里添加上\n插入B站,YouTube视频或PPT 详见:Hugo博客自定义shortcodes | Sulv\u0026rsquo;s Blog (sulvblog.cn)\n插入音乐播放器 详见:Hugo插入音乐播放器\n隐藏歌词:lrc-type=0\n修改全局字体 首先找到喜欢的字体,然后可以在Google Fonts中查询字体,我目前的文章字体为CodeNewRoman。Google Fonts会生成HTML和css,将HTML插入到themes/PaperMod/layouts/partials/extend_head.html中,将CSS插入到themes/PaperMod/assets/css/extended/blank.css。\nbody { font-family: \u0026#39;Code New Roman\u0026#39;, sans-serif; font-size: 1rem; line-height: 1.5; margin: 0; } 修改代码字体 与全局字体类似,区别为CSS代码插入的位置不同。\n.post-content pre, code { font-family: \u0026#39;Code New Roman\u0026#39;, sans-serif; max-height: 40rem; } 评论功能 详见:Hugo博客添加Twikoo评论 | Sulv\u0026rsquo;s Blog (sulvblog.cn)\nGmail邮箱配置 登录 Google Account,进入Security / Signing in to Google / 2-Step Verification / App passwords。点击Generate,并记住这个16位的密码\n在Twikoo中进行配置:\nSENDER_EMAIL:你的gmail邮箱\nSENDER_NAME:发件人名,我写的是Notification from Kunyang\u0026rsquo;s Blog\nSMTP_SERVICE:Gmail\nSMTP_HOST:smtp.gmail.com\nSMTP_PORT:587\nSMTP_SECURE:true\nSMTP_USER:你的gmail邮箱\nSMTP_PASS:16位的应用密码\nSMTP_SUBJECT:邮件主题,我写的是You have received a response from Kunyang\u0026rsquo;s Blog\nMAIL_TEMPLATE:邮件模板,我的是\n\u0026lt;div style=\u0026#34;border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;\u0026#34;\u0026gt; \u0026lt;h2 style=\u0026#34;border-bottom:1px solid #dddddd;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;\u0026#34;\u0026gt; You have received a new response from \u0026lt;a style=\u0026#34;text-decoration:none;color:#12ADDB;\u0026#34; href=\u0026#34;https://kyxie.github.io/\u0026#34; target=\u0026#34;_blank\u0026#34;\u0026gt;Kunyang\u0026#39;s Blog\u0026lt;/a\u0026gt; \u0026lt;/h2\u0026gt; ${PARENT_NICK} Your comment: \u0026lt;div style=\u0026#34;padding:0 12px 0 12px;margin-top:18px\u0026#34;\u0026gt; \u0026lt;div style=\u0026#34;background-color:#f5f5f5;padding:10px 15px;margin:18px 0;word-wrap:break-word;\u0026#34;\u0026gt; ${PARENT_COMMENT} \u0026lt;/div\u0026gt; \u0026lt;p\u0026gt; \u0026lt;strong\u0026gt;${NICK}\u0026lt;/strong\u0026gt; says: \u0026lt;/p\u0026gt; \u0026lt;div style=\u0026#34;background-color:#f5f5f5;padding:10px 15px;margin:18px 0;word-wrap:break-word;\u0026#34;\u0026gt; ${COMMENT} \u0026lt;/div\u0026gt; \u0026lt;p\u0026gt; Click \u0026lt;a style=\u0026#34;text-decoration:none;color:#12ADDB;\u0026#34; href=\u0026#34;${POST_URL}\u0026#34; target=\u0026#34;_blank\u0026#34;\u0026gt;to view the reply\u0026lt;/a\u0026gt;, welcome to \u0026lt;a style=\u0026#34;text-decoration:none;color:#12ADDB;\u0026#34; href=\u0026#34;${SITE_URL}\u0026#34; target=\u0026#34;_blank\u0026#34;\u0026gt;${SITE_NAME}\u0026lt;/a\u0026gt;。\u0026lt;br\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; 配置完成后评论消息就会有gmail邮箱发送的邮件提醒了,outlook邮箱配置见:关于邮箱配置的问题? · twikoojs/twikoo · Discussion #249 (github.com)。\n自定义邮箱回复模板 详见:自定义Twikoo邮件通知模板 | Guo Le\u0026rsquo;s Blog\n代码高亮 在两个地方修改\n一个是themes/PaperMod/assets/css/common/post-single.css:\n.post-content pre code { display: block; margin: auto 0; padding: 10px; /* 主要代码颜色 */ color: #abb2bf; font-weight: 200; overflow-x: auto; word-break: break-all; } 另一个是在themes/PaperMod/assets/css/hljs/an-old-hope.min.css,这是我自己修改的:\n/* 注释 */ .hljs-comment, .hljs-quote { font-weight: 200; color: #7f848e; } .hljs-deletion, /* html标签 */ .hljs-name, .hljs-regexp, .hljs-tag { font-weight: 200; color: #e06c75; } /* html属性 */ .hljs-tag { font-weight: 200; color: #d19a66; } /* css类名 */ .hljs-template-variable, .hljs-variable, .hljs-selector-class, .hljs-selector-id { font-weight: 200; color: #a9b600; } /* 内置函数 */ .hljs-built_in, .hljs-builtin-name { font-weight: 200; color: #56b6c2; } /* 函数输入 */ .hljs-params { font-weight: 200; color: #e5c07b; } /* 数字 */ .hljs-number { font-weight: 200; color: #d19a66; } /* css属性 */ .hljs-attribute { font-weight: 200; color: #ee7c2b; } /* 字符串 */ .hljs-addition, .hljs-bullet, .hljs-symbol, .hljs-string { font-weight: 200; color: #98c379; } /* 函数名称 */ .hljs-section, .hljs-title { font-weight: 200; color: #56b6c2; } /* 关键字 */ .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-link, .hljs-meta, .hljs-type { font-weight: 200; color: #c678dd; } .hljs { display: block; overflow-x: auto; background: #1c1d21; color: #c0c5ce; padding: 0.5em; } .hljs-emphasis { font-style: italic; } .hljs-strong { font-weight: 700; } /* 选中时的背景颜色 */ .hljs ::selection, .hljs::selection { background-color: #3d4556; } 代码边框圆角 themes/PaperMod/assets/css/common/post-single.css中修改:\n.post-content .highlight pre { background-color: var(--theme) !important; margin: 0; } 添加友链 详见:Hugo博客添加友链 | Sulv\u0026rsquo;s Blog (sulvblog.cn)\n图床 之前一直在使用Imgur的图床,但是国内的小伙伴说即使挂了梯子也看不到图片,现在有了域名打算利用Cloudflare自己做一个图床\n首先下载PicGo,Windows用户可以在GitHub下载.exe文件,Mac用户则建议使用Homebrew下载,命令为\nbrew install picgo --cask 下载完之后在LaunchPad出现了PicGo的图标,但是假如显示损坏让你移动到垃圾桶,这时只需要在终端输入\nsudo xattr -r -d com.apple.quarantine /Applications/PicGo.app 就可以解决问题了,安装完之后出现在顶部状态栏(Windows在右下角)\n然后回到Cloudflare,创建一个R2 bucket,我就叫img,将地址选在美国西部(这是因为后面的CDN也在美西)\n然后回到R2 Overview -\u0026gt; 右上角Manage R2 API Tokens,取个名字,然后选择Object Read and Write,可以选择只应用于特定的Bucket,也可以不选\n然后会生成一堆信息,有Token value,Access Key ID,Secret Access Key和jurisdiction-specific endpoints,这个页面只显示一遍,建议拿个小本本记好\n再来到img桶 -\u0026gt; Setting,里面有个R2.dev subdomain选择为Allow\n然后需要绑定一个域名,注意这里不能再使用kyxie.me了,但是可以设置一个子域名,比如img.kyxie.me,cloudflare会自动在DNS中添加一个Record\n回到PicGo,插件设置里搜索S3,然后安装S3插件,注意这里需要下载Node.js环境\n然后在图床设置中打开Amazon S3,然后配置信息,如图所示\n下面还有个自定义域名可以暂时填写img.kyxie.me,为了让国内小伙伴也能打开图片,我使用WebP Cloud Services将图像缓存,这样会打开更快\n注册用户后点击Create Proxy -\u0026gt; 选择美国Hillsboro, OR -\u0026gt; Proxy Origin Url就是http://img.kyxie.me,选择确定之后系统会生成一个url类似于http://xxx.webp.li,再把这个url粘贴到PicGo的自定义域名,配置好之后如图所示\n这样我们的图床就搭建好了,PicGo也可以使用了,经过测试国内的小伙伴也都能打开图片了\n","permalink":"https://kyxie.me/zh/blog/tech/web/papermod/","summary":"安装过程 首先需要安装Hugo,安装Hugo需要利用一个包管理工具,对于Windows系统Hugo可以直接用Winget来安装,打开终端输入 winget","title":"Hugo + PaperMod搭建技术博客"},{"content":"最近有一个项目需要使用GUI,又希望放在云端自动运行。一开始是打算用Windows的instance,尝试了一下基本上下载一个chrome都卡,AWS的免费用户又只能使用只有命令行的Ubuntu server。然后突发奇想诶我可不可以在Ubuntu server上安装一个GUI,查了一下这个方法似乎可行(其实还是不太可行,我已经打算放弃折腾了,不过倒是成功装上了GUI)。\n安装xrdp并enable,安装GUI就需要远程桌面系统,这是Linux的客户端\nsudo apt-get update sudo apt install xrdp -y sudo systemctl enable xrdp 我首先尝试的是gnome,尝试发现这个消耗资源太严重了,免费版用户用起来应该跟Windows一样卡\nsudo add-apt-repository ppa:gnome3-team/gnome3 sudo apt-get install gnome-shell ubuntu-gnome-desktop 后来我决定试试更轻量化的XFCE\nsudo apt install tasksel sudo tasksel install xubuntu-desktop sudo apt install xfce4 xfce4-goodies sudo update-alternatives --config x-session-manager sudo apt install lightdm sudo dpkg-reconfigure lightdm 设置密码\nsudo passwd ubuntu 在EC2 Security group中选择Allow All Traffic\n在MacBook中应用商店下载Windows App,这是Window开发的远程桌面应用,有一说一Windows给Mac开发的软件是真不错\n选择Add a PC,Computer使用AWS提供的DNS,用户名一般为ubuntu,密码为刚才设置的密码\n之后就可以连接上了\n但是尽管XFCE已经很轻量化了,我下载完Chrome之后还是觉得卡,于是放弃折腾了,AWS免费版用户不推荐这么做。\n","permalink":"https://kyxie.me/zh/blog/tech/others/aws-server-gui/","summary":"最近有一个项目需要使用GUI,又希望放在云端自动运行。一开始是打算用Windows的instance,尝试了一下基本上下载一个chrome都","title":"AWS Ubuntu Server安装GUI"},{"content":"Header 最近妈妈来了加拿大,打算带她去Calgary和Banff旅行,发现Banff旅游真的好多坑啊,正好写一篇游记博客,顺便记录一下Banff旅游攻略。\n首先是一些注意事项:\n进入Banff需要购买国家公园Pass,一天CAD$22,有效期到第二天的下午4点(因为4点查票的人就下班了)。我们Sep 19下午5点多才从Calgary提车,在Canmore和Banff之间有一个检票亭子(左侧道路是卖票亭,右侧道路可以bypass),我们从网上买了Sep 20开始的Pass,当我们路过的时候大概是晚上9点,但是还是补上了Sep 19号的(下次打算12点之后再试试,说不定就不用交当天的门票了)。网上买完Pass之后需要打印下来,放在租车玻璃前。 Lake Louise到Jasper以北都没有信号,出发前需要下载谷歌离线地图(开车强烈推荐Apple自带的地图)。 路上也没啥加油站,在大城市需要把油加满。 Sep 19 9.18晚上飞到的Calgary,然后9.19打算去购物,Alberta 5%的税是真香啊。下午5点去Enterprise租车(我终于满25岁了可以不用再交Yonge Driver Fee了,而且Cobalt的信用卡还自带租车保险简直美滋滋),然后准备出发去Banff,由于很早就定了YWCA酒店,所以价格也算是挺便宜的。\nSep 20 我们从这里买的套票,包含了Banff硫磺山的Gondola,冰原探险,和Golden的Skybridge。由于我们之前打算去Jasper的,结果野火把Jasper给烧了,我们不得不改变行程住在Golden,正好这票里的Golden Skybridge也派上了用场,还可以自由安排去各个景点的时间。\n但是有一点需要注意的是,在网上买票如果没有定下具体时间的话是需要到现场schedule的,举个例子,我们本来计划起床后在Banff转转,因为YWCA外边就是瀑布花园(Cascade of Time Garden),吃点饭去惊喜角(Surprise Corner Viewpoint),然后路上路过的湖(Hector Lake Viewpoint, Bow Lake, Peyto Lake)也可以游玩。这样到达冰原中心就大概1点多了,检票的时候告诉我们最早能坐3点的车,白白浪费两个小时。所以建议早晨先去冰原中心,观光完可以在游客中心吃个饭,然后回来的路上(如果晚上住在Canmore或者Banff的话)再顺着湖游玩(有人说下午2点左右是Peyto湖的最佳观赏时间)。\n虽然三四十年后Athabasca Glacier可能会消失,但是我觉得CAD$109的票价有点贵了,大部分时间都是在等车,到了冰原上只有半个小时的拍照时间。\n这天晚上我们住在了Canmore,Canmore景色真的很不错!\nSep 21 这天早晨我们从Canmore出发,逛了Banff镇,Banff Gondola(注意这里网上买了票,到现场也需要schedule,但是我们11:50的缆车,11:00排队没啥人我们就直接上了,不需要像冰原中心傻等)逛了逛Banff镇,然后下午就向Golden出发。下午到了Golden后游览了Golden Skybridge。\n其实Banff Gondola完全可以走着爬硫磺山,然后下缆车一般不检票,再坐缆车下山,Golden Skybridge更是完全没有玩的必要。\nSep 22 22号计划去Lake Louise和Moraine Lake,这两个地方需要提前两天预定Shuttle Bus否则无法停车,这个Shuttle Bus的出发地是Park and Ride - Lake Louise and Moraine Lake Bus Shuttle (1 Whitehorn Rd, Lake Louise, AB T0L 1E0)。由于我们头天晚上住在Golden,因此计划早起开车到这个停车场,然后坐车。在官网中点击Parks Canada shuttles,然后选择Day Use, Shuttle to Lake Louise and Moraine Lake,选好日期就可以预定了。后面选择会有两个,Lake Louise和Moraine Lake,这两个票买哪个都可以,选择哪个湖就是从滑雪场先去哪个湖,注意这里的时间则跟冰原中心一样,网上预约的几点就是几点发车,没错我们又在游客中心傻等了。我们先去的Moraine Lake再去的Lake Louise。Lake Louise旁边有一个Trail可以俯瞰费尔蒙酒店,难度也不大很合适。\n我们晚上是住在Lake Louise的,这是个非常错误的决定,应该前一天在这住,第二天逛完后住在哪里都可,这样就不需要像我们一样早起从Golden赶过来了。\nSep 23 今天是Banff旅行的最后一天,我们从Lake Louise出发看了看Morant\u0026rsquo;s Curve就回卡尔加里还车了。Morant\u0026rsquo;s Curve需要从Lake Louise不上Hwy1,走北边一条路,这条路能见到不少野生动物,所以最好慢点开车,不走hwy也非常有意思。我们见到了小鹿,但是可惜没有见到熊。这条小路可以通往Johnson Canyon,但是后面的路被封了,我其实挺想一直慢点走走到Banff的,如果不去Johnson Canyon的话提前从Castle Junction拐出来(听导航的话)。\nFooter 由于Jasper被火烧 -\u0026gt; 酒店选择错误 -\u0026gt; 在路上消耗的时间比较多 + 游客中心傻等,感觉还是白白浪费了不少时间。看来Banff的坑还是比较多的,下次的话争取合理安排时间多走几个Trail。\n但是无论如何Banff实在是太美啦!!放几张风景照\n\u003c!DOCTYPE html\u003e\rLake Louise Lake Louise Fairmont Viewpoint Morant\u0026#39;s Curve Banff Canmore Bow Lake Moraine Lake ","permalink":"https://kyxie.me/zh/blog/life/banff/","summary":"Header 最近妈妈来了加拿大,打算带她去Calgary和Banff旅行,发现Banff旅游真的好多坑啊,正好写一篇游记博客,顺便记录一下Banff旅","title":"Banff旅行游记"},{"content":"Sep 2021, Scotiabank 之前办学签来加拿大走SDS用的是Scotiabank,因此我第一张checking account是Scotiabank的。学生账户的话免年费和无限次e-Transfer,但是非学生就要交管理费了,不过我好多同学毕业之后并没有去银行更新身份,即使银行系统里的学生身份到期,也一直没有收取管理费。\n我个人并不喜欢五大行,主要原因还是要交管理费,否则的话要在checking account里存$4000(简直神坑,按照5%的利率算,$4000存一年也有$200刀的利息了,还不如交管理费)。后来PGWP下来以后想去关卡,发现不同的branch对管理费要求还不一样,有的branch必须要每一天结束时checking account的balance都要大于$4000,有的branch则要求月末最后一天balance高于$4000就行,全靠branch经理心情决定。我在hwy404 \u0026amp; hwy7交叉口那个branch关卡,阿三姐找阿三经理问了好长时间,人家非得要我11刀月费否则不给关,然后我跑到hwy404 \u0026amp; steels那个branch,华人小哥给我秒关,可见其管理混乱。\nBTW我觉得Scotiabank比其他银行的App做得要好,滑动滑块转账我是真喜欢,但是不知道为什么总感觉Scotiabank给人e-Transfer到账时间要慢一点。\nDec 2022, Tangerine 当时办这张卡是被Tangerine的信用卡吸引,可以自行设定2到3个categories 2%还是3%返现(后来发现这也不是什么好卡),我觉得有了checking account应该会更容易批信用卡(不仅不是什么好卡,反而因为我不是PR给我拒了),而且意识到自己学生身份快要过期所以想办一个不收管理费的checking account。因为主动开卡的意愿比较大,也没有研究该怎么做开卡任务,因此我好像一点开户奖励都没有捞到(血亏)。\n除此之外,同样是网上银行且受CDIC的保护,Tangerine给出的GIC利率总是比EQ低那么一点点,这导致我不怎么喜欢Tangerine,因此也不把它当作自己的主账户。Mar 2024 Tangerine提醒我账户长期未使用,如果2个月内checking account余额还是没有变动则要收取$10的Inactive fee,得,正好趁这功夫给你把账户全关了吧,于是我在May 2024把checking account关了。\n期间在往外转钱的时候从Wealthsimple link账户,当时Tangerine余额为$72.19,我转了$72.19(exactly the same amount)到Wealthsimple,过几天发现转账失败扣了我$45的overdraft fee。于是乎我给客服打电话问他为什么扣我钱,阿三小哥说你账户有$72.19你往外转了$72.19,然后两边尬了5秒钟,我又问所以你为什么扣我钱,阿三小哥说我问一下经理,回来之后表达歉意说要退我钱,然后又问我办不办overdraft protection1个月只要$5\u0026hellip;\n由于是Scotiabank旗下因此我觉得他往外e-Transfer也特别慢。\nMay 2023, Simplii 这张卡也是被他家的信用卡吸引,0年费吃饭4%返现。由于绑定工资可以拿到$400,refer能再拿$50便开了checking account。这张卡无管理费,无限次email transfer还是很爽的,可以去CIBC的ATM取现金,缺点就是一天取最多$200。\n个人对这张卡无感,目前已经清空了账户,Oct, 2024关卡。\nOct 2023, EQ Bank 这张卡是一张prepaid Mastercard,需要先转账到EQ bank的checking account中,再转到这个卡。我特别喜欢这张卡,觉得颜值超高,而且这张卡的包装方式很独特,是像个抽屉一样抽出来的。EQ Bank的GIC rate基本上是所有银行中最高的,而且受到CDIC保护,我的GIC基本上都是从EQ买的。\n这张卡在ATM取款是不收手续费的,更重要的是,它花外币也不收2.5%的手续费,而且还有0.5%的返现,我把ChatGPT,EZPass这种美元结算的都绑定在这张卡上(已经绑定到Rogers WEMC了他们家花美元虽然不免FX,但是3%的返现,还账单再1.5x合计是4.5%的返现)。因为平时花美元也不多,可能也就是去旅游的话会花,所以也没有单独去申请专门的外币卡。\nJan 2024, TD 最近薅了把TD的羊毛,开checking account绑定工资再还一次账单,能拿$400,新移民能waive掉第一年的年费。开saving账户存$5000能拿$100,存$10000拿$200。开TSFA,FHSA,RRSP 3个账户中的1个存$5000拿$150,3个中的2个各存$5000拿$350。\nTD这张卡如果接收从国内转来的汇款会收取CAD$37.5的手续费,本来是CAD$17.5,但是好像经过了一个中转银行就多收了CAD$20。\nMay 2024, Wealthsimple 这张卡与Wealthsimple的cash account相连,cash account里的现金4%的利率(绑定工资的话4.5%,资产超过$100000也是4.5,不知道有没有叠加,有叠加,如果账户总资产超过CAD $100000且将工资绑定在了cash account则5%利率),所有消费1%返现,感觉卡面设计的还挺好看的就办下来了。有论坛说这张卡似乎(确实)也免FX,这么一比那是全方位秒杀EQ Card了,我暂时两个卡先都开着。\n我试了一下去只收debit卡的饭店刷这个卡和EQ card被拒绝消费了,看来prepaid卡还是不能算是严格意义上的debit卡。\nOct 2024, BMO 由于有国内汇款需求,TD的手续费太高,于是开了BMO的Checking Account。120天5.5%的利率,CAD$600的Cash offer还算是挺不错了。\n","permalink":"https://kyxie.me/zh/blog/wool/checking-account/","summary":"Sep 2021, Scotiabank 之前办学签来加拿大走SDS用的是Scotiabank,因此我第一张checking account是Scotiabank的。学生账户的话","title":"我使用过的加拿大🇨🇦支票账户"},{"content":"常用链接 实时枫叶变色情况以及历史数据 预定门票,门票$21一天,可以提前5天预定 安省枫叶地图 阿冈昆公园地图 推荐的景点 周边:\n白求恩故居 Lions Lookout Dorset Lookout Tower: 印象里这个好像要收费 Big Bend Lookout 60号公路:\n13.8km: Hardwood Lookout Trail: 环形trail(1.61km, 85m, 34min),路上会有向右箭头指示trail的方向,如果想直接看Lookout可以不跟着箭头反着走,即向左走 20km: Art Center \u0026amp; Source Lake: 无需徒步,建议穿白色和浅蓝色的衣服 25km: Track \u0026amp; Tower Trail: 环形Trail(8km, 273m, 2h23min),难度比较高,但是和Booth\u0026rsquo;s Rock Trail风景有一拼 35km: Lake of Two Rivers: 是个沙滩,可以野餐 38km右拐: Centennial Ridges Trail: 环形trail(12.2km, 550m, 4h6min) 39.7km: Algonquin Lookout Trail: 环形trail(2.1km, 71m, 37min) 40.5km右拐: Booth\u0026rsquo;s Rock Trail: 环形trail(5.8km, 232m, 1h51min),需要预约车位 43km: Visitor Center 45km: Beaver Pond Trail: 环形trail(1.9km, 66m, 34min),但是不知道为什么我感觉这个最累,可能每次都放在最后一个走 50km: Brewer Lake: 不需要徒步,路边停车所以停车位有限,适合长焦拍风景 Footer 最后放几张照片吧\n\u003c!DOCTYPE html\u003e\rArt Center Found Lake ","permalink":"https://kyxie.me/zh/blog/life/algonquin/","summary":"常用链接 实时枫叶变色情况以及历史数据 预定门票,门票$21一天,可以提前5天预定 安省枫叶地图 阿冈昆公园地图 推荐的景点 周边: 白求恩故居 Lions Lookout Dorset Lookout Tower:","title":"Algonquin旅行攻略"},{"content":"前言 我就喜欢搞一些简洁而又花里胡哨的东西。\n教程基于Windows 11自带的Terminal。\n字体 我使用的字体是CodeNewRoman Nerd Font,这个字体同样是我博客的字体,可以从这里下载,下载后安装即可,也可以在VS Code上使用这个字体。\n下载 oh-my-posh winget install JanDeDobbeleer.OhMyPosh 终端设置 我这里直接修改了Windows PowerShell的配置,如果不想破坏默认的配置也可以新建一个配置文件。\n在配色方案的选项下,我选择的Campbell,但是我打开设置的json file里面把第一个主题的background改成了#0C0C0C,避免了纯黑的背景。\n在Windows PowerShell的常规选项下,取消勾选使用父进程目录,在外观选项下选取下载的字体CodeNowRoman Nerd Font。\n文件配置 在终端输入\necho $profile 找到这个文件,如果找不到自己新建一个。\n从这里选择一个自己喜欢的主题,点击主题名字进入相应的github并且下载.json源码,保存在本地,粘贴下面语句到这个文件中,修改路径为你保存的路径。\noh-my-posh init pwsh --config \u0026#39;C:/Users/Posh/jandedobbeleer.omp.json\u0026#39; | Invoke-Expression 保存后运行:\n. $profile FAQ 如果运行失败,可能需要更新PSReadLine。\n如果识别不了icon,大概率字体的问题,查看是否在PowerShell的页面下设置字体为Nerd字体。\n效果展示 ","permalink":"https://kyxie.me/zh/blog/tech/others/bash/","summary":"前言 我就喜欢搞一些简洁而又花里胡哨的东西。 教程基于Windows 11自带的Terminal。 字体 我使用的字体是CodeNewRoman Nerd Fo","title":"Windows 11 打造个性化终端"},{"content":" Dec 25, 2022,硕士毕业 Jan 3, 2023,收到毕业信 Apr 27, 2023,收到CELPIP成绩,入池,其实毕业之前就该考出来的,没必要等着PGWP下来再申请省提名,白浪费了半年多 Jun 6, 2023,被捞,当天提交申请 Jun 27, 2023,补交材料 Jun 28, 2023,收到DIP Jul 25, 2023,收到省提名信,这里估摸着差不多了提前把无犯罪证明,出生证明,身份证,户口本公正或者翻译了,还能再省点时间(身份证和户口本是Optional) Aug 1, 2023,提交联邦申请 Dec 1, 2023,收到AOR和指纹信,成功link到IRCC Dec 12, 2023,收到PAL Dec 14, 2023,上午录指纹的时候发现邮箱里有体检信,提醒一下如果有办学签时候的体检证明一块交了,到时候可以waive掉,我这里找不到了只能再做一次体检,验尿抽血胸片,怒花270刀保险还不报销😭,由于可以walk in下午我直接去做了体检 Feb 14, 2024,被要求提交简历,看来要被安调 Feb 15, 2024,tracker上F12出现17 security被安调了,这一时半会出不了安省了,怪你电太牛逼吧 未完待续\u0026hellip;希望早点收到枫叶卡,早点入籍了好让我南下赚钱 ","permalink":"https://kyxie.me/zh/blog/life/pr/","summary":"Dec 25, 2022,硕士毕业 Jan 3, 2023,收到毕业信 Apr 27, 2023,收到CELPIP成绩,入池,其实毕业之前就该考出来的,没必要等着PGWP下来再申","title":"OINP移民加拿大🇨🇦时间线"},{"content":"前言 我有时需要使用虚拟机上的Linux环境,但是有些软件在Linux是上是没有的,需要用Windows的软件但是用Linux的数据。于是找到了个办法将Linux映射为Windows的一个本地磁盘,这样Windows的软件就可以直接打开Linux的文件夹了。\nLinux 假如我现在登录用户为user1,我希望把home/user1的所有文件共享给Windows,当然也可以新建用户和新建文件夹来作为共享文件夹。\n安装Samba:\nsudo apt update sudo apt install samba 编辑Samba配置文件:\nsudo nano /etc/samba/smb.conf 在文本末尾添加:\n[Name] path = /home/user1/shared read only = no browsable = yes [Name]是共享文件夹的名称,会显示在Windows磁盘上\n设置Samba账户密码:\nsudo smbpasswd -a user1 sudo smbpasswd -e user1 重启Samba服务:\nsudo systemctl restart smbd Windows 打开文件资源管理器 右键点击“此电脑”,选择“映射网络驱动器” 选择一个驱动器字母(例如Z:) 在文件夹栏中输入:\\\\Linux IP Address\\Name 完成剩余步骤 ","permalink":"https://kyxie.me/zh/blog/tech/router/samba/","summary":"前言 我有时需要使用虚拟机上的Linux环境,但是有些软件在Linux是上是没有的,需要用Windows的软件但是用Linux的数据。于是找到","title":"使用Samba将Linux映射为Windows磁盘"},{"content":"安装 Ubuntu sudo apt update sudo apt upgrade sudo apt install wireguard OpenWrt 所需插件详见:使用树莓派4B+安装OpenWrt用作旁路由 | Kunyang\u0026rsquo;s Blog\n配置Wireguard 进入/etc/wireguard,并生成密钥对\nsudo -i cd /etc/wireguard umask 077 wg genkey | tee privatekey | wg pubkey \u0026gt; publickey 编辑配置文件wg0.conf\n[Interface] PrivateKey = [LINUX_PRIVATE_KEY] Address = 10.0.0.1/24 ListenPort = 51820 [Peer] PublicKey = [WINDOWS_PUBLIC_KEY] Endpoint = [WINDOWS_IP]:51820 AllowedIPs = 10.0.0.2/32 启动wireguard\nsudo wg-quick up wg0 Windows配置wireguard 从这里下载wireguard app\nAdd Tunnel → Add empty tunnel\n编写配置文件\n[Interface] PrivateKey = [WINDOWS_PRIVATE_KEY] ListenPort = 51820 Address = 10.0.0.2/24 [Peer] PublicKey = [LINUX_PUBLIC_KEY] AllowedIPs = 10.0.0.0/24 Endpoint = [LINUX_IP]:51820 点击运行\n","permalink":"https://kyxie.me/zh/blog/tech/router/wireguard/","summary":"安装 Ubuntu sudo apt update sudo apt upgrade sudo apt install wireguard OpenWrt 所需插件详见:使用树莓派4B+安装OpenWrt用作旁路由 | Kunyang\u0026rsquo;s Blog 配置Wireguard 进入/etc/wiregu","title":"Wireguard配置"},{"content":" 假设我们有两台Linux虚拟机A和B,使用A和B互相充当Server和Client\nTLS模式 假设我们使用A来充当server,B来充当client\nTLS Server 在A中下载OpenVPN\nsudo apt-get install openvpn 在/usr/share/doc/openvpn/examples/sample-keys/文件夹下有好多keys,在server中,复制ca.crt,server.key,server.crt,dh2048.pem到/etc/openvpn/tls-server\nsudo cp /usr/share/doc/openvpn/examples/sample-keys/{ca.crt,server.key,server.crt,dh2048.pem} /etc/openvpn/tls-server 编写服务器配置文件\nport 1194 proto udp dev tun0 ca ca.crt cert server.crt key server.key dh dh2048.pem server 10.8.0.0 255.255.255.0 keepalive 10 120 user nobody group nogroup persist-key persist-tun verb 3 如果使用TCP连接,则修改为\nport 1194 proto tcp-server dev tun0 ca ca.crt cert server.crt key server.key dh dh2048.pem server 10.8.0.0 255.255.255.0 keepalive 10 120 user nobody group nogroup persist-key persist-tun verb 3 启动OpenVPN Server\ncd /etc/openvpn/tls-server sudo openvpn --config server.conf 这时如果查看IP地址可以看到tun0接口,地址是10.8.0.1\nTLS Client 在B中下载OpenVPN\nsudo apt-get install openvpn 在A中/usr/share/doc/openvpn/examples/sample-keys/下找到ca.crt,client.key,client.crt,复制到B中\n# In B sudo scp [A_usrname]@[A_addr]:/usr/share/doc/openvpn/examples/sample-keys/{ca.crt,client.crt,client.key} /etc/openvpn/tls-client 编写server.conf\nclient dev tun0 remote [A_addr] 1194 udp ca ca.crt cert client.crt key client.key user nobody group nogroup persist-key persist-tun verb 3 如果是TCP连接则\nclient dev tun0 remote [A_addr] 1194 tcp-client ca ca.crt cert client.crt key client.key user nobody group nogroup persist-key persist-tun verb 3 运行OpenVPN Client\ncd /etc/openvpn/tls-client sudo openvpn --config client.conf 这时如果执行\nping 10.8.0.1 成功,说明OpenVPN成功建立\nPSK模式 PSK模式不需要配置复杂的keys,比较简单,但是安全性也会随之降低,这里我们同样让A充当Server,B充当Client\nPSK Server 在A中生成psk.key,并且复制一份给B\n# In A cd /etc/openvpn/psk-server openvpn --genkey --secret psk.key # In B cd /etc/openvpn/psk-client scp [A_usrname]@[A_addr]:/etc/openvpn/psk-server/psk.key . 编写server.conf\ndev-type tun dev tun0 ifconfig 10.8.0.6 10.8.0.1 keepalive 10 120 persist-tun secret psk.key verb 0 # proto tcp-server 如果是TCP连接,则取消注释最后一行\n启动OpenVPN\ncd /etc/openvpn/psk-server sudo openvpn --config server.conf PSK Client 编写client.conf\ndev-type tun dev tun0 remote [A_addr] 1194 udp ifconfig 10.8.0.1 10.8.0.6 keepalive 10 120 persist-tun secret psk.key verb 0 如果是TCP连接\ndev-type tun dev tun0 remote 10.10.200.120 1194 tcp-client ifconfig 10.8.0.1 10.8.0.6 keepalive 10 120 persist-tun secret psk.key verb 0 ","permalink":"https://kyxie.me/zh/blog/tech/router/openvpn/","summary":"假设我们有两台Linux虚拟机A和B,使用A和B互相充当Server和Client TLS模式 假设我们使用A来充当server,B来充当cli","title":"OpenVPN的简单配置"},{"content":"Character 判断是否为字母或数字:\nboolean res = Character.isLetterOrDigit(char); 转小写:\nchar res = Character.toLowerCase(char); 下一个字符:\n\u0026#39;b\u0026#39; == (char) (\u0026#39;a\u0026#39; + 1); Integer 最大值最小值:\nint max = Integer.MAX_VALUE; int min = Integer.MIN_VALUE; 比较相等:\nInteger a = 1; Integer b = 1; a == b;\t// true Integer c = 200; Integer d = 200; c == d;\t// false Objects.equals(c, d);\t// true Array 创建数组:\nint[] array = new int[5]; int[] array = new int[]{1,2,3,4}; int[] array = {1,2,3,4}; int[][] array = {{1,2}, {3,4}}; 引用:\narray[3]; 获取长度:\narray.length; 快速初始化:\n// 我们要给这个Map的值快速填充 Map\u0026lt;Integer, List\u0026lt;Integer\u0026gt;\u0026gt; map = new HashMap\u0026lt;\u0026gt;(); map.put(1, Arrays.asList(1, 2, 3)); map.put(2, Arrays.asList(2, 3, 4)); 排序:\nArrays.sort(array); // int[] 不能直接做降序排列 // 想做降序排列只能用Integer[] Integer[] array = new Integer[2]; Arrays.sort(array, Comparitor.naturalOrder());\t// 升序排列 Arrays.sort(array, Comparator.reverseOrder());\t// 降序排列 二维数组排序:\nint[][] array = new int[][]{{1, 2}, {2, 3}}; Arrays.sort(array, (o1, o2) -\u0026gt; o1[0] - o2[0]);\t// 按照二维数组的第一个元素从小到大排序 Arrays.sort(array, (o1, o2) -\u0026gt; o1[1] - o2[1]);\t// 按照二维数组的第二个元素从小到大排序 复制子数组:\n// array: 原始数组,不包括to的结束索引 subArray = Arrays.copyOfRange(array, from, to); // array = [4, 2, 5, 1, 6, 3, 7] subArray = Arrays.copyOfRange(array, 0, 3); // subArray = [4, 2, 5] 打印:\nSystem.out.println(Arrays.toString(array)); 填满:\nint[] array = new int[]; int num; Arrays.fill(array, num);\t// array全部元素等于num String 创建字符串:\nString string = \u0026#34;java\u0026#34;; 指定位置的字符\nchar charAt3 = string.charAt(3);\t// charAt3 = \u0026#39;a\u0026#39; 字符串相等:\nString string1 = \u0026#34;abc\u0026#34;; String string2 = \u0026#34;abc\u0026#34;; string1.equals(string2); 字符串转整数:\nString string = \u0026#34;123\u0026#34;; int integer = Integer.parseInt(string); 字符串长度:\nint length = string.length(); 截取字符串:\nString sb = \u0026#34;abcdef\u0026#34;; String str = sb.substring(0, 1);\t// str = \u0026#34;a\u0026#34;; String str = sb.substring(1);\t// str = \u0026#34;bcdef\u0026#34;;\t如果只有一个参数则为beginIndex 字符的位置:\nString str = \u0026#34;abc\u0026#34;; int index = str.indexOf(b);\t// index = 1 字符串转字符数组:\nString str; char[] temp = str.toCharArray(); 字符串分割:\nString str = \u0026#34;hello world\u0026#34;; String[] word = str.split(\u0026#34; \u0026#34;);\t// word = [\u0026#34;hello\u0026#34;, \u0026#34;world\u0026#34;] // 这里必须是字符串 // 如果有两个空格连在一起,会在数组中加入一个\u0026#34;\u0026#34;(空字符串) 将字符串数组合并为长字符串(中间插入):\nString[] words = new String[]{\u0026#34;hello\u0026#34;, \u0026#34;world\u0026#34;}; String str = String.join(\u0026#34; \u0026#34;, words); // str = \u0026#34;hello world\u0026#34;; 字符串替换:\nString str = \u0026#34;a! b\u0026#34;; str = str.replace(\u0026#34;!\u0026#34;, \u0026#34; \u0026#34;);\t// str = \u0026#34;a b\u0026#34;; // 字符或者字符串都可以替换 删除字符串头尾的空格:\nString str = \u0026#34; abc \u0026#34;; str.trim();\t// str = \u0026#34;abc\u0026#34; 字符串拼接:\nString str = \u0026#34;abc\u0026#34;; System.out.println(str + \u0026#34;def\u0026#34;);\t// 可以直接使用+ Stack 创建 stack:\nDeque\u0026lt;Integer\u0026gt; stack = new ArrayDeque\u0026lt;\u0026gt;(); 栈顶:\nstack.peek() 入栈:\nstack.push(); 出栈:\nstack.pop(); 栈是否为空:\nstack.isEmpty(); 栈的长度:\nstack.size(); ArrayList 创建列表:\nList\u0026lt;Integer\u0026gt; array = new ArrayList\u0026lt;\u0026gt;(); List\u0026lt;Integer\u0026gt; array = new ArrayList\u0026lt;\u0026gt;(Arrays.asList(1, 2, 3, 4));\t// 初始化值 添加元素:\narray.add(1);\t// List只能在末尾添加元素,在中间插入元素会导致额外的内存开销,可以选择使用LinkedList 指定位置的元素:\narray.get(0); 列表中是否存在某元素:\narray.contains(0); 删除列表元素:\narray.remove(0);\t// 删除array[0] array.remove(Integer.valueOf(0));\t// 删除元素0 列表大小:\narray.size(); 判断列表是否为空:\narray.isEmpty(); 清空列表:\narray.clear(); 升序排列:\narray.sort(Comparator.naturalOrder()); 降序排列:\narray.sort(Comparator.reverseOrder()); 修改值:\narray.set(int index, int value); 反转:\nCollections.reverse(array); HashMap 创建一个哈希映射:\nMap\u0026lt;Integer, Integer\u0026gt; map = new HashMap\u0026lt;\u0026gt;(); 存储键值对(修改键值对):\nmap.put(key, value); // 如果不知道key存不存在 map.putIfAbsent(key, defVal); 获取 key 的内容:\nmap.get(key); // 如果不知道key存不存在 map.getOrDefault(key, defVal); // 常见用法 map.put(key, map.getOrDefault(key, 0) + 1); 计算:\n// 键不存在时执行的操作 map.computeIfAbsent(key, k -\u0026gt; mappingFunc); // 键存在时执行的操作 map.computeIfPresent(key, (k, v) -\u0026gt; mappingFunc); 查询是否存在 key:\nmap.containsKey(key); 键集合和值集合:\n// 返回一个Collections\u0026lt;V\u0026gt;视图,keys组成的集合 map.keySet(); // 返回一个Collections\u0026lt;V\u0026gt;视图,values组成的集合 map.values(); // 假设map为{1: {1, 2, 3}, 2: {2, 3, 4}} map.keySet = {1, 2}; map.values = {{1, 2, 3}, {2, 3, 4}}; 遍历键值对:\n// 遍历key for (Integer key : map.keySet()) { } // 遍历value for (Integer value : map.values()) { } // 如果需要同时访问键和值,使用map.entrySet()会更直观 for (Map.Entry\u0026lt;Integer, Integer\u0026gt; entry : map.entrySet()) { Integer key = entry.getKey(); Integer value = entry.getValue(); } 是否为空:\nmap.isEmpty(); 删除Key:\nmap.remove(key); 大小:\nmap.size(); HashSet 创建哈希表:\nSet\u0026lt;Integer\u0026gt; set = new HashSet\u0026lt;\u0026gt;(); 添加元素:\nset.add(); 判断元素是否存在:\nset.contains();\t// HashSet查找元素要优于ArrayList 删除元素:\nset.remove(); 清空:\nset.clear(); 遍历:\nfor (int temp : set) { ... } StringBuilder 创建 StringBuilder:\nStringBuilder sb = new StringBuilder(); 在末尾添加字符或字符串:\nsb.append(char); 在末尾删除字符:\nsb.deleteCharAt(sb.length() - 1); 长度:\nsb.length(); 转化为 String:\nsb.toString(); 取反:\nsb.reverse(); 插入:\nsb.insert(0, \u0026#34;abcd\u0026#34;);\t// 在第0个元素插入\u0026#34;abcd\u0026#34; 清空:\nsb.setLength(0); 取字符:\nsb.charAt(i); 修改位置的字符:\nsb.setCharAt(i); Queue 创建queue:\nQueue\u0026lt;Integer\u0026gt; q = new LinkedList\u0026lt;\u0026gt;(); 加入元素:\nq.offer(1); 删除元素(先进先出):\nq.poll(); 队首元素:\nq.peek(); 队列大小:\nq.size(); 是否为空:\nq.isEmpty(); 队列清空:\nq.clear(); Deque 创建Deque:\nDeque\u0026lt;Integer\u0026gt; deque = new ArrayDeque\u0026lt;\u0026gt;(); 队尾添加元素:\ndeque.offerLast();\t// queue的用法 队首弹出元素:\ndeque.pollFirst();\t// queue的用法 取队首元素:\ndeque.peekFirst();\t// queue的用法 队首添加元素:\ndeque.offerFirst(); 队尾弹出元素:\ndeque.pollLast(); 取队尾元素:\ndeque.peekLast(); LinkedList 新建链表:\nLinkedList\u0026lt;Integer\u0026gt; link = new LinkedList\u0026lt;\u0026gt;(); 头部插入:\nlink.addFirst(); 末尾插入:\nlink.addLast(); link.add(); 指定位置插入:\nlink.add(int index, int Ele); 清空:\nlink.clear(); 删除并返回第一个:\nlink.removeFirst(); 删除并返回最后一个:\nlink.removeLast(); 删除特定位置:\nlink.remove(int index); 删除特定元素:\nlink.remove(Object o); link.remove(Integer.valueOf(2)); 重设:\nlink.set(); 头部取值:\nlink.getFirst(); 尾部取值:\nlink.getLast(); 特定位置取值:\nlink.get(int index); 是否存在:\nlink.contains(int key); 遍历:\n// 不涉及元素增添或删除可以用for each for (String element : link) { } // 涉及到则需要使用迭代器 Iterator\u0026lt;String\u0026gt; iterator = link.iterator();\t// 初始化时指向哑节点 while (iterator.hasNext()) { String element = iterator.next(); } PriorityQueue 创建优先队列:\n// 小根堆 (Min Heap) PriorityQueue\u0026lt;Integer\u0026gt; pq = new PriorityQueue\u0026lt;\u0026gt;(); // 大根堆 (Max Heap) PriorityQueue\u0026lt;Integer\u0026gt; pq = new PriorityQueue\u0026lt;\u0026gt;((a, b) -\u0026gt; b - a); 插入元素:\n// 每次插入一个元素,时间复杂度是O(log k),其中k是堆中当前元素的个数 // 将n个元素逐个push到一个空的大根堆的时间复杂度为O(n log n) pq.offer(); 取堆顶:\npq.peek(); 弹出堆顶:\n// 同样,pop一次的时间复杂度为O(log n) // n个元素则为O(n log n) pq.poll(); 删除特定元素:\npq.remove(); 堆大小:\npq.size(); AtomicInteger 多线程中的integer,线程操作对其是原子性的,不会被其他线程打断。\n创建:\nAtomicInteger a = new AtomicInteger(0); 获取当前值:\nint value = a.get(); 设置值:\na.set(2); 先获取再设置:\nint oldValue = a.getAndSet(20); 先比较再设置:\nboolean updated = a.compareAndSet(20, 43); // 如果a == 20,则将a = 43,updated = true // 如果a != 20,则将a不更新,updated = false 加一,返回加一后的值:\nint incrementedValue = a.incrementAndGet(); 减一,返回减一后的值:\nint decrementedValue = a.decrementAndGet(); 互相转换 // int转String int i; String str = String.valueOf(i); // String转int String str; int i = Integer.parseInt(str); // char转int char ch; int i = ch - \u0026#39;0\u0026#39;; // int转char int i; char ch = (char) (i + \u0026#39;0\u0026#39;); // String转char[] String str; char[] ch = str.toCharArray(); // char[]转String char[] ch; String str = Arrays.toString(ch);\t// 转化后有[]包裹 // char转String char ch = \u0026#39;a\u0026#39;; String str = ch + \u0026#34;\u0026#34;; // ArrayList转Integer[] List\u0026lt;Integer\u0026gt; list; Integer[] array = list.toArray(new Integer[list.size()]); // Integer[]转ArrayList Integer[] array; List\u0026lt;Integer\u0026gt; list = Arrays.asList(array); 坑 Math.ceil:\ndouble Math.ceil(double a);\t// 原函数 Math.ceil(24 / 23);\t// 1.0 Math.ceil(22 / 23);\t// 0.0 Math.ceil((double) 24 / 23);\t// 2.0 (int) Math.ceil((double) 24 / 23);\t// 2 Math.pow:\nMath.pow(10, 9);\t// 如果想求次方必须要用pow函数,返回double 10 ^ 9;\t// 这里表示的是亦或而不是次方 二维数组:\nint[][] a = new int[][] {{1, 2}, {3, 4}}; int[] b = a[1];\t// b = [3, 4] b[1] = 100; // a = [[1, 2], [3, 100]] ","permalink":"https://kyxie.me/zh/blog/tech/others/java/","summary":"Character 判断是否为字母或数字: boolean res = Character.isLetterOrDigit(char); 转小写: char res = Character.toLowerCase(char); 下一个字符: \u0026#39;b\u0026#39; == (char) (\u0026#39;a\u0026#39; + 1); Integer 最大值最小值: int max = Integer.MAX_VALUE; int min = Integer.MIN_VALUE; 比较相等: Integer a = 1; Integer b = 1; a == b; // true","title":"Java Cheat Sheet"},{"content":"Linux 下载OpenLDAP:\nsudo apt update sudo apt install slapd ldap-utils sudo apt install ldap-utils 配置OpenLDAP:\nsudo dpkg-reconfigure slapd DNS domain name: example.org\nPassword: root\n创建user.ldif:\n# ldap是username dn: uid=ldap,dc=example,dc=org objectClass: inetOrgPerson objectClass: posixAccount uid: ldap sn: LDAP givenName: LDAP cn: LDAP User displayName: LDAP User uidNumber: 10000 gidNumber: 10000 homeDirectory: /home/ldap loginShell: /bin/bash 把user加入OpenLDAP服务器:\nldapadd -x -D \u0026#34;cn=admin,dc=example,dc=org\u0026#34; -W -f user.ldif 启动和查看OpenLDAP的状态:\nsudo systemctl start slapd sudo systemctl status slapd 查看当前已有的用户:\nldapsearch -x -LLL -b \u0026#34;dc=example,dc=org\u0026#34; \u0026#34;(objectclass=inetOrgPerson)\u0026#34; uid userPassword 修改用户密码:\nldappasswd -x -D \u0026#34;cn=admin,dc=example,dc=org\u0026#34; -W -S \u0026#34;uid=ldap,dc=example,dc=org\u0026#34; ","permalink":"https://kyxie.me/zh/blog/tech/router/ldap/","summary":"Linux 下载OpenLDAP: sudo apt update sudo apt install slapd ldap-utils sudo apt install ldap-utils 配置OpenLDAP: sudo dpkg-reconfigure slapd DNS domain name: example.org Password: root 创建user.ldif: # ldap是username","title":"Linux配置LDAP Server"},{"content":"Wealthsimple 开户 使用推荐码VXU-UQ开设账号,在开户后的30天内存$1即可获得$25奖励。\nFeatures Core Premium 资金要求 $0 $100000 Commission Fee $0 $0 Cash Account 4% 4.5% USD FX 1.5% 1.5% 期权交易 $2 $0.75 Crypto Trading Fee 2% 1% USD Account $10 / mon $0 如果购买美元计价的股票买卖都是1.5%,加起来就是3% 如果是premium,买卖不收取1.5%手续费,但是加币转美元还是要收取外汇转换费1.5% 如果把工资的Direct Deposit绑在cash account上的话利率为4.5%,并且利率是可以和其他因素叠加的,比如我是Premium用户,我也绑了工资,那我的利率就是5%,详细信息可以看:我使用过的加拿大🇨🇦支票账户 | Kunyang\u0026rsquo;s Blog (kyxie.github.io) Questrade 开户 使用邀请码855908417478550开户,存入$1000可收到奖励$50。\nFeatures 交易股票每股$0.01,min $4.95 to max $9.95 买ETF$0,卖$0.01,min $4.95 to max $9.95 交易期权需要$9.95 + $1 / contract Questrade将部分账户金额头寸转移到其他金融机构的收费从原先的$25升至$150 TFSA RRSP无年费 可以存美元进RRSP USD Margin rate为3.25% IBKR 开户 使用https://ibkr.com/referral/kunyang118进行开户。\n推荐人奖励:每推荐一位客户成功开立个人账户或联名账户并使账户的净清算价值在一年之中保持在USD$10000以上,推荐人获得USD$200的奖金。\n被推荐人奖励:被推荐人在账户中每存入USD$100的资产(现金或其他资产)可获得USD$1的IBKR股票,最高可获得USD$1000的股票,平均余额必须至少保有一年方可使股票解禁。\nFeatures Trading Fee Fixed:每股USD $0.005,每次交易最低收USD $1,最高收交易价值的1% Tiered:低于300k Shares时,佣金为每股USD $0.0035,最低收USD $0.35,最高收交易价值的1%。但此收费方式还要加(或减)交易所费,清算费和规管等其他费用(加股交易Fixed每股CAD$0.01,最低CAD$1,最高为交易价值的0.5%) 对于大量资金和交易的客户,Fixed会比较划算。如果是少量资金入场的小伙伴,每次想一股一股的买,那Tiered更合适 兑换美金:每笔收换汇金额的0.002%,最低收USD$2(当换汇金额低于USD$100,000时,手续费一直都是USD$2,最少CAD$2500) 开设RRSP需要交CAD$12.5 / season的季度费,因此不要在IBKR中开RRSP USD Margin Interest为1.59% EQ EQ虽然不是券商,但是可以开一个免费的USD Account,3% interest,加拿大的银行USD to USD transfer免费。\n","permalink":"https://kyxie.me/zh/blog/wool/stock-brokers/","summary":"Wealthsimple 开户 使用推荐码VXU-UQ开设账号,在开户后的30天内存$1即可获得$25奖励。 Features Core Premium 资金要求 $0 $100000 Commission Fee $0 $0 Cash Account 4% 4.5% USD FX 1.5% 1.5% 期权交易 $2 $0.75 Crypto Trading","title":"加拿大券商对比"},{"content":"通过使用keys我们可以免密登录Linux server,这样以后ssh到Linux的时候就不需要每次填写密码了。\n首先在windows上生成一个密钥对,一般会生成在C:\\Users\\Username/.ssh/id_rsa,而且都是成对生成的,会有一个公钥id_rsa.pub和一个私钥。\nssh-keygen 在Linux中查看是否有.ssh目录,如果没有则新建\ncd ~ mkdir -p ~/.ssh chmod 700 ~/.ssh 将公钥id_rsa.pub上传到Linux\ncd C:\\Users\\Username/.ssh/ scp .\\id_rsa.pub username@address:~/.ssh 在Linux中查看是否有authorized_keys文件,如果没有则新建\ncd ~/.ssh touch authorized_keys chmod 600 ./authorized_keys cat id_rsa.pub \u0026gt;\u0026gt; ./authorized_keys 添加完之后就可以将id_rsa.pub删除了\ncd ~/.ssh rm id_rsa.pub 这样以后就不再需要输密码了。\n","permalink":"https://kyxie.me/zh/blog/tech/router/keys/","summary":"通过使用keys我们可以免密登录Linux server,这样以后ssh到Linux的时候就不需要每次填写密码了。 首先在windows上生成一","title":"使用Keys免密ssh到Linux"},{"content":"\rKyxie\u0026#39;s Blog\rA Hello World Printer\rSulv’s Blog\r记录技术、阅读、生活的博客\r嘰嘰乞乞\r但願我靈魂沒有生鏽\r友链格式:\nname=\u0026#34;Kyxie\u0026#39;s Blog\u0026#34; url=\u0026#34;https://kyxie.me/zh\u0026#34; logo=\u0026#34;https://kyxie.me/Avatar.jpg\u0026#34; word=\u0026#34;A Hello World Printer\u0026#34; ","permalink":"https://kyxie.me/zh/links/","summary":"Kyxie\u0026#39;s Blog A Hello World Printer Sulv’s Blog 记录技术、阅读、生活的博客 嘰嘰乞乞 但願我靈魂沒有生鏽 友链格式: name=\u0026#34;Kyxie\u0026#39;s Blog\u0026#34; url=\u0026#34;https://kyxie.me/zh\u0026#34; logo=\u0026#34;https://kyxie.me/Avatar.jpg\u0026#34; word=\u0026#34;A Hello World Printer\u0026#34;","title":"友链 🤝"},{"content":"👉️填写QQ邮箱可以自动获取QQ头像哦\n","permalink":"https://kyxie.me/zh/comment/comments/","summary":"👉️填写QQ邮箱可以自动获取QQ头像哦","title":"留言板 📋"},{"content":"研究生项目 Turbo Wallet - 记账软件 2022年1月 至 2022年3月,JavaScript\nGitHub (前端仓库): https://github.com/Kyxie/money-management.git\nGitHub (后端仓库): https://github.com/Kyxie/money-back.git\n这是一个帮助我们记录每天生活花费的手机App。 前端基于React.js框架,后端基于Express.js框架,数据库基于MongoDB。 可以添加,编辑和删除每一条消费记录,并且App会生成一些折线图和饼图帮助我们分析近期的消费。 还可以直观地看到哪一种消费花了多少钱,以及不同种类的消费的排序。 交通监视系统 2021年9月 至 2021年12月,Python / C++\nGitHub: https://github.com/Kyxie/Traffic.git\n这个项目帮助当地警察局在道路交叉口安装最少的摄像头,但是获得最大的监控覆盖面积。这是一个顶点覆盖问题,我们利用CNF-SAT来对这个问题进行优化。 使用Python生成一张包含城市交通细节的地图(道路和十字路口),然后尝试使用迪杰斯特拉算法在城市中找到最短路径,最后,我们利用CNF-SAT模拟安装摄像头是否能覆盖城市所有街道,解决顶点覆盖问题。 该项目实现了多线程和并行处理,以更高效地运行。 我的个人网站 2021年8月 至 今,HTML / CSS / JavaScript\nGitHub: https://github.com/Kyxie/Kyxie.github.io.git\n这个项目是基于Hugo的PaperMod主题。 本科项目 基于深度学习的行人重识别系统 2020年9月 至 2021年6月,Python\nGitHub: https://github.com/Kyxie/ReID-deep-learning.git\n本项目是基于深度学习方法的行人重识别系统,所使用的框架是PyTorch。 我们利用Market-1501数据集去训练模型,然后利用这个数据集和我们自创的UESTC Re-ID数据集去测试模型。 本项目的深度学习模型为ResNet-50,损失函数为TriHard损失。 对于Market-1501数据集的mAP指标达到58.8%,rank@1指标达到76.3%。 信道分配系统 2021年4月 至 2021年5月,MATLAB\nGitHub: https://github.com/Kyxie/Channels.git\n这是一个关于信道分配问题的项目,项目背景为在医院中,将最高信噪比的信道分配给最需要的人(例如病人),而将普通人分配给病人的干扰信道(信噪比低)。 我们提出了4种算法去实现这个问题。 Webots机器人 2020年2月 至 2020年6月,C++\nGitHub: https://github.com/Kyxie/TDPS-2020-UESTC-Glasgow.git\nBilibili: https://www.bilibili.com/video/BV1Rp4y1S7o3?from=search\u0026amp;seid=72774621551842110\n\u003c!DOCTYPE HTML\u003e\r这是一个基于Webots的项目。 我们在Webots软件中设计了一个智能小车和完成任务需要的场地,我们为小车安装了惯性导航模块,LIDAR模块和摄像头模块使得小车可以完成巡线,姿态解算,颜色识别等任务。 基于FPGA的波形发生器 2019年9月 至 2019年12月, Verilog\nGitHub: https://github.com/Kyxie/wave-generator.git\n利用FPGA (Xilinx xc7a35tftg256)来生成正弦波,三角波和方波。 波的频率可调,从0 - 255Hz,并由8位USART控制。 利用4个拨码开关来控制振幅,从0 - 1V,分辨率为0.1V。 利用2个拨码开关来选择波形。 输出结果可通过VGA显示,可显示相应波形的图像信息和频率、幅值。 一个RISC架构的CPU 2018年2月 至 2018年6月, Verilog\nGitHub: https://github.com/Kyxie/CPU.git\n使用Quartus II软件实现RISC CPU,使其能够进行加、减、乘、除操作。 CPU的设计包含数据路径模块设计(ALU,寄存器和PC),控制单元设计(状态转换和IR)以及这两个模块之间的通信(CPU的集成)。 ","permalink":"https://kyxie.me/zh/projects/","summary":"研究生项目 Turbo Wallet - 记账软件 2022年1月 至 2022年3月,JavaScript GitHub (前端仓库): https://github.com/Kyxie/money-management.git GitHub (后端仓库): https://github.com/Kyxie/money-back.git 这是一个帮助我们记录每天生活","title":"项目 👨💻"},{"content":"class Me: def __init__(self): self.name = \u0026#34;Kunyang Xie\u0026#34; self.born_year = 1999 self.MBTI = \u0026#34;ISTJ\u0026#34; self.hometown = \u0026#34;Weifang, Shandong, CN\u0026#34; self.location = \u0026#34;Toronto, ON, CA\u0026#34; self.school = \u0026#34;UESTC, uWaterloo\u0026#34; ","permalink":"https://kyxie.me/zh/about/","summary":"class Me: def __init__(self): self.name = \u0026#34;Kunyang Xie\u0026#34; self.born_year = 1999 self.MBTI = \u0026#34;ISTJ\u0026#34; self.hometown = \u0026#34;Weifang, Shandong, CN\u0026#34; self.location = \u0026#34;Toronto, ON, CA\u0026#34; self.school = \u0026#34;UESTC, uWaterloo\u0026#34;","title":"关于我 👋"}]
\ No newline at end of file
+[{"content":"需要的硬件和软件 硬件 一台有网线接口的电脑 内存2GB以上的树莓派4B+ 8GB以上的小SD卡,可以插在树莓派上 SD卡的读卡器 一根网线 显示器(非必须),Micro USB - HDMI线(非必须) 软件 Balena Etcher,MacBook用户可以选择下载这个,也可以选择用命令行代替 VM Virtual Box和Ubuntu虚拟机,非必须,用于编译OpenWrt固件,不过也可以选择下载别人编译好的固件。有一点需要注意,我第一次编译60GB就足够了,但是第二次希望编译一个固件库,想把所有功能全部选上,60GB不够,建议分配128GB储存 SecureCRT或PuTTy,非必须,不知道大家用什么命令行终端,但是我MacBook和Windows都是用系统自带的命令行终端 获得镜像 下载镜像 可以从OpenWrt的官网下载镜像\n编译镜像 但我是比较能折腾的,我找到了这个仓库:Lean,readme有比较详细的编译步骤,于是决定自己尝试一下\n第一次编译 首先在Ubuntu上clone repo\nhttps://github.com/coolsnowwolf/lede.git 安装依赖包\nsudo apt update -y sudo apt full-upgrade -y sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \\ bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib \\ git gperf haveged help2man intltool libc6-dev-i386 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 lrzsz mkisofs 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 更新feed并选择配置\ncd lede ./scripts/feeds update -a ./scripts/feeds install -a make menuconfig 输入这个命令后就开启了配置页面,我使用的是树莓派4B,我目前的常用场景有见这里\n# 编译的目标系统 TargetSystem: - Broadcom BCM27xx Subtarget: - BCM2711 boards (64 bit) TargetProfile: - Raspberry Pi 4B/400/4CM (64bit) # 镜像参数 TargetImages: - ext4 # ext4格式的固件可方便地调整分区大小 - squashfs # squashfs格式的固件可恢复出厂设置 - KernelPartitionSize: 64 # boot分区大小为64M - RootFilesystemPartitionSize: 2048 # root分区大小为2048M # 可选工具 BaseSystem: - block-mount # 在LuCI界面添加\u0026lt;挂载点\u0026gt;菜单 - blockd # 自动挂载设备 - wireless-tools # 无线扩展工具 Administration: - htop # 添加htop命令 Firmware: - xxx # 选择你需要的网卡固件,默认即可 # 文件系统 KernelModules: Filesystems: - kmod-fs-ext4 - kmod-fs-ntfs - kmod-fs-squashfs - kmod-fs-vfat - kmod-fuse # 网卡支持 NetworkDevices: - kmod-xxx # 有线网卡支持,跟以下几项可根据需求选择性添加 NetworkSupport: - kmod-wireguard WirelessDrivers: - kmod-rt2800-usb # 添加Ralink RT5370芯片的USB无线网卡驱动 USBSupport: - kmod-usb-net: - kmod-usb-net-asix # 添加支持亚信的有线网卡支持 - kmod-usb-net-asix-ax88179 # 添加USB3.0的有线网卡芯片AX88179的驱动 - kmod-usb-net-rtl8152 # 添加USB2/3的有线网卡RTL8152/3芯片支持 - kmod-usb-net-sr9700 # 添加USB2.0的有线网卡SR9700芯片支持 - kmod-usb-core # 启用USB支持 - kmod-usb-hid # USB键鼠支持 - kmod-usb-ohci # 添加OHCI支持 - kmod-usb-storage # 启用USB存储 - kmod-usb-storage-extras - kmod-usb-uhci # 添加UHCI支持 - kmod-usb2 # 开启USB2支持 - kmod-usb3 # 开启USB3支持 # LuCI设置 LuCI: Collections: - luci # 开启luci Modules: Translations: - Chinese(zh-cn) # 中文支持 Themes: - luci-theme-agron # 添加主题 # LuCI应用 Applications: - luci-app-adguardhome # 去广告 - luci-app-alist # 文件共享 - luci-app-aria2 # 下载工具 - luci-app-advanced-reoot - luci-app-cloudflared - luci-app-filebrowser # 文件管理 - luci-app-filetransfer - luci-app-firewall # 防火墙 - luci-app-frps - luci-app-frpc # 内网穿透 - luci-app-hd-idle # 硬盘休眠 # - luci-app-lucky - luci-app-opkg # 软件包 - luci-app-openvpn - luci-app-openvpn-server - luci-app-qos # 服务质量 - luci-app-samba # 网络共享 - luci-app-shadowsocks-libev # 翻墙软件 - luci-app-upnp # UPnP服务 - luci-app-wol # 网络唤醒 Protocols: - luci-protocol-wireguard # 网络工具 Network: DownloadManager: - ariang # Aria2管理页面 FileTransfer: - Aria2Configuration: - *** # 选择Aria2支持的功能 - curl # 添加curl命令 - wget # 添加wget命令 IP Addresses and Names: - ddns-scripts-cloudflare - drill VPN: - wireguard-tools # 实用工具 Utilities: Compression: - bsdtar # tar打包工具 - gzip # GZ 压缩套件 Disc: - fdisk # 磁盘分区工具 - lsblk # 磁盘查看工具 Filesystem: - ntfs-3g # NTFS读写支持 - resize2fs # 分区大小调整 - f2fs-tools Terminal: - screen # 添加screen - pciutils # 添加lspci命令 - usbutils # 添加lsusb命令 - losetup - qrencode 配置完成后选择Save,会保存为一个.config文件。在最后一步安装之前还需要安装screen,用于创建持久会话,否则如果不小心关了ssh之前编译的就都没了(你猜我是怎么知道的)\nsudo apt install screen screen -S buildlede 最后执行命令用8个线程下载dl库,第一次编译用1个线程编译。在这里一开始我用的AWS的Ubuntu一直下不下来,没有办法换成了本地的Ubuntu虚拟机才下载编译成功\nmake download -j8 make V=s -j1 然后就是等待编译,编译完成后在bin\\targets可以选择openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz这个版本进行烧录\n单独编译 有时候用着用着发现我们需要安装一个插件,这种情况下我们可以单独编译一个插件\n编辑.config文件\nmake menuconfig 找到我们想单独编译的插件,比如luci-app-diskman,这是个管理路由器上的磁盘和分区的插件,第一次编译选择为[*],意思是作为一个内置模块编译,不可以卸载。这次的话我们可以选择为[M],意思是作为一个模块编译\n使用如下命令可以编译\nmake package/luci-app-diskman/compile V=s 编译完成后在/bin/packages/aarch64_cortex-a72/luci文件夹下能找到luci-app-diskman_v0.2.11_all.ipk\n打开openwrt,System → File Transfer选择文件上传,右下角安装就可以了\n我安装完后OpenWrt没有立刻出现新安装的插件,过了一段时间才出现的\n如果要单独编译内核模块,比如kmod-wireguard,可以在kernel module中选中它为[M],然后运行\nmake package/kernel/linux/compile V=s 很快编译就完成了,编译出来的包在bin/packages/\u0026lt;target\u0026gt;/\u0026lt;package-repo\u0026gt;/kmod-wireguard_xxx.ipk\n第二次编译 拉取最新feeds\nsudo sh -c \u0026#34;apt update \u0026amp;\u0026amp; apt upgrade -y\u0026#34; git pull ./scripts/feeds update -a \u0026amp;\u0026amp; ./scripts/feeds install -a 清除旧的编译产物(可选)\nmake clean # 源码有大规模更新或者内核更新后执行,以保证编译质量 # 此操作会删除 /bin 和 /build_dir 目录中的文件 make dirclean # 如果要更换架构,例如要从 x86_64 换到 MediaTek Ralink MIPS 建议执行以下命令深度清理 # 此操作会删除 /bin 和 /build_dir 目录的中的文件(make clean),以及 /staging_dir、/toolchain、/tmp 和 /logs 中的文件 编译\nmake defconfig make download -j8 find dl -size -1024c -exec ls -l {} \\; make -j$(nproc) || make -j1 || make -j1 V=s 制作Docker镜像 以上的教程能得到使OpenWrt直接在树莓派上运行的镜像,但是目前我的想法是,让树莓派运行Ubuntu作为主系统,OpenWrt作为Docker Image部署在树莓派上,这样我们还可以运行一些其他的服务,以后更换重新编译的OpenWrt镜像也就不需要重新刷机了,仅仅换个Docker镜像即可。\n首先解压镜像文件,这里我们选择openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz\ngzip -d openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz 挂载镜像文件\nsudo losetup -fP openwrt-bcm27xx-bcm2711-rpi-4-ext4-factory.img sudo mount /dev/loop0p2 /mnt 制作rootfs.tar\nsudo tar -C /mnt -czf rootfs.tar . sudo umount /mnt sudo losetup -d /dev/loop0 创建Dockerfile\nFROM arm64v8/alpine:latest ADD rootfs.tar / CMD [\u0026#34;/sbin/init\u0026#34;] 构建Docker镜像\nsudo docker buildx build --platform linux/arm64 -t openwrt-docker --load . 上传到Dockerhub\nsudo docker tag openwrt-docker dockerhub-username/openwrt-docker:latest sudo docker push dockerhub-username/openwrt-docker:latest 然后回到树莓派,拉取镜像,注意这里最好用命令行\ndocker pull dockerhub-username/openwrt-docker:latest 创建一个容器来运行镜像\ndocker run -it --name openwrt-docker dockerhub-username/openwrt-docker:latest 烧录 直接烧录的image我们选择openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz\nWindows 可以使用Balena Etcher或者其他的disk imager软件将image烧录到SD卡中,非常简单,按顺序一步一步来即可\nMacOS MacOS也可以使用Balena Etcher将镜像导入到SD卡中,但是我不喜欢下乱七八糟的软件,干脆直接使用命令行了\n找到SD卡的磁盘编号,这里我的SD卡磁盘为/dev/disk4\ndiskutil list /dev/disk4 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *7.9 GB disk4 1: Windows_FAT_32 BOOT 67.1 MB disk4s1 2: Linux 109.1 MB disk4s2 (free space) 7.7 GB - 由于我这里以前装过一个不带GUI版本的OpenWrt,SD卡多了几个分区,这次打算重新装一个带着GUI的\n首先恢复分区,这个命令同时把SD卡进行格式化\ndiskutil eraseDisk FAT32 SDCARD MBRFormat /dev/disk4 恢复分区之后\ndiskutil list /dev/disk4 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *7.9 GB disk4 1: DOS_FAT_32 SDCARD 7.9 GB disk4s1 输入以下命令卸载(但不移除) SD 卡,否则会显示busy\ndiskutil unmountDisk /dev/disk4 解压下载的image\ngunzip ./openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img.gz 使用 dd 写入解压后的 .img 文件,注意这一步千万不要抄错了磁盘编号,否则伤害不可逆,dd是个很强的命令\nsudo dd if=/Users/xxx/Desktop/openwrt-bcm27xx-bcm2711-rpi-4-squashfs-factory.img of=/dev/disk4 bs=1M status=progress 如果不报错一般就是成功了\n最后将SD卡从电脑拔出,插到树莓派上,启动树莓派,这时使用网线将树莓派的以太网接口和电脑的以太网接口相连。由于OpenWrt 默认将树莓派的eth0接口桥接到br-lan并使用 IP 地址 192.168.1.1,我们要配置一下电脑端的Ethernet接口是否也在192.168.1.x的子网,x可以选2 - 255的随便一个数\n当树莓派就跟电脑在相同子网后,在浏览器中输入192.168.1.1,就能登录到OpenWrt的GUI(LuCI)了,默认用户名和密码是root和password\n大功告成了\n连接路由器 我家主路由器使用的子网为192.168.2.x,需要将树莓派改为这个子网下(当然如果主路由器子网为192.168.1.x的话就不用多折腾这一步了)。我们先禁用桥接模式和修改IP地址\nvi /etc/config/network 修改文件为\nconfig interface \u0026#39;lan\u0026#39; option device \u0026#39;eth0\u0026#39; option proto \u0026#39;static\u0026#39; option ipaddr \u0026#39;192.168.2.66\u0026#39; option netmask \u0026#39;255.255.255.0\u0026#39; option gateway \u0026#39;192.168.2.1\u0026#39; option dns \u0026#39;192.168.2.1\u0026#39; option ip6assign \u0026#39;60\u0026#39; 禁用DHCP,防止跟主路由器的DHCP冲突\nvi /etc/config/dhcp config dhcp \u0026#39;lan\u0026#39; option interface \u0026#39;lan\u0026#39; option ignore \u0026#39;1\u0026#39; 检查防火墙配置\nvi /etc/config/firewall config zone option name \u0026#39;lan\u0026#39; list network \u0026#39;lan\u0026#39; option input \u0026#39;ACCEPT\u0026#39; option output \u0026#39;ACCEPT\u0026#39; option forward \u0026#39;ACCEPT\u0026#39; 应用设置\n/etc/init.d/network restart 这时由于我们电脑还在192.168.1.x子网,但是树莓派已经到了192.168.2.x子网了,所以连接必定是断开的,我们再把电脑端的Ethernet端口改回192.168.2.x子网,就又能重新访问了\n将树莓派与电脑断开连接,插到路由器的LAN口上,应该能正常访问网络,而且电脑也能访问树莓派了\n设置旁路由 以上步骤只是将树莓派作为一个用网设备加入了家庭的局域网,我们的终端设备还是沿着主路由这条线进行通信,要想作为旁路由还需要进一步设置\n其实很简单,我们只要将Wifi的网关从路由器之前DHCP自动分配的地址改为旁路由树莓派即可,假设我的主路由器IP地址为192.168.2.1,我的电脑IP地址为192.168.2.54,我的树莓派的IP地址为192.168.2.66,我需要这么修改:\nMacBook也一样\n同样的iPhone也可以设置,这里我就不放图了\n因为怕炸网我暂时先使用这种非侵入式的设置,它只影响把网关设置为软路由的终端,这样一旦网坏了只影响部分设备,或者我修改一下网关修改到主路由器的IP地址就可以了\n详见:软路由做旁路由三步搞定!openwrt软路由 R2S R4S openwrt软路由上网设置\n安装插件 卸载插件 可以在System → Software → Installed中卸载插件 注意直接编译进内核固件的插件无法卸载 安装插件 直接安装 国外使用\nsrc/gz openwrt_core https://downloads.openwrt.org/releases/23.05.0/targets/bcm27xx/bcm2711/packages src/gz openwrt_base https://downloads.openwrt.org/releases/23.05.0/packages/aarch64_cortex-a72/base src/gz openwrt_luci https://downloads.openwrt.org/releases/23.05.0/packages/aarch64_cortex-a72/luci src/gz openwrt_packages https://downloads.openwrt.org/releases/23.05.0/packages/aarch64_cortex-a72/packages src/gz openwrt_routing https://downloads.openwrt.org/releases/23.05.0/packages/aarch64_cortex-a72/routing src/gz openwrt_telephony https://downloads.openwrt.org/releases/23.05.0/packages/aarch64_cortex-a72/telephony 国内使用\nsrc/gz openwrt_core https://mirrors.tencent.com/lede/snapshots/targets/bcm27xx/bcm2711/packages src/gz openwrt_base https://mirrors.tencent.com/lede/snapshots/packages/aarch64_cortex-a72/base src/gz openwrt_luci https://mirrors.tencent.com/lede/releases/18.06.9/packages/aarch64_cortex-a72/luci src/gz openwrt_packages https://mirrors.tencent.com/lede/snapshots/packages/aarch64_cortex-a72/packages src/gz openwrt_routing https://mirrors.tencent.com/lede/snapshots/packages/aarch64_cortex-a72/routing src/gz openwrt_telephony https://mirrors.tencent.com/lede/snapshots/packages/aarch64_cortex-a72/telephony 自己编译 首先需要在Ubuntu上编译插件\nmake menuconfig 在LuCI → Applications可以把固件全选上,毕竟我们是做个固件库,之后有啥需求就装啥。选择时应该模块化,按空格让前面括号里出现一个M。保存后回到命令行开始编译\nmake -j1 V=s 编译完成后在bin\\packages中就能找到我们编译的全部插件了,而且都为.ipk格式\n常见使用场景 去广告 所需插件(具体配置路径见这里) luci-app-adguardhome 配置参考:【韩风Talk】Openwrt插件对广告说不,怎么做?两款热门插件随你用!_哔哩哔哩_bilibili 外网访问我的Windows台式机 Wireguard Wireguard因为比OpenVPN轻量化速度更快,因此是我目前首选 所需插件(具体配置路径见这里) kmod-wireguard luci-proto-wireguard wireguard-tools luci-app-wireguard(可以不选,而且在我的menuconfig没找到) 详细配置见:Wireguard配置 | Kunyang\u0026rsquo;s Blog ZeroTire 所需插件\nluci-app-zerotire 配置参考:【韩风Talk】Openwrt的Zerotier插件玩法,异地组网不求人,大虚拟局域网走起!_哔哩哔哩_bilibili\nOpenVPN 所需插件 luci-app-openvpn luci-app-openvpn-server luci-i18n-openvpn-server-zh-cn luci-i18n-openvpn-zh-cn open-vpn-easy-rsa openvpn-openssl 文件管理 推荐插件 luci-app-filebrowser:Service → File Browser luci-app-samba:NAS → Network Shares,有一点视频里说的点击Path会进入/luci/admin/system/fstab,但是我的menuconfig没有luci-app-fstab,因此会404,好在如果编译了BaseSystem → block-mount的话这个url:/luci/admin/system/mounts跟视频里的是一样的。我认为这是个bug luci-app-filetransfer:System → File Transfer,用于上传ipk包 luci-app-alist:Services → AList 配置参考: 【韩风Talk】Openwrt文件管理的玩法合集,这期顺便解决中文乱码问题!_哔哩哔哩_bilibili 这期玩Alist的网络安全防护,随便折腾一下免费的内网穿透_哔哩哔哩_bilibili 扩容 OpenWrt的空间扩容问题,可以这么直接解决!_哔哩哔哩_bilibili OpenWrt空间扩容:这波补充超有料!_哔哩哔哩_bilibili ","permalink":"https://kyxie.me/zh/blog/tech/router/raspberrypi-openwrt/","summary":"需要的硬件和软件 硬件 一台有网线接口的电脑 内存2GB以上的树莓派4B+ 8GB以上的小SD卡,可以插在树莓派上 SD卡的读卡器 一根网线 显示器(非必","title":"使用树莓派4B+安装OpenWrt用作旁路由"},{"content":"Mac用户非常推荐使用Homebrew来安装一些软件,就Python来说如果在官网直接下载会在Launch Pad出现IDLE和Python Launcher两个图标,个人感觉很丑。\n其实MacOS Catalina只有系统就预装了Python3了(在这之前是Python2),如果只想处理一些基本的Python功能直接用系统自带的就好了,但是为了方便版本控制还是挺推荐使用Homebrew再下载一个版本方便管理,避免影响系统的Python。\n安装步骤 首先需要安装Xcode Command Line Tools,Homebrew依赖这些工具来正常工作,可以在命令行直接输入命令。其实安装完这个git也就顺带着一起安装了,但是一样的道理,还是推荐使用Homebrew再安装一个版本的git。\nxcode-select --install 安装Homebrew\n/bin/bash -c \u0026#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\u0026#34; 可能需要输入密码\n验证安装以及更新到最新版本\nbrew -v brew update 安装Python\nbrew install python 这时系统里可能有两个Python,我们需要指定使用哪个Python\nwhich python3 /usr/bin/python3\t# 出现这个就是还在用系统自带的python 我们找到通过Homebrew安装的Python的位置\nbrew --prefix python /opt/homebrew/opt/python@3.13 打开环境变量配置文件,MacOS Catalina之后默认为zsh\nvim ~/.zshrc 在最后一行加入\nexport PATH=\u0026#34;/opt/homebrew/opt/python@3.13/bin:$PATH\u0026#34; 保存,刷新file\nsource ~/.zshrc 然后再查看一下当前使用的哪个Python版本\nwhich python3 /opt/homebrew/opt/python@3.13/bin/python3\t# Homebrew版本 安装git\nbrew install git 验证安装\ngit -v 一般来说git不会出现像Python一样设置PATH的问题。\n配置git的邮箱和用户名,如果要使用GitHub来管理仓库的话,要保持这个邮箱和用户名和GitHub一致\ngit config --global user.name \u0026#34;Your Name\u0026#34; git config --global user.email \u0026#34;your.email@example.com\u0026#34; ","permalink":"https://kyxie.me/zh/blog/tech/others/python-and-git-for-macos/","summary":"Mac用户非常推荐使用Homebrew来安装一些软件,就Python来说如果在官网直接下载会在Launch Pad出现IDLE和Python L","title":"使用Homebrew在M芯片的MacBook安装Python和Git"},{"content":"Header 好久没折腾自行车了,最近刚换了roval的破风把,准备打算在车把也内走线,这样车把握起来就爽快多了。我自己拆车试了一下,结果被Shimano 7020两根油管两根线管一共4根线实在是折磨得不轻,于是有了买套Shimano 8170的念头,故刷起了加拿大的各大自行车网站。这不刷不知道一刷吓一跳,一套Shimano 8170至少得$3000,税后怎么着奔$4000去了。看了一眼淘宝国内的价格居然都跌到¥8000了,干脆从国内空运一套过来,在这里开个帖子记录一下我的装车的全过程。\n先说结论:我自认为我算是动手能力非常非常强的了,但是在装车的过程中还是踩了无数个坑,这里有点心疼国内的技师们,国外装个车就得$300+。\n拆车 想换套件换车把的同时做个大保健,然后开起了漫长的拆车之旅:\n首先是不知道自己该用什么中轴工具,找了半天自己的中轴型号是螺纹中轴(Thread Bottom Bracket) SM-BBR60 BSA,于是乎Temu买工具,等了半个月\n其次是中轴拿不下来,于是乎去the Home Depot买了个橡皮锤和wire cutter\n然后是是手变速线拿不下来,拆掉7020的螺丝之后才发现线头需要跟手变的孔对准(这里提醒大家如果想自己搞一定要勇于拆,一般来说不会装不上,拆下来才能明白他的原理)\n然后是油管自己剪不断,看了可利呼的视频发现应该拿小刀切\n\u003c!DOCTYPE HTML\u003e\r然后是这个线管穿线实在是穿不出来,后来发现了有专门的导线工具,于是我用了替换下来的变速线当导线工具(其实这时我还没有打算换套件,想继续用用7020来着)\n然后发现前刹车油管剪短了\n然后发现四根线根本无法同时从车把里穿出来\n这时由于我的手变没有油堵,刹车油已经弄得我新车把到处都是了(这时有了非常坚定的念头要换套件)\n放弃,套件挂咸鱼(最后竟然一共卖了C$600,也算是出乎我的意料了)\n配置 我的整车配置:\n车架:Specialized Tarmac SL6 Sport 套件:Shimano Ultegra R8170 前轮:Roval Rapide CLII 后轮:Roval Rapide CLX 弯把:Roval Rapide Handlebar 400mm 把立:Specialized Future Stem 100mm 坐垫:Specialized Power Comp 坐管:S-Works Carbon Seatpost 锁踏:Shimano Dura-Ace PD R9100 把带:Supacaz Super Sticky Kush 外胎:Continental GP5000 25c 内胎:RideNow TPU 码表:Garmin Edge 530 尾钩:Sigeyi 表架:扭矩 尾包:Silca Mattone Seat Pack 把包:Rapha Expore Bar Bag 2.4L 装车 后夹器 首先安装后夹器,将前叉拆下来,在穿油管的时候可以线把油管伸出头管,然后套上防止异响的保护套,然后再从头部油管口伸出油管 穿油管还是比较难的,这里淘宝买的引导线救了大命了\n然后用螺丝固定后夹器,注意特殊螺丝靠后\n不要忘记安装垫片\n最后安装保险栓\n前夹器 前叉穿线太痛苦了,再一次感谢淘宝买的引导线 把组 将手变固定在弯把上,放在地上或者使用激光仪调整平衡 千万不要忘记锁紧吊芯,注意吊芯上的箭头应该对准把立螺丝的缝隙(有些车需要对准前面) 调整把组垫片 将弯把固定在把立上 锁紧碗组盖 锁紧把立盖子 将码表架固定在把立上 电池 将电池固定在座管内部,可以用专用的Di2 battery holder,我这里就直接拿电工胶布固定了一下\n电池的三根线成等腰三角形,上面的连接后拨,左边的连接前拨,剩下的不动就行,但是也不要把保护套摘掉。\n后拨 我使用Sigeyi的直装尾勾(不小心买了绿色,但是绿色的实在是太丑了),因此需要先将原厂的吊耳摘下来,这里拧了好久实在是拧不下来,无奈还是去找车店了\n使用Shimano自带的工具将线连接,分别连接后拨电池和前拨电池\n手机下载E-TUBE按住后拨按钮2秒(不要按的时间太长了),就可以开始配对了,注意这里要等后拨电量比较充足的时候才能进行\n不要忘记装电线堵头\n前拨 这里电线要绕一圈然后从车架内进入,最后连接座管内的电池\n注意别忘了装电线堵头\n喜玛诺自带配件中有一个前拨折线配件\n手变 穿线\n首先需要切线,将油管跟手变末端对齐,做一个记号,再在记号后面21mm处再做一个记号,第二个记号就是截管的位置\n使用专用的截管工具截管\n将手变油管堵头螺丝拿下来,注意拿纸垫在下边,用来吸油,然后将橄榄头拿出来\n先穿入手变油管堵头螺丝,然后再将橄榄头穿入油管,最后用专用顶针工具将油针顶进油管(如果先顶针的话橄榄头有可能塞不进去)\n将螺丝拧紧,扭力是8Nm,一定要拧紧,否则会漏油\n灌油\n首先将轮组拿下,一定注意碟片不要沾到油 然后将夹器的来令片拆下来,来令片也不能沾到油,拆掉之后可以用六角扳手用力按压活塞,将活塞撑开到尽可能宽,然后使用专门卡住活塞的工具,顶住活塞 将手变的油缸螺丝拧下来,灌油工具有专门的连接件,一定要先把连接件拧上,再装油杯(也有可能是一体的没有连接件,总之一定要拧紧,直接插入是不行的),否则会漏油 将注射器连着管插入夹器中,然后拧开注油螺丝,就可以开始注油了,注油的同时可以弹一弹油管将空气排出 注意当注油螺丝没有拧紧的时候,刹车是肯定能按倒底的,只有当注油螺丝拧紧后才会按不到底 把多余的油擦干净 中轴 我的中轴规格是SM-BBR60 BSA螺纹中轴 牙盘和曲柄 不要忘记涂抹界面脂\n13N的扭力固定曲柄\n链条 有字面朝外\n我们需要确定链条长度,我使用的是这个方法\n\u003c!DOCTYPE HTML\u003e\r注意:截取链条的时候一定要注意,一定要让我们需要的链条的两端都为内导板(下图只是想介绍什么是内导板和外导板,Shimano的链条基本上都用魔术扣了很少用这样的销钉),如果我们一个为内导板一个是外导板的话魔术扣是装不上的,而且用截链器只截掉一节外导板是非常困难的\n下图办法也可以使用,我最后安装链条的时候不下心多截了一两节让链条变短了,事实证明一两节不太影响\n魔术扣第一次很难装上,我们需要把魔术扣转动到牙盘左上方,而且牙盘正好朝前,这时拿脚用力一踩曲柄就能把魔术扣装上了\n变速 首先将套件调至最大飞,然后调节张力螺丝,配合喜玛诺自带的卡尺,调整后拨和最大飞的间距\n然后在E-TUBE软件中选择Maintainance,按照步骤调节前拨,注意软件上的示意图是从上到下俯视观察的\n\u003c!DOCTYPE HTML\u003e\r然后将后拨调至从大到小第五个飞轮,软件中微调使后拨和飞轮处在同一个水平面\n最后在最大飞轮的情况下,调整限位螺丝,两颗螺丝都贴住限位板但是留一点距离\n\u003c!DOCTYPE HTML\u003e\r缠把带 最后就是缠把带了,虽然缠了好多次了但是还是很不会缠,最好还是找两个例子左边一个右边一个,不然我脑子转不过来,这个网上的教程应该也一大堆了 用电工胶布拧紧的时候要把胶布在车把上粘几圈,否则把带容易往下掉 回想起我第一次缠把带的时候b站找了半天竟然只有一个GCN的缠把带教学视频,如今看来公路车真的火起来了 Footer 最后放几张装好的照片\n文中的装车YouTube视频来自于\nUpdate 不知道为什么刚组装好车的时候没有发现这个问题,大概骑了一个月以后车把开始转不动,火山盖磨车架。一开始以为是苹果酱涂少了,抹酱后发现依旧不行。后边以为是吊芯太紧了,研究了半天如何拆卸闪电的吊芯,发现他实在是太难拆了感觉需要上锤子。实在搞不下来去找了Yonge街上的Bike Depot,阿三店员一脸客气地收了我CAD$10(不过取车的时候Manager并没有收我钱)。从车店取车回家以后用松的吊芯又重新安装了一遍把组,发现依旧磨车架。最终发现是缺少了垫片,无奈淘宝下单,等我妈来加拿大的时候给我捎过来。\n神奇啊我妈带来的0.1mm的垫片竟然给问题解决了,就差0.1mm!\n","permalink":"https://kyxie.me/zh/blog/life/bike/","summary":"Header 好久没折腾自行车了,最近刚换了roval的破风把,准备打算在车把也内走线,这样车把握起来就爽快多了。我自己拆车试了一下,结果被Shiman","title":"Specialized Tarmac SL6装车"},{"content":"Aug 2021, Bank of China 我的第一张信用卡是出国前和我爹一起去中国银行办的卓隽,我用我爹的副卡,不太清楚额度是多少。我只是刚到加拿大的前几天用这张卡,出了隔离之后办了Scotiabank就不再使用了,以后如果回国买水果产品分期的话说不定也会偶尔用用,反正我爹还钱。\n这张卡无年费,开卡奖励不清楚,返现不清楚,但是摸起来比加拿大的银行卡要厚好多,质感好一些,不知道是不是心理作用。据说这张卡现在有了CAD直接结算的,这样的话用起来会更方便。\nSep 2021, Scotiabank Scene+ 由于办学签来加拿大走的是SDS通道需要买个$10000的GIC,光大银行离家近,我就直接办的光大银行的GIC。光大银行对接的是Scotiabank,来到加拿大以后找了家Scotiabank的branch就给我开了checking account和信用卡,额度是$500。由于额度太少了我当时买好多东西都是先提前往里充钱,再刷卡消费,把信用卡花成了prepaid card。因为这是我第一张加拿大信用卡,所以也不会关卡。\n这张卡无年费,开卡送5000 Scene+积分,Sobeys旗下的超市,双立人,Cineplex都是2x积分,其他消费1x积分,之前换电影票好像是1250分,后来变成总价格 * 100 Scene+积分。最开始也没研究怎么薅羊毛,所以我在毕业之前一直在用这张卡。\nJan 2023, BMO Cashback 这个时候找到工作,就开始研究怎么薅羊毛了,最开始申请的是这张BMO的买菜卡,额度$1000。由于一开始只想找个无年费且返现高的就申请了这张,确实这张卡在无年费的里面算比较好的了。\n这张卡无年费,好像也没有什么开卡奖励(好像是前1个月还是3个月买菜10%返现),买菜3%返现(每月$500的cap),流媒体账单1%返现,其他消费0.5%返现,Mastercard应该会把沃尔玛算作Grocery因此也有3%(待考证)。最主要的是由于22年趁着黑五开了Costco,当时一直没有Mastercard来刷Costco,这下终于可以在Costco消费了。这张卡用了半年,基本只有买菜在用,返了$300多,因此还是挺不错的。\n2024年五月关卡。\nMar 2023, CIBC Costco 很快我就发现只有买菜返现可不行,还得再申请一张卡用来对应吃饭的返现,于是开始研究无年费饭卡。本来想申请Simplii是4%返现,但是听说非PR不太好下卡,最后还是选择了Costco的信用卡,刚开始给我的额度是$3000,后来他们给我提升到$6000。\n这张卡无年费,但是必须要有Costco会员,吃饭3%返现,Costco加油3%返现,其他加油站2%返现,Costco网站消费2%返现,但是网站价格要更贵一些,其他消费1%返现。这张卡也用了半年,感觉返现速度比较慢,半年多也才返了$300。打算把Costco停掉之后转到CIBC的其他卡。\n由于取消了Costco会员,2024年五月关卡。\nAug 2023, Triangle MC 这段时间被SportChek店员忽悠着办了一张Triangle的卡。他应该是按照惯例问我要不要办这张卡,我当时还对信用卡研究没有这么深,以为这是那张带着免费拖车的卡,于是稀里糊涂就同意了,这店员一听我同意了也很懵逼,可能是被拒绝惯了。正当我准备拿出自己的信用卡付款的时候店员说不用了,会把消费记到这张新信用卡身上。我问会不会被hard pull,他说可以不激活卡,这样就只会soft pull一下,我又问那我不激活怎么给这张信用卡付款,他说在你checking账户加入payee就可以了,最后我说好吧就这样办了这张卡。后来还是没发现该怎么不激活就还款,也懒得打电话问,干脆就激活了,当时也没管有没有hard pull。总结永远不要办沃尔玛,SportChek这种店员老大妈过来围着问你要不要办的卡。\n其实这张卡也挺不错的,无年费,Triangle加油直接每升便宜5分钱,Canadian Tire旗下包括SportChek都是4%返现。后边办了Cobalt之后基本上油价便宜的时候会去Canadian Tire加油刷这个卡,油价贵的时候去别的地方加油刷Cobalt,所有的返现都会转化成CT Money然后在Canadian Tire旗下的商店使用。\n不过对于加油问题我刚算了一下,假设油价为a,加油体积为b,Triangle真实的加油消费为:(a - 0.04) * b = ab - 0.04b,Cobalt真实加油消费为:ab * (1 - 0.016 * 2) = 0.968ab。也就是说当油价低于1.25的时候Triangle才比Cobalt划算,我来加拿大之后还没有遇见过这么便宜的油价,那这张MC真是屁用没有了,等着买了房子转成黑卡吧。\n黑卡WEMC除了这张普通卡有的服务以外,还有免费拖车和地税服务。不过我也暂时也用不上,等到时候再换卡就可以了。不过所有的WEMC信用卡都有免费的Boingo WiFi,之前在国泰航空上看到过这个,等什么时候有了张WEMC上飞机的时候试试。黑卡还有一点就是长时间不用的话就会自己关卡,所以得等有了房子之后用来交地税才能保证经常用。\nOct 2023, AMEX Cobalt 由于之前一直只想办无年费的信用卡,且觉得加拿大AMEX接受率不高,再加上觉得使用PPP过于麻烦,于是并没有考虑办AMEX的卡。后来在朋友的忽悠下,正好那段时间Cobalt refer别人奖励翻倍,于是我也办了张Cobalt,也幸亏如此,如果再晚一个周开卡的话,Cobalt奖励就从之前的30000MR变成了15000MR,这羊毛又薅到了。\n这张卡月费$12.99,相当于年费$155.88,开卡奖励每月花$500返2500MR持续12个月(现在变成了每月花$750返1250MR持续12个月)。吃饭(美国的餐厅也可以),买菜(建兴超市也可以刷)都是5x积分,流媒体(包括Apple Music)3x积分,酒店Airbnb机票加油 2x积分,其他消费1x积分,refer一个人送5000MR。我开卡两个月就拿了40000MR简直是太爽了(1MR可以看作$0.016)。所有的MR积分都可以1:1地转化为Areoplan积分,刷几个月一张回国机票就出来了。\n经过了几个月的记账之后发现,平时消费最多的地方不在买菜和外出吃饭而在于其他消费。好不容易办一张有年费的信用卡那可得薅个痛快,于是我开始买Paypower Prepaid Mastercard (PPP)。PPP也算是老羊毛了,比较安全,在超市里搭一根香蕉基本不会被FR。\n之前算过买reloadable的PPP和non-reloadable PPP的区别,假设我一个人,每个月买$2500的PPP。\nNon-reloadable:\nNon-reloadable的算法就很简单了,每张卡$9.95+tax就完了,一次买$500,不过这样的话我1个月最多也就买2张PPP,能5x积分的就直接拿Cobalt刷了。\nimport math COBALT_MONTHLY_FEE = 12.99 AMEX_VALUE = 0.016 # Let 1MR = $0.016 TAX_RATE = 1.13 PPP_NONRELOADABLE = 9.95 * TAX_RATE PPP_PER_MONTH = 1 class NONRELOAD: def __init__(self): self.cost = COBALT_MONTHLY_FEE + PPP_PER_MONTH * PPP_NONRELOADABLE self.cashback = round(round(500 + PPP_NONRELOADABLE, 2) * 5) * PPP_PER_MONTH * AMEX_VALUE self.profit = self.cashback - self.cost if __name__ == \u0026#34;__main__\u0026#34;: nonreload = NONRELOAD() print(f\u0026#39;Non-reload ppp cost\u0026#39;.ljust(30) + f\u0026#39;= {nonreload.cost:.2f}\u0026#39;) print(f\u0026#39;Non-reload ppp cashback\u0026#39;.ljust(30) + f\u0026#39;= {nonreload.cashback:.2f}\u0026#39;) print(f\u0026#39;Non-reload ppp profit\u0026#39;.ljust(30) + f\u0026#39;= {nonreload.profit:.2f}\u0026#39;) 按照每个月2张PPP算下来的返现是:\nNon-reload ppp cost = 35.48 Non-reload ppp cashback = 81.79 Non-reload ppp profit = 46.32 剩余的$2500 - $9.95 * 1.13 * 2 - $500 * 2 = $1477 肯定都是5x积分了,当然我是穷逼肯定不会都花完,就当$1000来算,这样最终的返现为:$1000 * 5 * 0.016 + $46.32 = $126.32。\nNon-reloadable的缺点就是每次只能买$500的卡,花完了就得再去超市买,所以如果想买超过$500的商品就比较麻烦了,可以搭配着gift card来使用。另外一个缺点就是最后剩下点钱不知道该怎么办了,本超级社恐肯定是不会厚着脸皮让店员separate to two bills的,我就都拿来充Presto卡了(Good News,最近Presto卡可以加到Apple Pay了,充值更方便,建议不要申请一张新的卡,可以更新Presto App后convert老卡到Apple Pay,这样一张卡更好管理,缺点就是实体卡就不能用了)。\nReloadable:\nReloadable由于需要耗费太多精力了,而且需要找菜店店员帮我充值,所以本超级社恐一直懒得搞,不过要是有人知道Richmond Hill或者Markham哪里可以买reloadable的ppp也麻烦告诉我一下😁。\n基本原理就是这样的,如果有一张其他的高返现的信用卡,比如说Rogers Bank新出的那张红卡,(不太清楚PPP能不能给这张卡还账单毕竟是张新卡,只是拿来举个例子)。0年费,而且只要是Rogers或者Fido用户都可以3%返现,那就可以平时的消费全部刷红卡,然后去超市用Cobalt买PPP用来还红卡的账单。\n当然PPP也是有一定费用的,PPP每次最多充$500,总金额最高是$2500,reload手续费是$6.95,月费是$4.95,每次付账单手续费是$1.95。付账单也有金额限制,每24小时最多$1000,每7天最多$2500,每30天最多$5000。\n假设我1个月花$2000,就需要买4张PPP来还账单:\nimport math COBALT_MONTHLY_FEE = 12.99 AMEX_VALUE = 0.016 # Let 1MR = $0.016 TAX_RATE = 1.13 PPP_NONRELOADABLE = 9.95 * TAX_RATE PPP_PER_MONTH = 2 PPP_RELOAD_FEE = 6.95 * TAX_RATE PPP_BILL_FEE = 1.95 * TAX_RATE PPP_MONTHLY_FEE = 4.95 * TAX_RATE MONTHLY_COST = 1000 # How much do I spend only by ppp per month PPP_BILL_AMOUNT = 1000 # How much PPP can pay bill at a time ROGERS_CASHBACK_RATE = 0.03 class RELOAD: def __init__(self): self.reload_cost = PPP_PER_MONTH * PPP_RELOAD_FEE self.card_cost = COBALT_MONTHLY_FEE + PPP_MONTHLY_FEE self.bill_cost = math.ceil(MONTHLY_COST / PPP_BILL_AMOUNT) * PPP_BILL_FEE self.rogers_cashback = MONTHLY_COST * ROGERS_CASHBACK_RATE self.cobalt_cashback = round(round(500 + PPP_RELOAD_FEE, 2) * 5) * PPP_PER_MONTH * AMEX_VALUE self.cost = self.reload_cost + self.card_cost + self.bill_cost self.cashback = self.rogers_cashback + self.cobalt_cashback self.profit = self.cashback - self.cost if __name__ == \u0026#34;__main__\u0026#34;: reload = RELOAD() print(f\u0026#39;Reload ppp total cost\u0026#39;.ljust(30) + f\u0026#39;= {reload.cost:.2f}\u0026#39;) print(f\u0026#39;Reload ppp total cashback\u0026#39;.ljust(30) + f\u0026#39;= {reload.cashback:.2f}\u0026#39;) print(f\u0026#39;Reload ppp profit\u0026#39;.ljust(30) + f\u0026#39;= {reload.profit:.2f}\u0026#39;) 所以同样是花$2000,这样最终的返现是:\nReload ppp cost = 54.40 Reload ppp cashback = 222.50 Reload ppp profit = 168.09 这样每个月比Non-reloadable多$41,也算是还行吧。\n现在Non-reloadable Paypower也是可以加入Apple Pay了,省的每次还要刷磁条卡刷完再签字显得很埋汰。\nJan 2024, TD Areoplan 最近薅了把TD的羊毛,开checking account绑定工资再还一次账单,能拿$400,新移民能waive掉第一年的年费。开saving账户存$5000能拿$100,存$10000拿$200。开TSFA,FHSA,RRSP 3个账户中的1个存$5000拿$150,3个中的2个各存$5000拿$350。信用卡本来想申请黑色的Areoplan卡结果被拒了说我不是PR,于是打算申请白色的,开卡消费一次送10000Areoplan积分,90天内消费$1000还能再拿10000Areoplan积分,第一年都是免年费的。算下来总共是$750的cash,20000Areoplan积分,免去了$292.4的月费。\n由于这张卡我就是打算薅开户奖励的,因此也不怎么在意返点。它年费是$89,买菜,加油,Air Canada消费1x积分,其他消费$1.5返1Areoplan积分,在星巴克消费可以多返50%Areoplan积分(也就是1.5x积分)。基本上都没有Cobalt好。\n黑卡的话是消费返10000Areoplan积分,半年之内消费$5000返25000Areoplan积分(Jan 3, 2024之后Approve的卡是20000),一年之内消费$7500返15000Areoplan积分(Jan 3, 2024之后Approve的卡是10000),纯开户奖励的话还真没有白卡好,而且必须要PR才行。\nFeb 2024, Rogers WEMC Rogers刚把自家的WEMC给升级了,于是马上办了这张卡,GCR给返了$50。所有消费2%返现,Fido, Rogers用户可以多redeem 50%也就是3%返现,这些跟Rogers Mastercard都一样。多出来的是美元的3%返现,等4月份充个ChatGPT会员看看是不是能4.5%的返现。不过这张卡对我来说也就是WEMC自带的Boingo可能会有点用,毕竟有Cobalt + PPP平时用的可能不怎么多,但不可否认是张很不错的抽屉卡,之后会留着PPP不够用了应急用,或者买一件超过500刀的东西用,或者刷美元时候用。\nMay 2024,AMEX Marriott 已经有计划5月份申请了AMEX Marriott Bonvoy了,目前是史高奖励,开卡后3个月内花$3000送65000万豪分,开卡后6个月内在汽油和旅游上的消费$1额外返3点万豪积分,GCR返$75, $60(又变成$75了)(80000 + $75 $60$75),refer的话能多5000积分(85000),按照1万豪分0.9cents来看的话还是GCR更划算一点。\n这个卡是个抽屉卡,年费$120,第二年开始(交完年费后8个星期)每年送一张35k免房券,在万豪消费$1返5积分,但是不免FX fee比较傻逼。\nSep 2024, AMEX Green 由于要出去旅游申请了AMEX绿卡,我用GCR申请的有CAD$30的返现,3个月刷满CAD$1000送10000MR,然后打电话给AMEX match到刷满CAD$1250送12500MR。\n最基础的无年费AMEX卡,花CAD$1返1分,申请着收藏用。\n","permalink":"https://kyxie.me/zh/blog/wool/credit-card/","summary":"Aug 2021, Bank of China 我的第一张信用卡是出国前和我爹一起去中国银行办的卓隽,我用我爹的副卡,不太清楚额度是多少。我只是刚到加拿大的前几天用这张卡,出了隔","title":"加拿大🇨🇦信用卡薅羊毛心得"},{"content":"安装过程 首先需要安装Hugo,安装Hugo需要利用一个包管理工具,对于Windows系统Hugo可以直接用Winget来安装,打开终端输入\nwinget install Hugo.Hugo.Extended 如果提示not recognized as the name of cmdlet,查找C:\\Users\\Username\\AppData\\Local\\Microsoft\\WindowsApps目录下有没有winget.exe,如果存在则添加这个目录到环境变量,否则去应用商店找winget,这是windows官方提供的windows包管理工具,一般系统里都会自带。\nHugo的tutorial介绍了如何创建一个项目,其中step2(.yml的config文件)和step3(下载主题)要根据PaperMod的guide来配置。\n文件介绍 content:用于放博客内容 data:不用管 layouts:自定义的HTML public:项目导出文件 resources:自定义的CSS和JavaScript static:存放的图片 themes:主题 进入themes/PaperMod则是PaperMod的相关代码,比较主要的目录有:\nassets:PaperMod的CSS和JavaScript代码 layouts:PaperMod的HTML Config.yml 建议直接按照【置顶】hugo博客搭建 | PaperMod主题 | Sulv\u0026rsquo;s Blog (sulvblog.cn)进行配置。\n创建文章 在终端输入hugo new 文章名称.md就会在content文件夹下创建markdown文件,文章头部信息可以修改这篇文章的属性\n常见的头部字段功能\n基本字段\ntitle: 页面标题,用于显示在浏览器标题、文章标题等地方\ndate: 创建日期,例如 2024-11-15T20:00:00+00:00\nlastmod: 最近修改时间,常用于生成更新时间\ndraft: 是否为草稿(true 表示草稿,生成站点时会被忽略)\nauthor: 作者名称 description: 页面描述,用于 SEO 和摘要\nslug: 页面友好的 URL 片段\nurl: 自定义页面 URL type: 页面类型(例如 post、page),决定模板的选择\n分类和标签\ncategories: 页面所属分类,例如 [\u0026ldquo;Tech\u0026rdquo;, \u0026ldquo;Programming\u0026rdquo;]\ntags: 页面标签,例如 [\u0026ldquo;Hugo\u0026rdquo;, \u0026ldquo;Static Site Generator\u0026rdquo;]\n页面内容控制\nsummary: 页面摘要,如果未指定,会自动从内容中提取\nweight: 排序权重,数值越小越靠前\naliases: 页面别名,用于创建 URL 重定向,例如 [\u0026quot;/old-url/\u0026quot;]\nlayout: 指定使用的布局模板,例如 single 或 list\noutputs: 输出格式,默认是 HTML,可以是 JSON、AMP 等\nresources: 页面资源,用于定义图片、PDF 等\nSEO和社交\nkeywords: 页面关键字,例如 [\u0026ldquo;Hugo\u0026rdquo;, \u0026ldquo;Markdown\u0026rdquo;, \u0026ldquo;SEO\u0026rdquo;]\ncanonical: Canonical URL,指定搜索引擎的首选页面地址\nimages: 页面分享时的图片链接(用于社交平台)\n创建子文件夹 可以直接用文件夹来管理目录,比如这是我中文博客的目录\n@Kunyang ➜ blog git(master) tree /F D:. │ _index.md │ ├───Life │\t... ├───Tech │ │ _index.md │ │ │ ├───Web │ │ Papermod.md | | ... │ │ _index.md │ │... │ └───Wool ... 可以看到每一层都有一个_index.md用来管理文件层级,文件中只包含头部信息。由于我使用了多语言,因此第一层不要添加url字段\n# zh/blog/_index.md title: \u0026#34;博客 📒\u0026#34; date: 2022-06-11T21:59:32-04:00 draft: false hidemeta: true 除此之外,在其他的子文件夹中的_index.md建议都添加url字段\n# zh/blog/tech/web/_index.md title: \u0026#34;建站 🚧\u0026#34; date: 2024-11-15T01:01:32-04:00 draft: false hidemeta: true url: \u0026#34;/zh/blog/tech/web/\u0026#34; weight: 1 可以使用weight字段来排序\n最后更新 可以修改post_meta.html加入\n{{- $scratch := newScratch }} {{ $date := .Date }} {{ $lastmod := \u0026#34;\u0026#34; }} {{- if not .Lastmod.IsZero -}} {{ $lastmod = .Lastmod }} {{- end }} {{- if not .Date.IsZero -}} {{- $scratch.Add \u0026#34;meta\u0026#34; (slice (printf \u0026#34;\u0026lt;span title=\u0026#39;%s\u0026#39;\u0026gt;%s\u0026lt;/span\u0026gt;\u0026#34; (.Date) (.Date | time.Format (default \u0026#34;January 2, 2006\u0026#34; site.Params.DateFormat)))) }} {{- end }} {{- if ne $lastmod $date -}} {{- $scratch.Add \u0026#34;meta\u0026#34; (slice (printf \u0026#34;\u0026lt;span title=\u0026#39;%s\u0026#39;\u0026gt;%s%s\u0026lt;/span\u0026gt;\u0026#34; (.Lastmod) (i18n \u0026#34;updated\u0026#34;) (.Lastmod | time.Format (default \u0026#34;January 2, 2006\u0026#34; site.Params.DateFormat)))) }} {{- end }} ... {{- with ($scratch.Get \u0026#34;meta\u0026#34;) }} {{- delimit . \u0026#34;\u0026amp;nbsp;·\u0026amp;nbsp;\u0026#34; -}} {{- end -}} 本地预览 在终端输入hugo server -D启动,建议新建一个.bat文件执行这条指令。 启动服务器后,打开浏览器,本地预览网址为localhost:1313。 网站部署 我用的是GitHub Page\n在GitHub里创建一个仓库,名称叫做你的名字.github.io 当我们本地预览没问题了的时候,在终端输入hugo -F --cleanDestinationDir,在public文件夹下就会生成输出文件 我们将public文件夹作为GitHub Page的本地仓库,每次生成输出文件就推送到GitHub上,GitHub Page就会自动帮我们部署了 自定义域名 建议早一点买个域名,避免配置完一遍结果更换了域名又得重新再配置一遍。\n点击GitHub右上角头像 -\u0026gt; Settings -\u0026gt; Pages -\u0026gt; Add a Domain\n填入自己的域名,我的是kyxie.me,然后会生成一个DNS TXT record,相当于一个用户名和密码,验证一下这个域名是属于你的\n我的域名是在cloudflare申请的,在kyxie.me -\u0026gt; DNS -\u0026gt; Records -\u0026gt; Add Records,添加三条规则,前两条为\nType Name Target CNAME @ kyxie.github.io CNAME www kyxie.github.io 第三条Type是TXT,Name为GitHub生成的Record,TTL选择Auto,Content是GitHub生成的Value\n然后在SSL/TLS -\u0026gt; Edge Certificates -\u0026gt; 勾选Always Use HTTPS\n配置完后回到GitHub,点击Verify,成功后会如图所示\n我的网站框架为Hugo,在static文件下添加一个文件CNAME,没有后缀名,内容为你的域名kyxie.me,然后publish出来push到GitHub就好了\n多语言 如果我们想要使用多语言(中英为例),就需要在content文件夹下准备两个文件夹,例如Chinese和English,一个放中文,另一个放英文。\n在config.yml中需要做以下修改:\ndefaultContentLanguage: en defaultContentLanguageInSubdir: true languages: en: languageName: \u0026#34;English\u0026#34; contentDir: content/English zh: languageName: \u0026#34;中文\u0026#34; contentDir: content/Chinese 搜索功能 分别在中英文的文件夹下创建search.md(hugo new search.md),修改文件头为\ntitle: \u0026#34;Search\u0026#34; date: ... draft: false layout: search config.yml中添加\nmenu: main: -identifier: Search name: Search url: search weight: ... Hover 主要在themes/PaperMod/assets/css/common/header.css中修改。\n左上角Home的hover\n.logo a:hover { transition: 0.15s; color: grey; } 社交媒体hover\nsvg:hover { transition: 0.15s; } .social-icons a:nth-child(1) svg:hover{ color: #C84370 !important; } .social-icons a:nth-child(2) svg:hover { color: grey !important; } ... nth-child可以设置各个图标的hover颜色\n黑夜模式和白天模式的hover\n#moon:hover { transition: 0.15s; color: deepskyblue; } #sun:hover { transition: 0.15s; color: gold; } menu中链接hover\n#menu a:hover { transition: 0.15s; color: grey; } 按钮hover,在themes/PaperMod/assets/css/common/profile-mode.css中修改\n.button:hover { -webkit-transform: scale(1.1); -moz-transform: scale(1.1); -ms-transform: scale(1.1); -o-transform: scale(1.1); /* box-shadow: 0 0 0 1px grey; */ transform: scale(1.1) translateZ(0) translate3d(0, 0, 0) rotate(0.01deg); } 自定义社交媒体图标 利用SVG图标制作网站,比如icons8,找到我们需要的图标,例如微信\n可以利用左侧菜单栏的Stroke调节线条粗细\n点击download,SVG Embed,自定义图标大小为24*24,然后点击copy HTML\n在themes/PaperMod/layouts/partials/svg.html中粘贴复制的HTML\n需要修改为fill=currentColor stroke=currentColor,才能适应白天黑夜切换\n微信和微博的图标\n{{- else if (eq $icon_name \u0026#34;wechat\u0026#34;) -}} \u0026lt;svg xmlns=\u0026#34;http://www.w3.org/2000/svg\u0026#34; x=\u0026#34;0px\u0026#34; y=\u0026#34;0px\u0026#34; width=\u0026#34;24\u0026#34; height=\u0026#34;24\u0026#34; viewBox=\u0026#34;0 0 50 50\u0026#34;\u0026gt; \u0026lt;g fill=\u0026#34;currentColor\u0026#34; stroke=\u0026#34;currentColor\u0026#34; stroke-width=\u0026#34;2\u0026#34;\u0026gt; \u0026lt;path d=\u0026#34;M 19 6 C 9.746094 6 2 12.359375 2 20.5 C 2 24.894531 4.292969 28.679688 7.835938 31.324219 L 5.179688 39.304688 L 13.472656 34.167969 C 15.1875 34.707031 17.082031 35 19 35 C 19.746094 35 20.472656 34.945313 21.195313 34.863281 C 23.378906 39.105469 28.328125 42 34 42 C 35.722656 42 37.316406 41.675781 38.796875 41.234375 L 45.644531 45.066406 L 43.734375 38.515625 C 46.3125 36.375 48 33.394531 48 30 C 48 23.789063 42.597656 18.835938 35.75 18.105469 C 34.398438 11.125 27.324219 6 19 6 Z M 19 8 C 26.308594 8 32.328125 12.351563 33.703125 18.011719 C 26.183594 18.148438 20 23.355469 20 30 C 20 31.019531 20.160156 32.003906 20.4375 32.941406 C 19.964844 32.980469 19.484375 33 19 33 C 17.101563 33 15.199219 32.710938 13.632813 32.15625 L 13.183594 32 L 8.820313 34.699219 L 10.1875 30.59375 L 9.5625 30.171875 C 6.082031 27.820313 4 24.445313 4 20.5 C 4 13.640625 10.65625 8 19 8 Z M 13 14 C 11.898438 14 11 14.898438 11 16 C 11 17.101563 11.898438 18 13 18 C 14.101563 18 15 17.101563 15 16 C 15 14.898438 14.101563 14 13 14 Z M 25 14 C 23.898438 14 23 14.898438 23 16 C 23 17.101563 23.898438 18 25 18 C 26.101563 18 27 17.101563 27 16 C 27 14.898438 26.101563 14 25 14 Z M 34 20 C 40.746094 20 46 24.535156 46 30 C 46 32.957031 44.492188 35.550781 42.003906 37.394531 L 41.445313 37.8125 L 42.355469 40.933594 L 39.105469 39.109375 L 38.683594 39.25 C 37.285156 39.71875 35.6875 40 34 40 C 27.253906 40 22 35.464844 22 30 C 22 24.535156 27.253906 20 34 20 Z M 29.5 26 C 28.699219 26 28 26.699219 28 27.5 C 28 28.300781 28.699219 29 29.5 29 C 30.300781 29 31 28.300781 31 27.5 C 31 26.699219 30.300781 26 29.5 26 Z M 38.5 26 C 37.699219 26 37 26.699219 37 27.5 C 37 28.300781 37.699219 29 38.5 29 C 39.300781 29 40 28.300781 40 27.5 C 40 26.699219 39.300781 26 38.5 26 Z\u0026#34;\u0026gt; \u0026lt;/path\u0026gt; \u0026lt;/g\u0026gt; \u0026lt;/svg\u0026gt; {{- else if (eq $icon_name \u0026#34;weibo\u0026#34;) -}} \u0026lt;svg xmlns=\u0026#34;http://www.w3.org/2000/svg\u0026#34; x=\u0026#34;0px\u0026#34; y=\u0026#34;0px\u0026#34; width=\u0026#34;24\u0026#34; height=\u0026#34;24\u0026#34; viewBox=\u0026#34;0 0 172 172\u0026#34;\u0026gt; \u0026lt;g fill=\u0026#34;currentColor\u0026#34; stroke=\u0026#34;currentColor\u0026#34; stroke-width=\u0026#34;4\u0026#34;\u0026gt; \u0026lt;path d=\u0026#34;M120.4,20.64c-2.67406,0 -5.25406,0.26875 -7.74,0.71219c-1.86781,0.3225 -3.1175,2.10969 -2.795,3.9775c0.3225,1.88125 2.10969,3.13094 3.9775,2.80844c2.17688,-0.38969 4.35375,-0.61813 6.5575,-0.61813c20.93563,0 37.84,16.90438 37.84,37.84c0,4.52844 -0.83312,8.85531 -2.31125,12.91344c-0.45687,1.16906 -0.25531,2.48594 0.5375,3.45344c0.80625,0.9675 2.05594,1.42437 3.29219,1.19594c1.23625,-0.22844 2.24406,-1.11531 2.63375,-2.29781c1.73344,-4.75687 2.72781,-9.87656 2.72781,-15.265c0,-24.65781 -20.06219,-44.72 -44.72,-44.72zM120.4,41.28c-1.46469,0 -2.84875,0.14781 -4.16562,0.37625c-1.86781,0.33594 -3.13094,2.10969 -2.795,3.99094c0.3225,1.86781 2.10969,3.1175 3.9775,2.795c1.00781,-0.17469 2.00219,-0.28219 2.98312,-0.28219c9.54063,0 17.2,7.65938 17.2,17.2c0,2.05594 -0.37625,4.01781 -1.06156,5.87219c-0.645,1.78719 0.28219,3.7625 2.06938,4.4075c1.78719,0.645 3.7625,-0.26875 4.4075,-2.05594c0.92719,-2.55312 1.46469,-5.32125 1.46469,-8.22375c0,-13.26281 -10.81719,-24.08 -24.08,-24.08zM72.46844,42.6775c-11.04562,0 -27.50656,8.66719 -42.18031,23.07219c-14.76781,14.76781 -23.40813,30.24781 -23.40813,43.57781c0,25.9075 33.12344,41.3875 65.88406,41.3875c42.47594,0 70.90969,-24.46969 70.90969,-43.91375c0,-11.87875 -10.07812,-18.35562 -19.08125,-21.23125c-2.15,-0.72562 -3.60125,-1.08844 -2.52625,-3.96406c0.72563,-1.73344 1.77375,-5.01219 1.77375,-9.36594c0,-4.945 -3.44,-9.23156 -10.32,-9.9975c-0.79281,-0.08062 -2.13656,-0.14781 -3.82969,-0.14781c-5.6975,0 -15.48,0.71219 -22.52125,3.66844c0,0 -1.38406,0.57781 -2.49938,0.57781c-1.00781,0 -1.80062,-0.48375 -1.11531,-2.37844c2.52625,-7.91469 2.16344,-14.39156 -1.80063,-18.00625c-2.23062,-2.23062 -5.42875,-3.27875 -9.28531,-3.27875zM72.46844,49.5575c1.43781,0 3.37281,0.215 4.43438,1.26313l0.1075,0.12094l0.12094,0.1075c1.54531,1.41094 1.51844,5.61687 -0.09406,10.72312c-1.38406,3.99094 -0.09406,6.75906 0.81969,8.04906c1.51844,2.16344 4.00437,3.39969 6.81281,3.39969c2.28438,0 4.39406,-0.79281 5.14656,-1.11531c5.50938,-2.31125 13.88094,-3.13094 19.87406,-3.13094c1.53187,0 2.60687,0.05375 3.07719,0.1075c2.78156,0.30906 4.1925,1.37063 4.1925,3.15781c0,3.23844 -0.77937,5.61688 -1.23625,6.73219l-0.05375,0.1075l-0.04031,0.09406c-1.075,2.88906 -1.06156,5.50938 0.04031,7.80719c1.62594,3.39969 4.82406,4.46125 6.54406,5.03906l0.28219,0.09406c5.34813,1.70656 14.2975,5.88562 14.2975,14.68719c0,7.90125 -6.81281,17.65688 -18.90656,25.16844c4.77031,-5.54969 7.47125,-12.05344 7.47125,-19.05437c0,-21.01625 -24.37562,-37.47719 -55.48344,-37.47719c-31.10781,0 -55.47,16.46094 -55.47,37.47719c0,0.645 0.01344,1.27656 0.05375,1.90812c-0.45687,-1.76031 -0.69875,-3.60125 -0.69875,-5.49594c0,-11.16656 7.59219,-24.91312 21.33875,-38.65969c14.86188,-14.59313 29.48188,-21.11031 37.36969,-21.11031zM69.875,82.33156c26.84813,0 48.60344,13.69281 48.60344,30.59719c0,16.89094 -21.75531,30.58375 -48.60344,30.58375c-26.83469,0 -48.59,-13.69281 -48.59,-30.58375c0,-16.90437 21.75531,-30.59719 48.59,-30.59719zM66.27375,89.52063c-10.38719,0.08062 -20.47875,5.76469 -24.85937,14.52594c-5.40188,11.13969 -0.36281,23.38125 12.59094,27.33187c12.95375,4.31344 28.42031,-2.16344 33.82219,-14.02875c5.38844,-11.5025 -1.43781,-23.73062 -14.39156,-26.95562c-2.365,-0.61813 -4.77031,-0.88688 -7.16219,-0.87344zM71.63531,104.06c1.98875,0 3.60125,1.59906 3.60125,3.58781c0,1.98875 -1.6125,3.60125 -3.60125,3.60125c-1.98875,0 -3.60125,-1.6125 -3.60125,-3.60125c0,-1.98875 1.6125,-3.58781 3.60125,-3.58781zM56.47781,107.64781c1.12875,0.01344 2.2575,0.18812 3.31906,0.55094c4.60906,1.46469 6.02,5.83188 3.18469,9.47344c-2.4725,3.64156 -8.12969,5.45563 -12.38938,3.64156c-4.23281,-1.81406 -5.29437,-6.19469 -2.82187,-9.46c1.85437,-2.74125 5.30781,-4.24625 8.7075,-4.20594z\u0026#34;\u0026gt; \u0026lt;/path\u0026gt; \u0026lt;/g\u0026gt; \u0026lt;path d=\u0026#34;\u0026#34; fill=\u0026#34;none\u0026#34;\u0026gt;\u0026lt;/path\u0026gt; \u0026lt;/svg\u0026gt; 目录栏目放侧边 详见:Hugo博客目录放在侧边 | PaperMod主题 | Sulv\u0026rsquo;s Blog (sulvblog.cn)。\nMarkdown渲染风格 详见:折腾 Hugo \u0026amp; PaperMod 主题 - Dvel\u0026rsquo;s Blog\n流量统计 这里我使用了不蒜子,在themes/PaperMod/layouts/partials/footer.html中修改:\n{{- if not (.Param \u0026#34;hideFooter\u0026#34;) }} \u0026lt;footer class=\u0026#34;footer\u0026#34;\u0026gt; {{- if site.Copyright }} \u0026lt;span\u0026gt;{{ site.Copyright | markdownify }}\u0026lt;/span\u0026gt; {{- else }} \u0026lt;span\u0026gt;\u0026amp;copy; {{ now.Year }} \u0026lt;a href=\u0026#34;{{ \u0026#34;\u0026#34; | absLangURL }}\u0026#34;\u0026gt;{{ site.Title }}\u0026lt;/a\u0026gt;\u0026lt;/span\u0026gt; {{- end }} \u0026lt;script async src=\u0026#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;span id=\u0026#34;busuanzi_container\u0026#34;\u0026gt; \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css\u0026#34;\u0026gt; Visitors: \u0026lt;span id=\u0026#34;busuanzi_value_site_uv\u0026#34;\u0026gt;\u0026lt;/span\u0026gt; Views: \u0026lt;span id=\u0026#34;busuanzi_value_site_pv\u0026#34;\u0026gt;\u0026lt;/span\u0026gt; \u0026lt;/span\u0026gt; \u0026lt;script\u0026gt; document.addEventListener(\u0026#34;DOMContentLoaded\u0026#34;, function () { const uvElement = document.getElementById(\u0026#39;busuanzi_value_site_uv\u0026#39;); const pvElement = document.getElementById(\u0026#39;busuanzi_value_site_pv\u0026#39;); const initialUv = 10000; const initialPv = 20000; if (!uvElement || !pvElement) { console.error(\u0026#34;Busuanzi elements not found.\u0026#34;); return; } const uvObs = new MutationObserver((mutationsList) =\u0026gt; { for (let mutation of mutationsList) { if (mutation.type === \u0026#39;childList\u0026#39;) { uvObs.disconnect(); mutation.target.innerHTML = parseInt(mutation.target.innerHTML || 0) + initialUv; break; } } }); const pvObs = new MutationObserver((mutationsList) =\u0026gt; { for (let mutation of mutationsList) { if (mutation.type === \u0026#39;childList\u0026#39;) { pvObs.disconnect(); mutation.target.innerHTML = parseInt(mutation.target.innerHTML || 0) + initialPv; break; } } }); uvObs.observe(uvElement, { childList: true }); pvObs.observe(pvElement, { childList: true }); }); \u0026lt;/script\u0026gt; \u0026lt;/footer\u0026gt; {{- end }} 其中initialUV和initialPV可以用于添加初始值,我由于换了个域名初始值都没了,可以在这里添加上\n插入B站,YouTube视频或PPT 详见:Hugo博客自定义shortcodes | Sulv\u0026rsquo;s Blog (sulvblog.cn)\n插入音乐播放器 详见:Hugo插入音乐播放器\n隐藏歌词:lrc-type=0\n修改全局字体 首先找到喜欢的字体,然后可以在Google Fonts中查询字体,我目前的文章字体为CodeNewRoman。Google Fonts会生成HTML和css,将HTML插入到themes/PaperMod/layouts/partials/extend_head.html中,将CSS插入到themes/PaperMod/assets/css/extended/blank.css。\nbody { font-family: \u0026#39;Code New Roman\u0026#39;, sans-serif; font-size: 1rem; line-height: 1.5; margin: 0; } 修改代码字体 与全局字体类似,区别为CSS代码插入的位置不同。\n.post-content pre, code { font-family: \u0026#39;Code New Roman\u0026#39;, sans-serif; max-height: 40rem; } 评论功能 详见:Hugo博客添加Twikoo评论 | Sulv\u0026rsquo;s Blog (sulvblog.cn)\nGmail邮箱配置 登录 Google Account,进入Security / Signing in to Google / 2-Step Verification / App passwords。点击Generate,并记住这个16位的密码\n在Twikoo中进行配置:\nSENDER_EMAIL:你的gmail邮箱\nSENDER_NAME:发件人名,我写的是Notification from Kunyang\u0026rsquo;s Blog\nSMTP_SERVICE:Gmail\nSMTP_HOST:smtp.gmail.com\nSMTP_PORT:587\nSMTP_SECURE:true\nSMTP_USER:你的gmail邮箱\nSMTP_PASS:16位的应用密码\nSMTP_SUBJECT:邮件主题,我写的是You have received a response from Kunyang\u0026rsquo;s Blog\nMAIL_TEMPLATE:邮件模板,我的是\n\u0026lt;div style=\u0026#34;border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;\u0026#34;\u0026gt; \u0026lt;h2 style=\u0026#34;border-bottom:1px solid #dddddd;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;\u0026#34;\u0026gt; You have received a new response from \u0026lt;a style=\u0026#34;text-decoration:none;color:#12ADDB;\u0026#34; href=\u0026#34;https://kyxie.github.io/\u0026#34; target=\u0026#34;_blank\u0026#34;\u0026gt;Kunyang\u0026#39;s Blog\u0026lt;/a\u0026gt; \u0026lt;/h2\u0026gt; ${PARENT_NICK} Your comment: \u0026lt;div style=\u0026#34;padding:0 12px 0 12px;margin-top:18px\u0026#34;\u0026gt; \u0026lt;div style=\u0026#34;background-color:#f5f5f5;padding:10px 15px;margin:18px 0;word-wrap:break-word;\u0026#34;\u0026gt; ${PARENT_COMMENT} \u0026lt;/div\u0026gt; \u0026lt;p\u0026gt; \u0026lt;strong\u0026gt;${NICK}\u0026lt;/strong\u0026gt; says: \u0026lt;/p\u0026gt; \u0026lt;div style=\u0026#34;background-color:#f5f5f5;padding:10px 15px;margin:18px 0;word-wrap:break-word;\u0026#34;\u0026gt; ${COMMENT} \u0026lt;/div\u0026gt; \u0026lt;p\u0026gt; Click \u0026lt;a style=\u0026#34;text-decoration:none;color:#12ADDB;\u0026#34; href=\u0026#34;${POST_URL}\u0026#34; target=\u0026#34;_blank\u0026#34;\u0026gt;to view the reply\u0026lt;/a\u0026gt;, welcome to \u0026lt;a style=\u0026#34;text-decoration:none;color:#12ADDB;\u0026#34; href=\u0026#34;${SITE_URL}\u0026#34; target=\u0026#34;_blank\u0026#34;\u0026gt;${SITE_NAME}\u0026lt;/a\u0026gt;。\u0026lt;br\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; 配置完成后评论消息就会有gmail邮箱发送的邮件提醒了,outlook邮箱配置见:关于邮箱配置的问题? · twikoojs/twikoo · Discussion #249 (github.com)。\n自定义邮箱回复模板 详见:自定义Twikoo邮件通知模板 | Guo Le\u0026rsquo;s Blog\n代码高亮 在两个地方修改\n一个是themes/PaperMod/assets/css/common/post-single.css:\n.post-content pre code { display: block; margin: auto 0; padding: 10px; /* 主要代码颜色 */ color: #abb2bf; font-weight: 200; overflow-x: auto; word-break: break-all; } 另一个是在themes/PaperMod/assets/css/hljs/an-old-hope.min.css,这是我自己修改的:\n/* 注释 */ .hljs-comment, .hljs-quote { font-weight: 200; color: #7f848e; } .hljs-deletion, /* html标签 */ .hljs-name, .hljs-regexp, .hljs-tag { font-weight: 200; color: #e06c75; } /* html属性 */ .hljs-tag { font-weight: 200; color: #d19a66; } /* css类名 */ .hljs-template-variable, .hljs-variable, .hljs-selector-class, .hljs-selector-id { font-weight: 200; color: #a9b600; } /* 内置函数 */ .hljs-built_in, .hljs-builtin-name { font-weight: 200; color: #56b6c2; } /* 函数输入 */ .hljs-params { font-weight: 200; color: #e5c07b; } /* 数字 */ .hljs-number { font-weight: 200; color: #d19a66; } /* css属性 */ .hljs-attribute { font-weight: 200; color: #ee7c2b; } /* 字符串 */ .hljs-addition, .hljs-bullet, .hljs-symbol, .hljs-string { font-weight: 200; color: #98c379; } /* 函数名称 */ .hljs-section, .hljs-title { font-weight: 200; color: #56b6c2; } /* 关键字 */ .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-link, .hljs-meta, .hljs-type { font-weight: 200; color: #c678dd; } .hljs { display: block; overflow-x: auto; background: #1c1d21; color: #c0c5ce; padding: 0.5em; } .hljs-emphasis { font-style: italic; } .hljs-strong { font-weight: 700; } /* 选中时的背景颜色 */ .hljs ::selection, .hljs::selection { background-color: #3d4556; } 代码边框圆角 themes/PaperMod/assets/css/common/post-single.css中修改:\n.post-content .highlight pre { background-color: var(--theme) !important; margin: 0; } 添加友链 详见:Hugo博客添加友链 | Sulv\u0026rsquo;s Blog (sulvblog.cn)\n图床 之前一直在使用Imgur的图床,但是国内的小伙伴说即使挂了梯子也看不到图片,现在有了域名打算利用Cloudflare自己做一个图床\n首先下载PicGo,Windows用户可以在GitHub下载.exe文件,Mac用户则建议使用Homebrew下载,命令为\nbrew install picgo --cask 下载完之后在LaunchPad出现了PicGo的图标,但是假如显示损坏让你移动到垃圾桶,这时只需要在终端输入\nsudo xattr -r -d com.apple.quarantine /Applications/PicGo.app 就可以解决问题了,安装完之后出现在顶部状态栏(Windows在右下角)\n然后回到Cloudflare,创建一个R2 bucket,我就叫img,将地址选在美国西部(这是因为后面的CDN也在美西)\n然后回到R2 Overview -\u0026gt; 右上角Manage R2 API Tokens,取个名字,然后选择Object Read and Write,可以选择只应用于特定的Bucket,也可以不选\n然后会生成一堆信息,有Token value,Access Key ID,Secret Access Key和jurisdiction-specific endpoints,这个页面只显示一遍,建议拿个小本本记好\n再来到img桶 -\u0026gt; Setting,里面有个R2.dev subdomain选择为Allow\n然后需要绑定一个域名,注意这里不能再使用kyxie.me了,但是可以设置一个子域名,比如img.kyxie.me,cloudflare会自动在DNS中添加一个Record\n回到PicGo,插件设置里搜索S3,然后安装S3插件,注意这里需要下载Node.js环境\n然后在图床设置中打开Amazon S3,然后配置信息,如图所示\n下面还有个自定义域名可以暂时填写img.kyxie.me,为了让国内小伙伴也能打开图片,我使用WebP Cloud Services将图像缓存,这样会打开更快\n注册用户后点击Create Proxy -\u0026gt; 选择美国Hillsboro, OR -\u0026gt; Proxy Origin Url就是http://img.kyxie.me,选择确定之后系统会生成一个url类似于http://xxx.webp.li,再把这个url粘贴到PicGo的自定义域名,配置好之后如图所示\n这样我们的图床就搭建好了,PicGo也可以使用了,经过测试国内的小伙伴也都能打开图片了\n","permalink":"https://kyxie.me/zh/blog/tech/web/papermod/","summary":"安装过程 首先需要安装Hugo,安装Hugo需要利用一个包管理工具,对于Windows系统Hugo可以直接用Winget来安装,打开终端输入 winget","title":"Hugo + PaperMod搭建技术博客"},{"content":"最近有一个项目需要使用GUI,又希望放在云端自动运行。一开始是打算用Windows的instance,尝试了一下基本上下载一个chrome都卡,AWS的免费用户又只能使用只有命令行的Ubuntu server。然后突发奇想诶我可不可以在Ubuntu server上安装一个GUI,查了一下这个方法似乎可行(其实还是不太可行,我已经打算放弃折腾了,不过倒是成功装上了GUI)。\n安装xrdp并enable,安装GUI就需要远程桌面系统,这是Linux的客户端\nsudo apt-get update sudo apt install xrdp -y sudo systemctl enable xrdp 我首先尝试的是gnome,尝试发现这个消耗资源太严重了,免费版用户用起来应该跟Windows一样卡\nsudo add-apt-repository ppa:gnome3-team/gnome3 sudo apt-get install gnome-shell ubuntu-gnome-desktop 后来我决定试试更轻量化的XFCE\nsudo apt install tasksel sudo tasksel install xubuntu-desktop sudo apt install xfce4 xfce4-goodies sudo update-alternatives --config x-session-manager sudo apt install lightdm sudo dpkg-reconfigure lightdm 设置密码\nsudo passwd ubuntu 在EC2 Security group中选择Allow All Traffic\n在MacBook中应用商店下载Windows App,这是Window开发的远程桌面应用,有一说一Windows给Mac开发的软件是真不错\n选择Add a PC,Computer使用AWS提供的DNS,用户名一般为ubuntu,密码为刚才设置的密码\n之后就可以连接上了\n但是尽管XFCE已经很轻量化了,我下载完Chrome之后还是觉得卡,于是放弃折腾了,AWS免费版用户不推荐这么做。\n","permalink":"https://kyxie.me/zh/blog/tech/others/aws-server-gui/","summary":"最近有一个项目需要使用GUI,又希望放在云端自动运行。一开始是打算用Windows的instance,尝试了一下基本上下载一个chrome都","title":"AWS Ubuntu Server安装GUI"},{"content":"Header 最近妈妈来了加拿大,打算带她去Calgary和Banff旅行,发现Banff旅游真的好多坑啊,正好写一篇游记博客,顺便记录一下Banff旅游攻略。\n首先是一些注意事项:\n进入Banff需要购买国家公园Pass,一天CAD$22,有效期到第二天的下午4点(因为4点查票的人就下班了)。我们Sep 19下午5点多才从Calgary提车,在Canmore和Banff之间有一个检票亭子(左侧道路是卖票亭,右侧道路可以bypass),我们从网上买了Sep 20开始的Pass,当我们路过的时候大概是晚上9点,但是还是补上了Sep 19号的(下次打算12点之后再试试,说不定就不用交当天的门票了)。网上买完Pass之后需要打印下来,放在租车玻璃前。 Lake Louise到Jasper以北都没有信号,出发前需要下载谷歌离线地图(开车强烈推荐Apple自带的地图)。 路上也没啥加油站,在大城市需要把油加满。 Sep 19 9.18晚上飞到的Calgary,然后9.19打算去购物,Alberta 5%的税是真香啊。下午5点去Enterprise租车(我终于满25岁了可以不用再交Yonge Driver Fee了,而且Cobalt的信用卡还自带租车保险简直美滋滋),然后准备出发去Banff,由于很早就定了YWCA酒店,所以价格也算是挺便宜的。\nSep 20 我们从这里买的套票,包含了Banff硫磺山的Gondola,冰原探险,和Golden的Skybridge。由于我们之前打算去Jasper的,结果野火把Jasper给烧了,我们不得不改变行程住在Golden,正好这票里的Golden Skybridge也派上了用场,还可以自由安排去各个景点的时间。\n但是有一点需要注意的是,在网上买票如果没有定下具体时间的话是需要到现场schedule的,举个例子,我们本来计划起床后在Banff转转,因为YWCA外边就是瀑布花园(Cascade of Time Garden),吃点饭去惊喜角(Surprise Corner Viewpoint),然后路上路过的湖(Hector Lake Viewpoint, Bow Lake, Peyto Lake)也可以游玩。这样到达冰原中心就大概1点多了,检票的时候告诉我们最早能坐3点的车,白白浪费两个小时。所以建议早晨先去冰原中心,观光完可以在游客中心吃个饭,然后回来的路上(如果晚上住在Canmore或者Banff的话)再顺着湖游玩(有人说下午2点左右是Peyto湖的最佳观赏时间)。\n虽然三四十年后Athabasca Glacier可能会消失,但是我觉得CAD$109的票价有点贵了,大部分时间都是在等车,到了冰原上只有半个小时的拍照时间。\n这天晚上我们住在了Canmore,Canmore景色真的很不错!\nSep 21 这天早晨我们从Canmore出发,逛了Banff镇,Banff Gondola(注意这里网上买了票,到现场也需要schedule,但是我们11:50的缆车,11:00排队没啥人我们就直接上了,不需要像冰原中心傻等)逛了逛Banff镇,然后下午就向Golden出发。下午到了Golden后游览了Golden Skybridge。\n其实Banff Gondola完全可以走着爬硫磺山,然后下缆车一般不检票,再坐缆车下山,Golden Skybridge更是完全没有玩的必要。\nSep 22 22号计划去Lake Louise和Moraine Lake,这两个地方需要提前两天预定Shuttle Bus否则无法停车,这个Shuttle Bus的出发地是Park and Ride - Lake Louise and Moraine Lake Bus Shuttle (1 Whitehorn Rd, Lake Louise, AB T0L 1E0)。由于我们头天晚上住在Golden,因此计划早起开车到这个停车场,然后坐车。在官网中点击Parks Canada shuttles,然后选择Day Use, Shuttle to Lake Louise and Moraine Lake,选好日期就可以预定了。后面选择会有两个,Lake Louise和Moraine Lake,这两个票买哪个都可以,选择哪个湖就是从滑雪场先去哪个湖,注意这里的时间则跟冰原中心一样,网上预约的几点就是几点发车,没错我们又在游客中心傻等了。我们先去的Moraine Lake再去的Lake Louise。Lake Louise旁边有一个Trail可以俯瞰费尔蒙酒店,难度也不大很合适。\n我们晚上是住在Lake Louise的,这是个非常错误的决定,应该前一天在这住,第二天逛完后住在哪里都可,这样就不需要像我们一样早起从Golden赶过来了。\nSep 23 今天是Banff旅行的最后一天,我们从Lake Louise出发看了看Morant\u0026rsquo;s Curve就回卡尔加里还车了。Morant\u0026rsquo;s Curve需要从Lake Louise不上Hwy1,走北边一条路,这条路能见到不少野生动物,所以最好慢点开车,不走hwy也非常有意思。我们见到了小鹿,但是可惜没有见到熊。这条小路可以通往Johnson Canyon,但是后面的路被封了,我其实挺想一直慢点走走到Banff的,如果不去Johnson Canyon的话提前从Castle Junction拐出来(听导航的话)。\nFooter 由于Jasper被火烧 -\u0026gt; 酒店选择错误 -\u0026gt; 在路上消耗的时间比较多 + 游客中心傻等,感觉还是白白浪费了不少时间。看来Banff的坑还是比较多的,下次的话争取合理安排时间多走几个Trail。\n但是无论如何Banff实在是太美啦!!放几张风景照\n\u003c!DOCTYPE html\u003e\rLake Louise Lake Louise Fairmont Viewpoint Morant\u0026#39;s Curve Banff Canmore Bow Lake Moraine Lake ","permalink":"https://kyxie.me/zh/blog/life/banff/","summary":"Header 最近妈妈来了加拿大,打算带她去Calgary和Banff旅行,发现Banff旅游真的好多坑啊,正好写一篇游记博客,顺便记录一下Banff旅","title":"Banff旅行游记"},{"content":"Sep 2021, Scotiabank 之前办学签来加拿大走SDS用的是Scotiabank,因此我第一张checking account是Scotiabank的。学生账户的话免年费和无限次e-Transfer,但是非学生就要交管理费了,不过我好多同学毕业之后并没有去银行更新身份,即使银行系统里的学生身份到期,也一直没有收取管理费。\n我个人并不喜欢五大行,主要原因还是要交管理费,否则的话要在checking account里存$4000(简直神坑,按照5%的利率算,$4000存一年也有$200刀的利息了,还不如交管理费)。后来PGWP下来以后想去关卡,发现不同的branch对管理费要求还不一样,有的branch必须要每一天结束时checking account的balance都要大于$4000,有的branch则要求月末最后一天balance高于$4000就行,全靠branch经理心情决定。我在hwy404 \u0026amp; hwy7交叉口那个branch关卡,阿三姐找阿三经理问了好长时间,人家非得要我11刀月费否则不给关,然后我跑到hwy404 \u0026amp; steels那个branch,华人小哥给我秒关,可见其管理混乱。\nBTW我觉得Scotiabank比其他银行的App做得要好,滑动滑块转账我是真喜欢,但是不知道为什么总感觉Scotiabank给人e-Transfer到账时间要慢一点。\nDec 2022, Tangerine 当时办这张卡是被Tangerine的信用卡吸引,可以自行设定2到3个categories 2%还是3%返现(后来发现这也不是什么好卡),我觉得有了checking account应该会更容易批信用卡(不仅不是什么好卡,反而因为我不是PR给我拒了),而且意识到自己学生身份快要过期所以想办一个不收管理费的checking account。因为主动开卡的意愿比较大,也没有研究该怎么做开卡任务,因此我好像一点开户奖励都没有捞到(血亏)。\n除此之外,同样是网上银行且受CDIC的保护,Tangerine给出的GIC利率总是比EQ低那么一点点,这导致我不怎么喜欢Tangerine,因此也不把它当作自己的主账户。Mar 2024 Tangerine提醒我账户长期未使用,如果2个月内checking account余额还是没有变动则要收取$10的Inactive fee,得,正好趁这功夫给你把账户全关了吧,于是我在May 2024把checking account关了。\n期间在往外转钱的时候从Wealthsimple link账户,当时Tangerine余额为$72.19,我转了$72.19(exactly the same amount)到Wealthsimple,过几天发现转账失败扣了我$45的overdraft fee。于是乎我给客服打电话问他为什么扣我钱,阿三小哥说你账户有$72.19你往外转了$72.19,然后两边尬了5秒钟,我又问所以你为什么扣我钱,阿三小哥说我问一下经理,回来之后表达歉意说要退我钱,然后又问我办不办overdraft protection1个月只要$5\u0026hellip;\n由于是Scotiabank旗下因此我觉得他往外e-Transfer也特别慢。\nMay 2023, Simplii 这张卡也是被他家的信用卡吸引,0年费吃饭4%返现。由于绑定工资可以拿到$400,refer能再拿$50便开了checking account。这张卡无管理费,无限次email transfer还是很爽的,可以去CIBC的ATM取现金,缺点就是一天取最多$200。\n个人对这张卡无感,目前已经清空了账户,Oct, 2024关卡。\nOct 2023, EQ Bank 这张卡是一张prepaid Mastercard,需要先转账到EQ bank的checking account中,再转到这个卡。我特别喜欢这张卡,觉得颜值超高,而且这张卡的包装方式很独特,是像个抽屉一样抽出来的。EQ Bank的GIC rate基本上是所有银行中最高的,而且受到CDIC保护,我的GIC基本上都是从EQ买的。\n这张卡在ATM取款是不收手续费的,更重要的是,它花外币也不收2.5%的手续费,而且还有0.5%的返现,我把ChatGPT,EZPass这种美元结算的都绑定在这张卡上(已经绑定到Rogers WEMC了他们家花美元虽然不免FX,但是3%的返现,还账单再1.5x合计是4.5%的返现)。因为平时花美元也不多,可能也就是去旅游的话会花,所以也没有单独去申请专门的外币卡。\nJan 2024, TD 最近薅了把TD的羊毛,开checking account绑定工资再还一次账单,能拿$400,新移民能waive掉第一年的年费。开saving账户存$5000能拿$100,存$10000拿$200。开TSFA,FHSA,RRSP 3个账户中的1个存$5000拿$150,3个中的2个各存$5000拿$350。\nTD这张卡如果接收从国内转来的汇款会收取CAD$37.5的手续费,本来是CAD$17.5,但是好像经过了一个中转银行就多收了CAD$20。\nMay 2024, Wealthsimple 这张卡与Wealthsimple的cash account相连,cash account里的现金4%的利率(绑定工资的话4.5%,资产超过$100000也是4.5,不知道有没有叠加,有叠加,如果账户总资产超过CAD $100000且将工资绑定在了cash account则5%利率),所有消费1%返现,感觉卡面设计的还挺好看的就办下来了。有论坛说这张卡似乎(确实)也免FX,这么一比那是全方位秒杀EQ Card了,我暂时两个卡先都开着。\n我试了一下去只收debit卡的饭店刷这个卡和EQ card被拒绝消费了,看来prepaid卡还是不能算是严格意义上的debit卡。\nOct 2024, BMO 由于有国内汇款需求,TD的手续费太高,于是开了BMO的Checking Account。120天5.5%的利率,CAD$600的Cash offer还算是挺不错了。\n","permalink":"https://kyxie.me/zh/blog/wool/checking-account/","summary":"Sep 2021, Scotiabank 之前办学签来加拿大走SDS用的是Scotiabank,因此我第一张checking account是Scotiabank的。学生账户的话","title":"我使用过的加拿大🇨🇦支票账户"},{"content":"常用链接 实时枫叶变色情况以及历史数据 预定门票,门票$21一天,可以提前5天预定 安省枫叶地图 阿冈昆公园地图 推荐的景点 周边:\n白求恩故居 Lions Lookout Dorset Lookout Tower: 印象里这个好像要收费 Big Bend Lookout 60号公路:\n13.8km: Hardwood Lookout Trail: 环形trail(1.61km, 85m, 34min),路上会有向右箭头指示trail的方向,如果想直接看Lookout可以不跟着箭头反着走,即向左走 20km: Art Center \u0026amp; Source Lake: 无需徒步,建议穿白色和浅蓝色的衣服 25km: Track \u0026amp; Tower Trail: 环形Trail(8km, 273m, 2h23min),难度比较高,但是和Booth\u0026rsquo;s Rock Trail风景有一拼 35km: Lake of Two Rivers: 是个沙滩,可以野餐 38km右拐: Centennial Ridges Trail: 环形trail(12.2km, 550m, 4h6min) 39.7km: Algonquin Lookout Trail: 环形trail(2.1km, 71m, 37min) 40.5km右拐: Booth\u0026rsquo;s Rock Trail: 环形trail(5.8km, 232m, 1h51min),需要预约车位 43km: Visitor Center 45km: Beaver Pond Trail: 环形trail(1.9km, 66m, 34min),但是不知道为什么我感觉这个最累,可能每次都放在最后一个走 50km: Brewer Lake: 不需要徒步,路边停车所以停车位有限,适合长焦拍风景 Footer 最后放几张照片吧\n\u003c!DOCTYPE html\u003e\rArt Center Found Lake ","permalink":"https://kyxie.me/zh/blog/life/algonquin/","summary":"常用链接 实时枫叶变色情况以及历史数据 预定门票,门票$21一天,可以提前5天预定 安省枫叶地图 阿冈昆公园地图 推荐的景点 周边: 白求恩故居 Lions Lookout Dorset Lookout Tower:","title":"Algonquin旅行攻略"},{"content":"前言 我就喜欢搞一些简洁而又花里胡哨的东西。\n教程基于Windows 11自带的Terminal。\n字体 我使用的字体是CodeNewRoman Nerd Font,这个字体同样是我博客的字体,可以从这里下载,下载后安装即可,也可以在VS Code上使用这个字体。\n下载 oh-my-posh winget install JanDeDobbeleer.OhMyPosh 终端设置 我这里直接修改了Windows PowerShell的配置,如果不想破坏默认的配置也可以新建一个配置文件。\n在配色方案的选项下,我选择的Campbell,但是我打开设置的json file里面把第一个主题的background改成了#0C0C0C,避免了纯黑的背景。\n在Windows PowerShell的常规选项下,取消勾选使用父进程目录,在外观选项下选取下载的字体CodeNowRoman Nerd Font。\n文件配置 在终端输入\necho $profile 找到这个文件,如果找不到自己新建一个。\n从这里选择一个自己喜欢的主题,点击主题名字进入相应的github并且下载.json源码,保存在本地,粘贴下面语句到这个文件中,修改路径为你保存的路径。\noh-my-posh init pwsh --config \u0026#39;C:/Users/Posh/jandedobbeleer.omp.json\u0026#39; | Invoke-Expression 保存后运行:\n. $profile FAQ 如果运行失败,可能需要更新PSReadLine。\n如果识别不了icon,大概率字体的问题,查看是否在PowerShell的页面下设置字体为Nerd字体。\n效果展示 ","permalink":"https://kyxie.me/zh/blog/tech/others/bash/","summary":"前言 我就喜欢搞一些简洁而又花里胡哨的东西。 教程基于Windows 11自带的Terminal。 字体 我使用的字体是CodeNewRoman Nerd Fo","title":"Windows 11 打造个性化终端"},{"content":" Dec 25, 2022,硕士毕业 Jan 3, 2023,收到毕业信 Apr 27, 2023,收到CELPIP成绩,入池,其实毕业之前就该考出来的,没必要等着PGWP下来再申请省提名,白浪费了半年多 Jun 6, 2023,被捞,当天提交申请 Jun 27, 2023,补交材料 Jun 28, 2023,收到DIP Jul 25, 2023,收到省提名信,这里估摸着差不多了提前把无犯罪证明,出生证明,身份证,户口本公正或者翻译了,还能再省点时间(身份证和户口本是Optional) Aug 1, 2023,提交联邦申请 Dec 1, 2023,收到AOR和指纹信,成功link到IRCC Dec 12, 2023,收到PAL Dec 14, 2023,上午录指纹的时候发现邮箱里有体检信,提醒一下如果有办学签时候的体检证明一块交了,到时候可以waive掉,我这里找不到了只能再做一次体检,验尿抽血胸片,怒花270刀保险还不报销😭,由于可以walk in下午我直接去做了体检 Feb 14, 2024,被要求提交简历,看来要被安调 Feb 15, 2024,tracker上F12出现17 security被安调了,这一时半会出不了安省了,怪你电太牛逼吧 未完待续\u0026hellip;希望早点收到枫叶卡,早点入籍了好让我南下赚钱 ","permalink":"https://kyxie.me/zh/blog/life/pr/","summary":"Dec 25, 2022,硕士毕业 Jan 3, 2023,收到毕业信 Apr 27, 2023,收到CELPIP成绩,入池,其实毕业之前就该考出来的,没必要等着PGWP下来再申","title":"OINP移民加拿大🇨🇦时间线"},{"content":"前言 我有时需要使用虚拟机上的Linux环境,但是有些软件在Linux是上是没有的,需要用Windows的软件但是用Linux的数据。于是找到了个办法将Linux映射为Windows的一个本地磁盘,这样Windows的软件就可以直接打开Linux的文件夹了。\nLinux 假如我现在登录用户为user1,我希望把home/user1的所有文件共享给Windows,当然也可以新建用户和新建文件夹来作为共享文件夹。\n安装Samba:\nsudo apt update sudo apt install samba 编辑Samba配置文件:\nsudo nano /etc/samba/smb.conf 在文本末尾添加:\n[Name] path = /home/user1/shared read only = no browsable = yes [Name]是共享文件夹的名称,会显示在Windows磁盘上\n设置Samba账户密码:\nsudo smbpasswd -a user1 sudo smbpasswd -e user1 重启Samba服务:\nsudo systemctl restart smbd Windows 打开文件资源管理器 右键点击“此电脑”,选择“映射网络驱动器” 选择一个驱动器字母(例如Z:) 在文件夹栏中输入:\\\\Linux IP Address\\Name 完成剩余步骤 ","permalink":"https://kyxie.me/zh/blog/tech/router/samba/","summary":"前言 我有时需要使用虚拟机上的Linux环境,但是有些软件在Linux是上是没有的,需要用Windows的软件但是用Linux的数据。于是找到","title":"使用Samba将Linux映射为Windows磁盘"},{"content":"Ubuntu 安装 sudo apt update sudo apt upgrade sudo apt install wireguard 配置 进入/etc/wireguard,并生成密钥对\nsudo -i cd /etc/wireguard umask 077 wg genkey | tee privatekey | wg pubkey \u0026gt; publickey 编辑配置文件wg0.conf\n[Interface] PrivateKey = [LINUX_PRIVATE_KEY] Address = 192.168.100.1/24 ListenPort = 51820 [Peer] PublicKey = [WINDOWS_PUBLIC_KEY] Endpoint = [WINDOWS_IP]:51820 AllowedIPs = 192.168.100.2/32 启动wireguard\nsudo wg-quick up wg0 OpenWrt 安装 所需插件详见:使用树莓派4B+安装OpenWrt用作旁路由 | Kunyang\u0026rsquo;s Blog\n配置 Network → Interface → Add new interface,创建一个wireguard,名字就叫wg0\n点击Generate new key pair,会自动生成一个公钥一个私钥,IP地址可以随便写一个私有地址的网段,我填写192.168.100.1/24,这就是这个VPN的子网,然后设置默认端口,可以随便写,这里我设置55555\n防火墙可以选择vpn\n在Network→Firewall→Custom Rules添加一条自定义命令\niptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE 这条命令的意思是针对子网192.168.100.0/24内的数据包,当数据从eth0也就是外接端口转发出去的时候,将数据包的源地址伪装成路由器的公网IP\n如果OpenWrt是主路由,则需要在Firewall→Traffic Rules中开放端口\n如果OpenWrt是旁路由,则需要在主路由上做端口转发\n在Network→Interface→wg0点击Edit,然后转到Peers,点击Add peer\n添加Description,比如我的Windows台式机 我们可以点击创建新的密钥对 建议创建Preshared Key Allow IPs就是这个节点在这个VPN网络的IP地址 Keep Alive可以设置为25 可以重启一下路由器\nWindows或Mac Os 安装 从这里下载wireguard app\n配置 在OpenWrt→Network→Interface→wg0→Edit Peer中可以很方便地为每个终端导出配置文件,复制粘贴在Windows客户端的wireguard中就可以了\n外网连接VPN 前提条件 需要一个域名\n需要公网IP\n一些包比如ddns-scripts-cloudflare和luci-app-ddns\n配置步骤 首先需要Cloudflare创建一条A记录,域名是vpn.kyxie.me,IP地址可以随便填,反正将来还会被DDNS覆盖,Proxy status选择关闭,只进行DNS不进行代理\n在这里点击Create Token,创建一个专用的API token\n选择Edit Zone DNS,点击Use Template\n按照下图配置\n生成API Token后注意保存好,只会显示一次\n然后回到OpenWrt→Service→Dynamic DNS→Services,添加一个ddns_ipv4,下面是详细配置,注意必须要安装了ddns-scripts-cloudflare之后才能在DDNS Service provider找到cloudflare.com-v4\nddns: \u0026#34;Enabled\u0026#34;: true \u0026#34;Lookup Hostname\u0026#34;: \u0026#34;vpn.kyxie.me\u0026#34; \u0026#34;IP address version\u0026#34;: \u0026#34;IPV4-Address\u0026#34; \u0026#34;DDNS Service provider\u0026#34;: \u0026#34;cloudflare.com-v4\u0026#34; \u0026#34;Domain\u0026#34;: \u0026#34;vpn@kyxie.me\u0026#34; \u0026#34;Username\u0026#34;: \u0026#34;Bearer\u0026#34; \u0026#34;Password\u0026#34;: \u0026#34;Your API Token\u0026#34; \u0026#34;Use HTTP Secure\u0026#34;: true \u0026#34;Path to CA-Certificate\u0026#34;: \u0026#34;/etc/ssl/certs\u0026#34; 如果OpenWrt为主路由,这样应该可以完成DDNS解析了,但是如果OpenWrt为旁路由,由于路由器的wan口并不知道公网IP,需要使用借助网站来得知自己的公网IP,我们在Service→Dynamic DNS→Services→ddns_ipv4→Edit→Advanced Settings→IP address source选择URL,URL to detect可以选择默认ipv4的urlhttp://checkip/dymdms.com\n这样DDNS的配置就完成了,以后如果运营商给你换了公网IP也不会影响域名的配对了\n配置完后可以去cloudflare看看ip地址有没有刷新\n现在有了DDNS,我们就可以把Peer的EndPoint改成自己的域名了\n将OpenWrt生成的Configuration填入其他设备,就可以接入VPN了\n","permalink":"https://kyxie.me/zh/blog/tech/router/wireguard/","summary":"Ubuntu 安装 sudo apt update sudo apt upgrade sudo apt install wireguard 配置 进入/etc/wireguard,并生成密钥对 sudo -i cd /etc/wireguard umask 077 wg genkey | tee privatekey | wg pubkey \u0026gt; publickey 编辑配置文件wg0.conf [Interface] PrivateKey","title":"Wireguard配置"},{"content":" 假设我们有两台Linux虚拟机A和B,使用A和B互相充当Server和Client\nTLS模式 假设我们使用A来充当server,B来充当client\nTLS Server 在A中下载OpenVPN\nsudo apt-get install openvpn 在/usr/share/doc/openvpn/examples/sample-keys/文件夹下有好多keys,在server中,复制ca.crt,server.key,server.crt,dh2048.pem到/etc/openvpn/tls-server\nsudo cp /usr/share/doc/openvpn/examples/sample-keys/{ca.crt,server.key,server.crt,dh2048.pem} /etc/openvpn/tls-server 编写服务器配置文件\nport 1194 proto udp dev tun0 ca ca.crt cert server.crt key server.key dh dh2048.pem server 10.8.0.0 255.255.255.0 keepalive 10 120 user nobody group nogroup persist-key persist-tun verb 3 如果使用TCP连接,则修改为\nport 1194 proto tcp-server dev tun0 ca ca.crt cert server.crt key server.key dh dh2048.pem server 10.8.0.0 255.255.255.0 keepalive 10 120 user nobody group nogroup persist-key persist-tun verb 3 启动OpenVPN Server\ncd /etc/openvpn/tls-server sudo openvpn --config server.conf 这时如果查看IP地址可以看到tun0接口,地址是10.8.0.1\nTLS Client 在B中下载OpenVPN\nsudo apt-get install openvpn 在A中/usr/share/doc/openvpn/examples/sample-keys/下找到ca.crt,client.key,client.crt,复制到B中\n# In B sudo scp [A_usrname]@[A_addr]:/usr/share/doc/openvpn/examples/sample-keys/{ca.crt,client.crt,client.key} /etc/openvpn/tls-client 编写server.conf\nclient dev tun0 remote [A_addr] 1194 udp ca ca.crt cert client.crt key client.key user nobody group nogroup persist-key persist-tun verb 3 如果是TCP连接则\nclient dev tun0 remote [A_addr] 1194 tcp-client ca ca.crt cert client.crt key client.key user nobody group nogroup persist-key persist-tun verb 3 运行OpenVPN Client\ncd /etc/openvpn/tls-client sudo openvpn --config client.conf 这时如果执行\nping 10.8.0.1 成功,说明OpenVPN成功建立\nPSK模式 PSK模式不需要配置复杂的keys,比较简单,但是安全性也会随之降低,这里我们同样让A充当Server,B充当Client\nPSK Server 在A中生成psk.key,并且复制一份给B\n# In A cd /etc/openvpn/psk-server openvpn --genkey --secret psk.key # In B cd /etc/openvpn/psk-client scp [A_usrname]@[A_addr]:/etc/openvpn/psk-server/psk.key . 编写server.conf\ndev-type tun dev tun0 ifconfig 10.8.0.6 10.8.0.1 keepalive 10 120 persist-tun secret psk.key verb 0 # proto tcp-server 如果是TCP连接,则取消注释最后一行\n启动OpenVPN\ncd /etc/openvpn/psk-server sudo openvpn --config server.conf PSK Client 编写client.conf\ndev-type tun dev tun0 remote [A_addr] 1194 udp ifconfig 10.8.0.1 10.8.0.6 keepalive 10 120 persist-tun secret psk.key verb 0 如果是TCP连接\ndev-type tun dev tun0 remote 10.10.200.120 1194 tcp-client ifconfig 10.8.0.1 10.8.0.6 keepalive 10 120 persist-tun secret psk.key verb 0 ","permalink":"https://kyxie.me/zh/blog/tech/router/openvpn/","summary":"假设我们有两台Linux虚拟机A和B,使用A和B互相充当Server和Client TLS模式 假设我们使用A来充当server,B来充当cli","title":"OpenVPN的简单配置"},{"content":"Character 判断是否为字母或数字:\nboolean res = Character.isLetterOrDigit(char); 转小写:\nchar res = Character.toLowerCase(char); 下一个字符:\n\u0026#39;b\u0026#39; == (char) (\u0026#39;a\u0026#39; + 1); Integer 最大值最小值:\nint max = Integer.MAX_VALUE; int min = Integer.MIN_VALUE; 比较相等:\nInteger a = 1; Integer b = 1; a == b;\t// true Integer c = 200; Integer d = 200; c == d;\t// false Objects.equals(c, d);\t// true Array 创建数组:\nint[] array = new int[5]; int[] array = new int[]{1,2,3,4}; int[] array = {1,2,3,4}; int[][] array = {{1,2}, {3,4}}; 引用:\narray[3]; 获取长度:\narray.length; 快速初始化:\n// 我们要给这个Map的值快速填充 Map\u0026lt;Integer, List\u0026lt;Integer\u0026gt;\u0026gt; map = new HashMap\u0026lt;\u0026gt;(); map.put(1, Arrays.asList(1, 2, 3)); map.put(2, Arrays.asList(2, 3, 4)); 排序:\nArrays.sort(array); // int[] 不能直接做降序排列 // 想做降序排列只能用Integer[] Integer[] array = new Integer[2]; Arrays.sort(array, Comparitor.naturalOrder());\t// 升序排列 Arrays.sort(array, Comparator.reverseOrder());\t// 降序排列 二维数组排序:\nint[][] array = new int[][]{{1, 2}, {2, 3}}; Arrays.sort(array, (o1, o2) -\u0026gt; o1[0] - o2[0]);\t// 按照二维数组的第一个元素从小到大排序 Arrays.sort(array, (o1, o2) -\u0026gt; o1[1] - o2[1]);\t// 按照二维数组的第二个元素从小到大排序 复制子数组:\n// array: 原始数组,不包括to的结束索引 subArray = Arrays.copyOfRange(array, from, to); // array = [4, 2, 5, 1, 6, 3, 7] subArray = Arrays.copyOfRange(array, 0, 3); // subArray = [4, 2, 5] 打印:\nSystem.out.println(Arrays.toString(array)); 填满:\nint[] array = new int[]; int num; Arrays.fill(array, num);\t// array全部元素等于num String 创建字符串:\nString string = \u0026#34;java\u0026#34;; 指定位置的字符\nchar charAt3 = string.charAt(3);\t// charAt3 = \u0026#39;a\u0026#39; 字符串相等:\nString string1 = \u0026#34;abc\u0026#34;; String string2 = \u0026#34;abc\u0026#34;; string1.equals(string2); 字符串转整数:\nString string = \u0026#34;123\u0026#34;; int integer = Integer.parseInt(string); 字符串长度:\nint length = string.length(); 截取字符串:\nString sb = \u0026#34;abcdef\u0026#34;; String str = sb.substring(0, 1);\t// str = \u0026#34;a\u0026#34;; String str = sb.substring(1);\t// str = \u0026#34;bcdef\u0026#34;;\t如果只有一个参数则为beginIndex 字符的位置:\nString str = \u0026#34;abc\u0026#34;; int index = str.indexOf(b);\t// index = 1 字符串转字符数组:\nString str; char[] temp = str.toCharArray(); 字符串分割:\nString str = \u0026#34;hello world\u0026#34;; String[] word = str.split(\u0026#34; \u0026#34;);\t// word = [\u0026#34;hello\u0026#34;, \u0026#34;world\u0026#34;] // 这里必须是字符串 // 如果有两个空格连在一起,会在数组中加入一个\u0026#34;\u0026#34;(空字符串) 将字符串数组合并为长字符串(中间插入):\nString[] words = new String[]{\u0026#34;hello\u0026#34;, \u0026#34;world\u0026#34;}; String str = String.join(\u0026#34; \u0026#34;, words); // str = \u0026#34;hello world\u0026#34;; 字符串替换:\nString str = \u0026#34;a! b\u0026#34;; str = str.replace(\u0026#34;!\u0026#34;, \u0026#34; \u0026#34;);\t// str = \u0026#34;a b\u0026#34;; // 字符或者字符串都可以替换 删除字符串头尾的空格:\nString str = \u0026#34; abc \u0026#34;; str.trim();\t// str = \u0026#34;abc\u0026#34; 字符串拼接:\nString str = \u0026#34;abc\u0026#34;; System.out.println(str + \u0026#34;def\u0026#34;);\t// 可以直接使用+ Stack 创建 stack:\nDeque\u0026lt;Integer\u0026gt; stack = new ArrayDeque\u0026lt;\u0026gt;(); 栈顶:\nstack.peek() 入栈:\nstack.push(); 出栈:\nstack.pop(); 栈是否为空:\nstack.isEmpty(); 栈的长度:\nstack.size(); ArrayList 创建列表:\nList\u0026lt;Integer\u0026gt; array = new ArrayList\u0026lt;\u0026gt;(); List\u0026lt;Integer\u0026gt; array = new ArrayList\u0026lt;\u0026gt;(Arrays.asList(1, 2, 3, 4));\t// 初始化值 添加元素:\narray.add(1);\t// List只能在末尾添加元素,在中间插入元素会导致额外的内存开销,可以选择使用LinkedList 指定位置的元素:\narray.get(0); 列表中是否存在某元素:\narray.contains(0); 删除列表元素:\narray.remove(0);\t// 删除array[0] array.remove(Integer.valueOf(0));\t// 删除元素0 列表大小:\narray.size(); 判断列表是否为空:\narray.isEmpty(); 清空列表:\narray.clear(); 升序排列:\narray.sort(Comparator.naturalOrder()); 降序排列:\narray.sort(Comparator.reverseOrder()); 修改值:\narray.set(int index, int value); 反转:\nCollections.reverse(array); HashMap 创建一个哈希映射:\nMap\u0026lt;Integer, Integer\u0026gt; map = new HashMap\u0026lt;\u0026gt;(); 存储键值对(修改键值对):\nmap.put(key, value); // 如果不知道key存不存在 map.putIfAbsent(key, defVal); 获取 key 的内容:\nmap.get(key); // 如果不知道key存不存在 map.getOrDefault(key, defVal); // 常见用法 map.put(key, map.getOrDefault(key, 0) + 1); 计算:\n// 键不存在时执行的操作 map.computeIfAbsent(key, k -\u0026gt; mappingFunc); // 键存在时执行的操作 map.computeIfPresent(key, (k, v) -\u0026gt; mappingFunc); 查询是否存在 key:\nmap.containsKey(key); 键集合和值集合:\n// 返回一个Collections\u0026lt;V\u0026gt;视图,keys组成的集合 map.keySet(); // 返回一个Collections\u0026lt;V\u0026gt;视图,values组成的集合 map.values(); // 假设map为{1: {1, 2, 3}, 2: {2, 3, 4}} map.keySet = {1, 2}; map.values = {{1, 2, 3}, {2, 3, 4}}; 遍历键值对:\n// 遍历key for (Integer key : map.keySet()) { } // 遍历value for (Integer value : map.values()) { } // 如果需要同时访问键和值,使用map.entrySet()会更直观 for (Map.Entry\u0026lt;Integer, Integer\u0026gt; entry : map.entrySet()) { Integer key = entry.getKey(); Integer value = entry.getValue(); } 是否为空:\nmap.isEmpty(); 删除Key:\nmap.remove(key); 大小:\nmap.size(); HashSet 创建哈希表:\nSet\u0026lt;Integer\u0026gt; set = new HashSet\u0026lt;\u0026gt;(); 添加元素:\nset.add(); 判断元素是否存在:\nset.contains();\t// HashSet查找元素要优于ArrayList 删除元素:\nset.remove(); 清空:\nset.clear(); 遍历:\nfor (int temp : set) { ... } StringBuilder 创建 StringBuilder:\nStringBuilder sb = new StringBuilder(); 在末尾添加字符或字符串:\nsb.append(char); 在末尾删除字符:\nsb.deleteCharAt(sb.length() - 1); 长度:\nsb.length(); 转化为 String:\nsb.toString(); 取反:\nsb.reverse(); 插入:\nsb.insert(0, \u0026#34;abcd\u0026#34;);\t// 在第0个元素插入\u0026#34;abcd\u0026#34; 清空:\nsb.setLength(0); 取字符:\nsb.charAt(i); 修改位置的字符:\nsb.setCharAt(i); Queue 创建queue:\nQueue\u0026lt;Integer\u0026gt; q = new LinkedList\u0026lt;\u0026gt;(); 加入元素:\nq.offer(1); 删除元素(先进先出):\nq.poll(); 队首元素:\nq.peek(); 队列大小:\nq.size(); 是否为空:\nq.isEmpty(); 队列清空:\nq.clear(); Deque 创建Deque:\nDeque\u0026lt;Integer\u0026gt; deque = new ArrayDeque\u0026lt;\u0026gt;(); 队尾添加元素:\ndeque.offerLast();\t// queue的用法 队首弹出元素:\ndeque.pollFirst();\t// queue的用法 取队首元素:\ndeque.peekFirst();\t// queue的用法 队首添加元素:\ndeque.offerFirst(); 队尾弹出元素:\ndeque.pollLast(); 取队尾元素:\ndeque.peekLast(); LinkedList 新建链表:\nLinkedList\u0026lt;Integer\u0026gt; link = new LinkedList\u0026lt;\u0026gt;(); 头部插入:\nlink.addFirst(); 末尾插入:\nlink.addLast(); link.add(); 指定位置插入:\nlink.add(int index, int Ele); 清空:\nlink.clear(); 删除并返回第一个:\nlink.removeFirst(); 删除并返回最后一个:\nlink.removeLast(); 删除特定位置:\nlink.remove(int index); 删除特定元素:\nlink.remove(Object o); link.remove(Integer.valueOf(2)); 重设:\nlink.set(); 头部取值:\nlink.getFirst(); 尾部取值:\nlink.getLast(); 特定位置取值:\nlink.get(int index); 是否存在:\nlink.contains(int key); 遍历:\n// 不涉及元素增添或删除可以用for each for (String element : link) { } // 涉及到则需要使用迭代器 Iterator\u0026lt;String\u0026gt; iterator = link.iterator();\t// 初始化时指向哑节点 while (iterator.hasNext()) { String element = iterator.next(); } PriorityQueue 创建优先队列:\n// 小根堆 (Min Heap) PriorityQueue\u0026lt;Integer\u0026gt; pq = new PriorityQueue\u0026lt;\u0026gt;(); // 大根堆 (Max Heap) PriorityQueue\u0026lt;Integer\u0026gt; pq = new PriorityQueue\u0026lt;\u0026gt;((a, b) -\u0026gt; b - a); 插入元素:\n// 每次插入一个元素,时间复杂度是O(log k),其中k是堆中当前元素的个数 // 将n个元素逐个push到一个空的大根堆的时间复杂度为O(n log n) pq.offer(); 取堆顶:\npq.peek(); 弹出堆顶:\n// 同样,pop一次的时间复杂度为O(log n) // n个元素则为O(n log n) pq.poll(); 删除特定元素:\npq.remove(); 堆大小:\npq.size(); AtomicInteger 多线程中的integer,线程操作对其是原子性的,不会被其他线程打断。\n创建:\nAtomicInteger a = new AtomicInteger(0); 获取当前值:\nint value = a.get(); 设置值:\na.set(2); 先获取再设置:\nint oldValue = a.getAndSet(20); 先比较再设置:\nboolean updated = a.compareAndSet(20, 43); // 如果a == 20,则将a = 43,updated = true // 如果a != 20,则将a不更新,updated = false 加一,返回加一后的值:\nint incrementedValue = a.incrementAndGet(); 减一,返回减一后的值:\nint decrementedValue = a.decrementAndGet(); 互相转换 // int转String int i; String str = String.valueOf(i); // String转int String str; int i = Integer.parseInt(str); // char转int char ch; int i = ch - \u0026#39;0\u0026#39;; // int转char int i; char ch = (char) (i + \u0026#39;0\u0026#39;); // String转char[] String str; char[] ch = str.toCharArray(); // char[]转String char[] ch; String str = Arrays.toString(ch);\t// 转化后有[]包裹 // char转String char ch = \u0026#39;a\u0026#39;; String str = ch + \u0026#34;\u0026#34;; // ArrayList转Integer[] List\u0026lt;Integer\u0026gt; list; Integer[] array = list.toArray(new Integer[list.size()]); // Integer[]转ArrayList Integer[] array; List\u0026lt;Integer\u0026gt; list = Arrays.asList(array); 坑 Math.ceil:\ndouble Math.ceil(double a);\t// 原函数 Math.ceil(24 / 23);\t// 1.0 Math.ceil(22 / 23);\t// 0.0 Math.ceil((double) 24 / 23);\t// 2.0 (int) Math.ceil((double) 24 / 23);\t// 2 Math.pow:\nMath.pow(10, 9);\t// 如果想求次方必须要用pow函数,返回double 10 ^ 9;\t// 这里表示的是亦或而不是次方 二维数组:\nint[][] a = new int[][] {{1, 2}, {3, 4}}; int[] b = a[1];\t// b = [3, 4] b[1] = 100; // a = [[1, 2], [3, 100]] ","permalink":"https://kyxie.me/zh/blog/tech/others/java/","summary":"Character 判断是否为字母或数字: boolean res = Character.isLetterOrDigit(char); 转小写: char res = Character.toLowerCase(char); 下一个字符: \u0026#39;b\u0026#39; == (char) (\u0026#39;a\u0026#39; + 1); Integer 最大值最小值: int max = Integer.MAX_VALUE; int min = Integer.MIN_VALUE; 比较相等: Integer a = 1; Integer b = 1; a == b; // true","title":"Java Cheat Sheet"},{"content":"Linux 下载OpenLDAP:\nsudo apt update sudo apt install slapd ldap-utils sudo apt install ldap-utils 配置OpenLDAP:\nsudo dpkg-reconfigure slapd DNS domain name: example.org\nPassword: root\n创建user.ldif:\n# ldap是username dn: uid=ldap,dc=example,dc=org objectClass: inetOrgPerson objectClass: posixAccount uid: ldap sn: LDAP givenName: LDAP cn: LDAP User displayName: LDAP User uidNumber: 10000 gidNumber: 10000 homeDirectory: /home/ldap loginShell: /bin/bash 把user加入OpenLDAP服务器:\nldapadd -x -D \u0026#34;cn=admin,dc=example,dc=org\u0026#34; -W -f user.ldif 启动和查看OpenLDAP的状态:\nsudo systemctl start slapd sudo systemctl status slapd 查看当前已有的用户:\nldapsearch -x -LLL -b \u0026#34;dc=example,dc=org\u0026#34; \u0026#34;(objectclass=inetOrgPerson)\u0026#34; uid userPassword 修改用户密码:\nldappasswd -x -D \u0026#34;cn=admin,dc=example,dc=org\u0026#34; -W -S \u0026#34;uid=ldap,dc=example,dc=org\u0026#34; ","permalink":"https://kyxie.me/zh/blog/tech/router/ldap/","summary":"Linux 下载OpenLDAP: sudo apt update sudo apt install slapd ldap-utils sudo apt install ldap-utils 配置OpenLDAP: sudo dpkg-reconfigure slapd DNS domain name: example.org Password: root 创建user.ldif: # ldap是username","title":"Linux配置LDAP Server"},{"content":"Wealthsimple 开户 使用推荐码VXU-UQ开设账号,在开户后的30天内存$1即可获得$25奖励。\nFeatures Core Premium 资金要求 $0 $100000 Commission Fee $0 $0 Cash Account 4% 4.5% USD FX 1.5% 1.5% 期权交易 $2 $0.75 Crypto Trading Fee 2% 1% USD Account $10 / mon $0 如果购买美元计价的股票买卖都是1.5%,加起来就是3% 如果是premium,买卖不收取1.5%手续费,但是加币转美元还是要收取外汇转换费1.5% 如果把工资的Direct Deposit绑在cash account上的话利率为4.5%,并且利率是可以和其他因素叠加的,比如我是Premium用户,我也绑了工资,那我的利率就是5%,详细信息可以看:我使用过的加拿大🇨🇦支票账户 | Kunyang\u0026rsquo;s Blog (kyxie.github.io) Questrade 开户 使用邀请码855908417478550开户,存入$1000可收到奖励$50。\nFeatures 交易股票每股$0.01,min $4.95 to max $9.95 买ETF$0,卖$0.01,min $4.95 to max $9.95 交易期权需要$9.95 + $1 / contract Questrade将部分账户金额头寸转移到其他金融机构的收费从原先的$25升至$150 TFSA RRSP无年费 可以存美元进RRSP USD Margin rate为3.25% IBKR 开户 使用https://ibkr.com/referral/kunyang118进行开户。\n推荐人奖励:每推荐一位客户成功开立个人账户或联名账户并使账户的净清算价值在一年之中保持在USD$10000以上,推荐人获得USD$200的奖金。\n被推荐人奖励:被推荐人在账户中每存入USD$100的资产(现金或其他资产)可获得USD$1的IBKR股票,最高可获得USD$1000的股票,平均余额必须至少保有一年方可使股票解禁。\nFeatures Trading Fee Fixed:每股USD $0.005,每次交易最低收USD $1,最高收交易价值的1% Tiered:低于300k Shares时,佣金为每股USD $0.0035,最低收USD $0.35,最高收交易价值的1%。但此收费方式还要加(或减)交易所费,清算费和规管等其他费用(加股交易Fixed每股CAD$0.01,最低CAD$1,最高为交易价值的0.5%) 对于大量资金和交易的客户,Fixed会比较划算。如果是少量资金入场的小伙伴,每次想一股一股的买,那Tiered更合适 兑换美金:每笔收换汇金额的0.002%,最低收USD$2(当换汇金额低于USD$100,000时,手续费一直都是USD$2,最少CAD$2500) 开设RRSP需要交CAD$12.5 / season的季度费,因此不要在IBKR中开RRSP USD Margin Interest为1.59% EQ EQ虽然不是券商,但是可以开一个免费的USD Account,3% interest,加拿大的银行USD to USD transfer免费。\n","permalink":"https://kyxie.me/zh/blog/wool/stock-brokers/","summary":"Wealthsimple 开户 使用推荐码VXU-UQ开设账号,在开户后的30天内存$1即可获得$25奖励。 Features Core Premium 资金要求 $0 $100000 Commission Fee $0 $0 Cash Account 4% 4.5% USD FX 1.5% 1.5% 期权交易 $2 $0.75 Crypto Trading","title":"加拿大券商对比"},{"content":"通过使用keys我们可以免密登录Linux server,这样以后ssh到Linux的时候就不需要每次填写密码了。\n首先在windows上生成一个密钥对,一般会生成在C:\\Users\\Username/.ssh/id_rsa,而且都是成对生成的,会有一个公钥id_rsa.pub和一个私钥。\nssh-keygen 在Linux中查看是否有.ssh目录,如果没有则新建\ncd ~ mkdir -p ~/.ssh chmod 700 ~/.ssh 将公钥id_rsa.pub上传到Linux\ncd C:\\Users\\Username/.ssh/ scp .\\id_rsa.pub username@address:~/.ssh 在Linux中查看是否有authorized_keys文件,如果没有则新建\ncd ~/.ssh touch authorized_keys chmod 600 ./authorized_keys cat id_rsa.pub \u0026gt;\u0026gt; ./authorized_keys 添加完之后就可以将id_rsa.pub删除了\ncd ~/.ssh rm id_rsa.pub 这样以后就不再需要输密码了。\n","permalink":"https://kyxie.me/zh/blog/tech/router/keys/","summary":"通过使用keys我们可以免密登录Linux server,这样以后ssh到Linux的时候就不需要每次填写密码了。 首先在windows上生成一","title":"使用Keys免密ssh到Linux"},{"content":"\rKyxie\u0026#39;s Blog\rA Hello World Printer\rSulv’s Blog\r记录技术、阅读、生活的博客\r嘰嘰乞乞\r但願我靈魂沒有生鏽\r友链格式:\nname=\u0026#34;Kyxie\u0026#39;s Blog\u0026#34; url=\u0026#34;https://kyxie.me/zh\u0026#34; logo=\u0026#34;https://kyxie.me/Avatar.jpg\u0026#34; word=\u0026#34;A Hello World Printer\u0026#34; ","permalink":"https://kyxie.me/zh/links/","summary":"Kyxie\u0026#39;s Blog A Hello World Printer Sulv’s Blog 记录技术、阅读、生活的博客 嘰嘰乞乞 但願我靈魂沒有生鏽 友链格式: name=\u0026#34;Kyxie\u0026#39;s Blog\u0026#34; url=\u0026#34;https://kyxie.me/zh\u0026#34; logo=\u0026#34;https://kyxie.me/Avatar.jpg\u0026#34; word=\u0026#34;A Hello World Printer\u0026#34;","title":"友链 🤝"},{"content":"👉️填写QQ邮箱可以自动获取QQ头像哦\n","permalink":"https://kyxie.me/zh/comment/comments/","summary":"👉️填写QQ邮箱可以自动获取QQ头像哦","title":"留言板 📋"},{"content":"研究生项目 Turbo Wallet - 记账软件 2022年1月 至 2022年3月,JavaScript\nGitHub (前端仓库): https://github.com/Kyxie/money-management.git\nGitHub (后端仓库): https://github.com/Kyxie/money-back.git\n这是一个帮助我们记录每天生活花费的手机App。 前端基于React.js框架,后端基于Express.js框架,数据库基于MongoDB。 可以添加,编辑和删除每一条消费记录,并且App会生成一些折线图和饼图帮助我们分析近期的消费。 还可以直观地看到哪一种消费花了多少钱,以及不同种类的消费的排序。 交通监视系统 2021年9月 至 2021年12月,Python / C++\nGitHub: https://github.com/Kyxie/Traffic.git\n这个项目帮助当地警察局在道路交叉口安装最少的摄像头,但是获得最大的监控覆盖面积。这是一个顶点覆盖问题,我们利用CNF-SAT来对这个问题进行优化。 使用Python生成一张包含城市交通细节的地图(道路和十字路口),然后尝试使用迪杰斯特拉算法在城市中找到最短路径,最后,我们利用CNF-SAT模拟安装摄像头是否能覆盖城市所有街道,解决顶点覆盖问题。 该项目实现了多线程和并行处理,以更高效地运行。 我的个人网站 2021年8月 至 今,HTML / CSS / JavaScript\nGitHub: https://github.com/Kyxie/Kyxie.github.io.git\n这个项目是基于Hugo的PaperMod主题。 本科项目 基于深度学习的行人重识别系统 2020年9月 至 2021年6月,Python\nGitHub: https://github.com/Kyxie/ReID-deep-learning.git\n本项目是基于深度学习方法的行人重识别系统,所使用的框架是PyTorch。 我们利用Market-1501数据集去训练模型,然后利用这个数据集和我们自创的UESTC Re-ID数据集去测试模型。 本项目的深度学习模型为ResNet-50,损失函数为TriHard损失。 对于Market-1501数据集的mAP指标达到58.8%,rank@1指标达到76.3%。 信道分配系统 2021年4月 至 2021年5月,MATLAB\nGitHub: https://github.com/Kyxie/Channels.git\n这是一个关于信道分配问题的项目,项目背景为在医院中,将最高信噪比的信道分配给最需要的人(例如病人),而将普通人分配给病人的干扰信道(信噪比低)。 我们提出了4种算法去实现这个问题。 Webots机器人 2020年2月 至 2020年6月,C++\nGitHub: https://github.com/Kyxie/TDPS-2020-UESTC-Glasgow.git\nBilibili: https://www.bilibili.com/video/BV1Rp4y1S7o3?from=search\u0026amp;seid=72774621551842110\n\u003c!DOCTYPE HTML\u003e\r这是一个基于Webots的项目。 我们在Webots软件中设计了一个智能小车和完成任务需要的场地,我们为小车安装了惯性导航模块,LIDAR模块和摄像头模块使得小车可以完成巡线,姿态解算,颜色识别等任务。 基于FPGA的波形发生器 2019年9月 至 2019年12月, Verilog\nGitHub: https://github.com/Kyxie/wave-generator.git\n利用FPGA (Xilinx xc7a35tftg256)来生成正弦波,三角波和方波。 波的频率可调,从0 - 255Hz,并由8位USART控制。 利用4个拨码开关来控制振幅,从0 - 1V,分辨率为0.1V。 利用2个拨码开关来选择波形。 输出结果可通过VGA显示,可显示相应波形的图像信息和频率、幅值。 一个RISC架构的CPU 2018年2月 至 2018年6月, Verilog\nGitHub: https://github.com/Kyxie/CPU.git\n使用Quartus II软件实现RISC CPU,使其能够进行加、减、乘、除操作。 CPU的设计包含数据路径模块设计(ALU,寄存器和PC),控制单元设计(状态转换和IR)以及这两个模块之间的通信(CPU的集成)。 ","permalink":"https://kyxie.me/zh/projects/","summary":"研究生项目 Turbo Wallet - 记账软件 2022年1月 至 2022年3月,JavaScript GitHub (前端仓库): https://github.com/Kyxie/money-management.git GitHub (后端仓库): https://github.com/Kyxie/money-back.git 这是一个帮助我们记录每天生活","title":"项目 👨💻"},{"content":"class Me: def __init__(self): self.name = \u0026#34;Kunyang Xie\u0026#34; self.born_year = 1999 self.MBTI = \u0026#34;ISTJ\u0026#34; self.hometown = \u0026#34;Weifang, Shandong, CN\u0026#34; self.location = \u0026#34;Toronto, ON, CA\u0026#34; self.school = \u0026#34;UESTC, uWaterloo\u0026#34; ","permalink":"https://kyxie.me/zh/about/","summary":"class Me: def __init__(self): self.name = \u0026#34;Kunyang Xie\u0026#34; self.born_year = 1999 self.MBTI = \u0026#34;ISTJ\u0026#34; self.hometown = \u0026#34;Weifang, Shandong, CN\u0026#34; self.location = \u0026#34;Toronto, ON, CA\u0026#34; self.school = \u0026#34;UESTC, uWaterloo\u0026#34;","title":"关于我 👋"}]
\ No newline at end of file
diff --git a/zh/index.xml b/zh/index.xml
index a62bc2ce..6f1d98d7 100644
--- a/zh/index.xml
+++ b/zh/index.xml
@@ -121,7 +121,7 @@
Sat, 25 May 2024 00:19:19 -0400
https://kyxie.me/zh/blog/tech/router/wireguard/
- 安装 Ubuntu sudo apt update sudo apt upgrade sudo apt install wireguard OpenWrt 所需插件详见:使用树莓派4B+安装OpenWrt用作旁路由 | Kunyang’s Blog 配置Wireguard 进入/etc/wiregu
+ Ubuntu 安装 sudo apt update sudo apt upgrade sudo apt install wireguard 配置 进入/etc/wireguard,并生成密钥对 sudo -i cd /etc/wireguard umask 077 wg genkey | tee privatekey | wg pubkey > publickey 编辑配置文件wg0.conf [Interface] PrivateKey
-