
在 Keyboard Maestro 的配置过程中,你可能希望某些命令只在特定的程序内生效,这个时候你可以选择将这些宏放置在一个特定的 Groups 里,并编辑这个 Group,设定 Group 为 Available in these applications:,并在其中选择你要生效的应用程序,就可以实现某些特定的宏只在对应的应用程序中生效,避免你定义的宏和其他应用程序冲突。
在 Keyboard Maestro 的配置过程中,你可能希望某些命令只在特定的程序内生效,这个时候你可以选择将这些宏放置在一个特定的 Groups 里,并编辑这个 Group,设定 Group 为 Available in these applications:,并在其中选择你要生效的应用程序,就可以实现某些特定的宏只在对应的应用程序中生效,避免你定义的宏和其他应用程序冲突。
我在写作时,会使用 aText 来做大量的文本替换,以提升输入的效率。但在 macOS 下,aText 常常会被 Secure Input 所阻塞,无法使用。这个时候你需要找到正在使用 Secure Input 的应用,并关掉它,不然你的 aText 始终无法启用。
想要找到它也非常简单,你可以执行如下命令,来查找开启了 Secure Input 的应用
ioreg -l -w 0 | grep SecureInput
找到对应的输入后,可以看到 kCGSSessionSecureInputPID
的 PID 值,比如我这里是 182,接下来可以执行如下命令来找到 PID 为 182 的程序到底是哪个
ps auxww | grep 182 #你在使用的时候,记得替换为你对应的 PID
Code language: PHP (php)
执行后可以看到红框的部分就是 182 进程。我这里是 macOS 自带的 Login Window。Login Window 只需要对系统执行一次锁屏 & 解锁,即可解开 Secure Input。如果你的是其他应用程序,则可以直接使用 kill PID
来关闭。
这本书里面是各种小技巧,如果你打算降低自己的开支,可以看一看
这本书我看了一半以后看不下去了,主要的原因是太水了。当成传记看还行,别的没必要。
绝大多数的人因为没有创办过公司,所以其实不太了解自己的工资的组成部分和企业付出的成本,甚至有很多人可能终其一生,都无法理解自己的工资薪金的组成部分。
最近刚好看到一个「中国薪资计算器」,借此机会,和大家聊一聊我们的工资的构成。
企业招聘一个员工是有成本的,你拿到手的现金 = 公司成本 – 公司承担的保险和公积金 – 个人承担的保险和公积金。所以,你到手的是一万块钱,但其实公司可能承担了不止一万块钱。
以天津为例,假设你一个月的税后收入是一万块钱,那么意味着你的税前收入是一万三千余元。差值的这三千余元,便是你自己缴纳的社保、公积金、个税的部分;而公司需要为你支付的整体成本,则是一万八千余元。差值的这五千余元,则是由公司承担的公积金和社保的部分。
一个详细的表单,可以参考下方的说明:
通过上面的表,你就明白了,为什么很多时候,企业主在招人上是十分肉疼的。企业主明明支付了 138% 的成本,但因为各种保险和公积金,真正到员工手里的只有 75% 了。
在一些劳动密集型行业当中,员工们往往喜欢不走社保,不打卡里,而是通过现金发放,也是希望规避掉公积金和各种保险。虽然可以减少保险和公积金的支出,但另一方面, 也致使劳动者失去了相应的保障。得不偿失。
如果你希望提升自己的税后收入,还是积极提升自己,让自己成为一个更贵的人吧。
总的来说,我还算是一个比较喜欢追求简单的生活的人。
虽然我依然会喜欢出门去吃饭(懒得自己做,或者是想吃的确实自己做不好,比如烤鱼),但不妨碍我其实在大多数时候只要能吃饱就行;
虽然我依然喜欢买买买,但不妨碍我大部分时候其实都不用我买的东西(这也是为啥近几年我开始疯狂断舍离),更多的时候,都是拿着之前买的东西,重复使用。
我们需要保持一个简单、干净、平静的生活,这样的生活方式让我们可以有充足的时间投入在我们想要做的事情当中,让我们可以专心专意,投身创作。
让自己的物质生活变得简单,让自己的精神生活变得丰富,才是我们应该追求的内容。
在我数十年的编程生涯里,我大部分时间写的都是动态类型语言,所以我对于类型并不太感冒。不过,当我在写 Golang 的时候,确实遇到了一些过去写 PHP、 Node.js、前端不同的问题。
一个最令我困扰的点便是:对于 JSON 的处理,需要先定义结构体来做转换。对于一些简单的 JSON 结构,我还可以简单的完成定义。但如果是一些比较复杂的结构体,我就放弃了手动定义,而是选择借助一些辅助工具来完成
比如我最常用的便是各种 JSON to Go 的网站,贴一个 JSON 进去,然后自动生成对应的 Golang 的 Struct,接下来我只需要复制右侧生成的 Struct 到我的代码里,就可以完成 JSON 的定义,使用 Golang 自带的 JSON 库解析即可。
截图的网站是 https://mholt.github.io/json-to-go/
另外一个可以实现 JSON 转换成 Go Struct 的网站是 https://transform.tools/json-to-go,它提供了更加全面的转换路径。不过有些时候选择太多也会让我有点困惑。
另外一个令我困扰的也是类似的格式转换,不过是 YAML 的。思路相同,手写要配置的 YAML 文件,并生成对应的 Struct: https://zhwt.github.io/yaml-to-go/。在设计风格上,和上面的 JSON2Struct 类似,是基于上面的项目改造过来的。
除此之外,如果你在定义 YAML 的时候, 对于部分数据如何定义不太明确,可以考虑使用 JSON2Yaml 的工具来实现将你需要的数据转换为 YAML 定义。
自 Go 1.16 版本开始,Go 提供了将二进制文件打包进入到 Binary 文件当中的机制:`//go:embed
。不过,我看到的示例大多数都是嵌入当前文件夹下的子文件夹的示例。并没有嵌入父一级文件夹的示例。于是,我便开始研究起来。
这是因为不同的项目的构建规则不同。一些小型项目可能只有一个 main.go
或同级目录下几个其他的 go source 文件即可,但对于更大型的项目,合理的项目拆分是有助于帮助提升项目的可维护性的。
以我为例,我的目录结构如下:biz 目录下是我的核心逻辑,也是我日常写代码的地方;conf 则放置了各种配置,比如各种 API Key,ral 则是网络访问层,比如我比较喜欢用 gin 来做底层的网络访问层;script 放置了开发所需要的各种脚本文件;static 则放置了前端所需要的 JS / CSS 文件。在开发一些偏内容向的页面时,我会习惯使用 Server Side Render,所以我在 biz 目录下还有一个 template 目录。而主要的逻辑则放在 handler。
├── biz
│ ├── dal
│ ├── handler
│ ├── logic
│ ├── service
│ └── template
├── conf
├── ral
│ └── gin
├── script
└── static
└── public
Code language: PHP (php)
在日常开发时,一个非常常见的操作是在 handler 里处理基本的逻辑,并将 template 中的模板渲染出来,并返回给用户,这个时候就需要在 handler 里使用上一级目录的文件了。
..
来引入作为文件系统的常规配置,我自然知道可以通过 ..
来代表上一级目录,因此我试着使用如下的语法来引入文件
//go:embed ../template/*
Code language: JSON / JSON with Comments (json)
结果报了个错误 invalid pattern syntax
。看得出来,是因为我的语法出现了问题。
通过搜索,我找到了这个 Github issue,才得知,由于避免跨模块的访问,go embed 阻止了 ..
语法的使用
Because embed.Files implements fs.FS, it cannot provide access to files with names beginning with .., so files in parent directories are also disallowed entirely, even when the parent directory named by .. does happen to be in the same module.
https://go.googlesource.com/proposal/+/master/design/draft-embed.md
go:generate
来执行复制在上面的 issue 当中,我注意到还有另外一个方式,可以实现类似的效果。可以借助 go:generate
来实现在执行 go generate
方法时,复制文件到本地,这样就可以实现在 Build 二进制文件之前,把文件复制到本地,即规避了跨模块的问题,也避免了将 template 文件放在本地,污染代码目录的问题。
//go:generate cp -r ../../assets ./local-asset-dir
//go:embed local-asset-dir
var assetFs embed.FS
Code language: JavaScript (javascript)
这个方法在运行的时候没有效果,不过在其他人可能是有效果的(我猜是因为我开发时很少直接用 go generate,都是直接 go run 了)。不过,这个方法也有个问题,因为是写在代码本身当中的,很有可能后续因为某些原因,这些代码被误删除或修改了,导致整个系统的运行不正常。而散落在各文件的描述也会使得修复十分复杂。
在看这个 issue 的最后,我注意到了正确的用法,在另外一个 issue 当中,开发者 tomasf 提到了,我们应该在 asset 目录下创建一个 embed.go 来完成 embedFs 的建立,并在其他文件直接引入这个文件,完成定义。
You can create a embed.go file in your assets directory and make the assets available as it’s own package to the rest of your program.
tomasf
这个说法一出,豁然开朗!尝试一下,果然有效。我在 template 目录下创建了一个 embed.go
文件,并添加了如下代码。
package template
import "embed"
//go:embed *
var TemplateFs embed.FS
并在另外一个文件当中使用template.TemplateFs.ReadFile("index.tmpl")
来完成模板文件的引用。这样既不违背 golang 的跨模块,也不会使得代码不可维护,非常好。
老后破产 + 老后两代破产,看的人心烦,也让人想起了自己的养老和父母的养老。