#2025 年 1 月事记

#markdown 格式修正

之前为了修复部分内容在 web 上的展示,使用了很多特殊的特性,比如<center>,比如不指定 http/https 协议。

为了在许多 markdown 工具中获得一致性,最好的方案其实是只使用官方推荐的少量语法。

#obsidian 脚注

obsidian居然不支持脚注,试了很多插件也没搞出来= =

#kitty

linux 下命令行从 alacritty 换成了 kitty,只能感叹怪不得广大 arch 用户都喜欢用 kitty。

  1. 字体渲染平滑,整体界面更好看。对于 neovim 用户特别友好。
  2. 支持命令行内显示图片。这个含金量就不用说了,基本上大家的工具链中都会有yazi,配合起来更舒服。
  3. 会有明显的感知,terminal 的启动时间变慢了,但是如果你是一个 mac+zsh 或 win+zsh 的用户,这个启动时间依然是比另两个场景下快的。

至此,已经走过了和很多人相似的terminal->item2->alacritty->kitty的链路。

#SwissTable

在进行哈希表的冲突解决时,通过拉链法是一般默认的实现方式。线性探测方法在删除的时候不能立即将状态标记为空,因为在查询时,依然需要跳过这个“坑”向后查询。所以只有查到第一个空的地方才能判断不存在。线性探测对于同一个插入 slot 有三种状态,占用、空闲、删除。

#jq

修数据需要对 json 进行处理,基于正则替换或字符串替换的方案在处理 json 转义的时候风险太大了,故记录基于语法解析的jq方案。

jq 本身有教程:https://jqlang.github.io/jq/tutorial/,可自行学习。

根据测试,jq 可以将多个 json 逐个进行解析并输出。

