Skip to content

Commit f44dfee

Browse files
committed
post: claude.md
1 parent 4213ddd commit f44dfee

30 files changed

+350
-128
lines changed

content/posts/2025-11-27_docker-context.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ docker context use default
1717

1818
```shell
1919
docker context create my-server --docker "host=ssh://[email protected]"
20-
docker context create my-server --docker "host=CompanyServer1"
20+
21+
docker context create my-server --docker "host=ssh://CompanyServer1"
2122
```
2223

2324
这里的 `CompanyServer1` 是 ssh 配置,例如这样

content/posts/2025-12-01_python-asyncio-03.md

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -358,40 +358,86 @@ import selectors
358358
import socket
359359
from selectors import SelectorKey
360360

361+
361362
selector = selectors.DefaultSelector()
362363

363364
server_socket = socket.socket()
364365
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
365366

366-
server_addres = ("127.0.0.1", 8000)
367+
server_address = ("127.0.0.1", 8000)
367368
server_socket.setblocking(False)
368-
server_socket.bind(server_addres)
369+
server_socket.bind(server_address)
369370
server_socket.listen()
370371

371372
selector.register(server_socket, selectors.EVENT_READ)
372373

373374
while True:
374-
# 创建 1 秒后过期的 selector 选择器
375+
# 创建 1 秒过期的选择器
375376
events: list[tuple[SelectorKey, int]] = selector.select(timeout=1)
376377

377-
# 如果没有事件,输出
378+
# 没有事件
378379
if len(events) == 0:
379380
print("No events, waiting a bit more!")
380381

381382
for event, _ in events:
382-
# 获取 fileobj 里面存储的 socket event
383+
# 获取 socket event
383384
event_socket = event.fileobj
384385

