mac使用cLion调试redis

想更深入的了解redis的底层实现,当然看源码是必不可少的。 redis是c语言开发的,因此如果需要本地运行调试,就需要相关的c语言编译运行环境。 我们可以选择vscode + 相关插件,也可以选择cLion等ide去处理。基于对JetBrains家族的信任,我选择的是cLion。 C环境依赖检测 ~ whereis g++ /usr/bin/g++ ~ whereis gcc /usr/bin/gcc 如果没装过gcc等C语言环境,则可以通过命令安装 ~ brew install gcc 下载cLion jetbrains官网可直接下载,不过是试用版 https://www.jetbrains.com/clion/ 目前最新版本 cLion 2021.3 版本开始支持 Makefile 的项目了,所以并不需要额外的将makefile转成cMakefile, 所以就不太需要折腾啦 查看clion的环境是否正确 下载redis 直接从github上克隆仓库 ~ git clone https://github.com/redis/redis.git 将项目导入到clion中 导入项目时会提示是否trust project,选择trust project。 是否 clean 项目,选择 clean 即可. 打开 Makefile 并运行 配置redis-server运行选项 点击工具栏右上侧的运行按钮,启动服务 参考文档 https://www.modb.pro/db/73281

March 9, 2022 · nobject

Redis Sds 简单动态字符串

March 9, 2022 · nobject

Goland 设置

go imports go的导入包的顺序有时候挺影响查阅导入的是哪些包的,而一个文件的最头部就是imports,因此看一个文件的头部,如果杂乱无章,心情就不那么美好。 安装goimports包 go install golang.org/x/tools/cmd/goimports@latest 文件发生改变时,调用goimports来自动排序我们的import包的顺序 goland > preferences > file watchers > + > goimports 设置import的包顺序排序规则: goland > preferences > editor > code style > go > imports 可根据规范或自己的习惯进行设置 http://cdn.huasay.com/1646791777936.png golanglint-cli 代码中往往会出现一些未处理的error,一些拼写错误,一些优化建议,那么配置golanglint是个不错的选择。 安装go linter插件: plugins -> go linter 安装golanglint-cli go install github.com/golangci/golangci-lint/cmd/golangci-lint file watcher 添加 golangcli-lint 并可对file watcher进行配置

March 3, 2022 · nobject

Golang Function Optional 功能选项

在看uber的golang最佳实践时,如果初始化一个结构时,在功能迭代中,初始化的参数不断地增加或改变,怎么才能让初始化结构变得可扩展。 uber提出的解决方案是功能选项。 几种备选方案 横冲直幢型 这是初学者最容易做到的,也是最不理想的,当我们每添加一项,就起一个新的初始化方法 type HttpServer struct{ Host string Port string } func NewHttpServer(host, port string) *HttpServer{} 当功能需要我们http服务器能同时支持tls时, 我们可能就换成以下写法 type HttpServer struct{ Host string Port string Cert tls.Cert Timeout int32 } func NewHttpServerWithTls(host,port string) *HttpServer{} func NewHttpServerWithTimeOut(host,port string, timeOut int32) *HttpServer{} 这种写法是没有任何扩展性可言的,当加入更多的配置选项,比如maxConn(最大并发连接数)等,导致针对不同的配置项,都可能产生一种组合,这种方式明显不太可取 没有一个config解决不了的事 显然,上面的方法太不灵活了,只适用于基本不动的配置处理,对于可能新增的选项,修改起来就是灾难。 当然,我们可以用万能的config作参数。 type HttpServer struct{ Host string Config *Config } type Config struct { Port string Cert tls.Config Timeout int32 } func NewHttpServer(host, &Config{ Port:8888, })*HttpServer 每次有新的配置加入时,我们可以直接塞进config选项中,这样,我们只需要根据不同的传参来解决扩展性问题。...

March 1, 2022 · nobject

搬家记