假设有个原始文件:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
{
"sha": "31dac287cce2d15357c3b78a90009007e9c21493",
"node_id": "C_kwDOAE3WVdoAKDMxZGFjMjg3Y2NlMmQxNTM1N2MzYjc4YTkwMDA5MDA3ZTljMjE0OTM",
"commit": {
"author": {
"name": "itchyny",
"email": "itchyny@cybozu.co.jp",
"date": "2025-01-25T23:08:31Z"
},
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"date": "2025-01-25T23:08:31Z"
},
"message": "tests: quote `.[]` in shtest which can break syntax highlight (#3235)",
"tree": {
"sha": "b4b70ee5f6da8bb0b9c4ecf4a1e33204900fb239",
"url": "https://api.github.com/repos/jqlang/jq/git/trees/b4b70ee5f6da8bb0b9c4ecf4a1e33204900fb239"
},
"url": "https://api.github.com/repos/jqlang/jq/git/commits/31dac287cce2d15357c3b78a90009007e9c21493",
"comment_count": 0,
"verification": {
"verified": true,
"reason": "valid",
"signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJnlW7vCRC1aQ7uu5UhlAAAC7wQAFs4sp09TXKfcrJ8/yb4bX57\n1x+f54OPixKexRw7cOjMMdN/3yPmr0KkgNFmnIcRk3Un5J0tpim3hokCVhgjaRZC\nOE2XtEomF/9Chm8ZIaE50E3EA01S0XyLiGeCGYN7CKV5mlJIZ42asu4a1kPe0qq7\nKpMNJq0HB3OWbynePu7azfBEiWtYPiZ+GDmPcg4Xt5kNZJJe/cwugy2+Wo3DBZ3V\n5Z3mWEqGy+s4MTRVNNmRNvCKyWsQ7mPMNMPaQ+W2BVZmC/g/mhYTiI9eQfM9rinf\nhlQua4M5oUvvRbUaWlMqrx/tNj0CTrZkTPAGX9gxe6QFcDDcVCn3TPNICYSbjjMn\nhc5UEy+HnO2Zi8/4lRgv2+XgY6OiiVrfdywRGBKm5sOqjDkdFB5RA3fbKaWwa+JQ\n9GMFVUEXqPDK9/DK/hoFlNobRIfXLXL8Xk0D7ryQylKprKz79Z2sgnvUnhLX9zUr\nam7TLdPy1uiNGcjVOop8yN1UHHPbqhSJiAmNae6xvE2BokeyzMyb6KMwc+uylhP+\niev/NsvzaA4ykeuKp79Mk6dyS8QlvP5UT9F/hBHk5kvuRuzaCOUYr4U4rhvK9swy\nu+mlMrFRD9w85UVcoU05LRPxdnoIA8OmvnmUTQfSW9rxgsoIMNtHFgOpJz4+jJ+A\n9Ued6vxHgIIhAizgWzKr\n=6PxT\n-----END PGP SIGNATURE-----\n",
"payload": "tree b4b70ee5f6da8bb0b9c4ecf4a1e33204900fb239\nparent 562ffec8696d522d1854f6e42c4a540ae85b3fad\nauthor itchyny <itchyny@cybozu.co.jp> 1737846511 +0900\ncommitter GitHub <noreply@github.com> 1737846511 +0900\n\ntests: quote `.[]` in shtest which can break syntax highlight (#3235)\n\n",
"verified_at": "2025-01-25T23:08:35Z"
}
},
"url": "https://api.github.com/repos/jqlang/jq/commits/31dac287cce2d15357c3b78a90009007e9c21493",
"html_url": "https://github.com/jqlang/jq/commit/31dac287cce2d15357c3b78a90009007e9c21493",
"comments_url": "https://api.github.com/repos/jqlang/jq/commits/31dac287cce2d15357c3b78a90009007e9c21493/comments",
"author": {
"login": "itchyny",
"id": 375258,
"node_id": "MDQ6VXNlcjM3NTI1OA==",
"avatar_url": "https://avatars.githubusercontent.com/u/375258?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/itchyny",
"html_url": "https://github.com/itchyny",
"followers_url": "https://api.github.com/users/itchyny/followers",
"following_url": "https://api.github.com/users/itchyny/following{/other_user}",
"gists_url": "https://api.github.com/users/itchyny/gists{/gist_id}",
"starred_url": "https://api.github.com/users/itchyny/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/itchyny/subscriptions",
"organizations_url": "https://api.github.com/users/itchyny/orgs",
"repos_url": "https://api.github.com/users/itchyny/repos",
"events_url": "https://api.github.com/users/itchyny/events{/privacy}",
"received_events_url": "https://api.github.com/users/itchyny/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"committer": {
"login": "web-flow",
"id": 19864447,
"node_id": "MDQ6VXNlcjE5ODY0NDQ3",
"avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/web-flow",
"html_url": "https://github.com/web-flow",
"followers_url": "https://api.github.com/users/web-flow/followers",
"following_url": "https://api.github.com/users/web-flow/following{/other_user}",
"gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
"starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
"organizations_url": "https://api.github.com/users/web-flow/orgs",
"repos_url": "https://api.github.com/users/web-flow/repos",
"events_url": "https://api.github.com/users/web-flow/events{/privacy}",
"received_events_url": "https://api.github.com/users/web-flow/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"parents": [
{
"sha": "562ffec8696d522d1854f6e42c4a540ae85b3fad",
"url": "https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad",
"html_url": "https://github.com/jqlang/jq/commit/562ffec8696d522d1854f6e42c4a540ae85b3fad"
}
]
}
{
"sha": "562ffec8696d522d1854f6e42c4a540ae85b3fad",
"node_id": "C_kwDOAE3WVdoAKDU2MmZmZWM4Njk2ZDUyMmQxODU0ZjZlNDJjNGE1NDBhZTg1YjNmYWQ",
"commit": {
"author": {
"name": "Eloy Coto",
"email": "eloy.coto@gmail.com",
"date": "2025-01-25T13:09:43Z"
},
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"date": "2025-01-25T13:09:43Z"
},
"message": "refactor: move bsearch function to C-code (#2945)\n\nThis commit fixes issue #527 and move the bsearch function to a native\r\nC-code. This change improves the performance of this function.",
"tree": {
"sha": "4379df769a1141b4a35a11d2dc8b1a4fb1a64e10",
"url": "https://api.github.com/repos/jqlang/jq/git/trees/4379df769a1141b4a35a11d2dc8b1a4fb1a64e10"
},
"url": "https://api.github.com/repos/jqlang/jq/git/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad",
"comment_count": 0,
"verification": {
"verified": true,
"reason": "valid",
"signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJnlOKXCRC1aQ7uu5UhlAAA2TsQAI0t2gsi4V6HE39MBnUDsn7/\nvQgq8FA/Xr+q1PyKoIVL8QVlaLE5FcWKn4fbfeXDoLYf7n5lzyLmV/Hm29IZSZHl\n9kLcrbq2U/ELlmsPOvTQRb/iEfnQrZ/k8PGg64aJqqPPyUMqsqb+V7CzCxJ/Eq40\np0f+OZIbfTZTmmcPyabfAMP4oZjKoHr9nqWRlMpzKq6oRu8YEAH9ynNZqqj4q3TT\nwgo1k7dpg1eNwffBGAIoPVkcqv97NEntKT/oFtC9fPyygWzQBp05G5bNl482lcCX\nnoIZNOhOX6+3AXwacQgQ2v4VMu14xRGtI+Lxr3TRmzIns1cXVnnKdQDiH6t5CUwe\nA72daOIloBwmLNEyPo5xnwJ5+Pyy+B6E8FAjX9+TPrYiY7l0gYlW9Hvavxdg95G2\nM24JRPWOCAV10itvOt7DonpYtwzH8Z9IqC6MTJkLmETdKbiRcNHHl3MkZw/g+GoF\n9/sSPpoSGYx2rM3WP2u0KgThjPkY1XD+jkEP8wzb/6r8DpLCKgKZ/CB5w9pbSIyo\n6rQMRliA5t5ouc582fKK9LWDviUuSI5OkZ50GXYtKNgsrwe9QUd2URGkMbLZXc6/\nwBlibp7n7mIGJuLN+wlMPThkJe04Oo9KLAzXd8F0A9yykFzA9uL3ZokA0Qsimc6/\nmqU01XTQD5XqnGTa3oWH\n=fgeN\n-----END PGP SIGNATURE-----\n",
"payload": "tree 4379df769a1141b4a35a11d2dc8b1a4fb1a64e10\nparent 18bd8374c1535bcf1060ad3ce24673898d5779be\nauthor Eloy Coto <eloy.coto@gmail.com> 1737810583 +0100\ncommitter GitHub <noreply@github.com> 1737810583 +0900\n\nrefactor: move bsearch function to C-code (#2945)\n\nThis commit fixes issue #527 and move the bsearch function to a native\r\nC-code. This change improves the performance of this function.",
"verified_at": "2025-01-25T13:09:46Z"
}
},
"url": "https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad",
"html_url": "https://github.com/jqlang/jq/commit/562ffec8696d522d1854f6e42c4a540ae85b3fad",
"comments_url": "https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad/comments",
"author": {
"login": "eloycoto",
"id": 868013,
"node_id": "MDQ6VXNlcjg2ODAxMw==",
"avatar_url": "https://avatars.githubusercontent.com/u/868013?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/eloycoto",
"html_url": "https://github.com/eloycoto",
"followers_url": "https://api.github.com/users/eloycoto/followers",
"following_url": "https://api.github.com/users/eloycoto/following{/other_user}",
"gists_url": "https://api.github.com/users/eloycoto/gists{/gist_id}",
"starred_url": "https://api.github.com/users/eloycoto/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/eloycoto/subscriptions",
"organizations_url": "https://api.github.com/users/eloycoto/orgs",
"repos_url": "https://api.github.com/users/eloycoto/repos",
"events_url": "https://api.github.com/users/eloycoto/events{/privacy}",
"received_events_url": "https://api.github.com/users/eloycoto/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"committer": {
"login": "web-flow",
"id": 19864447,
"node_id": "MDQ6VXNlcjE5ODY0NDQ3",
"avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/web-flow",
"html_url": "https://github.com/web-flow",
"followers_url": "https://api.github.com/users/web-flow/followers",
"following_url": "https://api.github.com/users/web-flow/following{/other_user}",
"gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
"starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
"organizations_url": "https://api.github.com/users/web-flow/orgs",
"repos_url": "https://api.github.com/users/web-flow/repos",
"events_url": "https://api.github.com/users/web-flow/events{/privacy}",
"received_events_url": "https://api.github.com/users/web-flow/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"parents": [
{
"sha": "18bd8374c1535bcf1060ad3ce24673898d5779be",
"url": "https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be",
"html_url": "https://github.com/jqlang/jq/commit/18bd8374c1535bcf1060ad3ce24673898d5779be"
}
]
}
{
"sha": "18bd8374c1535bcf1060ad3ce24673898d5779be",
"node_id": "C_kwDOAE3WVdoAKDE4YmQ4Mzc0YzE1MzViY2YxMDYwYWQzY2UyNDY3Mzg5OGQ1Nzc5YmU",
"commit": {
"author": {
"name": "Michael Färber",
"email": "01mf02@gmail.com",
"date": "2025-01-25T12:55:06Z"
},
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"date": "2025-01-25T12:55:06Z"
},
"message": "Escape some code parts in manual. (#3184)",
"tree": {
"sha": "3d3c96413584268b58ce77624acd2e3e33d31030",
"url": "https://api.github.com/repos/jqlang/jq/git/trees/3d3c96413584268b58ce77624acd2e3e33d31030"
},
"url": "https://api.github.com/repos/jqlang/jq/git/commits/18bd8374c1535bcf1060ad3ce24673898d5779be",
"comment_count": 0,
"verification": {
"verified": true,
"reason": "valid",
"signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJnlN8qCRC1aQ7uu5UhlAAAIFwQAI7fd+L74fuDkkPvx7pYdV1A\nBqLcJ7tq7tKEzcFxGs7IbbrGBDbEja7/ToAs1MikFEWTWgqc1/qjMUu+a5RFYN/f\nB3uOUuggbkHcLpCytNw88Mxj/dUaTYldRyq74qNNLtI5uotUYGmlL+CribUn1ZEa\nKh83KX8wyA63K5CRMQx+mM+QrSuz19xxfGWHF5shjJ6hraBwuTxy0rvjrhoQm72H\nMlNS67au8IWQWoBMB1w7+fUDGLpEYFOo0ucM/1HlePTipOrisrBhkRMepMvY3AHa\n0lyWiwlE+E1VTFMjVWOkEqFu3gOec/C+X44ftgyn9LgsRPH/gNrQWZN06dbJMffT\nB/BOhpaBbz/GDoHhiIvmtSKjYwqXMtqYjxgo+3sEe/IGII61k7q5umAwmoexxgkV\nE33rsqkPd/qDHqoI2MQU2kwi25QIYpd50IXNbiiO4IoAB0xNPJPm5GJD9By1VD2f\nIPN7HYIzUrS6YXNrjImaeK0g02sBTcZnK1DgDhiVF2lbOAFtU+78EtlWGVdbM/qA\nJiwECkEnrAR/d8wOiWdsCp3zh+A/xIijtEIeum7X2huYla8EKYPybvBRZvvGoTbm\npesEDQDlthCvqj8KPaMXWQRu85/9Jj8GenKRRrznE0sbBV+yOZOj54w6UvI9uq36\nXvgAmAaztPCZ9kCdqDi2\n=O8s7\n-----END PGP SIGNATURE-----\n",
"payload": "tree 3d3c96413584268b58ce77624acd2e3e33d31030\nparent d8463c25491b6150d748155ac530a3205d072e37\nauthor Michael Färber <01mf02@gmail.com> 1737809706 +0100\ncommitter GitHub <noreply@github.com> 1737809706 +0900\n\nEscape some code parts in manual. (#3184)\n\n",
"verified_at": "2025-01-25T12:55:09Z"
}
},
"url": "https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be",
"html_url": "https://github.com/jqlang/jq/commit/18bd8374c1535bcf1060ad3ce24673898d5779be",
"comments_url": "https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be/comments",
"author": {
"login": "01mf02",
"id": 864342,
"node_id": "MDQ6VXNlcjg2NDM0Mg==",
"avatar_url": "https://avatars.githubusercontent.com/u/864342?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/01mf02",
"html_url": "https://github.com/01mf02",
"followers_url": "https://api.github.com/users/01mf02/followers",
"following_url": "https://api.github.com/users/01mf02/following{/other_user}",
"gists_url": "https://api.github.com/users/01mf02/gists{/gist_id}",
"starred_url": "https://api.github.com/users/01mf02/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/01mf02/subscriptions",
"organizations_url": "https://api.github.com/users/01mf02/orgs",
"repos_url": "https://api.github.com/users/01mf02/repos",
"events_url": "https://api.github.com/users/01mf02/events{/privacy}",
"received_events_url": "https://api.github.com/users/01mf02/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"committer": {
"login": "web-flow",
"id": 19864447,
"node_id": "MDQ6VXNlcjE5ODY0NDQ3",
"avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/web-flow",
"html_url": "https://github.com/web-flow",
"followers_url": "https://api.github.com/users/web-flow/followers",
"following_url": "https://api.github.com/users/web-flow/following{/other_user}",
"gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
"starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
"organizations_url": "https://api.github.com/users/web-flow/orgs",
"repos_url": "https://api.github.com/users/web-flow/repos",
"events_url": "https://api.github.com/users/web-flow/events{/privacy}",
"received_events_url": "https://api.github.com/users/web-flow/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"parents": [
{
"sha": "d8463c25491b6150d748155ac530a3205d072e37",
"url": "https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37",
"html_url": "https://github.com/jqlang/jq/commit/d8463c25491b6150d748155ac530a3205d072e37"
}
]
}
{
"sha": "d8463c25491b6150d748155ac530a3205d072e37",
"node_id": "C_kwDOAE3WVdoAKGQ4NDYzYzI1NDkxYjYxNTBkNzQ4MTU1YWM1MzBhMzIwNWQwNzJlMzc",
"commit": {
"author": {
"name": "Dag-Erling Smørgrav",
"email": "des@des.no",
"date": "2025-01-25T08:10:05Z"
},
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"date": "2025-01-25T08:10:05Z"
},
"message": "Move closer to the standard autotools idiom. (#3187)\n\n* Create `src/config.h` instead of passing everything on the compiler\r\n command line.\r\n\r\n* To reduce the magnitude of this change, add `--include src/config.h`\r\n to CFLAGS instead of adding `#include \"src/config.h\"` at the top of\r\n each source file. Not all compilers support this, but I don't think\r\n we care about anything other than gcc and clang at this point.\r\n\r\n* Rather than generate `src/config_opts.inc`, emit `JQ_CONFIG` directly\r\n into `src/config.h`.\r\n\r\n* Rather than generate `src/version.h`, define `JQ_VERSION` as an alias\r\n for the standard `PACKAGE_VERSION`.",
"tree": {
"sha": "0e32e5eb9a30f3fb77d3c96a60266b45a7059ce5",
"url": "https://api.github.com/repos/jqlang/jq/git/trees/0e32e5eb9a30f3fb77d3c96a60266b45a7059ce5"
},
"url": "https://api.github.com/repos/jqlang/jq/git/commits/d8463c25491b6150d748155ac530a3205d072e37",
"comment_count": 0,
"verification": {
"verified": true,
"reason": "valid",
"signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJnlJxdCRC1aQ7uu5UhlAAANwAQAJa6ozhv7CBgWdaFni4/FipH\nMavO6CKPpiSbCWBrPpWnwen65NJowO5DQlcdoEFtyGZ31b1aR9Mif65/rSrKfpQk\nVxrXrqkTscBJ5iZWz9ZFecTBtSbqK6oSQ6CqzYu775XvtoddpHId/aTcl7d9EYww\nF5DspSoA9ZG4STf18qQhbyABK7+MevYMbPYaALE0fTo2VZ1JVjvV6RREB2wm4R50\nL9PVaLCvGdKXwHI8dvC64vruUtxM7GlYWrJ/rf+5tXD7Zlch1q/iQ/kET+gSeNZ2\ni7zvuw39XuUHlyTwhN+DKpdSkj/BO92wlZRLh3cNwRqDCmbZ1s+pantCwYZx7EJl\niv1nxMrGzRhdfiCldmBMWug0++oNduxIiNMBcuymA2/WR26KGhXB4uiy2XlZYUH+\nraaqEUhSDIqrDgbEyVB/zfIMnZIi+L3YY96tteDd+EOwCTs64KkBoTc6t8DKWS2H\nGQRzFkCjk5dtXWjYXPeIhdjafTaDbNT4b+Sa3W98JPwJ22zzOF/BWs48l6WN24Ti\nney1L4U33vLdLeaiRLT8hZSTwZ7XQnxZq7H/Sx6ee5CUbQ7RQ/USONOaRgrq76fV\nAByUUsCOPzLQLiNZ21oXIGYS9JnJvwtCW1YBFPtOzGXLrodrCm3soRByCA+D//DW\nAam9aVGsB2hablB6Fa4n\n=q8nQ\n-----END PGP SIGNATURE-----\n",
"payload": "tree 0e32e5eb9a30f3fb77d3c96a60266b45a7059ce5\nparent 71ed7b3412d33de8375d68e1ab552033ce0ab355\nauthor Dag-Erling Smørgrav <des@des.no> 1737792605 +0100\ncommitter GitHub <noreply@github.com> 1737792605 +0900\n\nMove closer to the standard autotools idiom. (#3187)\n\n* Create `src/config.h` instead of passing everything on the compiler\r\n command line.\r\n\r\n* To reduce the magnitude of this change, add `--include src/config.h`\r\n to CFLAGS instead of adding `#include \"src/config.h\"` at the top of\r\n each source file. Not all compilers support this, but I don't think\r\n we care about anything other than gcc and clang at this point.\r\n\r\n* Rather than generate `src/config_opts.inc`, emit `JQ_CONFIG` directly\r\n into `src/config.h`.\r\n\r\n* Rather than generate `src/version.h`, define `JQ_VERSION` as an alias\r\n for the standard `PACKAGE_VERSION`.",
"verified_at": "2025-01-25T08:10:09Z"
}
},
"url": "https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37",
"html_url": "https://github.com/jqlang/jq/commit/d8463c25491b6150d748155ac530a3205d072e37",
"comments_url": "https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37/comments",
"author": {
"login": "dag-erling",
"id": 4972155,
"node_id": "MDQ6VXNlcjQ5NzIxNTU=",
"avatar_url": "https://avatars.githubusercontent.com/u/4972155?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/dag-erling",
"html_url": "https://github.com/dag-erling",
"followers_url": "https://api.github.com/users/dag-erling/followers",
"following_url": "https://api.github.com/users/dag-erling/following{/other_user}",
"gists_url": "https://api.github.com/users/dag-erling/gists{/gist_id}",
"starred_url": "https://api.github.com/users/dag-erling/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/dag-erling/subscriptions",
"organizations_url": "https://api.github.com/users/dag-erling/orgs",
"repos_url": "https://api.github.com/users/dag-erling/repos",
"events_url": "https://api.github.com/users/dag-erling/events{/privacy}",
"received_events_url": "https://api.github.com/users/dag-erling/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"committer": {
"login": "web-flow",
"id": 19864447,
"node_id": "MDQ6VXNlcjE5ODY0NDQ3",
"avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/web-flow",
"html_url": "https://github.com/web-flow",
"followers_url": "https://api.github.com/users/web-flow/followers",
"following_url": "https://api.github.com/users/web-flow/following{/other_user}",
"gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
"starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
"organizations_url": "https://api.github.com/users/web-flow/orgs",
"repos_url": "https://api.github.com/users/web-flow/repos",
"events_url": "https://api.github.com/users/web-flow/events{/privacy}",
"received_events_url": "https://api.github.com/users/web-flow/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"parents": [
{
"sha": "71ed7b3412d33de8375d68e1ab552033ce0ab355",
"url": "https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355",
"html_url": "https://github.com/jqlang/jq/commit/71ed7b3412d33de8375d68e1ab552033ce0ab355"
}
]
}
{
"sha": "71ed7b3412d33de8375d68e1ab552033ce0ab355",
"node_id": "C_kwDOAE3WVdoAKDcxZWQ3YjM0MTJkMzNkZTgzNzVkNjhlMWFiNTUyMDMzY2UwYWIzNTU",
"commit": {
"author": {
"name": "itchyny",
"email": "itchyny@cybozu.co.jp",
"date": "2025-01-25T04:58:47Z"
},
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"date": "2025-01-25T04:58:47Z"
},
"message": "tests: refactor constant folding tests (#3233)",
"tree": {
"sha": "38620106b5c254e33971315213a72ab727903132",
"url": "https://api.github.com/repos/jqlang/jq/git/trees/38620106b5c254e33971315213a72ab727903132"
},
"url": "https://api.github.com/repos/jqlang/jq/git/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355",
"comment_count": 0,
"verification": {
"verified": true,
"reason": "valid",
"signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJnlG+ICRC1aQ7uu5UhlAAAR0IQAF2sTyroQHline95FlKhB2I0\nB3/0BCANHK20M5JEM1k1TAc7TtnGjegvIjGd2fX+KOCjaj5qYOUiGTc9bF0JAfoh\nMLpMHjtCieFYHocMvaK1y5lYoaFY8+KbZUmFQrDww1sgGhzfgcPzZoBd6d24jSsd\nUWuHaX4R4c8QWax7eHRBUex0w2tl4zYbatIbh6yjDB4CTxPtN5JN1elnf1DS7FJh\ndMS7eWGH1r8bd5t6ngfocfF9/bTuPampSUQGNsBIW41JIoA/BYzHgD8dgB0EGGOl\neGMt4O8EX+FQVqPp9ciZ/r63j1gf8D5pYP40Pz9MM90GkPdryPBN87dxLrybcJ2e\nldjdXIFS9DiEeFFkq/MB2oY4oo8Wbj/jprEsIq4PmMjpkZY5cC6yqnf0VU1PiN4v\neCxbXqAKQob2VQ+/RIL4OpWAT3ANDP5YIhnZ8RzVgpYn7KhTiXKC2Zs6DUuSUBlD\nHAn3zOMmYH2xrWxGtPTWGaJaBff5psN69Zt3dJDzrDOiVmEH8gagmHs0C7uQVDXl\nvH/deXUzP83gkr0c11lKrOxEXhaKjB0s3ONAdPmUzmD8aQmQKm8IdrhkFBRJMItY\nphWPq8Q0B9N+48Q6OWwD4w67bdLD0tVkbWc/U2EcXtWY22W0eeBSbpsIpckjehPn\nqD24QxULk0QxnYxPPmc6\n=xzR9\n-----END PGP SIGNATURE-----\n",
"payload": "tree 38620106b5c254e33971315213a72ab727903132\nparent 588ff1874c8c394253c231733047a550efe78260\nauthor itchyny <itchyny@cybozu.co.jp> 1737781127 +0900\ncommitter GitHub <noreply@github.com> 1737781127 +0900\n\ntests: refactor constant folding tests (#3233)\n\n",
"verified_at": "2025-01-25T04:58:51Z"
}
},
"url": "https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355",
"html_url": "https://github.com/jqlang/jq/commit/71ed7b3412d33de8375d68e1ab552033ce0ab355",
"comments_url": "https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355/comments",
"author": {
"login": "itchyny",
"id": 375258,
"node_id": "MDQ6VXNlcjM3NTI1OA==",
"avatar_url": "https://avatars.githubusercontent.com/u/375258?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/itchyny",
"html_url": "https://github.com/itchyny",
"followers_url": "https://api.github.com/users/itchyny/followers",
"following_url": "https://api.github.com/users/itchyny/following{/other_user}",
"gists_url": "https://api.github.com/users/itchyny/gists{/gist_id}",
"starred_url": "https://api.github.com/users/itchyny/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/itchyny/subscriptions",
"organizations_url": "https://api.github.com/users/itchyny/orgs",
"repos_url": "https://api.github.com/users/itchyny/repos",
"events_url": "https://api.github.com/users/itchyny/events{/privacy}",
"received_events_url": "https://api.github.com/users/itchyny/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"committer": {
"login": "web-flow",
"id": 19864447,
"node_id": "MDQ6VXNlcjE5ODY0NDQ3",
"avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/web-flow",
"html_url": "https://github.com/web-flow",
"followers_url": "https://api.github.com/users/web-flow/followers",
"following_url": "https://api.github.com/users/web-flow/following{/other_user}",
"gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
"starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
"organizations_url": "https://api.github.com/users/web-flow/orgs",
"repos_url": "https://api.github.com/users/web-flow/repos",
"events_url": "https://api.github.com/users/web-flow/events{/privacy}",
"received_events_url": "https://api.github.com/users/web-flow/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"parents": [
{
"sha": "588ff1874c8c394253c231733047a550efe78260",
"url": "https://api.github.com/repos/jqlang/jq/commits/588ff1874c8c394253c231733047a550efe78260",
"html_url": "https://github.com/jqlang/jq/commit/588ff1874c8c394253c231733047a550efe78260"
}
]
}

