去年的时候给自己的电脑升级Big Sur,结果升级完后发现一个严重的问题:鼠标指针的位置和鼠标实际点击的位置不一致。

比如我要点击关闭窗口的按钮,有可能点到窗口外面,或者点到窗口里面其他地方。

c76dfd1a0b0d9b8fccd6d189c58997.MP4

这基本就宣告本次升级的彻底失败,于是我灰溜溜地恢复备份,退回了Catalina。

今年又手痒了,直接升级到Monterey,结果还是一样的问题,鼠标根本点不到它显示的地方。这就不对了,苹果不可能两次系统大升级都没发现这个bug啊,难道是我的电脑有个很隐秘的设置和别人的不一样?

- 阅读剩余部分 -

有时候我们会对接一个弱鸡后端服务,只能支持很低的并发量。为了防止世界被破坏,我们需要对用户请求做限流,避免后端服务被打垮。

限流器有多种算法,比较常用的如令牌桶、漏桶、滑动窗口等。本文讲的是滑动窗口算法。

滑动窗口算法限流最适合的需求场景,就是X秒内,最多允许Y个请求。用漏桶和令牌桶算法我还没想出来应该咋能精确实现这一需求。

滑动窗口的原理网上一搜一大堆,这里就不描述了。我们直接来讲:

- 阅读剩余部分 -

我们会遇到这样的需求:

某一张表的某一列,存储的是用某个分隔符分割的字符串,我们现在要分割字符串的每个部分,求每个部分的汇总数据。

例如有一张表叫reward_detail

group_idmember_countnamestotal_reward
14Tom,Jack,HanMeimei,LiLei200
24Jack,Rose,Mary,张三400
32张三,李四300

这是一张设计得不那么好的表,有若干组,一个人可以同时在多个组,每组有奖金,组内成员平分奖金,成员存在一列,使用逗号分开。

我们已知每组不超过10个人,怎么仅使用SQL,求出每个人获得的奖金金额呢?

- 阅读剩余部分 -

有时候我们需要通过业务逻辑限制用户对某些路径的访问,这件事情通过nginx配置本身是做不了的,例如登录用户校验之类的逻辑。举个栗子:

有一个文件,这个文件位于服务器的 /home/server/private_files/ 目录。只有高等级的用户才能获取下载路径,且下载路径有时效,过期则失效。

要实现此功能,我们得把它分为两部分:一部分是下载路径的生成和有效性判断,这部分是业务逻辑代码实现的;另一部分则是对这个文件的保护,只有通过业务逻辑校验的请求才有权拿到此文件。

此时我们就需要用到Nginx的内部重定向功能了。

我们需要知道的两个知识点:

  1. Nginx在做反向代理拿到服务端生成的结果时,会检查服务端返回的响应头(Response Header),检查此字段:X-Accel-Redirect。如果此字段设置了内容,Nginx则会根据其设置的重定向地址,直接请求此地址的数据,并将数据输出。
  2. Nginx的location配置可以使用internal标记,将此路径标记为只允许内部访问。内部访问的意思并不是说localhost就可以访问,而是说「一次请求的」内部。

那么如何配置呢?

首先,nginx需要加上如下配置:

location /get_file/ {
    fastcgi_pass xxxxx # 或 proxy_pass,用于将请求转发到服务端
}

location /private_files/ {
    # 内部路径,禁止直接请求
    internal;
    alias /home/server/private_files/
}

然后,在服务端实现对 /get_file/xxx 的处理逻辑,如果允许访问,则返回的响应头中,写入如下信息:(以php为例)

// And redirect user to internal location
header("X-Accel-Redirect: /private_files/a.txt");

用图来表示一下:

在用户直接请求 /private_files/a.txt

直接访问

在用户请求 /get_files/xxxx

合法请求

写Python的时候,最讨厌做的事情就是处理时间——从时间戳转换到时间字符串,加减天数、月数,每次都是不看文档写不出来。

举个最简单的例子,获取昨天0点的时间戳

Python的变态代码需要这么写:

# 先以当前时间获取昨天的这个时间
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
# 格式化到日
yseterday_ymd = yesterday.strftime("%Y-%m-%d")
# 再转换为时间戳
ts = int(time.mktime(time.strptime(yesterday_ymd, '%Y-%m-%d')))

每次写完都感觉身体被掏空。

自从接触了世界上最好的语言——PHP,每次处理时间都信手拈来

// 没错!就这一行,就这么短!
ts = (int)strtotime('0:00 yesterday');

php的strtotime的参数可以基本接近自然语言的描述,只要稍微看看文档,了解一下规则,写起代码来简直神清气爽。

当然有些坑得注意,比如

strtotime('20190131 +1 month');

php在这里处理时,认为应该是20190231,2月31日,但是没这个日期,所以进位到3月,变成3月3日。