换了公司之后,离原先租的房实在太远,每天早晚通勤时间在1个半小时,来回3小时,也是累的够呛。工作也繁忙, 有时候会加班到很晚,回到家已是10点11点, 疲惫的一天,为了让自己更舒坦点,更希望能够找个离公司近的房子。 能捡漏么? 租房市场的乱相 都说年底租房可以捡漏。也不知道是不是真的,但年底的房源应该相比是会少点的。 从自己的找房经历来说,是否能捡漏? 答案: 不一定 本次找房接触过中介,个人转租,豆瓣,还有其他的途径。 锁定目标 时间:离公司通勤40分钟内都可以接受,在经历过1个半小时的通勤时间,竟然觉得40分钟也是种享受了。 地点:地铁站1公里以内,当然越近越好。总地铁站数不能超过8站。 房子:可合租独立,可一室户,可两户合租,可以养猫。 房在哪找 链家,我爱我家,中原地产等中介产品,链家适合找1室户,因为价格真实,可以作为参考依据,相比其他的中介,这些更有知名度,门店更多,房源更多,更靠谱点 缺点就是要50%的中介费,这些如果算在预算里,也是不小的一笔费用。 豆瓣租房小组,目前里面也是鱼龙混杂的,大多数都是中介与二房东占领,而且很能伪装。所以这里面想找些个人房源,其实也很难。最后加微信发现的其实都是房产中介/房产经理。当然眼光好点的可以找到个人转租房源 巴乐兔,二房东集中营,好处是不需要自己额外付中介费。之前的设计很不合理,一点开房子就有房产经纪来加微信。后面好像是改成让客户加了,更合理一点了 知乎,微博,贴吧等,不用试了,连人理都没有,直接放弃。 58同城,虚假房源集中营,价格假,房源架,好牌打烂自己作死的一个平台,尽管推出来个人房源,之前体验过也是假的,而且还会骗你到大老远,主动问他们是真是假,还不承认 什么微信公众号,适我家等,其实体验很一般,基本上没符合需求的。 找房历程 我爱我家小哥带我找一室户,看了一些图片,我说不喜欢的,但当天也带我去看了,可能他觉得来了都来了,可以都看看,我是觉得我连图片都不喜欢了,就不需要看了,省时省心。其实看中了一套3800的,我的预算是3500,显然我是想让他给我谈下价格的,结果也没谈下来多少,一般我认为挂牌价至少得谈下来200,最终谈下50,也是没办法 二房东,假房源骗去,说二楼刚10分钟之前被租,问我要不要看下一楼的,一楼的实际上连隔都没隔出来,这还租个毛,我觉得有点诚意的应该房间至少成型吧。另一个二房东,看的几间房子,说实话我心动了,但我还是介意房间隔音,实际上我感觉隔音也行,但更喜欢那间实体墙的。后面因为他没联系我,也没主动说降价,我也放弃了。 转租房源两套,都不错,一套室友人很好,装修也好,但6楼,搬家可能要命吧。另一套在1楼,房间还行,室友没见到,价格更便宜,离公司更近,其实两个方面的比较,最后还是选择了更便宜的。当然我是希望第一套的室友能够降点价,说也挺想租给我这种话的,表达了自己想租的欲望之后,对方也挺风轻云淡的,我觉得就是对室友没有很满意,也没有觉得很不好,我是个感性的人,需要别人的肯定。 搬家小记 确定了房间之后,就轮到搬家了,搬家是累人的,特别是只能自己搬的情况下,打包了很多东西,大概有8个纸箱+3个行李包+自行车,原住址有两级台阶,不过还好, 毕竟还算是个电梯房了。新地址是个一楼,我觉得如果再多一楼,我可能当天就趴下了。搬家小哥也是疲劳驾驶,一直在念叨着自己很困,这种驾驶让我有点担心,但所幸最后安然抵达。 对于猫,我觉得我很生气,它觉得它很郁闷。我拆了猫爬架,扔了;我把它装进背包里,它挣扎;在它们的世界里,我是个恶人吧。事实上,我忙得心情很复杂,我给它包里拉开了点缝隙,这是导致它最终跑出去的来源,最后它从窗户中翻出去了,我挺郁闷的,在搬家小哥在楼下等了10分钟之后,我放弃了它,我觉得它给我带来了很大的负担。第二天,房东和我说它在空调外机旁,我也去了,想方设法让它回来,但是它没有选择回来,我觉得那一刻起,这个世界上,不管是我抛弃它,还是它抛弃我,只能各自安好。尝试了所有方法后,也是无奈了,最后用猫叫声想吸引它回来,但失败了,它朝反方面头也不回的走了,那是对我的一种打击。我抱着一丝希望它能回头,或者能到隔壁室友房间里去,等了整整一下午,那点希望破灭了。我觉得我白养它两年了,至此恩断义绝,我不可能再回去找它了,我有自己的生活需要过,那是它的选择,或流浪,或被领养,都是它的命,与我无关。 在新房间,与新室友没见过面,自己有点说不出来的滋味,与人相处是种学问。不一定能相处好,但希望能够好好的相处,做好朋友。