记作 raw.log,由一个列表数据剥离为 5 个 json 数据。

在处理中一个比较重要的参数是-c,用来紧凑模式单行输出,方便后续的行处理:

1
2
3
4
5
6
7
┌ [2025/01/26 19:56:01] arch ~/Downloads/1232 git:(main) ✗
└➜ cat raw.log | jq -c '.parents'
[{"sha":"562ffec8696d522d1854f6e42c4a540ae85b3fad","url":"https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad","html_url":"https://github.com/jqlang/jq/commit/562ffec8696d522d1854f6e42c4a540ae85b3fad"}]
[{"sha":"18bd8374c1535bcf1060ad3ce24673898d5779be","url":"https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be","html_url":"https://github.com/jqlang/jq/commit/18bd8374c1535bcf1060ad3ce24673898d5779be"}]
[{"sha":"d8463c25491b6150d748155ac530a3205d072e37","url":"https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37","html_url":"https://github.com/jqlang/jq/commit/d8463c25491b6150d748155ac530a3205d072e37"}]
[{"sha":"71ed7b3412d33de8375d68e1ab552033ce0ab355","url":"https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355","html_url":"https://github.com/jqlang/jq/commit/71ed7b3412d33de8375d68e1ab552033ce0ab355"}]
[{"sha":"588ff1874c8c394253c231733047a550efe78260","url":"https://api.github.com/repos/jqlang/jq/commits/588ff1874c8c394253c231733047a550efe78260","html_url":"https://github.com/jqlang/jq/commit/588ff1874c8c394253c231733047a550efe78260"}]