385-
# 如果 event_socket 和 server_socket 是同一个,则说明是一次连接尝试
386386
if event_socket == server_socket:
387387
connection, address = server_socket.accept()
388388
connection.setblocking(False)
389389
print(f"I got a connection from {address}")
390-
# 注册连接到 selector 的客户端
391390
selector.register(connection, selectors.EVENT_READ)
392391
else:
393-
# 如果 event 不是 server socket,则接受数据并 echo 返回
394392
data = event_socket.recv(1024)
395393
print(f"I got some data: {data}")
396394
event_socket.send(data)
395+
397396
```
397+
398+
这样实现的 echo server 的 CPU 利用率就少了很多,虽然仍然是死循环,但是循环内部的 `selector()` 会让线程进入内核的阻塞睡眠状态,直到超时才会 print() 一条语句,是典型的事件驱动。
399+
400+
而 try except 轮询会不间断的轮询,且内部会不断抛出异常、处理异常、重试等,CPU 占用很高。
401+
402+
---
403+
404+
上面构建的部分和 asyncio 底层的大部分工作方式类似。
405+
在这个例子中,events 是 sockets 接收数据。
406+
无论是我们的事件循环还是 asyncio 的事件循环,它们的每一次迭代都是由两种情况触发的:要么有某个 socket 事件发生,要么是超时导致事件循环继续运行。
407+
408+
在 asyncio 的事件循环里,只要发生了这两种情况中的任意一种,所有正在等待调度的协程都会运行,直到它们结束,或者它们遇到下一个 await 语句为止。
409+
410+
当协程执行到一个基于非阻塞 socket 的 await 时,该 socket 会被注册到系统的 selector 中,同时事件循环会记录该协程已暂停并正在等待这个 socket 的结果。
411+
412+
我们可以把这个概念翻译成伪代码来展示。
413+
414+
```Python
415+
paused = []
416+
ready = []
417+
418+
while True:
419+
paused, new_sockets = run_ready_tasks(ready)
420+
selector.register(new_sockets)
421+
timeout = calculate_timeout()
422+
events = selector.select(timeout)
423+
ready = process_events(events)
424+
```
425+
426+
我们会运行所有“已经准备好的协程”,直到他们在某个 await 语句上暂停,并把这些协程放到 paused 列表中。
427+
同时,还会记录这些协程运行过程中产生的所有新 socket,并将他们注册到 selector 中。
428+
之后,我们需要计算下一次调用 select 时的超时时间。
429+
这个 timeout 的计算方式比较复杂,但通常取决于在未来某个时间点或者等待某个持续时间后要执行的任务。
430+
例如 asyncio.sleep() 就会影响这个 timeout。
431+
432+
接着,调用 select 并等待 socket 事件或超时。
433+
当其中一个发生时,会处理这些事件,并将其转化为一个可立即继续执行的协程列表。
434+
435+
---
436+
437+
虽然上面的 event loop 只是用于 socket 的,但其展示了使用 selectors 注册 sockets 的主要思想,
438+
即只在我们关心的事件发生后才启动。
439+
440+
然而,如果我们仅使用 selectors 来构建应用程序,就需要自行实现事件循环才能达到与 asyncio 相同的功能。
441+
下面介绍如何使用 async/await 来实现上面功能。
442+
443+
### An echo server on the asyncio event loop

content/posts/2025-12-02_claude.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
+++
22
date = '2025-12-02T8:00:00+08:00'
3-
draft = true
3+
draft = false
44
title = 'Writing a good CLAUDE.md'
55
tags = ['Agent']
66
+++
@@ -25,7 +25,8 @@ LLMs 是无状态函数。它们的权重在用于推理时是冻结的,因此
2525

2626
由于 Claude 在每个会话开始时对你的代码库一无所知,你应该使用 CLAUDE.md 来引导 Claude 了解你的代码库。在高层次上,这意味着它应该涵盖:
2727

28-
- **是什么(WHAT)**:告诉 Claude 关于技术栈、项目结构。给 Claude 一张代码库地图。这在 monorepos 中尤其重要!告诉 Claude 有哪些应用、有哪些共享包,以及每个部分的用途,这样它就知道在哪里查找内容
28+
- **是什么(WHAT)**:告诉 Claude 关于技术栈、项目结构。给 Claude 一张代码库地图。
29+
这在 monorepos 中尤其重要!告诉 Claude 有哪些应用、有哪些共享包,以及每个部分的用途,这样它就知道在哪里查找内容
2930
- **为什么(WHY)**:告诉 Claude 项目的目的以及仓库中所有内容的作用。项目不同部分的目的和功能是什么?
3031
- **如何(HOW)**:告诉 Claude 应该如何在项目上工作。例如,你使用 bun 而不是 node?你需要包含它实际完成有意义工作所需的所有信息。Claude 如何验证它的更改?它如何运行测试、类型检查和编译步骤?
3132

public/archives/index.html

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,13 @@
5151
<span class="max-w-[4rem] md:max-w-none truncate">Home</span></a></li><li class="flex items-center gap-1 md:gap-2 min-w-0"><span class="text-muted-foreground/50 flex-shrink-0"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
5252
</span><span class="text-foreground flex items-center gap-0.5 md:gap-1 font-medium min-w-0 flex-shrink-0"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"/></svg>
5353
<span class="max-w-[3rem] md:max-w-none truncate">Archives</span></span></li></ol></nav><header class=mb-8><div class="mb-4 flex items-center gap-3"><svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"/></svg><h1 class="text-foreground text-3xl font-bold">Archives</h1></div><p class="text-muted-foreground mb-6">Browse all articles in chronological order and discover what interests you.</p><div class="text-muted-foreground flex items-center gap-4 text-sm"><div class="flex items-center gap-1"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
54-
<span>82 posts total</span></div><div class="flex items-center gap-1"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5A2 2 0 003 7v12a2 2 0 002 2z"/></svg>
55-
<span>Timeline view</span></div></div></header><div class=relative><div class="bg-border absolute top-0 bottom-0 left-4 w-0.5"></div><div class=mb-12><div class="relative mb-8 flex items-center"><div class="bg-primary absolute left-0 z-10 flex h-8 w-8 items-center justify-center rounded-full"><svg class="h-4 w-4 text-primary-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5A2 2 0 003 7v12a2 2 0 002 2z"/></svg></div><div class=ml-12><h2 class="text-foreground text-2xl font-bold">2025</h2><p class="text-muted-foreground text-sm">80
56-
posts</p></div></div><div class="relative mb-8"><div class="relative mb-4 flex items-center"><div class="bg-accent border-background absolute left-2 z-10 h-4 w-4 rounded-full border-2"></div><div class=ml-12><h3 class="text-foreground text-lg font-semibold">November 2025</h3><p class="text-muted-foreground text-xs">21
54+
<span>83 posts total</span></div><div class="flex items-center gap-1"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5A2 2 0 003 7v12a2 2 0 002 2z"/></svg>
55+
<span>Timeline view</span></div></div></header><div class=relative><div class="bg-border absolute top-0 bottom-0 left-4 w-0.5"></div><div class=mb-12><div class="relative mb-8 flex items-center"><div class="bg-primary absolute left-0 z-10 flex h-8 w-8 items-center justify-center rounded-full"><svg class="h-4 w-4 text-primary-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5A2 2 0 003 7v12a2 2 0 002 2z"/></svg></div><div class=ml-12><h2 class="text-foreground text-2xl font-bold">2025</h2><p class="text-muted-foreground text-sm">81
56+
posts</p></div></div><div class="relative mb-8"><div class="relative mb-4 flex items-center"><div class="bg-accent border-background absolute left-2 z-10 h-4 w-4 rounded-full border-2"></div><div class=ml-12><h3 class="text-foreground text-lg font-semibold">December 2025</h3><p class="text-muted-foreground text-xs">1
57+
posts</p></div></div><div class="ml-12 space-y-3"><article class="group bg-card border-border hover:bg-accent/50 rounded-lg border p-4 transition-all duration-300"><div class="flex items-center justify-between gap-4"><div class="min-w-0 flex-1"><h4 class="text-foreground group-hover:text-primary mb-3 font-medium transition-colors duration-200"><a href=/posts/writing-a-good-claude.md/ class=block>Writing a good CLAUDE.md</a></h4><div class="text-muted-foreground flex items-center gap-4 text-xs"><div class="flex items-center gap-1"><svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5A2 2 0 003 7v12a2 2 0 002 2z"/></svg>
58+
<time datetime=2025-12-02>12-02</time></div><div class="flex items-center gap-1"><svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3A9 9 0 113 12a9 9 0 0118 0z"/></svg>
59+
<span>7
60+
min</span></div></div></div></div></article></div></div><div class="relative mb-8"><div class="relative mb-4 flex items-center"><div class="bg-accent border-background absolute left-2 z-10 h-4 w-4 rounded-full border-2"></div><div class=ml-12><h3 class="text-foreground text-lg font-semibold">November 2025</h3><p class="text-muted-foreground text-xs">21
5761
posts</p></div></div><div class="ml-12 space-y-3"><article class="group bg-card border-border hover:bg-accent/50 rounded-lg border p-4 transition-all duration-300"><div class="flex items-center justify-between gap-4"><div class="min-w-0 flex-1"><h4 class="text-foreground group-hover:text-primary mb-3 font-medium transition-colors duration-200"><a href=/posts/docker-context/ class=block>Docker Context</a></h4><div class="text-muted-foreground flex items-center gap-4 text-xs"><div class="flex items-center gap-1"><svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5A2 2 0 003 7v12a2 2 0 002 2z"/></svg>
5862
<time datetime=2025-11-25>11-25</time></div><div class="flex items-center gap-1"><svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3A9 9 0 113 12a9 9 0 0118 0z"/></svg>
5963
<span>1

0 commit comments

Comments
 (0)