January 24, 2022 · nobject

Git Reset hard后的恢复

缘于某次手贱,利用git工具的时候,没注意,直接用reset hard的方式将之前提交的内容给reset掉了,这直接导致了这一部分提交的内容直接丢失。 那么怎么才能恢复这些commit呢。也找了一些教程,大致可以使用以下几种途径去处理。 git reflog git reflog 命令读取本地的最近的操作记录,我们可以找到reset前的最后一次提交的commit。 可以看到,reset操作之前提交了两次,我们选取最近的一次commit:fbcf5ad git reset --hard fbcf5ad 执行上面命令后,发现又回到了最后一次提交的commit上了,也算是完美的恢复了。 对于已经commit的分支,都推荐使用这种方式恢复 git fsck –lost-found 使用该命令也可以查找到对应的悬空的commit(dangling commit),同样可以使用git reset或者git cherry-pick等命令恢复。 对于已提交的,使用该方式去恢复显然没有使用git reflog更直观 但对于未提交但已add的内容,git fsck --lost-found 也是有可能帮助恢复的。 我们通过git fsck --lost-found查看到的内容不仅能查看到悬空的commit,还能查看到悬空的blob(dangling blob), 而这些blob的内容实际就是我们未提交的内容,我们可以通过 git show 00bcb6e3738c7392875d6c3e65c22d569eaff069 的方式去读取到该blob对应的内容。 使用 git show 00bcb6e3738c7392875d6c3e65c22d569eaff069 > lost_file 的方式去将内容保存至丢失的文件中。 这样我们就可以将这些文件一个个恢复,当然过程是繁琐的。 总结 尽量少使用git reset --hard 命令,一不小心可能让你头脑崩溃 如果使用了该命令,却又想找回,commit过的直接使用git reflog命令找回,所以阶段性的commit是种好习惯 如果未commit过的,只能使用git fsck --lost-found尝试恢复,少量的文件还是容易恢复的,但大量的文件恢复也会让你疯狂。 未add过的文件很难恢复,所以如果有大量文件修改,最好还是阶段性的add或者commit 参考文献 https://mp.weixin.qq.com/s/58W1ljewwvextw05_OKE1w https://www.wencst.com/archives/470

January 24, 2022 · nobject

golang 结构体复制库 Copier

在一些业务场景下,两个不同的结构需要赋值,他们大部分字段是相同的,只有少部分不同,而字段又很多,有几十个,通过 手工的赋值就会觉得代码量很多,而且也不算是很有意义的工作。因此,这个场景下可以使用copier库来复制一些相同的字段 减少手工复制的处理。 下面是一些小场景下使用copier库,以防踩坑 type Copier1 struct { Name string Age int32 Hobby string } type Copier2 struct { Name string Age int32 } type Copier3 struct { Hobby string } v1 := &Copier1{Name: "zs", Age: 20} v2 := &Copier2{Name: "ls", Age: 30} copier.Copy(v1, v2) fmt.Printf("%#v\n", v1) // 会将v3置为默认值 v3 := &Copier1{Name: "zs", Age: 20} v4 := &Copier2{} copier.Copy(v3, v4) fmt.Printf("%#v\n", v3) // 将一个nil值的内容复制到v5,并不会将v5置为nil v5 := &Copier1{Name: "zs", Age: 20} var v6 *Copier2 copier....

January 13, 2022 · nobject

2022年

2021年是怎样度过的,有点苦涩,有点累,有点不舍。 2021年是非常特殊的一年,疫情当前,甚至都没回家过年。异地过年,草草地应付下,买了点火锅食材,也算丰盛了,临时用箱子搭了个小桌,在出租房里独自过了一年。 2021年,已过而立之年,催婚的压力毫无意外的大,但却无法真正的找到互相有点心灵相通的对象,事实上,我还是觉得单身好,也因此与父母冷战。 2021年,应该理论上已经刷新了全年去医院的次数,日常的配药,因为吃鱼被卡喉,因为脚上起鸡眼,因为身体的里面疼痛,这些都让我痛苦无比,却又不得不进医院。 2021年,换了工作,其实是想提早换的,但无奈一直以自己没准备好为借口没出去找,纠结,犹豫。对于原工作,不开心是因为绩效的问题,还有被大佬的压迫感,绩效给我打C因为嫌我活少,离职又扣绩效,这点我忍不了。 我觉得,对于一家公司以价值观为利他心的,最后一直都在利己,都有点谈不过去了,空谈口号又有什么意思呢。对于新公司,说实话,有点累,有点失望,但不后悔换了工作。 2021年,工作的调整,也带来通勤的时间非常长,基本上在1个半小时左右,这让自己身心俱疲,因此在年末也是找了离公司近的一间合租房,相比于合租需要与人相处,不知道之后相处会怎样。 2021年,开始玩基金,嗯,从年初到年底,好像玩了个寂寞。 2022年,希望能够身体健康,能够有份不错的工作,能够开心,能够拥有友谊

