[{"content":" 本文主要针对的是 ssh 场景\n网上有很多关于 git 多账号管理的文章，很多写的比较零碎，或者只解决了某一方面的问题，这里整理一下，方便自己使用\n对于该问题可设想的场景可以分为以下几种：\n不同域名使用不同的 sshkey 文件 同一域名使用不同的 sshkey 文件 同一域名使用 git 账号 对于上述场景，其实核心就两个问题：\nssh 客户端如何切换不同 sshkey git 客户端如何切换不同账号 ssh 的场景中，大多数 90% 的情况都是只需要不同 sshkey 文件就行了，至于 git 的账号 username \u0026lt;username@domain\u0026gt; 其实可以忽略，并没有那么重要。\n配置 ssh 账号 关于 ssh 的基础配置，可以参考 github 官方的文档\n这个处理最简单，也是网上能搜到最多的方案，通过 ~/.ssh/config 配置文件中的 Host 来区分不同的 sshkey 文件\nHost github.dev HostName github.com # 必须要 IdentityFile ~/.ssh/github_rsa IdentitiesOnly yes Host gitlab.yourdomain.com IdentityFile ~/.ssh/gitlab_rsa IdentitiesOnly yes 这样，你同一个 git 账号，就可以对不同仓库使用不同的 sshkey 文件了。\n配置 git 账号 这种场景主要是因为\n大多数公司会私有化部署 git server，然后账号基本都是公司域账号 如果是 github，将个人账号和公司账号隔离 所以，需要 git 客户端根据不同的 workspace，使用不同的 git 账号。\n这里就要搬出 git config 中的 Includes 配置了\n[includeIf \u0026#34;gitdir:~/workspace_github/\u0026#34;] path = ~/.gitconfig-github [includeIf \u0026#34;gitdir:~/workspace_gitlab/\u0026#34;] path = ~/.gitconfig-gitlab [includeIf \u0026#34;gitdir:~/workspace_work/\u0026#34;] path = ~/.gitconfig-work [filter \u0026#34;lfs\u0026#34;] required = true clean = git-lfs clean -- %f smudge = git-lfs smudge -- %f process = git-lfs filter-process [init] defaultBranch = main [core] symlinks = true ignorecase = false [pull] rebase = true 然后 ~/.gitconfig-xxx 内容都差不多，主要定义 name email，如果有 sign comments 的需求，可以定义 signingkey\n[user] name = github_username email = github_username@github.com signingkey = \u0026lt;YOUR_GPG_KEY_ID\u0026gt; [init] defaultBranch = main [commit] gpgsign = true 按照上述配置，你就可以在不同的 workspace 中使用不同的 git 账号了。\n不过实际真正的操作中，还是需要配合 ssh 的配置来使用的，最终可以通过 ssh -T git@github.dev 来测试连通情况。\n比如需要在 github 上开两个账号，然后使用不同的 git 和 sshkey 登陆时，结合上面两个配置完后，具体使用的时候只需要在 git clone 的时候将 github.com 替换为 github.dev（你自己定义的 host ） 即可。\n扩展：自定义 git 命令 我自己是为了方便，不需要每次手动改，所以写了一个 git 的 wrapper 脚本，通过 git clone 的执行目录来判断是否需要替换域名。\n#!/bin/bash # 你的 Git 安装实际路径 REAL_GIT=\u0026#34;/usr/local/bin/git\u0026#34; # 如果是 git clone 命令 if [[ \u0026#34;$1\u0026#34; == \u0026#34;clone\u0026#34; ]]; then current_dir=$(pwd) # 如果当前目录是在 /Users/\u0026lt;your_username\u0026gt;/workspace_github 路径下 if [[ \u0026#34;$current_dir\u0026#34; == /Users/\u0026lt;your_username\u0026gt;/workspace_github* ]]; then shift # 移除 clone 命令本身，处理其余参数 # 查找 URL 参数 for arg in \u0026#34;$@\u0026#34;; do if [[ \u0026#34;$arg\u0026#34; =~ ^git@github\\.com: ]]; then new_url=\u0026#34;${arg/git@github.com:/git@github.dev:}\u0026#34; echo \u0026#34;[git wrapper] 替换 clone URL 为: $new_url\u0026#34; exec \u0026#34;$REAL_GIT\u0026#34; clone \u0026#34;$new_url\u0026#34; fi done fi fi # 否则，直接执行原始 git 命令 exec \u0026#34;$REAL_GIT\u0026#34; \u0026#34;$@\u0026#34; 至此，你就可以在约定好的 workspace 目录中自由的使用 git 命令了。大家有更好的方案或者问题，欢迎留言讨论。\n","permalink":"https://genffy.com/posts/202504/git-multi-account-manage/","summary":"\u003cblockquote\u003e\n\u003cp\u003e本文主要针对的是 ssh 场景\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e网上有很多关于 git 多账号管理的文章，很多写的比较零碎，或者只解决了某一方面的问题，这里整理一下，方便自己使用\u003c/p\u003e\n\u003cp\u003e对于该问题可设想的场景可以分为以下几种：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e不同域名使用不同的 sshkey 文件\u003c/li\u003e\n\u003cli\u003e同一域名使用不同的 sshkey 文件\u003c/li\u003e\n\u003cli\u003e同一域名使用 git 账号\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e对于上述场景，其实核心就两个问题：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003essh 客户端如何切换不同 sshkey\u003c/li\u003e\n\u003cli\u003egit 客户端如何切换不同账号\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003essh 的场景中，大多数 90% 的情况都是只需要不同 sshkey 文件就行了，至于 git 的账号 \u003ccode\u003eusername \u0026lt;username@domain\u0026gt;\u003c/code\u003e 其实可以忽略，并没有那么重要。\u003c/p\u003e\n\u003ch2 id=\"配置-ssh-账号\"\u003e配置 ssh 账号\u003c/h2\u003e\n\u003cp\u003e关于 ssh 的基础配置，可以参考 \u003ca href=\"https://docs.github.com/en/authentication/connecting-to-github-with-ssh/about-ssh\"\u003egithub 官方的文档\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e这个处理最简单，也是网上能搜到最多的方案，通过 \u003ca href=\"https://www.ssh.com/academy/ssh/config\"\u003e\u003ccode\u003e~/.ssh/config\u003c/code\u003e\u003c/a\u003e 配置文件中的 Host 来区分不同的 sshkey 文件\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eHost github.dev\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  HostName github.com \u003cspan class=\"c1\"\u003e# 必须要\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  IdentityFile ~/.ssh/github_rsa\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  IdentitiesOnly yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eHost gitlab.yourdomain.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  IdentityFile ~/.ssh/gitlab_rsa\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  IdentitiesOnly yes\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这样，你同一个 git 账号，就可以对不同仓库使用不同的 sshkey 文件了。\u003c/p\u003e","title":"git 多账号管理"},{"content":"This message is used to verify that this feed (feedId:76154346478005248) belongs to me (userId:68909378636414976). Join me in enjoying the next generation information browser https://follow.is.\n","permalink":"https://genffy.com/posts/rss-verify/","summary":"\u003cp\u003eThis message is used to verify that this feed (feedId:76154346478005248) belongs to me (userId:68909378636414976). Join me in enjoying the next generation information browser \u003ca href=\"https://follow.is\"\u003ehttps://follow.is\u003c/a\u003e.\u003c/p\u003e","title":"Rss Verify"},{"content":"最近想着将公司里 Confluence 的内容拿来跑个智能知识库系统练练手，学习的是 Jiayuan (Forrest) 大大的 http://devv.ai 是如何构建高效的 RAG 系统的 这篇文章，找了一圈最终直接用的项目是 Langchain-Chatchat，结果在一启动的时候就报错了个错，UserWarning: CUDA initialization: The NVIDIA driver on your system is too old (found version 11080).，很明显，它是告诉我显卡驱动版本太低了，需要更新。这里其实有两种方式：\n降低 pytorch 的版本 升级显卡驱动 先确定本机的驱动信息，以及项目的 pytorch 版本所对应的 cuda 版本信息。\n基本信息 nvidia-smi 最开始的时候是单卡，初始的信息记录\n$ lspci | grep -i nvidia af:00.0 3D controller: NVIDIA Corporation GP102GL [Tesla P40] (rev a1) $ nvidia-smi +-----------------------------------------------------------------------------+ | NVIDIA-SMI 520.61.05 Driver Version: 520.61.05 CUDA Version: 11.8 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 Tesla P40 Off | 00000000:AF:00.0 Off | 0 | | N/A 28C P8 9W / 250W | 9MiB / 23040MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 2113 G /usr/lib/xorg/Xorg 4MiB | | 0 N/A N/A 7618 G /usr/lib/xorg/Xorg 4MiB | +-----------------------------------------------------------------------------+ $ nvcc --version nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2022 NVIDIA Corporation Built on Wed_Sep_21_10:33:58_PDT_2022 Cuda compilation tools, release 11.8, V11.8.89 Build cuda_11.8.r11.8/compiler.31833905_0 项目依赖的 CUDA 版本 通过简单的脚本能看到项目依赖的 cuda 版本为 12.1\n~/Langchain-Chatchat$ python Python 3.11.5 (main, Sep 11 2023, 13:54:46) [GCC 11.2.0] on linux Type \u0026#34;help\u0026#34;, \u0026#34;copyright\u0026#34;, \u0026#34;credits\u0026#34; or \u0026#34;license\u0026#34; for more information. \u0026gt;\u0026gt;\u0026gt; import torch; \u0026gt;\u0026gt;\u0026gt; print(torch.__version__) 2.1.2+cu121 \u0026gt;\u0026gt;\u0026gt; print(torch.version.cuda) 12.1 \u0026gt;\u0026gt;\u0026gt; 方案评估 降低 pytorch 版本 这个比较简单，直接去 pytorch 的官网 找到对应的版本，然后安装就行了。其实通过上面的信息发现，项目所依赖的版本与本机驱动能支持的版本只差一个小版本号 2.1.2 \u0026lt;- 2.1.1，但是这意味可能要去修改代码。 升级显卡驱动 简单来说就是先卸载，再重新安装，安装的方式也多种多样：\n通过 apt 安装 从 nvidia 的官网找到对应的显卡驱动安装 直接安装 CUDA Toolkit 会带上对应驱动 不过理论上这种方案是会直接被 pass 掉的：\n涉及到硬件驱动 多人共享，多任务运行 升级的结果不可测 机房服务器，没有太多操作经验 具体执行 和同事商量好后，决定升级显卡驱动，因为这台服务器是给我们做技术验证用的，目前也就我俩在使用，没有过多的项目在上面跑，即便搞不定，装回原来的版本就行，相对风险可控，且后面跑新项目也能用上，和同事确定好了时间窗口，就开始操作了，选择的是直接安装 CUDA Toolkit。\n安装 CUDA 稍微解释下为啥不直接去 nvidia 的驱动下载页面直接下载驱动，而是先安装 CUDA，是因为一般 cuda 会带驱动，且是兼容版本的。PS: 如果是有多个 cuda 的场景，那就安装个驱动能支持的 cuda 尽可能高的版本。\n先对老驱动进行卸载，咱也不知道之前是怎么安装的，就挨个都试了下\n$ lsmod | grep nvidia.drm $ sudo systemctl isolate multi-user.target $ sudo modprobe -r nvidia-drm $ lsmod | grep nvidia.drm $ sudo apt purge nvidia-* $ sudo apt purge libnvidia-* $ sudo apt autoremove # 检查是否还有 $ dpkg -l | grep -i nvidia 然后官网上按照要求选择的版本执行安装 CUDA Toolkit 12.3 Update 2 Downloads [一个图]\n$ sudo chmod a+x cuda_12.3.2_545.23.08_linux.run $ sudo sh cuda_12.3.2_545.23.08_linux.run ┌──────────────────────────────────────────────────────────────────────────────┐ │ End User License Agreement │ │ -------------------------- │ │ │ │ NVIDIA Software License Agreement and CUDA Supplement to │ │ Software License Agreement. Last updated: October 8, 2021 │ │ │ │ The CUDA Toolkit End User License Agreement applies to the │ │ NVIDIA CUDA Toolkit, the NVIDIA CUDA Samples, the NVIDIA │ │ Display Driver, NVIDIA Nsight tools (Visual Studio Edition), │ │ and the associated documentation on CUDA APIs, programming │ │ model and development tools. If you do not agree with the │ │ terms and conditions of the license agreement, then do not │ │ download or use the software. │ │ │ │ Last updated: October 8, 2021. │ │ │ │ │ │ Preface │ │ ------- │ │ │ │──────────────────────────────────────────────────────────────────────────────│ │ Do you accept the above EULA? (accept/decline/quit): │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────────────────────────┐ │ CUDA Installer │ │ - [X] Driver │ │ [X] 545.23.08 │ │ + [X] CUDA Toolkit 12.3 │ │ [X] CUDA Demo Suite 12.3 │ │ [X] CUDA Documentation 12.3 │ │ - [ ] Kernel Objects │ │ [ ] nvidia-fs │ │ Options │ │ Install │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Up/Down: Move | Left/Right: Expand | \u0026#39;Enter\u0026#39;: Select | \u0026#39;A\u0026#39;: Advanced options │ └──────────────────────────────────────────────────────────────────────────────┘ =========== = Summary = =========== Driver: Installed Toolkit: Installed in /usr/local/cuda-12.3/ Please make sure that - PATH includes /usr/local/cuda-12.3/bin - LD_LIBRARY_PATH includes /usr/local/cuda-12.3/lib64, or, add /usr/local/cuda-12.3/lib64 to /etc/ld.so.conf and run ldconfig as root To uninstall the CUDA Toolkit, run cuda-uninstaller in /usr/local/cuda-12.3/bin To uninstall the NVIDIA Driver, run nvidia-uninstall Logfile is /var/log/cuda-installer.log Failed to initialize NVML 问题排查 基本上就是一路 next 就行，根据最后的 summary 设置好 vim /etc/profile，然后重启，到此为止，基本上就大功告成，开始验证。\n$ cat /proc/driver/nvidia/version NVRM version: NVIDIA UNIX x86_64 Kernel Module 545.23.08 Mon Nov 6 23:49:37 UTC 2023 GCC version: gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2) $ nvidia-smi Failed to initialize NVML: Driver/library version mismatch NVML library version: 545.23 结果发现了不适配的问题 😨，然后继续找资料分析原因是什么，结论都是安装的版本不对，好嘛那就把不同的安装方式都试一下，重复之前的卸载过程。\n# 根据上面的提示安装对应的版本 $ ubuntu-drivers devices $ sudo apt install nvidia-driver-545 dkms 等安装完后，重启，还是不行，但是在搜索的过程中，这篇NVIDIA-SMI报错，dkms的都试了还不行，怎么办？里有个陌生的关键词引起了注意 dkms，那就试试？\n$ dkms status dkms: command not found $ sudo apt install dkms $ dkms status Error! Could not locate dkms.conf file. File: /var/lib/dkms/nvidia/520.61.05/source/dkms.conf does not exist. 果然有新发现，这个版本号 520.61.05 不就是之前安装的版本么？盲猜大概率是跟这个有关系。一顿搜索 dkms 的资料，发现这个是用来管理内核模块的，突然有点慌怎么就扯到内核了，本来想通过 dkms 自带的命令来看能不能卸载或者删除掉 nvidia 相关的东西，结果一直报上面找不到 dkms.conf 的错误，然后就去 /var/lib/dkms/ 下面看了下，原来这个 nvidia 是软链到其他地方的目录，但是已经被删掉了，那就也把 nvidia 目录也删掉吧，然后再重新安装 CUDA Toolkit 12.3，重启，再次验证，一切顺利。\n$ lspci | grep -i nvidia 3b:00.0 3D controller: NVIDIA Corporation GP102GL [Tesla P40] (rev a1) af:00.0 3D controller: NVIDIA Corporation GP102GL [Tesla P40] (rev a1) d8:00.0 3D controller: NVIDIA Corporation GP102GL [Tesla P40] (rev a1) $ cat /proc/driver/nvidia/version NVRM version: NVIDIA UNIX x86_64 Kernel Module 545.23.08 Mon Nov 6 23:49:37 UTC 2023 GCC version: gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2) $ nvidia-smi +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 545.23.08 Driver Version: 545.23.08 CUDA Version: 12.3 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla P40 Off | 00000000:3B:00.0 Off | Off | | N/A 33C P8 9W / 250W | 107MiB / 24576MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ | 1 Tesla P40 Off | 00000000:AF:00.0 Off | 0 | | N/A 32C P8 9W / 250W | 4MiB / 23040MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ | 2 Tesla P40 Off | 00000000:D8:00.0 Off | 0 | | N/A 30C P8 10W / 250W | 4MiB / 23040MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | 0 N/A N/A 2210 G /usr/lib/xorg/Xorg 96MiB | | 0 N/A N/A 2534 G /usr/bin/gnome-shell 9MiB | | 1 N/A N/A 2210 G /usr/lib/xorg/Xorg 4MiB | | 2 N/A N/A 2210 G /usr/lib/xorg/Xorg 4MiB | +---------------------------------------------------------------------------------------+ 总结 最终如愿启动 终于水完了，过程中其实还有蛮多细节没有记录📝，回头看也是非常简单的一件事情。如果一开始重装的时候，稍微花点时间去看看之前的驱动是如何安装的，就不会绕一大圈，简单总结下来正确的重装方式：\n记录当前版本信息 按照之前安装的方式去正确卸载 通过 CUDA Toolkit 安装驱动 重启 验证 PS：通过 CUDA Toolkit 安装的时候别选 Kernel Objects，除非你知道它是干嘛的，安装过程中选了它，结果安装失败，提示缺少 mofed，发现居然一个网卡驱动，放弃了，太复杂，主要是第一项检查都没通过\n$ lspci -nn | grep Eth | grep Mellanox # 啥都没有 参考:\nhttps://docs.nvidia.com/networking/display/mlnxofedv461000/installing+mellanox+ofed https://docs.daocloud.io/network/modules/spiderpool/install/ofed_driver/ 后面继续更新运行项目的过程，以及遇到的问题：\n向量数据库换成 es Confluence 数据的获取和 Embedding ","permalink":"https://genffy.com/posts/nvidia-cuda-driver-install/","summary":"\u003cp\u003e最近想着将公司里 \u003ccode\u003eConfluence\u003c/code\u003e 的内容拿来跑个智能知识库系统练练手，学习的是 \u003ca href=\"https://twitter.com/Tisoga\"\u003eJiayuan (Forrest)\u003c/a\u003e 大大的 \u003ca href=\"https://twitter.com/Tisoga/status/1731478506465636749\"\u003ehttp://devv.ai 是如何构建高效的 RAG 系统的\u003c/a\u003e 这篇文章，找了一圈最终直接用的项目是 \u003ca href=\"https://github.com/chatchat-space/Langchain-Chatchat\"\u003eLangchain-Chatchat\u003c/a\u003e，结果在一启动的时候就报错了个错，\u003ccode\u003eUserWarning: CUDA initialization: The NVIDIA driver on your system is too old (found version 11080).\u003c/code\u003e，很明显，它是告诉我显卡驱动版本太低了，需要更新。这里其实有两种方式：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e降低 \u003ccode\u003epytorch\u003c/code\u003e 的版本\u003c/li\u003e\n\u003cli\u003e升级显卡驱动\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e先确定本机的驱动信息，以及项目的 pytorch 版本所对应的 cuda 版本信息。\u003c/p\u003e\n\u003ch2 id=\"基本信息\"\u003e基本信息\u003c/h2\u003e\n\u003ch3 id=\"nvidia-smi\"\u003envidia-smi\u003c/h3\u003e\n\u003cblockquote\u003e\n\u003cp\u003e最开始的时候是单卡，初始的信息记录\u003c/p\u003e\u003c/blockquote\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ lspci \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep -i nvidia\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eaf:00.0 3D controller: NVIDIA Corporation GP102GL \u003cspan class=\"o\"\u003e[\u003c/span\u003eTesla P40\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003erev a1\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ nvidia-smi\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-----------------------------------------------------------------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e NVIDIA-SMI 520.61.05    Driver Version: 520.61.05    CUDA Version: 11.8     \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e-------------------------------+----------------------+----------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e GPU  Name        Persistence-M\u003cspan class=\"p\"\u003e|\u003c/span\u003e Bus-Id        Disp.A \u003cspan class=\"p\"\u003e|\u003c/span\u003e Volatile Uncorr. ECC \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e Fan  Temp  Perf  Pwr:Usage/Cap\u003cspan class=\"p\"\u003e|\u003c/span\u003e         Memory-Usage \u003cspan class=\"p\"\u003e|\u003c/span\u003e GPU-Util  Compute M. \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e                               \u003cspan class=\"p\"\u003e|\u003c/span\u003e                      \u003cspan class=\"p\"\u003e|\u003c/span\u003e               MIG M. \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"o\"\u003e===============================\u003c/span\u003e+\u003cspan class=\"o\"\u003e======================\u003c/span\u003e+\u003cspan class=\"o\"\u003e======================\u003c/span\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e   \u003cspan class=\"m\"\u003e0\u003c/span\u003e  Tesla P40           Off  \u003cspan class=\"p\"\u003e|\u003c/span\u003e 00000000:AF:00.0 Off \u003cspan class=\"p\"\u003e|\u003c/span\u003e                    \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e N/A   28C    P8     9W / 250W \u003cspan class=\"p\"\u003e|\u003c/span\u003e      9MiB / 23040MiB \u003cspan class=\"p\"\u003e|\u003c/span\u003e      0%      Default \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e                               \u003cspan class=\"p\"\u003e|\u003c/span\u003e                      \u003cspan class=\"p\"\u003e|\u003c/span\u003e                  N/A \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------------------------+----------------------+----------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                               \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-----------------------------------------------------------------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e Processes:                                                                  \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e  GPU   GI   CI        PID   Type   Process name                  GPU Memory \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e        ID   ID                                                   Usage      \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"o\"\u003e=============================================================================\u003c/span\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e    \u003cspan class=\"m\"\u003e0\u003c/span\u003e   N/A  N/A      \u003cspan class=\"m\"\u003e2113\u003c/span\u003e      G   /usr/lib/xorg/Xorg                  4MiB \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e    \u003cspan class=\"m\"\u003e0\u003c/span\u003e   N/A  N/A      \u003cspan class=\"m\"\u003e7618\u003c/span\u003e      G   /usr/lib/xorg/Xorg                  4MiB \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-----------------------------------------------------------------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ nvcc --version\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003envcc: NVIDIA \u003cspan class=\"o\"\u003e(\u003c/span\u003eR\u003cspan class=\"o\"\u003e)\u003c/span\u003e Cuda compiler driver\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCopyright \u003cspan class=\"o\"\u003e(\u003c/span\u003ec\u003cspan class=\"o\"\u003e)\u003c/span\u003e 2005-2022 NVIDIA Corporation\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eBuilt on Wed_Sep_21_10:33:58_PDT_2022\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCuda compilation tools, release 11.8, V11.8.89\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eBuild cuda_11.8.r11.8/compiler.31833905_0\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"项目依赖的-cuda-版本\"\u003e项目依赖的 CUDA 版本\u003c/h3\u003e\n\u003cp\u003e通过简单的脚本能看到项目依赖的 \u003ccode\u003ecuda\u003c/code\u003e 版本为 \u003ccode\u003e12.1\u003c/code\u003e\u003c/p\u003e","title":"RAG系列：环境初体验"},{"content":"《麦肯锡结构化战略思维：如何想清楚、说明白、做到位》 周国元 59个笔记\n◆ 点评 2023/10/29 认为好看 都是可以直接抄走的一些实操，适合各个行业\n◆ “焦虑”在VUCA时代蔓延\nvolatility（易变性），uncertainty（不确定性），complexity（复杂性），ambiguity（模糊性）\n2023/10/28发表想法 处于这个阶段估计有五年之久了，反反复复，时间却不止的流逝\n可有的人只停留在抱怨、对变化浅尝辄止的阶段\n要养成理性思考、理性办事的习惯，人们首先要走出心理上的舒适区和大脑快速思考的本能。\n◆ 2.3 “切”名词是结构化战略思维的起点\nMECE是英文“Mutually Exclusive，Collectively Exhaustive”的简写。MECE原则要求结构化切分后要达到如下要求。 （1）子分类相互独立无重叠； （2）子分类加起来穷尽全部可能。\n2023/10/28发表想法 精准划分的标准\n要把“好”和“坏”用明确数据标准做区分，给每个判断以充足、具体又可衡量的指引，这并不是一蹴而就的容易事\n◆ 2.4 “切”问题，更上一层楼\n切”问题主要有4种方法：公式法、子目录列举法、流程法和逻辑框架法。\n◆ 第3章 结构化战略思维四大原则\n结构化战略思维四大原则分别是数字说话、洞见优于表象、MECE原则和假设为前提，其中数字说话和洞见优于表象是偏重数字分析和高效交流的科学方法和行为准则，而MECE原则和假设为前提更多是指导思路的方法论。\n◆ 3.1 原则1：数字说话\n“以偏概全”就是一种常见的误导手段\n偷换概念也是一种很常用的误导手段。\n面对任何数字，我们首先要假设数字是不准确的。“先小人后君子”，主动验证是思辨者的责任。只有经得起调研和拷问的数字才可信\n面对用于决策的关键数字时，要有能力在有限的时间内依靠常识快速简易地证真或证伪，我把这种能力称为“常识推理能力”。这一数字核实的过程用英语描述为Back-of-the-envelop-calculation，直译“信封背面的计算”\n◆ 3.2 原则2：洞见优于表象\n海量的数据中萃取洞见的能力是数字决策的核心，初学者可以通过五个简单步骤来练习寻找洞见：（1）寻找数字中的规律和趋势（Pattern）；（2）寻找极端的数字及其含义；（3）对比参照数据并分析差异；（4）寻求其他相关信息；（5）推演并提炼洞见。\n试图寻找数字中的规律和趋势\n极端的数据点包括最大值、最小值和数字0\n对比参照数据并分析差异\n2023/10/29发表想法 这个常规是不是也有些武断\n参照业界常规，即使有大量和精准的市场投入，一个新品牌饮品也至少需要4个季度才能盈利\n参照业界常规，即使有大量和精准的市场投入，一个新品牌饮品也至少需要4个季度才能盈利\n◆ 3.3 原则3：MECE原则\n透过MECE原则看经典管理学理论\n2023/10/29发表想法 mece角度的模型分析\n从宏观PEST模型开始，到行业赛道吸引力的波特五力模型，然后是公司能力SWOT分析，再到内部公司管理的麦肯锡7S模型，最后看看多维度理论如BCG矩阵和消费者细分市场感知分析\nPEST模型由哈佛经济学教授弗朗西斯·阿吉拉尔（Francis J.Aguilar）最早在1967年提出[15]，是用来评判企业外部宏观经济大环境的理论框架\n波特五力模型有个“讨价还价/议价能力”的概\nSWOT（Strengths优势、Weaknesses劣势、Opportunities机会和Threats威胁）分析方法是最常见的分析\n2023/10/29发表想法\n麦肯锡7S模型\nStrategy战略：公司要建立相对竞争对手的可持续的竞争优势的计划。 Structure结构：公司的组织架构，如汇报的链条。 Systems系统：员工完成任务所用的系统和流程。 Shared values共同价值观：公司的核心使命和文化。 Style风格：公司决策和管理风格。 Staff员工：组织成员。 Skills能力：组织综合能力。 BCG矩阵（又称“市场增长率–相对市场份额矩阵”）是由波士顿咨询公司（The Boston Consulting Group，BCG）创始人布鲁斯·亨德森（Bruce Henderson）于1970年首创的，是一种关于企业产品战略的评判框架\n消费者感知图。消费者感知图的主要功能是细分消费者或购买者，并根据每个细分客户群体制定公司的产品战略\n拓展分析的多维关键图谱。在战略咨询中，“增长战略”是比较常见的议题。对于行业的头部企业[16]，由于本企业体量大，企业增长基本趋同于整个行业的增长趋势\n善于解决问题的思辨者永远不会把“不”当成最终答案\n◆ 3.4 原则4：假设为前提\n大胆假设，仔细求证”也是现代科学的原则\n公司层面体系化支持包含3个方面：组织、流程和文化。\n◆ 新麦肯锡五步法\n“七步成诗”的步骤分别是问题描述、问题分解、问题规划、信息整理、分析和论证、建议的提出和方案的表达。\n新麦肯锡五步法从项目管理的角度，串起战略项目解决从开始到交付的5个关键步骤：定义问题、结构化分析、提出假设、验证假设和交付\n◆ 5.1 对问题本身的推敲是思辨者的行为特色\n战略思维从全局高度把握问题的准确性，重点在于“为什么——解决什么问题”，并不聚焦“怎么做——实施的细节”。专家思维则往往把“为什么——解决什么的问题”当成已知，而侧重“怎么做——实施的细节”以及成果输出\n◆ 5.2 定义正确问题的衡量标准\n《哈佛商业评论》的《向上管理：如何与老板相处》（Managing Up——Best Practices for Interacting with Your Boss）一文提出4点建议加速共识达成：让决策人深入参与讨论过程、把决策拆分成具体步骤并落实初期的任务、建立信任、反复沟通。\n◆ 6.2 分析问题要小心逻辑陷阱\n归纳法是从“个别”上升到“一般”的方法，即从个别事实中提炼、概括出一般的原理。演绎法是从“一般”到“个别”的方法，即从一般原理推理出个别具体的结论。\n◆ 8.1 验证假设的功能和方法\n验证假设需要收集的信息量很大。为信息收集而做的验证假设调研工作分为两种：案头调研和实地调研。\n◆ 8.2 实地调研的技巧\n8.2.1 访谈的小技巧\n要对被访者有足够的尊重; 对话中要输入新的增值信息; 要有锲而不舍并以结果为导向的访谈态度； 访谈永远不是一次性的“交易”，访谈者与被访者要培养并建立长期信任关系； 访谈者要真心保护被访者，对被访者和正在解决的问题之间的微妙关系具有足够敏感度； ◆ 9.2 交付时：高效的商务沟通\n介绍高效商务沟通的部分原则和实用方法。\n常见的商务沟通形式有以下四种：口头陈述、文档备忘录、PPT和白板演示\n麦肯锡商务沟通的3S原则，它包括严谨缜密的战略（Thoughtful Strategy）、紧凑的结构（Tight Structure）和专业的风格（Professional Style）。\n金字塔原则就是，任何事情都可以归纳出一个中心论点，而此中心论点可由三至七个论据支持，这些一级论据本身也可以是个论点，被二级的三至七个论据支持，如此延伸，状如金字塔。\n故事线是5W2H分析法（又叫七问分析法）的简化版。5W2H包括：为什么（Why）、用什么（What）、何人做（Who）、何时（When）、何地（Where）、如何做（How）、多少钱（How much）\n个讲行业故事的SCP叙述框架。SCP是“规则/结构”（Structure）“行为”（Conduct）和“业绩”（Performance）的组合，被用来描述行业现状的叙述框架\nSCP+I的故事叙述顺序\n把SCP按结构顺序讲明白，先讲行业特色和商业模式； 讲主要的企业玩家是如何各显神通地在这个行业打拼； 谈一下各企业的成绩和企业表现如何 新的冲击隆重登场，由于这个冲击的存在，相关的供需平衡被打破：已有的产品无法满足冲击下的需求 介绍一个和“故事线”相辅相成的实用呈现工具：点线大纲\n点线大纲在咨询公司中的广泛使用也彰显了咨询公司在项目上结果导向的风格\n简化的3大核心要素：换位思考、提炼和清晰阐述\n2023/10/29发表想法 抄作业ing\n这里展示一张隐去客户具体内容的普通PPT文档[11]，我们来一起探究麦肯锡呈现的合格标准\n◆ 第10章 培养结构化战略思维需要养成的十个习惯\n反对的责任 解决真正的问题 下一层面的细节 总结提炼 第一天的答案 问正确的问题 认为还是知道 移动时间轴 数字和逻辑 知道边界 ","permalink":"https://genffy.com/posts/mckinsey-structured-thinking/","summary":"\u003cp\u003e《麦肯锡结构化战略思维：如何想清楚、说明白、做到位》\n周国元\n59个笔记\u003c/p\u003e\n\u003cp\u003e◆ 点评\n2023/10/29 认为好看\n都是可以直接抄走的一些实操，适合各个行业\u003c/p\u003e\n\u003cp\u003e◆ “焦虑”在VUCA时代蔓延\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003evolatility（易变性），uncertainty（不确定性），complexity（复杂性），ambiguity（模糊性）\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e2023/10/28发表想法\n处于这个阶段估计有五年之久了，反反复复，时间却不止的流逝\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e可有的人只停留在抱怨、对变化浅尝辄止的阶段\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e要养成理性思考、理性办事的习惯，人们首先要走出心理上的舒适区和大脑快速思考的本能。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 2.3 “切”名词是结构化战略思维的起点\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003eMECE是英文“Mutually Exclusive，Collectively Exhaustive”的简写。MECE原则要求结构化切分后要达到如下要求。\n（1）子分类相互独立无重叠；\n（2）子分类加起来穷尽全部可能。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cimg alt=\"MECE\" loading=\"lazy\" src=\"/images/2023-10-30/epub_34916572_67.jpeg\"\u003e\u003c/p\u003e\n\u003cp\u003e2023/10/28发表想法\n精准划分的标准\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e要把“好”和“坏”用明确数据标准做区分，给每个判断以充足、具体又可衡量的指引，这并不是一蹴而就的容易事\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 2.4 “切”问题，更上一层楼\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e切”问题主要有4种方法：公式法、子目录列举法、流程法和逻辑框架法。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cimg alt=\"四种切问题的方法\" loading=\"lazy\" src=\"/images/2023-10-30/epub_34916572_6.jpeg\"\u003e\u003c/p\u003e\n\u003cp\u003e◆ 第3章 结构化战略思维四大原则\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e结构化战略思维四大原则分别是数字说话、洞见优于表象、MECE原则和假设为前提，其中数字说话和洞见优于表象是偏重数字分析和高效交流的科学方法和行为准则，而MECE原则和假设为前提更多是指导思路的方法论。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cimg alt=\"结构化战略思维四大原则\" loading=\"lazy\" src=\"/images/2023-10-30/epub_34916572_15.jpeg\"\u003e\u003c/p\u003e\n\u003cp\u003e◆ 3.1 原则1：数字说话\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e“以偏概全”就是一种常见的误导手段\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e偷换概念也是一种很常用的误导手段。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e面对任何数字，我们首先要假设数字是不准确的。“先小人后君子”，主动验证是思辨者的责任。只有经得起调研和拷问的数字才可信\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e面对用于决策的关键数字时，要有能力在有限的时间内依靠常识快速简易地证真或证伪，我把这种能力称为“常识推理能力”。这一数字核实的过程用英语描述为Back-of-the-envelop-calculation，直译“信封背面的计算”\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 3.2 原则2：洞见优于表象\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e海量的数据中萃取洞见的能力是数字决策的核心，初学者可以通过五个简单步骤来练习寻找洞见：（1）寻找数字中的规律和趋势（Pattern）；（2）寻找极端的数字及其含义；（3）对比参照数据并分析差异；（4）寻求其他相关信息；（5）推演并提炼洞见。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e试图寻找数字中的规律和趋势\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e极端的数据点包括最大值、最小值和数字0\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e对比参照数据并分析差异\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e2023/10/29发表想法\n这个常规是不是也有些武断\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参照业界常规，即使有大量和精准的市场投入，一个新品牌饮品也至少需要4个季度才能盈利\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e参照业界常规，即使有大量和精准的市场投入，一个新品牌饮品也至少需要4个季度才能盈利\u003c/p\u003e","title":"麦肯锡结构化战略思维：如何想清楚、说明白、做到位"},{"content":"《格鲁夫给经理人的第一课（畅销版）》 安迪·格鲁夫 81个笔记\n◆ 点评 2023/10/21 认为好看 重读，在带十人团队之后。很多场景基本是可以完全抄着用，不过也有些前提。比如书中的主人公是大老板，有完全的空间，但大多数还有+1，+2 等，很多动作可能需要优化下。不过也可以用里面对下属的技巧，去反向管理自己的老板，让自己有更好的绩效。\n◆ 序 重温《格鲁夫给经理人的第一课》\n经理人不需要多聪明，多熟悉业务，最重要的是如何把知识转化为团队绩效和产出。\n如果一个人工作上毫无作为，只有两个原因：他要么不会做，要么不想做；不是没能力，就是没动力。”\n过程初期所付出的能量将会收到十倍的回报，而过程末期所付出的能量则会收到十倍的负回报\n2023/10/11发表想法 堂主一定是反复阅读了这本书的\n如果员工对任务的成熟度不高，经理人手把手培训就非常重要。如果员工足够成熟，那么适当放权则更为恰当。\n如果员工对任务的成熟度不高，经理人手把手培训就非常重要。如果员工足够成熟，那么适当放权则更为恰当。\n经理人只能从两个方面影响员工的产出：激励和培训\n◆ 序言 从20世纪80年代的巨变谈起\n在日益艰难的环境里，就算你“成为市场里的老二”也还不够\n◆ 顺应新环境\n这些改变将会催生一个竞争激烈且难以预期的工作环境。\n让混沌丛生，然后掌控混沌\n◆ 认识你的组织\n产出导向管理\n团队意识\n2023/10/11发表想法 本质上就是通过手段，让手下出更多的成绩，以前以为只有类似销售分销是这样的，其他类型的组织也大抵如此\n一个经理人的产出，便是他所管理和影响所及的下属工作的成效总和。”\n管理杠杆率”（\n2023/10/11发表想法 炒股也是这样吧 哈哈哈哈\n我们必须认清“无法预测未来”这个事实，但这并不等于“我们应该就此放弃计划”。\n◆ 经营你的职业生涯\n又让我得知自己是现实主义者——只有能在变化中生存的人才会对未来抱持乐观的态度。我写此书的动机就是提出能增加\n◆ 第一篇 早餐店的生产线\n限制步骤的概念\n时间互偿\n但凡是能以最低成本达到理想的运送速度以及品质的，便是最佳方案\n你都应该使用线上检视的方法，而避免必须要牺牲产品的测试方法。\n◆ 第2章 从早餐店的库存谈起\n任何管理都需要评估，但我们也发现，一个有效的指标应是评估产出，而不是产出之前的生产活动。\n设定标准，预测每个员工的工作量，这绝对有助于提高并维持产能。\n◆ 第二篇 打好团体战\n经理人的产出是什么？\n不仅对我，而且是对大多数的经理人而言，最重要的信息往往来自简短而非正式的谈话。这种信息的传递速度往往也比任何一种书面报告或是小纸条快。而信息的价值，通常也和其时效有绝对的关联\n报告用来表示一个人的自律，远胜于它在传递信息上的作用。\n增强并且维持你吸收信息的能力，你必须先了解能获取信息的途径有哪些\n所以你必须更进一步地去看这篇报道的内容，才能知道“五何”——何人、何事、何时、何处以及为何。经过这些理解，你才能够有一套自己的看法。 你绝对不能只靠某一种特定的信\n决策基本上可分为两种\n2023/10/13发表想法 有正负之分；减少技术性干预能降低负杠杆率\n什么是高杠杆率？\n2023/10/13发表想法 前面两个是什么\n第三种高杠杆率的活动是一个有特殊技能或知识的人，对其他人产生影响\n第三种高杠杆率的活动是一个有特殊技能或知识的人，对其他人产生影响\n2023/10/13发表想法 mark\n“授权人”和“被授权人”间的关系有一个必要条件：这两者必须有相同的信息基础，同时在开展工作和解决问题上有一套彼此认同的方法。\n我们都有这样的问题，即并不想真正把工作交给别人，因为我们喜欢自己做，不愿假手他人。\n没有完备监督计划的授权等于渎职。\n2023/10/13发表想法 mark：时间管理技巧\n找出限制步骤\n如果经理人能设法将常见的问题归类，并准备好答案，便能减少处理问题的时间。当然，既然能准备好答案，就表示经理人可以将其授权给其他下属来处理。\n建立起处理问题的模式。在制造生产上，“化不规律为规律”是非常基本的准则。在处理那些让你效率降低的干扰时也可以使用这个准则。\n◆ 第4章 管理的必经之路：开会\n两种不同性质的会议\n下属只要感觉事情有可能出错\n上司集学生和教练的角色于一身。德鲁克曾对经理人在这方面的职责下过很好的定义：“善用时间的经理人不必告诉下属他们的问题——但他知道怎么让下属将他们的问题告诉他。” 这要如何做到呢？你可以\n应想办法在这段时间里提升你及整个公司的效率，专心听别人讲并记下一些也许值得一试的事情。\n任务导向会议则不然，这种类型的会议随时召开，而且必须产生决策\n所以，在召开会议之前，先问问你自己：有什么任务要通过这场会议达成？是不是有开会的必要？如果你还有一点迟疑，或还有其他办法可以协助你达成任务，就先别动开会的念头。\n◆ 第5章 不挥舞权杖的决策\n2023/10/16发表想法 都一样\n在一场我必须采访的会议中，有人告诉我：在这家公司里，能干到高位的人都知道什么时候才能开口——他们通常等到上面的人表达了意见或立场之后，才开始陈述意见支持上司的论点。\n我发现这只对两种人“似乎还算容易”。一种是公司的高级主管，因为他们在公司里待得够久，知道事情该怎么做，而且和公司有同样的价值观；另一种是刚进公司的大学毕业生，他们在学校里和同学合作完成作业时就用这个模式。\n2023/10/16发表想法 一些普遍存在且很正常的现象\n我们必须克服这些障碍。我们都具备聪明才智以及意志力，应该能克服“怕人觉得自己很傻”以及意见不被采纳的恐惧，从而能够参与讨论并有自己的主张\n一定要确定你已在讨论中收集到足够的相关信息，而非只是泛泛地谈。\n在制定决策之前，经理人应对以下6个问题的答案了然\n2023/10/16发表想法 有理有据倒还好，“我觉得”就很没说服力\n如果决策参与人好不容易达成了共识，却被“决策敲定者”否决，这种情况一定令人沮丧，甚至会影响员工士气及工作\n如果决策参与人好不容易达成了共识，却被“决策敲定者”否决，这种情况一定令人沮丧，甚至会影响员工士气及工作\n◆ 第6章 规划是为了明天\n你规划行动方案之前，一定记得先问自己：有什么事情如果我“今天”做了，可以让“明天”更好，或者至少让“明天”不会更糟。\n2023/10/16发表想法 规划的大致步骤 预测需求 了解处境 找到平衡\n规划流程大致\n2023/10/16发表想法 所以大家对于做规划的事情也不要去抵触，觉得这种长期规划没意义，其实只要落实一年的就很好了\n我们希望能在这段时间内获得回馈，以此作为下次规划的依据\n2023/10/16发表想法 分享给自己！焦虑，反复是没有用的！\n如果你不知道何去何从，你将永远到到不了目的地。\n如果你不知道何去何从，你将永远到到不了目的地。\n2023/10/16发表想法 自上而下\n一个经理人的目标会构建在一连串的“成果验收”之上。他的目标和他上司的目标紧密结合：他必须达成自己的目标，他上司的目标才能够达成。\n一个经理人的目标会构建在一连串的“成果验收”之上。他的目标和他上司的目标紧密结合：他必须达成自己的目标，他上司的目标才能够达成。\n◆ 第8章 混合型组织\n明显的是在各事业部沟通如何分配总公司有限资源的时候——不管是分配产能、计算机使用时间还是办公室的面积，表面上大家是在沟通，但事实上经常是激烈的明争暗斗。\n◆ 第9章 双重报告\n2023/10/18发表想法 解决问题，其实就意味着有绩效，涉及到利益分配的问题？何解\n“同级群体”就可以解决问题\n“同级群体”就可以解决问题\n要让每个个体都愿意牺牲决策上的权限，关键在于这个同级群体要足以让人信服。这种信赖感能不能产生，近年来已不断地被广泛讨论。一个公司无法借助组织条文让员工产生“信任感”，而只能靠它的企业文化来建立信任。简而言之，这是一种对企业的认同，大家具有相同的价值观，且对事情的执行方式及优先级等有相当的共识。双重报告以及同级群体要发挥出最大效能，健全的企业文化绝对是关键。 在这种架构中，\n2023/10/18发表想法 that is it\n一个公司无法借助组织条文让员工产生“信任感”，而只能靠它的企业文化来建立信任。简而言之，这是一种对企业的认同，大家具有相同的价值观，且对事情的执行方式及优先级等有相当的共识。双重报告以及同级群体要发挥出最大效能，健全的企业文化绝对是关键。\n◆ 第10章 每个人都听命于三个“长官”\n我们在工作上的行为，主要也受着如下三项无形但极具效力的因素控制： （1）自由市场因素。 （2）契约义务。 （3）文化价值观。\n我们以CUA指标（即：complexity, uncertainty, ambiguity）来衡量一个工作环境的复杂性、不确定性以及指令的模糊性。\n[插图]\n2023/10/18发表想法 直接拿来用就行了\n经理人要选择最好的控制模式\n◆ 第四篇 谋事在人\n就要教你怎么激励你的队员超越极限\n如果一个人没做好他该做的事，只有两种原因：他不是“不为”就是“不能”——前者是缺乏诱因，后者是无能为力。\n培训与激励\n有两种内在动力可以促使个体将能力发挥到极致：精益求精型和成就导向型。\n2023/10/18发表想法 将职场通定义规则，变成一个竞技场\n没有什么系统性的方法可以引导个体提升至自我实现的层次？\n◆ 第12章 工作成熟度\n一个经理人最主要的职责，便是激发下属的最佳表现。\n这个变量被称为“工作成熟度”（task-relevant maturity, TRM），这个指标涵盖了下属是否为成就导向、是否能承担责任、他们的教育背景、受过什么训练以及以往的工作经验等。\n◆ 第13章 再难也得做：绩效评估\n为了提高下属的绩效\n要想让评估过程稍微简单一点，主管应该事先搞清楚他对下属的期望，然后再以此来判断下属的绩效是否合乎期望。评估最大的问题在于经理人并没有列明对下属的期望，就像我们早先提过的：“如果我们不知道到底要什么，最可能的结果是什么也得不到。”\n至于何者比较重要，我们可以运用财务管理上的“现值”观念：这项长期的活动到底最后能帮我们赚多少钱？\n倾听”则有其特殊的意义。沟通其实就是将甲脑子里的东西传输到乙的脑子里。因此，甲的思维必须先转化为语言，然后在讲话时通过声波送到乙的耳朵里。通过耳朵里神经的电波，信息得以在乙的脑子里储存起来。\n一次只能接受有限的事实、问题和建议。\n2023/10/21发表想法 前提是有持续性才行；如果自己是能够持续的，则倒是可以以此为引导下属的可持续性\n就算你在这次评估中遗漏了一些项目，在下一次还是能弥补。\n只要下属愿意采取行动改进就可以接受\n为了完成任务，你最需要的是下属愿意执行你决定的行动方案，至于他是否与你抱持同样的想法则在其次。期望别人凡事都和你想的一样其实并不是件好事，在工作上我们主要追求的是绩效，而不是心里舒不舒服。\n","permalink":"https://genffy.com/posts/high-output-management/","summary":"\u003cp\u003e《格鲁夫给经理人的第一课（畅销版）》\n安迪·格鲁夫\n81个笔记\u003c/p\u003e\n\u003cp\u003e◆ 点评\n2023/10/21 认为好看\n重读，在带十人团队之后。很多场景基本是可以完全抄着用，不过也有些前提。比如书中的主人公是大老板，有完全的空间，但大多数还有+1，+2 等，很多动作可能需要优化下。不过也可以用里面对下属的技巧，去反向管理自己的老板，让自己有更好的绩效。\u003c/p\u003e\n\u003cp\u003e◆ 序 重温《格鲁夫给经理人的第一课》\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e经理人不需要多聪明，多熟悉业务，最重要的是如何把知识转化为团队绩效和产出。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e如果一个人工作上毫无作为，只有两个原因：他要么不会做，要么不想做；不是没能力，就是没动力。”\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e过程初期所付出的能量将会收到十倍的回报，而过程末期所付出的能量则会收到十倍的负回报\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e2023/10/11发表想法\n堂主一定是反复阅读了这本书的\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e如果员工对任务的成熟度不高，经理人手把手培训就非常重要。如果员工足够成熟，那么适当放权则更为恰当。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e如果员工对任务的成熟度不高，经理人手把手培训就非常重要。如果员工足够成熟，那么适当放权则更为恰当。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e经理人只能从两个方面影响员工的产出：激励和培训\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 序言 从20世纪80年代的巨变谈起\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e在日益艰难的环境里，就算你“成为市场里的老二”也还不够\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 顺应新环境\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e这些改变将会催生一个竞争激烈且难以预期的工作环境。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e让混沌丛生，然后掌控混沌\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 认识你的组织\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e产出导向管理\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e团队意识\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e2023/10/11发表想法\n本质上就是通过手段，让手下出更多的成绩，以前以为只有类似销售分销是这样的，其他类型的组织也大抵如此\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e一个经理人的产出，便是他所管理和影响所及的下属工作的成效总和。”\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e管理杠杆率”（\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e2023/10/11发表想法\n炒股也是这样吧 哈哈哈哈\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e我们必须认清“无法预测未来”这个事实，但这并不等于“我们应该就此放弃计划”。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 经营你的职业生涯\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e又让我得知自己是现实主义者——只有能在变化中生存的人才会对未来抱持乐观的态度。我写此书的动机就是提出能增加\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 第一篇 早餐店的生产线\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e限制步骤的概念\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e时间互偿\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e但凡是能以最低成本达到理想的运送速度以及品质的，便是最佳方案\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003e你都应该使用线上检视的方法，而避免必须要牺牲产品的测试方法。\u003c/p\u003e\u003c/blockquote\u003e\u003c/blockquote\u003e\n\u003cp\u003e◆ 第2章 从早餐店的库存谈起\u003c/p\u003e","title":"格鲁夫给经理人的第一课"},{"content":"前置知识 会简单用一下 docker 以及 docker-compose 知道 github actions 以及会用 以及一点点 linux 操作的基础，可以 这里 了解下 背景 作为一个前端er，大多数场景下交付的都是纯静态的东西（html, js, css），可能对于服务部署自动化这块不是特别敏感，随便找个环境 build 下，拿到 dist 文件夹丢到服务器上就完事了。再高级一点的，可能有用到各种 SSX 的，或者还有点 serverless 的，还有个 vercel 这个特别好用的平台供我们使用，简直太强大，纯前端的常规操作，或者配合一些调用第三方数据接口的操作，vercel 一把梭，最多加个 serverless 函数转发下避免跨域之类的问题。比如 ChatGPT 的各种套壳，部署在 vercel 上占大多数。\n但是，如果你是一个后端er，或者是一个全栈，那么你可能会有一些服务端的东西需要部署，比如一些数据库，中间件等，这些似乎在 vercel 上就不能直接搞定了，虽然他们目前也有在计划 Storage 这个东西，尤其对于版本帝的 nodejs 应用来说，可能不用项目需要的基础环境不一样，按照常规的做法可能需要不同的服务器去做这种环境隔离的事情了。其实对于预算充足的来说，这都不是问题，那么现在要介绍的一种就是如何在极限环境下，去做这种多应用部署，方便自己实验。\n介绍 对于文中实验场景，唯一可能需要付钱的部份是一台低配的服务器，毕竟 github 的 action 不能和本地通信？（如果你有固定 ip 其实也可以）比如本文中使用的是一台腾讯云上的【标准型SA2 - 2核 2G】的服务器，买了三年千把块，算是很便宜了，装的系统是【\tTencentOS Server 3.1 (TK4)】，默认自带了 docker，还做了一些镜像源上的配置，其实自己去安装个也很方便，记得改下镜像源。\n需要准备的所有东西包括：\n一台云服务器 一个镜像仓库 一个 github 仓库 为什么需要一个镜像仓库，目前很多基础仓库其实都在公开的镜像仓库上，比如 dockerhub，但是对于自己应用的镜像制品，不适合放到公开仓库里。网上也有很多搭建的教程比如 How To Set Up a Private Docker Registry on Ubuntu 22.04。然后各个云商也提供此类服务，文中例子依旧选择的是腾讯云的 容器镜像服务。\n综上，整体的工作流程大概是这样的 配置 github action 这里很简单，配置下 publishing-docker-images，然后填上自己的 docker 镜像仓库的账号密码，然后就可以了。 用户名密码以及仓库地址这些变量可以通过 Actions secrets and variables 设置 下面是使用的 docker.yml 配置\n# .github/workflows/docker.yml name: docker-ci on: # schedule: # - cron: \u0026#34;0 10 * * *\u0026#34; push: branches: - \u0026#34;**\u0026#34; tags: - \u0026#34;v*.*.*\u0026#34; pull_request: branches: - \u0026#34;main\u0026#34; jobs: docker: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Docker meta id: meta uses: docker/metadata-action@v4 with: # list of Docker images to use as base name for tags images: | ${{ vars.TCR_REPOSITORY_URL }}/${{ vars.TCR_REPOSITORY_NAMESPACE }}/${{ github.event.repository.name }} # generate Docker tags based on the following events/attributes tags: | type=schedule type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry if: github.event_name != \u0026#39;pull_request\u0026#39; uses: docker/login-action@v2 with: # 私有仓库的地址和用户名密码，这里使用的是 github 的 secrets registry: ${{ vars.TCR_REPOSITORY_URL }} username: ${{ secrets.TCR_REPOSITORY_USERNAME }} password: ${{ secrets.TCR_REPOSITORY_USERPWD }} - name: Build and push uses: docker/build-push-action@v3 with: context: . platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != \u0026#39;pull_request\u0026#39; }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} 安装 watchtower 关于 watchtower 的详细使用可以直接去看 watchtower 的文档，有兴趣可以研究下它是怎么实现的，这里只是简单的介绍下如何安装和使用。\n# apps/watchtower/docker-compose.yml version: \u0026#34;3.9\u0026#34; services: watchtower: image: containrrr/watchtower restart: always environment: WATCHTOWER_CLEANUP: true TZ: Asia/Shanghai # WATCHTOWER_SCHEDULE: 0 0 1 * * * WATCHTOWER_POLL_INTERVAL: 7200 WATCHTOWER_LABEL_ENABLE: true volumes: - /var/run/docker.sock:/var/run/docker.sock # 这里主要是用户私有仓库的鉴权配置，如果是公开仓库可以不用配置 - $HOME/.docker/config.json:/config.json 然后在服务器上 docker-compose up -d 就可以了，这里需要注意的是，如果是私有仓库，需要在服务器上配置好鉴权，否则 watchtower 会报错，这里的鉴权配置可以参考 docker login。\n成功运行之后可以查看日志，看看是否有报错，如果没有报错，就可以去看看仓库里的镜像了，是不是已经更新了。\n[root@VM-0-12-centos ~]# docker logs -f \u0026lt;containrrr/watchtower CONTAINER_ID\u0026gt; time=\u0026#34;2023-06-07T17:24:21+08:00\u0026#34; level=info msg=\u0026#34;Watchtower 1.5.3\u0026#34; time=\u0026#34;2023-06-07T17:24:21+08:00\u0026#34; level=info msg=\u0026#34;Using no notifications\u0026#34; time=\u0026#34;2023-06-07T17:24:21+08:00\u0026#34; level=info msg=\u0026#34;Only checking containers using enable label\u0026#34; time=\u0026#34;2023-06-07T17:24:21+08:00\u0026#34; level=info msg=\u0026#34;Scheduling first run: 2023-06-07 19:24:21 +0800 CST\u0026#34; time=\u0026#34;2023-06-07T17:24:21+08:00\u0026#34; level=info msg=\u0026#34;Note that the first check will be performed in 1 hour, 59 minutes, 59 seconds\u0026#34; time=\u0026#34;2023-06-07T19:24:34+08:00\u0026#34; level=info msg=\u0026#34;Found new ${{ vars.TCR_REPOSITORY_URL }}/${{ vars.TCR_REPOSITORY_NAMESPACE }}/${{ github.event.repository.name }} image (\u0026lt;IMAGE_ID\u0026gt;)\u0026#34; time=\u0026#34;2023-06-07T19:24:34+08:00\u0026#34; level=info msg=\u0026#34;Stopping /CONTAINER_NAME (CONTAINER_ID) with SIGTERM\u0026#34; time=\u0026#34;2023-06-07T19:24:36+08:00\u0026#34; level=info msg=\u0026#34;Creating /CONTAINER_NAME\u0026#34; time=\u0026#34;2023-06-07T19:24:36+08:00\u0026#34; level=info msg=\u0026#34;Removing image IMAGE_ID\u0026#34; time=\u0026#34;2023-06-07T19:24:43+08:00\u0026#34; level=info msg=\u0026#34;Session done\u0026#34; Failed=0 Scanned=1 Updated=1 notify=no time=\u0026#34;2023-06-07T21:24:36+08:00\u0026#34; level=info msg=\u0026#34;Found new ${{ vars.TCR_REPOSITORY_URL }}/${{ vars.TCR_REPOSITORY_NAMESPACE }}/${{ github.event.repository.name }} image (IMAGE_ID)\u0026#34; time=\u0026#34;2023-06-07T21:24:36+08:00\u0026#34; level=info msg=\u0026#34;Stopping /CONTAINER_NAME (CONTAINER_ID) with SIGTERM\u0026#34; time=\u0026#34;2023-06-07T21:24:37+08:00\u0026#34; level=info msg=\u0026#34;Creating /CONTAINER_NAME\u0026#34; time=\u0026#34;2023-06-07T21:24:37+08:00\u0026#34; level=info msg=\u0026#34;Removing image \u0026lt;IMAGE_ID\u0026gt;\u0026#34; time=\u0026#34;2023-06-07T21:24:43+08:00\u0026#34; level=info msg=\u0026#34;Session done\u0026#34; Failed=0 Scanned=1 Updated=1 notify=no time=\u0026#34;2023-06-07T23:24:22+08:00\u0026#34; level=info msg=\u0026#34;Session done\u0026#34; Failed=0 Scanned=1 Updated=0 notify=no time=\u0026#34;2023-06-08T01:24:35+08:00\u0026#34; level=info msg=\u0026#34;Found new ${{ vars.TCR_REPOSITORY_URL }}/${{ vars.TCR_REPOSITORY_NAMESPACE }}/${{ github.event.repository.name }} image (IMAGE_ID)\u0026#34; time=\u0026#34;2023-06-08T01:24:35+08:00\u0026#34; level=info msg=\u0026#34;Stopping /CONTAINER_NAME (CONTAINER_ID) with SIGTERM\u0026#34; time=\u0026#34;2023-06-08T01:24:36+08:00\u0026#34; level=info msg=\u0026#34;Creating /CONTAINER_NAME\u0026#34; time=\u0026#34;2023-06-08T01:24:36+08:00\u0026#34; level=info msg=\u0026#34;Removing image IMAGE_ID\u0026#34; time=\u0026#34;2023-06-08T01:24:42+08:00\u0026#34; level=info msg=\u0026#34;Session done\u0026#34; Failed=0 Scanned=1 Updated=1 notify=no time=\u0026#34;2023-06-08T03:24:22+08:00\u0026#34; level=info msg=\u0026#34;Session done\u0026#34; Failed=0 Scanned=1 Updated=0 notify=no time=\u0026#34;2023-06-08T05:24:22+08:00\u0026#34; level=info msg=\u0026#34;Session done\u0026#34; Failed=0 Scanned=1 Updated=0 notify=no 总结 至此，我们通过 github actions 和 watchtower ，以及基于腾讯云的 TCR （换成其他云操作一致）实现了自动化构建和更新，当然，这里只是简单的介绍了下如何使用，如果你有更好的方法，欢迎留言讨论。\n","permalink":"https://genffy.com/posts/how-to-auto-deploy-with-github-docker/","summary":"\u003ch2 id=\"前置知识\"\u003e前置知识\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cul\u003e\n\u003cli\u003e会简单用一下 \u003ca href=\"https://docs.docker.com/get-started/\"\u003edocker\u003c/a\u003e 以及 \u003ca href=\"https://docs.docker.com/compose/\"\u003edocker-compose\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e知道 \u003ca href=\"https://docs.github.com/en/actions/learn-github-actions\"\u003egithub actions\u003c/a\u003e 以及会用\u003c/li\u003e\n\u003cli\u003e以及一点点 linux 操作的基础，可以 \u003ca href=\"https://logseq.genffy.com/#/page/code-snippet\"\u003e这里\u003c/a\u003e 了解下\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003ch2 id=\"背景\"\u003e背景\u003c/h2\u003e\n\u003cp\u003e作为一个前端er，大多数场景下交付的都是纯静态的东西（html, js, css），可能对于服务部署自动化这块不是特别敏感，随便找个环境 build 下，拿到 dist 文件夹丢到服务器上就完事了。再高级一点的，可能有用到各种 SSX 的，或者还有点 serverless 的，还有个 \u003ca href=\"https://vercel.com/docs\"\u003evercel\u003c/a\u003e 这个特别好用的平台供我们使用，简直太强大，纯前端的常规操作，或者配合一些调用第三方数据接口的操作，vercel 一把梭，最多加个 serverless 函数转发下避免跨域之类的问题。比如 ChatGPT 的各种套壳，部署在 vercel 上占大多数。\u003c/p\u003e\n\u003cp\u003e但是，如果你是一个后端er，或者是一个全栈，那么你可能会有一些服务端的东西需要部署，比如一些数据库，中间件等，这些似乎在 vercel 上就不能直接搞定了，虽然他们目前也有在计划 Storage 这个东西，尤其对于版本帝的 nodejs 应用来说，可能不用项目需要的基础环境不一样，按照常规的做法可能需要不同的服务器去做这种环境隔离的事情了。其实对于预算充足的来说，这都不是问题，那么现在要介绍的一种就是如何在极限环境下，去做这种多应用部署，方便自己实验。\u003c/p\u003e\n\u003ch2 id=\"介绍\"\u003e介绍\u003c/h2\u003e\n\u003cp\u003e对于文中实验场景，唯一可能需要付钱的部份是一台低配的服务器，毕竟 github 的 action 不能和本地通信？（如果你有固定 ip 其实也可以）比如本文中使用的是一台腾讯云上的【标准型SA2 - 2核 2G】的服务器，买了三年千把块，算是很便宜了，装的系统是【\tTencentOS Server 3.1 (TK4)】，默认自带了 docker，还做了一些镜像源上的配置，其实自己去\u003ca href=\"https://docs.docker.com/get-docker/\"\u003e安装\u003c/a\u003e个也很方便，记得改下镜像源。\u003c/p\u003e\n\u003cp\u003e需要准备的所有东西包括：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一台云服务器\u003c/li\u003e\n\u003cli\u003e一个镜像仓库\u003c/li\u003e\n\u003cli\u003e一个 github 仓库\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e为什么需要一个镜像仓库，目前很多基础仓库其实都在公开的镜像仓库上，比如 \u003ca href=\"https://hub.docker.com/search?q=\"\u003edockerhub\u003c/a\u003e，但是对于自己应用的镜像制品，不适合放到公开仓库里。网上也有很多搭建的教程比如 \u003ca href=\"https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-22-04\"\u003eHow To Set Up a Private Docker Registry on Ubuntu 22.04\u003c/a\u003e。然后各个云商也提供此类服务，文中例子依旧选择的是腾讯云的 \u003ca href=\"https://cloud.tencent.com/product/tcr\"\u003e容器镜像服务\u003c/a\u003e。\u003c/p\u003e","title":"如何使用 GitHub 和 Docker 进行自动部署"},{"content":" 家庭束缚 父母社会经验的可参考性 对子女爱的定位（天然的债权人 ） 家庭地位平等独立的人 How 解除思想束缚 平等 走向分离 解除现实束缚 靠自己，摒弃「等靠要」 寻找指路人 情绪束缚 生活中的 10%，是由发生在你身上的事情组成，而另外的 90%，则是由你对所发生的事情，如何反应决定。\u0026mdash; 费斯汀格\n问自己： 这是你的想法和情绪，还是事实？\nname desc 不自信 客观真实世界 悲观 主观精神世界 敏感 主观精神世界 自我否定 主观精神世界 抱怨 客观精神世界 不会拒绝 客观精神世界 长期内耗 主观精神世界 在意别人的眼光 主观精神世界 How 分清哪些是事实，哪些是情绪\n内观 第三视角观看，不要思考 建立正反馈机制\n做好一件事 \u0026#x1f3a7; 先做成一件事情，是打开世界大门的钥匙 经济束缚 基本的经济运行规律\n机会成本 通货膨胀 \u0026#x1f4fa; 经济机器是怎样运行的 (时长30分钟) Ray Dalio 什么是投资\n两要素 风险 回报率 How 第一阶段\n了解经济的运行规律 把自己当前主要收入来源的工作做好 顶尖 压缩时间 -\u0026gt; 提高效率 好工作 - 行业内最高端的工作 第二阶段\n现在不是考虑你缺少什么的时候，而是考虑用你拥有的东西可以做什么。 —— 《老人与海》\n分析自己的收入来源 如何把现有的资源效益最大化 思考自己有什么资源可以出售 思考怎么有更多的资源可以出售 思考怎么把目前不可出售的资源出售 自考怎么把已有的资源用更多种的方式出售 怎么把已有的资源已更高的价格出售 第三阶段\n能力、资源进行价值交换 第四阶段\n资本和资源信息差赚钱 知识束缚 知识变现\n找到对你有用的知识，迅速理解吸收使用 本质上是思维的困境 如何找全且正确有用的知识 需要完整的结构化思维系统 信息差\nHow 工作上专业的技能知识 丰富自己的常识和信息 建立自己的独立思维体系 第一性原理溯源思维 每个系统中存在一个最基本的命题，它不能被违背或删除。 —— 亚里士多德\n《第一性原理》李善友 |微信读书 结构化思维 ","permalink":"https://genffy.com/posts/how-ordinary-people-can-change-their-destiny/","summary":"\u003ciframe src=\"//player.bilibili.com/player.html?aid=611473938\u0026bvid=BV1i84y137f3\u0026cid=1066074529\u0026page=1\" width=\"100%\" style=\"min-height: 30vh;\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e \u003c/iframe\u003e\n\u003ch2 id=\"家庭束缚\"\u003e家庭束缚\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e父母社会经验的可参考性\u003c/li\u003e\n\u003cli\u003e对子女爱的定位（天然的债权人 ）\n\u003cul\u003e\n\u003cli\u003e家庭地位平等独立的人\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"how\"\u003eHow\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e解除思想束缚\n\u003cul\u003e\n\u003cli\u003e平等\u003c/li\u003e\n\u003cli\u003e走向分离\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e解除现实束缚\n\u003cul\u003e\n\u003cli\u003e靠自己，摒弃「等靠要」\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e寻找指路人\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"情绪束缚\"\u003e情绪束缚\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003e生活中的 10%，是由发生在你身上的事情组成，而另外的 90%，则是由你对所发生的事情，如何反应决定。\u0026mdash; 费斯汀格\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e问自己： 这是你的想法和情绪，还是事实？\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003ename\u003c/th\u003e\n          \u003cth style=\"text-align: right\"\u003edesc\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e不自信\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e客观真实世界\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e悲观\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e主观精神世界\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e敏感\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e主观精神世界\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e自我否定\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e主观精神世界\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e抱怨\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e客观精神世界\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e不会拒绝\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e客观精神世界\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e长期内耗\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e主观精神世界\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e在意别人的眼光\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e主观精神世界\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"how-1\"\u003eHow\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e分清哪些是事实，哪些是情绪\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e内观\u003c/li\u003e\n\u003cli\u003e第三视角观看，不要思考\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003e建立正反馈机制\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e做好一件事\n\u003cul\u003e\n\u003cli\u003e\u0026#x1f3a7; \u003ca href=\"https://www.xiaoyuzhoufm.com/episode/631af16f5d788154344241dc\"\u003e先做成一件事情，是打开世界大门的钥匙\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"经济束缚\"\u003e经济束缚\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e基本的经济运行规律\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e机会成本\u003c/li\u003e\n\u003cli\u003e通货膨胀\u003c/li\u003e\n\u003cli\u003e\u0026#x1f4fa; \u003ca href=\"https://youtu.be/rFV7wdEX-Mo\"\u003e经济机器是怎样运行的 (时长30分钟) Ray Dalio\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e什么是投资\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e两要素\n\u003cul\u003e\n\u003cli\u003e风险\u003c/li\u003e\n\u003cli\u003e回报率\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"how-2\"\u003eHow\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e第一阶段\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e了解经济的运行规律\u003c/li\u003e\n\u003cli\u003e把自己当前主要收入来源的工作做好\n\u003cul\u003e\n\u003cli\u003e顶尖\u003c/li\u003e\n\u003cli\u003e压缩时间 -\u0026gt; 提高效率\u003c/li\u003e\n\u003cli\u003e好工作 - 行业内最高端的工作\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e第二阶段\u003c/p\u003e","title":"📒是什么一直束缚你在社会底层？"},{"content":"Server-Sent Event 是什么 Server-Sent Event (SSE) 是一种用于在 Web 应用程序中向客户端发送实时事件的技术，它允许服务器向客户端推送数据，而无需客户端不断地轮询服务器。\n为了解决什么问题 SSE 是为了解决传统的轮询技术所面临的问题而引入的。在传统的轮询中，客户端不断地向服务器发送请求以检查数据是否可用。这种方式会占用大量带宽和服务器资源，同时也会导致响应延迟。SSE 则完全颠覆了这种方式，客户端只需要向服务器发送一个请求并保持长连接，服务器在有数据更新时即可通过这个连接向客户端推送数据。这种方式减少了不必要的请求和响应，从而提高了性能和效率。SSE 通常用于实时数据更新、通知和聊天应用程序等场景。 \u0026ndash; from @chatGPT\n数据流规范以及注意事项 数据流规范如下 数据流以 data: 开头，表示接下来是数据内容。 数据内容可以是任意文本格式的数据，通常是 JSON 或纯文本。 数据内容必须以 \\n\\n 结尾，表示这是一个完整的数据块。 可以包含一个或多个事件标识符 (event ID)，以 event: 开头。事件标识符可以用于标识服务器发送的数据类型。 可以包含一个或多个注释，以 : 开头。 可以包含一个可选的重试时间 (retry time)，以 retry: 开头，表示客户端在连接断开后应该等待多长时间后重试连接。重试时间必须是以毫秒为单位的整数。 \u0026ndash; from @chatGPT\n注意事项 当不使用 HTTP/2 时，SSE 存在打开连接数的限制，这个限制对于打开多个选项卡的情况尤其痛苦，因为每个浏览器都有一个非常低的限制数量 (6)。在 Chrome 和 Firefox 中，这个问题被标记为 “不会修复”。这个限制是针对每个浏览器 + 域名的，这意味着您可以在所有选项卡中打开 6 个 SSE 连接到 www.example1.com，以及另外 6 个 SSE 连接到 www.example2.com（根据 Stackoverflow 的说法）。在使用 HTTP/2 时，最大并发 HTTP 流的数量是服务器和客户端协商的（默认为 100）。 \u0026ndash; from MDN\n响应头的设置：在服务器发送 SSE 数据流时，需要设置一些特定的响应头。其中最重要的是 Content-Type，它必须设置为 text/event-stream。此外，可以设置一些其他的响应头，例如 Cache-Control、Access-Control-Allow-Origin、Access-Control-Allow-Credentials 等，以提高 SSE 的性能和可靠性。\n与 WebSocket 有什么区别 Server-Sent Event (SSE) 和 WebSocket 都是在 Web 应用程序中实现实时通信的技术，但它们有一些区别。\nSSE 是基于 HTTP 协议的一种技术，而 WebSocket 是一种独立的协议。因此，SSE 可以在任何支持 HTTP 的环境中使用，而 WebSocket 需要在客户端和服务器之间建立一个新的连接。\nSSE 只能从服务器向客户端发送数据，而 WebSocket 可以在客户端和服务器之间进行双向通信。\nSSE 通常用于单向的实时数据更新和通知场景，而 WebSocket 通常用于双向通信和交互式应用程序，如在线游戏和实时聊天等。\nSSE 使用简单，客户端只需要一个普通的 HTTP 请求即可建立连接，而 WebSocket 则需要在客户端和服务器之间进行协议协商。\nSSE 不能发送二进制数据，只能发送纯文本数据，而 WebSocket 可以发送任何类型的数据，包括二进制数据。\n综上所述，SSE 和 WebSocket 都有自己的优点和应用场景，具体使用哪种技术取决于具体的需求。\n\u0026ndash; from @chatGPT\nnodejs 实现一个 demo 在 Node.js 中，可以使用内置的 http 模块来实现 SSE，这个例子演示了如何通过 Node.js 创建一个 SSE 服务器，并通过浏览器的 EventSource API 来接收服务器发送的事件流。\n以下是一个简单的 SSE 服务器实现示例：\nconst http = require(\u0026#34;http\u0026#34;); http .createServer((req, res) =\u0026gt; { // 设置响应头 res.writeHead(200, { \u0026#34;Content-Type\u0026#34;: \u0026#34;text/event-stream\u0026#34;, \u0026#34;Cache-Control\u0026#34;: \u0026#34;no-cache\u0026#34;, Connection: \u0026#34;keep-alive\u0026#34;, }); // 发送初始数据 res.write(\u0026#34;data: Connected\\n\\n\u0026#34;); // 定时发送数据 const intervalId = setInterval(() =\u0026gt; { res.write(`data: ${new Date().toISOString()}\\n\\n`); // fix net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK) res.flushHeaders(); }, 1000); // 当客户端断开连接时停止发送数据 req.connection.on(\u0026#34;close\u0026#34;, () =\u0026gt; { clearInterval(intervalId); }); }) .listen(3000); console.log(\u0026#34;SSE server listening on port 3000\u0026#34;); 该服务器会每秒钟向客户端发送当前时间戳。客户端可以通过以下方式连接到该服务器：\nconst eventSource = new EventSource(\u0026#34;http://localhost:3000\u0026#34;); eventSource.addEventListener(\u0026#34;message\u0026#34;, (event) =\u0026gt; { console.log(event.data); }); 还可以通过将 Readable Stream 与 SSE 结合，实现服务器向客户端推送数据的功能\nconst http = require(\u0026#34;http\u0026#34;); const { Readable } = require(\u0026#34;stream\u0026#34;); // 创建 SSE 服务器 http .createServer((req, res) =\u0026gt; { res.writeHead(200, { \u0026#34;Content-Type\u0026#34;: \u0026#34;text/event-stream\u0026#34;, \u0026#34;Cache-Control\u0026#34;: \u0026#34;no-cache\u0026#34;, Connection: \u0026#34;keep-alive\u0026#34;, }); // 创建一个可读流，每秒钟向流中推送一条数据 const readable = new Readable({ read() {}, }); const intervalId = setInterval(() =\u0026gt; { const message = `Current time is: ${new Date().toISOString()}\\n\\n`; readable.push(`data: ${message}`); }, 1000); // 将可读流中的数据发送到 SSE 事件流中 readable.pipe(res); // 当客户端断开连接时停止向事件流发送数据 req.connection.on(\u0026#34;close\u0026#34;, () =\u0026gt; { readable.unpipe(res); clearInterval(intervalId); }); }) .listen(3000); console.log(\u0026#34;SSE server listening on port 3000\u0026#34;); 该服务器每秒钟向客户端发送一个包含当前时间戳的 SSE 事件。可读流的数据通过 pipe() 方法发送到 SSE 事件流中。\n完整 demo 代码参考\n","permalink":"https://genffy.com/posts/sse-what-why-how/","summary":"\u003ch2 id=\"server-sent-event-是什么\"\u003eServer-Sent Event 是什么\u003c/h2\u003e\n\u003cp\u003e\u003ccode\u003eServer-Sent Event (SSE)\u003c/code\u003e 是一种用于在 Web 应用程序中向客户端发送实时事件的技术，它允许服务器向客户端推送数据，而无需客户端不断地轮询服务器。\u003c/p\u003e\n\u003ch3 id=\"为了解决什么问题\"\u003e为了解决什么问题\u003c/h3\u003e\n\u003cp\u003eSSE 是为了解决传统的轮询技术所面临的问题而引入的。在传统的轮询中，客户端不断地向服务器发送请求以检查数据是否可用。这种方式会占用大量带宽和服务器资源，同时也会导致响应延迟。SSE 则完全颠覆了这种方式，客户端只需要向服务器发送一个请求并保持长连接，服务器在有数据更新时即可通过这个连接向客户端推送数据。这种方式减少了不必要的请求和响应，从而提高了性能和效率。SSE 通常用于实时数据更新、通知和聊天应用程序等场景。 \u0026ndash; from @chatGPT\u003c/p\u003e\n\u003ch2 id=\"数据流规范以及注意事项\"\u003e数据流规范以及注意事项\u003c/h2\u003e\n\u003ch3 id=\"数据流规范如下\"\u003e数据流规范如下\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e数据流以 \u003ccode\u003edata:\u003c/code\u003e 开头，表示接下来是数据内容。\u003c/li\u003e\n\u003cli\u003e数据内容可以是任意文本格式的数据，通常是 \u003ccode\u003eJSON\u003c/code\u003e 或纯文本。\u003c/li\u003e\n\u003cli\u003e数据内容必须以 \u003ccode\u003e\\n\\n\u003c/code\u003e 结尾，表示这是一个完整的数据块。\u003c/li\u003e\n\u003cli\u003e可以包含一个或多个事件标识符 \u003ccode\u003e(event ID)\u003c/code\u003e，以 \u003ccode\u003eevent:\u003c/code\u003e 开头。事件标识符可以用于标识服务器发送的数据类型。\u003c/li\u003e\n\u003cli\u003e可以包含一个或多个注释，以 : 开头。\u003c/li\u003e\n\u003cli\u003e可以包含一个可选的重试时间 \u003ccode\u003e(retry time)\u003c/code\u003e，以 \u003ccode\u003eretry:\u003c/code\u003e 开头，表示客户端在连接断开后应该等待多长时间后重试连接。重试时间必须是以毫秒为单位的整数。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u0026ndash; from @chatGPT\u003c/p\u003e\n\u003ch3 id=\"注意事项\"\u003e注意事项\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e当不使用 \u003ccode\u003eHTTP/2\u003c/code\u003e 时，SSE 存在打开连接数的限制，这个限制对于打开多个选项卡的情况尤其痛苦，因为每个浏览器都有一个非常低的限制数量 (6)。在 Chrome 和 Firefox 中，这个问题被标记为 “不会修复”。这个限制是针对每个浏览器 + 域名的，这意味着您可以在所有选项卡中打开 6 个 SSE 连接到 \u003ca href=\"https://www.example1.com\"\u003ewww.example1.com\u003c/a\u003e，以及另外 6 个 SSE 连接到 \u003ca href=\"https://www.example2.com\"\u003ewww.example2.com\u003c/a\u003e（\u003ca href=\"https://stackoverflow.com/questions/5195452/websockets-vs-server-sent-events-eventsource/5326159\"\u003e根据 Stackoverflow 的说法\u003c/a\u003e）。在使用 HTTP/2 时，最大并发 HTTP 流的数量是服务器和客户端协商的（默认为 100）。 \u0026ndash; from \u003ca href=\"https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#sect1\"\u003eMDN\u003c/a\u003e\u003c/p\u003e","title":"SSE What Why How"},{"content":"对不同的邮箱生成不同的 ssh key 生成密钥对 # 设置公司的 ssh-keygen -t rsa -C \u0026#34;zhengfei.li@orgname.com\u0026#34; -f ~/.ssh/gitlab_rsa # 设置默认的，一般都是给 gitlab 用的 ssh-keygen -t rsa -C \u0026#34;genffyl@gmail.com\u0026#34; # 查看生成的密钥对 ls -la ~/.ssh # -rw------- 1 genffy staff 2610 Feb 15 17:48 gitlab_rsa # -rw-r--r-- 1 genffy staff 578 Feb 15 17:48 gitlab_rsa.pub # -rw------- 1 genffy staff 2602 Feb 15 17:51 id_rsa # -rw-r--r-- 1 genffy staff 571 Feb 15 17:51 id_rsa.pub 创建配置文件 vim .ssh/config 填入以下内容\n# gitlab.orgname.com Host gitlab.orgname.com AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/gitlab_rsa User zhengfei.li@orgname.com # github.com # Host github.com # AddKeysToAgent yes # UseKeychain yes # IdentityFile ~/.ssh/github_rsa # User genffyl@gmail.com 测试设置效果 ssh -T git@github.com # Hi genffy! You\u0026#39;ve successfully authenticated, but GitHub does not provide shell access. ssh -T git@gitlab.orgname.com # Welcome to GitLab, @zhengfei.li! 配置不同的 git 目录使用不同的密钥 复制默认的 .gitconfig cp .gitconfig .gitconfig-gitlab cp .gitconfig .gitconfig-id 编辑不同的配置文件的 user 信息 vim .gitconfig-gitlab [user] name = zhengfei.li email = zhengfei.li@orgname.com signingkey = ~/.ssh/gitlab_rsa.pub [pull] rebase = false [filter \u0026#34;lfs\u0026#34;] process = git-lfs filter-process required = true clean = git-lfs clean -- %f smudge = git-lfs smudge -- %f [init] defaultBranch = main [commit] gpgsign = true [gpg] format = ssh vim .gitconfig-id [user] name = genffy email = genffyl@gmail.com signingkey = ~/.ssh/id_rsa.pub [pull] rebase = false [filter \u0026#34;lfs\u0026#34;] process = git-lfs filter-process required = true clean = git-lfs clean -- %f smudge = git-lfs smudge -- %f [init] defaultBranch = main [commit] gpgsign = true [gpg] format = ssh 设置不同仓库目录使用不同 .gitconfig vim .gitconfig [includeIf \u0026#34;gitdir:~/workspace/\u0026#34;] path = .gitconfig-id [includeIf \u0026#34;gitdir:~/Documents/workspace/\u0026#34;] path = .gitconfig-gitlab 最后可以在不同的目录下，修改下代码提交测试效果\n","permalink":"https://genffy.com/posts/ssh-key-with-gitconfig-for-different-repo/","summary":"\u003ch2 id=\"对不同的邮箱生成不同的-ssh-key\"\u003e对不同的邮箱生成不同的 ssh key\u003c/h2\u003e\n\u003ch3 id=\"生成密钥对\"\u003e生成密钥对\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置公司的\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003essh-keygen -t rsa -C \u003cspan class=\"s2\"\u003e\u0026#34;zhengfei.li@orgname.com\u0026#34;\u003c/span\u003e -f ~/.ssh/gitlab_rsa\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置默认的，一般都是给 gitlab 用的\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003essh-keygen -t rsa -C \u003cspan class=\"s2\"\u003e\u0026#34;genffyl@gmail.com\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看生成的密钥对\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003els -la ~/.ssh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# -rw-------    1 genffy  staff  2610 Feb 15 17:48 gitlab_rsa\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# -rw-r--r--    1 genffy  staff   578 Feb 15 17:48 gitlab_rsa.pub\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# -rw-------    1 genffy  staff  2602 Feb 15 17:51 id_rsa\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# -rw-r--r--    1 genffy  staff   571 Feb 15 17:51 id_rsa.pub\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"创建配置文件\"\u003e创建配置文件\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evim .ssh/config\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e填入以下内容\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# gitlab.orgname.com\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eHost gitlab.orgname.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  AddKeysToAgent yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  UseKeychain yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  IdentityFile ~/.ssh/gitlab_rsa\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  User zhengfei.li@orgname.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# github.com\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Host github.com\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#  AddKeysToAgent yes\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#  UseKeychain yes\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#  IdentityFile ~/.ssh/github_rsa\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#  User genffyl@gmail.com\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"测试设置效果\"\u003e测试设置效果\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003essh -T git@github.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Hi genffy! You\u0026#39;ve successfully authenticated, but GitHub does not provide shell access.\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003essh -T git@gitlab.orgname.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Welcome to GitLab, @zhengfei.li!\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"配置不同的-git-目录使用不同的密钥\"\u003e配置不同的 git 目录使用不同的密钥\u003c/h2\u003e\n\u003ch3 id=\"复制默认的-gitconfig\"\u003e复制默认的 \u003ccode\u003e.gitconfig\u003c/code\u003e\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp .gitconfig .gitconfig-gitlab\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp .gitconfig .gitconfig-id\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"编辑不同的配置文件的-user-信息\"\u003e编辑不同的配置文件的 \u003ccode\u003euser\u003c/code\u003e 信息\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evim .gitconfig-gitlab\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-toml\" data-lang=\"toml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003euser\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003ename\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ezhengfei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eli\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eemail\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ezhengfei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eli\u003c/span\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"nx\"\u003eorgname\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecom\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003esigningkey\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"err\"\u003e~/\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003essh\u003c/span\u003e\u003cspan class=\"err\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003egitlab_rsa\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epub\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003epull\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003erebase\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003efilter\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;lfs\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eprocess\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egit-lfs\u003c/span\u003e \u003cspan class=\"nx\"\u003efilter-process\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003erequired\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eclean\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egit-lfs\u003c/span\u003e \u003cspan class=\"nx\"\u003eclean\u003c/span\u003e \u003cspan class=\"nx\"\u003e--\u003c/span\u003e \u003cspan class=\"err\"\u003e%\u003c/span\u003e\u003cspan class=\"nx\"\u003ef\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003esmudge\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egit-lfs\u003c/span\u003e \u003cspan class=\"nx\"\u003esmudge\u003c/span\u003e \u003cspan class=\"nx\"\u003e--\u003c/span\u003e \u003cspan class=\"err\"\u003e%\u003c/span\u003e\u003cspan class=\"nx\"\u003ef\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003einit\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003edefaultBranch\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003emain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003ecommit\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003egpgsign\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003egpg\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eformat\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003essh\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evim .gitconfig-id\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-toml\" data-lang=\"toml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003euser\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003ename\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egenffy\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eemail\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egenffyl\u003c/span\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"nx\"\u003egmail\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecom\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003esigningkey\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"err\"\u003e~/\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003essh\u003c/span\u003e\u003cspan class=\"err\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003eid_rsa\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epub\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003epull\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003erebase\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003efilter\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;lfs\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eprocess\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egit-lfs\u003c/span\u003e \u003cspan class=\"nx\"\u003efilter-process\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003erequired\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eclean\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egit-lfs\u003c/span\u003e \u003cspan class=\"nx\"\u003eclean\u003c/span\u003e \u003cspan class=\"nx\"\u003e--\u003c/span\u003e \u003cspan class=\"err\"\u003e%\u003c/span\u003e\u003cspan class=\"nx\"\u003ef\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003esmudge\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003egit-lfs\u003c/span\u003e \u003cspan class=\"nx\"\u003esmudge\u003c/span\u003e \u003cspan class=\"nx\"\u003e--\u003c/span\u003e \u003cspan class=\"err\"\u003e%\u003c/span\u003e\u003cspan class=\"nx\"\u003ef\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003einit\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003edefaultBranch\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003emain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003ecommit\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003egpgsign\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003egpg\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003eformat\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003essh\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"设置不同仓库目录使用不同-gitconfig\"\u003e设置不同仓库目录使用不同 \u003ccode\u003e.gitconfig\u003c/code\u003e\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evim .gitconfig\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-toml\" data-lang=\"toml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003eincludeIf\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;gitdir:~/workspace/\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003epath\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egitconfig-id\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003eincludeIf\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;gitdir:~/Documents/workspace/\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nx\"\u003epath\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egitconfig-gitlab\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e最后可以在不同的目录下，修改下代码提交测试效果\u003c/p\u003e","title":"为不同的 git repo 配置 ssh key、gitconfig"},{"content":"git delete all local branch except master git branch | grep -v -E 'master' | xargs git branch -D\ngit revert commit git reset --soft HEAD^ maore options\n--mixed 意思是：不删除工作空间改动代码，撤销 commit，并且撤销 git add . 操作这个为默认参数， git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的。 --soft 不删除工作空间改动代码，撤销commit，**不撤销 git add . ** --hard 删除工作空间改动代码，**撤销commit，撤销 git add . ** **注意完成这个操作后，会删除工作空间代码 ！！！恢复到上一次的commit状态。**慎重！！！ modify commit msg git commit --amend\ngit blame -L file 对应是文件路径，也就是解析出来的原始堆栈的文件路径信息 range 对应的是查找的范围，也就是解析出来的原始堆栈的行号范围 shell 列出文件下大小 du -d 1 -h\n查找日志中的域名 // awk \u0026#39;{print $11}\u0026#39; ./access.log | awk -F/ \u0026#39;{print $3}\u0026#39; | sort | uniq 查找 #shell #find #grep # 查看目录下文件夹大小 find . -name \u0026#34;node_modules\u0026#34; -type d -prune -print | xargs du -chs # 查找并删除 find . -name \u0026#39;node_modules\u0026#39; -type d -prune -print -exec rm -rf \u0026#39;{}\u0026#39; \\; find . -name \u0026#34;node_modules\u0026#34; -exec rm -rf \u0026#39;{}\u0026#39; \\; find ./ -name \u0026#39;master-stderr.log.202008*\u0026#39; | xargs rm -fr grep -rnw \u0026#39;/etc/nginx/site/\u0026#39; -e \u0026#39;/market-coupon-app\u0026#39; grep -nr \u0026#34;get_spg2lsf\u0026#34; ./ grep -R --exclude-dir=node_modules --exclude-dir=nginxconf \u0026#39;open-ng.zmlearn.com\u0026#39; ./ find . -type d -wholename \u0026#39;*bench*/image\u0026#39; | xargs tar cf -\\n create symbolic link #┌── ln(1) link, ln -- make links #│ ┌── Create a symbolic link. #│ │ ┌── the optional path to the intended symlink #│ │ │ if omitted, symlink is in . named as destination #│ │ │ can use . or ~ or other relative paths #│ │ ┌─────┴────────┐ ln -s /path/to/original /path/to/symlink #\t└───────┬───────┘ #\t└── the path to the original file/folder #\tcan use . or ~ or other relative paths 网络相关的 shell 命令 # Linux netstat command find out which process is listing upon a port netstat -tulpn # ls -l /proc/\u0026lt;pid\u0026gt;/exe netstat -an | grep :80 lsof -n -P | grep :80 lsof -i tcp:8080 sre jumpserver 安装 sz rz 的机器上快速下载/上传 获取本机出口 ip curl cip.cc 查看当前出口 ip https://en.ipip.net/ ","permalink":"https://genffy.com/snippet/","summary":"\u003ch2 id=\"git\"\u003egit\u003c/h2\u003e\n\u003ch3 id=\"delete-all-local-branch-except-master\"\u003edelete all local branch except master\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003egit branch | grep -v -E 'master' | xargs git branch -D\u003c/code\u003e\u003c/p\u003e\n\u003ch3 id=\"git-revert-commit\"\u003egit revert commit\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003egit reset --soft HEAD^\u003c/code\u003e\nmaore options\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e--mixed \u003c/code\u003e\n意思是：不删除工作空间改动代码，撤销 commit，并且撤销 \u003ccode\u003egit add .\u003c/code\u003e 操作这个为默认参数， \u003ccode\u003egit reset --mixed HEAD^\u003c/code\u003e  和  \u003ccode\u003egit reset HEAD^\u003c/code\u003e  效果是一样的。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e--soft\u003c/code\u003e\n不删除工作空间改动代码，\u003cstrong\u003e撤销commit\u003c/strong\u003e，**不撤销 \u003ccode\u003egit add .\u003c/code\u003e  **\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e--hard\u003c/code\u003e\n\u003cstrong\u003e删除工作空间改动代码\u003c/strong\u003e，**撤销commit，撤销 \u003ccode\u003egit add .\u003c/code\u003e  ** **注意完成这个操作后，会删除工作空间代码 ！！！恢复到上一次的commit状态。**慎重！！！\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"modify-commit-msg\"\u003emodify commit msg\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003egit commit --amend\u003c/code\u003e\u003c/p\u003e\n\u003ch3 id=\"gitblame-l\"\u003egit blame -L \u003crange\u003e \u003cfile\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003efile 对应是文件路径，也就是解析出来的原始堆栈的文件路径信息\u003c/li\u003e\n\u003cli\u003erange 对应的是查找的范围，也就是解析出来的原始堆栈的行号范围\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"shell\"\u003eshell\u003c/h2\u003e\n\u003ch3 id=\"列出文件下大小\"\u003e列出文件下大小\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003edu -d 1 -h\u003c/code\u003e\u003c/p\u003e","title":"代码片段"},{"content":"你好 👋\n网络上 ID 是 genffy，真名 李正飞 本职工作是页面仔(Front-end Developer)，希望成为一个工程师 日常运动是跑步，偶尔游泳，骑车\nMBTI INTJ\n喜欢的诗 断章 - 卞之琳\n你站在桥上看风景 看风景的人在楼上看你 明月装饰了你的窗子 你装饰了别人的梦\n一些句子 路漫漫其修远兮，吾将上下而求索 心有猛虎，细嗅蔷薇 曾经沧海难为水，除却巫山不是云 胡适的话 总得时时寻一两个值得研究的问题 总得多发展一点非职业的兴趣 你得有一点信心 《少有的人走的路》 【推迟满足感】，承担责任，尊重事实，保持平衡\n","permalink":"https://genffy.com/about/","summary":"\u003cp\u003e你好 👋\u003cbr\u003e\n网络上 ID 是 \u003ccode\u003egenffy\u003c/code\u003e，真名 \u003ccode\u003e李正飞\u003c/code\u003e \u003cbr\u003e\n本职工作是页面仔(Front-end Developer)，希望成为一个工程师       \u003cbr\u003e\n日常运动是跑步，偶尔游泳，骑车\u003c/p\u003e\n\u003ch2 id=\"mbti\"\u003eMBTI\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://www.16personalities.com/ch/intj-%E4%BA%BA%E6%A0%BC\" target=\"_blank\"\u003eINTJ\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"喜欢的诗\"\u003e喜欢的诗\u003c/h2\u003e\n\u003cp\u003e断章 - 卞之琳\u003c/p\u003e\n\u003cp\u003e你站在桥上看风景  \u003cbr\u003e\n看风景的人在楼上看你  \u003cbr\u003e\n明月装饰了你的窗子  \u003cbr\u003e\n你装饰了别人的梦\u003c/p\u003e\n\u003ch2 id=\"一些句子\"\u003e一些句子\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e路漫漫其修远兮，吾将上下而求索\u003c/li\u003e\n\u003cli\u003e心有猛虎，细嗅蔷薇\u003c/li\u003e\n\u003cli\u003e曾经沧海难为水，除却巫山不是云\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"胡适的话\"\u003e胡适的话\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e总得时时寻一两个值得研究的问题\u003c/li\u003e\n\u003cli\u003e总得多发展一点非职业的兴趣\u003c/li\u003e\n\u003cli\u003e你得有一点信心\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"少有的人走的路\"\u003e《少有的人走的路》\u003c/h2\u003e\n\u003cp\u003e【推迟满足感】，承担责任，尊重事实，保持平衡\u003c/p\u003e","title":"关于"}]