Skip to content

Commit e95732c

Browse files
committed
post: update redis post
1 parent 6e292c1 commit e95732c

File tree

16 files changed

+378
-24
lines changed

16 files changed

+378
-24
lines changed

content/posts/2025-08-30_redis-learn05.md

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,108 @@ class RankingList:
141141
ZREVRANGEBYSCORE sorted_set max min
142142
```
143143
命令的 min 参数和 max 参数分别用于指定用户想要获取的最小分值和最大分值, 要注意这两条命令接受最大最小值的顺序正好相反.
144-
该命令也可以使用 WITHSCORES 参数来同时获取成员及其分值
144+
145+
- 该命令也可以使用 WITHSCORES 参数来同时获取成员及其分值
145146
```
146147
ZRANGEBYSCORE sorted_set min max [WITHSCORES]
147148
ZREVRANGEBYSCORE sorted_set max min [WITHSCORES]
148149
```
149-
默认情况下, 该命令会返回范围内的所有成员, 有时成员数量很多, 就可以使用 LIMIT 选项来限制命令返回的成员数量.
150+
- 默认情况下, 该命令会返回范围内的所有成员, 有时成员数量很多, 就可以使用 LIMIT 选项来限制命令返回的成员数量.
150151
```
151152
ZRANGEBYSCORE sorted_set min max [LIMIT offset count]
152153
ZREVRANGEBYSCORE sorted_set min max [LIMIT offset count]
153154
```
154155
其中, offset 是指从满足 min 和 max 的元素中, 跳过前面的 offset 个元素, count 是从 offset 之后开始, 返回接下来的 count 个元素.
155156
157+
- 如果要使用开区间而不是闭区间, 在分词的前面加上一个分括号
158+
```
159+
ZRANGEBYSCORE salary (3500 (5000 WITHSCORES
160+
```
161+
这样会返回分值大于3500, 小于5000的成员.
162+
163+
- 最后, 还可以使用无限值作为分值范围
164+
```
165+
ZRANGEBYSCORE salary -inf (5000 WITHSCORES
166+
```
167+
复杂度: O(log(N) + M), N 为有序集和的成员数量, M 为命令返回的成员数量
168+
169+
- ZCOUNT: 统计指定分词范围内的成员数量
170+
```
171+
ZCOUNT sorted_set min max
172+
```
173+
复杂度: O(N)
174+
175+
### 示例: 时间线
176+
在互联网上, 很多网站都会根据发布的内容来对时间进行排序:
177+
- 博客系统按照文章发布时间的先后, 将最近发布的文章放在前面
178+
- 新闻网站会按照新闻的发布时间, 把最新的新闻放在网站前面
179+
180+
类似的情形还有很多, 通过对这类行为进行抽象, 写出下面的时间线程序:
181+
- 把被添加到时间线里的元素用作成员, 与元素相关的时间戳用作分值, 将元素和时间戳添加到集和中
182+
- 将时间线中的元素按照时间戳的大小排序
183+
- 通过对时间线中的元素执行 ZREVRANGE 或者 ZREVRANGEBYSCORE 命令, 用户可以通过分页的方式取出时间线中的元素, 或者从时间线中取出指定时间区间内的元素
184+
185+
```Python
186+
class Timeline:
187+
def __init__(self, client, key):
188+
self.client = client
189+
self.key = key
190+
191+
def add(self, item, time):
192+
"""将元素添加到时间线中"""
193+
self.client.zadd(self.key, {item: time})
194+
195+
def remove(self, item):
196+
"""将元素从时间线中移除"""
197+
self.client.zrem(self.key, item)
198+
199+
def count(self):
200+
"""返回时间线包含的元素数量"""
201+
return self.client.zcard(self.key)
202+
203+
def pagging(self, number, count, with_time=False):
204+
"""
205+
按照每页 count 个元素, 取出时间线第 number 页上的所有元素, 将元素按照时间戳逆序排序
206+
with_time 表示是否返回时间信息
207+
"""
208+
start_index = (number - 1) * count
209+
end_index = number * count - 1
210+
return self.client.zrevrange(self.key, start_index, end_index, with_time)
211+
212+
def fetch_by_time_range(self, min_time, max_time, number, count, with_time=False):
213+
"""
214+
按照每页 count 个元素, 取出时间线第 number 页上的所有元素, 按照时间戳逆序排序
215+
with_time 表示是否返回时间信息
216+
"""
217+
start_index = (number - 1) * count
218+
end_index = start_index + count - 1
219+
return self.client.zrevrangebyscore(self.key, max_time, min_time, start_index, end_index, withscores=with_time)
220+
```
221+
222+
- ZREMRANGEBYRANK: 移除指定排名范围内的成员
223+
```
224+
ZREMRANGEBYRANK sorted_set start end
225+
```
226+
该命令可以从升序排列的有序集和中移除位于指定排名范围内的成员, 然后返回被移除成员的数量
227+
start-\>end 可以是正数, 也可以使用负数 end-\>start
228+
229+
- ZUNIONSTORE、ZINTERSTORE: 有序集和的并集运算和交集运算
230+
```
231+
ZUNIONSTORE destination numbers sorted_set [sorted_set ...]
232+
ZINTERSOTRE destination numbers sorted_set [sorted_set ...]
233+
```
234+
其中, numbers 用于指定参与计算的有序集和数量, 计算结果会存储到 destination 参数指定的键中, 最后返回计算结果包含的成员数量作为返回值
235+
- 此外, 还可以决定使用什么方法来获得集和成员的分值:
236+
```
237+
ZUNIONSTORE destination numbers sorted_set [sorted_set ...] [AGGREGATE SUM|MIN|MAX]
238+
ZINTERSTORE destination numbers sorted_set [sorted_set ...] [AGGREGATE SUM|MIN|MAX]
239+
```
240+
241+
- 如果上面的聚合函数不够用, 还可以为每个集和设置权重
242+
```
243+
ZUNIONSTORE destination numbers sorted_set [sorted ...] [WEIGHTS weight [weight ...]]
244+
```
245+
复杂度: ZUNIONSTORE - O(N * log(N)), ZINTERSTORE - O(N * log(N) * M)
246+
156247
248+
还有很多其他关于有序集和的内容, 这里就不再讨论了.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
+++
2+
date = '2025-09-02T8:00:00+08:00'
3+
draft = true
4+
title = 'Code Surgery: How AI Assistants Make Precise Edits to Your Files'
5+
tags = ['LLMs']
6+
+++
7+
原文链接: [代码手术: AI 助手如何对你的文件做出精确改动](https://fabianhertwig.com/blog/coding-assistants-file-edits/)
8+
9+
昨天的文章介绍了如何制作一个基本的 AI 编程助手, 今天更近一步, 探讨 AI 助手如何对文件进行精确的修改.
10+
11+
> 实际的 Coding Agent 一般并不会直接读取文件的全部代码, 因为这样可能会读取大量无关的代码, 导致 LLM 输出质量下降以及浪费 token, 同样的, 昨天的 agent 是直接重写整个文件, 也会导致输出 token 非常多, 一般也是会只对文件中必要的行进行修改, 而不是整个文件.

public/archives/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
<span>7
6464
min</span></div></div></div></div></article><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/redis-ordered-set/ class=block>Redis Ordered Set</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>
6565
<time datetime=2025-08-30>08-30</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>
66-
<span>5
66+
<span>7
6767
min</span></div></div></div></div></article><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/asyncio-vs-gevents-in-python/ class=block>Asyncio vs Gevents in Python</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>
6868
<time datetime=2025-08-29>08-29</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>
6969
<span>6

public/en/sitemap.xml

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

public/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<time datetime=2025-08-31 class=font-medium>August 31, 2025</time></div><div class="flex items-center gap-1.5"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-label="Reading time"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3A9 9 0 113 12a9 9 0 0118 0z"/></svg>
5858
<span class=font-medium>7 minute</span></div></div><div class="flex flex-wrap items-center gap-1.5 mt-2"><span class="bg-muted/50 border-muted/30 flex items-center gap-1 rounded-md border px-2 py-1"><span class=font-medium>Algorithm</span></span></div></div></div></div></a></article><article class=group><a href=/posts/redis-ordered-set/ class=block><div class="bg-card border-border hover:bg-primary/5 hover:border-primary/20 focus:ring-primary/20 relative flex flex-col overflow-hidden rounded-xl border transition-all duration-300 ease-out hover:-translate-y-1 hover:scale-[1.02] hover:shadow-lg focus:ring-2 focus:outline-none min-h-[200px]"><div class="block md:hidden"><div class="aspect-[2/1] overflow-hidden"><div class="from-pink-500/20 to-rose-500/10 relative aspect-[2/1] overflow-hidden bg-gradient-to-br" style="background-blend-mode:overlay;background-color:color-mix(in srgb,var(--color-primary) 15%,transparent)"><div class="absolute inset-0"><div class="absolute left-[15%] top-[20%] rotate-45"><div class="h-0 w-0 border-l-[10px] border-r-[10px] border-b-[16px] border-l-transparent border-r-transparent border-b-white/80"></div></div><div class="absolute right-[20%] top-[15%] rotate-12"><div class="h-0 w-0 border-l-[8px] border-r-[8px] border-b-[12px] border-l-transparent border-r-transparent border-b-white/70"></div></div><div class="absolute left-[25%] bottom-[25%] -rotate-30"><div class="h-0 w-0 border-l-[6px] border-r-[6px] border-b-[10px] border-l-transparent border-r-transparent border-b-white/60"></div></div><div class="absolute right-[15%] bottom-[20%] rotate-60"><div class="h-0 w-0 border-l-[7px] border-r-[7px] border-b-[11px] border-l-transparent border-r-transparent border-b-white/65"></div></div><div class="absolute left-[45%] top-[40%] -rotate-15"><div class="h-0 w-0 border-l-[5px] border-r-[5px] border-b-[8px] border-l-transparent border-r-transparent border-b-white/50"></div></div><div class="absolute right-[35%] top-[35%] h-2 w-2 rounded-full bg-white/40"></div><div class="absolute left-[40%] bottom-[35%] h-1.5 w-1.5 rounded-full bg-white/35"></div><div class="absolute right-[45%] bottom-[45%] h-1 w-1 rounded-full bg-white/30"></div><div class="absolute top-[30%] left-[30%] h-0.5 w-6 rotate-45 bg-white/25"></div><div class="absolute bottom-[30%] right-[30%] h-0.5 w-4 -rotate-30 bg-white/20"></div></div></div></div></div><div class="absolute top-0 right-0 hidden h-full w-80 transition-opacity duration-300 group-hover:opacity-90 md:block"><div class="h-full w-full"><div class="from-pink-500/20 to-rose-500/10 relative h-full w-full overflow-hidden bg-gradient-to-br" style="background-blend-mode:overlay;background-color:color-mix(in srgb,var(--color-primary) 15%,transparent)"><div class="absolute inset-0"><div class="absolute left-[15%] top-[20%] rotate-45"><div class="h-0 w-0 border-l-[10px] border-r-[10px] border-b-[16px] border-l-transparent border-r-transparent border-b-white/80"></div></div><div class="absolute right-[20%] top-[15%] rotate-12"><div class="h-0 w-0 border-l-[8px] border-r-[8px] border-b-[12px] border-l-transparent border-r-transparent border-b-white/70"></div></div><div class="absolute left-[25%] bottom-[25%] -rotate-30"><div class="h-0 w-0 border-l-[6px] border-r-[6px] border-b-[10px] border-l-transparent border-r-transparent border-b-white/60"></div></div><div class="absolute right-[15%] bottom-[20%] rotate-60"><div class="h-0 w-0 border-l-[7px] border-r-[7px] border-b-[11px] border-l-transparent border-r-transparent border-b-white/65"></div></div><div class="absolute left-[45%] top-[40%] -rotate-15"><div class="h-0 w-0 border-l-[5px] border-r-[5px] border-b-[8px] border-l-transparent border-r-transparent border-b-white/50"></div></div><div class="absolute right-[35%] top-[35%] h-2 w-2 rounded-full bg-white/40"></div><div class="absolute left-[40%] bottom-[35%] h-1.5 w-1.5 rounded-full bg-white/35"></div><div class="absolute right-[45%] bottom-[45%] h-1 w-1 rounded-full bg-white/30"></div><div class="absolute top-[30%] left-[30%] h-0.5 w-6 rotate-45 bg-white/25"></div><div class="absolute bottom-[30%] right-[30%] h-0.5 w-4 -rotate-30 bg-white/20"></div></div></div></div></div><div class="absolute top-0 right-0 hidden h-full w-80 opacity-0 transition-opacity duration-300 group-hover:opacity-100 md:block bg-gradient-to-l from-primary/5"></div><div class="relative z-10 flex flex-1 flex-col p-6 md:pr-[21rem]"><h3 class="text-foreground group-hover:text-primary mb-4 text-lg font-semibold leading-tight transition-colors duration-200">Redis Ordered Set</h3><p class="text-muted-foreground mb-4 text-sm leading-relaxed line-clamp-2">Redis 的有序集和(ordered set)同时具有"有序"和"集和"两种性质, 这种结构中每个元素都由一个成员和一个与成员相关联的分值组成, 其中成员与字符串方式存储, 而分值以64位双精度浮点数格式存储.</p><div class="mt-auto text-sm text-muted-foreground"><div class="flex items-center gap-3"><div class="flex items-center gap-1.5"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-label="Published on"><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>
5959
<time datetime=2025-08-30 class=font-medium>August 30, 2025</time></div><div class="flex items-center gap-1.5"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-label="Reading time"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3A9 9 0 113 12a9 9 0 0118 0z"/></svg>
60-
<span class=font-medium>5 minute</span></div></div><div class="flex flex-wrap items-center gap-1.5 mt-2"><span class="bg-muted/50 border-muted/30 flex items-center gap-1 rounded-md border px-2 py-1"><span class=font-medium>Redis</span>
60+
<span class=font-medium>7 minute</span></div></div><div class="flex flex-wrap items-center gap-1.5 mt-2"><span class="bg-muted/50 border-muted/30 flex items-center gap-1 rounded-md border px-2 py-1"><span class=font-medium>Redis</span>
6161
</span><span class="bg-muted/50 border-muted/30 flex items-center gap-1 rounded-md border px-2 py-1"><span class=font-medium>NoSQL</span></span></div></div></div></div></a></article><article class=group><a href=/posts/asyncio-vs-gevents-in-python/ class=block><div class="bg-card border-border hover:bg-primary/5 hover:border-primary/20 focus:ring-primary/20 relative flex flex-col overflow-hidden rounded-xl border transition-all duration-300 ease-out hover:-translate-y-1 hover:scale-[1.02] hover:shadow-lg focus:ring-2 focus:outline-none min-h-[200px]"><div class="block md:hidden"><div class="aspect-[2/1] overflow-hidden"><div class="from-orange-500/20 to-red-500/10 relative aspect-[2/1] overflow-hidden bg-gradient-to-br" style="background-blend-mode:overlay;background-color:color-mix(in srgb,var(--color-primary) 15%,transparent)"><div class="absolute inset-0"><div class="absolute left-[20%] top-[20%] h-6 w-6 rounded-full border-2 border-white/80 bg-white/15"></div><div class="absolute right-[25%] top-[25%] h-5 w-5 rounded-full border border-white/70 bg-white/12"></div><div class="absolute left-[30%] bottom-[30%] h-4 w-4 rounded-full border border-white/60 bg-white/10"></div><div class="absolute right-[20%] bottom-[20%] h-5 w-5 rounded-full border border-white/65 bg-white/13"></div><div class="absolute left-[45%] top-[45%] h-3 w-3 rounded-full border border-white/50 bg-white/8"></div><div class="absolute right-[35%] top-[35%] h-2 w-2 rounded-full bg-white/50"></div><div class="absolute left-[40%] bottom-[35%] h-1.5 w-1.5 rounded-full bg-white/45"></div><div class="absolute left-[35%] top-[50%] h-1 w-1 rounded-full bg-white/40"></div><div class="absolute right-[40%] bottom-[50%] h-1 w-1 rounded-full bg-white/35"></div><div class="absolute left-[50%] top-[30%] h-1 w-1 rounded-full bg-white/30"></div><div class="absolute right-[50%] bottom-[30%] h-1 w-1 rounded-full bg-white/25"></div><div class="absolute top-[40%] left-[15%] h-0.5 w-6 rotate-30 bg-white/25"></div><div class="absolute bottom-[40%] right-[15%] h-0.5 w-4 -rotate-30 bg-white/20"></div></div></div></div></div><div class="absolute top-0 right-0 hidden h-full w-80 transition-opacity duration-300 group-hover:opacity-90 md:block"><div class="h-full w-full"><div class="from-orange-500/20 to-red-500/10 relative h-full w-full overflow-hidden bg-gradient-to-br" style="background-blend-mode:overlay;background-color:color-mix(in srgb,var(--color-primary) 15%,transparent)"><div class="absolute inset-0"><div class="absolute left-[20%] top-[20%] h-6 w-6 rounded-full border-2 border-white/80 bg-white/15"></div><div class="absolute right-[25%] top-[25%] h-5 w-5 rounded-full border border-white/70 bg-white/12"></div><div class="absolute left-[30%] bottom-[30%] h-4 w-4 rounded-full border border-white/60 bg-white/10"></div><div class="absolute right-[20%] bottom-[20%] h-5 w-5 rounded-full border border-white/65 bg-white/13"></div><div class="absolute left-[45%] top-[45%] h-3 w-3 rounded-full border border-white/50 bg-white/8"></div><div class="absolute right-[35%] top-[35%] h-2 w-2 rounded-full bg-white/50"></div><div class="absolute left-[40%] bottom-[35%] h-1.5 w-1.5 rounded-full bg-white/45"></div><div class="absolute left-[35%] top-[50%] h-1 w-1 rounded-full bg-white/40"></div><div class="absolute right-[40%] bottom-[50%] h-1 w-1 rounded-full bg-white/35"></div><div class="absolute left-[50%] top-[30%] h-1 w-1 rounded-full bg-white/30"></div><div class="absolute right-[50%] bottom-[30%] h-1 w-1 rounded-full bg-white/25"></div><div class="absolute top-[40%] left-[15%] h-0.5 w-6 rotate-30 bg-white/25"></div><div class="absolute bottom-[40%] right-[15%] h-0.5 w-4 -rotate-30 bg-white/20"></div></div></div></div></div><div class="absolute top-0 right-0 hidden h-full w-80 opacity-0 transition-opacity duration-300 group-hover:opacity-100 md:block bg-gradient-to-l from-primary/5"></div><div class="relative z-10 flex flex-1 flex-col p-6 md:pr-[21rem]"><h3 class="text-foreground group-hover:text-primary mb-4 text-lg font-semibold leading-tight transition-colors duration-200">Asyncio vs Gevents in Python</h3><p class="text-muted-foreground mb-4 text-sm leading-relaxed line-clamp-2">python 中 asyncio 和 gevent 是两种协程(在一个线程内实现并发)的实现, 这篇文章对比介绍这两者实现.
6262
下面先介绍一下基础概念:
6363
Coroutines 协程 在 Python 中, 协程是可以暂停和继续运行的函数, 使得其是否适合并发编程. 定义使用 async def 语法, 协程运行编写非阻塞 …</p><div class="mt-auto text-sm text-muted-foreground"><div class="flex items-center gap-3"><div class="flex items-center gap-1.5"><svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-label="Published on"><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>

public/index.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)