为了方便还原,先构造出一个类似实际应用场景的数据:

1
2
3
4
5
6
7
┌ [2025/01/26 20:00:59] arch ~/Downloads/1232 git:(main) ✗
└➜ cat raw.log | jq -c '{data: (.parents[0] | @json)}'
{"data":"{\"sha\":\"562ffec8696d522d1854f6e42c4a540ae85b3fad\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad\",\"html_url\":\"https://github.com/jqlang/jq/commit/562ffec8696d522d1854f6e42c4a540ae85b3fad\"}"}
{"data":"{\"sha\":\"18bd8374c1535bcf1060ad3ce24673898d5779be\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be\",\"html_url\":\"https://github.com/jqlang/jq/commit/18bd8374c1535bcf1060ad3ce24673898d5779be\"}"}
{"data":"{\"sha\":\"d8463c25491b6150d748155ac530a3205d072e37\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37\",\"html_url\":\"https://github.com/jqlang/jq/commit/d8463c25491b6150d748155ac530a3205d072e37\"}"}
{"data":"{\"sha\":\"71ed7b3412d33de8375d68e1ab552033ce0ab355\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355\",\"html_url\":\"https://github.com/jqlang/jq/commit/71ed7b3412d33de8375d68e1ab552033ce0ab355\"}"}
{"data":"{\"sha\":\"588ff1874c8c394253c231733047a550efe78260\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/588ff1874c8c394253c231733047a550efe78260\",\"html_url\":\"https://github.com/jqlang/jq/commit/588ff1874c8c394253c231733047a550efe78260\"}"}