January 13, 2022 · nobject

Grpc Int64的坑

在使用grpc的时候,proto的类型定义成int64,但结果展示却显示成string类型。刚开始还纳闷客户端说文档上定义int类型,为啥不和文档统一呢? 自信的我坚定的回答我定义的就是int类型的,统一的很。然后模拟完接口请求,打脸来得真快。 问题复现 定义proto文件 // 音乐搜索项 message PartyMusicSearchItem { string name = 1; int32 fileSize = 2; string author = 3; string musicId = 4; int32 type = 6; int64 createdAt = 7; int64 lastTime = 8; } 返回值: { "author": "张碧晨", "createdAt": "1640157765000", "fileSize": 10907, "lastTime": "1640157765000", "musicId": "61c2d2459a01c38927334b03", "name": "年轮", "type": 0 } 我们看到返回值中createdAt与lastTime已经变成是string类型的。 究其原因 翻阅proto的文档,可以看到,其实官方已经定义了某些类型及对应的返回值。明确的定义了int64类型的返回值是string. 但官方为什么这么做。其实是和javascript中number的实现有关,javascript中的number的最大精度是2的52次方,如果超过该数, 就会缺少精度。因此,grpc的处理方式是将int64处理成string类型。 github上相关issue的一个解释: https://github.com/protocolbuffers/protobuf/issues/8331 这是另一个解释,本质上是和上面的一样的,因为中间会将proto文件转换成json,而json是基于javascript的标准的。因此,int64是不属于这个标准的,在这个标准体系里,int64会丢失精度。 https://github.com/golang/protobuf/issues/1280 解决方案 个人感觉只要使用json作为通信协议就无解,使用其他方式的通信协议就可以规避。但目前来说,json的通信协议还是最普遍的,因此也只能这样。 当然这个json不作为前后商通信,只是在同个项目里流转,比如golang,就可以使用json.NewEncoder相关的方式去处理。 参考文献 https://developers.google.com/protocol-buffers/docs/proto3#json https://github....

December 27, 2021 · nobject

Golang Defer

December 12, 2021 · nobject

redis lua 脚本运行工具

测试环境中,redis使用的是阿里云的rds,目前是没有权限运行redis-cli这种命令。如果对于lua长脚本,官方是推荐使用redis-cli去加载script然后运行的。 针对这样的环境,如果我们需要调试复杂或有不少逻辑的lua脚本,怎么调试? 一是直接用代码,调用端改代码调试,因为现在改代码不太方便,每次都要部署测试环境。 因此在想有没有更容易的方式,我们是有权限登录redis的,只是没有redis-cli的执行命令而已,因此我们还可以选择eval script …的命令去执行。 但是script脚本很长,这时候我们可以借助压缩工具去处理。 其实说来说去,就是得找个lua脚本的压缩工具。 工具1:Lua 压缩器 工具2:vscode + Lua Minify 插件

December 6, 2021 · nobject

Golang 多条件下的switch

在业务场景下,如果有多条件,怎么处理? 比如条件isModifyName是否修改姓名,条件isModifyAge是否修改姓名。 我们可以使用if else来拼凑出4个条件,那么怎么使用switch case呢,switch case是比if else效率高的,可读性也更好,所以在条件多于2个的时候,会优先选择switch case。 方式一: case相当于一个if isModifyName := 1 isModifyAge := 1 switch { case isModifyName == 0 && isModifyAge == 0: fmt.Println("all not modify") case isModifyName == 1 && isModifyAge == 1: fmt.Println("all modify") case isModifyName == 0 && isModifyAge == 1: fmt.Println("age modify") case isModifyName == 1 && isModifyAge == 0: fmt.Println("name modify") } 方式二: 我们可以巧妙地使用位运算来处理多个条件,将多个值融合成二进制的值,然后可以很容易的拼凑出来4个条件 isModifyName := 1 isModifyAge := 1 modify := isModifyName<<1 + isModifyAge switch modify { case 0: // 都未修改 fmt....

November 25, 2021 · nobject