列表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 的事情,服务端实现起来无比复杂,甚至无法实现。
所以其实图片编辑的操作一直以来都是由前端或者客户端完成的。但,任何客户端的用户行为其实都是不可信的,对于一个图像裁剪,如果接入审核流又会过于繁重。服务端处理在一定程度上能够解决这个问题,如果这个场景其实不会特别频繁的话。

clang-format使用记录

#前言

在团队协作上,代码的统一格式会让协作变得简单。
公司推荐用clang-format格式化proto文件,但格式化后的文档可读性很差,甚至“公司除了我没人在用”。

一番折腾,解决,记录之。

Mysql笔记

  • 服务器会为诸如 ALTER TABLE 之类的语句使用表锁,而忽略存储引擎的锁机制

#InnoDB 物理结构

Each space in InnoDB is assigned a 32-bit integer space ID, which is used in many different places to refer to the space.
InnoDB always has a “system space”, which is always assigned the space ID of 0.

Each page within a space is assigned a 32-bit integer page number, often called “offset”
page 0 is located at file offset 0, page 1 at file offset 16384

  • 页是最基础的 InnoDB 的概念,一般为 16kb。
  • 页一般由一个38 byteFIL header和一个8 byteFIL trailer组成。
  • FSP_HDR 和 XDES 是两种特殊的页,用来管理数据页。它们的区别在于,FSP_HDR 是第一个“管理页”,包含一些单独的信息。
  • 一个 FSP_HDR 或 XDES 会管理和它们连续分配的 16384 个页,256MB,或者叫 16 个 extent(16 块)。
  • FSP_HDR 和 XDES 由FIL headerFIL trailerFSP header和 256 个extent descriptorsXDES Entry)组成。

page

  • 一个XDES Entry管理64个页。

#参考链接