数据在 json 的 data 值中,以字符串的形式存在。

首先拿到数据:

1
2
3
4
5
6
7
┌ [2025/01/26 20:01:27] arch ~/Downloads/1232 git:(main) ✗
└➜ cat raw.log | jq -c '{data: (.parents[0] | @json)}' | jq -c '.data'
"{\"sha\":\"562ffec8696d522d1854f6e42c4a540ae85b3fad\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad\",\"html_url\":\"https://github.com/jqlang/jq/commit/562ffec8696d522d1854f6e42c4a540ae85b3fad\"}"
"{\"sha\":\"18bd8374c1535bcf1060ad3ce24673898d5779be\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be\",\"html_url\":\"https://github.com/jqlang/jq/commit/18bd8374c1535bcf1060ad3ce24673898d5779be\"}"
"{\"sha\":\"d8463c25491b6150d748155ac530a3205d072e37\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37\",\"html_url\":\"https://github.com/jqlang/jq/commit/d8463c25491b6150d748155ac530a3205d072e37\"}"
"{\"sha\":\"71ed7b3412d33de8375d68e1ab552033ce0ab355\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355\",\"html_url\":\"https://github.com/jqlang/jq/commit/71ed7b3412d33de8375d68e1ab552033ce0ab355\"}"
"{\"sha\":\"588ff1874c8c394253c231733047a550efe78260\",\"url\":\"https://api.github.com/repos/jqlang/jq/commits/588ff1874c8c394253c231733047a550efe78260\",\"html_url\":\"https://github.com/jqlang/jq/commit/588ff1874c8c394253c231733047a550efe78260\"}"

通过fromjson子命令得到 json 对象:

1
2
3
4
5
6
7
┌ [2025/01/26 20:04:10] arch ~/Downloads/1232 git:(main) ✗
└➜ cat raw.log | jq -c '{data: (.parents[0] | @json)}' | jq -c '.data | fromjson'
{"sha":"562ffec8696d522d1854f6e42c4a540ae85b3fad","url":"https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad","html_url":"https://github.com/jqlang/jq/commit/562ffec8696d522d1854f6e42c4a540ae85b3fad"}
{"sha":"18bd8374c1535bcf1060ad3ce24673898d5779be","url":"https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be","html_url":"https://github.com/jqlang/jq/commit/18bd8374c1535bcf1060ad3ce24673898d5779be"}
{"sha":"d8463c25491b6150d748155ac530a3205d072e37","url":"https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37","html_url":"https://github.com/jqlang/jq/commit/d8463c25491b6150d748155ac530a3205d072e37"}
{"sha":"71ed7b3412d33de8375d68e1ab552033ce0ab355","url":"https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355","html_url":"https://github.com/jqlang/jq/commit/71ed7b3412d33de8375d68e1ab552033ce0ab355"}
{"sha":"588ff1874c8c394253c231733047a550efe78260","url":"https://api.github.com/repos/jqlang/jq/commits/588ff1874c8c394253c231733047a550efe78260","html_url":"https://github.com/jqlang/jq/commit/588ff1874c8c394253c231733047a550efe78260"}

然后继续类似管道操作得到结果(假设):

1
2
3
4
5
6
7
┌ [2025/01/26 20:05:29] arch ~/Downloads/1232 git:(main) ✗
└➜ cat raw.log | jq -c '{data: (.parents[0] | @json)}' | jq -c '.data | fromjson | .url'
"https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad"
"https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be"
"https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37"
"https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355"
"https://api.github.com/repos/jqlang/jq/commits/588ff1874c8c394253c231733047a550efe78260"

至此解析完成,可以再通过 sed 等命令替换成可执行命令:

1
2
3
4
5
6
7
┌ [2025/01/26 20:06:12] arch ~/Downloads/1232 git:(main) ✗
└➜ cat raw.log | jq -c '{data: (.parents[0] | @json)}' | jq -c '.data | fromjson | .url' | sed 's/^/echo /'
echo "https://api.github.com/repos/jqlang/jq/commits/562ffec8696d522d1854f6e42c4a540ae85b3fad"
echo "https://api.github.com/repos/jqlang/jq/commits/18bd8374c1535bcf1060ad3ce24673898d5779be"
echo "https://api.github.com/repos/jqlang/jq/commits/d8463c25491b6150d748155ac530a3205d072e37"
echo "https://api.github.com/repos/jqlang/jq/commits/71ed7b3412d33de8375d68e1ab552033ce0ab355"
echo "https://api.github.com/repos/jqlang/jq/commits/588ff1874c8c394253c231733047a550efe78260"

#golang channel

可以阅读这篇关于通道的详细解读:https://gfw.go101.org/article/channel.html,并在此添加我个人觉得比较重要的点和与在阅读实际源码中产生不一致的点。

在 select 操作中的一些细节点:

  1. 通过简单随机保证不会有 case 被饿死。
  2. 通过对所有的通道排序,保证所有的 goroutine 都是以同样的顺序进行通道加锁,即不会产生死锁(不会循环等待)。
  3. 文章中可能简化了实现的细节,实际上源码中只是得到了所有的锁的排序,例如[A, A, B, B, C, D],在加锁的时候用简单的方式进行了去重(对于已经排序好的内容去重,只需要和前一个数据对比即可),并非文中所描述的排序结果中前N个通道不存在重复的情况。亦或许是 golang 的源码发生了变化,本次使用的代码版本是go1.23.5

#golang context

简单的看了一下服务端关于 grpc 的上下文控制的源码,感觉像是比以前更懂得了如何做上下文控制,罗列几点关于此的总结结论。

  1. 简单来说,context.Context 是通过关闭通道的广播来进行一对多的通知的,这也是我又把通道的相关设计又看了一次的原因。
1
2
3
4
5
6
7
go func() {
select {
case <-parent.Done():
child.cancel(false, parent.Err(), Cause(parent))
case <-child.Done():
}
}()
  1. 实际上,ctx 的结束传播依赖的是维护在内部的 children 相关数组遍历实现的,并非我最开始以为的,将多个通道连在了一起?顺带一提,每次WithDeadlineWithCancel都需要propagateCancel,这个操作会启动一个 goroutine 去传播 cancel,字面意思。
  2. 对于实际的使用侧而言,基于我现在阅读过的代码来说,会在进行 io 请求之前加ctx.Err()来判断是否要执行,再根据数据和case <-ctx.Done():哪个回来的更快来进行超时处理。

#golang gmp

  • 减少全局锁竞争
  • 控制并发规模
  • 负载均衡
  • 解耦 M 与 G

若没有 P,所有 M(线程)需从全局队列获取 G,导致频繁的锁竞争,成为性能瓶颈。
直接由 M 管理 G 可能导致线程过多(如大量阻塞操作时),浪费资源。
若某些 M 的 G 队列过载,而其他 M 空闲,会导致资源浪费。
若 M 直接管理 G,阻塞操作(如 I/O)会导致线程挂起,无法执行其他 G。