diff --git a/base/basics.rst b/base/basics.rst index cc5152c6..177ef85f 100644 --- a/base/basics.rst +++ b/base/basics.rst @@ -48,6 +48,7 @@ python,ruby之类的动态语言优势在于其生产力,你能在极短时 * `《算法图解》 `_ * `《算法导论》 `_ 你可以挑选感兴趣的章节啃一啃,也可以去网易公开课看下视频教程。如果不是计算机专业的可以看下《计算机科学导论》这门公开课,正好也是以Python语言讲解的。 * `《awesome-algorithm》 `_ +* `《每个程序员应该知道的 50 个算法(全)》 `_ 计算机网络 diff --git a/codingtools/codingtools.rst b/codingtools/codingtools.rst index 46273af2..5394702f 100644 --- a/codingtools/codingtools.rst +++ b/codingtools/codingtools.rst @@ -47,7 +47,7 @@ MacOS 开发效率工具 - Be Focused: mac 下番茄工作法工具,可以用来给任务计时,或者提醒该休息下了 - Qbserve: https://qotoqot.com/qbserve/ 一个 mac 下的时间追踪软件,可以查看自己在不同软件耗时,改善时间和工作管理 - xbar: 一款可以在 macos 菜单栏显示任意信息的 App,可以通过脚本扩展功能。有插件商店 -- vimac: 用 vim 的方式操作 mac,彻底抛弃鼠标提升效率! https://github.com/dexterleng/vimac +- vimac/homerow: 用 vim 的方式操作 mac,彻底抛弃鼠标提升效率!新款叫做 homerow。 https://github.com/dexterleng/vimac 网址 https://gist.github.com/lornajane/3892c39098cf70baa9c7a1874cddf233 列举了使用纯键盘操作 mac 的建议和所用软件 @@ -89,7 +89,7 @@ Mac 终端快速配置 - 安装 oh-my-zsh 主题 powerlevel9k 或者 spaceship。推荐使用异步的更快的 https://github.com/romkatv/powerlevel10k。 常见其他主题有(pure, powerlevel9k, spaceship) - 安装 vim / spacevim /neovim - 最好安装 tmux 用来替代iterm2 分屏 -- 按需安装 htop/autojump/z/fzf/ag 等命令行工具(使用 brew 可以安装) +- 按需安装 htop/btop/autojump/z/fzf/ag 等命令行工具(使用 brew 可以安装) 可以参考我 github 上的快速配置教程: @@ -130,9 +130,9 @@ Git 相关 Chrome 开发者插件 -------------------------------------- +- FE前端助手(FeHelper插件):浏览器前端插件,Json 格式化/json比对/代码美化/编解码/二维码等很多有用的工具,强烈建议安装 - SurfingKeys/vimium/Cvim: chrome 插件,可以用 vim 的方式操作浏览器,很方便,不用鼠标也能完成大部分操作,笔者使用的SurfingKeys比较强大,可以用 ctrl+i 来用 vim 编辑输入 - wasavi: 想在网页编辑框使用 vim 可以试试这个插件。安装完之后使用 ctrl+enter 就可以了 https://github.com/akahuku/wasavi -- FE助手:前端插件,Json 格式化/代码美化等很多有用的工具 - Octotree: Chrome github 浏览插件,可以把 github 项目的目录树结构展示出来,非常方便 - Github Hovercard: 可以在浏览 github 的时候展示一些链接信息,比如可以查看作者的个人页 - Momentum: 美化 Chrome 界面的插件,有很多漂亮的图片作为背景 @@ -162,6 +162,7 @@ Chrome 开发者插件 - python 可视化:http://www.pythontutor.com/live.html#mode=edit - VisuAlgo: https://visualgo.net/en 算法可视化 - https://www.cs.usfca.edu/~galles/visualization/RedBlack.html +- https://github.com/krahets/hello-algo 算法可视化 代码辅助和检测工具 @@ -351,6 +352,7 @@ Proxy - pyppeteer/selenium: 基于 python 动态网站爬虫处理,或者用于自动化测试 - portia: 类似造数、八爪鱼之类的可视化爬虫 https://github.com/scrapinghub/portia - Pholcus/Colly/crawlab: Go语言编写的爬虫框架 +- Scrapling https://github.com/D4Vinci/Scrapling 自动化测试 -------------------------------------- @@ -427,10 +429,11 @@ APM (Application Performance Management) 参考:https://www.zhihu.com/question/27994350 -数据库工具 +数据库命令行/可视化工具 -------------------------------------- - mycli: mysql 命令行补全等。https://github.com/dbcli/mycli - MysqlWorkbench/Sequel Pro: mysql 客户端工具。也可以用来生成生成 ER 图 +- Dbeaver 跨平台的mysql/sqllite等可视化工具。mac可以通过 ``brew install --cask dbeaver-community`` 安装 - Navicat Premium: 强大的数据库管理工具,收费 - pt-online-schema-change: mysql数据库变更工具 - Medis: redis client 工具 @@ -454,10 +457,11 @@ APM (Application Performance Management) - excalidraw: 手写风格绘图 https://excalidraw.com/ - onemodel: 程序员绘图,有很多编程图标 https://www.onemodel.app/ -量化投资 +量化投资(偏向python量化) -------------------------------------- - tushare: https://github.com/waditu/tushare 有本小白参考书: https://wizardforcel.gitbooks.io/python-quant-uqer/ - +- efinance: https://github.com/Micro-sheep/efinance efinance 是一个可以快速获取基金、股票、债券、期货数据的 Python 库,回测以及量化交易的好帮手 +- akshare: https://github.com/akfamily/akshare 开源财经数据接口库 效率,时间管理工具 -------------------------------------- diff --git a/conf.py b/conf.py index a67f0378..891ea0d2 100755 --- a/conf.py +++ b/conf.py @@ -17,7 +17,7 @@ def _warn_node(self, msg, node, **kw): master_doc = "index" project = "python-golang-web-guide" -copyright = "2023, 公众号|知乎|B站 PegasusWang" +copyright = "2025, 公众号|知乎|B站 PegasusWang" version = release = "0.1" diff --git a/database/mysql.rst b/database/mysql.rst index 1881d94a..e7130111 100644 --- a/database/mysql.rst +++ b/database/mysql.rst @@ -160,7 +160,8 @@ Sqlalchemy 示例 """ sqlalchemy 快速读取 mysql 数据示例 - pip install SQLAlchemy -i https://pypi.doubanio.com/simple --user + # pip install SQLAlchemy -i https://pypi.doubanio.com/simple --user + pip install SQLAlchemy==1.3.20 -i https://pypi.doubanio.com/simple --user pip install pymysql -i https://pypi.doubanio.com/simple --user """ diff --git a/debug/index.rst b/debug/index.rst index 2a4afd95..c4219210 100644 --- a/debug/index.rst +++ b/debug/index.rst @@ -112,7 +112,8 @@ bug主要来源于粗心(比如拼写错误)、认知偏差(比如错误理解 ~~~~~~~~~~~~~~~~~~~~~~ - 数值截断错误。注意强制类型转换是否会发生截断,损失精度,结果是否符合期望。如果需要精确数值,比如银行存款、电商交易可以 用定点数或者整数。 -- 数值范围越界:注意前端 javascript(设计缺陷) 无法表示完整的 int64,传给前端需要用 string 替换 int64 (被坑过好几次, 有些序列化协议会自动给你把int64转成string处理) +- 数值范围越界:注意前端 javascript(设计缺陷) 无法表示完整的 int64,传给前端需要用 string 替换 int64 (被坑过好几次, 有些序列化协议会自动给你把int64转成string处理)。 + golang里如果有一个 json 数据包含了 int64,反序列化到一个 ``map[string]interface{}`` 也会有类似问题,可以用 UseNumber() 属性解决。https://zhuanlan.zhihu.com/p/347985826 - 浮点数比较:浮点数不能直接用等号比较,应该是比较两个数的差值小于指定范围 内存问题 diff --git a/go-note/concurrency_patterns.rst b/go-note/concurrency_patterns.rst index bf74d342..79dfa03a 100644 --- a/go-note/concurrency_patterns.rst +++ b/go-note/concurrency_patterns.rst @@ -3,6 +3,17 @@ Go 并发设计模式 ===================================================================== +并发编程常见问题 +-------------------------------------------------- + +1. 资源共享问题。竞争条件(race condition), 死锁(deadlock),资源争用(contention) + + - 比如并发读写原生的 map 导致 panic + - 读锁重入导致思索。获取读锁的协程,不要二次重入再去获取读锁 + +2. 协程管理 +3. 通道使用 + 屏障模式(Barrier Mode) -------------------------------------------------- 屏障模式(Barrier Mode),用来阻塞goroutine直到聚合所有goroutine返回结果,可以用通道实现。使用场景: diff --git a/go-note/optimize.rst b/go-note/optimize.rst index 018159ef..349941e3 100644 --- a/go-note/optimize.rst +++ b/go-note/optimize.rst @@ -58,6 +58,8 @@ string 与 []byte 互转 - `Go性能优化技巧 `_ - `Golang 中 string 与 []byte 互转优化 `_ - `Go 语言高性能编程 `_ +- `Golang后台服务性能优化,实用Tips梳理大全 `_ + 大量字符串拼接 --------------------------------------------------------------- @@ -110,6 +112,11 @@ Go 内置的 rand.Int()在生成随机数时,为了并发安全底层使用了 可以使用 github.com/valyala/fastrand 等三方库替换。 +更快的Json序列化 +--------------------------------------------------------------- +可以使用字节开源的 sonic 库 https://github.com/bytedance/sonic 替换内置的 json + + 伪共享问题(false sharing) --------------------------------------------------------------- 如果并发更新一个结构体的字段,我们可以通过填充空字节防止字段被 cpu 缓存到一个 cache line 单位中,需要不断同步降低效率。 @@ -137,3 +144,69 @@ Go 内置的 rand.Int()在生成随机数时,为了并发安全底层使用了 容器中运行 Go 程序需要正确设置 GOMAXPROCS,推荐使用 https://github.com/uber-go/automaxprocs 这个库,直接一行代码就可以。 ``import _ "go.uber.org/automaxprocs"`` + +日志延迟序列化 +--------------------------------------------------------------- +经常需要在日志里打印 json 数据,但是免不了序列化的开销。即使你只在 debug 级别下打印,还是要先序列化参数之后传入数据。 +可以使用延迟序列化的方式,这样正式环境下的 debug 日志不会真正序列化,减少 cpu 开销。 + +.. code-block:: go + + package main + + import ( + "time" + + "xxxx/logs" // 你们用的日志库 + "github.com/bytedance/sonic" + ) + + func GetLog(data interface{}) string { + if log, err := sonic.MarshalString(data); err == nil { + return log + } + return "" + } + + // 延迟序列化,避免 debug 模式下序列化 json 开销 + type LazyInfo struct { + Data any + } + + func (l *LazyInfo) String() string { + dataStr, err := sonic.MarshalString(l.Data) + if err != nil { + panic(err) + } + return dataStr + } + + func NewLazyInfo(d any) *LazyInfo { + return &LazyInfo{Data: d} + } + + type S struct { + a string + b string + } + + func init() { + // logs.SetLevel(logs.LevelDebug) // 测试环境 + logs.SetLevel(logs.LevelInfo) // 正式环境 + } + + func main() { + s := S{a: "a", b: "b"} + logs.Info("info getLog:%s", GetLog(s)) + logs.Debug("debug getLog:%s", GetLog(s)) + + logs.Info("info lazyInfo:%s", NewLazyInfo(s)) // 正式环境使用info + logs.Debug("debug lazyInfo:%s", NewLazyInfo(s)) // 正式环境使用 info 级别后,debug 函数参数不会真序列化,减少开销 + + time.Sleep(time.Second) + } + + +使用 context cache 避免重复下游调用(调用放大) +--------------------------------------------------------------- +TODO diff --git a/go-note/tricks.rst b/go-note/tricks.rst index 4f77995b..eb22a485 100644 --- a/go-note/tricks.rst +++ b/go-note/tricks.rst @@ -648,15 +648,20 @@ go 的返回值可以命名,使用命名返回值有几个用处: } -defer 语句参数是立即计算 +defer 的一些坑 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +1. defer 语句的参数是立即计算 +2. defer for 循环中使用注意循环的量级,避免内存泄露 +3. defer 碰到panic也能执行,但是如果直接执行了 os.Exit 退出而不是正常的 return/panic 退出,程序会立刻终止不会执行 defer。遇到服务升级 defer 可能失效 + 来看一个例子,通过 defer 计算一下执行的时间,错误写法因为 defer 的参数是立即计算的,所以不生效。 .. code-block:: go func testDeferLogTime() { // 记录执行的毫秒数 start := time.Now() - defer func() { fmt.Println(time.Since(start).Milliseconds()) }() // 正确写法输入 1s + defer func() { fmt.Println(time.Since(start).Milliseconds()) }() // 正确写法输入 1s 。需要用匿名函数包一层 // defer fmt.Println(time.Since(start).Milliseconds()) // NOTE: 写法错误,defer 参数及时计算,这样写结果是 0 time.Sleep(1 * time.Second) } @@ -823,9 +828,11 @@ Failed Type Assertions } } -interface 和 nil 比较的坑。An interface holding a nil value is not nil ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +为什么接口判断nil!=nil? interface 和 nil 比较的坑。An interface holding a nil value is not nil +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> An interface holding nil value is not nil. An interface equals nil only if both type and value are nil. +接口的底层实现包含两个部分:type 和 data。type 表示接口存储值的具体类型,data 则存储实际的值。只有当 type 和 data 都为 nil 时,接口才被认为是 nil。 +这个问题可能会导致一些非常隐蔽的 bug。 .. code-block:: go @@ -837,10 +844,10 @@ An interface holding nil value is not nil. An interface equals nil only if both var b interface{} var p *int = nil b = p - fmt.Printf("b == nil is %t\n", b == nil) // b == nil is false - // 在一些场景中如果需要返回 nil,直接显示返回 nil 不容易出错 + fmt.Printf("b == nil is %t\n", b == nil) // b == nil is false。这里接口的类型并不是空,所以判断不是nil } + // 在一些场景中如果需要返回 nil,直接显示返回 nil 不容易出错 func testInterfaceNilWrong() { doit := func(arg int) interface{} { var result *struct{} = nil @@ -869,6 +876,13 @@ An interface holding nil value is not nil. An interface equals nil only if both } } +总结一下,严格遵守几个原则,可以避免出现这种隐蔽的 bug: + +1. 如果 interface 被具体类型变量赋值过,无论是否具体变量本身是不是 nil,接口值都是非 nil。 +2. 如果函数返回具体类型,然后又在其他地方需要赋值给接口,那函数应该直接返回接口类型。 +3. 不要写任何可能存在 ``接口 = 具体类型(nil)`` 的代码,如果有 nil 值,直接赋给接口,不要引入中间具体类型 + + 逃逸分析 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 想要知道变量在 stask 还是 heap 分配使用 ``go run -gcflags -m app.go`` @@ -1050,8 +1064,8 @@ go 的匿名嵌入是一种 Pseudo is-a 关系(伪is a),不能完全等价于 Go 标准库相关 -------------------------------------------------- -Json 序列化的坑 ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +Json 序列化/反序列化的坑 +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1. 类型嵌入导致序列化字段丢失问题 .. code-block:: go @@ -1076,6 +1090,33 @@ go 的 time.Time 对象包含日历时钟(Wall time)和单调时钟(Monitonic ti 3. 如果序列化 map 的值是 any,序列化后的数字类型都是 float64 +4. JSON Unmarshal 到 interface{} 精度丢失问题! https://forum.golangbridge.org/t/preserve-int64-value-for-map-string-interface/26374 + +.. code-block:: go + + // interface 接收 int64 的unmarshal结果,会丢失精度 + func testUnmarshalInt64() { + res := map[string]interface{}{} + data := `{"id": 7444023959772728345}` + if err := json.Unmarshal([]byte(data), &res); err != nil { + panic(err) + } + fmt.Printf("%d\n", int64(res["id"].(float64))) // 输出 7444023959772728320 + } + + // 解决方式: 1. 使用 decoder.UseNumber 2. 使用 string 字段 + // 如果你使用 sonic 库,可以设置 sonic 的参数 UseInt64 为 true + func testUnmarshalInt64RightWay() { + res := map[string]interface{}{} + data := `{"id": 7444023959772728345}` + decoder := json.NewDecoder(strings.NewReader(data)) + decoder.UseNumber() + if err := decoder.Decode(&res); err != nil { + panic(err) + } + fmt.Println(res["id"]) // 输出 7444023959772728345 + } + 网络相关 -------------------------------------------------- diff --git a/go-note/web.rst b/go-note/web.rst index e06689a7..bd3847b0 100644 --- a/go-note/web.rst +++ b/go-note/web.rst @@ -116,7 +116,7 @@ Go 常用框架(工具)技术雷达 ❤️ - Zookeeper: go-zookeeper/zk - 设计模式:tmrts/go-patterns - 数据结构:deckarep/golang-set, emirpasic/gods -- 通用泛型工具库:thoas/go-funk +- 通用泛型工具库:thoas/go-funk, bytedance/gg(字节内部广泛使用且开源的泛型库) - 通用工具库:duke-git/lancet - 深拷贝:mohae/deepcopy, barkimedes/go-deepcopy - 采样监控:mosn/holmes(排查OOM等问题) @@ -276,10 +276,47 @@ Go项目Layout - github.com/alicebob/miniredis 可以用来 mock redis,无需启动真实的 resdis server。试了下非常好用,也不用使用 mock 和真实的 redis 了。个人强烈推荐 - bouk/monkey: 通过替换函数指针的方式修改任意函数的实现,如果以上都无法满足需求,可以用这种比较 hack 的方式。可能需要禁止编译器内联优化 ``go test -gcflask=-l ./...`` - agiledragon/gomonkey: go 语言实现 monkey patch +- mockey: 字节开源的 go mock 工具库。 https://juejin.cn/post/7159568574699274248 -目前比较推荐使用 assert 做断言,使用 gomonkey 用来 mock 函数/方法等。 +目前项目推荐使用 mockey 和 convey 库,可以方便地实现 mock 和 bdd 行为驱动测试,一个简单的示例如下。 -参考: +.. code-block:: shell + + // https://juejin.cn/post/7159568574699274248 + import ( + "fmt" + "testing" + + . "github.com/bytedance/mockey" + . "github.com/smartystreets/goconvey/convey" + ) + + func Foo(in string) string { + return in + } + + type A struct{} + + func (a A) Foo(in string) string { return in } + + var Bar = 0 + + func TestMockXXX(t *testing.T) { + PatchConvey("TestMockXXX", t, func() { // 推荐用 PatchConvey 方法,它会帮我们自动释放掉 mock + Mock(Foo).Return("c").Build() // mock函数 (一般对于下游调用、数据库调用、缓存调用等需要 mock 掉,方便测试且跑单测无需依赖下游部署) + Mock(A.Foo).Return("c").Build() // mock方法 + MockValue(&Bar).To(1) // mock变量 + + // convey 提供了 ShouldEqual 等诸多方法用来比对单测结果和各种数据结构 + So(Foo("a"), ShouldEqual, "c") // 断言`Foo`成功mock + So(new(A).Foo("b"), ShouldEqual, "c") // 断言`A.Foo`成功mock + So(Bar, ShouldEqual, 1) // 断言`Bar`成功mock + }) + // `PatchConvey`外自动释放mock + fmt.Println(Foo("a")) // a + fmt.Println(new(A).Foo("b")) // b + fmt.Println(Bar) // 0 + } - https://medium.com/@rosaniline/unit-testing-gorm-with-go-sqlmock-in-go-93cbce1f6b5b (medium.com有阅读次数限制,隐身模式打开似乎就可以了) @@ -381,8 +418,11 @@ Go 常用命令 go list -f '{{range $imp := .Imports}}{{printf "%s\n" $imp}}{{end}}' | sort go list -f '{{range $dep := .Deps}}{{printf "%s\n" $dep}}{{end}}' | xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' - # 清理模块缓存, GO111MODULE=on 以后,下载的模块内容会缓存在$GOPATH/pkg/mod 目录中: 使用以下命令可清空缓存: - go clean --modcache + # 清理模块缓存, GO111MODULE=on 以后,下载的模块内容会缓存在$GOPATH/pkg/mod 目录中: 使用以下命令可清空缓存(重新下载很久注意是否要清理): + # https://zhuanlan.zhihu.com/p/668274139 + go clean --modcache # 清理模块缓存。模块缓存包括在模块管理过程中下载的模块文件和依赖项信息 + go clean -cache # 清理构建缓存,但不会删除无用文件。构建缓存包括编译过程中生成的中间文件和对象文件 + go clean -testcache # 清理测试缓存。测试缓存包括在测试运行过程中生成的文件和状态 # 跨平台编译 `GOOS=linux GOARCH=amd64 go build main.go` @@ -390,6 +430,9 @@ Go 常用命令 # 强制重新构建(依赖包) 使用 -a。参考:http://c.biancheng.net/view/120.html go build -a main.go + # go mod why 加上包名查看特定模块被引入的原因,用于查询依赖关系 + go mod why pakage_name + # go mod graph # 会显示出go.mod里需要的每个包,都依赖了哪些包。可以用这个工具可视化 https://github.com/PaulXu-cn/go-mod-graph-chart go get -u github.com/PaulXu-cn/go-mod-graph-chart/gmchart diff --git a/memo/memo.rst b/memo/memo.rst index 40714a11..5d2a245c 100644 --- a/memo/memo.rst +++ b/memo/memo.rst @@ -70,6 +70,27 @@ pip/easy_install trusted-host = pypi.douban.com +uv 一个用 Rust 编写的极速 Python 包和项目管理器。 +--------------------------------------------------------------- + +.. code-block:: sh + + # 安装(linux/mac) + curl --proto '=https' --tlsv1.2 -LsSf https://gh-proxy.com/https://github.com/astral-sh/uv/releases/download/0.9.11/uv-installer.sh | sh + # 初始化项目 + uv init . + # 创建虚拟环境 + uv venv + # 导入 requirements.txt 依赖 + uv add -r requirements.txt + # 添加新的依赖 + uv add requests + # 删除依赖 + uv remove requests + # 运行 + uv run main.py + + IPython --------------------------------------------------------------- @@ -183,6 +204,9 @@ Chrome(Mac) # 黑科技:如何chrome 证书认证(不推荐) 在网页中输入 thisisunsafe 或者 badidea 就可以了 + # surfingkeys 插件可以通过T 搜索当前打开的标签,但是打开数量在 tabsThreshold 以下的时候只会高亮 tab 不会打开搜索框 + # 可以设置这个值 tabsThreshold 只要打开超过该数量的标签就可以使用搜索浏览器标签的功能 + settings.tabsThreshold = 5; MacOS --------------------------------------------------------------- @@ -284,6 +308,10 @@ MacOS osascript -e 'id of app "ebook-viewer.app"' # 安装 calibre 之后,找到附带的电子书浏览软件 id duti -s com.calibre-ebook.ebook-viewer .mobi all # 用 ebook-viewer 打开所有的 mobi + # legacyScreenSaver memory 内存占用高。装了 fliqlo 翻页时钟屏保, 尝试重新装下 https://fliqlo.com/screensaver/ 最新版 + + # 如何恢复删除的 dot file。 打开废纸篓,使用 command+shift+. 可以显示,然后恢复到原处即可 + 如何发送 mac 通知,可以用来做提示 .. code-block:: python @@ -635,6 +663,9 @@ Tmux # use prefix + m zoom and unzoom panes. https://tao-of-tmux.readthedocs.io/en/latest/manuscript/07-pane.html bind-key -T prefix m resize-pane -Z + # 清理 tmux 备份文件(超过 1 天) + cd ~/.local/share/tmux/resurrect + find . -type f -mmin +1440 -name 'tmux_resurrect_*.txt' -exec rm {} \; SSH @@ -974,6 +1005,44 @@ Git工作流 # 压缩提交 git rebase -i HEAD~~ # 最近两次提交 +Git Worktree +---------------------- + +.. code-block:: shell + + # 参考 https://zhuanlan.zhihu.com/p/1938293629455152167 + # git Worktree 让一个 git 分支仓库对应多个本地目录,每个目录不同分支。不用反复切分支,多分支并行。结合 claude code 并行开发 + # 格式:git worktree add <新目录路径> <分支名> + # 示例1:给bug-fix分支创建独立目录(同级目录)。创建目录并且关联分支 + # 先在当前项目创建一个 .wt 目录用作作为 worktree 的容器。可以写到全局 ~/.gitignore_global 忽略这个目录 + # 注意:先切到你的项目代码目录后执行 + mkdir .wt + # 如果现有了 bugfix 分支直接执行 + git worktree add .wt/bugfix bugfix + # 否则,使用 -b 参数同时创建分支,比如这里创建两个目录跟踪两个不同分支开发 + git worktree add .wt/bugfix -b bugfix + git worktree add .wt/feat -b feat + # 此时 cd .wt 目录下可以看到这两个目录 bugfix 和 feat + + # 查看所有创建目录 + git worktree list + + # 使用方式,直接切到新建的 worktree 某个目录下开发即可 + cd .wt/bugfix + git add . && git commit -m "修复登录Bug" && git push + + # 删除某个工作区目录(先确保其中无未跟踪变更) + git worktree remove .wt/feat + git worktree remove -f .wt/feat # 强制删除,可能有风险 + + # 预演清理(只显示将被清理的内容),安全起见先执行这个之后再去掉参数实际执行清理 + git worktree prune -n -v # 先执行 + git worktree prune + + # 收尾:先 remove 再 prune + git worktree remove .wt/feat + git worktree prune + Git hook ------------ @@ -1199,6 +1268,9 @@ Ffmpeg && youbute-dl # 目前youtube-dl 貌似不更新了,用 yt-dlp 代替 python3 -m pip install --force-reinstall https://github.com/yt-dlp/yt-dlp/archive/master.tar.gz + # 比如映射了俩命令下载 MP3 或者 mp4 + alias download_youtube_mp3='yt-dlp --cookies-from-browser chrome -x --audio-format mp3' + alias download_youtube='yt-dlp --cookies-from-browser chrome -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]" ' # 转换格式,比如 flv -> mp4 https://superuser.com/questions/624565/ffmpeg-convert-flv-to-mp4-without-losing-quality ffmpeg -i input.flv -codec copy output.mp4 @@ -1367,6 +1439,16 @@ Mac 微信 # 支持微信多开、消息防撤回、微信皮肤等多种功能。懒人安装 curl -o- -L https://omw.limingkai.cn/install.sh | bash -s +iphone telegram 新设备迁移 +------------------------------------------------------------- + +.. code-block:: shell + + 1. 新的 ios 设备上用 chrome 登录网页版telegram,可以选择扫描二维码登录。 + 2. 老的ios机器登录app->设置->设备->扫描二维码,此时新设备登录上网页版 + 3. 新设备左上角网页版设置->隐私和安全->Passkeys 点击创建,此时可以创建一个新的 passkey,且新设备会保存这个passkey。 + 4. 新设备重启一下app版本的telegram ,选择这个passkey登录即可 + Wireshark(mac tcp 抓包) ------------------------------------------------------------- @@ -1385,13 +1467,27 @@ Capture -> Options -> lo0 抓本地 127.0.0.1 包。筛选 tcp.port == 6379 抓 Niz/HHKB 静电容键盘。Karabiner 修改 mac 键位配置 ------------------------------------------------------------- +HHKB 静电容: + - HHKB 开关我只打开了 2 (mac 模式),貌似网上有说打开开关 6 会出现无法唤醒的问题。 - Mac 模式 HHKB 可以用使用 Fn+Esc 休眠。 -- 如何禁用内置键盘: Karabiner-Elements 同时可以禁用内置键盘,配置在 Devices -> Advanced, 勾选 Disable the built-in keyboard. +- 如何禁用内置键盘: Karabiner-Elements 可以在插入外置键盘的时候禁用内置键盘,配置在 Devices -> Advanced, 勾选 Disable the built-in keyboard. - 网易云音乐切歌:使用 Fn + 7/8/9 分别是上一首,暂停和下一首 -- Niz 键盘(Atom66)可以用 Fn+Option+Command 切换mac和win模式。左下角ctrl 右边三个键一起按闪灯两次即是 mac 模式 -- Niz 键盘如果感觉不灵敏了,可能是误调整了键程。niz66 可以通过 fn+7 调节,亮灯一下键程最短最灵敏 +Niz Atom66 静电容: + +- Niz 键盘(Atom66)可以用 Fn+Option+Command 切换mac和win模式。左下角ctrl 的右边三个键一起按闪灯两次即是 mac 模式 +- Niz 键盘如果感觉不灵敏了比如按键按下去有时候没有出来字符,可能是误调整了键程。niz66 可以通过 fn+7 调节,亮灯一下键程最短最灵敏 +- 如何锁定键盘? niz atom66 可以使用 Fn+Esc 临时禁用键盘(再次按下恢复),niz L84 在键盘 F1 位置上方边框有一个键盘锁按钮按下即可。 + +Niz L84 矮轴静电容: + +- Niz L84 键盘,有时候会误触 command+f1 导致外置显示器屏幕镜像,可以重新按一下恢复。 +- Niz L84 键盘,左空格失灵了。可以长按 Fn+左空格恢复。 "晓览外设" 可以关注公众号有niz宁芝键盘系列说明书。https://mp.weixin.qq.com/s/S8dpXg6h4WHEUFOPg4Kv5A +- Niz L84 键盘有线版除了自带的数据线,还可以直接用苹果的双头typec充电线使用 +- 如果键盘失灵了,尝试 Esc+左Ctrl+Delete+方向右键 (四角的四个键) 5 秒后重置。 +- L84初始化:``Fn+左Alt(左下角第三个) 同时按住三秒切到mac模式(状态等闪2次); Fn+\同时按住 3 秒切换 \ 和BackSpace`` +- L84 可以直接使用平台的双头 typec 充电线使用,甚至可以连接 iphone 手机使用 如何使用 mac 使用 Karabiner-Elements 改键配置 @@ -1407,3 +1503,36 @@ Niz/HHKB 静电容键盘。Karabiner 修改 mac 键位配置 这里我把 right_command + WASD 修改成上下左右,方便 HHKB 方向键移动,默认的 HHKB 方向键不方便。 目前键盘已经从 HHKB 切换到 niz 静电容 35 克,长期打字对小指头挺友好的,再也没疼过。niz支持切换键程,个人一般习惯切到最短的 键程打字比较顺畅,轻点一下按键就可以触发。 + + +Goland IDE +------------------------------------------------------------- +代码可以正常运行,但是打开项目飘红: + +- 可能是缓存已满。File->Invalidate Caches -> Invalidate and Restart +- 项目设置问题。设置->Go -> Go modules -> 勾选 Enable Go modules integration +- Mac M1 芯片 IDEA GoLand 卡顿解决方式。 Help -> 选择 Edit Custom VM Options 然后粘贴以下代码: + +.. code-block:: shell + + -XX:+UseNUMA + -Xms2048m + -Xmn2048m + -XX:MaxMetaspaceSize=2048m + -XX:ReservedCodeCacheSize=2048m + -Xmx8192m + -Dfile.encoding=UTF-8 + -XX:SoftRefLRUPolicyMSPerMB=500 + -XX:CICompilerCount=2 + -XX:+HeapDumpOnOutOfMemoryError + -XX:-OmitStackTraceInFastThrow + -ea + -Dsum.io.useCanonCaches=false + -Djdk.http.auth.tunneling.disabledSchemes="" + -Djdk.attach.allowAttachSelf=true + -Djdk.module.illegalAccess.silent=true + -Dkotlinx.coroutines.debug=off + -XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log + -XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof + -XX:+IgnoreUnrecognizedVMOptions + -Dide.no.platform.update=true AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル