列表2023-week50

#最近读的东西

#你真的知道如何设置数据库连接池的大小吗

#Go 函数指针是如何让你的程序变慢的?

#Go 1.22 中的 For 循环

#Go1.21 速览:Context 可以设置取消原因和回调函数了,等的可太久了!

列表2023-week49

#最近读的东西

#自己的一些项目该如何组织

#github 仓库拉取优化

背景是neovim的插件都在 github 上,大陆拉不下来。

解决方案:全局配置 Git 使用 SSH

1
vi ~/.gitconfig

加入 👇

1
2
[url "git@github.com:"]
insteadOf = https://github.com/

#https 证书

阿里云免费的证书有效期变成 3 个月了= =

免费方案 👆

#快速 csv 文件处理

为压测准备数据

  1. 从源数据中选取指定列作为待选数据:
1
cut -d',' -f6 raw.csv > res.txt
  • -d指定分隔符
  • -f指定选的列,比如我只要第 6 列数据
  1. 拆分数据集合:

因为我的数据从 100 个表取出来的,然后需要分成多个数据集合,我选择的第一种方法是把奇数行和偶数行拆分成两个文件(假设数据集只需要 2 个)

1
awk '{if (NR % 2 == 0) print > "res_1.txt"; else print > "res_2.txt"}' res.txt
  1. 打散数据:

因为数据是按尾号聚合的数据,具有不均匀性,需要打乱。

1
2
shuf res_2.txt  > res_2_suf.txt
shuf res_2.txt > res_2_suf.txt

感觉 chatgpt 出来之后,笔记已经显得不那么重要了= =

列表2023-week48

#最近读的东西

#1

排序的稳定性,之前还真没关注过= =

#2

#3

验证了很久,一个 redis 的分布式读写锁,在脏缓存的情况下会发生问题,其它 ok

列表2023-week45

#最近读的东西

#1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Usage: paste [OPTION]... [FILE]...
Write lines consisting of the sequentially corresponding lines from
each FILE, separated by TABs, to standard output.

With no FILE, or when FILE is -, read standard input.

Mandatory arguments to long options are mandatory for short options too.
-d, --delimiters=LIST reuse characters from LIST instead of TABs
-s, --serial paste one file at a time instead of in parallel
-z, --zero-terminated line delimiter is NUL, not newline
--help display this help and exit
--version output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report paste translation bugs to <http://translationproject.org/team/>
Full documentation at: <http://www.gnu.org/software/coreutils/paste>
or available locally via: info '(coreutils) paste invocation'

paste1.txt:

1
2
1 2 3
4 5 6

paste2.txt:

1
2
a b c
d e f
1
2
3
4
5
6
$ paste paste1.txt paste2.txt
1 2 3 a b c
4 5 6 d e f
$ paste -s paste1.txt paste2.txt
1 2 3 4 5 6
a b c d e f

把 N 个文件按列合并

#2

有点难

列表2023-week44

#最近读的东西

#1

Mysql 官方文档

With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values. If you specify the CLIENT_FOUND_ROWS flag to the mysql_real_connect() C API function when connecting to mysqld, the affected-rows value is 1 (not 0) if an existing row is set to its current values.

在用upsert语句时,标准的返回值是 1 插入、2 更新、0 无影响。

In assignment value expressions in the ON DUPLICATE KEY UPDATE clause, you can use the VALUES(col_name) function to refer to column values from the INSERT portion of the INSERT … ON DUPLICATE KEY UPDATE statement. In other words, VALUES(col_name) in the ON DUPLICATE KEY UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred.

VALUES() 在上述语句的后面的时候,语法从来没见过,是存在歧义的,是代指数据库里的值还是插入语句中的值。

1
2
3
4
5
6
7
8
9
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

-- 等价于:

INSERT INTO t1 (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=3;
INSERT INTO t1 (a,b,c) VALUES (4,5,6)
ON DUPLICATE KEY UPDATE c=9;

An INSERT … ON DUPLICATE KEY UPDATE statement against a table having more than one unique or primary key is also marked as unsafe. (Bug #11765650, Bug #58637)

当一个表中有多个唯一索引时,同时使用upsert的结果是不确定的,只会更新随机一个。

#2

在开发时经常会出现 int 与 string 相互转换的场景,所以从int64转换成interface{}的时候,到底发生了什么 👆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
"strconv"
"testing"
)

func BenchmarkInterfaceConversion(b *testing.B) {
num := int64(123)
var result int64

b.ResetTimer()
for i := 0; i < b.N; i++ {
interfaceNum := interface{}(num)
result = interfaceNum.(int64)
}

_ = result
}

func BenchmarkStrconvConversion(b *testing.B) {
num := int64(123)
var result int64

b.ResetTimer()
for i := 0; i < b.N; i++ {
str := strconv.FormatInt(num, 10)
result, _ = strconv.ParseInt(str, 10, 64)
}

_ = result
}
1
2
3
4
5
6
7
8
 [2023/11/03 13:11:15] mbp ➜  ~/Downloads/workspace/ct  go test -bench=. conv_test.go
goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
BenchmarkInterfaceConversion-8 1000000000 0.4254 ns/op
BenchmarkStrconvConversion-8 23592367 52.78 ns/op
PASS
ok command-line-arguments 2.849s

#3

为什么对 map 的访问,接了一个参数就不会 panic,还没找到资料

1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
"fmt"
"testing"
)

func TestHelloWorld(t *testing.T) {
var m map[string]string
v, ok := m["o"]
fmt.Printf("value:%+v ok:%+v\n", v, ok)
}
1
2
3
4
5
6
 [2023/11/03 13:21:49] mbp ➜  ~/Downloads/workspace/ct  go test -v -run . map_test.go
=== RUN TestHelloWorld
value: ok:false
--- PASS: TestHelloWorld (0.00s)
PASS
ok command-line-arguments 0.290s

Neovim配置相关

#为什么用 Neovim

Goland项目开多了之后编辑起来太卡了,严重影响了开发效率,所以只能换编辑器。同时 Neovim 可以允许你远程操作,有时候救急会很重要。

neovim笔记

#移动

1
2
3
4
5
6
7
8
9
10
# 下移半页
ctrl d
# 上移半页
ctrl u
# 移动光标到中心
zz
# 向上移动屏幕
ctrl e
# 向下移动屏幕
ctrl y

#编辑

1
2
3
4
5
# 撤销
u
# 恢复撤销
ctrl r
# 剪切

#调试

#断点

#其它

1
2
3
4
5
6
7
8
# 挂起nvim
:sus
:suspend
# 从挂起中恢复
$ fd
# 窗口交换
# 与下一个
ctrl + w + x

golang图片处理

#前言

不得不感慨,前端的发展迅速以至于我觉得在前端样式下一小段 css 的事情,服务端实现起来无比复杂,甚至无法实现。
所以其实图片编辑的操作一直以来都是由前端或者客户端完成的。但,任何客户端的用户行为其实都是不可信的,对于一个图像裁剪,如果接入审核流又会过于繁重。服务端处理在一定程度上能够解决这个问题,如果这个场景其实不会特别频繁的话。